<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:"Segoe UI";
panose-1:2 11 5 2 4 2 4 2 2 3;}
@font-face
{font-family:Menlo;
panose-1:2 11 6 9 3 8 4 2 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:#0563C1;
text-decoration:underline;}
code
{mso-style-priority:99;
font-family:"Courier New";}
p.xmsonormal, li.xmsonormal, div.xmsonormal
{mso-style-name:x_msonormal;
margin:0in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
p.xp1, li.xp1, div.xp1
{mso-style-name:x_p1;
margin:0in;
font-size:8.5pt;
font-family:Menlo;
color:black;}
span.xs1
{mso-style-name:x_s1;}
span.EmailStyle27
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;
mso-ligatures:none;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Thanks for clarifying, Angelos! That helps.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div id="mail-editor-reference-message-container">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">Angelos Bimpoudis <angelos.bimpoudis@oracle.com><br>
<b>Date: </b>Thursday, October 19, 2023 at 4:41 PM<br>
<b>To: </b>Ella Ananeva <ella.ananeva@oracle.com>, amber-dev@openjdk.org <amber-dev@openjdk.org><br>
<b>Subject: </b>Re: Float to byte and back in switch<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">That section defines the runtime semantics of switch label selection indeed.
<o:p></o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">What is also important is the kind of types that can be "allowed" to reach this point. The permitted case constant associations are shown in 14.11.1 Switch Blocks where we split
(add) the new kinds of constants separately. <o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">if T is one of char, byte, short, int, Character, Byte, Short, Integer, or String, the constant is assignment compatible with T.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">if T is one of long, float, double, boolean, Long, Float, Double, Boolean, the constant is the same type:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">with T if T is a primitive type, or<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">with T' where T' is T after unboxing conversion, otherwise.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">That second bullet essentially says that a selector of a float type can match only float constant labels and so on and so forth.
<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">While comparing y to 1 (the integer one) is crystal clear, there are other occasions that this is not. Consider this:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">jshell> float f = 16777216 // 224 and that can be represented exactly into a float<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">f ==> 1.6777216E7<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">jshell> f == 16777217 // 224+1 that cannot be represented exactly because the bits of the mantissa do not suffice, so the RHS constant maps also to 1.6777216E7<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">$7 ==> true<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">As result the following switch is not permitted:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"> void test(float f) {<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"> switch (f) {<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"> case 16777216:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"> break;<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"> case 16777217:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"> break;<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"> default:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"> break;<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"> }<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"> }<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black"><o:p> </o:p></span></p>
</div>
<p class="MsoNormal"><span style="font-family:"Segoe UI",sans-serif;color:black">both labels map to the same float while the two labels are clearly, representationally different (among them). That would lead to great confusion.<o:p></o:p></span></p>
</div>
<div class="MsoNormal" align="center" style="text-align:center">
<hr size="0" width="100%" align="center">
</div>
<div id="divRplyFwdMsg">
<p class="MsoNormal"><b><span style="color:black">From:</span></b><span style="color:black"> amber-dev <amber-dev-retn@openjdk.org> on behalf of Ella Ananeva <ella.ananeva@oracle.com><br>
<b>Sent:</b> 19 October 2023 19:01<br>
<b>To:</b> amber-dev@openjdk.org <amber-dev@openjdk.org><br>
<b>Subject:</b> Float to byte and back in switch</span> <o:p></o:p></p>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
</div>
<div>
<div>
<p>Hi team,<o:p></o:p></p>
<p>When we match labels in switch with primitive types, the spec defines the behavior for integral types and for floating-point types.
<o:p></o:p></p>
<p><span style="font-family:Symbol">·</span> <strong><span style="font-family:"Calibri",sans-serif">If
</span></strong><em><b><span style="font-family:"Calibri",sans-serif">T</span></b></em><strong><span style="font-family:"Calibri",sans-serif"> is a primitive type, then a</span></strong>
<code><span style="font-size:10.0pt">case</span></code> label with a <code><span style="font-size:10.0pt">case</span></code> constant
<em><span style="font-family:"Calibri",sans-serif">c</span></em> applies to a value that is of type
<code><span style="font-size:10.0pt">char</span></code>, <code><span style="font-size:10.0pt">byte</span></code>,
<code><span style="font-size:10.0pt">short</span></code>, <code><span style="font-size:10.0pt">int</span></code>,
<code><b><span style="font-size:10.0pt">long</span></b></code><strong><span style="font-family:"Calibri",sans-serif">,
</span></strong><code><b><span style="font-size:10.0pt">float</span></b></code><strong><span style="font-family:"Calibri",sans-serif">,
</span></strong><code><b><span style="font-size:10.0pt">double</span></b></code><strong><span style="font-family:"Calibri",sans-serif">,
</span></strong><code><b><span style="font-size:10.0pt">boolean</span></b></code><strong><span style="font-family:"Calibri",sans-serif">,</span></strong>
<code><span style="font-size:10.0pt">String</span></code> or an enum type if the constant
<em><span style="font-family:"Calibri",sans-serif">c</span></em> is equal to the value.<o:p></o:p></p>
<p>Equality is defined in terms of the <code><span style="font-size:10.0pt">==</span></code> operator
<strong><span style="font-family:"Calibri",sans-serif">(<a href="https://docs.oracle.com/javase/specs/jls/se21/html/jls-15.html#jls-15.21">15.21</a>) for the integral types and the boolean type, and in terms of representation equivalence (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Double.html#repEquivalence">java.lang.Double</a>)
for the floating-point types.</span></strong> <strong><span style="font-family:"Calibri",sans-serif">If</span></strong> the value is a
<code><span style="font-size:10.0pt">String</span></code>, equality is defined in terms of the
<code><span style="font-size:10.0pt">equals</span></code> method of class <code><span style="font-size:10.0pt">String</span></code>.<o:p></o:p></p>
<p> <o:p></o:p></p>
<p>What should be the behavior, though, when we try to match an integral type to a floating-point type?<o:p></o:p></p>
<p>e.g., In this scenario:<o:p></o:p></p>
<p class="xp1"><span style="font-size:10.0pt;font-family:"Courier New";color:#0033B3">private static void
</span><span style="font-size:10.0pt;font-family:"Courier New";color:#00627A">testSwitch</span><span style="font-size:10.0pt;font-family:"Courier New";color:#080808">(</span><span style="font-size:10.0pt;font-family:"Courier New";color:#0033B3">float
</span><span style="font-size:10.0pt;font-family:"Courier New";color:#080808">y) {<br>
</span><span style="font-size:10.0pt;font-family:"Courier New"">System</span><span style="font-size:10.0pt;font-family:"Courier New";color:#080808">.</span><i><span style="font-size:10.0pt;font-family:"Courier New";color:#871094">out</span></i><span style="font-size:10.0pt;font-family:"Courier New";color:#080808">.println(y
== </span><span style="font-size:10.0pt;font-family:"Courier New";color:#1750EB">1</span><span style="font-size:10.0pt;font-family:"Courier New";color:#080808">); //prints true<br>
</span><span style="font-size:10.0pt;font-family:"Courier New";color:#0033B3">switch
</span><span style="font-size:10.0pt;font-family:"Courier New";color:#080808">(y) {<br>
</span><span style="font-size:10.0pt;font-family:"Courier New";color:#0033B3">case
</span><span style="font-size:10.0pt;font-family:"Courier New";color:#1750EB">1 </span>
<span style="font-size:10.0pt;font-family:"Courier New";color:#080808">-> { </span>
<span style="font-size:10.0pt;font-family:"Courier New"">System</span><span style="font-size:10.0pt;font-family:"Courier New";color:#080808">.</span><i><span style="font-size:10.0pt;font-family:"Courier New";color:#871094">out</span></i><span style="font-size:10.0pt;font-family:"Courier New";color:#080808">.println(y
== </span><span style="font-size:10.0pt;font-family:"Courier New";color:#1750EB">1</span><span style="font-size:10.0pt;font-family:"Courier New";color:#080808">);}//throws a compile-time error:
</span><span class="xs1">constant label of type int is not compatible with switch selector type float</span><o:p></o:p></p>
<p class="xmsonormal" style="background:white"><span style="font-size:10.0pt;font-family:"Courier New";color:#080808"><br>
</span><span style="font-size:10.0pt;font-family:"Courier New";color:#0033B3">default
</span><span style="font-size:10.0pt;font-family:"Courier New";color:#080808">-> { }<br>
}<br>
}</span><o:p></o:p></p>
<p class="xmsonormal"> <o:p></o:p></p>
<p class="xmsonormal">I would expect the compiler to be able to handle this situation: since int can be converted to float and the equality operator returns true, the label should be chosen.<o:p></o:p></p>
<p class="xmsonormal"> <o:p></o:p></p>
<p class="xmsonormal">The opposite situation with narrowing conversion, when we try to convert float to int may be trickier, but shouldn’t it also be accepted?<o:p></o:p></p>
<p class="xmsonormal"> <o:p></o:p></p>
<p class="xmsonormal">Thank you,<o:p></o:p></p>
<p class="xmsonormal">Ella Ananeva<o:p></o:p></p>
<p class="xmsonormal"> <o:p></o:p></p>
<p class="xmsonormal"> <o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>