0

I have project that should calculate an equation and it checks every number to see if it fits the equation. every time it pluses the number by 0.00001. but sometiomes it gets random on next decimals for example 0.000019999999997.

I even tried a breakpoint at that line. When I am right on that line it is 1.00002 for example but when I go to next line it is 1.00002999999997.

I don't why it is like that. I even tried smaller numbers like 0.001.

List<double> anwsers = new List<double>();
double i = startingPoint;
double prei = 0;

double preAbsoluteValueOfResult = 0;
while (i <= endingPoint)
{
    prei = i;
    i += 0.001;
}
Stefan Wuebbe
  • 2,109
  • 5
  • 17
  • 28

3 Answers3

0

Computers don't store exact floating point numbers. A float is usually 32 bits or 64 bits and cannot store numbers to arbitrary precision.

If you want dynamic precision floating point, use a number library like GMP.

jmpsabisb
  • 182
  • 1
  • 10
0

There are some good video's on this https://www.youtube.com/watch?v=2gIxbTn7GSc

But esentially its because there arnt enough bits. if you have a number being stored e.g. 1/3 it can only store so many decimal places, so its actually going to be something like 0.3334. Which means when you do something like 1/3 + 1/3 it isnt going to equal 2/3 like one might expect, it would equal 0.6668

To summarize, using the decimal type https://learn.microsoft.com/en-us/dotnet/api/system.decimal?view=net-7.0 Over double, should fix your issues.

JDChris100
  • 146
  • 9
0

TL;DR: You should use a decimal data type instead of a float or double. You can declare your 0.001 as a decimal by adding an m after the value: 0.001m

The double data type you chose relies on a representation of decimal numbers via a fraction of two integers. It is great for storing large decimal numbers with little memory, but it also means your number gets rounded to the closest value which can be represented by such a fraction. A decimal on the other hand will store the information in a different way, which will more closely represent what you intuitively expect from decimal numbers.

More information about float values: https://floating-point-gui.de/

More information about numeric types declaration: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types

The documentation also explains:

Just as decimal fractions are unable to precisely represent some fractional values (such as 1/3 or Math.PI), binary fractions are unable to represent some fractional values. For example, 1/10, which is represented precisely by .1 as a decimal fraction, is represented by .001100110011 as a binary fraction, with the pattern "0011" repeating to infinity. In this case, the floating-point value provides an imprecise representation of the number that it represents. Performing additional mathematical operations on the original floating-point value often tends to increase its lack of precision.

Ama
  • 1,373
  • 10
  • 24