# A double variable equals one, it also doesn't equal one.

This is a discussion on A double variable equals one, it also doesn't equal one. within the C Programming forums, part of the General Programming Boards category; I have this code: Code: #include <stdio.h> int main() { double temp; temp = 0; temp = temp + .6; ...

1. ## A double variable equals one, it also doesn't equal one.

I have this code:

Code:
```#include <stdio.h>

int main()
{
double temp;
temp = 0;
temp = temp + .6;
temp = temp + .3;
temp = temp + .1;
printf("%lf\n", temp);
if(temp != 1)
{
printf("Improper matrix!  Please use another.\n");
}
return(0);
}```
I'm sure most people know why it prints "Improper matrix! Please use another."

I have no idea what to search for, so I guess I'll ask you guys/girls why it does this (besides the fact that .6+.3+.1 != 1).

Yesterday when I was working on it, it printed it when I was using if(temp == 1), today it won't.

Edit: Apparently using %.999lf prints:

.9999999999999998889776975374843459576368331909179 687500..0 How interesting. Is there a way to get around this?

2. When you use floats/doubles, there's an error. In this case, although the number appears as 1.00000 in printf, it's just rounded from 0.99999999 (at least on my computer, I believe in other machines, it may be rounded from 1.0000000001, for example).
You can't really use it to compare.
You can, however, use the math library and round the double, so that it becomes an exact number. I'd recommend you round it to a long, with the function lround().
The code would stay like this:

Code:
```#include <stdio.h>
#include <math.h>

int main()
{
double temp;
temp = 0;
temp = temp + .6;
temp = temp + .3;
temp = temp + .1;
printf("%lf\n", temp);
if(lround(temp) != 1)
{
printf("Improper matrix!  Please use another.\n");
}
return(0);
}```

3. It's going to be terribly annoying to have to deal with that. I thought the point of double was to have accuracy. (I'm not flaming you)
I guess everything has problems =\

I put #include <math.h> in the header and I'm still getting an error...

Thanks for the help mang

4. What's the error that you have?
It is terribly annoying, that's a fact xD
If you're using linux, don't forget to include the math library in the compiler line.
To compile it using gcc, would be something like this:
gcc -lm -o test test.c
(test.c = source file)
If you're using another compiler, search for how to enable the math library with it.

5. Originally Posted by madmax2006
It's going to be terribly annoying to have to deal with that.
Perhaps a little, but if you use floating point for a while you'll get used to it and know what the good methods of approximate comparison are
I thought the point of double was to have accuracy.
That's just it, the way they work does give you about the most accuracy possible! The problem is that you're expecting it to give especially accurate results for base 10 values, but IEEE floating point types don't use base 10, they use base 2.

The platforms out there that have base 10 floating point types require 4 bits to store each digit, which as you know could store 16 possible values, and 6 of those are unusable. That's (37.5%) wastage - OUCH!
What's more they still don't help you with calculations as simple as 1.0 / 3.0. Now if they used base 3 then that 1.0 / 3.0 work be exactly representable, but you'd have problems with something as simple as 1.0 / 2.0! In other words, no matter what base they use, they are going to fail to represent even some of the simplest fractions exactly. Picking a different base just makes different cases worse. So the best thing to do is for them to use a base that is a power of two to waste the least space. Funnily enough a base of exactly two is also the simplest the implement, and you get at least as many decimal places as you would in base 10 since no bits are wasted. As an example, using just 10 bits you can represent numbers with 3 decimal digits if you store the number using binary, but if you use BCD (base 10) you can only store 2 decimal digits.

No matter what, you will always need to compare floating points using a method that checks for approximately equal. The only way around it is to use a custom 'fraction' data type instead.

6. Originally Posted by madmax2006
Edit: Apparently using %.999lf prints:

.9999999999999998889776975374843459576368331909179 687500..0 How interesting.
There are 53 non-zero digits here, which not coincidentally is the number of bits in the significand of a double. In binary, this is '0.' followed by 53 1s: 0.111111111111111111111111111111111111111111111111 11111. This is equivalent to the fraction (2^53-1)/2^53.

BTW, are you using gcc on Linux? Not too many compilers will let you print all those digits -- gcc is one of them (see my article Print Precision of Dyadic Fractions Varies by Language - Exploring Binary .)

7. Originally Posted by DoctorBinary
There are 53 non-zero digits here, which not coincidentally is the number of bits in the significand of a double.
A binary digit is not the same as a decimal digit. I think this is just a freakish coincidence.

8. Originally Posted by brewbuck
A binary digit is not the same as a decimal digit. I think this is just a freakish coincidence.
It's not a coincidence. A binary fraction (i.e. 0 < f < 1) has as many decimal digits as bits. Try any binary fraction you like. Here are just two examples:

0.11001111 = 0.80859375
0.1100101010101 = 0.7916259765625

9. Originally Posted by madmax2006
I thought the point of double was to have accuracy.
On the contrary, the format is specifically designed to represent a vast range of approximations. If you want real accuracy, use integral fractions.

Popular pages Recent additions