标签: bigdecimal

如何在ConcurrentHashMap线程安全的情况下更新BigDecimal

我正在制作一个应用程序,它需要一堆日记帐分录并计算总和.

当有多个线程调用该addToSum()方法时,下面的方法是线程/并发安全.我想确保每次通话都能正确更新总数.

如果不安全,请说明我必须做些什么来确保螺纹安全.

我需要synchronize获取/放置还是有更好的方法?

private ConcurrentHashMap<String, BigDecimal> sumByAccount;

public void addToSum(String account, BigDecimal amount){
    BigDecimal newSum = sumByAccount.get(account).add(amount);
    sumByAccount.put(account, newSum);
}
Run Code Online (Sandbox Code Playgroud)

非常感谢!

更新:

谢谢大家的答案,我已经知道上面的代码不是线程安全的.

感谢Vint建议AtomicReference作为替代品synchronize.之前我AtomicInteger用来保存整数和,我想知道BigDecimal是否有类似的东西.

关于两者的赞成和反对,这是一个明确的结论吗?

java concurrency thread-safety bigdecimal concurrent-collections

16
推荐指数
1
解决办法
6038
查看次数

BigDecimal是如何实现的?

我正在阅读BigDecimal Class但我无法找到BigDecimal类如何将值存储在计算机内存中的任何信息.

您知道任何可以提供此信息的可靠来源吗?

java bigdecimal

16
推荐指数
2
解决办法
7981
查看次数

将Java BigDecimal舍入到最近的间隔

我有一个BigDecimal计算结果,我需要舍入到最近的指定区间(在这种情况下,它是金融市场的标记大小).

例如价格[Tick Size] - > Rounded Price

100.1 [0.25] -> 100
100.2 [0.25] -> 100.25
100.1 [0.125] -> 100.125
100.2 [0.125] -> 100.25
Run Code Online (Sandbox Code Playgroud)

谢谢.

更新:schnaader的解决方案,翻译成Java/BigDecimal术语:

price = price.divide(tick).setScale(0, RoundingMode.HALF_UP).multiply(tick)
Run Code Online (Sandbox Code Playgroud)

java rounding bigdecimal intervals

15
推荐指数
1
解决办法
6246
查看次数

为什么BigDecimal会返回一个奇怪的值?

我正在编写处理货币,收费等的代码.我将使用BigDecimal类进行数学和存储,但我们遇到了一些奇怪的东西.

这个说法:

1876.8 == BigDecimal('1876.8')
Run Code Online (Sandbox Code Playgroud)

返回false.

如果我通过格式化字符串运行这些值,"%.13f"我得到:

"%.20f" % 1876.8 => 1876.8000000000000
"%.20f" % BigDecimal('1876.8') => 1876.8000000000002
Run Code Online (Sandbox Code Playgroud)

请注意2最后一个小数位的BigDecimal中的额外值.

我认为BigDecimal应该能够抵消直接在计算机的本机浮点中存储实数的不准确性.这是2从哪里来的?

ruby floating-point bigdecimal

15
推荐指数
3
解决办法
1万
查看次数

为什么新的BigDecimal("0.015").compareTo(new BigDecimal(0.015))返回-1?

为什么new BigDecimal("0.015").compareTo(new BigDecimal(0.015))返回-1?如果我希望这两者相等,是否有另一种方法来比较它们?

java bigdecimal

15
推荐指数
3
解决办法
917
查看次数

Java,BigDecimal.分裂的问题

我正在尝试计算百分比"因子".也就是说,给定20%,将其转换为0.2(我的意图是稍后将值乘以该值并获得20%的值).

无论如何,这个问题与这段代码有关:

public static void main(String[] args) {
    int roundingMode = BigDecimal.ROUND_FLOOR;
    BigDecimal hundred = new BigDecimal("100");
    BigDecimal percentageFactor = null;
    BigDecimal percentage = new BigDecimal("20");
    BigDecimal value = new BigDecimal("500");
    percentageFactor = percentage.divide(hundred, roundingMode);
    float f = percentage.floatValue() / hundred.floatValue();
    f = value.floatValue() * f;
    BigDecimal aux = value.multiply(percentageFactor);
    System.out.println("factor:"+percentageFactor.toString());
    System.out.println("final falue:"+aux.toString());
    System.out.println("Float Value:"+f);       
}
Run Code Online (Sandbox Code Playgroud)

我希望这个结果是这样的:

factor: 0.2
final value: 100
float value: 100
Run Code Online (Sandbox Code Playgroud)

但是percentage.divide(hundred, roundingMode);返回零,因此我得到:

factor:0
final falue:0
Float Value:100.0
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?如何正确划分两位大小数?

顺便说一下,我正在使用,BigDecimal因为我将计算货币百分比,所以我想要控制四舍五入.

java division bigdecimal

14
推荐指数
2
解决办法
4万
查看次数

为什么Bigdecimal(双d)结构仍然存在?

我注意到这个构造函数有很大的痛苦(即使在Stack Overflow上也是如此).人们使用它,即使文档明确指出:

这个构造函数的结果可能有点不可预测 http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html#BigDecimal(double)

我甚至看到JSR-13批准了一条建议,说明:

可能不推荐使用的现有规范:我们建议弃用BigDecimal(double)构造函数,该构造函数目前提供的结果与Double.toString()方法不同.

尽管如此,构造函数还没有被弃用.

我很想听到有关这方面的任何看法.

java api bigdecimal

14
推荐指数
2
解决办法
1万
查看次数

Java BigDecimal精度问题

我知道以下行为是一个老问题,但我仍然不明白.

System.out.println(0.1 + 0.1 + 0.1);    
Run Code Online (Sandbox Code Playgroud)

或者即使我使用 BigDecimal

System.out.println(new BigDecimal(0.1).doubleValue()
    + new BigDecimal(0.1).doubleValue()
    + new BigDecimal(0.1).doubleValue());
Run Code Online (Sandbox Code Playgroud)

为什么这个结果是:0.30000000000000004而不是:0.3

我怎么解决这个问题?

java bigdecimal double-precision

14
推荐指数
3
解决办法
2万
查看次数

BigDecimal movePointRight和scaleByPowerOfTen有什么区别?

使用以下代码:

BigDecimal x = new BigDecimal("34.5678");
BigDecimal a = x.movePointRight(3);
BigDecimal b = x.scaleByPowerOfTen(3);
BigDecimal c = x.movePointRight(-3);
BigDecimal d = x.scaleByPowerOfTen(-3);
Run Code Online (Sandbox Code Playgroud)

a和b均为34567.8,c和d均为0.0345678. a.scale()并且b.scale都是1 c.scale()d.scale()都是7.

这两种方法在什么情况下产生不同的结果?

java math bigdecimal

14
推荐指数
1
解决办法
2604
查看次数

BigDecimal.add奇怪的行为

BigDecimal.add当一个参数具有大指数(9位数)时,方法需要很长时间,而第二个参数具有不同长度的指数.我已经等了5分钟以上,而且还在继续.

这是代码:

@Test
public void testAddBig() throws Exception {
    MathContext mc = new MathContext(10, RoundingMode.HALF_UP);
    BigDecimal v1 = new BigDecimal("1E+100000000", mc);
    BigDecimal v2 = new BigDecimal("1", mc);
    System.out.println(v1.add(v2));
}
Run Code Online (Sandbox Code Playgroud)

这是线程转储的一部分:

at java.math.BigInteger.square(BigInteger.java:1884)
at java.math.BigInteger.squareKaratsuba(BigInteger.java:1975)
at java.math.BigInteger.square(BigInteger.java:1888)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2011)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2006)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2012)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2010)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2006)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2012)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2011)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.pow(BigInteger.java:2263)
at java.math.BigDecimal.bigTenToThe(BigDecimal.java:3543)
at java.math.BigDecimal.bigMultiplyPowerTen(BigDecimal.java:4508)
at java.math.BigDecimal.add(BigDecimal.java:4443)
at java.math.BigDecimal.add(BigDecimal.java:1289)
Run Code Online (Sandbox Code Playgroud)

到底是怎么回事?这是一个错误吗?

java fixed-point bigdecimal

13
推荐指数
1
解决办法
385
查看次数