Python 数据类型:浮点数
在Python语言中,浮点数是有精度的,通常有精度缺失,这是由于浮点数是使用2进制进行计算的,如下所示:
>>> print(0.3 - 0.2) >>> print(0.3 - 0.2 == 0.1) 0.09999999999999998 False
让我们考虑十进制的 1 / 3 是 0.3333333,十进制的 2 / 3 是 0.6666666,如果两者相加只会得到 0.9999999,它不等于 1。同样,0.3、0.2 也不能用二进制准确表示您使用了多少有效数字。 分母为 5 和 2 倍数的分数只能用十进制精确表示,同样分母为 2 倍数的分数只能用二进制精确表示。 浮点数使用 IEEE 标准 754 在内部存储,该标准仅在 15-17 位有效数字范围内是正确的。
我们可以使用内置的decimal (十进制) 模块来改变精度并获得准确的结果。 getcontext().prec 可用于设置每个十进制值的精度。 默认精度为 28 位。
为什么 0.1 + 0.2 = 0.30000000000000004
?
在开始回答之前,让我们先了解一个小概念:出于计算目的,数字是如何表示的? 非常小的和非常大的数字通常以科学记数法存储,表示为:
当一个数字以科学计数法表示时,小数点前有一个非零十进制数据,该数字被标准化。例如,以科学记数法表示数字 0.0005606 :
该表示法有一个显著的特点是:前面的数字是不为0的个位数,基数是10,指数表示小数点向前(-4,负整数)或向后(正整数)移动的位数。
在计算机编程语言中,浮点数运算通常有两种表示数字的方法:单精度和双精度。 单精度使用 32 位,双精度使用 64 位进行浮点运算。与许多其他编程语言不同,JavaScript 没有定义不同类型的数字数据类型,并且始终按照国际 IEEE 754 标准将数字存储为双精度浮点数。IEEE 754标准格式以64位来存储浮点数,其中小数存储在第0-51位,值数存储在第52-62位,符号存储在第63位。
按照IEEE 754的标准,以64位来表示0.1,
第一步是将 (0.1) 基数 10 转换为其二进制等效值(基数 2)。
为此,我们将从 0.1 乘以 2 开始,并将小数点前的数字分开以获得二进制等价物。
在对 64 位重复此操作时,我们将按升序排列它们以获得我们的尾数,我们将根据双精度标准将其四舍五入为 52 位。
以科学形式表示并四舍五入到前 52 位将产生:
对于指数,我们需要使用以下公式来计算:
11表示用于指数的64位表示法的位数,-4表示科学计数法中的指数。
最终0.1按照IEEE 754的二进制表示是:
相似的,0.2按照IEEE 754的二进制表示是:
把这两个数字加和得到:
最后,0.1+0.2 的结果用二进制表示是:
这就是为啥0.1+0.2=0.30000000000000004的理由。