Testing floating point numbers for equality

AI Thread Summary
The discussion revolves around a programming issue related to calculating electric fields and potentials where two values, r1o and r2o, can lead to infinite results when they equal a specific condition. The original poster struggles with testing floating-point numbers for equality, particularly when values approach zero, which can cause inaccuracies. Suggestions include implementing a test for values being smaller than a defined threshold to avoid infinite results. Participants recommend improving the loop structure for clarity and efficiency, suggesting alternatives to fixed step sizes. A proposed solution involves defining a tolerance level (TAD) for comparing floating-point numbers, using methods like absolute differences or ratiometric comparisons to determine equality. The poster reports success after applying these suggestions.
ulfaazmi
Messages
17
Reaction score
1
Anybody can help me?? The problem is when the value of (r1o = r, and r2o=r), the result will be infinite,,,what the the probably test for this case?? I can't test floating point numbers for equality ( if r == 0.5 and r == -0.5). But, when running this program without test floating point, it is success. however, the result is not true because it should be infine value or missing.
This is my code :

Fortran:
Program EfieldEpotential
 implicit none
 integer,parameter :: ikind = selected_real_kind(p=15)
 real (kind=ikind)::E1,E2,E,V,V1,V2
 real :: k,r1o,r2o,q1,q2,r,r1,r2
 integer :: i,n=100

! initial position
 r1o = -0.5
 r2o = 0.5
 q1 = -1  ! the charge at r1o
 q2 = 1   ! the charge at r2o
 k = 9E+9

 do i = 1,n
 r  = -2.1 + real(i)*0.1
 r1 = abs(r1o-r)
 r2 = abs(r2o-r)
 E1 = k*q1/r1**2
 E2 = k*q2/r2**2
 E  = E1+E2
 V1 = k*q1/r1
 V2 = k*q2/r2
 V  = V1+V2

if ( r>2.1) then
     stop 'Program End'
     else
        write(*,30) r,E,V
    30 format(7x,f8.2,8x,E15.7,8x,E15.7)
    
 end if
 end do
 End
<Moderator's note: code tags added>

Thank you.
 
Last edited by a moderator:
Technology news on Phys.org
You have to test for r1 or r2 being smaller than a very small number, to see if it is near 0.

Some comments on your program. First, please use code tags when posting code at PF.

Second, your loop is quite strange. Either calculate the step size (instead of using a fixed value of 0.1) so that n = 100 points take you to r = 2.1, or calculate the value of n needed to get just the right number of points. Alternatively, you can use a do without a counter
Fortran:
do
   ! some code here
   if (r > 2.1) exit
   ! some code here
end do
 
  • Like
Likes jim mcnamara, ulfaazmi and Nik_2213
"You have to test for r1 or r2 being smaller than a very small number, to see if it is near 0."

Or their absolute difference being less than 'baseline noise'...

Met this using HP Technical BASIC (Run under Unix on a plasma-screen 'luggable' with integral printer !), which, IIRC, had a totally-huge dynamic range for its FP variables, and a real-neat 'close enough' function to prevent near misses and infinite iterations ...
 
  • Like
Likes ulfaazmi
DrClaude said:
You have to test for r1 or r2 being smaller than a very small number, to see if it is near 0.

Some comments on your program. First, please use code tags when posting code at PF.

Second, your loop is quite strange. Either calculate the step size (instead of using a fixed value of 0.1) so that n = 100 points take you to r = 2.1, or calculate the value of n needed to get just the right number of points. Alternatively, you can use a do without a counter
Fortran:
do
   ! some code here
   if (r > 2.1) exit
   ! some code here
end do
DrClaude said:
You have to test for r1 or r2 being smaller than a very small number, to see if it is near 0.

Some comments on your program. First, please use code tags when posting code at PF.

Second, your loop is quite strange. Either calculate the step size (instead of using a fixed value of 0.1) so that n = 100 points take you to r = 2.1, or calculate the value of n needed to get just the right number of points. Alternatively, you can use a do without a counter
Fortran:
do
   ! some code here
   if (r > 2.1) exit
   ! some code here
end do
thank you for your advices and help. I will do it.
 
  • Like
Likes Nik_2213
It will depend on the application. I define something like; TAD = 1e-12.
Then I can use; If Abs( f1 – f2 ) < TAD Then equal.
Or ratiometric; If Abs( f1 / f2 – 1 ) < TAD Then equal.
 
  • Like
Likes scottdave and ulfaazmi
Try this function

C:
template<int DECIMALS> inline bool equals(float f1, float f2){
    return (fabs(f1 - f2) < 1.0f / (10.0f * static_cast<float>(DECIMALS)));
}

...

if (equals<3>(f1, f2)) dostuff();
 
  • Like
Likes ulfaazmi
Baluncore said:
It will depend on the application. I define something like; TAD = 1e-12.
Then I can use; If Abs( f1 – f2 ) < TAD Then equal.
Or ratiometric; If Abs( f1 / f2 – 1 ) < TAD Then equal.

I have tried it and success. thank you very much.
 
Baluncore said:
It will depend on the application. I define something like; TAD = 1e-12.
Then I can use; If Abs( f1 – f2 ) < TAD Then equal.
Or ratiometric; If Abs( f1 / f2 – 1 ) < TAD Then equal.
I have used something along the same lines.
 

Similar threads

Replies
8
Views
2K
Replies
4
Views
3K
Replies
3
Views
2K
Replies
2
Views
3K
Replies
5
Views
2K
Replies
2
Views
4K
Back
Top