float 浮点型底层存储原理

float 浮点型底层存储原理




“0.1 + 0.2 到底等于几?”

>>> 0.1 + 0.2
0.30000000000000004
>>> 39.29 + 0.3
39.589999999999996
>>> 0.2 + 0.3
0.5

常用的编程语言,其中的小数都是默认的 float 浮点型,而 float 浮点型的内部存储机制会导致其有时候不精准。


十进制转二进制

39.29 转换为二进制过程:

  1. 整数部分直接转成二进制。39 直接转换为 100111
  2. 小数部分转换:让小数一直乘以 2,小于 1 则用结果继续乘,大于 1 则结果减 1 继续乘,等于1 则结束。
0.29 * 2 = 0.58	# 小于1,则继续乘
0.58 * 2 = 1.16	# 大于1,则减1继续乘
0.16 * 2 = 0.32	# 小于1,则继续乘
0.32 * 2 = 0.64	# 小于1,则继续乘
0.64 * 2 = 1.28	# 大于1,则减1继续乘
0.28 * 2 = 0.56	# 小于1,则继续乘
0.56 * 2 = 1.12	# 大于1,则减1继续乘
0.12 * 2 = 0.24	# 小于1,则继续乘
0.24 * 2 = 0.48	# 小于1,则继续乘
0.48 * 2 = 0.96	# 小于1,则继续乘
0.96 * 2 = 1.92	# 大于1,则减1继续乘
0.92 * 2 = 1.84	# 大于1,则减1继续乘
0.84 * 2 = 1.68	# 大于1,则减1继续乘
0.68 * 2 = 1.36	# 大于1,则减1继续乘
0.36 * 2 = 0.72	# 小于1,则继续乘
0.72 * 2 = 1.44	# 大于1,则减1继续乘
0.44 * 2 = 0.88	# 小于1,则继续乘
0.88 * 2 = 1.76	# 大于1,则减1继续乘
0.76 * 2 = 1.52	# 大于1,则减1继续乘
0.52 * 2 = 1.04	# 大于1,则减1继续乘
0.04 * 2 = 0.08	# 小于1,则继续乘
0.08 * 2 = 0.16	# 小于1,则继续乘
0.16 * 2 = 0.32	# 小于1,则继续乘(与第三行相同,这样会一直循环执行下去)
。。。
将相乘之后的结果的整数部分拼接起来,所以0.29 的二进制表示:01001010001111010111000...

科学计数法

39.29科学计数法表示:

  • 10111.01001010001111010111000…
  • 1.011101001010001111010111000…* 2^5

1.011101001010001111010111000…* 2^5
在这里插入图片描述

  • sign,用1位来表示浮点数正负,0表示正数;1表示负数。
  • exponent,用8位表示二进制的科学计数法中的指数部分的值,8位表示的数据范围可以是0~255,但是由于指数部分可能为负数,所以这个指数的范围为-128~127。再计算时让【指数+127】得到值转换为二进制存储在此即可。注:0.5375的二进制小数位0.10001,科学计数法为 1.0001 * 2^-1。
  • fraction,用32为来表示二进制小数的科学计数法中的小数部分(不管整数部分,因为科学计数法中的整数总是为 1)。
  • sign = 0,浮点数为正数。
  • exponent = 01000010,指数 5 + 127 = 132,将132转换为二进制。
  • fraction = 00111010010100011110101,最多保留32为二进制小数位,其他省略(不精确)。
  • 所以,最终39.25在存储时的二进制为:0 01000010 00111010010100011110101

当我们开发的程序里用到的小数需要是精准的,一定不能是 float,需要用 Decimal 类库,各个语言都有相应的库。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值