math.nroot [was Re: A brief question.]

Tom Anderson twic at urchin.earth.li
Sun Jul 3 15:26:20 EDT 2005


On Sun, 3 Jul 2005, Tim Peters wrote:

> [Fredrik Johansson]
>
>>>> I'd rather like to see a well implemented math.nthroot. 64**(1/3.0)
>>>> gives 3.9999999999999996, and this error could be avoided.
>
> [Steven D'Aprano]
>>>>>> math.exp(math.log(64)/3.0)
>>> 4.0
>>>
>>> Success!!!
>
> None of this generalizes usefully -- these are example-driven
> curiousities.

I was afraid of that. Thanks for shedding some light on it, though.

>> YES! This is something that winds me up no end; as far as i can tell,
>> there is no clean programmatic way to make an inf or a NaN;
>
> All Python behavior in the presence of infinities, NaNs, and signed 
> zeroes is a platform-dependent accident, mostly inherited from that all 
> C89 behavior in the presence of infinities, NaNs, and signed zeroes is a 
> platform-dependent crapshoot.

Okay. That's a shame.

>> in code i write which cares about such things, i have to start:
>>
>> inf = 1e300 ** 1e300
>> nan = inf - inf
>
> That would be much more portable (== would do what you intended by 
> accident on many more platforms) if you used multiplication instead of 
> exponentiation in the first line.

Yes - that's what i meant to write, but i must have got carried away with 
the asterisks. Sorry about that.

>> And then god forbid i should actually want to test if a number is NaN,
>> since, bizarrely, (x == nan) is true for every x; instead, i have to
>> write:
>>
>> def isnan(x):
>>        return (x == 0.0) and (x == 1.0)
>
> The result of that is a platform-dependent accident too.  Python 2.4
> (but not eariler than that) works hard to deliver _exactly_ the same
> accident as the platform C compiler delivers, and at least NaN
> comparisons work "as intended" (by IEEE 754) in 2.4 under gcc and MSVC
> 7.1 (because those C implementations treat NaN comparisons as intended
> by IEEE 754; note that MSVC 6.0 did not):
>
> So at the Python level you can do "x != x" to see whether x is a NaN
> in 2.4+(assuming that works in the C with which Python was compiled;
> it does under gcc and MSVC 7.1).

I see. I have to confess that i'm using 2.3.

So, is there a way of generating and testing for infinities and NaNs 
that's portable across platforms and versions of python? If not, could we 
perhaps have some constants in the math module for them? math.inf and 
math.nan should do nicely (although there is the question of just _which_ 
nan that should be ...). It wouldn't help with old versions of python, but 
it'd solve the problem for the future.

>> or is this expression:
>>
>> -1.0 ** 0.5
>>
>> Evaluated wrongly?
>
> Read the manual for the precedence rules.  -x**y groups as -(x**y). -1.0 
> is the correct answer.  If you intended (-x)**y, then you need to insert 
> parentheses to force that order.

So i see. Any idea why that precedence order was chosen? It goes against 
conventional mathematical notation, as well as established practice in 
other languages.

Also, would it be a good idea for (-1.0) ** 0.5 to evaluate to 1.0j? It 
seems a shame to have complex numbers in the language and then miss this 
opportunity to use them!

tom

-- 
When you mentioned INSERT-MIND-INPUT ... did they look at you like this?



More information about the Python-list mailing list