Running following program produces inconsistent and incorrect results. Program and output provided.
Specifically
Double x=65.99 *100;
prints out 6598.999
class Lesson_6_Activity_Three {
public static void main(String[] args) throws IOException {
Scanner scan = new Scanner (System.in); double d, temp; System.out.println("Please input a decimal number:"); d = scan.nextDouble(); for (int i=1; i<100; i++) { temp = (d+i) * 100; System.out.println("(" + i + " + number) *= 100: " + temp ); } }
}
OUTPUT:
run Lesson_6_Activity_Three
Please input a decimal number:
[DrJava Input Box - entered 63.99]
(0 + number) = 100: 6399.0
(1 + number) = 100: 6499.000000000001
(2 + number) = 100: 6599.000000000001
(3 + number) = 100: 6699.000000000001
(4 + number) = 100: 6799.000000000001
(5 + number) = 100: 6899.000000000001
(6 + number) = 100: 6999.000000000001
(7 + number) = 100: 7099.000000000001
(8 + number) = 100: 7199.000000000001
(9 + number) = 100: 7299.000000000001
(10 + number) = 100: 7399.000000000001
(11 + number) = 100: 7499.000000000001
(12 + number) = 100: 7599.000000000001
(13 + number) = 100: 7699.000000000001
(14 + number) = 100: 7799.000000000001
(15 + number) = 100: 7899.000000000001
(16 + number) = 100: 7999.000000000001
(17 + number) = 100: 8099.000000000001
(18 + number) = 100: 8199.0
(19 + number) = 100: 8299.0
DrJava Version : drjava-20140826-r5761
DrJava Build Time: 20140826-0459
Windows 10
Floating-point numbers cannot represent all numbers accurately.
See, for example, http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
This is not a bug in DrJava.
In the interactions window, I type
65.99 * 100
the output is
6598.999999999999
But if I type
62.99 * 100
the output is
6299.0
Why the difference?
Madge Smith
Computer Science Teacher
Academy for Science and Design
Nashua, NH 03063
603.595.4705
"Always code as if the guy who ends up maintaining your code
will be a violent psychopath who knows where you live."
~ Martin Golding
On Sat, Sep 12, 2015 at 11:29 PM, Mathias Ricken mgricken@users.sf.net
wrote:
Related
Bugs:
#956Please remember that computers use binary and not decimal.
Floating point numbers are a combination of a significand (the actual digits of the number) and an exponent (which says where the decimal point goes).
The digits are binary, as I've stated. Let's say you want to represent the decimal number 1.25. The general idea here is to use the binary significand 101 and an exponent of -2. That means 1 * 1 + 0 * 0.5 + 1 * 0.25 = 1.25.
Now let's say you want to represent 1.26. You start with 101, because that gets you to 1.25. But now you need to represent 0.01. 1/8, 1/16, 1/32 and 1/64 are all too big. 1/128 is finally less than 0.01. 10100001e-7 gets you to 1.2578125. Not quite 1.26 yet.
And you continue with more and more digits representing smaller and smaller fractions. But you only have so many bits (32 bit for float or 64 bit for double, and that's significand and exponent combined).
At some point, you have to realize that the floating-point number is only an approximation for most numbers. Do you understand?
If you want decimal arithmetic, you should look into Java's BigDecimal (http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html). It will do what you want to do, just less efficiently.
Some more information: http://floating-point-gui.de/basic/
Thanks for the detailed explanation. I need to brush up on floating point
numbers!
Madge Smith
Computer Science Teacher
Academy for Science and Design
Nashua, NH 03063
603.595.4705
"Always code as if the guy who ends up maintaining your code
will be a violent psychopath who knows where you live."
~ Martin Golding
On Sun, Sep 13, 2015 at 12:31 AM, Mathias Ricken mgricken@users.sf.net
wrote:
Related
Bugs:
#956Hi Madge,
Some languages like Scheme support a more intuitive formulation of "real"
numbers than mainstream languages like Java. If you are interested,
try downloading the Racket system (see http://racket-lang.org/download/)
which includes the IDE DrRacket, which has much in common with DrJava.
(The original creators of Racket [formerly called MzScheme/DrScheme] were
Matthias Felleisen and his students at Rice University. Matthias was my
principal reseach partner from 1987 to 2000.) There is an excellent
introductory (but deep) programming text based on DrRacket at www.htdp.org.
Java is representative of mainstream languages which generally provide
numeric types that are directly supported in computer hardware. The Java
double type (standard IEEE 64-bit floating point as implemented on all x86
processors and nearly all competing processor designs) is a very good
version of floating point arithmetic but it is still easy to devise simple
calculations that show it is NOT performing true real arithmetic. It is
possible in principle to support exact real arithmetic, but it is VERY
expensive. I wrote a paper on this subject in 1986 with some colleagues at
Rice University and elsewhere; see http://dl.acm.org/citation.cfm?id=319860.
Exact real arithmetic still behaves counter-intuitively in some cases
(e.g., comparing equal numbers generally diverges [does not terminate]),
In exact real arithmetic every number is effectively represented by a
Cauchy sequence of rational numbers that converges to the real number in
question. One possible representation of such a Cauchy sequence is a
function mapping rational tolerances to rational approximations. In
effect, every elementary arithmetic operation in exact real arithmetic must
construct a new function. Even in languages that explicitly support
functions as data (e.g., Scheme, Haskell, Scala), dynamically constructing
new functions is expensive. Java can easily represent such functions as
objects but each arithmetic operation forces the construction of a new
object. In addition, actually demanding a rational approximation from such
an object can be expensive because the computation must effectively
evaluate the accumulated expression tree corresponding to the object.
My former colleague Hans Boehm has implemented an exact real calculator
which is available in several formulations as a Java applet (see
http://www.hboehm.info/new_crcalc/CRCalc.html) but it will not run in my
browser because of security issues with Java applets (I may need to lower
my security settings).
The anomalies that you observed in the behavior of Java arithmetic show
that floating point computation can be hazardous. If you are interested in
digging more deeply into the subject of large scale numerical computation
which consists almost entirely of floating point arithmetic, I highly
recommend the book "Introduction to Scientific Computing: A Matrix-Vector
Approach Using MATLAB" by Charley Van Loan--despite the bad reviews the
book has received at Amazon.com. Evidently, the book contains some typos.
There is an errata sheet posted at
http://www.cs.cornell.edu/cv/Books/SCMV/Errata.htm. You can buy a used
copy in very good condition for $1.98 + $3.99 shipping at
http://www.amazon.com/gp/offer-listing/0139491570/ref=dp_olp_used?ie=UTF8&condition=used).
The book assumes some familiarity with linear algebra and the mechanics of
floating point arithmetic, as well as access to a MatLab implementation.
MathWorks offers a free 30 day trial for MatLab and FreeMat (see
http://freemat.sourceforge.net/) appears to an open source alternative
(which I have not yet tried). If you decide to seriously read the book, I
will be glad to answer any questions that arise. (So I suspect would
Charley Van Loan whom I know well. See http://www.cs.cornell.edu/cv/.) I
have access to MatLab on some educational machines at Rice University. For
the record, my research expertise lies in the realm of programming
languages (like Java) and tools (like DrJava), but I think scientific
computing is cool and challenging.
Thanks for your interest in DrJava, which may have enticed you to learn
more about scientific computing.
Best,
Robert "Corky" Cartwright
P.S. I spent a year in 1997-1998 living in Chelmsford, MA on sabbatical at
Sun Microsystems Laboratories (then located in Chelmsford and subsequently
in Burlington). Nashua was our favorite shopping destination.
On Sun, Sep 13, 2015 at 8:36 AM, Madge Smith madgeh@users.sf.net wrote:
Related
Bugs:
#956Hi Robert,
Wow, thanks for all the information. I am sure I was much better versed in
this topic at one time. But I took a long sabbatical from programming to
raise some kiddos. Now getting back into it on the teaching side. Very
interesting switch for me. Funny you should mention Racket. I introduced a
class to our 8th grade students last year which used WeScheme and the
Bootstrap curriculum develop by Dr. Emmanuel Schanzer. My students used
loads of algebra while creating video games. Great stuff. This year adding
AP CS, programming in Java, for our juniors and seniors. They are loving it!
Again, thanks for the detailed answer. I will check out the links you
provided.
Sincerely,
Madge
Madge Smith
Computer Science Teacher
Academy for Science and Design
Nashua, NH 03063
603.595.4705
"Always code as if the guy who ends up maintaining your code
will be a violent psychopath who knows where you live."
~ Martin Golding
On Sun, Sep 13, 2015 at 5:34 PM, Robert Cartwright <rcartwright@users.sf.net
Related
Bugs:
#956I am closing this bug report because the behavior of double precision floating point arithmetic in DrJava as shown in the report exactly matches the IEEE Floating Point standard and the JLS standard for Java. Floating point arithmetic is not identical to real arithmetic.