https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711
--- Comment #11 from Steve Kargl <sgk at troutmask dot apl.washington.edu> --- On Thu, Aug 20, 2020 at 01:47:58PM +0000, bre08 at eggen dot co.uk wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96711 > > --- Comment #10 from B Eggen <bre08 at eggen dot co.uk> --- > I've been experimenting with the suggested work-around > > m = anint(y) > > This works for larger numbers, even in quad precision, however, it breaks down > a long way before the integer*16 range is exhausted, consider the code below, > which starts with 2^113 and tries to double it, minus 1. The minus 1 is not > taking effect: > Of course, that is going to fail if you want an exact result. REAL(16) is a floating point format, which has 113 digits of precision. This means that integers less than 2**113 are exactly representable as REAL(16) floating point numbers. When you double (2._16)**113 to (2._16)**114, that is a prefectly fine REAL(16) floating point number. Subtracting 1._16 from (2._16)**114 is a valid floating point operation. Your problem lies in that result is rounded, and 1._16 is less than epsilon(1._16) in comparison to (2._16)**114. > I guess at some point NINT() will be fixed, can anyone suggest a robust > workaround that is valid until 2^127-1 ? If you're trying to use floating point arithmetic in computations and you need exact integral values up to 2**127-1, then there isn't a REAL type that works. If you're looking for arbitrary precision arithmetic and you want to use Fortran, I suggest that you google "David Bailey arithmetic".