从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
为什么我无法将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.?!?!?!
无法1.1754945E-38
将二进制0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
转换为十进制。
我哪里错了?
答案 0 :(得分:2)
我哪里错了?
一些问题
Moving by exp
不正确 0
应该是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
// ^
对于高达0.0000000000000000000000000000000000000000000000000000000000000000000001 2
的值,OP reference tool返回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));
}
输出继电器
1.1754945e-38
1.1754944909521339e-38
OP不正确&#34; 0.0000000000(省略多个零)0000000000000000000000000001&#34;转换为1.4012985e-45
答案 1 :(得分:0)
你没错。该工具是错误的。
我找到了一个页面(第一个是我用Google搜索时出现的#34; ieee 754转换器&#34;),这个页面没有问题:https://www.h-schmidt.net/FloatConverter/IEEE754.html
我写了一个小C程序,它可能包含一些不可移植性,未定义的行为和过时的编码实践,但它显示了一些相关的浮点数和整数之间的转换:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef union {
float f;
int i;
} both;
void printbits(int k) {
int i;
for (i = 0; i < 32; i++) {
if (i == 1 || i == 9)
printf(" ");
if (k & (1<<(31-i)))
printf("1");
else
printf("0");
}
printf("\n");
}
int main() {
printf("sizeof(float) = %ld\n", sizeof(float));
printf("sizeof(int) = %ld\n", sizeof(int));
both u;
u.i = 0x00800001;
printbits(u.i);
printf("%g\n", u.f);
printf("%d %d\n", fpclassify(u.f), isnormal(u.f));
printf("\n");
u.i = 0x00800000;
printbits(u.i);
printf("%g\n", u.f);
printf("%d %d\n", fpclassify(u.f), isnormal(u.f));
printf("\n");
u.i = 0x007fffe1;
printf("%g\n", u.f);
printf("%d %d\n", fpclassify(u.f), isnormal(u.f));
printf("\n");
u.i = 0x42a98001;
printf("%g\n", u.f);
printf("%g\n", 84.75000762939453125);
printf("%d %d\n", fpclassify(u.f), isnormal(u.f));
printf("\n");
u.f = 1.17549e-38;
printbits(u.i);
printf("%#010x\n", u.i);
printf("%d %d\n", fpclassify(u.f), isnormal(u.f));
u.f = 1.1754944e-38;
printbits(u.i);
printf("%#010x\n", u.i);
printf("%d %d\n", fpclassify(u.f), isnormal(u.f));
u.f = 1.1754945e-38;
printbits(u.i);
printf("%#010x\n", u.i);
printf("%d %d\n", fpclassify(u.f), isnormal(u.f));
}
输出(在Ubuntu上,用gcc编译,处理器x86)是:
sizeof(float) = 4
sizeof(int) = 4
0 00000001 00000000000000000000001
1.17549e-38
4 1
0 00000001 00000000000000000000000
1.17549e-38
4 1
1.17549e-38
3 0
84.75
84.75
4 1
0 00000000 11111111111111111100001
0x007fffe1
3 0
0 00000001 00000000000000000000000
0x00800000
4 1