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

floating point display problem

16 views
Skip to first unread message

J.H.Kim

unread,
Jul 12, 2010, 11:07:36 AM7/12/10
to
Hi, everyone

My java compiler and interpreter cannot display floating point variable.

public class PrintTest {
public static void main(String[] args) {
double a = 3.141592;
System.out.println(a);
}
}

The routine above does not display 3.141592.

My compiler version is

frog1120:/home/frog/Java/Work/012# javac -version
Eclipse Java Compiler v_774_R33x, 3.3.1, Copyright IBM Corp 2000, 2007.

and interpreter version is

frog1120:/home/frog/Java/Work/012# java -version
java version "1.5.0"
gij (GNU libgcj) version 4.3.2
Copyright (C) 2007 Free Software Foundation, Inc.


Please give me a hint for this problem.


p.s) My system is debian linux and when I installed eclipse,
the development tools are installed, too. But now I want to unistall the
java development tools of eclipse. So, I did it, but the java tools of
eclipse is not installed.
When I overwrite sun java packages, the java tools of eclipse remains.
How can I uninstall the java tools for eclipse completely?


Thanks in advance

Best Regards,
J.Hwan Kim

markspace

unread,
Jul 12, 2010, 11:15:16 AM7/12/10
to
J.H.Kim wrote:
> Hi, everyone
>
> My java compiler and interpreter cannot display floating point variable.
>
> public class PrintTest {
> public static void main(String[] args) {
> double a = 3.141592;
> System.out.println(a);
> }
> }
>
> The routine above does not display 3.141592.

<http://docs.sun.com/source/806-3568/ncg_goldberg.html>

Floating point numbers aren't exact. You can't get exactly 3.141592 out
of any floating point system. Consider using BigDecimal if you need
"exact" numbers.

Screamin Lord Byron

unread,
Jul 12, 2010, 12:36:13 PM7/12/10
to


Well, in this example there is no calculation, and significand fits
within 52 bits of IEEE 754 double type so it should be printed out as
expected: 3.141592. Please someone correct me if I'm wrong.

However, OP forgot to mention what actually is displayed after running this.

rossum

unread,
Jul 12, 2010, 12:44:27 PM7/12/10
to
On Tue, 13 Jul 2010 00:07:36 +0900, "J.H.Kim" <frog...@gmail.com>
wrote:

>My java compiler and interpreter cannot display floating point variable.
>
>public class PrintTest {
> public static void main(String[] args) {
> double a = 3.141592;
> System.out.println(a);
> }
> }
>
>The routine above does not display 3.141592.

What does it display?

rossum

markspace

unread,
Jul 12, 2010, 1:58:49 PM7/12/10
to
Screamin Lord Byron wrote:

> Well, in this example there is no calculation, and significand fits
> within 52 bits of IEEE 754 double type so it should be printed out as
> expected: 3.141592. Please someone correct me if I'm wrong.
>
> However, OP forgot to mention what actually is displayed after running this.


You're right, it prints correctly on my system. I assumed that the OP
had run afoul of some infinitely repeating decimal/binary problem.
Since everything I've heard about gij suggests it's just plain broken, I
now assume the problem must be there.

The OP should try an up-to-date JVM from Sun.

Martin Gregorie

unread,
Jul 12, 2010, 2:13:45 PM7/12/10
to
On Tue, 13 Jul 2010 00:07:36 +0900, J.H.Kim wrote:

> Hi, everyone
>
> My java compiler and interpreter cannot display floating point variable.
>
> public class PrintTest {
> public static void main(String[] args) {
> double a = 3.141592;
> System.out.println(a);
> }
> }
>
> The routine above does not display 3.141592.
>

So, what does it display?

It works fine here:

[kiwi@zappa java]$ javac PrintTest.java
[kiwi@zappa java]$ java PrintTest
3.141592
[kiwi@zappa java]$ javac -version
javac 1.6.0_17
[kiwi@zappa java]$ java -version
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) Client VM (build 14.3-b01, mixed mode, sharing)


--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |

J.H.Kim

unread,
Jul 12, 2010, 6:23:28 PM7/12/10
to
Martin Gregorie wrote:

>
> So, what does it display?
>
> It works fine here:
>
> [kiwi@zappa java]$ javac PrintTest.java
> [kiwi@zappa java]$ java PrintTest
> 3.141592
> [kiwi@zappa java]$ javac -version
> javac 1.6.0_17
> [kiwi@zappa java]$ java -version
> java version "1.6.0_17"
> Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
> Java HotSpot(TM) Client VM (build 14.3-b01, mixed mode, sharing)
>

It displayed blank.

Martin Gregorie

unread,
Jul 12, 2010, 6:33:58 PM7/12/10
to

And what does it display when run from the command line?

Arne Vajhøj

unread,
Jul 12, 2010, 9:11:35 PM7/12/10
to

Even though 7 decimals digits is less than 52 bits, then it is
far from guaranteed that a 7 decimals number can be represented
exact within 52 bit.

It would be nice if println guaranteed that any literal with less
digits than what is max. due to size would be printed exactly
like the literal. But I don't think that will always be the case.

Arne

Screamin Lord Byron

unread,
Jul 13, 2010, 7:02:56 AM7/13/10
to
On 07/13/2010 03:11 AM, Arne Vajhøj wrote:
> On 12-07-2010 12:36, Screamin Lord Byron wrote:
>> On 07/12/2010 05:15 PM, markspace wrote:
>>> J.H.Kim wrote:
>>>> Hi, everyone
>>>>
>>>> My java compiler and interpreter cannot display floating point
>>>> variable.
>>>>
>>>> public class PrintTest {
>>>> public static void main(String[] args) {
>>>> double a = 3.141592;
>>>> System.out.println(a);
>>>> }
>>>> }
>>>>
>>>> The routine above does not display 3.141592.
>>>
>>> <http://docs.sun.com/source/806-3568/ncg_goldberg.html>
>>>
>>> Floating point numbers aren't exact. You can't get exactly 3.141592 out
>>> of any floating point system. Consider using BigDecimal if you need
>>> "exact" numbers.
>>
>>
>> Well, in this example there is no calculation, and significand fits
>> within 52 bits of IEEE 754 double type so it should be printed out as
>> expected: 3.141592. Please someone correct me if I'm wrong.
>
> Even though 7 decimals digits is less than 52 bits, then it is
> far from guaranteed that a 7 decimals number can be represented
> exact within 52 bit.

I am aware there is a problem of representing fractions in any numeral
system (for example, decimal 0.1 can't be exactly represented in binary,
just as 1/3 can't be exactly represented in decimal), and here we're not
saying nothing like double d = 2. - 0.1;

Am I wrong if I say that the literal 3.141592 is represented in memory
like this: the sign is 0, the significand is 3141592 and the exponent is
-6. There are no mathematical operations with this number, so it's sole
representation is in fact exact, is it not? The println should print it
like it's represented, just like it prints 0.8999999999999999 as a
result of 2. - 0.1.


Screamin Lord Byron

unread,
Jul 13, 2010, 7:11:09 AM7/13/10
to
On 07/13/2010 01:02 PM, Screamin Lord Byron wrote:
> just like it prints 0.8999999999999999 as a
> result of 2. - 0.1.

Typo

2. - 1.1

Anyway, the result isn't exact, of course, but I don't think it would be
such a good idea if println did rounding to show us "expected" 0.9.

Patricia Shanahan

unread,
Jul 13, 2010, 10:06:04 AM7/13/10
to

You are wrong. 3.141592 in Java is a double literal, and double is a
binary floating point type. See
http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.2

"The details of proper input conversion from a Unicode string
representation of a floating-point number to the internal IEEE 754
binary floating-point representation are described for the methods
valueOf of class Float and class Double of the package java.lang."

The actual rule for double is described in
http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/lang/Double.html#valueOf(java.lang.String)

"Otherwise, s is regarded as representing an exact decimal value in the
usual "computerized scientific notation" or as an exact hexadecimal
value; this exact numerical value is then conceptually converted to an
"infinitely precise" binary value that is then rounded to type double by
the usual round-to-nearest rule of IEEE 754 floating-point arithmetic,
which includes preserving the sign of a zero value."

The compiler's input conversion for 3.141592 is necessarily inexact for
the reason you mentioned in the first paragraph.

Patricia

Roedy Green

unread,
Jul 13, 2010, 10:18:58 AM7/13/10
to
On Tue, 13 Jul 2010 00:07:36 +0900, "J.H.Kim" <frog...@gmail.com>
wrote, quoted or indirectly quoted someone who said :

> double a = 3.141592;
> System.out.println(a);

see http://mindprod.com/jgloss/decimalformat.html
--
Roedy Green Canadian Mind Products
http://mindprod.com

You encapsulate not just to save typing, but more importantly, to make it easy and safe to change the code later, since you then need change the logic in only one place. Without it, you might fail to change the logic in all the places it occurs.

J.H.Kim

unread,
Jul 13, 2010, 10:24:29 AM7/13/10
to
J.H.Kim wrote:

> My compiler version is
>
> frog1120:/home/frog/Java/Work/012# javac -version
> Eclipse Java Compiler v_774_R33x, 3.3.1, Copyright IBM Corp 2000, 2007.
>
> and interpreter version is
>
> frog1120:/home/frog/Java/Work/012# java -version
> java version "1.5.0"
> gij (GNU libgcj) version 4.3.2
> Copyright (C) 2007 Free Software Foundation, Inc.
>

I solved problem by replacing java toolkit with SUN java JDK and JRE.
Thank you.

Best Regards,
J.Hwan Kim

John B. Matthews

unread,
Jul 13, 2010, 11:52:29 AM7/13/10
to
In article <2ZGdncexkoRQ76HR...@earthlink.com>,
Patricia Shanahan <pa...@acm.org> wrote:

I often use this online calculator to peek at the internal representation:

<http://babbage.cs.qc.edu/IEEE-754/Decimal.html>

For double a = 3.141592, Long.toHexString(Double.doubleToRawLongBits(a))
yields 400921fafc8b007a, which breaks down in binary and decimal as
follows:

sign: 0 -> +
exponent: 10000000000 = 1024 - 1023 = 1
significand: 1.1001001000011111101011111100100010110000000001111010
= 1.5707960000000000

2^1 * 1.570796 = 3.141592, also expanded here:

<http://en.wikipedia.org/wiki/Floating_point#Overview>

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

Eric Sosman

unread,
Jul 13, 2010, 12:44:06 PM7/13/10
to

Yes, you're wrong. It is represented in memory like this:

- The sign is zero

- The significand is 7074236280275066/9007199254740992

- The exponent is 2

- ... and the bit you're missing is that the exponent's base
is not ten, but two. From this fact flow many of the
consequences that mystify you.

> There are no mathematical operations with this number, so it's sole
> representation is in fact exact, is it not?

It is not. Do the arithmetic yourself, and you'll see that the
value derived from the representation is not exactly 3.141592, but
about 1.6e-16 greater.

> The println should print it
> like it's represented, just like it prints 0.8999999999999999 as a
> result of 2. - 0.1.

If that's what it prints, your computer is broken (and not by
just a little bit, either).

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

Patricia Shanahan

unread,
Jul 13, 2010, 5:33:23 PM7/13/10
to

There is also a simple pure Java way of getting the actual decimal
expansion. The BigDecimal(double) constructor and BigDecimal's toString
are both exact:

import java.math.BigDecimal;
public class DemoExactDoubleOutput {


public static void main(String[] args) {

System.out.println(new BigDecimal(3.141592));
}
}

Output:

3.14159200000000016217427400988526642322540283203125

Patricia


Patricia Shanahan

unread,
Jul 13, 2010, 5:56:31 PM7/13/10
to

I think it will if the literal has fewer than about 14 significant
digits and is in the normalized range. Let the infinitely precise value
of the decimal literal be x and the double representation y. According
to the compiler's input conversion rules, x does round to y under the
normal rounding rules.

Another decimal fraction of the same or shorter length would be too
different from x to also round to y. They would differ by more than the
gap between doubles. They would not be possible choices for the
Double.toString result.

Of course, there will be many numbers with more decimal places than x
that also round to y, including the one that is exactly equal to y.
Double.toString should pick x, because it is the shortest decimal
expansion of all those that round to y.

Once the number of significant digits gets high enough there may be
another value of the same or shorter length that also rounds to y.

Patricia

Arne Vajhøj

unread,
Jul 13, 2010, 7:35:00 PM7/13/10
to
On 13-07-2010 07:02, Screamin Lord Byron wrote:
> Am I wrong if I say that the literal 3.141592 is represented in memory
> like this: the sign is 0, the significand is 3141592 and the exponent is
> -6. There are no mathematical operations with this number, so it's sole
> representation is in fact exact, is it not? The println should print it
> like it's represented, just like it prints 0.8999999999999999 as a
> result of 2. - 0.1.

Yes.

Double in Java are IEEE 64 bit floating point and they are binary
not decimal, so you have 1/2, 1/4 etc. not 1/10, 1/100 etc..

Arne

Arne Vajhøj

unread,
Jul 13, 2010, 7:36:43 PM7/13/10
to

Cute.

You are using the well-known flaw in that constructor
as a useful feature!

Arne

Arne Vajhøj

unread,
Jul 13, 2010, 8:33:26 PM7/13/10
to

In most cases that is probably what people want.

Of course they can use printf with a fixed number of decimals
in most cases.

Arne

Screamin Lord Byron

unread,
Jul 14, 2010, 9:20:04 AM7/14/10
to

Of course they are and of course I'm wrong. Thanks to all who replied to
my post. It's much clearer now.

I must admit that what I said earlier was pretty naive thing to say.
The more posts I read here, the more I realize how bad my Java training
course was. There's nothing related to this even on the SCJP exam, so
you can officially be "Java Certified Programmer" and not know anything
about floating point. Now how about that.

Patricia Shanahan

unread,
Jul 14, 2010, 9:52:18 AM7/14/10
to
Arne Vajhøj wrote:
> On 13-07-2010 17:33, Patricia Shanahan wrote:
...

>> There is also a simple pure Java way of getting the actual decimal
>> expansion. The BigDecimal(double) constructor and BigDecimal's toString
>> are both exact:
>>
>> import java.math.BigDecimal;
>> public class DemoExactDoubleOutput {
>> public static void main(String[] args) {
>> System.out.println(new BigDecimal(3.141592));
>> }
>> }
>>
>> Output:
>>
>> 3.14159200000000016217427400988526642322540283203125
>
> Cute.
>
> You are using the well-known flaw in that constructor
> as a useful feature!

It can even be combined with the String constructor to get an estimate
of the relative rounding error:

import java.math.BigDecimal;
public class TestFraction {


public static void main(String[] args) {
System.out.println(new BigDecimal(3.141592));

System.out.println(relativeError("3.141592"));
}

static double relativeError(String s){
double d = Double.valueOf(s);
BigDecimal error = new BigDecimal(d).subtract(new BigDecimal(s)).abs();
return error.doubleValue()/d;
}
}

output:

3.14159200000000016217427400988526642322540283203125
5.162168544161217E-17

Arne Vajhøj

unread,
Jul 14, 2010, 9:40:01 PM7/14/10
to
On 14-07-2010 09:20, Screamin Lord Byron wrote:
> On 07/14/2010 01:35 AM, Arne Vajhøj wrote:
>> On 13-07-2010 07:02, Screamin Lord Byron wrote:
>>> Am I wrong if I say that the literal 3.141592 is represented in memory
>>> like this: the sign is 0, the significand is 3141592 and the exponent is
>>> -6. There are no mathematical operations with this number, so it's sole
>>> representation is in fact exact, is it not? The println should print it
>>> like it's represented, just like it prints 0.8999999999999999 as a
>>> result of 2. - 0.1.
>>
>> Yes.
>>
>> Double in Java are IEEE 64 bit floating point and they are binary
>> not decimal, so you have 1/2, 1/4 etc. not 1/10, 1/100 etc..
>
> Of course they are and of course I'm wrong. Thanks to all who replied to
> my post. It's much clearer now.
>
> I must admit that what I said earlier was pretty naive thing to say.
> The more posts I read here, the more I realize how bad my Java training
> course was. There's nothing related to this even on the SCJP exam, so
> you can officially be "Java Certified Programmer" and not know anything
> about floating point. Now how about that.

For many Java programmers doing various business apps, the only
think they need to know about floating point is that they should
not use them.

Arne

0 new messages