Discussion:
mantissa and exponent in base 10
Steven D'Aprano
2010-10-06 22:54:20 UTC
Permalink
I want the mantissa and decimal exponent of a float, in base 10:

mantissa and exponent of 1.2345e7
=> (1.2345, 7)

(0.12345, 8) would also be acceptable.
math.frexp(1.2345e7)
(0.73581933975219727, 24)

Have I missed a built-in or math function somewhere?
--
Steven
Robert Kern
2010-10-06 23:25:45 UTC
Permalink
Post by Steven D'Aprano
mantissa and exponent of 1.2345e7
=> (1.2345, 7)
(0.12345, 8) would also be acceptable.
math.frexp(1.2345e7)
(0.73581933975219727, 24)
Have I missed a built-in or math function somewhere?
|7> def frexp10(x):
..> exp = int(math.log10(x))
..> return x / 10**exp, exp
..>

|8> frexp10(1.2345e7)
(1.2344999999999999, 7)
--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
Jason Swails
2010-10-07 00:23:47 UTC
Permalink
On Wed, Oct 6, 2010 at 6:54 PM, Steven D'Aprano <
Post by Steven D'Aprano
mantissa and exponent of 1.2345e7
Perhaps not the prettiest, but you can always use string manipulations:

def frexp_10(decimal):
parts = ("%e" % decimal).split('e')
return float(parts[0]), int(parts[1])

You could also create your own mathematical function to do it

def frexp_10(decimal):
import math
logdecimal = math.log10(decimal)
return 10 ** (logdecimal - int(logdecimal)), int(logdecimal)

Testing the timings on those 2 functions for the number 1.235323e+09 on my
machine had the math-version at about 3x faster than the string version
(admittedly it was a single conversion... who knows what the general answer
is). The math module was loaded at the top of the program, so that didn't
add to the time of the math-execution.

Good luck!
Jason

=> (1.2345, 7)
Post by Steven D'Aprano
(0.12345, 8) would also be acceptable.
math.frexp(1.2345e7)
(0.73581933975219727, 24)
Have I missed a built-in or math function somewhere?
--
Steven
--
http://mail.python.org/mailman/listinfo/python-list
--
Jason M. Swails
Quantum Theory Project,
University of Florida
Ph.D. Graduate Student
352-392-4032
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20101006/5e866a2e/attachment.html>
Ulrich Eckhardt
2010-10-07 06:23:33 UTC
Permalink
Post by Steven D'Aprano
mantissa and exponent of 1.2345e7
=> (1.2345, 7)
(0.12345, 8) would also be acceptable.
[...]
Post by Steven D'Aprano
Have I missed a built-in or math function somewhere?
The integral, decimal exponent is just the floor/ceiling of log10 of that
number.

Uli
--
Sator Laser GmbH
Gesch?ftsf?hrer: Thorsten F?cking, Amtsgericht Hamburg HR B62 932
Dave Angel
2010-10-07 11:11:37 UTC
Permalink
Post by Steven D'Aprano
mantissa and exponent of 1.2345e7
=> (1.2345, 7)
(0.12345, 8) would also be acceptable.
math.frexp(1.2345e7)
(0.73581933975219727, 24)
Have I missed a built-in or math function somewhere?
First point is that this is a conversion, since the float is stored
internally using a binary exponent. So anything you do with logs might
just give roundoff errors, one way or another. I'd therefore suggest
converting the number explicitly, using whatever approach is appropriate
to the further processing of the number.

If you want the version that will display, then convert it to a string,
and parse that.

If you want to do further processing, use the decimal module to convert
it. Once it's converted, there's an as_tuple() method that will give
you an exact representation of the original value. That may not be the
same mantissa as you'd get with the original, and for numbers like
9.99999999 or whatever, this could be significant.

DaveA
C or L Smith
2010-10-07 15:51:55 UTC
Permalink
I just sent a similar suggestion to tutor: check out the %g format.
print '%g' % 1.2345e7
1.2345e+07
print '%g' % 1.2345e-7
1.2345e-07
print '%g' % 1.2345
1.2345
... s = ('%.'+'%ig' % sigfigs) % n # check docs for a better way?
... if 'e' in s: m, e = s.split('e')
... else: m, e = s, 0
... m, e = float(m), float(e)
... if m >= 10:
... m /= 100
... e += 2
... elif m >= 1:
... m /= 10
... e += 1
... return m, e
...
me(9.9999999)
(0.10000000000000001, 2.0)
me(12345)
(0.12350000000000001, 5.0)
me(1.2345e-9)
(0.12350000000000001, -8.0)
me(1.2345e-9, 2)
(0.12, -8.0)

Best regards,
Chris Smith
Jason Swails
2010-10-07 17:40:21 UTC
Permalink
Post by C or L Smith
I just sent a similar suggestion to tutor: check out the %g format.
print '%g' % 1.2345e7
1.2345e+07
print '%g' % 1.2345e-7
1.2345e-07
print '%g' % 1.2345
1.2345
... s = ('%.'+'%ig' % sigfigs) % n # check docs for a better way?
s = ('%%%ig' % sigfigs) % n # double-% cancels the %

... if 'e' in s: m, e = s.split('e')
Post by C or L Smith
... else: m, e = s, 0
... m, e = float(m), float(e)
... m /= 100
... e += 2
... m /= 10
... e += 1
... return m, e
...
me(9.9999999)
(0.10000000000000001, 2.0)
me(12345)
(0.12350000000000001, 5.0)
me(1.2345e-9)
(0.12350000000000001, -8.0)
me(1.2345e-9, 2)
(0.12, -8.0)
Best regards,
Chris Smith
--
http://mail.python.org/mailman/listinfo/python-list
--
Jason M. Swails
Quantum Theory Project,
University of Florida
Ph.D. Graduate Student
352-392-4032
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20101007/52340691/attachment.html>
C or L Smith
2010-10-08 13:43:02 UTC
Permalink
Post by Jason Swails
s = ('%%%ig' % sigfigs) % n # double-% cancels the %
'%%.%ig' % 3 % 4.23456e-5
'4.23e-05'

/c

Loading...