浮点数相比定点数或者整数,为了处理小数点引入了指数,导致小数点的位置根据不同浮点数而不同,故名为Floating Point Number. 一般而言,IEEE754标准被大部分编程语言的浮点数使用,它节省了浮点数的保存空间。如不然,浮点数可能按每一位ASCII码保存,包括整数部分、小数点和小数部分,占用空间不可控制。
小数点位置浮动的原因
浮点数整数部分长度不一,为了统一整数部分和指数部分,把所有整数都转换成0.xx格式,造成小数点位置不一。
浮点数和整数
- 浮点数的位级存储和整数完全不同,整数1和浮点数1.0存储也截然不同。通过调试器查看int变量和float变量的内存存储,或者写一段dump字节代码比较其区别,还有一种方式,C/C++ %a格式串可用十六进制形式表达浮点数(其他编程语言可能不适用)。
- 不同浮点数位级存储也不相同,float和double是不同的。
- 浮点数和整数运算,整数会默认先转换成浮点数。
f = f + i;
cvtsi2ss xmm0,dword ptr [i]
addss xmm0,dword ptr [f]
movss dword ptr [f],xmm0
浮点数指令
早期计算机根本没有浮点数处理ALU,浮点数靠软件整数去模拟,性能极低。后来,加入了浮点数FPU,浮点数处理速度极大提升,比如xmm寄存器。
- double f = 2.25; // IEEE 754内存存储
- 00501056 movsd xmm0,mmword ptr [__real@4002000000000000 (0502108h)]
精确性
浮点数的表达方式利用整数位和小数位计算的2n数值(n可正可负)计算,必然出现不准确。1.5可精确表示,0.3却无法精确表示。有的书籍上提到,浮点数不要用==或!=判断,其实是考虑有不精确表达的可能。在商业银行金融领域,这是不能容忍的。
- COBOL编程语言是上古时期可以处理小数精确度很好的一门语言,因为它真的用模拟的形式保存小数点和小数位,而非IEEE 754这种压缩版。
- C#引入了decimal类型处理小数点更精确。如下两种不同类型变量输出的结果第一个会更精确。
decimal d = 3.14159265124m;
float f = 3.14159265123f;
浮点数的类型
尽管4字节的浮点数可表达相当大的数值,但对于人类而言,总不够用。一般而言,浮点数有3种类型,单精度的float和双精度的double以及更长的long double, 可参考:数据类型大小
- C语言为了区分float和double, 输入时用%f代表float, %lf代表double, 但对于输出%f和%lf作用相同。
- C语言中float类型是默认转换成double去处理,如下图所示。
- C99引入了long double (%Lf), 注意并不意味long double一定比double要长,根据编译器选择。
微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。
我是程序员小迷(致力于C、C++、Java、Kotlin、Android、iOS、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。
欢迎关注。助您在编程路上越走越好!