Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Am I Crazy? V. simple math question.

Reply
Thread Tools

Am I Crazy? V. simple math question.

 
 
MS
Guest
Posts: n/a
 
      04-08-2007
Hi,

I haven't programmed in Java for a while and just wrote a program to calc
the odds of winning the British national lottery. BUT it is giving me the
wrong result !!

Here's the relevant bit:

public void DoCalc()
{
float winOdds = 49 * 48 * 47 * 46 * 45 * 44;
System.out.println(winOdds);

float anyOrder = 6 * 5 * 4 * 3 * 2;
System.out.println(anyOrder);

float res = winOdds / anyOrder;

System.out.println(res);
}

It outputs:

1.47841293E9
720.0
2053351.2

But the result should be:

10,068,347,520
720
13,983,816

Don't believe me? Paste the following into your calc program:

(49 * 48 * 47 * 46 * 45 * 44) / (6 * 5 * 4 * 3 * 2) =

Or let google do it:
http://www.google.co.uk/search?hl=en...e+Search&meta=

Am I going crazy? Why doesn't my Java program work?

Please help.

MS
 
Reply With Quote
 
 
 
 
=?ISO-8859-1?Q?Arne_Vajh=F8j?=
Guest
Posts: n/a
 
      04-08-2007
MS wrote:
> I haven't programmed in Java for a while and just wrote a program to
> calc the odds of winning the British national lottery. BUT it is giving
> me the wrong result !!
>
> Here's the relevant bit:
>
> public void DoCalc()
> {
> float winOdds = 49 * 48 * 47 * 46 * 45 * 44;


I am pretty sure you make an integer overflow here.

try:

float winOdds = 49.0 * 48.0 * 47.0 * 46.0 * 45.0 * 44.0;


> System.out.println(winOdds);
>
> float anyOrder = 6 * 5 * 4 * 3 * 2;
> System.out.println(anyOrder);
>
> float res = winOdds / anyOrder;
>
> System.out.println(res);
> }
>
> It outputs:
>
> 1.47841293E9
> 720.0
> 2053351.2
>
> But the result should be:
>
> 10,068,347,520
> 720
> 13,983,816


Arne
 
Reply With Quote
 
 
 
 
Tom Hawtin
Guest
Posts: n/a
 
      04-08-2007
MS wrote:
> float winOdds = 49 * 48 * 47 * 46 * 45 * 44;


> 1.47841293E9
> 720.0
> 2053351.2
>
> But the result should be:
>
> 10,068,347,520
> 720
> 13,983,816



What's the value of Integer.MAX_VALUE?

Tom Hawtin
 
Reply With Quote
 
MS
Guest
Posts: n/a
 
      04-08-2007
Arne Vajh°j emailed this:
> MS wrote:
>> I haven't programmed in Java for a while and just wrote a program to
>> calc the odds of winning the British national lottery. BUT it is
>> giving me the wrong result !!
>>
>> Here's the relevant bit:
>>
>> public void DoCalc()
>> {
> > float winOdds = 49 * 48 * 47 * 46 * 45 * 44;

>
> I am pretty sure you make an integer overflow here.
>
> try:
>
> float winOdds = 49.0 * 48.0 * 47.0 * 46.0 * 45.0 * 44.0;


Many thanks. What you suggested gave a 'possible loss of precision' error,
when I swapped the floats to doubles I got the correct result.

Strange oversight by the Java designers that Java doesn't assume the .0 at
the end of any real number.

Thanks again.
 
Reply With Quote
 
Joshua Cranmer
Guest
Posts: n/a
 
      04-08-2007
MS wrote:
> Hi,
>
> I haven't programmed in Java for a while and just wrote a program to
> calc the odds of winning the British national lottery. BUT it is giving
> me the wrong result !!
>
> Here's the relevant bit:
>
> public void DoCalc()
> {
> float winOdds = 49 * 48 * 47 * 46 * 45 * 44;
> // snip
> }
>
> It outputs:
>
> 1.47841293E9
> 720.0
> 2053351.2
>
> But the result should be:
>
> 10,068,347,520
> 720
> 13,983,816

No it shouldn't. float refers to single-precision floating point
scientific values (base two, of course), so ones-digit accuracy may not
possible when working with millions, but the answer would be expressed
(if properly calculated) as something with E7.
>
> Don't believe me? Paste the following into your calc program:
> [snip]
> Am I going crazy? Why doesn't my Java program work?

What Java is doing when it calculates winOdds is it is multiplying the
numbers /as integers/ and then converting to a float. The number
obviously exceeds 2^31-1, so it is rolling over. There are several ways
to avoid this, the easiest being
float winOdds = 1.0f * 49 * 48 * 47 * 46 * 45 * 44;
or
float winOdds = 49.0f * 48 * 47 * 46 * 45 * 44;

The answer is, no, you aren't crazy, but you do need to learn more about
when conversions get applied.
 
Reply With Quote
 
MS
Guest
Posts: n/a
 
      04-08-2007
> What's the value of Integer.MAX_VALUE?

Too low for my needs.
Thanks.
 
Reply With Quote
 
MS
Guest
Posts: n/a
 
      04-08-2007
Joshua Cranmer emailed this:
> MS wrote:
>> Hi,
>>
>> I haven't programmed in Java for a while and just wrote a program to
>> calc the odds of winning the British national lottery. BUT it is
>> giving me the wrong result !!
>>
>> Here's the relevant bit:
>>
>> public void DoCalc()
>> {
>> float winOdds = 49 * 48 * 47 * 46 * 45 * 44;
>> // snip
>> }
>>
>> It outputs:
>>
>> 1.47841293E9
>> 720.0
>> 2053351.2
>>
>> But the result should be:
>>
>> 10,068,347,520
>> 720
>> 13,983,816

> No it shouldn't. float refers to single-precision floating point
> scientific values (base two, of course), so ones-digit accuracy may not
> possible when working with millions, but the answer would be expressed
> (if properly calculated) as something with E7.
>>
>> Don't believe me? Paste the following into your calc program:
>> [snip]
>> Am I going crazy? Why doesn't my Java program work?

> What Java is doing when it calculates winOdds is it is multiplying the
> numbers /as integers/ and then converting to a float. The number
> obviously exceeds 2^31-1, so it is rolling over. There are several ways
> to avoid this, the easiest being
> float winOdds = 1.0f * 49 * 48 * 47 * 46 * 45 * 44;
> or
> float winOdds = 49.0f * 48 * 47 * 46 * 45 * 44;
>
> The answer is, no, you aren't crazy, but you do need to learn more about
> when conversions get applied.


Many thanks for the explanation.

Cheers.
 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      04-08-2007
MS wrote:
> Arne Vajh├Şj emailed this:
>> MS wrote:
>>> I haven't programmed in Java for a while and just wrote a program to
>>> calc the odds of winning the British national lottery. BUT it is
>>> giving me the wrong result !!
>>>
>>> Here's the relevant bit:
>>>
>>> public void DoCalc()
>>> {
>> > float winOdds = 49 * 48 * 47 * 46 * 45 * 44;

>>
>> I am pretty sure you make an integer overflow here.
>>
>> try:
>>
>> float winOdds = 49.0 * 48.0 * 47.0 * 46.0 * 45.0 * 44.0;

>
> Many thanks. What you suggested gave a 'possible loss of precision'
> error, when I swapped the floats to doubles I got the correct result.
>
> Strange oversight by the Java designers that Java doesn't assume the .0
> at the end of any real number.


Huh? What "real" numbers?

There was absolutely no oversight on the part of the Java designers here. The
compiler worked exactly as documented.

49, 48, 47, et al. are /integers/.
<http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.1>

not float or double literals
<http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.2>

You did /integer/ calculation.

Arne pointed out that that cause an /integer/ overflow.

After which you converted the incorrect /integer/ value to float. (Why not
double?)

How is the compiler suppose to "assume the [sic] .0" in an integer?

--
Lew

 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      04-08-2007
MS wrote:
> Arne Vajh°j emailed this:
>> MS wrote:
>>> I haven't programmed in Java for a while and just wrote a program to
>>> calc the odds of winning the British national lottery. BUT it is
>>> giving me the wrong result !!
>>>
>>> Here's the relevant bit:
>>>
>>> public void DoCalc()
>>> {
>> > float winOdds = 49 * 48 * 47 * 46 * 45 * 44;

>>
>> I am pretty sure you make an integer overflow here.
>>
>> try:
>>
>> float winOdds = 49.0 * 48.0 * 47.0 * 46.0 * 45.0 * 44.0;

>
> Many thanks. What you suggested gave a 'possible loss of precision'
> error, when I swapped the floats to doubles I got the correct result.
>
> Strange oversight by the Java designers that Java doesn't assume the .0
> at the end of any real number.


Strange oversight by the Java programmers who can't
distinguish between `int' and `double' constants ...

To put it another way: The eventual "target" of an
expression does not influence the way the expression is
calculated. You wrote `float winOdds =' and apparently
expected the right-hand side to somehow magically understand
that it should be evaluated in `float' arithmetic. But the
original is an expression involving `int' values multiplied
together, so it is evaluated according to the rules of `int'.
After the evaluation, the result is converted to `float' for
the assignment -- but by then it's too late, the overflow has
already occurred and the damage has been done.

Perhaps the commonest situation where this misunderstanding
crops up is

double fahrenheit = 212;
double celsius = 5 / 9 * (fahrenheit - 32);

As a test of your newfound understanding of how expressions
are evaluated, can you say what's wrong with this formula?
For extra credit, can you explain why

double celsius = (fahrenheit - 32) * 5 / 9;

works as (presumably) intended?

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)lid
 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      04-08-2007
Tom Hawtin wrote:
>> What's the value of Integer.MAX_VALUE?


MS wrote:
> Too low for my needs.


Exactly! That was the problem!

--
Lew
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Math.random() and Math.round(Math.random()) and Math.floor(Math.random()*2) VK Javascript 15 05-02-2010 03:43 PM
Math.min and Math.max for byte / short Philipp Java 9 07-23-2008 12:37 AM
math.h trig functions questions (and some forgotten high school math) Mark Healey C Programming 7 05-22-2006 10:42 AM
Re: Is still math.h the C++ math library ? AciD_X C++ 4 04-01-2004 07:29 PM
Why can I not use: Math a=new Math(); chirs Java 18 03-02-2004 06:00 PM



Advertisments