我一直在使用BigNumber.js库进行高精度算术计算。为了保持更高的精度,我使用toFixedBignumber 对象的方法,如下所示:(new BigNumber(6000 )).minus(9006000).div(9006000).times(4503000 ).plus(4503000 ).toFixed()上面的代码给出的结果为2999.99999999999998275。我尝试使用数据类型在 C# 中验证此计算结果decimal,因为十进制的精度比双精度高,但结果在粒度级别上有所不同。decimal rg1 = 6000m;decimal lastSavedRG1 = 9006000m;decimal lastsavedrefinedgoalMonthly1 = 4503000m;decimal cal1 = (lastsavedrefinedgoalMonthly1 + (lastsavedrefinedgoalMonthly1 * ((rg1 - lastSavedRG1) / lastSavedRG1)));该计算给出的值为3000.0000000000000000000001。知道为什么会有这样的差异吗?
1 回答
狐的传说
TA贡献1804条经验 获得超3个赞
为了澄清一下我的评论 -BigNumber
来自 JS 的是任意精度数。这意味着它可以存储任意大小的数字。然而,小数部分不能具有任意精度,因为许多数字具有无限的小数扩展。1 / 3
像or这样的简单表达式的sqrt(2)
小数部分有无限多个数字。为此,bigjs 中有一个配置选项 -DECIMAL_PLACES
定义为:
涉及除法的运算结果的最大小数位数,即除法、平方根和基数转换运算以及带负指数的幂运算。
另一方面,C# 小数不是任意精度类型。它具有固定大小和 28-29 位数字的固定精度(如文档中所述)。该数字包括点之前和之后的数字。
这意味着,如果您设置DECIMAL_PLACES
为 28 并将两个数字相除,结果小于 1 - 该结果应与 C# 十进制一致。然而,一旦你将该结果乘以某个更大的数字 - 他们就会开始不同意。BigJS 的点后仍然有 28 位,但是 C# 小数总共有 28 位,所以如果结果是,比如 10000.,那么小数部分的精确位数是 28-5=23,他们会开始不同意。
简而言之 - 您需要找到 C# 的第三方库,它提供相同的小数任意精度数(这BigInteger
还不够,因为它是整数)。
添加回答
举报
0/150
提交
取消