我正在尝试将一些AS400
/ RPG
代码转换为Java
。
我能够在网上找到一个example,该代码与我在代码中看到的内容完全相同:
d elevensix s 11 6 inz(26285.88991)
d seventwo s 7 2
c eval(h) seventwo = elevensix
c eval *inlr = *on
我已经在Java
中编写了代码,但发现在RPG
代码中看到的舍入结果与我在Java
中看到的舍入类型不匹配。这是我在Java
中进行的四舍五入的示例:
private Long roundAmount(Double amount) {
return Math.round(amount);
}
在实践中,我的代码生成的结果与RPG
代码的结果相匹配,但是我发现了逻辑上不一致的示例。有些会按预期四舍五入,而有些则不会。
我在Java方面做了大量工作;这是我对RPG
的首次尝试。老实说,我什至不知道从哪里开始。例如,在上面的RPG
代码中;它是如何工作的?我看到了将运算结果放入标有2个小数位的变量中的情况;舍入是隐式的吗?在在线find the following definition中搜索Java如何处理舍入:
Java中的Math.round()方法用于将数字四舍五入到 最接近的整数。这是通过将数字加1/2来完成的, 取下结果,并将结果转换为整数 数据类型。
老实说,这是简洁明了的。在RPG
中,我没有找到类似的解释。需要明确的是,这是在使用RPG
的AS400上进行编程的,但是比我认为当前标准的版本要旧得多。但是,即使是对于现代的实现方法,也只能作为一个解释。
答案 0 :(得分:6)
您发布的RPG代码与Java代码的作用不同。
Java代码将Double
转换为Long
,而RPG代码将一个带有十进制小数的数字舍入为带有两个十进制小数的数字。
特别地,elevensix
是一个11位数字,其中6位为小数部分,其中5位为整数部分; seventwo
是一个由7位数字组成的数字,其中2位代表小数,5位代表整数。
eval(h)
正在将elevensix
的值复制到seventwo
中,并使用“ half-adjust”逻辑将其四舍五入为两位小数(这就是“ h”的意思,没有它小数点将被截断)。
在RPG documentation(您也可以在PDF format中找到)中,尤其是在here中:
通过将5(如果该字段为负,则为-5)加1来进行半调整 最后指定的小数位右边的位置 结果字段。
对我来说,这似乎与Math.round
相似,但是可以推广到任何小数位。
而且它也将对应于Java Math RoundingMode.HALF_UP。
由于您没有提供一些实际的示例来产生不一致,因此很难为您提供确定的解决方案。
无论如何,可以使用setScale
方法使用BigDecimals复制Java中的RPG代码,如下所示:
double result = new BigDecimal(amount.toString())
.setScale(2, RoundingMode.HALF_UP)
.doubleValue();
您还可以考虑使用Apache Commons Math方法round
,该方法在实现方面几乎相同。
您的问题也可能是由于Double的精度有限所致,在这种情况下,您应该只使用BigDecimals,请参见Double vs. BigDecimal?。