The floating point knowledge that every JavaScript developer should know

Source: Internet
Author: User

Some of the points in the JavaScript developer's development career will always encounter strange bugs-seemingly basic mathematical problems, but they still feel a bit wrong. One day, you will be told that the number in JavaScript is actually a floating point number. Trying to understand floating point numbers and why they are so strange, welcoming you will be a stinking and long article. The purpose of this article is to give JavaScript developers a brief description of floating point numbers. This article assumes that the reader is familiar with the decimal number expressed in binary (1 is written as 1b, 2 is 10b, 3 is 11b, 4 is 100b ...... ). In this chapter, "decimal" mainly refers to the decimal digit notation (for example, 2.718) in the computer to make the expression clearer ). "Binary" refers to the internal representation of the computer in this article. The written statement will be referred to as "base on ten" and "bottom on two" respectively ″. What is a floating point number? we started to think we have seen various numbers. I can say that 1 is an integer because it has no score. A score is called a score. This means that dividing an average score into two is a very important concept in floating point operations. 0.5 is usually called a decimal number. However, there is a very important difference that we must clarify that -- 0.5 is actually represented by the decimal (base on 10) of the score limit. In this article, we call this representation vertex notation. We call 0.5 A finite representation (a finite decimal number) because the number indicated by its score is finite-there are no other numbers after 5. It indicates the 0.3333… of the queue... Is an example of infinite representation. This idea is very important in our discussion. Another method also exists to indicate all integers, scores, or decimals. You may have seen it. It looks like this: 6.022X1023 (note: this is the number of molecules in the chemical solution of affaradro, this is the number of molecules in the molar ). It is often referred to as a standard form or scientific notation. The form can BE abstracted as follows: D1.D2D3D4... Dp x BE is a universal form called a floating point number. A sequence composed of p and D -- D1.D2D3D4... Dp -- is called a valid number or ending number. P is the weight of valid numbers, which is usually called accuracy. The x after the valid number is a part of the symbol (the multiplication symbol in this article will be represented ). The base is followed by the index. This index can be positive or negative. The advantage of floating point is that it can be used to represent any number. For example, an integer of 1 can be expressed as 1.0 × 100. The light speed can be expressed as 2.99792458x108 Mbit/s. 1/2 can be expressed as a binary format of 0.1 × 20. In the preceding example, the decimal point is still retained (the decimal point is in the number ). This poses some problems when binary is used to represent values. Given any floating point number, such as π (PI), we can represent it as a floating point number: 3.14159x100. In binary format, it looks like this: 11.00100100 001111 ...... Assume that the number is represented in a sixteen-bit machine, which means that the number is put in the machine as follows: 11001001000011111. Now the question is: where should the decimal point be placed? This does not even involve an index (our default base is 2 ). If the number is 5.14159? The integer is changed to 101 instead of 11, and an additional digit is added. Of course, we can specify that the first N digits of a field belong to the integer part (that is, the left side of the decimal point), and the rest belong to the decimal part, but that is another topic about the number of points. Once we remove the decimal point, we only have two things to record: the index and the ending number. We can remove the decimal point by applying the transformation formula to make the generalized floating point number look like this: D1D2D3D4... Dp/(Bp-1) x BE this is what we get most of the binary floating point numbers. Note that the valid number is an integer. This makes it easier to store a floating point number on a machine. In fact, the most widely used binary floating point representation method is the IEEE 754 standard. Floating Point Numbers in IEEE 754 JavaScript use the IEEE-754 format. More specifically, it is a double-precision format, which means that each floating point occupies 64 bits. Although it is not the only way to represent a floating point in binary format, it is currently the most widely used format. The format is represented in 64-bit binary format as follows: SIGNEXPONENTMANTISSA you may notice that the machine representation method is a little different from the conventional written representation. In 64-bit, one digit is used as the flag bit to indicate whether a number is a positive number or a negative number. 11 digits are used for the index-this allows the maximum index to 1024. The remaining 52 digits represent the ending number. If you are curious about why some JavaScript items such as + 0 and-0, the flag bit indicates everything-All numbers in JavaScript have a signed bit. Infinity and NaN are also encoded into floating-point numbers-2047 as a special index. If the ending number is 0, it is positive infinity or negative infinity. If not, it is NaN. The rounding error is introduced above to the floating point number. Now we have entered a more difficult problem-the rounding error. It is the root cause for all developers to use floating point numbers. This is especially true for JavaScript developers because the only available numbering format for JavaScript developers is floating point numbers. The score limit mentioned above cannot be limited at the base of 10. This actually exists in any number system. For example, in the base-two number, 1/10 cannot be limited. Expressed as 0.00110011001100110011 ...... Note that 0011 is an infinite repetition. This is because of this special quirks and rounding errors. Let's first look at an example of rounding errors. Consider the most famous irrational number, PI: 3.141592653589793 ...... Most people remember that the first five digits (3.1415) were great-we will use this example to illustrate the rounding error, so we can calculate the rounding error: (R-A)/Bp-1 ...... Here, R represents the radius of the circle, and A represents A real number. Bp indicates the accuracy based on p. So keep in mind the rounding error of PI: 0.00009265 ....... Although this seems to be not very serious, let's try to test this idea with a base-two number. The score is 1/10. In decimal, it is written 0.1. In binary, it is: 0.0011001100110011 ...... Suppose we keep only the five-digit ending number, which can be written as 0.0001. But 0.0001 is actually 1/16 (or 0.0625) in the binary representation! This means there is a rounding error of 0.0375, which is quite large. Imagine basic addition operations, such as 0.1 + 0.2. The answer is 0.2625! Fortunately, the floating point specification specifies that ECMAScript can use up to 52 tails, so the rounding error becomes very small-the specifics of the specification circumvent most of the rounding errors. The error is amplified during arithmetic operations on floating point numbers. The IEEE 754 standard also includes specific algorithms used for mathematical operations. However, it should be pointed out that, despite this, the Association attributes of arithmetic operations (such as addition, subtraction, multiplication and subtraction) cannot be ensured even if the precision is higher when processing floating point numbers. I mean, (x + y) + A + B) is not necessarily equal to (x + y) + (A + B )). This is the root of JavaScript developers. For example, in JavaScript, 0.1 + 0.2 = 0.3 returns false. I hope you understand why. Worse, in fact, rounding errors will increase (accumulate) in continuous mathematical operations ). There are already a lot of suggestions on how to handle JavaScript numbers in the design of JavaScript processing floating point numbers. Most of these suggestions are made before or after arithmetic operations. To date, I have seen few suggestions that I have stored all the operation numbers as integers (no type) and formatted them for display. An example shows how to store a large amount of cents instead of dollars in an account (I don't know what account is used as an example ). It is worth noting that not all the currencies in the world are in decimal format (Mauritius currency: Mauritius rupee is a currency in circulation in zookeeper. Value options include 25, 50, 100, 200, 500, 1000, and 2000. Unit: minute ). At the same time, I spoke about the Japanese dollar and personal currency ....... In the end, you will re-create the floating point -- it is possible. I have seen that the best advice for handling floating point numbers is to use libraries such as sinfuljs or mathjs. I personally prefer mathjs (but in fact, I don't even use JavaScript to do anything related to mathematics ). BigDecimal is also very useful when any mathematical computation of precision is required. Another suggestion that is repeated multiple times is to use the built-in toPrecision () and toFixed () methods. When using them, the most likely logical error is to forget the return value strings of these methods. So if you do not get the expected result like the following: function foo (x, y) {return x. toPrecision () + y. toPrecision ()}> foo (0.1, 0.2) "0.10.2" the built-in Methods toPrecision () and toFixed () are designed for display only. Exercise caution! Conclusion The number in JavaScript is a real floating point number. Due to the inherent defects of binary representation and limited machine space, we have to face a specification full of rounding errors. This article explains why the rounding errors are and why. Remember to use a great library instead of doing everything on your own.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.