Typescript
  • Introducão
  • Primeiros Passos
    • Por que TypeScript
  • JavaScript
    • Igualdade
    • Referências
    • Null vs. Undefined
    • this
    • Closure
    • Number
    • Truthy
  • Futuro JavaScript Agora
    • Classes
      • Classes Emit
    • Arrow Functions
    • Rest Parameters
    • let
    • const
    • Destructuring
    • Spread Operator
    • for...of
    • Iterators
    • Template Strings
    • Promise
    • Generators
    • Async Await
  • Project
    • Compilation Context
      • tsconfig.json
      • Which Files?
    • Declaration Spaces
    • Modules
      • File Module Details
      • globals.d.ts
    • Namespaces
    • Dynamic Import Expressions
  • Node.js QuickStart
  • Browser QuickStart
  • TypeScript's Type System
    • JS Migration Guide
    • @types
    • Ambient Declarations
      • Declaration Files
      • Variables
    • Interfaces
    • Enums
    • lib.d.ts
    • Functions
    • Callable
    • Type Assertion
    • Freshness
    • Type Guard
    • Literal Types
    • Readonly
    • Generics
    • Type Inference
    • Type Compatibility
    • Never Type
    • Discriminated Unions
    • Index Signatures
    • Moving Types
    • Exception Handling
    • Mixins
  • JSX
    • React
    • Non React JSX
  • Options
    • noImplicitAny
    • strictNullChecks
  • Errors in TypeScript
    • Interpreting Errors
    • Common Errors
  • NPM
  • Testing
    • Jest
    • Cypress
  • Tools
    • Prettier
    • Husky
    • Changelog
  • TIPs
    • String Based Enums
    • Nominal Typing
    • Stateful Functions
    • Bind is Bad
    • Currying
    • Type Instantiation
    • Lazy Object Literal Initialization
    • Classes are Useful
    • Avoid Export Default
    • Limit Property Setters
    • outFile caution
    • JQuery tips
    • static constructors
    • singleton pattern
    • Function parameters
    • Build Toggles
    • Barrel
    • Create Arrays
    • Typesafe Event Emitter
  • StyleGuide
  • TypeScript Compiler Internals
    • Program
    • AST
      • TIP: Visit Children
      • TIP: SyntaxKind enum
      • Trivia
    • Scanner
    • Parser
      • Parser Functions
    • Binder
      • Binder Functions
      • Binder Declarations
      • Binder Container
      • Binder SymbolTable
      • Binder Error Reporting
    • Checker
      • Checker Diagnostics
      • Checker Error Reporting
    • Emitter
      • Emitter Functions
      • Emitter SourceMaps
    • Contributing
Powered by GitBook
On this page
  • Core Type
  • Decimal
  • Integer
  • big.js
  • NaN
  • Infinity
  • Infinitesimal

Was this helpful?

  1. JavaScript

Number

Whenever you are handling numbers in any programming language you need to be aware of the idiosyncrasies of how the language handles numbers. Here are a few critical pieces of information about numbers in JavaScript that you should be aware of.

Core Type

JavaScript has only one number type. It is a double-precision 64-bit Number. Below we discuss its limitations along with a recommended solution.

Decimal

For those familiar with doubles / float in other languages, you would know that binary floating point numbers do not map correctly to Decimal numbers. A trivial (and famous) example with JavaScript's built in numbers is shown below:

console.log(.1 + .2); // 0.30000000000000004

For true decimal math use big.js mentioned below.

Integer

The integer limits represented by the built in number type are Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER.

console.log({max: Number.MAX_SAFE_INTEGER, min: Number.MIN_SAFE_INTEGER});
// {max: 9007199254740991, min: -9007199254740991}

Safe in this context refers to the fact that the value cannot be the result of a rounding error.

The unsafe values are +1 / -1 away from these safe values and any amount of addition / subtraction will round the result.

console.log(Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2); // true!
console.log(Number.MIN_SAFE_INTEGER - 1 === Number.MIN_SAFE_INTEGER - 2); // true!

console.log(Number.MAX_SAFE_INTEGER);      // 9007199254740991
console.log(Number.MAX_SAFE_INTEGER + 1);  // 9007199254740992 - Correct
console.log(Number.MAX_SAFE_INTEGER + 2);  // 9007199254740992 - Rounded!
console.log(Number.MAX_SAFE_INTEGER + 3);  // 9007199254740994 - Rounded - correct by luck
console.log(Number.MAX_SAFE_INTEGER + 4);  // 9007199254740996 - Rounded!

To check safety you can use ES6 Number.isSafeInteger:

// Safe value
console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER)); // true

// Unsafe value
console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)); // false

// Because it might have been rounded to it due to overflow
console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 10)); // false

big.js

  • Perfect decimal math

  • Safe out of bound integer values

Installation is simple:

npm install big.js @types/big.js

Quick Usage example:

import { Big } from 'big.js';

export const foo = new Big('111.11111111111111111111');
export const bar = foo.plus(new Big('0.00000000000000000001'));

// To get a number:
const x: number = Number(bar.toString()); // Loses the precision

Do not use this library for math used for UI / performance intensive purposes e.g charts, canvas drawing etc.

NaN

When some number calculation is not representable by a valid number, JavaScript returns a special NaN value. A classic example is imaginary numbers:

console.log(Math.sqrt(-1)); // NaN

Note: Equality checks don't work on NaN values. Use Number.isNaN instead:

// Don't do this
console.log(NaN === NaN); // false!!

// Do this
console.log(Number.isNaN(NaN)); // true

Infinity

The outer bounds of values representable in Number are available as static Number.MAX_VALUE and -Number.MAX_VALUE values.

console.log(Number.MAX_VALUE);  // 1.7976931348623157e+308
console.log(-Number.MAX_VALUE); // -1.7976931348623157e+308

Values outside the range where precision isn't changed are clamped to these limits e.g.

console.log(Number.MAX_VALUE + 1 == Number.MAX_VALUE);   // true!
console.log(-Number.MAX_VALUE - 1 == -Number.MAX_VALUE); // true!

Values outside the range where precision is changed resolve to special values Infinity/-Infinity e.g.

console.log(Number.MAX_VALUE + 10**1000);  // Infinity
console.log(-Number.MAX_VALUE - 10**1000); // -Infinity

Of-course, these special infinity values also show up with arithmetic that requires it e.g.

console.log( 1 / 0); // Infinity
console.log(-1 / 0); // -Infinity

You can use these Infinity values manually or using static members of the Number class as shown below:

console.log(Number.POSITIVE_INFINITY === Infinity);  // true
console.log(Number.NEGATIVE_INFINITY === -Infinity); // true

Fortunately comparison operators (< / >) work reliably on infinity values:

console.log( Infinity >  1); // true
console.log(-Infinity < -1); // true

Infinitesimal

The smallest non-zero value representable in Number is available as static Number.MIN_VALUE

console.log(Number.MIN_VALUE);  // 5e-324

Values smaller than MIN_VALUE ("underflow values") are converted to 0.

console.log(Number.MIN_VALUE / 10);  // 0

Further intuition: Just like values bigger than Number.MAX_VALUE get clamped to INFINITY, values smaller than Number.MIN_VALUE get clamped to 0.

PreviousClosureNextTruthy

Last updated 6 years ago

Was this helpful?

JavaScript will eventually get support. For now, if you want arbitrary precision integer math use big.js mentioned below.

Whenever you use math for financial calculations (e.g. GST calculation, money with cents, addition etc) use a library like which is designed for

BigInt
big.js