【问题标题】:Binary value to float value conversion is not working due to type casting由于类型转换,二进制值到浮点值的转换不起作用
【发布时间】:2014-04-25 05:38:20
【问题描述】:

在这里我从我的代码中添加函数,用于从给定的二进制数生成浮点数。

代码:

double binary_float(double f) /* Function to convert binary to float.*/
{
   long     integral = 0, floatInt = 0, i = 1, temp1 = 0, k = 1;
   double   floatFract = 0, fractional = 0, floatTotal = 0;

   //Separating the integral value from the floating point variable
   integral = (long)f;

   //Separating the fractional value from the variable
   fractional = f - (long)f;

   //Converting binary to decimal
   floatInt = binary_decimal(integral);

   //Loop for converting binary to Fractional value
   while( k < 10000000 && fractional != (double)0 )
   {
      k = k * 10;
      i = i * 2;
      temp1 = (long)(fractional * k);

printf("temp: %ld, r: %lf\n", temp1, (fractional * k));

      floatFract = floatFract + (double)temp1/(double)i;

printf("fact: %lf, r: %lf\n", floatFract, ((double)temp1/(double)i));

      fractional = fractional - (double)temp1/(double)k;

printf("frac: %lf, r: %lf\n", fractional, ((double)temp1/(double)k));

   }

   //Combining both the integral and fractional binary value.
   floatTotal = floatInt + floatFract;

   return floatTotal;
}

long binary_decimal(long n)
{
   long decimal=0, i=0, rem;
   while (n!=0)
   {
      rem = n%10;
      n/=10;
      decimal += rem*pow(2,i);
      ++i;
   }
   return decimal;
}

输出:

Enter a binary number: 1010.001100
temp: 0, r: 0.011000
fact: 0.000000, r: 0.000000
frac: 0.001100, r: 0.000000
temp: 0, r: 0.110000
fact: 0.000000, r: 0.000000
frac: 0.001100, r: 0.000000
temp: 1, r: 1.100000
fact: 0.125000, r: 0.125000
frac: 0.000100, r: 0.001000

temp: 0, r: 1.000000

fact: 0.125000, r: 0.000000
frac: 0.000100, r: 0.000000
temp: 9, r: 10.000000
fact: 0.406250, r: 0.281250
frac: 0.000010, r: 0.000090
temp: 9, r: 10.000000
fact: 0.546875, r: 0.140625
frac: 0.000001, r: 0.000009
temp: 9, r: 10.000000
fact: 0.617188, r: 0.070312
frac: 0.000000, r: 0.000001
1010.001100 in binary = 10.617188 in float

在输出中您可以看到 temp: 0, r: 1.000000 表示 temp1 = 0 是 1.000000 的 long 类型转换。

谁能解释一下为什么这种类型转换不起作用?

【问题讨论】:

    标签: c type-conversion


    【解决方案1】:

    OP: "temp: 0, r: 1.000000 表示 temp1 = 0 是 1.000000 的 long 类型转换。"
    答:doublelong 的转换是有效的,因为 double 小于 1.0。

    代码正在打印double四舍五入 值,而不是其精确值,略小于 1.0。 (long) some_number_slightly_less_than_10。尝试使用更精确的"%.20le" 而不是"%lf" 打印double

    给定典型的 IEEE binary64 浮点,当代码以 double1010.001100 开头时,代码实际上是以 1010.00109999999995125108.... 开头。

    至于为什么10.617188的答案错误,我怀疑是未贴代码binary_decimal();


    代码有错误:

    // floatFract = floatFract + (double) temp1 / (double) i;
    floatFract = floatFract + (double) temp1 / (double) k;
    ...
    // wrong result of 10.61718750000000000000
    // correct result follows
    10.00109989999999982047....
    // or to 6 decimal places
    10.001100
    

    次要:请注意,以下代码仅适用于 double f 范围内的 LONG_MINLONG_MAX

    integral = (long)f;
    

    【讨论】:

    • 所以我遇到了问题。但是我该如何解决这个问题呢?
    • 张贴 binary_decimal() 会有所帮助。
    【解决方案2】:

    temp1 使用%ld 标志打印,即long int,而r 使用%lf 标志打印double,因此尾随0s。

    【讨论】:

    • 问题不是尾随 0 秒。问题是类型转换不起作用。
    • printf("temp: %ld, r: %lf\n", (double)(fractional * k), (fractional * k));会给你同样的输出。并不是演员表不起作用。
    • 也试试 printf("temp: %lf, r: %lf\n", (long)(fractional * k), (fractional * k));。 PS:不应该使用错误的标志,它会导致未定义的行为。
    • 请看代码,看看什么是变量类型,我只是为了理解目的而打印。如果你看到一条线与其他线分开,那么你就会得到确切的问题。
    【解决方案3】:

    在这里,我想出的东西并没有完全发挥作用。长数据类型有限制,所以我们不能在这个程序中输入比这个范围更大的数字,否则这个程序可以正常工作。

    代码:

    double binary_float(double f) /* Function to convert binary to float.*/
    {
       long     integral = 0, floatInt = 0;
       double   floatFract = 0, fractional = 0, floatTotal = 0;
    
       //Separating the integral value from the floating point variable
       integral = (long)f;
       //Separating the fractional value from the variable
       fractional = f - (long)f;
    
       //Converting binary to decimal
       floatInt = binary_decimal(integral);
       //Converting float value from binary to float value
       floatFract = binary_float_float(fractional);
    
       //Combining both the integral and fractional binary value.
       floatTotal = floatInt + floatFract;
    
       return floatTotal;
    }
    
    long binary_decimal(long n) /* Function to convert binary to decimal.*/
    {
       long decimal=0, i=0, rem;
       while (n!=0)
       {
          rem = n%10;
          n/=10;
          decimal += rem*pow(2,i);
          ++i;
       }
       return decimal;
    }
    
    double binary_float_float(double fractional)
    {
       long     temp1 = 0, k = 1, i = 1;
       double   floatFract = 0;
    
       //Loop for converting binary to Fractional value
       while( k < 1000000000 && fractional != (double)0 )
       {
          k = k * 10;
          i = i * 2;
          temp1 = (long)(fractional * k);
          //If value is larger then 1 it means .001100 is represented as .00109994....
          //So it's last digit and so we can break loop from that point
          if (temp1 > 1)
          {
             temp1 = 1;
             floatFract = floatFract + (double)temp1/(double)i;
             break;
          }
    
          floatFract = floatFract + (double)temp1/(double)i;
          fractional = fractional - (double)temp1/(double)k;
       }
    
       return floatFract;
    }
    

    任何有更好的想法和更好的方法从二进制数中找到浮点值的人,请分享。

    【讨论】:

      猜你喜欢
      • 2015-01-25
      • 1970-01-01
      • 2021-09-10
      • 2011-06-03
      • 2015-06-01
      • 2015-10-11
      • 1970-01-01
      • 1970-01-01
      • 2018-10-17
      相关资源
      最近更新 更多