为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

新闻 前端
打开你的 Python,输入「0.1+0.2=」,结果是多少?0.30000000000000004 对不对?为什么结果不是 0.3?本文作者给出了详细的解释。

 打开你的 Python,输入「0.1+0.2=」,结果是多少?0.30000000000000004 对不对?为什么结果不是 0.3?本文作者给出了详细的解释。

从小我们就知道 0.1 + 0.2=0.3。但是,在光怪陆离的计算世界中,运算方式却大相径庭。

 

我最近开始用 JavaScript 进行编码,在阅读数据类型时,我注意到 0.1 + 0.2 不等于 0.3 的奇怪行为。我向 Stack Overflow 寻求帮助,在上面找到了一些有用的帖子。如下图所示:

 

为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

 

Stack Overflow 界面图像。

 

 

经过大量的研究和数学运算后,我得出结论,这不是错误。这是数学运算中的浮点运算。让我们进一步了解内在机制。

 

 

问题描述: 为什么 0.1 + 0.2 = 0.30000000000000004?

 

 

如果你用 Java 或 C 语言编过程,那你一定知道用于存储值的不同数据类型。我们在前面的讨论中将考虑两种数据类型:整数型和浮点型。

 

 

整数型存储整数,而浮点型存储小数。

 

 

在这之前,我们先来了解一个小概念:为了实现计算,数字是如何表示的?极小数和极大数通常用科学计数法表示,即:
 
为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

 

 

同样,如果一个用科学计数法书写的数字小数点前有一个非零的十进制数,则该数字是标准化写法。例如,0.0005606 用科学计数法的标准化写法为:

 

 

为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

 

 

Significant 是指不包含零的有效数字,base 表示所使用的进制——此处为十进制(10)。Exponent(指数)表示小数点需要向左或向右移动的步数。

 

 

现在,有两种显示浮点数的方法:单精度和双精度。在进行浮点运算时,单精度使用 32 位,而双精度使用 64 位。

 

 

与许多其他编程语言不同,JavaScript 并未定义不同类型的数字数据类型,而是始终遵循国际 IEEE 754 标准,将数字存储为双精度浮点数。

 

 

这种格式以 64 位存储数字,其中数字(分数)存储在位 0 到 51 中,指数存储在位 52 到 62 中,符号存储在位 63 中。

 

 

为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

 

IEEE754 双精度标准。

 

 

我们按 IEEE754 标准用 64 位表示 0.1。第一步是将十进制的 0.1 转换为二进制的 0.1。首先将 0.1 乘以 2,然后将小数点前的数字分离出来,得到其相应的二进制数。
 
为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

 

 

重复此操作至 64 位。然后把它们按升序排列,获取尾数,再根据双精度标准,我们将把其四舍五入到 52 位。
为什么0.1+0.2不等于0.3?原来编程语言是这么算的……
尾数

 

 

用科学计数法表示二进制 0.1 并只保留前 52 位:
为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

 

 

尾数部分处理好后。现在我们用下面的方式处理指数:
为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

 

 

这里,11 代表我们要使用的 64 位表示的指数位数,-4 代表科学计数中的指数。

 

 

所以最终数字 0.1 的表示形式是:

 

 

 
为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

 

 

同理,0.2 表示为:

 

 

 为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

 

 

将两个数相加,得到:

 

 

 为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

 

转换为浮点数,它变成:
 
为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

 

这就是 0.1 + 0.2 = 0.30000000000000004 的原因。

 

责任编辑:张燕妮 来源: 机器之心
相关推荐

2023-11-08 13:32:00

JavaScript浮点数计算

2024-08-23 08:43:08

2020-10-12 13:27:21

计算机浏览器电脑

2023-05-16 17:42:04

浮点加法Python

2023-06-02 13:53:56

2017-06-29 08:45:06

MySQLNOT INNOT EXISTS

2012-02-03 14:39:12

Java

2015-08-12 10:04:24

2021-10-29 22:49:57

JavaScript开发精度

2021-09-06 15:29:16

大数据防疫信息安全

2010-04-28 14:38:26

云计算

2019-08-27 08:43:15

2010-10-18 10:51:00

苹果

2013-01-15 09:41:45

编程语言

2022-07-26 23:43:29

编程语言开发Java

2023-03-07 07:45:28

2019-03-15 10:55:12

通信系统手机

2011-08-08 09:59:35

Android

2022-05-13 23:35:19

Java编程语言开发

2010-07-19 11:12:43

Perl 不等于
点赞
收藏

51CTO技术栈公众号