在 C# 中使用十进制数据类型进行相同计算时,BigNumber.js 计算显示不同的值

问题描述 投票:0回答:2

我一直在使用BigNumber.js库进行高精度算术计算。为了保持更高的精度,我使用 Bignumber 对象的

toFixed
方法,如下所示:

(new BigNumber(6000 )).minus(9006000).div(9006000).times(4503000 ).plus(4503000 ).toFixed()

上面的代码给出的结果为

2999.99999999999998275
。我尝试使用
decimal
数据类型在 C# 中验证此计算结果,因为十进制的精度比双精度高,但结果在粒度级别上有所不同。

decimal rg1 = 6000m;
decimal lastSavedRG1 = 9006000m;
decimal lastsavedrefinedgoalMonthly1 = 4503000m;
decimal cal1 = (lastsavedrefinedgoalMonthly1 + (lastsavedrefinedgoalMonthly1 * ((rg1 - lastSavedRG1) / lastSavedRG1)));

此计算给出的值为

3000.0000000000000000000001
。知道为什么会有这样的差异吗?

javascript c# arbitrary-precision bignumber.js
2个回答
1
投票

澄清一下我的评论 - JS 中的

BigNumber
是任意精度数。这意味着它可以存储任意大小的数字。然而,小数部分不能具有任意精度,因为许多数字具有无限的小数扩展。像
1 / 3
sqrt(2)
这样的简单表达式的小数部分有无限多个数字。为此,bigjs 中有一个配置选项 -
DECIMAL_PLACES
定义为:

运算结果最大小数位数 涉及除法,即除法、平方根和基数转换 运算,以及负指数幂运算。

另一方面,C# 小数不是任意精度类型。它具有 28-29 位的固定大小和固定精度(如文档中所述)。该数字包括点之前和之后的数字。

这意味着,如果您将

DECIMAL_PLACES

 设置为 28 并将两个数字相除,结果小于 1 - 该结果应与 C# 十进制一致。然而,一旦你将该结果乘以某个更大的数字 - 他们就会开始不同意。 BigJS 的点后仍然有 28 位,但是 C# 小数总共有 28 位,所以如果结果是,比如 10000.,那么小数部分的精确位数是 28-5=23,他们会开始不同意。

简而言之 - 您需要找到 C# 的第三方库,它提供相同的小数任意精度数(

BigInteger

还不够,因为它是整数)。


0
投票
尝试在 google colaboratory

https://colab.research.google.com/ - 即使对于小精度,你也会得到相同的结果 3000.0

from mpmath import mp # Setting the precision mp.dps = 5 # set precision # Defining values a = mp.mpf(6000) b = mp.mpf(9006000) c = mp.mpf(4503000) # Calculations result = ((a - b) / b) * c + c print(mp.nstr(result, 40)) # Equivalent calculations result = a * c / b print(mp.nstr(result, 40))qq # Defining values a = mp.mpf(6000) b = mp.mpf(9006000) c = mp.mpf(4503000) # Calculations result = ((a - b) / b) * c + c print(mp.nstr(result, 40)) # Equivalent calculations result = a * c / b print(mp.nstr(result, 40))
    
© www.soinside.com 2019 - 2024. All rights reserved.