Floating point arithmetic is too reliable

喜你入骨 提交于 2019-12-01 11:43:15
double x = (0.1 * 3) / 3;
Console.WriteLine("x: {0}", x); // prints "x: 0.1"
Console.WriteLine("x == 0.1: {0}", x == 0.1); // prints "x == 0.1: False"

Remark: based on this don't make the assumption that floating point arithmetic is unreliable in .NET.

Anthony Pegram

Here's an example based on a prior question that demonstrates float arithmetic not working out exactly as you would think.

float f = (13.45f * 20);
int x = (int)f;
int y = (int)(13.45f * 20);
Console.WriteLine(x == y);

In this case, false is printed to the screen. Why? Because of where the math is performed versus where the cast to int is happening. For x, the math is performed in one statement and stored to f, then it is being cast to an integer. For y, the value of the calculation is never stored before the cast. (In x, some precision is lost between the calculation and the cast, not the case for y.)

For an explanation behind what's specifically happening in float math, see this question/answer. Why differs floating-point precision in C# when separated by parantheses and when separated by statements?

My favourite demonstration boils down to

double d = 0.1;
d += 0.2;
d -= 0.3;

Console.WriteLine(d);

The output is not 0.

Try making it so the decimal is not .5.

Take a look at this article here

http://floating-point-gui.de/

try sum VERY big and VERY small number. small one will be consumed and result will be same as large number.

Try performing repeated operations on an irrational number (such as a square root) or very long length repeating fraction. You'll quickly see errors accumulate. For instance, compute 1000000*Sqrt(2) vs. Sqrt(2)+Sqrt(2)+...+Sqrt(2).

The simplest I can think of right now is this:

class Test
{
    private static void Main()
    {
        double x = 0.0;

        for (int i = 0; i < 10; ++i)
            x += 0.1;

        Console.WriteLine("x = {0}, expected x = {1}, x == 1.0 is {2}", x, 1.0, x == 1.0);
        Console.WriteLine("Allowing for a small error: x == 1.0 is {0}", Math.Abs(x - 1.0) < 0.001);
    }
}

I suggest that, if you're truly interested, you take a look any one of a number of pages that discuss floating point numbers, some in gory detail. You will soon realize that, in a computer, they're a compromise, trading off accuracy for range. If you are going to be writing programs that use them, you do need to understand their limitations and problems that can arise if you don't take care. It will be worth your time.

double is accurate to ~15 digits. You need more precision to really start hitting problems with only a few floating point operations.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!