AS400/RPG 中的舍入与 Java 中的舍入



我正在尝试将一些AS400/RPG代码转换为Java

我能够在网上找到一个镜像我在代码中看到的示例:

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 位小数的变量中;舍入是隐式的吗?在线搜索时,我发现 Java 如何处理舍入的以下定义:

Java 中的 Math.round() 方法用于将数字四舍五入为其 最接近的整数。这是通过在数字上加 1/2 来完成的, 获取结果的发言权,并将结果转换为整数 数据类型。

老实说,这是清晰简洁的。我还没有找到关于它在RPG中如何工作的类似解释;需要明确的是,这是在使用RPG的AS400上进行编程,但比我认为的当前标准要旧得多。然而,即使是对现代实现的解释也将是一个开始。

你发布的RPG代码与你的Java代码不同。

Java代码将Double转换为Long,而RPG代码是将小数点后6位的数字四舍五入为小数点后2位的数字。

特别是,elevensix是一个有 11 位数字的数字,其中 6 位用于小数部分,5 位用于整数部分;seventwo是一个有 7 位数字的数字,其中 2 位用于小数部分,5 位用于整数部分。

eval(h)elevensix的值复制到seventwo,并使用"半调整"逻辑将其四舍五入为 2 位十进制数字(这就是"h"代表的,没有它,小数将被截断)。

从 RPG 文档(您也可以找到 PDF 格式)中,特别是在这里:

半调整是通过添加 5(如果字段为负值,则为 -5)1 来完成的 位置位于 结果字段。

在我看来,这似乎与Math.round所做的相似,但推广到任何小数位。 此外,它还对应于Java Math RoundingMode.HALF_UP。

由于您没有提供一些产生不连贯性的实际示例,因此很难为您提供明确的解决方案。

无论如何,Java 中的 RPG 代码可以使用 BigDecimals 复制,方法setScale如下:

double result = new BigDecimal(amount.toString())
.setScale(2, RoundingMode.HALF_UP)
.doubleValue();

你也可以考虑使用Apache Commons Math方法round从实现来看,它做几乎同样的事情。

您的问题也可能是由 Double 的有限精度引起的,在这种情况下,您应该只使用 BigDecimals,请参阅Double vs. BigDecimal?。

相关内容

  • 没有找到相关文章

最新更新