epsilon for float, double long double
Author |
Message |
V-ma #1 / 24
|
epsilon for float, double long double
My system (x86) allows 32 bit, 64 bit and 80 bit IEEE floats. For 32 bit, this is what Im doing: float number=somenumber_close_to_PI; float epsilon=1.0e-5; if((number+epsilon>=PI)&&(number-epsilon<=PI)) cout<<"yes, it is equal to PI"; Is this an OK value of epsilon for 32 bit? What about 64 bit and 80 bit? Before, I was using epsilon=1.0e-6 but ended up causing problems, that's why Im asking. Thanks for your input. V-man
|
Sat, 15 May 2004 08:33:12 GMT |
|
|
Mark Duel #2 / 24
|
epsilon for float, double long double
<snippage> Quote: > cout<<"yes, it is equal to PI";
<snippage>
(And in general, the value for epsilon depends on the application) Cheers, Mark Duell
|
Sat, 15 May 2004 08:50:44 GMT |
|
|
Mark Duel #3 / 24
|
epsilon for float, double long double
Quote:
> <snippage> > > cout<<"yes, it is equal to PI"; > <snippage>
> (And in general, the value for epsilon depends on the application)
s/value for/precision of/ Mark Duell
|
Sat, 15 May 2004 08:54:20 GMT |
|
|
Sven Sandber #4 / 24
|
epsilon for float, double long double
Quote:
> if((number+epsilon>=PI)&&(number-epsilon<=PI)) > cout<<"yes, it is equal to PI"; > Is this an OK value of epsilon for 32 bit? What about 64 bit and 80 > bit?
This depends on your application. Every time you do a floating point operation (such as adding or dividing two numbers), there is a potential error introduced. So if you know that your number was created as the sum of 10000 other numbers, you probably need a greater epsilon than if it was created as the sum of 2 numbers. And of course, you need a bigger epsilon for float than for double or long double. But you probably have to find the optimal values by trial and error. Sven Sandberg
|
Sat, 15 May 2004 19:59:37 GMT |
|
|
Lawrence Kir #5 / 24
|
epsilon for float, double long double
Quote: >My system (x86) allows 32 bit, 64 bit and 80 bit IEEE floats. >For 32 bit, this is what Im doing: >float number=somenumber_close_to_PI; >float epsilon=1.0e-5; >if((number+epsilon>=PI)&&(number-epsilon<=PI)) > cout<<"yes, it is equal to PI";
epsilon is a measure of precision which is a relative quantity. The only number that it is sensible to add epsilon to is 1. C provides measures of floating point precision (althougb not quite the same as an epsilon) in <float.h> as FLT_DIG, DBL_DIG, LDBL_DIG and FLT_MANT_DIG, DBL_MANT_DIG, LDBL_MANT_DIG along with FLT_RADIX. Quote: >Is this an OK value of epsilon for 32 bit? What about 64 bit and 80 >bit?
float is guaranteed to have at least 6 decimal digits worth of precision, double and long double 10. For IEEE doubles you get at least 15 digits. 80 bit extended doubles give you something like 19 digits. Quote: >Before, I was using epsilon=1.0e-6 but ended up causing problems, >that's why Im asking.
Lets say you have float number = 1000000.0f; The 6th digit in that case has the value of 1, not 1.0e-6. Your test above would clearly not work in that case. You have to scale your error range according to the magnitude of the value. You might have something like float error; error = 2 * epsilon * number; if((number+error>=PI)&&(number-error<=PI)) The factor of 2 is because a true epsilon value is only defined for the value 1. -- -----------------------------------------
-----------------------------------------
|
Sat, 15 May 2004 20:13:32 GMT |
|
|
Lawrence Kir #6 / 24
|
epsilon for float, double long double
Quote:
>> if((number+epsilon>=PI)&&(number-epsilon<=PI)) >> cout<<"yes, it is equal to PI"; >> Is this an OK value of epsilon for 32 bit? What about 64 bit and 80 >> bit? >This depends on your application.
epsilon is the smallest positive value that when added to 1 produces a result that is different from 1. It has nothing to do with the application, it is a property of a type on the implementation. Quote: >Every time you do a floating point >operation (such as adding or dividing two numbers), there is a potential >error introduced. So if you know that your number was created as the sum >of 10000 other numbers, you probably need a greater epsilon than if it >was created as the sum of 2 numbers.
You are confusing epsilon with the error bounds of a calculation. Quote: >And of course, you need a bigger >epsilon for float than for double or long double. But you probably have >to find the optimal values by trial and error.
It is true that the epsilon for float is usually larger than that for double and long double. -- -----------------------------------------
-----------------------------------------
|
Sat, 15 May 2004 21:59:48 GMT |
|
|
willem veenhove #7 / 24
|
epsilon for float, double long double
Quote:
> > Every time you do a floating point operation (such as adding > > or dividing two numbers), there is a potential error > > introduced. So if you know that your number was created as > > the sum of 10000 other numbers, you probably need a greater > > epsilon than if it was created as the sum of 2 numbers. > You are confusing epsilon with the error bounds of a > calculation.
I almost replied in the same sense. But if you had read the original article, you also would have seen that the OP uses a variable epsilon, which has no direct relation with the machine epsilon which you and I obviously have in mind. So in fact you are the one who is confusing things here :-) willem
|
Sun, 16 May 2004 00:14:21 GMT |
|
|
Pai-Yi HSIA #8 / 24
|
epsilon for float, double long double
Quote:
> Lets say you have > float number = 1000000.0f; > You might have something like > float error; > error = 2 * epsilon * number; > if((number+error>=PI)&&(number-error<=PI)) > The factor of 2 is because a true epsilon value is only defined for the > value 1.
I question about the introduction of the factor 2. Epsilon is defined as the difference between 1 and the smallest value greater than 1 which is representable in the given floating point type. In this floating point type XXX, a number A can not be distinguished from PI while fabs(A-PI) <= PI* XXX_EPSILON. paiyi
|
Sun, 16 May 2004 00:38:43 GMT |
|
|
Pai-Yi HSIA #9 / 24
|
epsilon for float, double long double
Quote:
> Epsilon is defined as the difference between 1 and the smallest value > greater than 1 which is representable in the given floating point type. > In this floating point type XXX, > a number A can not be distinguished from PI while > fabs(A-PI) <= PI* XXX_EPSILON.
If you are SURE that your calculation rests always in the same floating point type, according to the unique representation of a given number, you can directly do TYPE A, PI, ZERO = 0.0; if ((A-PI) == ZERO) {/*...*/} where TYPE stands for float, double, or long double. paiyi
|
Sun, 16 May 2004 00:53:54 GMT |
|
|
Tobias Oe #10 / 24
|
epsilon for float, double long double
Quote:
> > Epsilon is defined as the difference between 1 and the smallest value > > greater than 1 which is representable in the given floating point type. > > In this floating point type XXX, > > a number A can not be distinguished from PI while > > fabs(A-PI) <= PI* XXX_EPSILON. > If you are SURE that your calculation rests always in the same floating > point type, according to the unique representation of a given number, > you can directly do > TYPE A, PI, ZERO = 0.0; > if ((A-PI) == ZERO) {/*...*/} > where TYPE stands for float, double, or long double.
This would work only for types short, int and long and not for float and double :-(. That's the whole point of the epsilon thingy; Precision in floating point calculation is not infinite so floating points are equal when they are close enough. Tobias.
|
Sun, 16 May 2004 01:06:25 GMT |
|
|
Pai-Yi HSIA #11 / 24
|
epsilon for float, double long double
Quote:
> > If you are SURE that your calculation rests always in the same floating > > point type, according to the unique representation of a given number, > > you can directly do > > TYPE A, PI, ZERO = 0.0; > > if ((A-PI) == ZERO) {/*...*/} > > where TYPE stands for float, double, or long double. > This would work only for types short, int and long and > not for float and double :-(.
I don't agree with you. The finite precision of the floating point representation implies that the value stored in the float variable is discrete. There are, hence, only "finite" number of different byte representations. (although this number is very large for float. For e.g., FIXing the bit patterns in sign and in exponent part, 23 bit mantissa yields 2^23 different bit patterns.) Suppose A and PI and ZERO are float. (A-PI) stays also in float. To compare (A-PI) and ZERO, the smart compiler knows how to compare them correctly just as the comparison between two integers. paiyi Quote: > That's the whole point of the epsilon thingy; Precision in floating > point calculation is not infinite so floating points are equal when they > are close enough.
|
Sun, 16 May 2004 02:38:55 GMT |
|
|
Morris Dove #12 / 24
|
epsilon for float, double long double
Quote:
> My system (x86) allows 32 bit, 64 bit and 80 bit IEEE floats. > For 32 bit, this is what Im doing: > float number=somenumber_close_to_PI; > float epsilon=1.0e-5; > if((number+epsilon>=PI)&&(number-epsilon<=PI)) > cout<<"yes, it is equal to PI"; > Is this an OK value of epsilon for 32 bit? What about 64 bit and 80 > bit? > Before, I was using epsilon=1.0e-6 but ended up causing problems, > that's why Im asking. > Thanks for your input.
V-man... A while back I wrote a little C program to answer this question in the context of decimalization of option prices for the Philadelphia Stock Exchange. I think you might enjoy playing with it. If so, you're welcome to download it from http://www.iedu.com/mrd/c/conv2.c HTH -- Morris Dovey West Des Moines, Iowa USA
|
Sun, 16 May 2004 03:07:55 GMT |
|
|
Tobias Oe #13 / 24
|
epsilon for float, double long double
Quote:
> > > If you are SURE that your calculation rests always in the same floating > > > point type, according to the unique representation of a given number, > > > you can directly do > > > TYPE A, PI, ZERO = 0.0; > > > if ((A-PI) == ZERO) {/*...*/} > > > where TYPE stands for float, double, or long double. > > This would work only for types short, int and long and > > not for float and double :-(. > I don't agree with you. > The finite precision of the floating point representation implies > that the value stored in the float variable is discrete. > There are, hence, only "finite" number of different byte representations. > (although this number is very large for float. > For e.g., FIXing the bit patterns in sign and in exponent part, > 23 bit mantissa yields 2^23 different bit patterns.) > Suppose A and PI and ZERO are float. > (A-PI) stays also in float. > To compare (A-PI) and ZERO, the smart compiler knows how to compare > them correctly just as the comparison between two integers.
Yes, the compiler can generate code to compare floating point values for equality but generally, this is not what the programer wants. From the FAQ 14.5: What's a good way to check for "close enough" floating-point equality? A: Since the absolute accuracy of floating point values varies, by definition, with their magnitude, the best way of comparing two floating point values is to use an accuracy threshold which is relative to the magnitude of the numbers being compared. Rather than double a, b; ... if(a == b) /* WRONG */ use something like #include <math.h> if(fabs(a - b) <= epsilon * fabs(a)) for some suitably-chosen degree of closeness epsilon (as long as a is nonzero!). References: Knuth Sec. 4.2.2 pp. 217-8. Tobias.
|
Sun, 16 May 2004 03:19:38 GMT |
|
|
Tak-Shing Cha #14 / 24
|
epsilon for float, double long double
Quote:
> The finite precision of the floating point representation implies > that the value stored in the float variable is discrete. > There are, hence, only "finite" number of different byte representations. > (although this number is very large for float. > For e.g., FIXing the bit patterns in sign and in exponent part, > 23 bit mantissa yields 2^23 different bit patterns.) > Suppose A and PI and ZERO are float. > (A-PI) stays also in float. > To compare (A-PI) and ZERO, the smart compiler knows how to compare > them correctly just as the comparison between two integers.
When A = B + PI - B, you are unlikely to get (A-PI)==ZERO. Tak-Shing
|
Sun, 16 May 2004 03:21:43 GMT |
|
|
V-ma #15 / 24
|
epsilon for float, double long double
Quote:
> > Epsilon is defined as the difference between 1 and the smallest value > > greater than 1 which is representable in the given floating point type. > > In this floating point type XXX, > > a number A can not be distinguished from PI while > > fabs(A-PI) <= PI* XXX_EPSILON. > If you are SURE that your calculation rests always in the same floating > point type, according to the unique representation of a given number, > you can directly do > TYPE A, PI, ZERO = 0.0; > if ((A-PI) == ZERO) {/*...*/} > where TYPE stands for float, double, or long double. > paiyi
Having the calculation rest in the same floating point type is not the issue. I was using 32 bit float for ALL my calculation. In my algorithm, I do a bunch of calculations, then I test whether one number is equal to some other number. In other parts of my algorithm, I test whether 2 line segments cross, whether a line in 3D space crosses a triangle. Unfortunatly, conceptually my technic should work. In practical form (a program) it fails for some cases. Working with floats is extrememly troublesome... This is not typically discussed in progarmming books. I took a course in Numerical Methods and technics were discussed there. I may have to go back and read my notes. V-man
|
Sun, 16 May 2004 08:22:38 GMT |
|
|
Page 1 of 2
|
[ 24 post ] |
|
Go to page:
[1]
[2] |
|