user1887919
user1887919

Reputation: 923

Rounding large floats to integer

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

Answers (1)

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

Related Questions