在C中将浮点数转换为二进制表示程序

时间:2016-10-17 06:53:18

标签: c floating-point binary converters

#include "ieee754.h"
#include <stdio.h>
#include <math.h>

//This program convert a floating number to its binary representation (IEEE754) in computer memory
int main() {
    long double f, binaryTotal, binaryFrac = 0.0, frac, fracFractor = 0.1;
    long int integer, binaryInt = 0;
    long int p = 0, rem, temp;

    printf("\nEnter floating number: ");
    scanf("%Lf", &f);

    //separate the integer part from the input floating number
    integer = (int)f;

    //separate the fractional part from the input floating number
    frac = f - integer;

    //loop to convert integer part to binary
    while (integer != 0) {
        rem = integer % 2;
        binaryInt = binaryInt + rem *pow(10, p);
        integer = integer / 2;
        p++;
    }

    //loop to convert fractional part to binary
    while (frac != 0) {
        frac = frac * 2;
        temp = frac;
        binaryFrac = binaryFrac + fracFractor * temp;
        if (temp == 1)
            frac = frac - temp;

        fracFractor = fracFractor / 10;
    }

    binaryTotal = binaryInt + binaryFrac;
    printf("binary equivalent = %Lf\n", binaryTotal);
}

我正在尝试将浮点数转换为二进制表示(64位)。这段代码有效,但并不完美。例如,当我转换.575时,它会向我0.100100但是当我使用此网站http://www.exploringbinary.com/floating-point-converter/进行转换时,正确的输出应为0.1001001100110011001100110011001100110011001100110011

我无法理解是什么让我的代码截断了数字。任何人都可以帮我解决这个问题吗?我感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

许多问题:

  1. 使用(int)提取long double的整数部分会严重限制范围。使用modfl(long double value, long double *iptr);

    long double f;
    long int integer;
    //separate the integer part from the input floating number
    // Weak code
    integer = (int)f;
    
    long double ipart;
    long double fpart = modfl(f, &ipart);
    
  2. long p; pow(10,p); - &gt; pow()一旦p超过某个值,pow()返回值的精度就会降低(例25)。将long double与使用powl()的函数一起使用也很奇怪。我期待fracFractor/10

  3. 各种其他不精确的FP问题:long10精度有限。

  4. 代码很奇怪,因为它试图将FP编号(可能是某种二进制格式)转换为二进制表示。它不应该在代码中的任何位置#include<stdio.h> #include<stdlib.h> #include<math.h> #include<float.h> static void print_ipart(long double x) { int digit = (int) (modfl(x/2, &x)*2.0) + '0'; if (x) { print_ipart(x); } putchar(digit); } void print_bin(long double x) { // Some TBD code // Handle NAN with isnan() // Handle infinity with isfinite() putchar(signbit(x) ? '-' : '+'); long double ipart; long double fpart = modfl(fabsl(x), &ipart); print_ipart(ipart); putchar('.'); while (fpart) { long double ipart; fpart = modfl(fpart * 2, &ipart); putchar((int)ipart + '0'); } putchar('\n'); } int main() { print_bin(-4.25); print_bin(.575); print_bin(DBL_MAX); print_bin(DBL_MIN); print_bin(DBL_TRUE_MIN); }

    建议像

    这样简单的东西
    -100.01
    +0.1001001100110011001100110011001100110011001100110011001100110011
    +1111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.
    +0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
    +0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
    

    输出

    await

答案 1 :(得分:0)

这就是为什么这不太可行:

fracFractor = 0.1
...
fracFractor = fracFractor/10

0.1无法以任何二进制浮点格式准确表示。你不能将0.1表示为2的负幂的倍数。将它除以10将使每一步都收集舍入误差。可能是你实际退出了这个循环,因为你最终将重复分数与另一个重复分数进行比较。

这将严重限制你可以实现的目标:

binaryTotal = binaryInt + binaryFrac;

以浮点形式执行此操作将具有严重的限制 - 至少表示0.1不能表示如上所述。这就是为什么你得到的答案显示为二进制和十进制数字的混合。

要解决此问题,您应该查看数字的各个位。为了保持解决方案的整体概念不变,最简单的方法是从你的分数中减去2的负功率(0.5,0.25等),测试它是否仍为正,并根据它构建一个字符串。然后对整数部分使用类似的逻辑。