It is said in many places that comparing two floating numbers for equality can give wrong result and we have to take into account some epsilon value like this

float f1,f2;
if (f1-f2<epsilon) printf("gotcha");

So what is the reasonable estimate of epsilon? My intuition is that that has to be decided on application requirement. Or we can use epsilon as like 0.0001 and be happy about it.

There is some interesting case where the integer operation is replaced by the floating point operations. Like how many digits are there in the factorial of a very big number like 1000000. Now instead of calculating the real factorial and taking log we can express it as a summation of logarithm of the numbers from 1 ... n. Then this bothers me how to adjust for values of the final result. Because a integer operation (calculating the factorial first and then taking the log) is replaced by floating point operation (addition of individual floating point numbers).

For application where two values can be different but very close like the readings taken from pressure gauge, thermometers and other analog devices, are we supposed to represent the numbers in string instead? I think someone said for business application it is recommended to represent money in string instead of double. I need to verify all these information.

3
Contributors
5
Replies
6
Views
7 Years
Discussion Span
Last Post by jephthah

epsilon definitely depends on the application. i prefer to just hold it out at arm's length and close one eye. if it lines up, we're good. that's called "engineering approximation". but, sadly, the quality engineers don't like it. :(

for large integers like factorials use a big number library, not floating point.

for money, you have to be aware of and careful of rounding errors. i've never heard of using strings, but i guess you could. i dont' program things involving money, so i don't know. personally when i need to account for rounding, i just round and truncate all the remaining digits after each operation as necessary.

to round to *nearest* whole cent:

``````(double)dollars = dollars * 100
(double)dollars = dollars + 0.5
(double)dollars = (cast as integer)dollars / 100.0``````

.

Edited by jephthah: n/a

>My intuition is that that has to be decided on application requirement.
Your intuition is correct. It depends on how much precision needs to be involved in the test. I've used as little precision as 0.1, myself.

>are we supposed to represent the numbers in string instead?
That's always an option, I suppose, but when dealing with such small variances you're more likely to eschew float/double and use something with more precision to help alleviate the usual rounding errors. Assuming long double isn't the same as double (like on Windows), it's suitable for that kind of thing. Double would be your bare minimum for floating-point in general.

>I think someone said for business application it is recommended
>to represent money in string instead of double.

Nah, you just need to be aware of rounding issues, take care with arithmetic, and use a high precision floating-point type.

Keep in mind that if you store values as strings, you still have to do conversions and you still have to manage arithmetic somehow. One common suggestion is to use an integer type to store the smallest unit value, such as cents for currency. That's a good idea until you realize that fractions of those units are often not unexpected, at which point the suggestion starts to seem less attractive.

Edited by Narue: n/a

Tell me one thing. If I have a floating point number like 123.456
and then if I multiply it by say 1000 then will it become 123456.000 or it might have the possibility of becoming like 123455.999 or something like that as a result of the multiplication.

Tell me one thing. If I have a floating point number like 123.456
and then if I multiply it by say 1000 then will it become 123456.000 or it might have the possibility of becoming like 123455.999 or something like that as a result of the multiplication.

that's why you add 0.5 to the float before you (1) cast the value as an integer (removing the fractional parts) then (2) divide it by 1000, keeping the result as a float (double)

the end result is that you have the precision you want with none of the extra fractional part beyond that.