I got this from one of Enthuware's SCJP 1.6 exams:
float f = Integer.MAX_VALUE; int i = (int) f; System.out.println( i == Integer.MAX_VALUE);
This will print true. But why? The float and int primitive types have the same bit depth, but surely there must be some potential loss of precision when storing an int in a float. The float type has the same bit depth, but it must be able to store more values, since it can store decimals as well as the integer part. I wonder if there is any reliable and rational way to distinguish when there is and there is not loss of precision. [ December 24, 2008: Message edited by: Ruben Soto ]
All code in my posts, unless a source is explicitly mentioned, is my own.
Ruben Soto
Ranch Hand
Joined: Dec 16, 2008
Posts: 1032
posted
0
The confusion continues:
Output is: a1 = 2147483647 af = 2.14748365E9 a2 = 2147483647
Ruben Soto
Ranch Hand
Joined: Dec 16, 2008
Posts: 1032
posted
0
I think I know what's happening. When you assign primitives you just copy the bit pattern, and that's why there is no loss of precision doing int to float to int assignments. Could anyone confirm?
Thanks!
Abhi vijay
Ranch Hand
Joined: Sep 16, 2008
Posts: 509
posted
0
I still have not understood why its returning true?
Ruben Soto
Ranch Hand
Joined: Dec 16, 2008
Posts: 1032
posted
0
Hi Abhi,
I think this is the reason why:
A primitive variable is just a bunch of bits with a type associated to it. The type determines the meaning of the bits.
When you assign a primitive variable to other primitive variable, what you do is copy the bits (in the case of float and int, since both are 32 bit entities, that's exactly what happens, without truncation or padding by zero bits to the left, which happens when you assign something that's bigger or smaller to a variable of a different bit-depth type.)
So, the bits remain the same. When you assign the int to the float, the bits remain the same (but the value reported by the float is different, since the meaning of the value for a bit pattern of a float type is different than the meaning of the value for a bit pattern of an int type.) However, when you assign from the float to another int, the bits still are the same as those in the first int, and that's why the value is the same.
I know this is a little confusing, but I hope the explanation helped. [ December 24, 2008: Message edited by: Ruben Soto ]
Abhi vijay
Ranch Hand
Joined: Sep 16, 2008
Posts: 509
posted
0
Thanks..Ruben.
Ruben Soto
Ranch Hand
Joined: Dec 16, 2008
Posts: 1032
posted
0
You're welcome, Abhi. There are so many things to learn...
Abhi vijay
Ranch Hand
Joined: Sep 16, 2008
Posts: 509
posted
0
I agree..Ruben.The questions are so tricky. I just saw a question in one of the posts.
This code will not compile and say possible loss of precession. Why? Because i is assigned a value that is out of the range of short (0-32767). In this case an explicit cast is required. When l is given the value 23L it is of 64-bit which does not fit into an int.
Remember short is a int but the value that can be stored in a short is 0-32767. The value, if increases than 32767 ,it can't be stored in a short as short can store a int between the range 0-32767. It would then require an explicit casting.
See this code. a byte is assigned an int. The range of byte is0-127. The code works fine.
But when the value of j is changed to 128 it requires a casting! Why? Because j contains a value that is bigger than the value that a byte can store.
Hope this explains.
Abhi vijay
Ranch Hand
Joined: Sep 16, 2008
Posts: 509
posted
0
why is this giving error, 32 does fall in the range of int.
Integer literals are 32-bit int values unless they end with the character L or l, in which case they are 64-bit long values:
1234 // An int value 1234L // A long value
But when I try this code
it does not work!
Ruben Soto
Ranch Hand
Joined: Dec 16, 2008
Posts: 1032
posted
0
Automatic narrowing in primitives only works for compile constant values, and it only works from int to smaller values, not for long, float, or double. Also, in order for it to work implicitly the compiler must be able to determine (therefore, this must be determined at compile time) that the value will fit in the variable without loss of information.
Harvinder Thakur
Ranch Hand
Joined: Jun 10, 2008
Posts: 231
posted
0
Added later: (Please refer Khaled Mughal Chapter 3) Implicit narrowing conversions on assignment can occur in cases where all the following conditions are met:
1. the source is a constant expression of either byte, short, char or int type 2. the destination type is either byte, short or char type 3. the value of the source is determined to be in the range of the destination type at compile time.
Added later: Moreover, Bert has clarified below that this topic is not on the 1.5/1.6 exam. Still i've typed this explanation just to share some knowledge [ December 25, 2008: Message edited by: Harvinder Thakur ]
thanks
Harvinder
Bert Bates
author
Sheriff
Joined: Oct 14, 2002
Posts: 8712
posted
0
FWIW -
This topic *might* possibly be found on the 1.4 exam, but it won't be found on the 1.5 or 6 exam.
ho ho ho,
Bert
Eliminate fossil fuel subsidies. (If you're not on the edge, you're taking up too much room.)
As being an aspirant of SCJP myself I know that the topic is not in 1.5 exam. But just being in the forum of SCJP does not mean it cannot be discussed... Only the forum is wrong.
Any ways Happy New Year to all of you..Have a nice and safe celebration .
awad saleh
Greenhorn
Joined: Jul 04, 2007
Posts: 22
posted
0
I really Thanks allot Harvinder Thakur AND sudipto shekhar and all others....... [ December 26, 2008: Message edited by: awad saleh ]
meera kanekal
Ranch Hand
Joined: Feb 13, 2005
Posts: 75
posted
0
Hi, Contrary to some of the inputs given in this discussion the following program compiled and gave the following output: This is my own code public class Casting {
public static void main(String[] args) { byte b = 5; byte c = 3; //byte d = b+c; byte d = (byte) (b + c); System.out.println("Casting is necessary even when you add 2 bytes "+d);
int i = 127; //byte e = i; byte e = (byte)i; System.out.println("Casting is necessary for Narrowing conversions of int to byte "+e);
int j = 128; byte f = (byte) j; System.out.println("byte capacity is smaller "+f);
int k = 32700; short s = (short)k; System.out.println("Narrowing conversion of int to short requires casting "+s); final int m = 32700; short sh = m; System.out.println("Narrowing conversion of int to short requires NO casting because int is final and a " + "compile time constant "+sh);
int a1 = Integer.MAX_VALUE; float af = a1; int a2 = (int) af; System.out.println("int-float-int conversion a1 = " + a1 + " af = " + af + " a2 = " + a2);
long l1 = 32l; // int n = l1; int n = (int)l1; System.out.println("long to int narrowing conversion "+n);
final long l2 = 1000L; int p = (int)l2; System.out.println("long to int narrowing conversion:" + " long does not have to be final "+p);
long l3 = 130l; byte g = (byte)l3; System.out.println(" long to byte narrowing conversion. byte capacity is smaller "+g); }
}
Casting is necessary even when you add 2 bytes 8 Casting is necessary for Narrowing conversions of int to byte 127 byte capacity is smaller -128 Narrowing conversion of int to short requires casting 32700 Narrowing conversion of int to short requires NO casting because int is final and a compile time constant 32700 int-float-int conversion a1 = 2147483647 af = 2.14748365E9 a2 = 2147483647 long to int narrowing conversion 32 long to int narrowing conversion: long does not have to be final 1000 long to byte narrowing conversion. byte capacity is smaller -126
Thanks, Meera
Ruben Soto
Ranch Hand
Joined: Dec 16, 2008
Posts: 1032
posted
0
I know that, as Bert mentioned, this is not on the exam, but I would like to correct a mistake.
My theory was that when you assign an int to a float, then back to an int, the bit pattern remained unchanged, because that's what seemed to be the case.
After further testing, that appears not to be the case. The Integer.MAX_VALUE "lossless" roundtrip conversion seems to be a fluke, and not the norm. Run the following code and you will understand:
I agree. Here's the link: http://ej-technologies/jprofiler - if it wasn't for jprofiler, we would need to
run our stuff on 16 servers instead of 3.
subject: int -> float -> int and loss of precision