1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

  2. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

[Progress Blogs] Limitations of the Number Type in JavaScript

Discussão em 'Progress Blogs' iniciado por Thierry Ciot, Setembro 21, 2021.

  1. Thierry Ciot

    Thierry Ciot Guest

    You don’t want any errors in your commercial or Scientific applications, do you?

    In Javascript, the number type is used to represent all numbers like integers and decimals (123 or 123.45). But the underlying system representation of these numbers has an impact on the quality of your computations.

    In this blog, we will see why JavaScript numbers are not necessarily suitable for commercial and scientific applications.

    In a follow up blog, we will see a solution using decimals support.

    Background Information on Numbers in JavaScript


    According to the ECMAScript standard, there is only one number type in JavaScript: the double-precision 64-bit binary format IEEE 754 value.

    The 64 bits are used like this: 1 bit for sign,11 bits for exponent and 53 bits for significant digits.

    Unlike some other languages, there is no specific type for integers. Starting with ECMAScript 2015, one can check if a number is in the double-precision floating-point number range using Number.isSafeInteger() as well as Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER.

    Beyond this range, integers in JavaScript are not safe anymore and will be a double-precision floating point approximation of the value. We will see below some examples of this.

    Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_typ

    Specific Limitations


    Because all numbers in JavaScript are implemented with floating point numbers, we have the following issues which could be detrimental to commercial or scientific applications:

    • Incorrect results with inexact numbers
    • Float computations are not deterministic
    • Very large or very small numbers cannot be processed, in particular when using Integers

    In the next sections, we will go into detailed explanations for each of these issues.

    Incorrect results with inexact numbers


    The issue is that some floats do not have an exact representation. This leads to incorrect results and results that cannot be compared with certainty. Another way to put it, float numbers can only approximate decimal numbers that are commonly used for many commercial purposes.

    At this point, you may be wondering what I am really talking about. Let’s look at a simple example:

    Well, in JavaScript, 0.1 + 0.2 is NOT equal to 0.3.

    Try this in a browser console: (to open the console for example with Google Chrome, type CRTL Shift J on Windows/Linux or Command+Option+J on Mac—see here).

    console: console.log(0.1)

    Output: 0.1

    console: console.log(0.2)

    Output: 0.2

    console: console.log(0.1+0.2)

    Output: 0.30000000000000004

    The reason is that 0.1 has the following representation as a double: 0.1000000000000000055511151231257827021181583404541015625

    So, you can imagine how repeating this kind of precision errors over lots of transactions could result in unacceptable financial results (million dollars a year differences on some transactions).

    Note: Only dyadic numbers have an exact representation. You can check here and also here for more info.

    Here is a tool to check if a number has an inexact representation as a float.

    Float computations are not deterministic


    Float computations are not deterministic (they produce different results) across machine architecture, compiler versions, etc. (Read this for issues encountered by game programmers).

    This could potentially lead to different results when run on client side where the devices from cell phone to tablets to desktop run different OSes, hardware CPUs and floating point accelerators.

    I haven’t personally run into this, and would be curious to know if you have. Please leave a note in the comments section if you ran into this issue.

    Very large numbers cannot be processed


    In the case of Integers, we are limited on both the positive and negative side. JavaScript defines constants for the limits: Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER.

    console.log(Number.MAX_SAFE_INTEGER) produces 9007199254740991

    console.log(Number.MIN_SAFE_INTEGER) produces -9007199254740991

    Here is an example of errors you could get into:

    Number.MAX_SAFE_INTEGER + 1: 9007199254740992 → correct.

    Number.MAX_SAFE_INTEGER + 2: 9007199254740992 → clearly incorrect.

    When doing any operations on your numbers, you can use Number.isSafeInteger() to verify that you have not exceeded the range.

    Conclusion


    In conclusion, when dealing with commercial or scientific applications, JavaScript developers need to carefully consider the limitations of the built-in number type.

    In a follow-up blog, we will see how one can use a decimal library to minimize the issues outlined here.

    Continue reading...

Compartilhe esta Página