Testing floating point numbers for equality

Click For Summary
SUMMARY

This discussion focuses on the challenges of testing floating point numbers for equality in programming, specifically in the context of a Fortran program calculating electric potential. The user encountered issues with infinite results when comparing values close to zero. Solutions proposed include defining a threshold value (TAD = 1e-12) for comparison and using a custom function to determine equality based on a specified number of decimal places. The importance of checking for values near zero and adjusting loop parameters for better accuracy is emphasized.

PREREQUISITES
  • Understanding of floating point arithmetic and its limitations
  • Familiarity with Fortran programming language
  • Knowledge of electric potential calculations in physics
  • Experience with numerical methods and error handling in programming
NEXT STEPS
  • Implement and test the custom equality function for floating point comparisons in various programming languages
  • Research techniques for handling floating point precision issues in numerical simulations
  • Explore the use of thresholds in scientific computing to improve accuracy
  • Learn about alternative numerical libraries that handle floating point operations more robustly
USEFUL FOR

Software developers, physicists, and engineers involved in numerical simulations or calculations requiring precise floating point comparisons.

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   Reactions: 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   Reactions: 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   Reactions: 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   Reactions: 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   Reactions: 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 ·
Replies
8
Views
2K
Replies
2
Views
1K
  • · Replies 10 ·
Replies
10
Views
3K
  • · Replies 3 ·
Replies
3
Views
3K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 1 ·
Replies
1
Views
5K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 2 ·
Replies
2
Views
4K