# Falsehoods Programmers Believe About Money

A presentation at NodeConf Remote in October 2021 in by Sarah Dayan

#### Slide 1

Falsehoods Programmers Believe About Money Sarah Dayan NodeConf Remote 2021

#### Slide 3

You can safely store money as a fractional value

#### Slide 4

const cart = [ { name: ‘Mass Effect: Legendary Edition’, platform: ‘Xbox One’, price: 69.99, }, { name: ‘The Legend of Zelda: Breath of the Wild’, platform: ‘Nintendo Switch’, price: 51.91, } ];

#### Slide 5

cart.reduce((acc, { price }) => acc + price, 0); // 121.89999999999999 😧

#### Slide 7

‣ ‣ number (doubles) bigint (arbitrary precision integers)

#### Slide 8

dinero({ amount: 6999, currency: USD });

\$69.99 ¢6999

#### Slide 10

type Money<TAmount> = { amount: TAmount; currency: Currency<TAmount>; // … }

#### Slide 11

All currencies are decimal and split into 100 sub-units

x = 100x / 100

#### Slide 14

function toMajorUnit(minorUnitAmount) { return minorUnitAmount / 100; }

#### Slide 16

const USD = { code: ‘USD’, base: 10, exponent: 2, }; // Represents USD 10.00 dinero({ amount: 1000, currency: USD });

#### Slide 17

// Iraqi dinar const IQD = { code: ‘IQD’, base: 10, exponent: 3, }; // Represents IQD 1.000 dinero({ amount: 1000, currency: IQD });

#### Slide 18

// Japanese yen const JPY = { code: ‘JPY’, base: 10, exponent: 0, }; // Represents JPY 1000 dinero({ amount: 1000, currency: JPY });

#### Slide 19

// Mauritanian ouguiya const MRU = { code: ‘MRU’, base: 5, exponent: 1, }; // Represents 2 ouguiyas and 3 khoums dinero({ amount: 13, currency: MRU });

#### Slide 20

Currencies can’t be subdivided further than their sub-unit

#### Slide 22

€19.95 + 5.5% VAT €21.04725

#### Slide 23

const EUR = { code: ‘USD’, base: 10, exponent: 3, }; // Represents EUR 1.131 const diesel = dinero({ amount: 1131, currency: EUR });

#### Slide 24

// Represents EUR 1.131 dinero({ amount: 1131, currency: EUR, scale: 3 });

#### Slide 25

const diesel = dinero({ amount: 1131, currency: EUR, scale: 3 }); const fullTank = multiply(diesel, 50); const coffee = dinero({ amount: 99, currency: EUR }); // Amount 57540 and scale 3 (aka EUR 57.540) const total = add(fullTank, coffee);

#### Slide 26

All currencies have a single subdivision level

#### Slide 29

// Pre-decimal Great Britain pound sterling const GBP = { code: ‘GBP’, base: [20, 12], exponent: 1, }; // 267 pence, or 1 pound, 2 shillings and 3 pence const d = dinero({ amount: 267, currency: GBP }); toUnits(d); // [1, 2, 3]

#### Slide 30

Splitting money is as simple as dividing it

#### Slide 31

const purchase = { title: ‘Microsoft Xbox Series S’, price: 369.99, };

#### Slide 32

const length = 2; Array.from({ length }).map(() => purchase.price / length); // [184.995, 184.995]

#### Slide 33

Array.from({ length: count }).map( () => Math.round((purchase.price / count) * 100) / 100 ); // [185, 185]

#### Slide 34

const purchase = { title: ‘Microsoft Xbox Series S’, price: dinero({ amount: 36999, currency: USD }), }; const [d1, d2] = allocate(purchase.price, [50, 50]); d1; // a Dinero object with amount 18500 d2; // a Dinero object with amount 18499

#### Slide 35

You’ll never need to represent very large amounts

296000000000000

#### Slide 37

296000000000000 9000000000000000

#### Slide 38

29600000000000000 9000000000000000

#### Slide 40

const dineroBigint = createDinero({ calculator: { add: (a, b) => a + b, // … }, });

#### Slide 41

const dineroBigJs = createDinero({ calculator: { add: (a, b) => a.plus(b), // … }, });

#### Slide 42

const USD = { code: ‘USD’, base: 10n, exponent: 2n, }; dineroBigint({ amount: 500n, currency: USD });

#### Slide 43

So, is JavaScript safe to manipulate money?

#### Slide 44

Thank you! ff @frontstu _io