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.
Related
In the commented line compiler does not give any errors and I'm confused why? Should I not have done and casting? I guess not since it seems to be working just fine but I don't know why!
public class Stack {
int[] array;
public Stack(int n)
{
maxsize = n;
length = maxsize;
array = new int[maxsize];
top = 0;
}
public void Delete()
{
if( array[0] != '\0' ) // \0 is string while array is of type int
{
array[top-1] = 0;
top= top-1;
}
}
}
'\0' is a char, not a string.
You can compare int with a char
The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers, respectively, and char, whose values are 16-bit unsigned integers representing UTF-16 code units (§3.1).
char is a 16-bit unsigned integer
You are actually comparing an int with a char, because you use single brackets.
This is possible, since typecasting allows you to convert a higher data type into lower.
Comparing a String to an int, or int[] for that matter, gives you a compile error.
'/0' is a char not a string, and when you are comparing them, then that char is automatically converted to int value (which is its ASCII value), and there is no exception.
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
Why doesn't the following code compile
int n = 5;
char c = n;
but the following does compile
char c = 5;
Aren't I just assigning an integer value to char in both cases?
A char can be assigned to an int without a cast because that is a widening conversion. To do the reverse, an int to a char requires a cast because it is a narrowing conversion.
See also JLS. Chapter 5. Conversions and Promotions.
His question is why his code does not compile, not how to do what he's trying to do.
The reason the line
char c = n
does not compile, is because the range of char (-2^15 to 2^15 - 1) is much smaller than the range of int (-2^31 to 2^31 - 1). The compiler sees you are trying to assign an int to a char, and stops you, because it realizes this.
This question already has answers here:
Do Java arrays have a maximum size?
(10 answers)
What does "possible lossy conversion" mean and how do I fix it?
(1 answer)
Why I can't create an array with large size?
(5 answers)
Closed 1 year ago.
I wish to enter one int and another long ex: 1 and 1000000000, and now I wish to create an array of size 1000000000. And then at each index of array, store int val, ex: arr[100000000] = 4.
When I'm trying to do this Netbeans shows me an error in this line:
arr = new long[y+1]` and `arr[j] = 0`
"Possible Lossy conversion from long to int".
Here's my code:-
public static void main(String[] args) throws IOException
{
BufferedReader s = new BufferedReader(new InputStreamReader(System.in));
String[] xe = s.readLine().split(" ");
int x = Integer.parseInt(xe[0]);
long y = Long.parseLong(xe[1]);
long []arr;
arr = new long[y+1];
for(long j=0;j<=y;j++)
arr[j] = 4;
}
Array index is an integer in Java and the compiler will advice you. So maximum array size is (aproximately) Integer.MAX_VALUE. For bigger arrays you should use ArrayList.
To go around this dirt&quick
arr = new long[(int)y+1];
The size of an array can only be an int. That is you, can not create arrays that are larger than Integer.MAX_VALUE (2147483647), probably a few elements less (depending on the VM). You can cast your value to int
arr = new long[(int)(y+1)];
but this will produce invalid results when the value of y is actually larger than the maximum allowed size.
You need to convert/cast y and j to int.
Also your incrementing var shouldn't be long when you're just adding 1.
You cannot create an array with more than 2^31-1 entries, so you should use an int value when you do so (the compiler is simply warning you that the size will be truncated from long to int). 1000000000 is small enough to fit into int, so you basically have no reason to use long y in order to store this value in the first place.
According to your description, the array itself is designated to store int values, so it doesn't need to be an array of long values.
In short, you can and should change every long in your code to int.
I think you have some misconception about typecasting here. In Java down casting is allowed as already mentioned you can down cast it to integer
arr = new long[(int)(y+1)];
But here the main problem is that array allocation should takes integer value so that the same number of homogeneous space can be allocated.
If you want more space than an integer range then you should use ArrayList which is dynamically grow-able array because if we give that much liability to a user to declare a large amount array memory then our system may run out of the memory as array is a static memory allocation data structure.
The same stands true for
arr[j]=4;
It should be:
arr[(int)j]=4;
In static array we cannot use long datatype values for assigning index position.
1.Either convert long to int in for/while/do while loop.
2. Typecast arr[(int)i] to remove error
I can assign char to int as follows.
char c = 'a';
int a = 0;
a = c;
Then, why I can't assign a char[] to int[]?
int[] ints= new int[4];
char[] chars= new char[4];
ints = chars; // Cannot convert from char[] to int[] ?? But why?
The char to int promotion is a special provision for primitive types.
Regarding arrays, the Java Language Specification says this:
If an array variable v has type A[], where A is a reference type, then
v can hold a reference to an instance of any array type B[], provided
B can be assigned to A. This may result in a run-time exception on a
later assignment; see §10.10 for a discussion.
This works only "if A is a reference type." Even though char can be assigned to int, this rule doesn't apply because it doesn't apply to primitive types.
So, without any special provision for assigning incompatible types, the assignment fails.
If it were allowed, you'd introduce the possibility of ArrayStoreException being raised on stores to primitive arrays (just like you currently have with arrays of reference types):
ints[0] = Integer.MAX_VALUE; /* Exception! */
This happens because ints is an alias to a char[] that can't accommodate a 32-bit value. I'm not sure why this is acceptable for reference types, and not for primitives, but it probably has to do with all of the special treatment already required for primitives.
Not sure I can supply more for you other than the concept of casting from char[] to int[] doesn't exist in the language specification.
At a low level, it probably has to do with iteration through the array itself. If I treat a char[] like an int[] indexing through it in memory at a low level wouldn't work. A step of 4 bytes (treating like int[]) would actually step 2 indices in a char[].
Then, why I can't assign a char[] to int[]?
The first answer is because the Java Language Specification forbids this. The key section is 4.10.3. which specifies the subtyping rules for array types. The rules mean that no primitive array type is a subtype of another (different) primitive array type. One consequence of that is the assignment is forbidden.
The second answer (and the reason that the JLS forbids it) is that it would break the type system if it was allowed. Consider this example:
int[] ints= new int[4];
char[] chars= new char[4];
ints = chars;
The assignment is a reference assignment. What this means is that ints would now point to the array object that was created by new char[4] on the previous line. (It is NOT equivalent to a loop that assigns the values of chars' elements to ints.)
Now lets add a method:
public void paranoidIncrement(int[] ints) {
for (int i = 0; i < ints.length; i++) {
int tmp = int[i];
ints[i] = ints[i] + 1;
assert tmp + 1 == ints[i];
}
}
and lets combine it with the previous code:
int[] ints= new int[4];
char[] chars= new char[4];
ints = chars; // assume this is legal ...
paranoidIncrement(ints);
So what does this mean? Well paranoidIncrement is going to treat the argument (which is really a char[]) as if it was an int[]. But what happens when we do ints[i] = ints[i] + 1;? If the cells of the actual array are really chars then the JVM has to truncate the values to make them fit, or throw an exception.
If it truncates the value, then the assert statement will fail. And that is so counter-intuitive that it is just plain broken.
If it throws an exception, then we've suddenly got a whole class of new bugs that are (under the JLS rules) currently detected at compile time.
The way that Java avoids that brokenness is to say that you can't assign a char[] to an int[].
int[] a = new int[4];
int[] b = a;
Both a and b will reference the same array - there is no copying involved.
If ints=chars were allowed, you would have an int[] variable referencing an array of 16-bit chars. An assignment such as ints[0] = 0x12345678 would be valid, yet what should the outcome be?
You cannot assign in this manner because it is a type mismatch. The types int[] and char[] are not compatible.
It doesn't work as you expect because (in the first case) the language is hiding some of the type conversion details from you. That is, when you assign a char to an int it's sometimes called an implicit cast. It's equivalent to doing this:
char c = 'a';
int a = 0;
a = (int) c;
... which would work fine, but the language doesn't force you to write the (int) cast every time.
In the second example, a cast will not work. If you try to add an explicit cast in, you would get an error such as:
Foo.java:9: inconvertible types
found : char[]
required: int[]
int[] ints = (int[]) chars;