Parse different data type Java - 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.

Related

Changing the value in the Generics object in Java

I recently started to learn about generics in Java, and I understand the basic concepts of generics. However, one thing I don't understand is that I don't know why the following method doesn't work:
public class Generics<T extends Number> {
T num;
Generics(T n){
num = n;
}
//...
T timesTwo() { //Return the value that's twice as much as 'num'
return num * 2;
}
}
It was my first approach, and I kind of understand why it is not working. The error message said: The operator * is undefined for the argument types(s) T, int.
I guess Java couldn't multiply the T and int type together. (But shouldn't the compiler be able to auto-unbox T since it's involved in an expression AND the class extends Number?)
So I gave up on this method and tried to replace it with this method:
T times(T i) { //This method was supposed to receive another T object as
//an argument and multiply them together, then return the output
return num * i;
}
But once again, the exact same error message appeared (the only change was that int was replaced by T).
Why is the code not working, and how can I fix it?
I agree with the first two comments. Also, it's not a generics problem, it's just that the method doesn't work because it's not supposed to work because the boxing assumption you concluded doesn't apply here.
Autoboxing and Unboxing are supplied for some of the Number types but not all. See table below: https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
So while this works the way you expect (because both types are in the supported table):
public static void main(String[] args) {
Integer a = 3;
Integer b = 2;
Number answer = a * b;
System.out.println("Answer: " + answer);
}
This intuitively equivalent code will NOT work:
public static void main(String[] args) {
Number a = 3;
Number b = 2;
Number answer = a * b;
System.out.println("Answer: " + answer);
}
In fact, from the Compiler's perspective, it gives you the same cross-eyed look you would get if you tried this:
public static void main(String[] args) {
String a = "what does it even mean to multiply a string with a number..??";
Byte b = 2;
Number answer = a * b;
System.out.println("Answer: " + answer);
}
So to finish the point, from the compiler's perspective, since auto-boxing does not apply, it's just as confused as to how to multiply two Numbers as it is how to multiply two other random objects like a String and a Byte and reports the error accordingly

Possible Lossy Conversion error in java from double to int

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!

Passing the array to method (using random numbers)

I am writing a program piece by piece. I continue to receive compile errors. Can you look at my code to determine my issue?
So here, I am saying that array can store 1000 elements of the double type. Now I want to pass the array to my main method and place 1000 random numbers into the array. So I will create a new method.
public class Practice{
public static void main(String[] args){
double[]array=new double[1000];
}
}
Here, I have created a new method named passArray. I am trying to say that for each array element at its respective index (based on the count) assign a random integer until we reach 1000.
public static void passArray(double[]x){
for(int counter=0; counter<x.length; counter++){
x[counter]=(int)(Math.random()*1000);
}
Okay, so now I want to print my results to determine if my code does what I want it to do. In my main method, I will use an enhanced for loop:
for(double k: array)
System.out.println(k);
}//End of main Method
The problem I continue to encounter is a compile error. However, the output displays 999 values as a double value at random. What in the world am I missing here?
I think you have a typo ( remove the '}' from the for loop )
and you need to pass the array to the method to make it work.
This compiles and runs :
public class Practice{
public static void main(String[] args){
double[]array=new double[1000];
// calling the method
passArray(array);
// print the array
for(double k: array)
System.out.println(k);
//End of main Method
}
public static void passArray(double[]x){
for(int counter=0; counter<x.length; counter++){
// compiles ... but why cast to int if you have double[] ?
x[counter]=(int)(Math.random()*1000);
}
}
}
Not sure about the compile error, but your int to double problem is at the start of your code.
You declared an array of type double:
double[] array = new double[1000];
You're trying to type cast your random values to type int, which the compiler should accept.
x[counter] = (int) (Math.random() * 1000);
However since this is an array of type double, then you're storing the values as doubles. i.e. the values get cast back to double immediately. All that java is really doing is, changing from a double, eg. 567.97, to an int 567, and stroing it as a double again 567.0. Notice that it has now lost all its floating point information from being cast to an int. Or in geekier terms, the mantissa has been set to all 0's.
Either you will have to declare your array as type integer. Or cast back to int every time you access a value.
eg.
int[] array = new int[1000];
public static void passArray(int[] x) {
// code
}
or
System.out.println((int)k);
Edit: Are you getting a compiler error, or warning? There's a big difference. A warning will allow it to run, which your posts suggests is happening, an error will not compile, and thus not run. You may just be getting a warning about the type cast from int to double.

Testing whether a method's return type is a number?

As part of an autograder for a class I'm teaching, I would like to be able to test whether a student wrote a method whose return type was a numeric type (int, double, Integer, Double, etc.). I tried to do this as follows:
Method m = StudentClass.class.getDeclaredMethod(/* ... */);
return Number.class.isAssignableFrom(m.getReturnType());
This code will work correctly if the return type of the method is Integer or Double, but not if it's int or double. This confuses me, since it's legal to write
Number n = 137; // Assign an int to a Number
and
Number n = 1.608; // Assign a double to a Number
Why doesn't the code I've written above correctly if the method returns int or double? Aside from hardcoding tests to see if the result is int, long, char, double, etc., what can I do to test if the method returns a result of numeric type?
Thanks!
This solution does not touch the underlying cause but instead provides a workaround. It is not very elegant but considering it should never change (not unless Java somehow adds a new numeric type), I'm willing to put up with it for clarity reasons.
public class Main {
private static List<String> validTypes = new ArrayList<String>() {{
add("int");
add("Integer");
add("double");
add("Double");
add("long");
add("Long");
add("float");
add("Float");
}};
public static void main(String[] args) {
Main main = new Main();
for(Method m : main.getClass().getDeclaredMethods()){
System.out.println(m.getName() + ": " + validTypes.contains(m.getReturnType().getSimpleName()));
}
}
public static int mInt(){ return 1; }
public static Integer mInteger(){ return 1; }
public static double mDouble(){ return 1.0; }
public static Double mDoubleD(){ return 1.0; }
}
Output
main: false
mDoubleD: true
mInt: true
mInteger: true
mDouble: true
The problem you have is that int, long, double are primitives and not objects at all and do not inherit from Number. Its possible but unlikely someone could role there own version of a number class that also did not inherit from number which could make this question harder to answer but generally you would be ok yo do your number check and then also hardcode the primitives.
An alternative is to actually call the method with a value and check that the value back is numeric doing a similar thing to your cast above and checking for the exception or using http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/math/NumberUtils.html isNumber on the String.valueof result. Of course its eniterly possible that someone could still write a class/method that could do the correct thing but fail any of these checks.

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