Problems when averaging a value

Click For Summary

Discussion Overview

The discussion revolves around issues encountered in a Fortran 90 program related to averaging values, specifically the behavior of a variable when its precision is altered. Participants explore the implications of using different data types on numerical accuracy and the resulting output.

Discussion Character

  • Technical explanation
  • Mathematical reasoning

Main Points Raised

  • One participant describes a problem where the variable suma2 does not update correctly when using a single precision real type, despite non-zero contributions from the term s(fixed2(j))/real(nfixed).
  • Another participant suggests that declaring suma2 as real(8) increases the precision to double (64-bit), which may resolve the issue.
  • A participant elaborates that the difference in precision between real (4 bytes) and real(8) (8 bytes) affects the ability to accurately represent small changes when added to larger numbers.
  • Further clarification is provided that real*8 is equivalent to double in C, with a machine epsilon of approximately 2.22e-16, allowing for greater precision in calculations.

Areas of Agreement / Disagreement

Participants generally agree that the precision of the data type affects the accuracy of the calculations, but there is no explicit consensus on the best approach or resolution of the initial problem.

Contextual Notes

The discussion highlights limitations related to numerical precision in programming, particularly in the context of Fortran, but does not resolve the underlying issue of the variable not updating as expected.

jbenet
Messages
2
Reaction score
0
Hi,
I am running a fortran 90 program and I have some problems when getting an average. It happens that at some point the value of suma2 is not updated, even when the value of the term s(fixed2(j))/real(nfixed) is not zero. Below is the output of fort.32. The problem dissapears when suma2 is declared as real(8), could anyone please tell me the reason?

Thank you very much
Code:
real :: suma2

10 do i = 1, ncycle

  call   mc_swap_thermo(n1,nsites,s,sorted,beta,lambda,seed,neigh,iacc,fixed1,fixed2,nfixed,sblock,sfixed,switch_thermo)

  do j = 1, nfixed

    suma2 = suma2 + s(fixed2(j))/real(nfixed)
    write(32,*) suma2, s(fixed2(j)), s(fixed2(j))/real(nfixed)

  end do
 
  steps=steps+1

end do 

   262144.000       0.00000000       0.00000000  
   262144.000      0.139704779       1.16420649E-02
   262144.000       0.00000000       0.00000000  
   262144.000      0.139704779       1.16420649E-02
   262144.000       0.00000000       0.00000000  
   262144.000      0.139704779       1.16420649E-02
   262144.000       0.00000000       0.00000000  
   262144.000      0.139704779       1.16420649E-02
   262144.000      0.139704779       1.16420649E-02
 
Last edited by a moderator:
Technology news on Phys.org
I think the real(8) increases the precision to double ie 64-bit precision whereas the real or real(4) is only 32-bit precision.
 
  • Like
Likes   Reactions: jbenet
jbenet said:
Hi,
I am running a fortran 90 program and I have some problems when getting an average. It happens that at some point the value of suma2 is not updated, even when the value of the term s(fixed2(j))/real(nfixed) is not zero. Below is the output of fort.32. The problem dissapears when suma2 is declared as real(8), could anyone please tell me the reason?

Thank you very much

real :: suma2

10 do i = 1, ncycle

call mc_swap_thermo(n1,nsites,s,sorted,beta,lambda,seed,neigh,iacc,fixed1,fixed2,nfixed,sblock,sfixed,switch_thermo)

do j = 1, nfixed

suma2 = suma2 + s(fixed2(j))/real(nfixed)
write(32,*) suma2, s(fixed2(j)), s(fixed2(j))/real(nfixed)

end do

steps=steps+1

end do

262144.000 0.00000000 0.00000000
262144.000 0.139704779 1.16420649E-02
262144.000 0.00000000 0.00000000
262144.000 0.139704779 1.16420649E-02
262144.000 0.00000000 0.00000000
262144.000 0.139704779 1.16420649E-02
262144.000 0.00000000 0.00000000
262144.000 0.139704779 1.16420649E-02
262144.000 0.139704779 1.16420649E-02
What you're encountering is the difference in precision between real (4 bytes) and real(8) (8 bytes). With 4-byte reals, you have only about 7 digits of precision. When you add .0116 to 262144.00, the change is too small to affect the larger number. Changing to 8-byte reals gives you precision out to 12 or 13 places, if I'm remembering correctly.
 
  • Like
Likes   Reactions: jbenet
Mark44 said:
Changing to 8-byte reals gives you precision out to 12 or 13 places, if I'm remembering correctly.
real*8 is the same as double in C, so the machine epsilon is 2−52 ≈ 2.22e-16, giving 15 to 16 decimal places.
 
  • Like
Likes   Reactions: jbenet and Mark44
Ok, I understand now. Thank you very much
 

Similar threads

  • · Replies 6 ·
Replies
6
Views
3K