This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Inline round for IA64


As far as I can seem from this patch, it rounds incorrectly.
This is a problem with the library version as well, I believe.

The issue is that one cannot round a positive float to int
by adding 0.5 and truncating. (Same issues with negative values
and subtracting 0.5, of course). This gives an error for the
predecessor of 0.5. The between Pred (0.5) and 0.5 is half that of
pred (1.0) and 1.0. So the value of Pred (0.5) + 0.5 lays exactly
halfway Pred (1.0) and 1.0. The CPU rounds this halfway value to
even, or 1.0 in this case.

So try rounding .4999999999999999444888487687421729788184165954589843750
using IEEE double on non-x86 platform, and you'll see it gets rounded to 1.0.
A similar problem exists with large odd integers between 2^52+1 and 2^53-1,
where adding 0.5 results in a value exactly halfway two integers,
rounding up to the nearest even integer. So, for IEEE double,
4503599627370497 would round to 4503599627370498.


These issues can be fixed by not adding/subtracting 0.5, but Pred (0.5).
As shown above, this rounds to 1.0 correctly for 0.5. For larger values
halfway two integers, the gap with the next higher representable number will
only decrease so the result will always be rounded up to the next higher
integer. For this technique to work, however, it is necessary that the
addition will be rounded to the target precision according to IEEE
round-to-even semantics. On platforms such as x86, where GCC implicitly
widens intermediate results for IEEE double, the rounding to integer
should be performed entirely in long double mode, using the long double
predecessor of 0.5.


See ada/trans.c around line 5340 for an example of how Ada does this.

-Geert

On Apr 7, 2005, at 05:38, Canqun Yang wrote:
Gfortran translates the Fortran 95 intrinsic DNINT to
round operation with double precision type argument
and return value. Inline round operation will speed up
the SPEC CFP2000 benchmark 189.lucas which contains
function calls of intrinsic DNINT from 706 (SPEC
ratio) to 783 on IA64 1GHz system.

I have implemented the double precison version of
inline round. If it is worth doing, I can go on to
finish the other precision mode versions.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]