1

I have a code, and I do not understand it. I am developing an application which precision is very important. but it does not important for .NET, why? I don't know.

double value = 3.5;
MessageBox.Show((value + 1 * Math.Pow(10, -20)).ToString());

but the message box shows: 3.5 Please help me, Thank you.

Jakob Gade
  • 12,319
  • 15
  • 70
  • 118
Hossein Margani
  • 1,056
  • 2
  • 15
  • 35

5 Answers5

3

If you're doing anything where precision is very important, you need to be aware of the limitations of floating point. A good reference is David Goldberg's "What Every Computer Scientist Should Know About Floating-Point Arithmetic".

You may find that floating-point doesn't give you enough precision and you need to work with a decimal type. These, however, are always much slower than floating point -- it's a tradeoff between accuracy and speed.

dF.
  • 74,139
  • 30
  • 130
  • 136
  • 1
    Good article, but it's a little hard for non-mathematicians to read. This one's somewhat easier reading for code monkeys: http://floating-point-gui.de/ – Solomon Slow Oct 09 '14 at 17:53
2

Or use the Decimal type rather than double.

Colin Desmond
  • 4,824
  • 4
  • 46
  • 67
2

The precision of a Double is 15 digits (17 digits internally). The value that you calculate with Math.Pow is correct, but when you add it to value it just is too small to make a difference.

Edit:
A Decimal can handle that precision, but not the calculation. If you want that precision, you need to do the calculation, then convert each value to a Decimal before adding them together:

double value = 3.5;
double small = Math.Pow(10, -20);

Decimal result = (Decimal)value + (Decimal)small;

MessageBox.Show(result.ToString());
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
2

You can have precision, but it depends on what else you want to do. If you put the following in a Console application:

double a = 1e-20;
Console.WriteLine(" a  = {0}", a);
Console.WriteLine("1+a = {0}", 1+a);

decimal b = 1e-20M;
Console.WriteLine(" b  = {0}", b);
Console.WriteLine("1+b = {0}", 1+b);

You will get

 a  = 1E-20
1+a = 1
 b  = 0,00000000000000000001
1+b = 1,00000000000000000001

But Note that The Pow function, like almost everything in the Math class, only takes doubles:

double Pow(double x, double y);

So you cannot take the Sine of a decimal (other then by converting it to double)

Also see this question.

Community
  • 1
  • 1
H H
  • 263,252
  • 30
  • 330
  • 514
0

Double precision means it can hold 15-16 digits. 3.5 + 1e-20 = 21 digits. It cannot be represented in double precicion. You can use another type like decimal.

Kcats
  • 884
  • 1
  • 15
  • 26
  • 15-16 digits total. The floating point can be anywhere before, after or inbetween these digits – Kcats May 18 '09 at 10:50