Jonatan
Jonatan

Reputation: 61

long not enough to store an integer

public class SDO 
{
    public static void main(String args[])
    {
        SDO sdo = new SDO();
        System.out.println(sdo.amountOfData(1));       
        System.out.println(sdo.amountOfData(86400));  
    }

    public long amountOfData(int seconds)
    {
        long result =  (4096*4096*seconds);
        return result;
    }

}

This code is returning in my test, error: amountData(1000) expected:<16777216000> but was:<-402653184>. Shouldn't type long store even higher integers? or if not how to make this code working ?

Upvotes: 1

Views: 619

Answers (2)

paxdiablo
paxdiablo

Reputation: 881323

With:

long result =  (4096*4096*seconds);

result can indeed hold the value, but the calculation is being done exclusively with int types, because it's performing arithmetic on exclusively ints.

So the result of the expression will be an int, and you'll later place that into the long but not before you've lost information.

You can coerce Java into using long for the intermediate result simply by making the first constant a long:

long result =  4096L * 4096 * seconds;

though it may be more prudent to make them all longs so as to make your intent clearer.

This is covered in the Java Language Spec:

Numeric promotion is applied to the operands of an arithmetic operator. Numeric promotion contexts allow the use of an identity conversion, a widening primitive conversion, or an unboxing conversion.

Numeric promotions are used to convert the operands of a numeric operator to a common type so that an operation can be performed. The two kinds of numeric promotion are unary numeric promotion and binary numeric promotion.

One other solution is to let the function call itself widen the data type, with something like:

public long amountOfData (long seconds) {
    return seconds * 4096 * 4096;
}

This will have a similar effect since seconds will now be a long so the calculation will be done as a long. It will also shorten your code a little.

Upvotes: 6

Eran
Eran

Reputation: 393781

Change

long result = (4096*4096*seconds);

to

long result =  (4096L*4096L*seconds);

in order to get a long result and avoid int overflow.

4096*4096*seconds is a multiplication of 3 ints, and results in an int, which may overflow before being assigned to your long variable.

Upvotes: 10

Related Questions