Groovy开启/关闭Invoke Dynamic时除法运算结果不一致问题咨询
Groovy开启/关闭Invoke Dynamic时除法结果不一致的问题解决
问题原因
关闭Invoke Dynamic(简称Indy)时,Groovy编译器触发了字节码优化逻辑:检测到3/2的两个操作数都是原始int类型,直接执行Java风格的整数除法,得到结果1后再转为double,最终输出1.0。
开启Indy后,除法操作通过invokedynamic调用Groovy的动态运算符处理逻辑,Groovy会自动将整数操作数提升为浮点类型进行计算,3/2得到1.5,转double后输出1.5。两种编译模式的运算逻辑差异导致了结果不一致。
解决方案
要让两种模式下结果统一,有两种明确的处理方式:
方式一:统一执行浮点除法
把其中一个操作数改成浮点类型,确保无论编译模式如何,都触发浮点除法:
static void main(String[] args) { double a = 3.0 / 2 // 或者写成 3 / 2.0 println a }
修改后两种模式都会输出1.5。
方式二:强制执行整数除法
如果业务逻辑需要整数除法的结果,显式通过类型转换或Groovy内置方法指定:
static void main(String[] args) { // 方式1:强制整数除法后转double double a = (int)(3 / 2) // 方式2:使用Groovy的intdiv方法做整数除法 // double a = 3.intdiv(2) println a }
修改后两种模式都会输出1.0。
补充提示
Groovy关闭Indy时的优化是为了兼容旧版本的性能表现,而开启Indy后更符合动态语言的运算符处理逻辑。为避免这类差异,建议在数值运算时,要么显式指定操作数类型,要么使用Groovy提供的intdiv(整数除法)、div(浮点除法)方法来明确运算类型。
内容的提问来源于stack exchange,提问作者lucky dog
相关产品推荐
相关产品推荐

