首页 > 解决方案 > 在c中将浮点数更改为整数

问题描述

在我的程序的某些部分,我有一个包含浮点数的数组(例如 9.8、5.0、4.45)。我要做的是将这些数字放到另一个数组中,如果它们是浮点数(我的意思是如果它们的小数点后的数字不为零),然后将它们乘以 10 次足以使其成为一个int值(所以从第一个例子,之后我应该有 98、5、445)。我知道这听起来不太清楚,但我很难更好地描述我的问题。

我的尝试是这样做,但我有错误。

for(i=0;i<size;i++)
    {
       if(teb[i]%10!=0)
       {
           while(teb[i]%1!=0)
           {
               teb[i]=teb[i]*10;
           }
       }
    }

我有错误:invalid operator to binary % (have float and int)我不确定我是否可以使用 char 或类似的变量。

标签: cinteger

解决方案


在我看来,如果不使用字符串格式化然后从字符串转换回浮点数,您将无法明智地管理此问题。我使用double而不是float. 这是我想出的代码,包括您的三个测试值作为前三个。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static inline int all_same_as(char *str, char c)
{
    while (*str != '\0')
    {
        if (*str++ != c)
            return 0;
    }
    return 1;
}

static inline void zap_trailing(char *str, char c)
{
    char *end = str + strlen(str);
    while (end > str)
    {
        if (*(end - 1) != c)
            return;
        *--end = '\0';
    }
}

static inline void zap_leading(char *str, char c)
{
    char *end = str;
    while (*end == c)
        end++;
    if (end > str)
        memmove(str, end, strlen(end) + 1);  /* Not memcpy()! */
}

int main(void)
{
    double d[] =
    {
        9.8,
        5.0,
        4.45,
        1.0,
        18.0,
        9.25,
        8.719,
        2.78128,
        2721.0/1001.0,
        3.14159,
        355.0/113.0,
        0.001234,   /* Smaller */
        1.2345E+13, /* Biggest */
        1.2345E-13, /* Smallest */
    };
    enum { NUM_D = sizeof(d) / sizeof(d[0]) };

    for (int i = 0; i < NUM_D; i++)
    {
        char buffer1[32];
        snprintf(buffer1, sizeof(buffer1), "%.6f", d[i]);
        char buffer2[32];
        strcpy(buffer2, buffer1);
        zap_leading(buffer2, ' ');              /* Not needed with %.6f; was needed with %10.6f */
        char *dot = strchr(buffer2, '.');
        if (all_same_as(dot + 1, '0'))
            *dot = '\0';
        else
        {
            zap_trailing(dot + 1, '0');
            size_t len = strlen(dot + 1);
            memmove(dot, dot + 1, len + 1);     /* Not memcpy()! */
        }
        double iv = strtod(buffer2, NULL);
        printf("%8g = %8.2g = %8.3g = %10s (converted: %10s - [%s] %g)\n",
               d[i], d[i], d[i], buffer1, buffer2, buffer2, iv);
    }
    return 0;
}

输出:

     9.8 =      9.8 =      9.8 =   9.800000 (converted:         98 - [98] 98)
       5 =        5 =        5 =   5.000000 (converted:          5 - [5] 5)
    4.45 =      4.5 =     4.45 =   4.450000 (converted:        445 - [445] 445)
       1 =        1 =        1 =   1.000000 (converted:          1 - [1] 1)
      18 =       18 =       18 =  18.000000 (converted:         18 - [18] 18)
    9.25 =      9.2 =     9.25 =   9.250000 (converted:        925 - [925] 925)
   8.719 =      8.7 =     8.72 =   8.719000 (converted:       8719 - [8719] 8719)
 2.78128 =      2.8 =     2.78 =   2.781280 (converted:     278128 - [278128] 278128)
 2.71828 =      2.7 =     2.72 =   2.718282 (converted:    2718282 - [2718282] 2.71828e+06)
 3.14159 =      3.1 =     3.14 =   3.141590 (converted:     314159 - [314159] 314159)
 3.14159 =      3.1 =     3.14 =   3.141593 (converted:    3141593 - [3141593] 3.14159e+06)
0.001234 =   0.0012 =  0.00123 =   0.001234 (converted:    0001234 - [0001234] 1234)
1.2345e+13 =  1.2e+13 = 1.23e+13 = 12345000000000.000000 (converted: 12345000000000 - [12345000000000] 1.2345e+13)
1.2345e-13 =  1.2e-13 = 1.23e-13 =   0.000000 (converted:          0 - [0] 0)

您可以选择支持多少个小数位数等。我选择在小数点后最多使用 6 个(%.6f与 一起使用的格式snprintf())。我包括了非常小的 (1.23E-13) 和非常大的 (1.23E+13) 值;更大或更小的值的行为是相似的。

我最初%10.6fsnprintf()声明中使用。当我这样做时,值以前导空格打印。该zap_leading()功能删除了那些。该代码已被修改为可以使用%.6f,并且没有前导空格可以删除。我留下了代码来替换前导字符;它也可以被删除。


推荐阅读