Chris Barker wrote:
-Scott David Daniels wrote:
How about:
import math
def IsFloat(s):
try:
x = float(s)
return x == 0.0 or 0.0 != math.frexp(x)[0]
except ValueError:
return False # ValueError either from the float or frexp
Again, I think the behaviour of math.frexp is going to be system/compiler/mathlib dependent.
Actually, frexp / ldexp / modf were designed to allow access to
floating point in a way that allowed implementation of higher-
precision software.
My mistakes were in the comparison and float handling.work:
With Python 2.3 on Linux:
IsFloat("23e999999")
OverflowError: math range error
This OverFlow is from float(string).
Now, you could do:
except (ValueError, OverflowError):
Which _is_ the right thing to do
Which seems to work, but still fails on a NaN:
NaN Is a valid Float
(note: msc doesn't produce NaNs from the same string)
return x == 0.0 or 0.0 != math.frexp(x)[0]
This was the problem: The NaN compares equal to 0.0, so no frexp used.
I'm also not sure, without doing more math that I can handle at the moment, if math.frexp() can take any valid float.
It can indeed. The exponent field of all IEEE floats are
significantly smaller than storage for an int. frexp will
easily be able to store the exponent, and the fraction should
simply be "normalized" to .5 <= fraction < 1.0 (a not-so-
difficult task). Numbers in that range are easy to represent
in pretty much all known floating point systems.
This should do the trick:
def IsFloat(s):
try:
vals = math.frexp(float(s))
except (ValueError, OverFlowError):
return False # ValueError either from the float or
return vals == (0.0, 0) or 0.5 <= abs(vals[0]) < 1.0
frexp should return 0.0 for the fraction part of all non-numbers
(NaNs, Infs) as well as for 0.0 (and set an error), but in the NaN
cases, it should _not_ return a zero exponent (spec as remembered).
I still think explicitly testing for +Inf, -Inf and NaN may be the only way, and that makes it explicit how you are handling those values, which may, in fact, be valid for a given application.
But the only way I know of testing for those values involves
either IEEE - conformant predicates (isNan, isInf, ...) which
are infrequently implemented correctly, or looking at frexp
results.
-Scott David Daniels