Reputation: 923
In Fortran, I want to be able to round a large double precision float to the nearest integer. I attempt this as follows,
PROGRAM rounding
IMPLICIT NONE
INTEGER, PARAMETER :: DP = 8
REAL(KIND=DP) :: value
value = 12345678987.123456
print *, CEILING(value)
END PROGRAM ROUNDING
However, this does not output the correct answer, but instead gives -2147483648
. I appreciate that this is related to the nature and precision of floating points, but rounding a number like this seems a reasonable goal.
Can anyone point me in the right direction?
Upvotes: 1
Views: 167
Reputation: 59998
The integer variable returned by ceiling()
is of a too small kind to contain the value. You have to tell ceiling to produce an integer of a larger kind. Otherwise it uses the default integer.
For example by
print *, CEILING(value, kind=dp)
(assuming there exist such kind, but it should exist, if DP
is selected sensibly)
Do note that kind=8
is ugly and not portable. You should not use literal constants such as 8
. There is no guarantee that any such kind exist.
So I would use:
INTEGER, PARAMETER :: DP = kind(1.d0)
For the integer kind you can use SELECTED_INT_KIND to select the kind with enough digits like
INTEGER, PARAMETER :: IP = SELECTED_INT_KIND(15)
print *, CEILING(value, kind=IP)
or use any other method from Fortran: integer*4 vs integer(4) vs integer(kind=4)
Upvotes: 1