• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Liutauras Vilda
  • Junilu Lacar
Sheriffs:
  • Tim Cooke
  • Jeanne Boyarsky
  • Knute Snortum
Saloon Keepers:
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:
  • salvin francis
  • fred rosenberger
  • Frits Walraven

JAVA casting bug ? Maybe!

 
Ranch Hand
Posts: 117
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello folks,
The following snippet gives two different answers and I don't quite know how to explain it. Please help. Thanks in advance.
------------------------------------------------------------
double d = Double.MAX_VALUE;
long L = (long) d;
int I1 = (int) d;
int I2 = (int) L;
While I1 is a positive value, I2 is -1. Any explanation?
Not over yet
short S1 = (short) d;
short S2 = (short) L;
Both S1 and S2 yield -1. What causes the difference between an int and a short casting?

Regards,
Lam

 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This (admittedly strange) behavior is described in the JLS here.
 
Lam Thai
Ranch Hand
Posts: 117
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Jim Yingst:
This (admittedly strange) behavior is described in the JLS here.


Hi Jim,
Thanks - the document shows exactly what I found. But do you know the logic behind it? Any explanation from Java language designer(s)?
Regards,
Lam
 
author
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Lam Thai:
But do you know the logic behind it?


The logic is contained in the following phrases from the JLS section 5.1.3 quoted above:
About conversion from a floating point number: "A narrowing conversion of a floating-point number [... if the value is too large] the result of the first step is the largest representable value of type int or long. In the second step: [...] If T is byte, char, or short, the result of the conversion is the result of a narrowing conversion" (my emphasis)
About conversions between integral types (long, int, short): "A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits [...]".
The difference between int casting and short casting is that a double can be directly cast to an int, but the casting to a short is a two step process which uses an integer narrowing conversion.
Line by line, this means:
long L = (long) d;
Since Double.MAX_VALUE cannot be represented in a long, the JLS dictates that the "largest representable value" is stored in L. Its bit pattern is a 0 (positive sign) followed by sixty-three 1s.
int I1 = (int) d;
Again a conversion from a floating point number. The bit pattern for the largest positive number representable in an int is a 0 followed by thirty-one 1s.
int I2 = (int) L;
This is a conversion between integral types and simply discards the thirty-two highest order bits of L. What remains are thirty-two 1s, which is the bit pattern of the number -1.
short S1 = (short) d;
Again converting from a float. But now there is a two-step conversion process: first, the double is converted to an int (giving a 0 with thirty-one 1s); then, the int is narrowed to a short (only the sixteen lowest order 1s remain, which gives -1).
short S2 = (short) L;
Again this simply discards the highest order bits.
Hope this clears things up.
- Peter

[This message has been edited by Peter den Haan (edited May 01, 2001).]
 
Lam Thai
Ranch Hand
Posts: 117
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Peter,
Thanks for your methodical explanation. In reading the document, I understood the 'algorithm'. However, it could be due to my unclear question by using the word 'logic' that I did not convey what I am looking for.
I like to find out why the Java language design team chose to be inconsistent unless there is a good reason for it. That what I like to find out, "the good reason."
For instant to be specific, in the "two-step conversion process", why did they decide to errect the 32-bit barrier by treating long and int differently from the others? Why not just one step for all such as "The conversion from huge double to all T types will be the largest signed value of their types?" What could be more wrong by doing so?...

Best regards,
Lam Thai
 
Peter den Haan
author
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I see. Sorry for misjudging the intent of your question.
Regarding the justification, note that int is treated as the "baseline integer type" in other places in the language. All integer operations, including arithmetic operators, return either a long (if any of the operands is long) or an int (JLS 4.2.2). The thought behind it appears to be that you would generally not use anything smaller than int for numerical calculations, and if you do, you should be made very much aware of the fact by forcing you to plaster casts all over the place.
It might have been more consistent to define the cast-to-integer-type operator to return either a long or an int like all the others, and to make you do step 2 (in JLS 5.1.3) explicitly:
short S1 = (short)(int)d;
But that would look a bit odd, wouldn't it?
That's my best guess anyway.
- Peter

[This message has been edited by Peter den Haan (edited May 01, 2001).]
 
Drove my Chevy to the levee but the levee was dry. A wrung this tiny ad and it was still dry.
Two software engineers solve most of the world's problems in one K&R sized book
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
    Bookmark Topic Watch Topic
  • New Topic