double vs Double as Floating Point Numbers in Eclipse - java

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;

Related

integer division java returns a double? What is going on?

See screenshot:
What is going on there? i see that we're casting 23F to an int so in choice "II", we wind up doing 23/7 which should give us 3... at least so I thought. But why do we have 3.0? Why do we get a double?
Here is the context:
float x = myFunc(23F);
int myFunc(float x) { ... }
The right hand side of the expression is an int and you have correctly deduced that its value is 3.
When you assign an int value to a float variable, the integer will be converted to a float.
This is an example of a primitive widening conversion. It can happen in various contexts when you are going from a "smaller" primitive numeric type to a "larger" primitive numeric type. The int type is "smaller" than the float type. In general:
byte < short and char < int < long < float < double.
Why do we get a double?
See above. But it is a float not a double.
When you output a number in Java using println, a float and a double will look the same. The println method won't output a float with an F suffix. The F and D suffixes are only used in Java source code.
Because the function that return the result is assigned to z, and the type of z is float.

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.

Math.ceil(x / 50d) - What is the "50d"

I jsut found this code snippet and was wondering what the 50d actually means? I've been searching the web, but can't find anything useful.
Here' the complete code snippet:
public int CalculateMinimumDiameterFilter(){
CalculateFilterAreaRequirement();
double val1 = filterAreaRequirement /Math.PI;
double val2 = Math.sqrt(val1);
double val3 = val2 * 2;
int val4 = (int)Math.round(val3 * 1000);
minimumDiameterFilter = (int) (Math.ceil(val4 / 50d) * 50);
return minimumDiameterFilter;
}
Can anyone explain to me what the 50d actually does?
It is an explicit declaration of a number to be a double as defined in the JLS
3.10.2. Floating-Point Literals
A floating-point literal is of type float if it is suffixed with an ASCII letter F or f; otherwise its type is double and it can optionally be suffixed with an ASCII letter D or d
You may take a look at Java Primitive Data Types which will give you a good explanation.
50d in this case means the 50 is not of type integer (int) by of type double (50.0).
Not only we can do 50d. You may also see people writing things like:
long serialNo = 1234567L;
In this case the L after the number means that I want to let serialNo be of type long. If you don't place the L, the default type of whole number will be integer (int).
Instead of writing 50d, the person who writes that code could have written it as 50.0 as well. It will mean the same thing in this case because by default, floating point values in Java are double. Whole numbers are int unless otherwise specified by the postfix (such as l, d, f..etc).
Example:
double d1 = 50.0; //ok! 50.0 will be double by default
double d2 = 50.0d; //ok! 50.0 is already in double, no harm putting a "d"
double d3 = 50d; //ok! 50 becomes a double
double d4 = 50; //ok! trying to store int into double (no loss of precision)
double d5 = 50f; //ok! trying to store float into double (no loss of precision)
float f1 = 0.1f; //ok!
float f2 = 0.0; //not ok! trying to store double into float (loss of precision)
float f3 = 50d; //not ok! trying to store double into float (loss of precision)
50d means the number 50 with double type.
This is required because val4 as an int, divided by 50 as an int, will return an int and Java will be rounding it to the floor, which is not what is expected.
d is short for double. Standard the number 50 without any decimal (ie: 50.0) is just an int. You need to add the d to plain 50 to state that you want it expressed as a double.
The d suffix forces it to be a double literal instead of an int literal.

Java Ceil Weirdness

Why does this output 0 instead of 1?
System.out.println((int) (Math.ceil(1/2)));
While this one correct outputs 1
System.out.println((int) (Math.ceil((double) 1/ (double) 2)));
Shouldn't Math.ceil(double) automatically type cast the 1/2 to double?
Math.ceil does, indeed, cast the integer to a double. But it only does so after the integer operation has been performed. This is the order of operations:
int a = 1;
int b = 2;
int c = a / b; // now equals 0, because it's an integer operation.
double d = (double)c; // now it's a double - but equals 0.0.
double e = Math.ceil(d); // still 0.0.
You're thinking of 1/2 as a fraction, but it's not - it's an expression of two ints and an operator that has to be resolved before its value can be used in further expressions.
Explicit casting always require (datatype) to be mentioned. Here 1 and 2 represents itself as int and to cast from int to double explicit casting will be introduced. Whenever casting is preformed from lower to higher datatypes explicit casting should be imposed. See example below;
public class MainClass{
public static void main(String[] argv){
int a = 100;
long b = a; // Implicit cast, an int value always fits in a long
}
}
An explicit casts looks like this:
public class MainClass{
public static void main(String[] argv){
float a = 100.001f;
int b = (int)a; // Explicit cast, the float could lose info
}
}
Code Snippet: Source
The first thing which happens when that line is executed, is that the division 1/2 is resolved. This happens without any consideration for the method-call to Math.ceil it is embedded in.
The literals 1 and 2 are integers. When you perform a division with only integers as arguments, an integer division is performed, which always rounds down. So the term gets resolved to the int value 0. Math.ceil() only accepts type double, but that's not a problem because Java can perform the conversion automatically and turn the int 0 to a double 0.0.
To perform an explicit floating point division, have one or both of the parameters to the division be floating point literals:
System.out.println((int) (Math.ceil(1.0/2.0)));

Java Casting in Method Overloading

I have the methods overloading such as:
public int sum1(int a, int b)
{
int c= a+b;
System.out.println("The method1");
return c;
}
public float sum1(int a, float b)
{
float c= a+b;
System.out.println("The method2");
return c;
}
public double sum1(float a, float b)
{
double c= (double) a+b;
System.out.println("The method3");
return c;
}
From the main method, suppose we have
double x=10.10f;
double y=10.20f;
the apparent type for x and y is double, but the actual type is float. when I call
System.out.println(" the output is :"+cc.sum1(x,y));
the error in the compile-time.
The method sum1(int, int) in the type Class is not applicable for the arguments double, double).
where it should go to sum1 (i.e. method3) by casting double to float
TL;DR version of this answer:
Variables of primitive types never have a different type at execution-time to their compile-time. (A double is always a double, never a float, etc.)
Overload resolution (picking which method signature is used) is performed using the compile-time types of expressions
Method implementation of the picked signature is performed using the execution-time type of the target of the method call
the apparent type for x and y is double, but the actual type is float
No, it's not. You've just got a conversion from the assigned float literals to double values. The actual values are double.
Primitives don't work like objects - there's no idea of an int value still being an int inside a double variable, for example.
It's simpler to take an example with integer types. Suppose we have:
byte b = 100;
int x = b;
The value of x is the 32-bit integer representing the value 100. It doesn't "know" that it was originally assigned from a byte value... there just happened to be a conversion from byte to int at the point of assignment.
Compare that with reference types:
String x = "hello";
Object y = x;
Here, the value of y really is a reference to a String object. That type information is preserved precisely because there's a whole object that can contain it, and because the value of the variable itself is only a reference. (The bits themselves don't need to change as part of the assignment - in a simple VM at least, they'll be the exact same bits in x and y, because they're referring to the same object.)
Even in that case, however, overload resolution occurs based on the compile-time type of the arguments, not their actual values at execution time. The only way that the execution-time type of a variable gets involved is with overriding based on the target of a method call. So if we have:
Foo f = new X();
Foo g = new Y();
Foo h = new Z();
f.someMethod(g, h);
... then the compiler will look for a method in Foo which has two Foo parameters (or Object or other superclasses/interfaces) - the actual types of the objects involved are irrelevant. At execution time, however, if that method has been overridden in X, then that override will be called due to the execution-time type of the object f's value refers to.
Casting double to float may cause loss of data, since it's a narrowing conversion, and is therefore not done automatically by the compiler. You'll have to cast the variables to float explicitly if you want it to take place.
No, the actual type of the variables is double. The type of the constants that you're assigning to that double variable, which get promoted on assignment, is float.
Try to add new function: public double sum1(double a, double b). It will solve your problem.
And also, this kind of casting will cause loss of data.
Floats are funny that way.. they always try to convert to doubles automatically. This code compiles, with floats at every turn.
public class wood {
public static void main(String[] args) {
float x = 10.1f;
float y = 10.2f;
System.out.println("Sum of x and y = " + sum1((float)x, (float)y));
}
public static float sum1(float x, float y) {
return (float)((float)x+(float)y);
}
}
edit; note that using a cast operator outside of parenthesis will cast after what is inside of the parenthesis has computed. So;
System.out.println((int)(50.5 + 50.7));
will print out 101.
Within java, some data conversions are automatic, and others require cast operators.. simply put, java will automatically make widening conversions, while you will have to use a cast operator for narrowing conversions.
The hierarchy of primitive data types is as follows:
byte //1 byte (-128 through 127)
short //2 bytes (over 32,000 give/take from 0)
int //4 bytes (over 2billion give/take from 0)
long //8 bytes (over 9 quintillion (10^18) give/take from 0)
float //4 bytes (holds 7 decimal places)
double //8 bytes (holds 15 decimal places)
java will not make narrowing conversions automatically, because then data is at risk of being lost. Both byte and short will become ints automatically.
short s = 5;
byte b = 5;
short sum = s + b; //this will cause an error!
s and b automatically make a widening conversion to an int, and an int cannot be assigned to a short without a cast operator.
short sum = (short)(s + b);
would be needed.

Categories

Resources