How to avoid overflowing a multiplication of variables? - java

If I have the following code:
long interval = 0;
interval = ((6000 * 60) * 24) * 30;
It won't run because I would need to make every literal a Long. So this would work:
interval = ((6000L * 60L) * 24L) * 30L;
But what if I'm trying to multiply different variables that are in type char? Say I have:
char a, b, c, d;
And I give each of these chars a number value so I try:
interval = a * b * c * d;
If this overflows, I can't just put the L because that would call different variables.
interval = aL * bL * cL * dL;
I have tried converting each of these chars into a long before hand but the product still returns a negative number.

You just have to cast (any) one of the variables to long in order for long multiplication to take place :
interval = (long)a * b * c * d;

interval = ((6000L * 60L) * 24L) * 30L;
This code seems to be calculating the number of milliseconds in 30 days.
Well, then, use what the JDK has to offer:
interval = TimeUnit.DAYS.toMillis(30L);
javadoc for TimeUnit

When applying the multiplicative operator to its operands,
Binary numeric promotion is performed on the operands (§5.6.2).
That is, for this case,
Otherwise, if either operand is of type long, the other is converted to long.
So, really, all you need is to have one long value at the beginning of the multiplication. You can achieve this in a few ways. Either use a cast as demonstrated by Eran. Or use a long literal in the expression
char a, b, c, d;
...
interval = 1L * a * b * c * d;
// (......) result is a long value
By beginning of the multiplication, I'm referring to the fact that multiplicative operator is left associative. In your example, if the result of the first application of * is a long value, it will propagate to the next *.

Related

IEEEremainder(double, double) is undefined for the type Math

I am trying to use java.lang.Math.IEEEremainder(double f1, double f2) in GWT. But I got below exception.
[ERROR] Line 1119: The method IEEEremainder(double, double) is
undefined for the type Math
I attempted to execute this code : angle = Math.IEEEremainder(angle, 360.0);
How to solve this issue in GWT?. If its not solve then what would be the alternative way to achieve the same functionality of Math.IEEEremainder this method.
According to the JRE Emulation this function is not supported in GWT.
So if you really need it and can't work around it, you will need to implement it yourself.
If I understand it correctly, you are trying to limit the angle to 360 degrees.
You could achieve that with this code:
/**
* Normalize a degree value.
* #param d value
* #return 0<=value<=360
*/
public static double normalizeDegrees(double d)
{
while (d < 0)
{
d += 360;
}
while (d > 360)
{
d -= 360;
}
return d;
}
If you just got positive numbers, you can even skip the upper while-Block.
If you really need to have the IEEEremainder method in GWT, implement it like that:
/**
* Computes the remainder operation on two arguments as prescribed by the IEEE 754 standard. The remainder value is
* mathematically equal to <code>f1 - f2</code> × <i>n</i>, where <i>n</i> is the
* mathematical integer closest to the exact mathematical value of the quotient {#code f1/f2}, and if two
* mathematical integers are equally close to {#code f1/f2}, then <i>n</i> is the integer that is even. If the
* remainder is zero, its sign is the same as the sign of the first argument. Special cases:
* <ul>
* <li>If either argument is NaN, or the first argument is infinite, or the second argument is positive zero or
* negative zero, then the result is NaN.
* <li>If the first argument is finite and the second argument is infinite, then the result is the same as the first
* argument.
* </ul>
* #param f1 the dividend.
* #param f2 the divisor.
* #return the remainder when {#code f1} is divided by {#code f2}.
*/
public static double IEEEremainder(double f1, double f2)
{
double div = Math.round(f1 / f2);
return f1 - (div * f2);
}
(I added this as a new comment to show the syntax highlighting).

Java divide operation exception

Given following codes:
long testNum = 1000;
double midNum = testNum/60000;
System.out.println(midNum);
long another = Math.round(7600/midNum);
System.out.println(another);
The output is:
0.0
9223372036854775807
Why the first output is 0.0? How could I get the right result in java?
Since the first output is 0, why the next expression has an result? Shouldn't it throw out an by zero expression?
Why the first output is 0.0?
You are using integer division so this is the right result.
How could I get the right result in java?
Don't use integer division, use floating point instead, the simplest way to to make one of the value a floating point like this.
double midNum = testNum/60000.0;
or
double midNum = testNum/60e3;
Since the first output is 0, why the next expression has an result?
Floating point arithmetic uses IEEE-754 standard (sometimes called IEEE-753.99999999999998 ;)
In floating point, you never get an exception in Java, you might get infinity, negative infinity or NaN.
Integers don't have Infinity, or NaN and have no way to represent this, so it produced an Exception.
When you round any number too big for a long it gives you the closest presentable value which is Long.MAX_VALUE
BTW
long l = Math.round(Double.POSITIVE_INFINITY); // l == Long.MAX_VALUE
long l = Math.round(Double.NEGATIVE_INFINITY); // l == Long.MIN_VALUE
long l = (long) Double.NaN; // l == 0
From Double you might find this interesting.
public final class Double extends Number implements Comparable<Double> {
/**
* A constant holding the positive infinity of type
* {#code double}. It is equal to the value returned by
* {#code Double.longBitsToDouble(0x7ff0000000000000L)}.
*/
public static final double POSITIVE_INFINITY = 1.0 / 0.0;
/**
* A constant holding the negative infinity of type
* {#code double}. It is equal to the value returned by
* {#code Double.longBitsToDouble(0xfff0000000000000L)}.
*/
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
/**
* A constant holding a Not-a-Number (NaN) value of type
* {#code double}. It is equivalent to the value returned by
* {#code Double.longBitsToDouble(0x7ff8000000000000L)}.
*/
public static final double NaN = 0.0d / 0.0;
/**
* A constant holding the largest positive finite value of type
* {#code double},
* (2-2<sup>-52</sup>)·2<sup>1023</sup>. It is equal to
* the hexadecimal floating-point literal
* {#code 0x1.fffffffffffffP+1023} and also equal to
* {#code Double.longBitsToDouble(0x7fefffffffffffffL)}.
*/
public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308
long is can't hold decimals. Long is equal to int just with a higher range.
You should use decimal or float.
The reason your first result is 0.0 is due to your use of implicit casting. When dividing a long by a number, Java assumes that number is of the same type and will do "long" division, which has no remainder. Since 1000/60000 is between 0 and 1, the result is effectively floored to 0, and cast to 0.0 when it's a double. You can fix this by changing a line to double midNum = testNum/60000D;
Note the "D" at the end, indicating that 60000 is a double. This will force the long to be cast as a double and give the proper result.
For the second part, you're basically dividing by a very very small number, making it appear to be quite large. 0.0 cannot be represented accurately by a double, so you're actually dividing by something slightly above 0.0, which will be fixed when you fix the other part.
use type cast operator.
double midNum = (double)testNum/60000;

why long COOKIE_TIMEOUT = 1000 * 60 * 60 * 24 * 30 return negative? [duplicate]

This question already has answers here:
Multiplication operation in Java is resulting in negative value
(4 answers)
Closed 8 years ago.
final long COOKIE_TIMEOUT = 1000 * 60 * 60 * 24 * 30;
Output: -1702967296
Someone told me to put L after 1000 & it works
final long COOKIE_TIMEOUT = 1000L * 60 * 60 * 24 * 30;
Output: 2592000000
Why does that happen?
Integer overflow, put 1000L, this will force long conversion
UPDATE
Slightly longer explanation:
If you just do 1000*10 for example, java will see them as integers.
In your original code, you were doing an integer calculation which overflowed, then cast the overflowed value to long.
However if you put L after the first number, java will see them as longs (left-most operand defines the granularity) and you won't get an overflow.
As another example take this code:
double a = 5 / 2;
double b = 5d / 2;
System.out.println(a + " != " + b);
This will print out:
2.0 != 2.5
Why? When calculating a, java sees 5 and 2 as integers and does an integer division, then casts the result to a double. When calculating b you tell java that 5 is actually a double at which point it performs a double division.
Although COOKIE_TIMEOUT is long the right-hand expression consists of integers, so its type is int. The result is greater than Integer.MAX_VALUE that causes overflow. When at least one operand in your expression belongs to higher type (e.g. long) whole expression becomes long and overflow does not happen.
This is what you did in your second example when you added L modifier after one of the numeric constants. This constant became long, so the expression became long too.
This behavior is due to the type of the expression selected by the Java compiler. In this case it looks something like so:
int * int -> int (which overflows here during the multiplication)
long * long -> long
long * int = long * long (by promotion) -> long
int * long = long (by promotion) * long -> long
This promotion happens pretty much universally for the math operators: the widest/largest type is used, with the smaller type being promoted and the x op x -> x expression being applied (classically, integer vs. floating division).
The L results in a long value and thus the multiplication selected is long * long (by promotion) -> long, which is free from the immediate overflow discovered. The long expression result type propagates to all the other multiplications.
Bonus points: it would still fail (overflow) if written as 1000 * 60 * 60 * 24 * 30 * 1L, why?
It is greatter than Integer.MAX_VALUE which is 2147483647
By default all numeric litaral are considered as Integer. to define a Long numeric value you have to add L or 'l' with the number.
The reason of that behavior is integer overflow.
Your first statement can be understand like this:
long time = 1000 * 60 * 60 * 24 * 30;
is the same as
int time = 1000 * 60 * 60 * 24 * 30;
long timel = time;
First you compute the expression, then you assign to long type;
When you put suffix L to literal you define it as long type.
JSL 3.10.1. Integer Literals
An integer literal is of type long if it is suffixed with an ASCII
letter L or l (ell); otherwise it is of type int (§4.2.1).
long time = 1000L * ( 60 * 60 * 24 * 30);
can be written also as
long time = ((long) 1000) * ( 60 * 60 * 24 * 30);
More about Primitive Data Types
It is causing for Integer overflow(Max value upto 2147483647).
You can postfix L at the end of the any numeric value.
Like 1000L
Then it forcely converts into Long type
What happens here is that the right hand side is evaluated before the assignment to the left hand side. Since you are multiplying several ints, the resulting type will be int. Then, after evaluating the right hand side, it will see that it is supposed to assign this value to a long, and do the casting automatically.
So you have:
Evaluated right hand side as int: 1000 * 60 * 60 * 24 * 30 = 2,592,000,000.
The maximum value of an int is: 2,147,483,647.
So you have an overflow, which makes the int negative. This is then assigned to a long, still negative.
When you specify one of the operands on the right hand side to be long, then the expression will be evaluated has a long, which has a much larger maximum value.
Every number in the formula is an Integer, hence Java will perform all calculations in Integer and store the result temporarily as Integer. However the result exceeds Integer Max range (overflow), so it becomes negative.
1000 * 60 * 60 * 24 * 30 = 2592000000 (exceeds Integer.MAX_VALUE)
Only when Java needs to assign it to the Long variable Java will cast it into a Long. Since the result is already wrong result (due to overflow) then the Long variable will be assigned with the wrong result.
However if you already declare the 1000 as Long (1000L), then the remaining calculations will be done as Long instead of Integer.

Java math operations shorthand?

I've been searching but no luck. I want to know if there is a way to perform shorthand operations with the number 1. I know how to do it with addition and subtraction:
/*
* Addition: variableName++;
* Addition: variableName +=;
* Subtraction: variableName--;
* Subtraction: variableName -=;
* Multiplication: variableName*=
* Multiplication: variableName**; ?
* Division: variableName /=;
* Division: variableName// ? impossible
* Exponent: variableName ^=;
* Exponent: variableName^^; ?
* Modulo: variableName %=;
* Modulo: variableName%%; ?
*/
What about the others? Multiplication, Division, Exponents, Modulo.
Doing division seems almost impossible.
EDIT:
I should have been more specific.
I want to know if there is another version of ++ or - - for the other operators.
The other mathematical shorthand operators which Java provides are the += (a = a + number), *=, and so on.
The complete list of operators can be obtained from here.
Try these:
Int a = 5;
a += 1;
a -= 1;
a *= 2;
a /= 2;
Are these shorthand enough?
The other operators won't actually change the number.
e.g.
x = x * 1;
x is unchanged, why would you want a shorthand that doesn't change the value of x?
There are some languages that allow you to make your own shorthand for operators but this requires a bit of research
I think there is no increment or decrement operator like for multiplication and division.Instead we can use them like below
a *= b (a = a * b)
a /= b (a = a / b) and so on..
also if we want to multiply x by 1 or divide x by 1 then also there will be no effect on the final result..so what's the need

How to check if number fits primitive type in java?

I need do to some input validation but run into a question and I do not seem to find an answer (even with Google). The problem is simple: I have 2 positive integers on the input, and I need to check if their product fits int type in Java.
One of my attempts was to compare product with Integer.MAX_VALUE, but it seems if the product is too big for integer, value becomes negative.
I wanted to reason that product is too big by change in sign, but it seems if the product is "way too big" it will become positive again.
Could someone advise me how to detect if number becomes too big?
Many thanks in advance!
If you are doing a UI, you are presumably in no particular hurry. So you could use a BigInteger and then test the product against MAX_VALUE.
Cast the value to int and see if the value is the same. A simple check looks like
double d =
long l =
BigInteger bi =
if (d == (int) d) // can be represented as an int.
if (l == (int) l) // can be represented as an int.
int i = bi.intValue();
if (bi.equals(BigInteger.valueOf(i)))
If the value is the same when cast back, there is no loss of information and you can use an int value.
Searched and found the following:
Java is cavalier about overflow. There are no compile-time warnings or run-time exceptions to let you know when your calculations have become too big to store back in an int or long. There is no warning for float or double overflow either.
/**
* multiplies the two parameters, throwing a MyOverflowException if the result is not an int.
* #param a multiplier
* #param b multiplicand
* #result product
*/
public static int multSafe(int a, int b) throws MyOverflowException
{
long result = (long)a * (long)b;
int desiredhibits = - ((int)( result >>> 31 ) & 1);
int actualhibits = (int)( result >>> 32 );
if ( desiredhibits == actualhibits )
{
return(int)result;
}
else
{
throw new MyOverflowException( a + " * " + b + " = " + result );
}
}
You could create a BigInteger from your input value and use its intValue() method to convert. If the BigInteger is too big to fit in an int, only the low-order 32 bits are returned. So you need to compare the resulting value to your input value to ensure it was not truncated.

Categories

Resources