Why no promotion when adding ints to List<Double> - java

in Java I created an ArrayList of Double and I invoked the method list.add(1), however, I get an error. If I can assign an int to a double variable like this: double num = 1; due to automatic promotion, then why can't I add a 1 to ArrayList of Double via automatic promotion?

You're not trying to convert int to double; you're trying to convert int to Double, which is a combination of boxing and the implicit conversion from int to double. That doesn't work, even in a simple assignment:
// Error: incompatible types: int cannot be converted to Double
Double num = 1;
It doesn't even work for Long - you need to specify a long literal:
Long num1 = 1; // Invalid
Long num2 = 1L; // Valid
In your case, you just need to use a double literal, e.g.
list.add(1.0);
list.add(1D);

Related

double vs Double as Floating Point Numbers in Eclipse

My question is two-part.
Why does the following work fine in Eclipse? Isn't "Double" a class?
Double h = 2.5;
double j = 2;
Why does "Double" above give me an error when I don't assign a decimal value to it, but "double" is fine whether or not I assign a decimal value to it?
As was already mentioned, the term is autoboxing. The object wrappers for the primitive types will automatically convert.
As to your second part,
Double a = 2;
Doesn't work since 2 is not a double and the auto boxing only works between the same types. In this case 2 is an int.
But if you cast it.
Double a = (double)2;
works just fine.
double a = 2;
works because an int can be automatically converted to a double. But going the
other way doesn't work.
int a = 2.2; // not permitted.
Check out the Section on conversions. In the Java Language Specification. Warning that it can sometimes be difficult to read.
Amended Answer.
In java you can cast up or down or have narrowing or widening casts (going from a 32 bit to 16 bit) value is narrowing. But I tend to think about it is losing vs not losing something. In most cases if you have the potential to lose part of value in assignment, you need to cast, otherwise you don't (See exceptions at end). Here are some examples.
long a = 2; // 2 is an integer but going to a long doesn't `lose` precision.
int b = 2L; // here, 2 is a long and the assignment is not permitted. Even
// though a long 2 will fit inside an int, the cast is still
// required.
int b = (int)2L; // Fine, but clearly a contrived case
Same for floating point.
float a = 2.2f; // fine
double b = a; // no problem, not precision lost
float c = b; // can't do it, as it requires a cast.
double c = 2.2f; // a float to a double, again a not problem.
float d = 2.2; // 2.2 is a double by default so requires a cast or the float designator.
float d = (float)2.2;
Exceptions
No cast is required when converting from int to float or long to double. However, precision can still be lost since the floats only have 24 bits of precision and doubles only have 53 bits of precision.
To see this for ints you can run the following:
for (int i = Integer.MAX_VALUE; i > Integer.MAX_VALUE-100; i--) {
float s = i;
int t = (int)s; // normal cast required
if (i != t) {
System.out.println (i + " " + t);
}
}
Double is a wrapper class, creating a new Double casts a primitive variable of the SAME type into a Object. For Double h = 2, you are wrapping a int into a Double. Since wrapping only works between same types, if you want your Double variable be 2, then you should use
Double h = 2.0;

What's the difference between declaring a long variable with 'L' and without? [duplicate]

This question already has answers here:
Using the letter L in long variable declaration
(2 answers)
Closed 5 years ago.
What's the difference between the following?
long var1 = 2147483647L;
long var2 = 2147483648;
(or any primitive variable declaration)
Does it have any performance issue with or without L? Is it mandatory?
In the first case you are assigning a long literal to a long variable (the L or l suffix indicates long type).
In the second case you are assigning an int literal (that's the default type when no suffix is supplied) to a long variable (which causes an automatic type cast from int to long), which means you are restricted to the range from Integer.MIN_VALUE to Integer.MAX_VALUE (-2147483648 to 2147483647).
That's the reason why
long var2 = 2147483648;
doesn't pass compilation (2147483648 is larger than Integer.MAX_VALUE).
On the other hand
long var2 = 2147483648L;
would pass compilation.
For easy understanding each of the type have range in java.
By default every digit you entered in java is either byte or short or integer.
short s = 32767;
byte b = 127;
int i = 2147483647;
So if you assign anything except from their range you'll get compilation error.
int i = 2147483648; //compilation error.
Type range
And when you write long longNumber = 2147483647;
though it falls in long range but internally java treat it as
long l = (int) 2147483647;
you wont get any errors.
But if we assign beyond the range of integer like
longNumber = 2147483648; we will get compilation error as
long o = (int) 2147483648;
here java will try to convert the 2147483648 to int but it is not in int range so widening error is thrown.
To indicate java that the number what we have written is beyond the integer range just append l or L to the end of the number.
so java will wide his range till long and convert it as
long o = (long) 2147483648;
By default every floating point or digit with floating points (.) are size of double. So when you write some digits with (.) java treat as a double and it must be in double range.
As we know the float range is smaller then double.
so when you write
float f = 3.14;
though it falls in double range but internally java treat this assignment as
float f = (double) 3.14;
here you are assigning the double to float narrowing which is not correct.
so either you have to convert the expression like that
float f = (float)3.14;
or
float f = 3.14f; // tell jvm to assign this in float range by appending **f** or **F**
If we don't mention the L with the value then value is considered to be int value.
It type casts the int to long automatically.

Math floor mixing types error?

I have this:
String a = tonsescolhidos.getValue().toString();
int tons = Integer.parseInt(a);
float distlevel = 256/(tons - 1);
int temp;
temp = Math.floor(((float) (tons / distlevel) + 0.5)*distlevel);
tons = temp;
I get the error: "Incompatible types: possible lossy conversion from double to int" in the 5th line. How do i cast the variables in the right way.. what am I missing?
Math.floor only has one overload: double Math.floor(double). That always returns a double.
You would need to explicitly cast it to an int:
temp = (int) Math.floor(...);
But note that it is potentially lossy: double can store values too large to store in an int. So, you need to ensure that it's not a lossy operation by ensuring that the double's value is between Integer.MIN_VALUE and Integer.MAX_VALUE, by constraining the inputs appropriately.
Alternatively, rearrange your calculation so that you can do it all in integer math.

Casting Double object to int

How can I convert from a Double object to an int? The following code works but seems slightly unconventional (with casting twice):
Double d = new Double(4.0);
int i = (int)(double)d;
When I try int i = (int)d, I get an error from Eclipse (Cannot cast from Double to int), which makes sense. Nevertheless, is there a simpler way of converting a Double object to an int?
Double.intValue()
is the provided method that does that conversion.
If you cast double to int you will loss decimal value.. so 4.99 double become 4 int. If still want to convert than try-
int i = d.intValue();
In your case you use
Double.intValue()
as a method to convert the Double Object to Integer.

java division: Inconvertible types found: int

What's wrong with this code
int numOfPrimes=pf.FindNumPrimes(10000);
Double frequency=((Double)numOfPrimes)/10000d;
Says
inconvertible types found : int
required: java.lang.Double Double
frequency=((Double)numOfPrimes)/10000d;
You're trying to autobox an int to a Double object, which is invalid.
Try:
int numOfPrimes=pf.FindNumPrimes(10000);
Double frequency=((double)numOfPrimes)/10000d;
Don't cast from primitives to wrapper types. Use lower-case double. And you don't need any casting in this case - the compiler does that automatically. The above can be simplified to:
int numOfPrimes = ...;
double frequency = numOfPrimes / 10000d;
You should almost never mix primitives with wrappers. And always prefer primitives (if possible). Use Double.valueOf(..) for conversion if you need to.
Double is not a primitive type (like int, long, byte, etc). It's a class type. You can convert between double and Double using autoboxing but not between int and Double.
You should either declare numOfPrimes as double or do the cast to a double instead of a Double
double numOfPrimes=pf.FindNumPrimes(10000);
Double frequency=((Double)numOfPrimes)/10000d;
or
int numOfPrimes=pf.FindNumPrimes(10000);
Double frequency=((double)numOfPrimes)/10000d;
or without unnecessary casts:
double numOfPrimes = pf.FindNumPrimes(10000);
Double frequency= numOfPrimes /10000d;
or
int numOfPrimes = 10;
Double frequency = numOfPrimes /10000d;

Categories

Resources