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

Ged*_*lya 2 java rpg ibm-midrange

我正在尝试将一些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
Run Code Online (Sandbox Code Playgroud)

我已经编写了代码,Java我发现我在RPG代码中看到的舍入结果与我在Java. 这是我正在做的舍入示例Java

private Long roundAmount(Double amount) {
        return Math.round(amount);
}
Run Code Online (Sandbox Code Playgroud)

在实践中,我的代码生成的结果与代码的结果相匹配,RPG但是我发现了逻辑不一致的示例;有些按预期四舍五入,而另一些则没有。

我曾大量使用 Java;这是我第一次涉足RPG。老实说,我什至不确定从哪里开始。例如,在RPG上面的代码中;它究竟是如何工作的?我看到操作的结果被放入一个标有 2 个小数位的变量中;四舍五入是隐含的吗?在线搜索我发现以下关于 Java 如何处理舍入的定义

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

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

Lor*_*uro 6

您发布的 RPG 代码与 Java 代码的作用不同。

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

尤其elevensix是11位数字,其中6位为小数部分,5位为整数部分;seventwo是一个7位数字,其中2位是小数部分,5位是整数部分。

eval(h)被复制的价值elevensixseventwo,并将其与“半调”逻辑四舍五入至小数点后2个位数(这是什么“H”代表,如果没有它,小数将被截断)。

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

半调整是通过在结果字段中最后一个指定的小数位右侧添加 5(如果字段为负则为 -5)一个位置来完成的。

这对我来说似乎类似于什么Math.round,但可以概括为任何小数位。它也对应于 Java Math RoundingMode.HALF_UP

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

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

double result = new BigDecimal(amount.toString())
        .setScale(2, RoundingMode.HALF_UP)
        .doubleValue();
Run Code Online (Sandbox Code Playgroud)

您可能还考虑使用 Apache Commons Math 方法round,从实现来看,它几乎可以完成相同的事情。

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