View previous topic :: View next topic |
Author |
Message |
Helen
Joined: 15 Mar 2018 Posts: 9
|
Posted: Tue Apr 17, 2018 10:40 am Post subject: floaty problem (beginner) |
|
|
must be a stupid question but...
i have a variable a = 1.5
i add to it 0.00125
and then a shows in a write as 1.50124999997
what am i doing wrong?
is there a different declaration for fixed floats? |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2555 Location: Sydney
|
Posted: Tue Apr 17, 2018 10:55 am Post subject: |
|
|
try the following code: Code: | real*8 a8
real*4 a4
a8 = 1.5
a8 = a8 + .00125
write (*,*) 'a8 =',a8
a4 = 1.5
a4 = a4 + .00125
write (*,*) 'a4 =',a4
a8 = .00125
write (*,*) 'a8 =',a8
a8 = .00125d0
write (*,*) 'a8 =',a8
end |
The problem is 1.5 = 1.5d0 ( the 8 byte representation of the 2 constants is the same)
but .00125 is not the same as .00125d0
( although .125 is the same as .125d0 ) |
|
Back to top |
|
|
Helen
Joined: 15 Mar 2018 Posts: 9
|
Posted: Tue Apr 17, 2018 10:54 pm Post subject: fascinating stuff but... |
|
|
i declared my a as real*4
and all was going well but...
on the 1924th (or so) iteration of adding 0.00125 to 1.5...
when i would expect the value of 3.90255 to go to 3.90380
it actually jumps to 3.90381
this is really quite interesting... any suggestions from my wizards greatly appreciated! |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1887
|
Posted: Tue Apr 17, 2018 11:48 pm Post subject: |
|
|
You have an interesting adventure ahead of you. Try the following calculation using ftn95 /lgo, then ftn95 /64 /lgo, and on a pocket calculator if you have one:
Code: | program tst
real :: x=4.0, y=3.0
print *,(x/y-1)*y-1
end |
After observing and trying to explain the results, please read this article:
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Wed Apr 18, 2018 11:50 am Post subject: |
|
|
Things won't get much better with integers, just different. Try this, for example:
Code: | PROGRAM INT
INTEGER*1 K
K = 0
DO 10 I=1,260
K = K + 1
WRITE(*,*) I, K
10 CONTINUE
END |
Or (for a much longer loop) with INTEGER*2 or INTEGER*4.
Eddie |
|
Back to top |
|
|
Helen
Joined: 15 Mar 2018 Posts: 9
|
Posted: Wed Apr 18, 2018 12:12 pm Post subject: managed a workaround |
|
|
Did a more accurate calculation on the iteration (instead of adding to previous, possibly wonky, value, I RE-calculated).
Thanks for this guys! |
|
Back to top |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Wed Apr 18, 2018 5:44 pm Post subject: |
|
|
Managing the propagation of rounding errors is a skill that can be picked up over time. It helps to build up your own library of useful information, books, websites etc.
Here is a good site that considers floating point.
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
In the mid 80s I was fortunate to own a workstation running RISC-OS that was designed to be programmed. It had a C and Fortran 77 compiler. It also had a large 8x8 card as a "floating point co processor". Nowadays this is just built into the chips. However, I still have the manual that came with that card (not the machine or card now sadly) and it contains a lot of useful diagrams that I still consult today.
What a shame proper manuals have disappeared from computer stuff we all purchase. All we get these days is a getting started card with scribbled cartoons. _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
|
Helen
Joined: 15 Mar 2018 Posts: 9
|
Posted: Wed Apr 18, 2018 5:52 pm Post subject: yes, thanks! |
|
|
Thanks for this... yes, I'll ride the learning curve like a trooper. Checked out that page (same one given earlier I think... great minds think alike!) |
|
Back to top |
|
|
|