看下面的内容之前,你要先看过这篇文章或者类似的文章
浮点数在计算机中的存储方式:
https://www.cnblogs.com/wuyuan2011woaini/p/4105765.html
float类型的浮点数的存储格式使用的是 IEEE 的 R32.24 标准
就是 1位符号位,8位指数位,23位尾数位
那么如何得到最大值呢?
在计算机中不是1就是0
1 大于 0
全 1 就是最大了
那就这样
0 11111111 11111111111111111111111 # 最大
符号位是0,表示这是一个正数
“元数据+127:大概是指“指数”从00000000开始(表示-127)至11111111(表示+128)”
就是说指数部分的这个 11111111,表示的其实是 128
“任何一个数的科学计数法表示都为1. xxx * 2n ,尾数部分就可以表示为xxxx,由于第一位都是1嘛,干嘛还要表示呀?所以将小数点前面的1省略。”
所以上面那个值就可以写成这样
1.11111111111111111111111 * 2^128 # 小数点后面有23个1
这个写法可能不方便理解,不方便之后的计算,换成下面这样的写法,不使用科学记数法
# 24个1,105个0
111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
这个就是最大值,但是这是二进制形式的,要转换成十进制才更方便理解
怎么转呢?这就是另外一个问题了
二进制转十进制,自己百度
但是嘛,就是你会转换,这个规模的数字也不应该人工进行转换
现在用我们的python来转换
$ cat main.py
#!/usr/bin/env python
#coding=utf-8
#number = '1110'
number = '111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
number_len = len(number)
result = 0
for i in range(number_len):
if number[number_len - i - 1] == '1':
result += 2**i
print(result)
print(f'{result:e}')
$ ./main.py
680564693277057719623408366969033850880
6.805647e+38
$
这么一长串的二进制转成十进制是 680564693277057719623408366969033850880
科学记数法表示成 6.805647e+38
这个明显不是最大值,因为你题目中说最大值是 3.40E+38 (-3.40E+38 ~ +3.40E+38)
问题的原因是浮点数中有两个特殊值 INF 和 NAN
确实是两个,IND其实就是NAN,他们是一回事,不同的环境可能会选NAN,也可能选IND
不管怎么说,他们是完全一样的,都是一回事
INF IND NAN 参考下面的文章
https://www.cnblogs.com/Malphite/p/12068991.html
https://www.thinbug.com/q/15288406
“
阶码全1,尾数全0表示无穷大INF。例如1.0/0.0
阶码全1,尾数非全0的表示无效数NaN。例如:求负数的平方根,例如0.0/0.0。
”
也就是说 指数部分不能全1,全1已经给这两个特殊值占用了
那就让 11111111 减 1,就是去掉这两个特殊值后的最大值
0 11111110 11111111111111111111111 # 最大
没错,这里是127,之前是128
1.11111111111111111111111 * 2^127 # 小数点后面有23个1
# 24个1,104个0
111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
现在,再让咱们的python算一下这个十进制是多少
$ cat main.py
#!/usr/bin/env python
#coding=utf-8
#number = '1110'
number = '11111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
number_len = len(number)
result = 0
for i in range(number_len):
if number[number_len - i - 1] == '1':
result += 2**i
print(result)
print(f'{result:e}')
$ ./main.py
340282346638528859811704183484516925440
3.402823e+38
$
这一次算出的结果是 340282346638528859811704183484516925440
科学记数法表示成 3.402823e+38
这个就是float的最大值
最小值?
简单,前面加上一个负号就是了
所以float的取值范围就是
-340282346638528859811704183484516925440 ~ 340282346638528859811704183484516925440
科学记数法就表示成
-3.402823e+38 ~ 3.402823e+38