For Programmers: Free Programming Magazines  


Home > Archive > Java Help > April 2004 > Trouble with a double









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Trouble with a double
Princess Morgiah

2004-04-19, 5:54 pm

Hi everyone,

Why does this
for (double x = 0.80; x < 1.0; x += 0.01)
{
System.out.println("Threshold " + x);
}
give me the following result:
Threshold 0.8
Threshold 0.81
Threshold 0.8200000000000001
Threshold 0.8300000000000001
Threshold 0.8400000000000001
Threshold 0.8500000000000001
Threshold 0.8600000000000001
Threshold 0.8700000000000001
Threshold 0.8800000000000001
Threshold 0.8900000000000001
Threshold 0.9000000000000001
Threshold 0.9100000000000001
Threshold 0.9200000000000002
Threshold 0.9300000000000002
Threshold 0.9400000000000002
Threshold 0.9500000000000002
Threshold 0.9600000000000002
Threshold 0.9700000000000002
Threshold 0.9800000000000002
Threshold 0.9900000000000002

I can understand that there is a deviation from the expected value, but why
not in the first two cases?

Thanks in advance,

Princess Morgiah


VisionSet

2004-04-19, 6:41 pm

Xref: kermit comp.lang.java.help:174002


"Princess Morgiah" <princess_morgiah_nospamplease@yahoo.com> wrote in
message news:n3Xgc.78407$6%5.5262466@phobos.telenet-ops.be...
> Hi everyone,
>
> Why does this
> for (double x = 0.80; x < 1.0; x += 0.01)
> {
> System.out.println("Threshold " + x);
> }
> give me the following result:
> Threshold 0.8
> Threshold 0.81
> Threshold 0.8200000000000001
> Threshold 0.8300000000000001
> Threshold 0.8400000000000001
> Threshold 0.8500000000000001
> Threshold 0.8600000000000001
> Threshold 0.8700000000000001
> Threshold 0.8800000000000001
> Threshold 0.8900000000000001
> Threshold 0.9000000000000001
> Threshold 0.9100000000000001
> Threshold 0.9200000000000002
> Threshold 0.9300000000000002
> Threshold 0.9400000000000002
> Threshold 0.9500000000000002
> Threshold 0.9600000000000002
> Threshold 0.9700000000000002
> Threshold 0.9800000000000002
> Threshold 0.9900000000000002
>
> I can understand that there is a deviation from the expected value, but

why
> not in the first two cases?


Because the error (due to the fact binary cannot represent decimal fractions
accurately) is cumulative and the error initially is not sufficient to
register in the 64 bit representation.

--
Mike W


Bryce (Work)

2004-04-19, 6:41 pm

On Mon, 19 Apr 2004 20:57:55 GMT, "Princess Morgiah"
<princess_morgiah_nospamplease@yahoo.com> wrote:

>Hi everyone,
>
>Why does this
> for (double x = 0.80; x < 1.0; x += 0.01)
> {
> System.out.println("Threshold " + x);
> }
>give me the following result:
>Threshold 0.8
>Threshold 0.81
>Threshold 0.8200000000000001
>Threshold 0.8300000000000001
>Threshold 0.8400000000000001
>Threshold 0.8500000000000001
>Threshold 0.8600000000000001
>Threshold 0.8700000000000001
>Threshold 0.8800000000000001
>Threshold 0.8900000000000001
>Threshold 0.9000000000000001
>Threshold 0.9100000000000001
>Threshold 0.9200000000000002
>Threshold 0.9300000000000002
>Threshold 0.9400000000000002
>Threshold 0.9500000000000002
>Threshold 0.9600000000000002
>Threshold 0.9700000000000002
>Threshold 0.9800000000000002
>Threshold 0.9900000000000002



Someone answered this better than I could... But I'd suggest if you
want to keep a 2 decimal place number, try using one of the Decimal
classes...

>I can understand that there is a deviation from the expected value, but why
>not in the first two cases?
>
>Thanks in advance,
>
>Princess Morgiah
>



--
now with more cowbell
Mark Haase

2004-04-19, 9:35 pm

In article <n3Xgc.78407$6%5.5262466@phobos.telenet-ops.be>,
"Princess Morgiah" <princess_morgiah_nospamplease@yahoo.com> wrote:

> I can understand that there is a deviation from the expected value, but why
> not in the first two cases?


Certain fractions become repeating decimals in binary. Just like 1/3 in
decimal is .33333333333, etc. When you convert back to decimal, these
repeating fractions can leave behind odd artifacts.

--
|\/| /| |2 |<
mehaase(at)sas(dot)upenn(dot)edu
Yoyoma_2

2004-04-19, 11:37 pm

Bryce (Work) wrote:

> On Mon, 19 Apr 2004 20:57:55 GMT, "Princess Morgiah"
> <princess_morgiah_nospamplease@yahoo.com> wrote:
>
>
[color=darkred]
> Someone answered this better than I could... But I'd suggest if you
> want to keep a 2 decimal place number, try using one of the Decimal
> classes...


And that was me hihihi.

Ok here's the deal. With double numbers you are not guaranteed the
"precision" of the number. This is also called "Machine Epsilon" and
you can look it up on google.

Basically for a 32 bit machine it works out that you can only guarantee
a number to 10^-9 decimal places, for a 64bit its 10^-12 if i remember
correctly.

You aren't guaranteed that 0.8 + 0.1 = 0.9. It could be 0.899999999999
or 0.900000000001 as you magically observed.

Its a normal side-effect of the way floating point numbers are
calculated on-chip.

If you want a large number of places, then you can use BigDouble or
BigInt.

This is the same reason you can't do an if directly on a double.

For example "if( myVal == 0.81 )" in your case would return false since
myVal = 0.81000000000001 which is != 0.81

To do this all you have to do is get the machine epsilon (the smallest
number that the CPU can distinguish from zero) and do the test like this.

if( myVal - epsilon >0 ){

}


But since you want to output these numbers, i reccomend using a
NumberFormat to strip your superfluous digits.

If you are taking computer science or an engineering disciplin, ask your
teacher he will tell you all about it. There are ways to calculate for
this error and take it into account. Very important when doing
engineering work where public liability is at stake.

If not then you can check out "Machine Epsilon" on google and you will
have all the info you need.

Good luck!

>
>
>
> --
> now with more cowbell

Tom

2004-04-20, 3:42 pm

It stems from the fact that .1 is a repeating decimal when translated to binary.

"Princess Morgiah" <princess_morgiah_nospamplease@yahoo.com> wrote in message news:<n3Xgc.78407$6%5.5262466@phobos.telenet-ops.be>...
> Hi everyone,
>
> Why does this
> for (double x = 0.80; x < 1.0; x += 0.01)
> {
> System.out.println("Threshold " + x);
> }
> give me the following result:
> Threshold 0.8
> Threshold 0.81
> Threshold 0.8200000000000001
> Threshold 0.8300000000000001
> Threshold 0.8400000000000001
> Threshold 0.8500000000000001
> Threshold 0.8600000000000001
> Threshold 0.8700000000000001
> Threshold 0.8800000000000001
> Threshold 0.8900000000000001
> Threshold 0.9000000000000001
> Threshold 0.9100000000000001
> Threshold 0.9200000000000002
> Threshold 0.9300000000000002
> Threshold 0.9400000000000002
> Threshold 0.9500000000000002
> Threshold 0.9600000000000002
> Threshold 0.9700000000000002
> Threshold 0.9800000000000002
> Threshold 0.9900000000000002
>
> I can understand that there is a deviation from the expected value, but why
> not in the first two cases?
>
> Thanks in advance,
>
> Princess Morgiah

Thomas Schodt

2004-04-20, 6:36 pm

Bryce (Work) wrote:

> I'd suggest if you
> want to keep a 2 decimal place number, try using one of the Decimal
> classes...


Personally, in this case, I'd probably just go for the simpler

for (int x=80;x<100;++x) {
System.out.println("Threshold " + (x*.01) );
}
Eric Sosman

2004-04-20, 6:36 pm

Thomas Schodt wrote:
>
> Bryce (Work) wrote:
>
>
> Personally, in this case, I'd probably just go for the simpler
>
> for (int x=80;x<100;++x) {
> System.out.println("Threshold " + (x*.01) );
> }


... which produces this output:

Threshold 0.8
Threshold 0.81
Threshold 0.8200000000000001
Threshold 0.8300000000000001
Threshold 0.84
Threshold 0.85
Threshold 0.86
Threshold 0.87
Threshold 0.88
Threshold 0.89
Threshold 0.9
Threshold 0.91
Threshold 0.92
Threshold 0.93
Threshold 0.9400000000000001
Threshold 0.9500000000000001
Threshold 0.96
Threshold 0.97
Threshold 0.98
Threshold 0.99

Any more suggestions?

(I've got one: See java.text.Format and its descendants.)

--
Eric.Sosman@sun.com
Princess Morgiah

2004-04-21, 5:42 pm

"Eric Sosman" <Eric.Sosman@sun.com> wrote in message
news:40859596.97B40E37@sun.com...
> Thomas Schodt wrote:
>


Would this do the trick then?
System.out.println("Threshold " + (float) x / 100);
gives
Threshold 0.8
Threshold 0.81
Threshold 0.8200000000000001
Threshold 0.8300000000000001
Threshold 0.84
Threshold 0.85
Threshold 0.86
Threshold 0.87
Threshold 0.88
Threshold 0.89
Threshold 0.9
Threshold 0.91
Threshold 0.92
Threshold 0.93
Threshold 0.9400000000000001
Threshold 0.9500000000000001
Threshold 0.96
Threshold 0.97
Threshold 0.98
Threshold 0.99

Or am I missing something else here?

Thanks to everyone who replied!

Princess Morgiah



Carl Howells

2004-04-21, 7:43 pm

Princess Morgiah wrote:

> Or am I missing something else here?


You're missing every time someone has told you to look at the classes in
the java.text package.

In particular, look at java.text.DecimalFormat. It has a constructor
that takes a string that lets you set its output format, and a method
format(double d) which produces a String from d, in the given format.
Roedy Green

2004-04-21, 9:44 pm

On Mon, 19 Apr 2004 20:57:55 GMT, "Princess Morgiah"
<princess_morgiah_nospamplease@yahoo.com> wrote or quoted :

>Why does this
> for (double x = 0.80; x < 1.0; x += 0.01)
> {
> System.out.println("Threshold " + x);
> }

see http://mindprod.com/jgloss/floatingpoint.html

--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
Carl Howells

2004-04-22, 5:41 pm

Princess Morgiah wrote:

> "Which produces a String" indeed, in which I am not interested. I want to
> use the resulting double value, for which I can see no possible way to get
> to via the DecimalFormat class, part from possibly a very wordy construct
> involving the parse method.


Ahh.. That's important. I didn't realize, and I suspect most people
reading the thread also didn't realize, that you wanted to continue
treating the values as doubles. In your example, you only were
displaying them, which led me to believe the wrong thing.

In that case, it seems what you're looking for is a general set of rules
for working with floating point types to minimize cumulative error. I
don't know of any, offhand, but I can confirm that what you're doing in
the case you listed is correct.

If only Patricia Shannahan (Did I spell that right?) was still following
this newsgroup.... She was the best I ever saw at explaining how
floating-point types work in the real world. Unfortunately, her web
page doesn't have anything about the topic up.
Andrew Thompson

2004-04-22, 5:41 pm

On Thu, 22 Apr 2004 13:17:48 -0700, Carl Howells wrote:

> If only Patricia Shannahan (Did I spell that right?) ..


No double 'nn', Shanahan.

--
Andrew Thompson
http://www.PhySci.org/ Open-source software suite
http://www.PhySci.org/codes/ Web & IT Help
http://www.1point1C.org/ Science & Technology
Princess Morgiah

2004-04-25, 11:45 am

"Carl Howells" <chowells@janrain.com> wrote in message
news:108dvlladcrnd50@corp.supernews.com...
> Princess Morgiah wrote:
>
>
> You're missing every time someone has told you to look at the classes in
> the java.text package.


You assume that. I did have a look at those classes, yet found nothing of
importance that would help me, therefor I posted another possible solution.

> In particular, look at java.text.DecimalFormat. It has a constructor
> that takes a string that lets you set its output format, and a method
> format(double d) which produces a String from d, in the given format.


"Which produces a String" indeed, in which I am not interested. I want to
use the resulting double value, for which I can see no possible way to get
to via the DecimalFormat class, part from possibly a very wordy construct
involving the parse method.

Therefor I ask what is wrong with
for (int x=80;x<100;++x) {
System.out.println("Threshold " + (x*.01) );
}

which gives me the correct result - or at least appears to do so.

Thanks,

Princess Morgiah



Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com