[ 
https://issues.apache.org/jira/browse/GROOVY-9094?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16831064#comment-16831064
 ] 

Eric Milles edited comment on GROOVY-9094 at 5/1/19 3:33 PM:
-------------------------------------------------------------

See also GROOVY-9011 and GROOVY-8948


was (Author: emilles):
See also GROOVY-9011

> Coercion to primitive double from primitive integer produces different 
> results in dynamic and static compilation
> ----------------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-9094
>                 URL: https://issues.apache.org/jira/browse/GROOVY-9094
>             Project: Groovy
>          Issue Type: Bug
>          Components: bytecode, Compiler
>    Affects Versions: 3.0.0-alpha-4, 2.5.6
>            Reporter: Szymon Stępniak
>            Priority: Major
>
> Ticket created based on the following question on Stack Overflow - 
> https://stackoverflow.com/questions/55789411/groovy-primitive-double-arithmetic
> It seems like primitive double coercion is unstable. Consider the following 
> example:
> {code:groovy}
> void ex1() {
>     double x = 255 / 2
>     println x
> }
> void ex2() {
>     Double x = 255 / 2
>     println x
> }
> void ex3() {
>     def x = 255 / 2
>     println x
> }
> void ex4() {
>     println 255 / 2
> }
> ex1()
> ex2()
> ex3()
> ex4()
> {code}
> It produces the following output:
> {code:bash}
> 127.0
> 127.5
> 127.5
> 127.5
> {code}
> I checked the generated bytecode and here is what the {{ex1}} method 
> implementation looks like:
> {code:java}
>     public void ex1() {
>         CallSite[] var1 = $getCallSiteArray();
>         double x = 0.0D;
>         if (BytecodeInterface8.isOrigInt() && BytecodeInterface8.isOrigD() && 
> !__$stMC && !BytecodeInterface8.disabledStandardMetaClass()) {
>             int var5 = 255 / 2;
>             x = (double)var5;
>         } else {
>             Object var4 = var1[5].call(255, 2);
>             x = DefaultTypeTransformation.doubleUnbox(var4);
>         }
>         var1[6].callCurrent(this, x);
>     }
> {code}
> And here is what {{ex2}} method's bytecode looks like:
> {code:java}
>     public void ex2() {
>         CallSite[] var1 = $getCallSiteArray();
>         Double x = null;
>         if (BytecodeInterface8.isOrigInt() && !__$stMC && 
> !BytecodeInterface8.disabledStandardMetaClass()) {
>             Object var4 = var1[8].call(255, 2);
>             x = (Double)ScriptBytecodeAdapter.castToType(var4, Double.class);
>         } else {
>             Object var3 = var1[7].call(255, 2);
>             x = (Double)ScriptBytecodeAdapter.castToType(var3, Double.class);
>         }
>         var1[9].callCurrent(this, x);
>     }
> {code}
> If we compile statically the first method, it will produce {{127.5}} output, 
> and will generate the following bytecode:
> {code:java}
>     public void ex1() {
>         double x = 
> DefaultTypeTransformation.doubleUnbox(NumberNumberDiv.div(255, 2));
>         ((qweqwe23)this).println(x);
>         Object var10000 = null;
>     }
> {code}
> But the weirdest thing happens if we try to use type checking. My first 
> impression was that this unstable coercion could be avoided if we use type 
> checking. However, it doesn't work. If I add {{@TypeChecked}} annotation to 
> {{ex1}} method, it does not make any effect - the code runs and it still 
> produces {{127.0}} output. But when I add {{@TypeChecked}} to {{ex2}} method, 
> it does not run and produces the following compilation error.
> {code:bash}
> Error:(10, 20) Groovyc: [Static type checking] - Cannot assign value of type 
> java.math.BigDecimal to variable of type java.lang.Double
> {code}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to