Koeiegeloei wrote:
However, your workaround is not 100% reliable either, unfortunately.
I tried to substitute your proposal in in one of my worksheets and found the following anomaly, which I reproduce in a simplified version below:
Formula Result
0 0
=(MOD(ROUND(A1+1/3,12),1)) 0.333333
=(MOD(ROUND(A2+1/3,12),1)) 0.666667
=(MOD(ROUND(A3+1/3,12),1)) 1
The last result should of course be 0. Rounding to less or more digits does not change the result.
Your example reflects a number of misunderstandings.
I wrote: "Change ROUND(...,2) to whatever precision is sufficient for your application".
When we round to a specific precision, the presumption is that either we format the results with at least the same number of decimal places, or we understand the difference between displayed and actual values.
If we format the results with 12 decimal place, consistent with your use of ROUND(....,12), we see the following:
The formulas in column A are displayed in column B.
Hopefully, it is clear now that the result in A4 is indeed correct.
It only appears to be 1 because you formatted with less than 12 decimal places. Actually, it appears that you used the General format. So Excel decides the number of displayed decimal places arbitrarily.
When we display fewer decimal places, Excel rounds the displayed value. But usually [1], that does not change the underlying actual value.
So A2 is actually 0.333333333333 (12 digits). When you add 1/3 in A3, the result is 0.666666666666333 (15 digits), which you round to 0.666666666666 (12 digits). Similarly, when you add 1/3 in A4, the result is 0.999999999999333, which you round to 0.999999999999.
Koeiegeloei wrote:
I guess that most people need a work-around that is 100% reliable. So far, it seems to me that there is no such workaround.
As I wrote in my response to JP, the more reliable solution is, in general:
ROUND(MOD(ROUND(A1+1/3,12),1),12)
The outer ROUND(...,12) is not needed for your examples because A+1/3 is less than 1 in all cases. But consider the following example:
Column A is formatted as Number with 15 decimal places so we can see the problem.
A6 is correctly 100.333333333333 (12 decimal places). When we add 1/3 and round, A7 is correct 100.666666666666. But in A8, MOD(A7,1) is 0.666666666666003 (15 decimal places). As demonstrated in A9, we must explicitly round in order to get the correct result to the desired precision of 12 decimal places.
The reason why A8 is 0.666666666666003 is complicated. It really is not necessary that you understand the explanation.
The reason is that the number in A7 is represented by a sum of 53 consecutive powers of 2 ("bits") times an exponential factor. 7 of those bits represent the integer 100. The remaining 46 bits are the best approximation of the fraction 0.666666666666.
When we do MOD(A7,1) in A8, we simply strip away the integer part. Thus, 0.666666666666 is still represented using only 46 bits. The remaining 7 bits to the right are zero.
But the constant 0.666666666666 can be represented more accurately using all 53 bits: as many as 7 more powers of 2, which are increasingly smaller fractions in this case.
This might be clearer if you could see the exact internal values, not limited by the 15 significant digits that Excel will format. (In the following, period (".") is the decimal point, and comma (",") demarcates the first 15 significant digits.)
A7: 100.666666666666 100.666666666666,00349344662390649318695068359375
A8: =MOD(A7,1) 0.666666666666003,49344662390649318695068359375
A9: 0.666666666666 0.666666666666000,05175524756850791163742542266845703125
As you can see, the difference between A7 and A8 is simply that 100 is subtracted, effectively shifting the first 15 significant digits left to include the 003 that was there all along.
But the constant 0.666666666666 is represented more accurately with 000 following the first 12 significant digits, in this case.
[1] The format affects the underlying actual value only when the "Precision as displayed" option is set. But in that case, you really should format with 12 decimal places, since ROUND(...,12) implies that that is the precision you require. Note: I do not recommend that you use "Precision as displayed".