C# 1-1= 8.88178419700125E-16? (new to coding, help needed)

Status
Not open for further replies.

ELREVENGE

Honorable
Jan 23, 2014
1
0
10,510
I would first like to state that I'm new to coding, so there's probably a better way to do this.So I'm working on a quick program to count the number of digits after the decimal in a number. The lines of code that is causing issues are:
while (dx < 1&dx != 0)
{
//count is here to keep track of how many times it's ran
count++;
x = x * 10;
//the writelines are only so I can see what each variable's value is.
Console.WriteLine(dx is {0}",x);
Console.WriteLine("floor x is = {0}", Math.Floor(x));
Console.WriteLine("x - x rounded down = {0}", (x - (Math.Floor(x))));
dx = dx - Math.Floor(x);
Console.WriteLine(x);
}
this code repeats until it's left with 0
when run with x=0.11 this is what it outputs:
x is 1.1
floor x is = 1
x - x rounded down = 0.1
0.1
x is 1
floor x is = 1
x - x rounded down = 8.88178419700125E-16
8.88178419700125E-16
and this continues until it runs out of numbers to work with and ends as expected.
0.5
dx is 5
floor dx is = 5
dx - dx rounded down = 0
0
I have no idea what causes this and would really appreciate any help.
Sense I'm learning explaining why this is caused would be helpful, thanks!
 
Solution
The issue is that floating point numbers are expressed in binary, while you're trying to do decimal math on them. This leads to rounding issues, as you've seen.

I'd suggest converting the number into a string of decimal figures, then just counting how many characters are after the decimal point before you hit a 0.
The issue is that floating point numbers are expressed in binary, while you're trying to do decimal math on them. This leads to rounding issues, as you've seen.

I'd suggest converting the number into a string of decimal figures, then just counting how many characters are after the decimal point before you hit a 0.
 
Solution


Beat me to it. This is a classic problem and your solution is the "programming 101" way to do it and the only way to get around floating point math. lol.
 

wirefire99

Honorable
Jun 20, 2013
3
0
10,510
Apologies for this being in vb.net but it is how my brain works

Dim x as double
Dim y as double
Dim z as string
Dim q as int16

y= math.round(math.floor(x))
x = x -y
z = x.tostring
q = z.length - 1

q holds the number of decimals. No loop. No goofy very small rounding errors.
 

Pinhedd

Distinguished
Moderator


This occurs because 1.1, 0.1, and 0.11 cannot be represented in floating point notation. Only 1.0 can be represented without any loss of precision.

By default, the decimal print functions in most languages will print only a handful of figures to the right hand side of the radix. The rest are either truncated or rounded off.

Run the following code through a C compiler and observe the printed results

C++:
#include <stdio.h>

int main()
{
double a = 0.1, b = 1.0, c = 1.1, d = 0.11;
printf("%.30lf\n",a);
printf("%.30lf\n",b);
printf("%.30lf\n",c);
printf("%.30lf\n",d);
printf("%.30lf\n",c-b);
return 0;
}

Since 1.1, 0.1, and 0.11 cannot be represented without error, any arithmetic operations on these values will compound the error while potentially introducing errors of their own.

Fl(1.1) - Fl(1.0) != Fl(0.1). This is demonstrated in the fifth print statement which subtracts b from c. Some of the values in there should look familiar.
 
Status
Not open for further replies.