As almost every developers knows, Javascript has notorious problems when working with really big or really small decimal numbers. The reason is floating point. Purpose of this article is not to explain why it behaves the way it does, there are much better resources dedicated just for that. You can read the explanation here or here. There are also various libraries dedicated to working with decimals and precise calculations, such as big.js.
To ilustrate the problem, see the short video below. The input shows the text value, and on the right there is raw value as represented in Javascript. The issue it can cause, is that when Angular (or any other framework for that sake) re-renders the value, it uses the raw value. So the 0.00000001 is replaced with 1e-8. Not very user friendly.
So as a workaround, I’ve written simple utility function. It takes a number and returns correctly formatted string. Be aware that because how Javascript handles decimal numbers, you are not able to represent small fractions in their decimal form. Therefore it has to be represented as a string or some kind of object.
/** * Checks if number is in exponential format (eg: 1e-8 for 0.00000001). * If it does not, original number is returned. * If it does it converts it to string representation of that number * which forces it to format 0.00000001 */ export function convertExponentialToDecimal(exponentialNumber: number): number|string { // sanity check - is it exponential number const str = exponentialNumber.toString(); if (str.indexOf('e') !== -1) { const exponent = parseInt(str.split('-')[1], 10); // Unfortunately I can not return 1e-8 as 0.00000001, because even if I call parseFloat() on it, // it will still return the exponential representation // So I have to use .toFixed() const result = exponentialNumber.toFixed(exponent); return result; } else { return exponentialNumber; }
If it helped you solve your problem, let me know in comments below