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
<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.
However, OP forgot to mention what actually is displayed after running this.
>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
> 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.
> 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 |
>
> 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.
And what does it display when run from the command line?
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
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.
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.
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
> 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.
> 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
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>
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
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
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
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
Cute.
You are using the well-known flaw in that constructor
as a useful feature!
Arne
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
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.
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
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