为什么说有的浮点数无法精确的表示呢?

时间:2023-01-08 08:35:25
为什么说有的浮点数无法精确的表示呢?

比如存储10进制 0.1,为什么无法保证每一台机子对其存储的值不一样呢?

0.1

0.2 0 0.2
0.4 0 0.4
0.8 0 0.8
1.6 1 0.6
1.2 1 0.2
0.4 0 0.4
0.8 0 0.8
1.6 1 0.6
1.2 1 0.2

二进制:
0.0001 1001 1001 1001 .... 1001

1.1001 1001 1001...1001*2^-4

符号位:0
阶码:-4+127=123 0111 1011

0011 1101 1100 1100 1100 1100 1100 1101
 
3 d c c c c c c

即:0x3d cc  cc cc

每一台机子里的值都是0x3d cc cc cc

不都一样吗?
不是吗








12 个解决方案

#1


浮点数结构,可以看IEEE754

#2


引用 1 楼 luciferisnotsatan 的回复:
浮点数结构,可以看IEEE754


我已经按照这个标准手工求解出结果来了

#3


引用 1 楼 luciferisnotsatan 的回复:
浮点数结构,可以看IEEE754


float val=0.1f;
printf("0x%x",val);
return 0;

0xa0000000请按任意键继续. . .

的结果和内存中观察的结果不一致啊

#4


1.1 - 1.0 和 2.1 - 2.0 是否一致,然后3.1,4.1等等?浮点数是要用来计算的。

#5


引用 3 楼 combobox2013 的回复:
引用 1 楼 luciferisnotsatan 的回复:浮点数结构,可以看IEEE754

float val=0.1f;
printf("0x%x",val);
return 0;

0xa0000000请按任意键继续. . .

的结果和内存中观察的结果不一致啊

float给push到printf的堆栈的时候会转成double……你看到的是(double)0.1的高32位或者低32位……

#6


赵老师说过,十进制小数无法精确表示 三分之一,
同理,二进制小数也无法精确表示 十分之一。

#7


引用 6 楼 Athenacle_ 的回复:
赵老师说过,十进制小数无法精确表示 三分之一,
同理,二进制小数也无法精确表示 十分之一。

用10进制小数不能精确表示某些三进制小数0.1(3)=0.33333333333……(10)
同理,用二进制小数也不能精确表示某些10进制小数。

#8


引用 5 楼 FancyMouse 的回复:
引用 3 楼 combobox2013 的回复:引用 1 楼 luciferisnotsatan 的回复:浮点数结构,可以看IEEE754

float val=0.1f;
printf("0x%x",val);
return 0;

0xa0000000请按任意键继续. . .

的结果和内存中观察的结果不一致啊
float给push到printf的堆……


按照这个说法,printf打印float浮点数 的十六进制, 岂不是很危险,结果显示是错误的,因为已经被push了
double了.
还有printf一个doulbe的十六进制也是错误的, 只有低4个字节可以打印。

如何解决呢?

spritnf也解决不了打印一个浮点数的十六进制



#9


比如存储10进制0.1,为什么无法保证每一台机子对其存储的值不一样呢?
如果说每台机器存贮浮点数的格式都是iee754,这个说法显然是错的,必然是一样的

#10


引用 9 楼 nice_cxf 的回复:
比如存储10进制0.1,为什么无法保证每一台机子对其存储的值不一样呢?
如果说每台机器存贮浮点数的格式都是iee754,这个说法显然是错的,必然是一样的


那为什么 6楼,7楼,说无法精确的表示, 而且这种答案,很多帖子里都复制粘贴过去。

计算机里的数字都一样,他们想什么呢
为什么说有的浮点数无法精确的表示呢?

#11


引用 10 楼 zrdongjiao 的回复:
引用 9 楼 nice_cxf 的回复:比如存储10进制0.1,为什么无法保证每一台机子对其存储的值不一样呢?
如果说每台机器存贮浮点数的格式都是iee754,这个说法显然是错的,必然是一样的

那为什么 6楼,7楼,说无法精确的表示, 而且这种答案,很多帖子里都复制粘贴过去。

计算机里的数字都一样,他们想什么呢

无法精确表示和不同机器值不一样不是一回事,很多数的确是无法精确表示,你可以自己查一下iee754格式

#12


引用 8 楼 zrdongjiao 的回复:
引用 5 楼 FancyMouse 的回复:引用 3 楼 combobox2013 的回复:引用 1 楼 luciferisnotsatan 的回复:浮点数结构,可以看IEEE754

float val=0.1f;
printf("0x%x",val);
return 0;

0xa0000000请按任意键继续. . .

的结果和内存中观察的结果不一致……

printf看到%f也是当做double打印的。也就是说printf不区分%f和%lf。scanf是区分的。

>按照这个说法,printf打印float浮点数 的十六进制, 岂不是很危险,结果显示是错误的,因为已经被push了
double了


你的情况需要printf("%x", *(int*)(&val));

#1


浮点数结构,可以看IEEE754

#2


引用 1 楼 luciferisnotsatan 的回复:
浮点数结构,可以看IEEE754


我已经按照这个标准手工求解出结果来了

#3


引用 1 楼 luciferisnotsatan 的回复:
浮点数结构,可以看IEEE754


float val=0.1f;
printf("0x%x",val);
return 0;

0xa0000000请按任意键继续. . .

的结果和内存中观察的结果不一致啊

#4


1.1 - 1.0 和 2.1 - 2.0 是否一致,然后3.1,4.1等等?浮点数是要用来计算的。

#5


引用 3 楼 combobox2013 的回复:
引用 1 楼 luciferisnotsatan 的回复:浮点数结构,可以看IEEE754

float val=0.1f;
printf("0x%x",val);
return 0;

0xa0000000请按任意键继续. . .

的结果和内存中观察的结果不一致啊

float给push到printf的堆栈的时候会转成double……你看到的是(double)0.1的高32位或者低32位……

#6


赵老师说过,十进制小数无法精确表示 三分之一,
同理,二进制小数也无法精确表示 十分之一。

#7


引用 6 楼 Athenacle_ 的回复:
赵老师说过,十进制小数无法精确表示 三分之一,
同理,二进制小数也无法精确表示 十分之一。

用10进制小数不能精确表示某些三进制小数0.1(3)=0.33333333333……(10)
同理,用二进制小数也不能精确表示某些10进制小数。

#8


引用 5 楼 FancyMouse 的回复:
引用 3 楼 combobox2013 的回复:引用 1 楼 luciferisnotsatan 的回复:浮点数结构,可以看IEEE754

float val=0.1f;
printf("0x%x",val);
return 0;

0xa0000000请按任意键继续. . .

的结果和内存中观察的结果不一致啊
float给push到printf的堆……


按照这个说法,printf打印float浮点数 的十六进制, 岂不是很危险,结果显示是错误的,因为已经被push了
double了.
还有printf一个doulbe的十六进制也是错误的, 只有低4个字节可以打印。

如何解决呢?

spritnf也解决不了打印一个浮点数的十六进制



#9


比如存储10进制0.1,为什么无法保证每一台机子对其存储的值不一样呢?
如果说每台机器存贮浮点数的格式都是iee754,这个说法显然是错的,必然是一样的

#10


引用 9 楼 nice_cxf 的回复:
比如存储10进制0.1,为什么无法保证每一台机子对其存储的值不一样呢?
如果说每台机器存贮浮点数的格式都是iee754,这个说法显然是错的,必然是一样的


那为什么 6楼,7楼,说无法精确的表示, 而且这种答案,很多帖子里都复制粘贴过去。

计算机里的数字都一样,他们想什么呢
为什么说有的浮点数无法精确的表示呢?

#11


引用 10 楼 zrdongjiao 的回复:
引用 9 楼 nice_cxf 的回复:比如存储10进制0.1,为什么无法保证每一台机子对其存储的值不一样呢?
如果说每台机器存贮浮点数的格式都是iee754,这个说法显然是错的,必然是一样的

那为什么 6楼,7楼,说无法精确的表示, 而且这种答案,很多帖子里都复制粘贴过去。

计算机里的数字都一样,他们想什么呢

无法精确表示和不同机器值不一样不是一回事,很多数的确是无法精确表示,你可以自己查一下iee754格式

#12


引用 8 楼 zrdongjiao 的回复:
引用 5 楼 FancyMouse 的回复:引用 3 楼 combobox2013 的回复:引用 1 楼 luciferisnotsatan 的回复:浮点数结构,可以看IEEE754

float val=0.1f;
printf("0x%x",val);
return 0;

0xa0000000请按任意键继续. . .

的结果和内存中观察的结果不一致……

printf看到%f也是当做double打印的。也就是说printf不区分%f和%lf。scanf是区分的。

>按照这个说法,printf打印float浮点数 的十六进制, 岂不是很危险,结果显示是错误的,因为已经被push了
double了


你的情况需要printf("%x", *(int*)(&val));