Why is 0.1 + 0.2 not equal to 0.3?

tomee 2021-04-07 21:48:15
equal


The problem background


It's a question that's likely to be asked in an interview , After online access to a variety of information 、 Articles, etc , There are descriptions of this problem . But the details and some key points need to be carefully studied and pondered to understand . In the process of figuring out this problem, we have experienced a lot of ideological struggles , So it's still necessary to record and share your insights .

Theoretical basis


First , Be clear about all the calculations in the program , Going to the bottom of the computer is binary Computing , and , Binary computation has no concept of subtraction , The subtraction will be calculated by adding a negative number .

One more thing to note ,0.1+0.2 It's not equal to 0.3 It's not just about JavaScript in , Follow in other areas IEEE 754 This problem also exists in standard programming languages .JavaScript There is only one type for all numbers, including integers and decimals — Number. Its implementation follows  IEEE 754  standard , Use 64 Bit fixed length , That's standard double Double precision floating point ( There's more to it float 32 Bit single precision ).

Concrete realization


The whole calculation process goes through the following steps :

  1. Decimal to binary .
  2. Binary to scientific notation .
  3. Memory is used to analyze the data represented by scientific notation 、 Storage .
  4. Operations on orders .
  5. Binary addition .
  6. Rounding operation .
  7. Binary to decimal .

Decimal to binary

Back to the question itself , Let's start with how to put 0.1 Convert it to the underlying storage of the computer ,0.2 The idea of the transformation is clear . How to convert decimal to binary , Reference resources Novice tutorial that will do , No more details here .0.1 The conversion to binary is like this :

image.png

Go back and you'll find , This process is an infinite loop state . Never mind that , Write it down first :

0.00011(0011)…

Binary to scientific notation

Next, should we deal with infinite loops ? Not at all , We know , In everyday decimal operations , We want to represent as much data as possible , Will use scientific notation . The same goes for the bottom layer of the computer , As we mentioned earlier ,JavaScript In order to double precision storage Number type , Therefore, if the data is converted to binary and stored directly , So the maximum number it can store is 263( The first bit is the sign bit ), In today's data age , This computable range is quite limited . therefore , Binary data should also be converted into scientific notation , Then the scientific notation is stored in parts :

1.1(0011)… * 2-4( Move the decimal point to the right 4 position , The base of binary is 2)

Binary representation of scientific notation data

OK, The next question is , The computer 64 How do bits store scientific notation ?

image.png

This icon shows 64 Bit binary different parts of the stored data label . First , The highest bit is the sign bit , So it can't participate in the task of storing data , The subsequent 11 position ( Index part ) Binary number used to store the index in scientific notation , remainder 52 position ( Mantissa part ) It is used to store the decimal point of mantissa in scientific notation 52 position . The sign bits and mantissa of these three parts are very clear , Sign bit 0 It means a positive number ,1 A negative number ; The mantissa part of science is just the mantissa part 52 position ; The determination of the index part is a little more complicated .

Memory gives 11 Bit binary gives exponent , therefore ,11 If bit binary is converted to decimal , The range of data that can be stored is :[0, 211], namely [0, 2048]. But there's a problem , The index can also be negative ! How do negative numbers mean ? Don't 11 The bit has to give up another bit to represent the sign bit ? Not at all , In this part of the processing ,IEEE754 The standard index is 0 The cardinal number of is 1023( With 1023 As the dividing line between positive and negative numbers ), It's equivalent to being able to store [-1023, 1024] The number of this range . therefore , With 0.1 Take the index converted to scientific notation as an example , Index -4 Will be converted into 1023 - 4 = 1019, And then convert it to binary : image.png

1019 It's converted to binary :1111111011. therefore ,0.1 Before the final binary 12 Position as :

001111111011

Next , The mantissa is reserved for 52 position , What about infinite loops ? It's time to Rounding operation , follow 0 House 1 The principle of entry ( It is similar to the meaning of rounding in decimal system ), This is also the key point of this issue , Rounding makes the data lose some precision .

You may wonder , A simple calculation can lead to the deviation of the calculation results , So is the result of a slightly more complex operation reliable ? Of course it's reliable . firstly , It's rare to see an infinite loop in such a transformation , Even if there is , The double precision storage provided by the computer can also ensure that the data operation is within the allowable error range ; second , The bottom layer of the computer has a processing mechanism for precision error calculation , Calculation will not be allowed to go further and further on the road of deviation .

0.1 The final binary form is like this :

0 01111111011 1001100110011001100110011001100110011001100110011010

0.2 The binary storage of is :

0 01111111100 1001100110011001100110011001100110011001100110011010

Operations on orders

The next step is to do the addition , Binary addition is not difficult , It's like the decimal system . But it's not easy , Before we will 0.1 and 0.2 When it comes to scientific notation , We found that 0.1 My index is -4,0.2 My index is -3. If you want to express the results of their operations in a scientific way , We have to unify the exponents and then extract the common factor for calculation . Here's a question Operations on orders , To minimize the loss of accuracy , We need to follow the small order to the large order ( That is, to convert a smaller index into a larger one ) Principles . In this case , We need to unify the index into -3. therefore ,0.1 After the operation of the order of the binary , That's true :

0 01111111100 (0.)1100110011001100110011001100110011001100110011001101.

The mantissa needs to be shifted one bit to the right , Move the excess right to round . The integer part omitted by default 1 It's moved to the decimal part , So the integral part becomes 0.

Binary addition

Next, when you do the addition , To complete the integer part omitted before the mantissa , Because when there is carry , The integral part can change , This is also to facilitate the subsequent adjustment of the calculation results .

The result of adding mantissa is :

10.0110011001100110011001100110011001100110011001100111

image.png

Rounding operation

There are two problems with this result :

  1. It doesn't conform to the rules of scientific notation .
  2. The mantissa part exceeds the number of digits .

So adjust the results , First, change the result to “1.” At the beginning , The decimal point is shifted one place to the left , become :

1.00110011001100110011001100110011001100110011001100111

meanwhile , Add the index to 1: become :

01111111101

Last , Still based on 0 House 1 The principle of entry , Put the mantissa part beyond 52 The part outside the bit is rounded , The result is :

1.0011001100110011001100110011001100110011001100110100

therefore , The complete result is :

0 11111111101 (1.)0011001100110011001100110011001100110011001100110100

Binary to decimal

Converting to decimal is :

0.30000000000000004

thus , All the steps and detailed analysis of this problem have come to an end .

summary


  1. JavaScript Decimals are at the bottom of the computer with double precision ( namely 64 position ) How to store .
  2. There are many precision losses in the whole process : Operations on orders 、 Addition operation .
  3. The loss of precision is essentially the result of rounding operations , When it comes to rounding operations, we have to follow 0 House 1 The principle of entry .
版权声明
本文为[tomee]所创,转载请带上原文链接,感谢
https://qdmana.com/2021/04/20210407213623157f.html

  1. Element tree control: invalid to modify current node key
  2. linux下安装apache(httpd-2.4.3版本)各种坑
  3. How to install Apache (httpd-2.4.3) under Linux
  4. 程序员业余时间写的代码也算公司的?Nginx之父被捕引发争议
  5. Nacos serialize for class [com.alibaba.nacos.common.http.HttpRestResult] failed.
  6. Do programmers write code in their spare time? Controversy over the arrest of nginx's father
  7. Nacos serialize for class [ com.alibaba.nacos . common.http.HttpRestResult ] failed.
  8. Seamless management of API documents using eolink and gitlab
  9. vue 的基础应用(上)
  10. 28岁开始零基础学前端,这些血的教训你一定要避免
  11. Basic application of Vue
  12. Starting at the age of 28, you must avoid these bloody lessons
  13. Ubuntu 16.04 can not connect to the wireless solution and QQ installation
  14. Industry security experts talk about the rapid development of digital economy, how to guarantee the security of data elements?
  15. 利用Vue实现一个简单的购物车功能
  16. Behind the "tireless classroom" and teacher training, can byte education really "work wonders"?
  17. Using Vue to realize a simple shopping cart function
  18. 【css】伪类和伪类元素的区别
  19. 【css效果】实现简单的下拉菜单
  20. 【vue】父子组件传值
  21. The difference between pseudo class and pseudo class elements
  22. [CSS effect] simple drop-down menu
  23. [Vue] value transfer by parent-child component
  24. 【css】设置table表格边框样式
  25. 【css】修改input,textarea中的placeholder样式
  26. vue-router的两种模式(hash和history)及区别
  27. CSS3的滤镜filter属性
  28. [CSS] set table border style
  29. [CSS] modify the placeholder style in input and textarea
  30. Two modes of Vue router (hash and History) and their differences
  31. Filter property of CSS3
  32. 全局安装gulp 报错问题解决
  33. Solution of error report in global installation of gulp
  34. 18个好用的自定义react hook
  35. 你应该知道的常用服务器HTTP状态码?
  36. 18 user defined react hooks
  37. What HTTP status codes should you know about common servers?
  38. 手把手教你打造属于自己团队的前端小报系统
  39. Hand in hand to teach you to build your own front-end tabloid system
  40. In 2021, enterprise SEO actual operation, how to less update, batch ranking regional words?
  41. vue cli4.0 快速搭建项目详解
  42. Vue cli4.0 quick build project
  43. vue-cli脚手架安装
  44. Installation of Vue cli scaffold
  45. [JS knowledge] method of getting elements from DOM
  46. 【jQuery效果】文字滚动
  47. [jQuery effect] text scrolling
  48. [front end] live broadcast of user experience optimization series, real-life sharing of front-line celebrities
  49. React native introduces third party Android SDK
  50. Using html2canvas to generate shared images, CDN images do not show the problem
  51. Using hooks to write react components
  52. Explain the module hot replacement function of webpack in detail
  53. An incomplete guide to writing a simple native wechat applet
  54. How JavaScript calculates 1 + 1 - Part 1 creates a source string
  55. Jsonp method to solve cross domain problems
  56. Canvas animation demo (from zero to one)
  57. El dialog of elementui component encapsulation
  58. Transition group of Vue source code
  59. When encountering bracket validity, next larger element, specific minimum value, try stack
  60. Vue3 virtual DOM