我一直在使用BigNumber.js库进行高精度的算术计算。为了保持更高的精度,我使用Bignumber对象的toFixed方法,如下所示:
(new BigNumber(6000 )).minus(9006000).div(9006000).times(4503000 ).plus(4503000 ).toFixed()
上面的代码给出的结果是2999.99999999999998275。我试着用C#数据类型来验证这个计算结果,因为十进制比双进精度高,但是在粒度级别上的结果是不同的。
decimal rg1 = 6000m;
decimal lastSavedRG1 = 9006000m;
decimal lastsavedrefinedgoalMonthly1 = 4503000m;
decimal cal1 = (lastsavedrefinedgoalMonthly1 + (lastsavedrefinedgoalMonthly1 * ((rg1 - lastSavedRG1) / lastSavedRG1)));此计算给出的值为3000.0000000000000000000001。知道为什么会有这样的差异吗?
发布于 2020-11-11 15:25:55
为了澄清我的评论-来自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是不够的,因为它是整数)。
https://stackoverflow.com/questions/64769822
复制相似问题