一道C的编程疑惑

来源:百度知道 编辑:UC知道 时间:2024/07/13 02:42:25
#include <stdio.h>
void main ()
{
float a,b;
a=123456.789e5;
b=a+20;
printf("%f\n%f",a,b);
}
理论值是12345678920
在VC运行结果是12345678848 12345678868;
在TC运行结果是12345678848 12345678848;
末尾三位数怎么来的?
我知道是数据太大溢出了。但我想知道末尾三位数为什么是848而不是别的数字呢?怎么得出848的?

848其实还是有规律的,并不市随机溢出数.确定了一个编译器后,这个数是不会因为你执行2,3次会发生改变.你自己可以运行验证一下,确定的溢出数,每次的结果是一样的.
那为什么会在不同编译器上运行会得出不一样的结果?其实由于浮点数不是直接存在计算机上的,它是要按照固定的格式(也可以认为就是一个转换公式)进行转换后才存储的.我们知道一般而言,数据在内存或硬盘存储时,是一个字节或每8位作为基本单位的.可有趣的是,浮点就不是这样,举个形象但不准确的例子:表示123,存在4个字节中(float宽度),它的存储形式类似于:0000,0001,2300,0000...
是跨字节的.因此在保留小数位时由于4舍5入关系(2进制的4舍5入),会得到令你疑惑的848这样的值.
因此,奇怪的值是由浮点转换公式及4舍5入双重作用引起的,而且每个编译器所使用的2进制4舍5入机制可能不同,才会出现你现在的提问.有兴趣你可以找本书来研究下浮点转换格式,挺有意思的,不过也有点复杂!!

换成double

这是随机产生的数据。如果能知道后三位数那就不叫溢出了。

这个问题还真是挺麻烦的
首先浮点数必须转成
1.23456789e10
0.23456789被近似转换成16进制,而16进制小数没有办法表示精度到你的0.234568900,它只能近似到0.2345678848。因为二进制0.1是十进制0.5,二进制0.01是0.25,。。。以此类推。这就是为什么你看到的是0.2345678848,所以问题不是你的数字太大溢出了,而是你的数字太精确,单精度浮点表示不了。而且我用vc编译结果a和b输出都是12345678848 不知道你那你是怎么回事,原因很简单,单精度浮点已经精确不到0.00000001了,只能精确到0.0000000596左右,所以你加上20,大约是加在0.0000000020这样子,所以达不到这个精度就舍去了

你换一台机器试试,肯定不相同,那是因为内存本身的型号,和属性决定的,不同的内存会以不同的规律,来决定溢出位的值。

精而简的回答:

如果程序数据溢出的话..
或者变量没有被赋值..
那么该部分的数据是随机的..