Fortran - Having to add integer command

  • Context: Fortran 
  • Thread starter Thread starter Nugso
  • Start date Start date
  • Tags Tags
    Fortran Integer
Click For Summary

Discussion Overview

The discussion revolves around a Fortran programming issue related to calculating and printing integer square roots from 1 to 1000. Participants explore why certain integer square roots, specifically 25 and 49, are not displayed in the output when using real number comparisons.

Discussion Character

  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant shares their initial Fortran code and notes that it fails to display certain integer square roots, questioning why adding an integer variable resolves the issue.
  • Another participant explains that comparing real numbers for exact equality can lead to issues due to small arithmetic errors, suggesting the use of a tolerance level for comparisons.
  • It is noted that assigning a real value to an integer variable truncates the value, which may affect comparisons.
  • Further contributions emphasize the presence of "stray bits" in floating-point representations, which can cause certain values to be missed in comparisons.
  • Participants suggest printing values with maximal decimal formatting to reveal these stray bits and discuss the concept of guard bits in floating-point arithmetic.

Areas of Agreement / Disagreement

Participants generally agree on the challenges of comparing real numbers and the potential for stray bits affecting output. However, the specific reasons for the behavior observed in the original code remain somewhat contested, with multiple explanations provided.

Contextual Notes

Limitations include the dependence on floating-point representation and the nuances of real versus integer comparisons in programming. The discussion does not resolve the underlying technical issues but highlights various perspectives on the problem.

Nugso
Gold Member
Messages
170
Reaction score
10
Hello everyone. Today I learned how to write a program which calculates and prints integer squares roots from 1 to 1000. Here is what I wrote:
Code:
program example
real::i
do i=1,1000
if(sqrt(i)**2==i) then
print*,i
end if
end do
end program example

After compling this, 25, 49 etcs can't be seen. It lists like;
1.0000
4.0000
9.0000

and so on. However, if I write it like this;

Code:
program example
real::i
integer::physicsforum
do i=1,1000
physicsforum=sqrt(i)
if(physicsforum**2=i)then
print*,i
end if
end do
end program example

then I do see 25.0000, 49.0000 etc too. What is confusing me is why do I have to add integer for sqrt(i) to see 25.0000, 49.0000?

Thanks.
 
Technology news on Phys.org
You should never compare 'real' numbers for exact equality, because arithmetic inevitably introduces small errors because of the finite number of binary bits used. Your first program probably compares 25.00000 with 25.00001 or 24.99999 or something like that.

When you need to do a comparision like this, you must allow for small deviations from equality by doing something like this:

if (abs(a - b) < epsilon)

where 'epsilon' is a suitably small number.

Or you can try to set up the comparision so that it uses integers instead, like you did in the second program. Here you need to be careful because when you assign a real value to an integer variable, it is truncated to the nearest lower integer, not rounded (which could go either up or down). So 24.99999 would become 24, not 25.
 
By assigning it to an integer you've thrown away the small decimal remainder that is common to floating pt numbers.

This is why programmers never do equals testing like you did but instead do this

if ( abs(sqrt(i)**2 - i) < 0.000001) ...

to determine if they are equal to within some small range
 
Last edited:
because they have some stray bits that the other values don't have.

you'd need to print the values out with maximal decimal formatting to see what the stray bits may be.

For example you might print 1.000,000 but the number is really 1.000,000,001 (commas added for clarity) in memory.

There are also even smaller guard bits that aren't shown normally but can be teased out be multiplying the number up a few orders of magnitude up.

see wikipedia for something on guard bits:

http://en.wikipedia.org/wiki/Guard_digit
 
jedishrfu said:
because they have some stray bits that the other values don't have.

you'd need to print the values out with maximal decimal formatting to see what the stray bits may be.

For example you might print 1.000,000 but the number is really 1.000,000,001 (commas added for clarity) in memory.

There are also even smaller guard bits that aren't shown normally but can be teased out be multiplying the number up a few orders of magnitude up.

see wikipedia for something on guard bits:

http://en.wikipedia.org/wiki/Guard_digit

Thank you very much sir.
 

Similar threads

  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 12 ·
Replies
12
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 19 ·
Replies
19
Views
3K
  • · Replies 13 ·
Replies
13
Views
3K
  • · Replies 12 ·
Replies
12
Views
3K
  • · Replies 5 ·
Replies
5
Views
5K