I found what I think is a suspiciously simple solution for dealing with rounding floating-point numbers if I only want small levels of precision (only 2 o 4 decimal places) but haven't found any mention of it.
Here's an illustrative example of the situation: I have a number like 1.4349999999999998 (0.1025 * 14), one would expect it to round up to 1.44. However, due to the nature of JavaScript's floating-point precision, rounding to 2 decimal places gives 1.43 instead.
I came across a potential solution. This technique involves two steps: 1. Initially rounding to a higher precision (the target number of decimal places plus an arbitrary number, in my case, 6). 2. Then rounding again to the desired precision.
Here's an example using lodash's `_.round()` function:
```javascript const _ = require('lodash');
let num = 0.1025 * 14; // 1.4349999999999998 The number we want to round let tempNum = _.round(num, 8); // First we round to 8 decimal places (2 + 8) let finalNum = _.round(tempNum, 2); // Then we round to the 2 decimal places we want
console.log(finalNum); // Outputs: 1.44
```
This method seems to provide the expected result for this and several other test cases. However, I'm aware that this might not be a one-size-fits-all solution due to the complexities of floating-point precision.
So, has anyone has used this double-rounding technique before or has thoughts on its effectiveness? Are there specific pitfalls I should be aware of?
I'm aware of solutions like decimal.js to deal with precise values but I think this might work for 2 or 4 decimal places.
No one wouldn't. Maybe your domain has very specific, unorthodox rounding requirements? The most common rounding algorithms only look at the (n+1)th digit when rounding to n decimal places.
ie: 1.4349999999999998 rounded to 2 decimal places considers only 1.434. 4 is less than 5, so the result is correctly 1.43.
Edit: I just realized I missed the forest for the trees. The original calculation should have resolved to 1.435, which would round to 1.44.
I don't think your solution would work in the general case for floating point numbers, where numbers could be much smaller than your rounding attempts. Maybe if you based it on `value * Number.EPSILON`, or something?
0.1025 × 14
and not, for example, 0.1025 × 14 - 0.000000000000000001
to get the IEEE float that prints as 1.4349999999999998
All it knows is that it got that float, and its value is less than 1.435.