Possible Lossy Conversion error in java from double to int - java

We already know that the return type of Math.lang() function in java is double.
class Lossy {
public static void main(String args[]) {
int sum;
sum=Math.pow(2,3);
System.out.println (sum);
}
}
Now this statement results in possible lossy conversion error because the variable is of type int and Math.pow() return a double value i.e. 8.0 which is fair enough.
Now look at the code below with some changes.
class Lossy {
public static void main(String args[]) {
int sum=2;
sum+=Math.pow(2,3);
System.out.println (sum);
}
}
Now if we compile this code we don't get an error of possible conversion error, which we should get because we are storing a double value in an integer variable. Moreover, when we are printing the value it shows an integer value. Why?

In the first code, you are assigning a double value to a integer variable. since double value needs 8 bytes whereas integer needs only 4 bytes of memory. We cant store a 8 bytes value into a 4 bytes variable. That's why it shows possible loss of conversion error.
class Lossy
{
public static void main(String args[])
{
int sum;
sum=Math.pow(2,3); //Assigning double value to a int variable. its an Error
System.out.println (sum);
}
}
In the second example you are not simply or directly assigning a value to a integer variable. but you used an add and assign operator(+=), which functions as follows:
sum+=Math.pow(2,3) is equal to sum = sum + Math.pow(2,3);
When you do like the above one, JVM performs Automatic Type Conversion(double to int) or Parsing for the function Math.pow() and it converts the return value of the function to int while compilation. So it works fine. I hope you understand. Thanks!

Related

How do I provide byte value specifically to a class having m1(byte) and m1(int) signatures

public class HelloWorld
{
public void m1(int i)
{
System.out.println("int-arg");
}
public void m1(byte j)
{
System.out.println("byte-arg");
}
public static void main(String []args)
{
HelloWorld n=new HelloWorld();
n.m1(12);
}
}
O/P: int-arg
Question: 12 is int type and byte type too. so in this case int is the exact match everytime. so what value should I provide if I want to call m1(byte) method?
Thanks.
You can either declare it with type or cast it
byte b = 12;
n.m1(b);
or cast
n.m1((byte)b);
As others have said, you will need to cast it.
In Java, plain numbers (ex: 12) are int by default, if the number has decimals (ex: 12.0), it will default to float double type (thank you #Sushil for the correction). There are suffixed to force some types, but not for all types (ex: 12L is long, 12.0f is float).
You'll need to cast prior to passing the value.
n.m1((byte)12);

Parse different data type Java

Since int is less precise than double I thought I needed to cast it when parsing it into a method. Yet the following code runs fine. Why?
public class MyClass {
public static void main(String[] args) {
System.out.println(met(3/2));
}
static String met(int i){
return "This is what I get " + i;
}
}
When you do 3/2 that won't give you a double result. Integer division happens and result gets truncated to an integer. Hence there is no need of cast. In order to get double result, either needs to be cast to double so that get a compiler error to get it casted to double.
Try doing met(3d / 2), then you run into the compiler error which you are expecting.

How does the NullpointerException is not throwing when i use int? [duplicate]

This question already has an answer here:
Primitives/Objects Declaration, default initialization values
(1 answer)
Closed 7 years ago.
I have two different programs, the one that uses int and the other Double.
For the below code am getting NullpointerException
public class Solution {
Double cost;
void addTax(Double b)
{
cost+=b;
}
public static void main(String[] args)
{
new Solution().addTax(30.00);
}
}
But for the below code that uses int isn't getting any runtime error.
public class Solution {
int cost;
void addTax(int b)
{
cost+=b;
}
public static void main(String[] args)
{
new Solution().addTax(30);
}
}
So how does that possible? Please explain me.
A primitive (such as int) gets a default value of 0, while a reference type (such as Double) gets a default value of null.
Therefore cost+=b; throws a NullPointerException in the first code snippet (since it's equivalent to cost = cost.doubleValue() + b;), while in the second snippet it is equivalent to cost = 0 + b;, which is fine.
Double is a wrapper over double. Since Double will be set to null when your class's instance is initialized, trying to increment its value (which involves unboxing from Double to double will cause NPE.
Default value of int is 0, so no NPE Hurray :)
In first example you're using class Double and in second one just primitive type int. My guess is that you did it by mistake and you probably you just wanted to use primitive type 'double'

final casting concept doesn't apply for overloading

In my casting class, teacher taught us an interesting fact as follows.
class Casting {
public static void main(String args[]){
int i = 10;
byte b = i;
System.out.println(b);
}
}
We got an error
java:5: possible loss of precision
And then we changed the code as follows
class Casting1 {
public static void main(String args[]){
final int i = 10;
byte b = i;
System.out.println(10);
}
}
10
We got the correct output. As for the reason, he told that when we modify a variable final the variable is stored in the smallest data type possible. In this case was a byte. That's the reason that we were able to cast that without using the cast keyword.
But when we use method overloading like this,
class A {
void m(int i){
System.out.println("int");
}
void m(byte b){
System.out.println("byte");
}
public static void main(String args[]){
A a1 = new A();
final int i = 10;
a1.m(i);
}
}
I get the output int. If the final variables are stored in the lowest possible data type, it should be byte. So I tried the following code without overloading.
class A {
void m(byte b){
System.out.println("byte");
}
public static void main(String args[]){
A a1 = new A();
final int i = 10;
a1.m(i);
}
}
java:9: m(byte) in A cannot be applied to (int)
What's the reason for this? Is there any point that I have misunderstood?
You are mixing up memory space of variables and their type.
Calling the method m(...) will first of all check the type of the paramether variable. Here it is an int so it will chose the according overloaded method, no matter the size of the int in memory.
Although I really apreciate you first example that brings the light into one of the characteristics of the final identifier.
This bit isn't quite correct...
"As for the reason, he told that when we modify a variable final the variable is stored in the smallest data type possible. In this case was a byte."
It doesn;t store it as a byte, it stores it as an int, BUT it is effectively a constant so when Java compiles the line byte b = i; it knows for sure that the value will be 10, which doesn't need casting.
Is there any point that I have misunderstood?
Yes. The search for which method to apply depends on the types of the arguments. Unlike the case of assignments, there's no conversion attempt for method arguments (at least, there wasn't before autoboxing was added to the language, which adds another set of arbitrary rules).
If the conversion is part of an assignment, and the value can fit into a byte, the compiler performs the conversion automatically for you.
The JLS clearly explains that is a special case that only applies to assignment and not to conversions in other contexts.
It's worth mentioning that byte is useful only when you program for embedded devices or dealing with files/networks. byte and int occupy the same space because variables addresses are aligned.

Incorrect Casting

For some reason I am getting a precision error when I try to compile my code. The precision error comes in the return of my second method where I am trying to calculate the circumference. What am I doing incorrectly?
public class Methods2
{
public static final double PI = 3.14;
public static double calcCirc(double x)
{
return PI*x;
}
public static int calcCirc(int x)
{
return (2*(double) x)*PI;
}
public static void main(String[]args)
{
System.out.println(calcCirc(10.2));
System.out.println(calcCirc(4));
}
}
You are attempting to return a double value in a method declared to return an int. Java won't let you implicitly narrow your value like that.
If you're okay with the loss of precision, then explicitly cast the value to int -- Java will let you do that.
return (int) ((2*(double) x)*PI);
However, I would change the method to return double instead, not to lose precision:
public static double calcCirc(int x)
... as you already did with your other calcCirc method.
Both versions of calcCirc() ought to return doubles.
Also, side note--consider using different method names since they accept inputs that differ not only in type but also in semantics.
E.g. calcCircFromRadius(double radius), calcCircFromDiameter(double diameter). There's not really a reason to take an int as an input type here since Java will automatically cast ints to doubles for you.
try
public static int calcCirc(int x){
return (int)((2*x)*PI);
}

Categories