浮点运算-争议与思考_python_2021-07-05

1、十进制的数往往无法被二进制精确表示
2、python一般保证小数点后16位正确,从17位开始出现误差

0.1+0.1+0.1 == 0.3  --> False,  
round(.1, 1) + round(.1, 1) + round(.1, 1) == round(.3, 1)  --> False

3、限定输出位数:format(math.pi, ‘.2f’)=>‘3.14’
4、需要精确十进制表示:decimal,fractions
5、经常使用浮点运算,考虑Numpy,Scipy
6、python自带: float.as_integer_ratio(), float.hex()(以16进制保存精确值)

	>>> x = 3.14159
	>>> x.as_integer_ratio()
	(3537115888337719, 1125899906842624)
	>>> x == 3537115888337719 / 1125899906842624
	True
	
	>>> x.hex()
	'0x1.921f9f01b866ep+1'
	>>> x == float.fromhex('0x1.921f9f01b866ep+1')
	True

7、十六进制表示:由于这种表示法是精确的,它适用于跨越不同版本(平台无关)的 Python 移植数值,
以及与支持相同格式的其他语言(例如 Java 和 C99)交换数据。
8、math.fsum(),减少求和过程中的精度损失

	sum([0.1] * 10) == 1.0
	False
	math.fsum([0.1] * 10) == 1.0
	True

9、decimal, fractions举例

	>>> from decimal import Decimal
	>>> from fractions import Fraction

	>>> Fraction.from_float(0.1)
	Fraction(3602879701896397, 36028797018963968)

	>>> (0.1).as_integer_ratio()
	(3602879701896397, 36028797018963968)

	>>> Decimal.from_float(0.1)
	Decimal('0.1000000000000000055511151231257827021181583404541015625')

	>>> format(Decimal.from_float(0.1), '.17')
	'0.10000000000000001

10、要想0.1+0.1+0.1 == 0.3,有两种方式
①、事后舍入,小数点后小于17位
round(.1 + .1 + .1, 10) == round(.3, 10)
②、使用分数运算
Fraction(‘0.1’) + Fraction(‘0.1’) + Fraction(‘0.1’) == Fraction(‘0.3’)
注意:一定要加上引号,否则无法获取精确的分数

上一篇:工作中遇到很大的浮点数,导致浮点数精度错误


下一篇:C# 数值类型后缀