Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Double Precision to Int

rdsrivathsa
Beginner
844 Views
I have a very simple question. I might better pose it with this sample program.

[cpp]program test

real*8 a,b,c
integer d

a = 5.6
b = 0.1
c = a/b
d = int(c)

write (*,*) a,b,c,d

end[/cpp]

The output is 5.6, 0.1, 56, 55 (I did not show the zeroes after the decimal place which also appear in the display)

I understand that I am assigning single-precisionconstants to double precision variables and there could be issues with that. I tried using the /fpconstant option in the Configuration Property but the outputis unchanged.

One workaround is to add an infinitesimal value to c, such as 1.0e-8 to c beforing converting to an integer. But, I was wondering if there was some more elegant way.

Thanks!
0 Kudos
2 Replies
abhimodak
New Contributor I
844 Views
Try using nint(c) which gives the nearest integer.

FYI:

(1) The above program "as is" gives me 5.59999990463257, 0.100000001490116, 55.999982118607, 55. Use of nint(c) gives the last as 56.

(2) When using a = 5.6d0 and b = 0.1d0 I get the zeros after decimal as you mention but int(c) is still 55.

(3) When using real*4 and a = 5.6, b = 0.1, I get the zeros after decimal AND int(c) = 56.

I think you may want to read perils of real numbers and related articles by Steve Lionel and be careful with these round-off etc.

Abhi
0 Kudos
jparsly
New Contributor I
844 Views
This isn't a real or double precision issue; its a fundamental feature of floating point representation.
Floating point numbers are broken down into the sum of positive and negative powers of 2, and many numbers
don't have exact representations.

.1 is, in fact, such a number. When you try to store .1 in a variable. The number stored is going to be
either slightly above or below the real value of .1

It appears the result of your calculation is actually something like 55.9999999... which gets rounded up
by the write statement. The INT function truncates rather than rounds, so the
.999999 part gets thrown out.

This is just something you have to learn to deal with. You should never, for example, test whether
a floating point number is exactly equal to another. Instead you should test whether the absolute value of the difference between the numbers is "close enough" for them to be considered to be the same.

Other languages (and at leat one version of Fortran that I have encounted) have fixed decimal arithmetic
available as an option. This uses a decimal rather than a binary representation, with numbers stored
to a special number of digits after the decimal point. This is popular for handling financial numbers that
need to be exact to the penny.









Quoting - rdsrivathsa
I have a very simple question. I might better pose it with this sample program.

[cpp]program test

real*8 a,b,c
integer d

a = 5.6
b = 0.1
c = a/b
d = int(c)

write (*,*) a,b,c,d

end[/cpp]

The output is 5.6, 0.1, 56, 55 (I did not show the zeroes after the decimal place which also appear in the display)

I understand that I am assigning single-precisionconstants to double precision variables and there could be issues with that. I tried using the /fpconstant option in the Configuration Property but the outputis unchanged.

One workaround is to add an infinitesimal value to c, such as 1.0e-8 to c beforing converting to an integer. But, I was wondering if there was some more elegant way.

Thanks!

0 Kudos
Reply