Javascript numeric Problems

Source: Internet
Author: User
If you are a Web developer, You should have written such JavaScript code that accepts user input:


     <input type="text" name="age" onchange="return (this.value>0)">

On the surface, this line of code does not have any problems, but after running for a while, it is found that it occasionally strikes inexplicably.

The problem with this line of code is that the user does not necessarily enter a standard age integer. He may enter "23.5" or "23 ". The correct method is to add some conversion processes, such:


     <input type="text" name="age" onchange="return parseFloat( this.value)">

JavaScript is a scripting language. One of its design goals is to simplify its use as much as possible. Therefore, it is extremely flexible to process strings and values. Many operations are performed implicitly without developer intervention. To which extent is it flexible? Are traps hidden under high flexibility and automation? Can I define an array with 3.5 elements? 1. Must 1000000 be equal to 1000001 instead of 1.000E6? How can I ensure that this value is correctly displayed?

We know that many browsers have numerical processing bugs in the past. Can we leave it easy or be careful? This article introduces the numeric processing restrictions of the script engine, mainly for popular browsers, including IE at or above 5.x, Netscape at or above 4.7x, and Mozilla at 1.x. After reading this article, you will know which numeric operations are safe and which operations are insecure in the browser.

One explanation: science is to describe the real world.

On the surface, numerical values are easy to understand. The most common numeric types are integers and real numbers. You must be familiar with them. Simple examples include 2 and 23.45, but there are also complex examples, such as the result of the largest Mason prime number search on the Internet has more than 4 million digits. We know that PI (circumference rate) is an infinitely non-repeating decimal number. How can we write a PI value higher than 3.141592654 accuracy? In a word, you cannot do it at all.

Whether using paper to record the value or using a computer to record the value, a certain encoding scheme must be used to express the value. It must be understood that the value expressed by encoding is not a numerical value, but a human or computer-understandable description of the value. Any encoding scheme has its own limitations, either the limitation on the Expression range (accuracy) or other complexity constraints. For example, is "2" an integer or a real number? Or are both of them?

From the mathematics class, we know that the number of cycles can be expressed by a period. For example, we don't have to write 1.9999 ...... (There are countless 9 s added later), as long as you write 1.9 and then add a vertex on 9. In addition, we know that the "cycle at" is actually equal to 2, because 1 + (0.90.09 + 0.009 + ...) The Convergence limit is 2. That is to say, there are two expressions for the same value "2. If it is 2.0000, there are three expressions. Therefore, not every value only has a unique expression, even if it is written on paper! In this way, it is inconvenient or even unacceptable to process the value!

Two sets of standards: simplified and traditional compromise

Scientific theories are wonderful, but in real life it is impossible (and not necessary) to strictly adhere to the precision of scientific theories. What should we do? Establish engineering standards. For example, the IEEE 754 standard binary floating point algorithm (www.ieee.org) is a standard for computer encoding of real numbers.

JavaScript numeric processing is based on such standards. According to the JavaScript standard of ECMA, the Number type is the double precision value of IEEE 754. The perfect numerical encoding scheme does not exist. For the convenience of processing, this standard introduces a lot of trade-offs and compromises. The same is true for algorithms based on this expression (such as Division operations. Because the numeric expression has a "defect", the calculation results inevitably pile up more and more errors-in most cases, such errors will not cause problems, but this does not mean you can ignore them completely, see the following two examples:

(1) the IEEE 754 Division Error once caused Intel's Pentium to pay a high price. Later, Intel had to apologize publicly for the chip BUG released, with a total loss of about $0.5 billion.

(2) The daily interest calculation inevitably involves floating point operations. No one is willing to pay more interest or reduce income due to calculation problems. Therefore, the numerical standards must be accurate enough.

The floating point number stored in the IEEE 754 format has the same precision as the decimal number with 15, 16, or 17 decimal places. Due to the binary and decimal conversion problems, the specific digits will change. To obtain the highest conversion accuracy, you must specify 17 decimal places-in this case, you can trust the accuracy of the first 15 digits.

You can make an experiment to output the following values in JavaScript (note that they cannot be output as strings): 0.1000000000000000000000000001 (28 decimal places), 0.100000000000000000000000001 (27 decimal places), 0.1000000000000000000000000456 (28 decimal places), 0.09999999999999999999999 (23 decimal places), the displayed result is a value of 0.1. For example, if a rational number expression of 1/3 is output, the result is 0.3333333333333333.

Three formats: JavaScript Number

In actual use, the JavaScript value also has a second standard, which is a common format used by many computer languages, that is, a 32-bit integer, equivalent to the int type in C language. It consists of four 8-bit bytes and can store smaller integers. You may have used this format unintentionally, but JavaScript does not allow explicit declaration of int, which is an implicit type.

Therefore, JavaScript numeric values can be saved in the string format, including IEEE double-precision floating-point numbers or integers.
Why does JavaScript provide an implicit numeric type similar to int? There are three reasons: first, it is easy to execute bitwise operations, such as or (|) and shift (>); second, it is used for array processing; and third, for the sake of accuracy.

Consider the array. ECMA's JavaScript standard allows each array to have 4294967295 array elements-32 bits can save the maximum value minus 1, and the remaining one is used to save the length data. When we specify an array index, the JavaScript interpreter checks whether the variable is a 32-bit integer. For example, assume that there is an array var and a variable item. If item = 2, arr [item] = 5 is equivalent to arr [2] = 5; however, if the index value looks like a floating point number (or not as a value), for example, item = 2.0, the third statement is equivalent to: arr ["2.0"] = 5 ;.

This expression is easy to misunderstand. It seems that JavaScript supports index values in the negative and decimal forms, such as arr [-6] and arr [2.35]. In fact, such special index values are automatically converted into strings.

Here is another example. Suppose the initial value of the index variable slot1 is equal to 1.1, and arr [slot1] = 10. Now let's make also11 = Math. pow (Math. pow (1.1, 1/20), 20). Theoretically, slot1 should still be 1.1. Otherwise, the error in floating point operations will change slot1 to 1.100019, if we access arr [alot1] Again, then the arr [slot1] is no longer the original arr [alot1.

As you can see, a floating point number is much more complicated. But you don't have to worry too much. JavaScript will give priority to integers. That is to say, when JavaScript encounters a value, it first tries to process the value according to the integer. If it works, the value is saved as a 31-bit integer. If the value cannot be regarded as an integer, if the value exceeds the 31-bit range, the value is saved as a 64-bit IEEE 754 floating point number.

In the browser environment, numeric data may come from a variety of data sources, including XML, XHTML, DOM, and CSS standards, all of which provide JavaScript with data capabilities. No matter where the data comes from, these values are either treated as String or Number. If yes, the internal storage format may be an integer.

Four values: critical points that must be paid close attention

A clever reader must have come up with the question: When will a regular integer suddenly become an undefined double-precision floating point number? The answer is: when their values become very large, or when they enter between 1 and 0. Therefore, values 1 and 0 are the two values that must be paid attention to first.

Next, the maximum Unicode value is 1114111 (7 digits, equivalent to/x31677777), and the maximum RGB color value is 16777215 (8 digits, equivalent to # FFFFFF ). The maximum 32-bit signed integer is 2147483647 (10 digits), and-2147483648 is the smallest. Therefore, JavaScript stores all Unicode values and RGB colors as integers. 2147483647 is the third value that must be paid attention to. Any data greater than this value is saved in double-precision format.

9007199254740992 (16-digit) is the largest floating point number. It is similar to an integer in output. All Date objects (calculated in milliseconds) are smaller than this value. Therefore, they are always output in an integer format. It is the fourth value that must be noted.

Finally, the maximum double-precision value is 1.7976931348623157e + 308. exceeding this range is counted as Infinity.

Five Principles: Stay away from errors and troubles

■ Decimals are not required for most Web pages.
Avoid using decimals and try to use integers. Make sure that the index of the array is an integer. Calculate the amount by minute (not dollar. The percentage is increased by 100 times to avoid decimals. Try not to use Division (/) and modulo (%) operations, because in most cases they directly result in floating point numbers. If division is required, use the Math. round method to return to the integer operation immediately.

■ If a floating point number is required, introduce redundant decimal places as much as possible-that is, add decimal places in addition to the operation precision required by the program
If the program requires a decimal precision of five digits, at least six decimal places are retained in the operation, and eight digits are better. The more vertices, the less influence the cumulative error.

■ Avoid using numbers with too many or too small differences in the same expression
Performing subtraction or comparison operations on two very close values is prone to errors. Adding a small value to a large value is a waste of time. A small value may be treated as 0. However, if a small value is multiplied by a large value, the problem is normal. For example, if the value is 2*12345678, the correct result is 24691356. However, the result of 0.1-0.09 is 0.010000000000000009.

■ Use isFinite () and isNaN () to check the operation result
Before submitting any numeric results through a form, check the validity of the data.

■ Use numeric operations with caution
The less numeric operations a program involves, the smaller the possibility of introducing errors. The floating point number is a VIP and cannot be driven at will.

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.