Why JavaScript Numbers Are Weird (and How to Fix It)

A presentation at Frontend Love Meetup in March 2020 in by Sarah Dayan

Slide 1

Slide 1

Why Javascript Numbers Are Weird (And How to Fix It) @frontstuff_io

Slide 2

Slide 2

@frontstuff_io

Slide 3

Slide 3

Slide 4

Slide 4

Slide 5

Slide 5

Slide 6

Slide 6

We use a decimal system. @frontstuff_io

Slide 7

Slide 7

0 12 345 6789 @frontstuff_io

Slide 8

Slide 8

345 @frontstuff_io

Slide 9

Slide 9

345 300 + 40 + 5 @frontstuff_io

Slide 10

Slide 10

345 300 3 x 100 + 40 4 x 10 + 5 5x1 @frontstuff_io

Slide 11

Slide 11

345 300 + 40 + 5 3 x 100 4 x 10 5x1 3 x 10^2 4 x 10^1 5 x 10^0 @frontstuff_io

Slide 12

Slide 12

Computers use a binary system. @frontstuff_io

Slide 13

Slide 13

Slide 14

Slide 14

Computers must convert decimal to binary. @frontstuff_io

Slide 15

Slide 15

5 @frontstuff_io

Slide 16

Slide 16

1 5 1 x 2^2 (4) 5-4=1 @frontstuff_io

Slide 17

Slide 17

5 10 0 x 2^1 (2) 1-0=1 @frontstuff_io

Slide 18

Slide 18

5 101 1 x 2^0 (1) 1-1=0 @frontstuff_io

Slide 19

Slide 19

1 0 1 4 + 0 + 1 @frontstuff_io

Slide 20

Slide 20

Double-precision floating-point format @frontstuff_io

Slide 21

Slide 21

Java 1 System.out.println(.1 + .2); 2 3 // 0.30000000000000004 Python 1 print(.1 + .2) 2 3 # 0.30000000000000004 Ruby 1 puts 0.1 + 0.2 2 3 # 0.30000000000000004 C# JavaScript 1 Console.WriteLine(“{0:R}”, .1 + .2); 2 3 // 0.30000000000000004 1 console.log(.1 + .2); 2 3 // 0.30000000000000004

Slide 22

Slide 22

Before ES2020 JavaScript only had the number type @frontstuff_io

Slide 23

Slide 23

Slide 24

Slide 24

Slide 25

Slide 25

Slide 26

Slide 26

Slide 27

Slide 27

5 @frontstuff_io

Slide 28

Slide 28

Slide 29

Slide 29

0.75 @frontstuff_io

Slide 30

Slide 30

0.75 1 0.75 x 2 = 1.5 @frontstuff_io

Slide 31

Slide 31

0.75 11 0.5 x 2 = 1 @frontstuff_io

Slide 32

Slide 32

0.75 O.11 @frontstuff_io

Slide 33

Slide 33

Slide 34

Slide 34

5.75 @frontstuff_io

Slide 35

Slide 35

Slide 36

Slide 36

Slide 37

Slide 37

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

Slide 38

Slide 38

0.1 @frontstuff_io

Slide 39

Slide 39

0.1 + 0.2 @frontstuff_io

Slide 40

Slide 40

Same goes with Large integers @frontstuff_io

Slide 41

Slide 41

Number.MAX_SAFE_INTEGER; // 9007199254740991 Number.MAX_SAFE_INTEGER + 2; // 9007199254740992 @frontstuff_io

Slide 42

Slide 42

9007199254740991 -9007199254740991 @frontstuff_io

Slide 43

Slide 43

Slide 44

Slide 44

What to do instead? @frontstuff_io

Slide 45

Slide 45

(1 + 2) / 10^1 @frontstuff_io

Slide 46

Slide 46

Dinero({ amount: 500, currency: “USD” }); // represents $5 @frontstuff_io

Slide 47

Slide 47

10n @frontstuff_io

Slide 48

Slide 48

9007199254740991n + 2n; // 9007199254740993n @frontstuff_io

Slide 49

Slide 49

Arbitrary precision math is slower than floating point math. @frontstuff_io

Slide 50

Slide 50

Arbitrary precision integers are still new. @frontstuff_io

Slide 51

Slide 51

bartaz.github.io/ieee754-visualization 0.30000000000000004.com floating-point-gui.de @frontstuff_io

Slide 52

Slide 52

youtu.be/MqHDDtVYJRI @frontstuff_io

Slide 53

Slide 53

Thank you! sarahdayan.dev @frontstuff_io