Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Java failing to multiply two numbers correctly!

Posted on 2004-08-17
18
Medium Priority
?
851 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
Suggested Courses

609 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