Cannot cast double as int - java

I'm having a problem in my script where it says I can't convert a double to an integer...
Here's the where the error is noted in the bat:
cm.getPlayer().yellowMessage("You have gained " +
getJQ.getCurrentMap() + " JQ points!");
The error is off of the method getCurrentMap(), which is here...
public int getCurrentMap() {
return maps.get((level - 1));
}
Level is an integer that is incremented every time the player advances a level. What I don't understand is how I'm receiving that error. When I print out the List<Integer> maps, I get a list of numbers. I don't see what's wrong.
Here is how I declare it:
private int level = 0;
Image of Error:
Code:
Code - Look at the methods getCurrentMap and the declaration of maps in the file. Ignore everything else.
Source Code: As you can see level is declared as an int, and getCurrentMap() only details with integers. There main lines that deal with this error are lines 29-32, and lines 59-61, where I push an array with a random value.

If level is a double then the result is a double as well. Java won't convert it to an integer because that would lose information. So you have to make it explicit:
return maps.get((int) (level - 1));
If level (or any other int) is retrieved from JavaScript, the code will not even be executed however. You are assigning a double from JavaScript to an int, so it never even reaches your Java code. Accept a double from JavaScript, then convert it to an integer by casting using (int).
You may want to use Math.ceil first - or another rounding method - if you want to round up instead of down.

If you want to create an integer from a double, use a function like Math.ceil or Math.round. Otherwise it is ambiguous how the conversion should be done.

JavaScript doesn't have integers, everything is a floating point value. So somewhere you have some floating point value you're getting from JavaScript that you're trying to treat as an integer. Where this happens is unclear from your question.
Casting something to a class that it isn't a subclass of will fail; Double and Integer are both subclasses of Number, you can cast a Double to a Number but not to an Integer. If you have a double value you want to convert to an integer, you could call a conversion method on the object wrapper for Double:
new java.lang.Double(10.001D).intValue();
which returns the integer part and discards any fractional part.

Related

Can I somehow implement bracketed casting between Double and Integer classes in Java?

I know Java doesn't allow direct casting between Integer and Double classes like so:
var intList = new ArrayList<Integer>();
// code that fills intList with Integer entries
var doubleVal = (Double) intList.get(0); // Class Cast exception
I also know the reason why and the solution(s) to this.
My question is - is there a way to make this work ? Can I implement something such that when I use (Double) intList.get(0) in my code, it actually gives me what I want instead of throwing an exception ?
In C# I would simply override the cast operator to do this and it would work, but sadly Java doesn't allow that.
Can I somehow implement bracketed casting between Double and Integer classes in Java?
Basically no. There are no Java tricks that you can use to make a simple (Double) cast do what you want to happen here.
Your example expression (Double) intList.get(0) requires too many conversions for the compiler to be "happy". It needs to unbox the Integer to an int, widen it to a double, and then box it as a Double. Three conversions.
You have to give it some help. Here are some of the ways you could help:
(Double) ((int) intList.get(0))
The cast to int causes the Integer to be unboxed. From there it can be widened to a double and then auto-boxed to a Double.
(Double) (intList.get(0).doubleValue())
This does the Integer to double via the doubleValue call, and then the (Double) does the final step.
Double.valueOf(intList.get(0).doubleValue())
As above but using an explicit call to do the boxing.

How to convert number from double to int without rounding?

I want to calculate how many columns can fit into container. First I calculate how many columns can fit in, then I calculate number of margins for them. After that I check if they will fit in with margins, if no - reduce amount of columns by one.
Code:
int columnMargin = 50;
double result = columnContainerHBox/minimalColumnWidth;
int columnCount = (int) result; // here's the problem
int numberOfMargins = columnCount - 1;
double finalCount = columnContainerHBox/minimalColumnWidth*columnCount+columnMargin*numberOfMargins;
if(finalCount<1){
columnCount--;
}
The problem is that I don't know how to convert from double to int without rounding number. I just need to get rid of all numbers after decimal. I already tried (int) double, (int)Math.floor(double) and new DecimalFormat('#').format(double). As a double I took 1.99999999999999999999. All above was converting it to 2. Desirable result - 1;
My double is going to be completely random. It can be 1.0, 1.9999999999, 2.45, 3.5959547324 etc.
What I need is to get a whole part and completely discard everything after decimal.
You do it by casting to int, as you're already doing in the code you've presented as an attempt.
I understand that you feel unsatisfied because you think you have found a case when your attempt will round the value instead of dropping the decimal part.
You have tried with value 1.99999999999999999999 and you've noticed that casting it to int produces an int of value 2. You concluded from there that casting is not just dropping the decimal part, it is rounding to the closest whole number 2.
Your conclusion is incorrect. The number 2 is not obtained as a result of casting to int. The number 2 is a result of the compiler parsing the written literal value 1.99999999999999999999. doubles don't have infinite precision. That means you can't write as many decimals as you want and expect it to be correctly kept in a double value. doubles only offer approximations of what you're asking. So when you type the literal value 1.99999999999999999999, the compiler knows that it is incapable to represent that value exactly, and instead it will take it as the closest value that can be represented in a double.
And the representable value closest to 1.99999999999999999999 is 2. As far as the Java compiler is concerned, these two numbers are one and the same.
So when you write:
double d = 1.99999999999999999999d;
the Java compiler treats it completely equivalent to:
double d = 2d;
You'll notice that at this point, you have yet to do any attempt to drop the decimals and only keep the whole part. You've only declared a value for your double, and as far as you're concerned this value could very well have a decimal part.
Your attempt to only keep the whole value only happens when you do:
int i = (int)d;
and here the decimals are dropped and your int contains only the whole part of what the double value contained.
However, in your example, since your double value was 2.0, then taking the whole part of it is 2. That's not rounding. That's not anything else than keeping only the whole part.
The correct way to drop decimals and only keep the whole part, is to cast to int.
(If it is important to you to be able to manipulate values such as 1.99999999999999999999 and have them not be the same as 2.0, then you cannot use doubles. They don't have sufficient precision. You should use BigDecimal, with new BigDecimal("1.99999999999999999999"). The constructor must be called with a String rather than a floating-point value, since floating-point values are unable to represent the value you want.)
Math.floor() is what you are looking for https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floor-double-
Math.floorDiv() also might be useful in your case.
I have do this but it isn't a very good solution but I have that:
public class Main {
public static void main(String args[]) {
double d = 1.9999;
String s = (""+d).contains(".") ? (""+d).substring(0, (""+d).indexOf(".")) : (""+d);
System.out.println(Integer.parseInt(s));
}
}

What does a 'int' in parenthesis mean when giving a value to an int?

Here's an example I have.
public int getDelta()
{
long time = getTime();
int delta = (int) (time - lastFrame);
lastFrame = time;
return delta;
}
In the fourth line, there's an "(int)". What does it mean?
This code is just an example I found with it; I'm not looking for a specific answer to the code I posted. What the (int) even does, generally. I've seen it done with (byte) too.
It means you're casting a long into an int. See: http://en.wikipedia.org/wiki/Type_conversion
You can't just say
int delta = (time - lastFrame);
Because time and lastFrame are longs (I'm assuming lastFrame is, at least). Therefore you must convert the type (cast) the result of that subtraction into an integer value.
When you cast with (int), you discard any fraction number after the floating point. For example:
System.out.println((int) 15.5); // prints 15
That is cast to the primitive data type int. It will try casting the result produced by the calculation (which would be a long type in this case)into a primitive int (Integer) type.
So, if you had a result of 16.253353 from that line (as an example), the cast would return just 16, since int doesn't deal with decimal places, only whole numbers.
It's a conversion operator. It converts (time - lastFrame) to an integer.
As both time and lastFrame are long ints, there is no need for rounding.
If you had either a float or a double, the difference there might have been rounded down.
In your case it just uses a smaller data type: int, rather than long.
(typename) value or variable is called casting. It tells Java to treat the value as the type stipulated in the cast. Sometimes it's necessary because a method already written returns a type that's too big - you need an int and the method returns a long. Sometimes its used to cast a superclass to a subclass so that methods in the subclass can be called. If you cast primitives to other types make sure the size of the variable is "big" enough to hold the value or you'll get wierd overflow values. If you cast an object to a different type you have make sure the object is the correct type or you'll get a ClassCastException, for example - casting a String to a Date won't work because they're not in the same class hierarchy.
This cast are used to ensure that result will be returned in a int value. In this case, time is a long value (probably int64) to use getTime() function. But for delta you need to casto it to a int (int32) value. This cast can loose values.
Stating the data type in parenthesis makes the compiler perform an explicit cast to that type.
It can be done with any type/object. For instance:
MyObject myobject = (MyObject) MyArray[0];
In your code I believe it will define your resulting variable as an int and not date.

operation with integer: result is only zero - Java

I have to do an operation with integers, very simple:
a=b/c*d
where all the variables are integer, but the result is ZERO whatever is the value of the parameters. I guess that it's a problem with the operation with this type of data (int).
I solved the problem converting first in float and then in integer, but I was wondering if there is a better method.
The / operator, when used with integers, does integer division which I suspect is not what you want here. In particular, 2/5 is zero.
The way to work around this, as you say, is to cast one or more of your operands to e.g. a float, and then turn the resulting floating point value back into an integer using Math.floor, Math.round or Math.ceil. This isn't really a bad solution; you have a bunch of integers but you really do want a floating-point calculation. The output might not be an integer, so it's up to you to specify how you want to convert it back.
More importantly, I'm not aware of any syntax to do this that would be more concise and readable than (for example):
a = Math.round((float)b / c * d)
In this case, you can reorder the expression so division is performed last:
a = (b*d)/c
Be careful that b*d won't ever be large enough to overflow an int. If it might be, you could cast one of them to long:
a = (int)(((long)b*d)/c)

Beginner Java Question about Integer.parseInt() and casting

so when casting like in the statement below :-
int randomNumber=(int) (Math.random()*5)
it causes the random no. generated to get converted into an int..
Also there's this method I just came across Integer.parseInt() which does the same !
i.e return an integer
Why two different ways to make a value an int ?
Also I made a search and it says parseInt() takes string as an argument.. So does this mean that parseInt() is ONLY to convert String into integer ?
What about this casting then (int) ?? Can we use this to convert a string to an int too ?
sorry if it sounds like a dumb question..I am just confused and trying to understand
Help ?
Integer.parseInt does not do the same thing as a cast.
Let's take a look at your first example:
int randomNumber=(int) (Math.random()*5)
Math.random returns a double, and when you multiply a double by an int Java considers the result to be a double. Thus the expression Math.random()*5 has a type of double. What you're trying to do is assign that value to a variable of type int. By default Java will not allow you to assign a double value to a variable of type int without your explicitly telling the compiler that it's ok to do so. Basically you can think of casting a double to an int as telling the compiler, "I know this int variable can't hold the decimal part of this double value, but that's ok, just truncate it."
Now take a look at the conversion of a String to an int:
int value = Integer.parseInt("5");
The string "5" is not immediately convertible to an integer. Unlike doubles, which by definition can be converted to an integer by dropping the decimal part, Strings can't be easily or consistently converted to an int. "5", "042", and "1,000" all have integer representations, but something like "Hello, World!" does not. Because of this there is no first order language feature for converting a String to an int. Instead, you use a method to parse the String and return the value.
So to answer all your questions:
Why two different ways to make a value an int ?
You have to take into account what the type of the value you are converting is. If you're converting a primitive to an int you can use a cast, if you're converting an Object you'll need to use some sort of conversion method specific to that type.
Also I made a search and it says parseInt() takes string as an argument.. So does this mean that parseInt() is ONLY to convert String into integer ?
Correct. You cannot pass any other type to the parseInt method or you will get a compiler error.
What about this casting then (int) ?? Can we use this to convert a string to an int too ?
No, casting to int will only work for primitive values, and in Java a String is not a primitive.
In your example, you are casting a floating-point number to an int. Integer.parseInt(), however, reads an integer value from a String.
You can only cast between compatible types (I'd link to the JLS but that might be too much for a beginner question).
Casting is basically just taking a value and saying, "Hey, this thing that was a double? Now it's an int. So there."
You can't do that with a string because it isn't anything like an int. You have to instead parse an int out of it, which is actually a lot harder than it sounds. Fortunately, it's already implemented for you so you don't have to worry about how it works.
Casting can only convert from one numeric type to another. Interpreting a string (aka parsing) needs to be done with a method call.
Let's start from the top.
int randomNumber=(int) (Math.random()*5);
Yes, this does indeed give a random integer between 0 and 4, but this is very much not the proper way of doing this. You see, if you forget a parenthesis, i.e. you type
int notSoRandomNumber=(int) Math.random()*5;
you'll always get 0 because casting has higher precedence than multiplication. That is to say the result of Math.random() is first coerced into an integer, which will always be 0 and then it's multiplied by 5, which is still 0.
I'd favour using java.util.Random for generating random integers. q.v. http://java.sun.com/javase/6/docs/api/java/util/Random.html#nextInt(int).
Casting can only be done between "compatible types". For primitive types and their wrappers (i.e. int, Integer, long, Long, &c.) you can always cast between them with the caveat that some conversions lose information. e.g. when casting a long to an int, the long may contain a number larger than Integer.MAX_VALUE]. This kind of casting Java basically got from C++ which it in turn got from C.
As for casting objects, it's actually simpler. Simply ask "is this object, o, an X?" If so then (X) o makes sense and has static type X. If o is not an X and you try to cast anyway, you'll get a ClassCastException signifying that o's dynamic (runtime) type is not compatible with X. This will probably make a lot more sense later when you get the difference between the static and the dynamic (runtime) type of objects.
Following code convert String to int without any methods
public class MyStringToNumber {
public static int convert_String_To_Number(String numStr){
char ch[] = numStr.toCharArray();
int sum = 0;
//get ascii value for zero
int zeroAscii = (int)'0'; // '0'=48 zeroAscii=48
for(int i=0;i<ch.length;i++){
int tmpAscii = (int)ch[i]; // for 0 ch[i]=3,3=51, tempAscii=51
// (0*10)+(51-48)
// 0 +3
// 3
// sum=3
// for 1 ch[i]=2,2=50, tempAscii=50
sum = (sum*10)+(tmpAscii-zeroAscii); // 0 +(51-48)=3 sum=3
// (3*10)=30+(50-48)
// 30 + 2
// sum=32
// for 2 ch[i]=5, 5=53 tempAscii=53
// (32*10)+(53-48)
// 320 + 5
// 325
// sum=325
// for 3 ch[i]=6,6=54, tempAscii=54
// (325*10)+(54-48)
// 3250 +6
// 3256
// sum=3256
}
return sum;
}
public static void main(String a[]){
System.out.println("\"3256\" == "+convert_String_To_Number("3256"));
}
}
Output "3256" --> 3256
Parse() method is available is many formats, Integer class having the method ParseInt() which is a static method, we to call this method by Integer.ParseInt()
Similarly Double class having ParseDouble()and we call it as Double.ParseDouble().
The more Generic way is XXXX.ParseXXXX()
The main use of this Method is to convert any Object into a Primitive.
And here you can raise a question why we need to convert into Primitives?
The answer is, we know that primitives are stored in stack area and objects are stored in Heap area, and you doesn't want to waste the Heap Memory and you can convert an Object into a Primitive.
And the other thing, while accessing any Object there may be Overhead.
It is better to use as a Primitive.

Categories