I'm working with double in C#. Double has Precision ~15-17 digits.
In my program, the user enters: 0.011 - 0.001, and the result shows 0.0099999999999999985 --> that's ugly in the user's eye - they will question my math ability.
I'm okay with the result being 0.0099999999999999985 internal, but when display, I want to find a way to fix the precision digits. For example:
double a = 0.011;
double b = 0.001;
double result, display;
result = a - b;//result = 0.0099999999999999985
display = ConvertForDisplay(result);//I want display = 0.01
I see that the build-in Android app "Calculator" on Samsung smartphone (e.g Galaxy Tab SM-T295) also use double
(because I enter 10^309 and it gives error) but when I enter the math 0.011 - 0.001, it properly shows me 0.01.
I thought about Math.Round (double value, int digits)
, but the digits
must be in range [0,15], while I also need to display the numbers like 1E-200.
I've search around the internet but I just saw questions about how to deal with the floating point accuracy problems (e.g don't use ==
but use Math.Abs(a-b) < double.Epsilon
, Math.Round
,...). But I can't find how to round the precision digits (e.g the value 0.0099999999999999985 has the precision digits 99999999999999985
, when the those digits contains more than 15 "9"s, then it should be round for display).
So what is the proper way to fix this problem (e.g convert 0.0099999999999999985 into 0.01)?
Extra: when I enter 9999999999999999d
, C# gives me 1E+16, I know this happens because C# sees that all the precision digits, which it can hold, is 9 so it rounds up to 10, but is there any way I can make it keeps all the 9s - I see that the Android app "Calculator", which I mention above, also gives this behavior, so I count this as extra - not a must-fix, but I want to know if it's fixable just for fun.
Update:
I see the behavior: (1.021 - 1.01) = 0.010999999999999899
But (1.021 - 1.01) + 1 = 1.011
So when I add 1, double triggers its "internal round" feature (I guess) and it rounds to the number I want. Maybe this could lead to my solution?
Here's another interesting discover: cast the value to float can also give the number I want, e.g: (float)(1.021 - 1.01) = 0.011