generated from tc39/template-for-proposals
-
Notifications
You must be signed in to change notification settings - Fork 5
Open
Description
When casting an Amount to a Number, it's possible that the result would not have the same decimal string representation as the Amount's value. As in:
let a = new Amount('0.1')
let b = new Amount('0.10000000000000001')
String(a) === String(a.toNumber()) // '0.1' === '0.1'
String(b) !== String(b.toNumber()) // '0.10000000000000001' !== '0.1'
It's also possible (actually, pretty likely for non-integer values) that the 𝔽(x) finite Number value is different from the Amount's mathematical value:
let c = new Amount('0.25')
let d = new Amount('0.3')
String(c) === c.toNumber().toFixed(60).replace(/0+$/, '') // '0.25' === '0.25'
String(d) !== d.toNumber().toFixed(60).replace(/0+$/, '') // '0.3' !== '0.299999999999999988897769753748434595763683319091796875'
So we have at least the above two definitions by which calling .toNumber()
can be observably lossy. Should we maybe add an option like Temporal's overflow: 'constrain' | 'restrict'
to .toNumber()
? This would make calling it throw a RangeError for one or both of the precision-loss cases:
new Amount('0.25').toNumber({ overflow: 'restrict' }) // ok, 0.25
new Amount('0.10000000000000001').toNumber() // ok, 0.1
new Amount('0.10000000000000001').toNumber({ overflow: 'restrict' }) // error
new Amount('0.3').toNumber({ overflow: 'restrict' }) // ok or error?
I'm not completely sure myself whether this is warranted, but it would address the use case presented in Lxxyx/proposal-number-is-safe-numeric#4.
Metadata
Metadata
Assignees
Labels
No labels