AS400/RPG 中的舍入与 Java 中的舍入
Rounding in AS400/RPG vs Rounding in Java
我正在尝试将一些 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
代码中看到的舍入结果与我在 [=16] 中看到的舍入类型不匹配=].这是我在 Java
:
中进行的舍入示例
private Long roundAmount(Double amount) {
return Math.round(amount);
}
在实践中,我的代码生成的结果与 RPG
代码的结果相匹配,但是我发现在逻辑上不一致的示例;有些像预期的那样四舍五入,有些则没有。
我曾与 Java 一起工作过;这是我第一次涉足 RPG
。老实说,我什至不知道从哪里开始。例如上面的RPG
代码;它究竟是如何工作的?我看到操作的结果被放入一个标有 2 位小数的变量中;舍入是隐式的吗?我 find the following definition 在线搜索 Java 如何处理舍入:
The Math.round() method in Java is used to round a number to its
closest integer. This is done by adding 1/2 to the number,
taking the floor of the result, and casting the result to an integer
data type.
老实说,这很简洁明了。我还没有在 RPG
中找到关于它如何工作的类似解释;需要明确的是,这是在使用 RPG
的 AS400 上编程,但比我认为当前标准的版本要旧得多。然而,即使是对现代实施的解释也将是一个开始。
您发布的 RPG 代码与您的 Java 代码不同。
Java 代码将 Double
转换为 Long
,而 RPG 代码将 6 位小数舍入为 2 位小数。
其中,elevensix
是一个11位数字,其中6位小数部分,5位整数部分; seventwo
是一个7位数字,其中2位小数部分,5位整数部分。
eval(h)
将 elevensix
的值复制到 seventwo
并使用“half-adjust”逻辑将其四舍五入为 2 个十进制数字(这就是“h”的含义因为,没有它,小数点将被截断)。
来自RPG documentation (that you can find also in PDF format) and in particular here:
Half-adjusting is done by adding 5 (-5 if the field is negative) one
position to the right of the last specified decimal position in the
result field.
这对我来说似乎类似于 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?。
我正在尝试将一些 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
代码中看到的舍入结果与我在 [=16] 中看到的舍入类型不匹配=].这是我在 Java
:
private Long roundAmount(Double amount) {
return Math.round(amount);
}
在实践中,我的代码生成的结果与 RPG
代码的结果相匹配,但是我发现在逻辑上不一致的示例;有些像预期的那样四舍五入,有些则没有。
我曾与 Java 一起工作过;这是我第一次涉足 RPG
。老实说,我什至不知道从哪里开始。例如上面的RPG
代码;它究竟是如何工作的?我看到操作的结果被放入一个标有 2 位小数的变量中;舍入是隐式的吗?我 find the following definition 在线搜索 Java 如何处理舍入:
The Math.round() method in Java is used to round a number to its closest integer. This is done by adding 1/2 to the number, taking the floor of the result, and casting the result to an integer data type.
老实说,这很简洁明了。我还没有在 RPG
中找到关于它如何工作的类似解释;需要明确的是,这是在使用 RPG
的 AS400 上编程,但比我认为当前标准的版本要旧得多。然而,即使是对现代实施的解释也将是一个开始。
您发布的 RPG 代码与您的 Java 代码不同。
Java 代码将 Double
转换为 Long
,而 RPG 代码将 6 位小数舍入为 2 位小数。
其中,elevensix
是一个11位数字,其中6位小数部分,5位整数部分; seventwo
是一个7位数字,其中2位小数部分,5位整数部分。
eval(h)
将 elevensix
的值复制到 seventwo
并使用“half-adjust”逻辑将其四舍五入为 2 个十进制数字(这就是“h”的含义因为,没有它,小数点将被截断)。
来自RPG documentation (that you can find also in PDF format) and in particular here:
Half-adjusting is done by adding 5 (-5 if the field is negative) one position to the right of the last specified decimal position in the result field.
这对我来说似乎类似于 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?。