(original) (raw)
Ok. I'm wrong on that example.
On Wed, Mar 21, 2018, 9:11 PM Tim Peters <tim.peters@gmail.com> wrote:
\[David Mertz <mertz@gnosis.cx>\]
\>> For example, this can be true (even without reaching inf):
\>>
\>> >>> x.is\_integer()
\>> True
\>> >>> (math.sqrt(x\*\*2)).is\_integer()
\>> False
\[Mark Dickinson <dickinsm@gmail.com> \]
\> If you have a moment to share it, I'd be interested to know what value of
\> \`x\` you used to achieve this, and what system you were on. This can't happen
\> under IEEE 754 arithmetic.
I expect it might happen under one of the directed rounding modes
(like "to +infinity").
But under 754 binary round-nearest/even arithmetic, it's been formally
proved that sqrt(x\*x) == x exactly for all non-negative finite x such
that x\*x neither overflows nor underflows (and .as\_integer() has
nothing to do with that very strong result):
https://hal.inria.fr/hal-01148409/document
OTOH, the paper notes that it's not necessarily true for IEEE decimal
arithmetic; e.g.,
\>>> import decimal
\>>> decimal.getcontext().prec = 4
\>>> (decimal.Decimal("31.66") \*\* 2).sqrt() # result is 1 ulp smaller
Decimal('31.65')
\>>> decimal.getcontext().prec = 5
\>>> (decimal.Decimal("31.660") \*\* 2).sqrt() # result is 1 ulp larger
Decimal('31.661')