C:将实数转换为64位浮点二进制

时间:2014-08-23 07:33:56

标签: c floating-point binary converter fractions

我正在尝试编写一个将实数转换为64位浮点二进制的代码。为此,用户输入实数(例如,547.4242),程序必须输出64位浮点二进制数。

我的想法:

  • 标志部分很简单。
  • 程序转换整数部分(前一个例子为547)并将结果存储在int变量中。然后,程序转换小数部分(前一个示例的.4242)并将结果存储到数组中(数组的每个位置存储'1'或'0')。

这就是我被困住的地方。总结一下,我有:“整数部分= 1000100011”(类型为int)和“分数部分= 0110110010011000010111110000011011110110100101000100”(数组)。

我该怎么办?

4 个答案:

答案 0 :(得分:0)

以下代码用于根据IEEE754表示法确定浮点数的内部表示。此代码在Turbo c ++ ide中生成,但您可以轻松转换为通用ide。

#include<conio.h>
#include<stdio.h>

void decimal_to_binary(unsigned char);

union u
{
    float f;
    char c;
};

int main()
{
    int i;
    char*ptr;
    union u a;

    clrscr();
    printf("ENTER THE FLOATING POINT NUMBER : \n");
    scanf("%f",&a.f);

    ptr=&a.c+sizeof(float);

    for(i=0;i<sizeof(float);i++)
    {
        ptr--;
        decimal_to_binary(*ptr);
    }

    getch();
    return 0;
}

void decimal_to_binary(unsigned char n)
{
    int arr[8];
    int i;
    //printf("n = %u  ",n);

    for(i=7;i>=0;i--)
    {
        if(n%2==0)
            arr[i]=0;
        else
            arr[i]=1;
        n/=2;
    }

    for(i=0;i<8;i++)
        printf("%d",arr[i]);
    printf(" ");
}

有关详细信息,请点击here

答案 1 :(得分:0)

诀窍是将值视为整数,因此将547.4242读作无符号长long(即64位或更多),即5474242,计算后的数字位数。 &#39;。&#39;,在这种情况下4.现在你有一个比它应该大10 ^ 4的值。所以你浮动5474242(作为双倍或长双)并除以10 ^ 4。

十进制到二进制转换看似简单。当你有更多的位数而不是浮点数时,它将不得不舍入。当你有比64位整数更多的数字时会发生更多的乐趣 - 注意尾随的零是特殊的 - 你必须决定是否舍入(以及浮动时发生的舍入)。然后就是处理E +/- 99。然后,当你最终划分(或乘法)10 ^ n时,你有(a)另一个潜在的舍入,以及(b)你的浮动中表示大10 ^ n不是完全的问题点 - 这是另一个错误来源。 (对于E +/- 99表格,最后一步可能需要达到10 ^ 300以上。)

享受!

答案 2 :(得分:0)

为了将所有可能的十进制表示正确地舍入到最近的double,您需要大整数。仅使用C中的基本整数类型将使您重新实现大整数算术。这两种方法都是可能的,关于每种方法的更多信息如下:

  1. 对于第一种方法,您需要一个大整数库:GMP是一个很好的库。使用这样一个大整数库,你可以处理一个输入,例如123.456E78作为整数123456 * 10 75 ,并开始想知道[2 53 中的M值是多少...... 2 54 )和[-1022 ... 1023]中的P使得(M / 2 53 )* 2 P 最接近该数目。这个问题可以通过大整数运算来回答,遵循this blog post中描述的步骤(摘要:首先确定P.然后使用除法来计算M)。完整的实现必须处理次正规数和无穷大(inf是返回指数大于+1023的数字的任何十进制表示的正确结果。

  2. 第二种方法,如果您不想包含或实现完整的通用大整数库,仍然需要在表示大数的C整数数组上实现一些基本操作。此implementation中的函数decfloat()表示基数10 9 中的大数字,因为这简化了从初始十进制表示到内部表示的转换,如数组x uint32_t

答案 3 :(得分:0)

以下是基本转换。足够让OP开始。

OP的“实数的整数部分” - &gt; int太有限了。最好将整个字符串简单地转换为像uintmax_t这样的大整数。请注意小数点'.'并考虑扫描时溢出。

此代码不处理指数也不处理负数。由于有限整数ui或最终num = ui * pow10(expo),它可能在最后一位左右关闭。它处理大多数溢出情况。

#include <inttypes.h>

double my_atof(const char *src) {
  uintmax_t ui = 0;
  int dp = '.';
  size_t dpi;
  size_t i = 0;
  size_t toobig = 0;
  int ch;
  for (i = 0; (ch = (unsigned char) src[i]) != '\0'; i++) {
    if (ch == dp) {
      dp = '\0';  // only get 1 dp
      dpi = i;
      continue;
    }
    if (!isdigit(ch)) {
      break; // illegal character
    }
    ch -= '0';
    // detect overflow
    if (toobig || 
        (ui >= UINTMAX_MAX / 10 && 
        (ui > UINTMAX_MAX / 10 || ch > UINTMAX_MAX % 10))) {
      toobig++;
      continue;
    }
    ui = ui * 10 + ch;
  }
  intmax_t expo = toobig;
  if (dp == '\0') {
    expo -= i - dpi - 1;
  }

  double num;
  if (expo < 0) {
    // slightly more precise than: num = ui * pow10(expo);
    num = ui / pow10(-expo);
  } else {
    num = ui * pow10(expo);
  }
  return num;
}