I am new to Java programming and I am working with arrays .In arrays
index needs to be an integer and it doesn't allow float or double so I used long data type for index and it gave error. Whereas when I used byte and short and Int it worked . I want to know since the error was "possible lossy conversion from long to int "
Is it such that only int is allowed in index and since byte and short are small in size that's why it worked (auto promotion) and long was larger than int so it gave error(no auto depromotion)plz help
import Java.util.*;
class Demo{
public static void main(String args[]){
long n=5;
int a[]=new int[n]; //error possible lossy conversion from long to int
System.out.println(Arrays.toString(a));
}
}
In short, it's because that's the way the language is designed. If you take a look at section 10.7 of the Java language specifications, you'll notice that the length of the array is defined as an int (which is smaller than a long). Semtantically, ints and longs represent integers, but "larger" integer types will not be automatically cast to "smaller" integer types.
Needs to be int. Long, short, byte, float are other data types. Implicit or explicit conversion of your supplied data type can occur, but the index of your array will only be constructed with an int by the javac.
An array object contains a number of variables. The number of variables may be zero, in which case the array is said to be empty. The variables contained in an array have no names; instead they are referenced by array access expressions that use non-negative integer index values. These variables are called the components of the array. If an array has n components, we say n is the length of the array; the components of the array are referenced using integer indices from 0 to n - 1, inclusive.
Oracle Docs
You cannot cast long to int or rather cannot convert from long to int.
The only conversion you can do is
•
byte to short, int, long, float, or double
•
short to int, long, float, or double
•
char to int, long, float, or double
•
int to long, float, or double
•
long to float or double
•
float to double
Since you have array of int you can store int ,short and byte datatype values
Related
The following code:
import java.util.*;
public class HelloWorld{
public static void main(String []args){
Scanner s = new Scanner(System.in);
long N = s.nextLong();
long[] arr = new long[N];
System.out.println(N);
}
}
Getting this error:
HelloWorld.java:12: error: incompatible types: possible lossy conversion from long to int long[] arr = new long[N];
As far as I understand there is no int involved in the code, can anyone explain why this is happening and how to solve this issue?
The size of arrays in Java can not exceed the range of an int, so the size parameter for array creation is implicitly an int. Change N to an int.
From JLS 15.10.1 Array Creation Expression (emphasis mine):
Each dimension expression undergoes unary numeric promotion (§5.6.1). The promoted type must be int, or a compile-time error occurs.
Array subscripts and sizes in Java must always be int, so in this expression new long[N] the N is converted to int, and because long has wider range than int, it's a narrowing conversion which must be done explicitly: new long[(int) N]. Or just read N as int: int N = s.nextInt().
long[] arr = new long[N];
In this line you are creating an array of size N, but array sizes in Java can only be integers, that's why it's reading N as an int, if your intent is creating an array of N size you should read N as an int
int N = s.nextInt();
The maximum length of an array in java is 2,147,483,647 (2^31 - 1) which is the maximum length of int. So implicitly an array can have maximum the value of an int. So it cannot accept a long number.
I'm studying java by Herbert Schildt's "Java for beginners" book. It is said that, being a destiny variable compatible and sufficiently big to store an origin one, an automatic conversion is done.
That being said, an Int should be able to store an Float and vice-versa, since they both have a 4 bytes size.
public class MyClass {
public static void main(String args[]) {
int i = 10;
float f = i;
float ff = 10;
int ii = ff;
}
}
However, when compiled, this piece of code generetes the following error:
/MyClass.java:15: error: incompatible types: possible lossy conversion from float to int
int ii = ff;
^
1 error
Why is there that, being a compatible type and sufficiently big to store each other, a float can store an int but an int cannot store a float?
Because float contains numbers also after the decimal point and int does not. Without this you shouldn't be able to simply trim the decimal part from the number by explicitly casting the float to int too.
an Int should be able to store an Float and vice-versa, since they both have a 4 bytes size.
The size of the data is not the important part. Rather it is about the values which can be stored in the give number of bytes. int can only store whole number values between -2^31 and 2^31-1. On the other hand, float can store decimal values.
As you can see, you can store a int into a float, but you can't put a float inside a int.
This heappens because the internal structure of float is a decimal number and int, as its name says, is integer.
For more information you can take a look into this discussion about How are floating point numbers are stored in memory.
Int to float is never a lossy conversion if the integer value will be within the range of maximum integer value that float can store as value will always be stored/converted to <intvalue>.0 like 4 will be stored as 4.0. But in case of conversion from float to int, your fraction value will be lost so JVM gives you such error. If you can take such risk then you have to explicitly convert the float value into int.
the below code gives me -1894967296 as result but this is not expected. What is exactly happening? I can't figure it out. The result has to be 2400000000 as per my calculator :(
import java.util.List;
import java.util.ArrayList;
public class Calculate{
public static void main(String []args){
int result = 1;
List<Integer> integer = new ArrayList<Integer>();
integer.add(100);
integer.add(200);
integer.add(300);
integer.add(400);
for (Integer value : integer) {
result *= value;
}
System.out.println(result);
}
}
When I debug, it works correctly till the third iteration.
Update:
As per the answers, the int primitive type range has been exceeded but what will happen to the int variable? It will be defaulted to some value?
The largest number Java can store in an int is 2^31 - 2147483648
2400000000 is larger than that so "wraps around".
You need to use a 64 bit data type such as long.
2400000000 is too large to store in an int. It would be more appropriate to use a long which has a minimum value of -2^63 and maximum value of 2^63 - 1 which your number is well within the range of.
more info here
The expected result 2400000000 > Integer.MAX_VALUE. So, use long instead of int to store result.
Use BigInteger instead of int because the int is limited
Java doc:
int: By default, the int data type is a 32-bit signed two's complement integer, which has a > minimum value of -231 and a maximum value of 231-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 232-1. Use the Integer class to use int data type as an unsigned integer. See the section The Number Classes for more information. Static methods like compareUnsigned, divideUnsigned etc have been added to the Integer class to support the arithmetic operations for unsigned integers.
That's what most programmer call Pillage. You shouldn't save a long value inside a small variable, don't expect an Int to save a value 2^31+.
For what you want to do there's a long
i was developing the below code
static String m(float i) {
return "float";
}
static String m(double i) {
return "double";
}
public static void main(String[] args) {
int a1 = 1;
long b1 = 2;
System.out.print(m(a1) + "," + m(b1));
}
Both results in output float, float , what the reason behind that please advise and how can I call double please advise thanks a lot.
Short answer: Java can automatically widen ints and longs to both floats and doubles, but Java will choose to widen to a float because it is smaller (in terms of memory footprint) than a double. You can call the double version of the method by explicitly casting the argument to a double:
System.out.print(m((double)a1) + "," + m((double)b1));
Long answer: Each primitive data type in Java has a size (measured in bytes), which determines how much information (or rather, what range of values) a given primitive can hold. The table below shows the sizes of some of Java's primitive data types:
byte 1 byte
short 2 bytes
char 2 bytes
int 4 bytes
float 4 bytes
long 8 bytes
double 8 bytes
Java will automatically "widen" values for you in certain situations, following some well-defined rules from the Java Language Specification. The following widening primitive conversions are performed by Java automatically:
byte to short, int, long, float, or double
short to int, long, float, or double
char to int, long, float, or double
int to long, float, or double
long to float or double
float to double
The other rules that are applicable to this situation are:
Widening does not lose information about the overall magnitude of the numeric value.
Widening from an integral type to another integral type does not lose any information at all; the numeric value is preserved exactly.
Widening an int or long value to a float, or of a long value to a double may result in a loss of precision.
For example, Java can safely widen an int to a long without changing the numeric value at all, because both are integral types and a long is larger than an int (see rule 2). Java can also widen an int to a float, but there might be a loss of precision. The sample code below demonstrates this loss of precision.
public static void foo(float f) {
System.out.println(f);
}
public static void main(String[] args) {
int a = 123;
int b = 1234567890;
foo(a);
foo(b);
}
The first call to foo(float) prints "123.0" as expected. The int value "123" is widened to the float value "123.0". The second call prints "1.23456794E9", which makes sense when you take rule 3 into account. The value "1234567940" is the same magnitude as but less precise than "1234567890".
The other piece of information that is key here: when multiple overloaded methods are present, Java determines which method to call by choosing the method with the smallest parameter type (in terms of memory footprint) such that the given argument is capable of being widen to the parameter type. In other words, the number you pass to the method must be capable of being widened to the parameter type of the method, and if multiple overloaded methods satisfy that requirement, Java will choose the method whose parameter type is of the smallest size.
In your case, you are passing an int and a long to one of two overloaded methods. Java will look at methods m(float) and m(double) to determine which method to call. An int can be widened to a float and a double, but a float (4 bytes) is smaller than a double (8 bytes), so Java will choose to call m(float). The same is true when you call the method with a long argument: float is chosen because it's the smallest data type that a long can be widened to.
If you want to call the double version, make it explicitly a double: m((double)a1)
Take a look at the JLS §8.4.9 - Method Overloading
Try
System.out.print(m(1f)+","+ m(2d));
why are you creating an int and long to test it? Well, what is actually happening is that both parameters are converted to float by default.
how can I call double?
Use a double variable
double d = 3.3;
m(d);
import java.lang.Math;
class Squr
{
public static void main ()
{
Squr square = new Squr();
System.out.println ("square root of 10 : " + square.mysqrt(10));
System.out.println (" Square root of 10.4 : "+ square.mysqrt(10.4));
}
int mysqrt ( int x)
{
return Math.sqrt(x);
}
double mysqrt (double y)
{
return Math.sqrt(y);
}
}
When we compile it then it's giving error
possible loss of precision
found :double
required :int
I have written this program for calculating square root of int or double type values by method overloading concept.
How can I fix my error so I can find the square root of an int and a double?
I don't think this is anything to do with method overloading - it's actually quite simple.
Math.sqrt() returns a double, but in your first class method, you're trying to return this directly from a method that returns int. This would be a lossy conversion, and you'd need to perform it manually.
In particular - when you call mysqrt(5), which integer do you expect the answer to be? 2? 3? Some "warning, not a whole number" value like -1? I suspect that perhaps you meant to return double for both methods, and differ only in the type of the arguments.
My eclipse gives:
Type mismatch: cannot convert from double to int
Whatever the message is, you fix this by: return (int) Math.sqrt(x);
This has nothing to do with overloading though.
By the way, a square root of an integer can be double, so by having a return type int you are truncating possibly important information.
Hence I'd advise for simply using Math.sqrt(..) without making any additional methods. If you need the whole part, you can use Math.floor(..) or Math.round(..)
http://download.oracle.com/javase/6/docs/api/java/lang/Math.html#sqrt%28double%29
returns double. Casting in int will loose precision. Don't you think so?
JLS has something to say on conversions. See this http://java.sun.com/docs/books/jls/third_edition/html/conversions.html
The following 22 specific conversions on primitive types are called the narrowing primitive conversions:
* short to byte or char
* char to byte or short
* int to byte, short, or char
* long to byte, short, char, or int
* float to byte, short, char, int, or long
* double to byte, short, char, int, long, or float
Narrowing conversions may lose information about the overall magnitude of a numeric value and may also lose precision.