Solved

Java failing to multiply two numbers correctly!

Posted on 2004-08-17
18
842 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 175 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
 
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 75 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Passing list of object to Oracle Database Procedure 3 60
Java Timer (static) 9 36
split string containing \r\n in Java 46 38
servlet filter example 37 42
By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.

910 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now