?
Solved

Java failing to multiply two numbers correctly!

Posted on 2004-08-17
18
Medium Priority
?
853 Views
Last Modified: 2008-03-17
Hi,
I was wondeing if anyone could help clear up some very strange java behaviour.  I have been running a program sucessfully for the last few weeks.  Recently it stoped working and I located the problem to the function below.  For some reason the program has started to assign a completely wrong negative number when it multiplies two values input to the function.  An example  from the print statement below is 171944*172557=-3946302646.  If anyone has any ideas as to what could be causing the problem it would be greatly appreciated.
        Cheers,
        everton690.


private static void writeList(int size, int pageno,int linkno) {
            
 try {
      
        File f = new File("somefile");
        RandomAccessFile raf = new RandomAccessFile(f, "rw");
 
System.out.println(pageno+"*"+size+"="+(pageno*size));

       int location=(pageno*size)+linkno;
           
   raf.seek(location);
    raf.writeByte(1);
 
   
    } catch (IOException e) {
          System.out.println("exception");
    }
                      
             
}
0
Comment
Question by:everton690
  • 5
  • 4
  • 3
  • +4
18 Comments
 
LVL 7

Accepted Solution

by:
bvanderveen earned 700 total points
ID: 11820746
I think you are using a datatype that is too small.  When that happens, your result gets screwy.  Try using the long datatype for the result.
0
 
LVL 7

Expert Comment

by:bvanderveen
ID: 11820775
To be clear, int is 32 bits, or a max upper limit of 4,294,967,295.  The negative number is from "overflow" resetting the sign bit. Java doesn't throw an error when this happens, so you need to make sure you have an adequate datatype.   A long (integer) datatype is 64 bits, with an upper limit of 18,446,744,073,709,551,615, which gives a bit more range.
0
 

Author Comment

by:everton690
ID: 11820812
Ints work fine, I tried using longs instead just in case but this made no difference unfortunately!
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 5

Expert Comment

by:TrekkyLeaper
ID: 11820873
I just tried with a long and it worked fine. Try replacing:

(pageno*size)

with:

((long)pageno * (long)size)
0
 
LVL 35

Assisted Solution

by:girionis
girionis earned 300 total points
ID: 11820888
bvanderveen is right, you do not use the proper data types that's why it's failing. Multiplying those two int values will result in a long. Try this:

long pageno = 171944;
                   long size = 172557;
                 System.out.println(pageno+"*"+size+"="+(pageno*size));

and you wil lsee the correct result. Now try this:

int pageno = 171944;
                   int size = 172557;
                 System.out.println(pageno+"*"+size+"="+(pageno*size));

and you will see the wrong result.
0
 
LVL 7

Expert Comment

by:bvanderveen
ID: 11820917
It is defaulting your result to an int.  Make it explicit with a cast or by declaring a variable for the result

   long result;
   int pageno = 171944;
   int size = 172557;
   result = pageno * size;
  System.out.println(pageno+"*"+size+"="+ result);
0
 

Author Comment

by:everton690
ID: 11820919
This does not help in my case, maybe the solution lies elsewhere.  The program had been working fine with ints for a few weeks
0
 
LVL 35

Expert Comment

by:girionis
ID: 11820944
> This does not help in my case, maybe the solution lies elsewhere.  The program had been working fine with ints for a few weeks

This could be because you were passing it values that their product didn't exceed the int limit.
0
 
LVL 35

Expert Comment

by:girionis
ID: 11820955
What's wrong with making them long? Is it the memory you want to save?
0
 
LVL 7

Expert Comment

by:bvanderveen
ID: 11821362
It is almost certainly an overflow.  The giveaway is the sign changing to negative.  The overflow is setting the sign bit.  

It worked before because you didn't overflow.  Don't believe us?   Step through with a debugger, and check the values you are multiplying.  If they exceed (2**32) -1 you are going to overflow every time.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11821543
>>To be clear, int is 32 bits, or a max upper limit of 4,294,967,295

Not so, the max is 2,147,483,648 as the datatype is signed

But you're right about the overflow:

171944*172557 = 29,670,140,808  i.e. a clear overflow
0
 
LVL 7

Expert Comment

by:bvanderveen
ID: 11821811
>>Not so, the max is 2,147,483,648 as the datatype is signed

Yep, forgot the sign bit.  

Upper limit for a long would be 9,223,372,036,854,775,808.  Ought to be big enough.

We have suggested casting the result to long.  I'm not sure this will work, if done after overflow has occured.  Compiler may make result an int when you multiply 2 ints together, then cast.  If still getting errors, make them all longs and see what happens.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11824308
Just make the parameters to the method long
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 11824726
And where does the error come from? From the fact that JAVA only promotes int's to long's if requested:

long q = 1000000000 * 1000000000; // Fails because you introduce integers.
long q = 1000000000L * 1000000000; // Succeeds, because you force the second integer into promotion to long.

A common error is:

public static final long TERA = 1024*1024*1024*1024;  // Without any warning a **** constant is created.

;JOOP!
0
 
LVL 92

Expert Comment

by:objects
ID: 11826455
> Just make the parameters to the method long

Not necessary as earlier mentioned.

Try this if you haven't already:

 long location=((long)pageno*(long)size)+(long)linkno;
0
 

Author Comment

by:everton690
ID: 11828576
Cheers,
Bvanderveen you were right all along it was just a simple overflow problem, I had been expecting something more drastic.  The reason I never had the problem before was because the int values were smaller (bit of a schoolboy error).  Thanks again.
         everton690.
 
0
 
LVL 35

Expert Comment

by:girionis
ID: 11828667
:)
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11829578
>>Not necessary as earlier mentioned.

How do you know? One or more of the parameters may already be too big for a int
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
This video teaches viewers about errors in exception handling.
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.
Suggested Courses
Course of the Month16 days, 16 hours left to enroll

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question