Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Get Mantissa and exponent from double?

2,113 views
Skip to first unread message

Sundar

unread,
Jun 18, 2008, 7:19:14 AM6/18/08
to
Hi,

How do I get Mantissa and exponent from double?

For eg.
* If the value is 15.0E0 then I want to get mantissa =.15000, exponent
= 2
* If the value is 1.3E-3 then I want to get mantissa = .13000,
exponent = -2

How can we do this in java? Any pointers is highly appreciated.

Thanks in advance.

Eric Sosman

unread,
Jun 18, 2008, 7:46:30 AM6/18/08
to

It's a bit awkward, because Java `double' uses a base-two
representation and you want to work in base-ten. The best I
can suggest is something like

double value = ...;
int exponent = (int)Math.log10(value) + 1;
double mantissa = value * Math.pow(10.0, -exponent);

(You'll need additional code to deal with negative or zero
values, and you may need to make some decisions about how to
handle NaNs and infinities.)

Be aware that this procedure will perturb the numbers a
little, so `mantissa * Math.pow(10.0, exponent)' will usually
*not* be exactly equal to `value'.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Patricia Shanahan

unread,
Jun 18, 2008, 8:40:54 AM6/18/08
to

The actual mantissa and exponent are related to the binary
representation. What you seem to want are those values for a decimal
conversion of the number.

I can see two ways of approaching it, through BigDecimal or by parsing
the formatted String representation. Each approach does the binary to
decimal conversion for you.

Using BigDecimal, you can do it exactly, which may or may not be what
you want. Note that 1.3E-3 is not the exact value of any double.
Alternatively, consider whether you want double at all, rather than
working in BigDecimal.

Patricia

Mark Space

unread,
Jun 18, 2008, 3:22:00 PM6/18/08
to

You might consider doubleToLongBits() and then check the IEEE 754 spec
yourself.

Patricia Shanahan

unread,
Jun 18, 2008, 3:44:38 PM6/18/08
to

That would give the binary exponent and mantissa. That may be what is
really wanted, although the examples show decimal, given the fact that
Java double is binary based.

The OP may not have easy access to a copy of IEEE 754, but
http://en.wikipedia.org/wiki/IEEE_754 contains enough data for
extracting the binary exponent and mantissa from the bit pattern.
Remember to reinstate the hidden bit in normalized numbers.

Patricia

Eric Sosman

unread,
Jun 18, 2008, 3:50:49 PM6/18/08
to

... but that will only get him a binary exponent and
a binary mantissa. For his value 15.0E0 it would yield
an exponent of 4 and a mantissa of 0.9375, not the 2 and
0.15 he's looking for.

Besides, he'd be better off using Math.getExponent()
and Math.scalb().

--
Eric....@sun.com

Mark Space

unread,
Jun 18, 2008, 7:05:53 PM6/18/08
to
Eric Sosman wrote:

>
> ... but that will only get him a binary exponent and
> a binary mantissa. For his value 15.0E0 it would yield
> an exponent of 4 and a mantissa of 0.9375, not the 2 and
> 0.15 he's looking for.

ah, ok, I didn't see that initially, good point.

Roedy Green

unread,
Jun 18, 2008, 7:08:38 PM6/18/08
to
On Wed, 18 Jun 2008 04:19:14 -0700 (PDT), Sundar
<sunda...@gmail.com> wrote, quoted or indirectly quoted someone who
said :

>ow do I get Mantissa and exponent from double?
>
>For eg.
>* If the value is 15.0E0 then I want to get mantissa =.15000, exponent
>= 2
>* If the value is 1.3E-3 then I want to get mantissa = .13000,
>exponent = -2

see http://mindprod.com/jgloss/floatingpoint.html#CALC
--

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Sundar

unread,
Jun 19, 2008, 2:16:15 AM6/19/08
to

>
>      Besides, he'd be better off using Math.getExponent()
> and Math.scalb().

Problem is I cannot use Java 1.6, I got to use only Java 1.4.2 and
these methods Math.getExponent() and Math.scalb() do not exisit in
1.4.2.

>
> ... but that will only get him a binary exponent and
> a binary mantissa. For his value 15.0E0 it would yield
> an exponent of 4 and a mantissa of 0.9375, not the 2 and
> 0.15 he's looking for.

How do I convert exponent of 4 and a mantissa of 0.9375 to the 2 and
0.15 which I am looking for.

Thanks again.

Sundar

John B. Matthews

unread,
Jun 19, 2008, 6:17:39 AM6/19/08
to
In article
<7477a10e-905b-4e85...@27g2000hsf.googlegroups.com>,
Sundar <sunda...@gmail.com> wrote:

> I [have] only Java 1.4.2.
> [...]
> How do I convert [15.0E0] to the 2 and 0.15 which I am looking for.

Patricia already suggested parsing the formatted String representation.
Use a DecimalFormat with your desired precision, e.g. ".00000E0", and
split the string on the "E".

John
--
John B. Matthews
trashgod at gmail dot com
home dot woh dot rr dot com slash jbmatthews

Eric Sosman

unread,
Jun 19, 2008, 8:07:24 AM6/19/08
to

My advice would be "Don't." Unless you have some powerful
reason to avoid logarithms (which would appear to be at the
core of the task here), see my first suggestion on this thread.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Sundar

unread,
Jun 19, 2008, 10:08:52 AM6/19/08
to
>
>      My advice would be "Don't."  Unless you have some powerful
> reason to avoid logarithms (which would appear to be at the
> core of the task here), see my first suggestion on this thread.

Accuracy of the result is of highest priority, se we cannot use
logarithms.

Patricia Shanahan

unread,
Jun 19, 2008, 10:31:02 AM6/19/08
to

It can be done with perfect accuracy using BigDecimal.

First use the BigDecimal(double) constructor to get a BigDecimal with
the same value as your double. The scale will be the smallest scale that
makes the unscaled value an integer. Use the precision() method to find
out the adjustment to the mantissa range you want. Use movePointRight to
multiply or divide by a power of ten to get the mantissa as a BigDecimal.

Note that one of your original examples will not give the result you
expect if you do the job exactly. 1.3E-3 is not the exact value of any
double. The double will be the closest one to it, and the mantissa will
not be .13000, but something that matches it to about 16 decimal places.

If you prefer to get the sort of result you expected, even at the
expense of loss of accuracy, it would be better to parse a formatted
String representation.

Patricia

Eric Sosman

unread,
Jun 19, 2008, 12:07:44 PM6/19/08
to

What do you mean by "accuracy?" Note that your very
first example (value 15, exponent 2, mantissa 0.15) creates
an error no matter how you arrive at the result: It begins
with the number 15 and ends with 0.15, that is, it starts
with an exact number and ends with a number that cannot be
represented exactly as a Java double.

Perhaps it's time you explained the context: Where do
these numbers come from, why do you want to separate them
into exponent and mantissa, what's the larger problem you're
trying to solve? Then, perhaps, someone can offer better-
directed advice.

--
Eric....@sun.com

John B. Matthews

unread,
Jun 19, 2008, 2:49:26 PM6/19/08
to
In article <TaydnVf9IrY68MfV...@earthlink.com>,
Patricia Shanahan <pa...@acm.org> wrote:

> Sundar wrote:
> >> My advice would be "Don't." Unless you have some powerful
> >> reason to avoid logarithms (which would appear to be at the
> >> core of the task here), see my first suggestion on this thread.
> >
> > Accuracy of the result is of highest priority, se we cannot use
> > logarithms.

Sundar: Are you testing a requirement? Sadly, "highest priority" is not
a well defined measure of accuracy. For example, "one part in 10^12" is
more specific, and it can be measured.

> It can be done with perfect accuracy using BigDecimal.
>
> First use the BigDecimal(double) constructor to get a BigDecimal with
> the same value as your double. The scale will be the smallest scale that
> makes the unscaled value an integer. Use the precision() method to find
> out the adjustment to the mantissa range you want. Use movePointRight to
> multiply or divide by a power of ten to get the mantissa as a BigDecimal.

Patricia: I think Sundar is restricted to 1.4.2, so precision() may be
unavailable to him.

> Note that one of your original examples will not give the result you
> expect if you do the job exactly. 1.3E-3 is not the exact value of any
> double. The double will be the closest one to it, and the mantissa will
> not be .13000, but something that matches it to about 16 decimal places.

Sundar: This distinction between model and view is crucial. IEEE-754
mantissas model real numbers using a polynomial with rational
coefficients and a finite number of terms. Most real numbers cannot be
represented exactly. Viewing a number in decimal reveals this. Here is
your double model value 1.3E-3, viewed with 24 decimal digits:

.1299999999999999940326E-2: .1299999999999999940326 * 10^-2

A different model gives a different result, BigDecimal("1.3E-3", new
MathContext(24))):

.1300000000000000000000E-2: .1300000000000000000000 * 10^-2

> If you prefer to get the sort of result you expected, even at the
> expense of loss of accuracy, it would be better to parse a formatted
> String representation.

This works marvelously well with BigInteger. Thanks! The decimal format
and context precision can be adjusted to display the desired accuracy.

import java.math.BigDecimal;
import java.math.MathContext;
import java.text.DecimalFormat;

public class EMTest {

private static DecimalFormat dForm =
new DecimalFormat(".0000000000000000000000E0");

private static void print(BigDecimal v) {
String s = dForm.format(v);
String[] em = s.split("E");
System.out.println(s + ": " + em[0] + " * 10^" + em[1]);
}

public static void main(String[] args) throws Exception {
MathContext mc = new MathContext(24);
print(new BigDecimal(1.3E-3, mc));
print(new BigDecimal("1.3E-3", mc));

Patricia Shanahan

unread,
Jun 19, 2008, 3:20:31 PM6/19/08
to
John B. Matthews wrote:
> In article <TaydnVf9IrY68MfV...@earthlink.com>,
> Patricia Shanahan <pa...@acm.org> wrote:
...

>> First use the BigDecimal(double) constructor to get a BigDecimal with
>> the same value as your double. The scale will be the smallest scale that
>> makes the unscaled value an integer. Use the precision() method to find
>> out the adjustment to the mantissa range you want. Use movePointRight to
>> multiply or divide by a power of ten to get the mantissa as a BigDecimal.
>
> Patricia: I think Sundar is restricted to 1.4.2, so precision() may be
> unavailable to him.
...

If so, he could repeatedly movePointRight by one or movePointLeft by one
until the BigDecimal is in the target range. The exponent is the
original scale with the number of digits of point move added or
subtracted as appropriate.

However, I feel the requirements are a bit vague, so I am still not sure
which approach is best. The fact that Sundar talks in terms of the
double's exponent and mantissa as though it were base 10 rather than
base 2 suggests that BigDecimal, rather than double, may be the
appropriate type for the whole job.

Patricia

Roedy Green

unread,
Jun 20, 2008, 8:37:37 AM6/20/08
to
On Wed, 18 Jun 2008 04:19:14 -0700 (PDT), Sundar
<sunda...@gmail.com> wrote, quoted or indirectly quoted someone who
said :

>How do I get Mantissa and exponent from double?

Why do you want to do this? What do you do with the results? Knowing,
that, we might think of a totally different way to get to your end
result that does not require splitting the number into exponent and
mantissa.

For example, if you are trying to precisely format a number as a
String, fine points of the formatting methods may do the trick.

John B. Matthews

unread,
Jun 20, 2008, 9:28:46 AM6/20/08
to
In article <c-adncc1s8UOLMfV...@earthlink.com>,
Patricia Shanahan <pa...@acm.org> wrote:

> John B. Matthews wrote:
> > In article <TaydnVf9IrY68MfV...@earthlink.com>,
> > Patricia Shanahan <pa...@acm.org> wrote:
> ...
> >> First use the BigDecimal(double) constructor to get a BigDecimal with
> >> the same value as your double. The scale will be the smallest scale that
> >> makes the unscaled value an integer. Use the precision() method to find
> >> out the adjustment to the mantissa range you want. Use movePointRight to
> >> multiply or divide by a power of ten to get the mantissa as a BigDecimal.
> >
> > Patricia: I think Sundar is restricted to 1.4.2, so precision() may be
> > unavailable to him.
> ...
>
> If so, he could repeatedly movePointRight by one or movePointLeft by one
> until the BigDecimal is in the target range. The exponent is the
> original scale with the number of digits of point move added or
> subtracted as appropriate.

Ah, I see; precision would be a convenience, but scale and move would
suffice.

> However, I feel the requirements are a bit vague, so I am still not sure
> which approach is best. The fact that Sundar talks in terms of the
> double's exponent and mantissa as though it were base 10 rather than
> base 2 suggests that BigDecimal, rather than double, may be the
> appropriate type for the whole job.

I agree on the vagueness, but I see the use of BigDecimal (model) and an
appropriate DecimalFormat (view) as complementary.

I confess to avoiding BigDecimal, actually exec'ing bc instead! I see
now it's the familiar rational polynomial with an arbitrary number of
terms. Thanks!

0 new messages