为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

有只小跳蛙 2023-07-20 14:44:25
我一直在使用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还不够,因为它是整数)。


查看完整回答
反对 回复 2023-07-20
  • 1 回答
  • 0 关注
  • 88 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信