mathcontext保留2位小数_java.math.MathContex的使用

本文围绕java.math.MathContext的用法展开,作者起初未能正确理解其用途,怀疑是否用于ANSI标准中的舍入。文中给出了5个解决方案,介绍了BigDecimal.setScale方法,还通过多个示例说明了MathContext中精度和舍入模式对输出的影响,强调其指定的是总有效位数而非小数点后位数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java.math.MathContex的使用

最近,我尝试了解java.math.MathContext的用法,但未能正确理解。 是否将其用于ANSI X3.274-1996中的舍入。如果是,为什么不舍入小数点后甚至尾数部分。

从API文档中,我知道它遵循ANSI X3.274-1996和ANSI X3.274-1996/AM 1-2000规范中指定的标准,但是我没有让他们在线阅读。

如果您对此有任何想法,请告诉我。

5个解决方案

64 votes

要仅舍入BigDecimal的小数部分,请查看BigDecimal.setScale(int newScale, int roundingMode)方法。

例如。 将小数点后三位数的数字更改为两位数的数字,并四舍五入:

BigDecimal original = new BigDecimal("1.235");

BigDecimal scaled = original.setScale(2, BigDecimal.ROUND_HALF_UP);

结果是一个BigDecimal,其值为1.24(由于四舍五入规则)

hacklife productions answered 2020-02-15T06:47:13Z

44 votes

@贾坦

感谢您的回答。 这说得通。 您能否在BigDecimal#round方法的上下文中向我解释MathContext。

RoundingMode与其他123方法没有什么特别的。 在所有情况下,RoundingMode指定有效数字的数量和舍入技术。 基本上,每个RoundingMode有两个部分。有一个精度,还有一个RoundingMode。

精度再次指定有效位数。 因此,如果您将RoundingMode指定为一个数字,并要求输入2个有效数字,您将获得123129。

RoundingMode用科学计数法将是123。 如果仅保留2个有效数字,则得到RoundingMode或27483002850419681968131。通过减少有效数字的位数,我们降低了指定数字的精度。

RoundingMode部分指定了如何处理精度损失。 要重用该示例,如果您使用123作为数字,并要求输入2个有效数字,则会降低精度。 在RoundingMode为HALF_UP(默认模式)的情况下,123将变为120。在RoundingMode为CEILING的情况下,您将获得130。

例如:

System.out.println(new BigDecimal("123.4",

new MathContext(4,RoundingMode.HALF_UP)));

System.out.println(new BigDecimal("123.4",

new MathContext(2,RoundingMode.HALF_UP)));

System.out.println(new BigDecimal("123.4",

new MathContext(2,RoundingMode.CEILING)));

System.out.println(new BigDecimal("123.4",

new MathContext(1,RoundingMode.CEILING)));

输出:

123.4

1.2E+2

1.3E+2

2E+2

您可以看到精度和舍入模式都会影响输出。

Derek Park answered 2020-02-15T06:46:44Z

13 votes

我将在此处添加一些示例。 我在以前的答案中没有找到它们,但是对于那些可能误导小数位数的有效数字的人,我发现它们很有用。 让我们假设,我们有这样的上下文:

MathContext MATH_CTX = new MathContext(3, RoundingMode.HALF_UP);

对于此代码:

BigDecimal d1 = new BigDecimal(1234.4, MATH_CTX);

System.out.println(d1);

十分清楚,正如您所说的,您的结果是4.55E-7。 第一位有效数字是123 ...

但是在这种情况下:

BigDecimal d2 = new BigDecimal(0.000000454770054, MATH_CTX);

System.out.println(d2);

您的电话号码不会在逗号后四舍五入到3位-对于某人来说,这可能并不直观,也不值得强调。 取而代之的是,它将四舍五入到前3个有效数字,在这种情况下为“ 4 5 4”。 因此,上面的代码将导致4.55E-7,而不是0.000,这可能会引起人们的预期。

类似的例子:

BigDecimal d3 = new BigDecimal(0.001000045477, MATH_CTX);

System.out.println(d3); // 0.00100

BigDecimal d4 = new BigDecimal(0.200000477, MATH_CTX);

System.out.println(d4); // 0.200

BigDecimal d5 = new BigDecimal(0.000000004, MATH_CTX);

System.out.println(d5); //4.00E-9

我希望这个明显但相关的示例会有所帮助...

guitar_freak answered 2020-02-15T06:48:00Z

4 votes

如果我正确地理解了您的声音,那听起来就像您期望MathContext控制小数点后应保留的位数。 那不是它的目的。 它指定要保留的总位数。 因此,如果您指定要3个有效数字,那将是您的全部。

例如,这:

System.out.println(new BigDecimal("1234567890.123456789",

new MathContext(20)));

System.out.println(new BigDecimal("1234567890.123456789",

new MathContext(10)));

System.out.println(new BigDecimal("1234567890.123456789",

new MathContext(5)));

将输出:

1234567890.123456789

1234567890

1.2346E+9

Derek Park answered 2020-02-15T06:48:29Z

4 votes

这不是为了好玩。 实际上,我在网上找到了一个示例,该示例说明使用Number = 101.5294来四舍五入BigDecimal中存储的金额/数字。

例如,

如果Number = 101.5294配置为具有100和rounding mode = ROUND_HALF_EVEN

Number = 101.5294,四舍五入为0.53

因此,我认为这是一种较新的技术,并将其用于取整目的。 但是它变成了噩梦,因为它开始对数字的mentissa部分进行四舍五入。

例如,

Number = 101.5294舍入为100

Number = 101.5294 is rounded to 100

Number = 101.5294 is rounded to 100

.... 等等

因此,这不是我期望的四舍五入行为(精度= 2)。

这似乎有些逻辑,因为从模式上我可以说,它采用数字的前两位(精度为2),然后将0附加到no。 位数与未取整金额相同(请参见示例101.5294 ...)

jatanp answered 2020-02-15T06:51:29Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值