这个浮点到十进制转换有什么问题?

mar*_*zzz 5 floating-point

转换0 10000101 01010011000000000000001为十进制(这是84.75000762939453125)效果很好:

FP: 0 10000101 01010011000000000000001
Fraction: (1.)01010011000000000000001
Exp 10000101: 133
Bias: 133-127=6
Moving by exp: 1010100.11000000000000001
Convert parts to decimal: 84.75000762939453125
Run Code Online (Sandbox Code Playgroud)

为什么我无法将相同的转换0 00000001 00000000000000000000001为十进制(即(1.1754945E-38):

FP: 0 00000001 00000000000000000000001
Fraction: (1.)00000000000000000000001
Exp 00000001: 1
Bias: 1-127=-126
Moving by exp: 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
Convert parts to decimal: 0.?!?!?!
Run Code Online (Sandbox Code Playgroud)

无法1.1754945E-38将二进制转换0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001为十进制.

我哪里错了?

chu*_*ica 2

我哪里错了?

几个问题

Moving by exp不正确

A0应该是1.

FP: 0 00000001 00000000000000000000001
Fraction: (1.)00000000000000000000001
Exp 00000001: 1
Bias: 1-127=-126
// wrong
Moving by exp: 0.0000000000 (many zeros omitted) 0000000000000000000000000001
// should be 
Moving by exp: 0.0000000000 (many zeros omitted) 0000100000000000000000000001
//                                                   ^
Run Code Online (Sandbox Code Playgroud)

网站不正确

OP 的参考工具对于 0.000000000000000000000000000000000000000000000000000000000000000000001 2的值返回 0

输入0.0000000000 (many zeros omitted) 0000100000000000000000000001也报告0。


将字符串“0.0000000000(省略许多零)0000100000000000000000000001”正确转换为以 2 为基数的分数很容易给出 OP 的预期值。

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

int main(void) {
  char *Moving_by_exp = "0."
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "0000000000"
      "00000100000000000000000000001";
  char *s = Moving_by_exp;
  double x = 0.0;
  int power2 = 0;
  while (*s) {
    power2--;
    if (*s == '.') power2 = 0;
    else x = x*2 + *s - '0';
    s++;
  }
  printf("%.7e\n", x*pow(2,power2));
  printf("%.16e\n", x*pow(2,power2));
}
Run Code Online (Sandbox Code Playgroud)

输出

1.1754945e-38
1.1754944909521339e-38
Run Code Online (Sandbox Code Playgroud)

OP的错误“0.0000000000(省略了许多零)0000000000000000000000000001”转换为1.4012985e-45