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

Rounding issue with output formats

Arjen_Markus
Honored Contributor I
1,215 Views
Hello,

we ran into a small but annoying problem with formatted output. Here is
an illustration of the issue (note that all numbers are exactly representable):

PROGRAM checkrounding

write (*,'(4x,f8.1)') 0.25

write (*,'(4x,f8.2)') 0.125

write (*,'(4x,f8.3)') 0.0625

write (*,'(4x,f8.4)') 0.03125

end

This program produces:

0.2
0.12
0.062
0.0312

Apparently this is "round to even".
If I compile this program with gfortran I get:

0.3

0.13

0.063

0.0313

And this rounding mode is more in line with theoriginal program (we do not know
with what compiler it was compiled).

The question is: howcan we getthis round-up mode? Should I use ieee_arithmetic for this?
Or is there a compile option?

Regards,

Arjen

0 Kudos
6 Replies
mecej4
Honored Contributor III
1,215 Views
> Apparently this is "round to even".

I don't think so. Rather, it is the "round to nearest or even" rule that I learned in school in the 1950s. The second part of the prescription comes into play when the part being rounded off is 5 X 10^{-n}.
0 Kudos
Arjen_Markus
Honored Contributor I
1,215 Views
Right, sothat is the proper name?

I tried the following variation to see if the Fortran 2003 IEEE modules could solve this:

PROGRAM checkrounding

use, intrinsic :: ieee_arithmetic

call ieee_set_rounding_mode( ieee_nearest )

write (*,'(4x,f8.1)') 0.25

write (*,'(4x,f8.2)') 0.125

write (*,'(4x,f8.3)') 0.0625

write (*,'(4x,f8.4)') 0.03125

end

(By the way: The online documentation mentions ieee_exceptions as the module for this,
but that leads to an unresolved external!)

The result is slightly "better", but also more confusing:

0.2

0.12

0.063

0.0313

Regards,

Arjen

0 Kudos
Steven_L_Intel1
Employee
1,215 Views
What usage led to an unresolved external?

The default is "round to nearest". A good explanation of this can be found here.
0 Kudos
Arjen_Markus
Honored Contributor I
1,215 Views
I used the statement:

use, intrinsic :: ieee_exceptions

in accordance with the online help (the following copied from there):

IEEE_SET_ROUNDING_MODE

Intrinsic Module Subroutine (Generic): Sets the IEEE rounding mode.

Module

USE, INTRINSIC :: IEEE_EXCEPTIONS

Syntax

CALL IEEE_SET_ROUNDING_MODE (round_value)

round_value

(Output) Must be scalar and of type TYPE (IEEE_ROUND_TYPE). It specifies one of the following IEEE floating-point rounding values:

IEEE_DOWN, IEEE_NEAREST, IEEE_TO_ZERO, IEEE_UP, or IEEE_OTHER.


Now that I looked at it again, the example uses "use ieee_arithmetic".

Regards,

Arjen

0 Kudos
Arjen_Markus
Honored Contributor I
1,215 Views
Oh dear, I have been confusing myself:

- The version where the last digit is always 2 was produced on Linux, using Intel Fortran 12.0.3
- The version that produces both 2's and 3's was produced on Windows, using Intel Fortran 11.1.065

There is NO influence of the rounding mode on the result. I have tried all five- on Windows - and the result
remains the same.

Regards,

Arjen
0 Kudos
Steven_L_Intel1
Employee
1,215 Views
Thanks for pointing this out. I have alerted our writers to the error. Other routines with the wrong module mentioned are IEEE_GET_FLAG and IEEE_GET_UNDERFLOW_MODE.
0 Kudos
Reply