我正试图在Java中进行一些舍入。我把它发送到Fiscal打印机,它已经定义了一些舍入参数。
有一个数字定义小数位数...例如 x = 0.0100 ; 第二个数字是舍入的一些系数。例如 y = 0.0050 ;所有大于 0.0050 应四舍五入至 0.01 且所有小于 0.0050 应四舍五入至 0.00 。 BigDecimal不是解决方案,因为这个数字定义了舍入模式。
在打印机的文档中,我有一些表格包含舍入数字的例子......
我试图解决这个问题几个小时,我找不到解决方案。这是我当前的代码...处理带有数字x的小数点。
Math.round(value / x) * x;
我应该如何添加数字“y”...我尝试了一些解决方案,但我仍然会对某些变量组合得到错误的值。
我也检查了这一点,但它没有正常工作...... How to customize the form of rounding
答案 0 :(得分:1)
这匹配除x = 0.0100; y = 0.0100
之外的所有示例,其中15.2241 = 15.22; 15.0009 = 15.00
而不是15.23
。根据描述,这应该是正确的结果。
static BigDecimal round(BigDecimal val, BigDecimal x, BigDecimal y) {
BigDecimal remainder = val.remainder(x);
BigDecimal base = val.subtract(remainder);
return remainder.compareTo(y) < 0 ? base : base.add(x);
}
(编辑:已更新以处理x = 0.0200
示例)
这是我能得到的尽可能接近,但没有解释为什么第三个例子不一致。仅为该示例添加特殊情况代码可能无法准确反映其背后的规则,并且可能会为类似值提供不正确的结果。
另请注意,在处理资金时,绝不应使用浮点(浮点数/双数)值,不准确可能会迅速增加。 BigDecimal
个实例应直接从String
的值创建,并且应使用String
将其转换回DecimalFormat
。
答案 1 :(得分:0)
我做了这样的功能...值似乎没问题,但仍有一个错误... x = 0.0100; y = 0.0100; 15.0009 = 15.01 应该 15.00
由@SeanVanGorder创建的代码不是很好,因为如果x = 0.0200 ... value是错误的。我的函数使 x = 0.0200; y = 0.0030; 15.2241 = 15.24 ,它应该是这样的...四舍五入到第一个 2 。
返回类型是double,因为我没有设法使用BigDecimal将变量x依赖于变量x。我将仅使用返回值写入打印机,因此浮点数不应该有问题,但如果有人知道解决方案,请随意发布。这可能是我做的最好的解决方案,但它仍然不是100%罚款。
更新:我更新了代码...现在它完全使用BigDecimal,它可能是解决此问题的最佳解决方案。我给打印机制造商写了一封电子邮件,我得到了一些与程序员手册中的描述相冲突的回复。所以,这不是100%精细的解决方案,而且一个值仍然是错误的value = 15.0009; x = 0.0100; y = 0.0100;
应该是15.00
(手动),但制造商写了15.01
,我的代码返回15.01
。< / p>
static BigDecimal roundVaros(BigDecimal value, BigDecimal x, BigDecimal y) {
BigDecimal a = value.divide(x, RoundingMode.HALF_UP);
BigDecimal b = y.divide(x, RoundingMode.HALF_UP);
a = a.subtract(BigDecimal.valueOf(a.longValue()));
b = b.subtract(BigDecimal.valueOf(b.longValue()));
if (a.compareTo(b) >= 0) {
return value.divide(x, RoundingMode.HALF_UP).setScale(0, RoundingMode.CEILING).multiply(x);
} else {
return value.divide(x, RoundingMode.HALF_UP).setScale(0, RoundingMode.FLOOR).multiply(x);
}
}
感谢@SeanVanGoder(他的代码也帮助了我)
答案 2 :(得分:-1)
尝试将此数字添加0.0050。逻辑是,如果它小于0.50则保持小于1,当切断其余时它会自动变为0.如果大于1将如此,因此当切断时将保持为1。