Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/425.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Javascript中舍入一个数字,使其与C匹配#_Javascript_C#_Rounding_Rounding Error - Fatal编程技术网

在Javascript中舍入一个数字,使其与C匹配#

在Javascript中舍入一个数字,使其与C匹配#,javascript,c#,rounding,rounding-error,Javascript,C#,Rounding,Rounding Error,我有一个用nodejs编写的应用程序。该应用程序需要计算海运税。计算需要与端口的结果相匹配。港口的征税计算器是用C#编写的 注意:我无法控制C代码。我需要根据C#返回的内容调整JS代码 这是Javascript代码: console.log('Testing rounding -- js') nrt = 34622 c = 0 if (nrt <= 5000) c = nrt * 0.405 else if (nrt > 5000 && nrt <= 2000

我有一个用nodejs编写的应用程序。该应用程序需要计算海运税。计算需要与端口的结果相匹配。港口的征税计算器是用C#编写的

注意:我无法控制C代码。我需要根据C#返回的内容调整JS代码

这是Javascript代码:

console.log('Testing rounding -- js')
nrt = 34622
c = 0

if (nrt <= 5000) c = nrt * 0.405
else if (nrt > 5000 && nrt <= 20000) c = 2025 + ( (nrt - 5000) * 0.291)
else if (nrt > 20000 && nrt <= 50000) c = 6390 + ( (nrt - 20000) * 0.24)
else c = 13590 + ( (nrt - 50000) * 0.18)

var p = nrt * 0.1125

var t = c + p

console.log(t)
console.log(t.toFixed(2))
这是C代码:

请注意,我一点也不懂C。我意识到它有一个“decimal”类型,这是一个128位的数据类型,适合于金融和货币计算。它有28-29位精度

据我所知,Javascript不处理128位的数据类型

我还想知道,问题是否可能出在舍入的不同实现中

我在写这篇文章的同时还补充说,13794.2550很难跨系统可靠地取整。这是一个完全不同的兔子洞

但是,例如,使用:

结果:

Testing rounding -- js
13794.255
13794.25
Testing rounding -- csharp
13794.2550
13794.26
13794.26 <--- this is what I want! But, is it reliable?
13794.25

13794.26我认为您遇到的问题是因为您使用了不同类型的舍入函数

在JS部分中,您使用的是
toFixed()
,而不是
Math.round()
。toFixed与C#rounding并不完全相同。它更类似于C#舍入,在C#舍入中,您向它添加了一个
AwayFromZero
属性。您也可以在C#中执行此操作,但必须明确说明-->
Math.Round(value,2,middpointrounding.AwayFromZero)。您应该能够使用
Math.round()
获得与C#相同的结果。它们都是由Microsoft维护的,因此通常它们的工作方式非常相似,有时它们具有相同的库实现(从用户角度来看)


所以,您使用的第二个实现是可靠的。如果您担心128字节的转换,请尝试使用
double
而不是
decimal
,并检查结果是否与
double
为64位时相同,如果需要进一步测试,请使用32位的
float

+1,但由于JavaScript使用浮点数学,我会先用
float
测试C#的可靠性(可能根本不用
double
测试)。对不起。。。我忘了更清楚地说明,虽然我完全控制Javascript代码,但我对C#代码没有控制权!你能记住这一点来更新答案吗?请看我的编辑:我无法控制C#,我需要修改JS代码,使它能像C#那样工作!
function r(n, decimals) {
    return Number((Math.round(n + "e" + decimals)  + "e-" + decimals));
}

console.log(r(13794.2550,2))
console.log(13794.2550.toFixed(2))
13794.26 <--- this is what I want! But, is it reliable?
13794.25