如何在Javascript中应用C#等效舍入方法

时间:2017-09-28 13:43:07

标签: javascript c# rounding-error

我正在实现一个混合移动应用程序,我必须在其中代表用C#编写的桌面应用程序。

在舍入值时,桌面和移动应用程序之间的值会有所不同。

示例

C#中使用的代码:

Math.Round (7060.625, 2); // prints 7060.62
Math.Round (7060.624, 2); // prints 7060.62
Math.Round (7060.626, 2); // prints 7060.63

JS中使用的代码:

+(7060.625).toFixed(2); // prints 7060.63 (value differs)
+(7060.624).toFixed(2); // prints 7060.62
+(7060.626).toFixed(2); // prints 7060.63

如何更改JS代码以表示C#中的值。

注意:

我们可以使用 Math.Round(7060.625,2,MidpointRounding.AwayFromZero)使C#代表JS中的值;

但我没有选择在那里改变。

编辑1

舍入小数不是固定的。它由移动应用程序中的用户选择。

2 个答案:

答案 0 :(得分:7)

您需要自定义实施四舍五入以实施"银行家的四舍五入"或甚至四舍五入。

来自:

Gaussian/banker's rounding in JavaScript

function evenRound(num, decimalPlaces) {
    var d = decimalPlaces || 0;
    var m = Math.pow(10, d);
    var n = +(d ? num * m : num).toFixed(8); // Avoid rounding errors
    var i = Math.floor(n), f = n - i;
    var e = 1e-8; // Allow for rounding errors in f
    var r = (f > 0.5 - e && f < 0.5 + e) ?
                ((i % 2 == 0) ? i : i + 1) : Math.round(n);
    return d ? r / m : r;
}

console.log( evenRound(1.5) ); // 2
console.log( evenRound(2.5) ); // 2
console.log( evenRound(1.535, 2) ); // 1.54
console.log( evenRound(1.525, 2) ); // 1.52

答案 1 :(得分:1)

如果您同时控制客户端和服务器端,则可以遵循这种超级简单的模式,适用于边缘情况和常规情况:

让我们看一下2.155、2.145(中点问题)和2.166、2.146(常规)。

C#:

public static decimal RoundFromJavaScript(this Decimal value)
{
    return Decimal.Round(value, 2, MidpointRounding.AwayFromZero);
}

//-Midpoint Issue 
RoundFromJavaScript(2.155); --> 2.16             
RoundFromJavaScript(2.145); --> 2.15
//-Regular 
RoundFromJavaScript(2.166); --> 2.17             
RoundFromJavaScript(2.146); --> 2.15

*我省略了m小数点,它应该是2.155m

JavaScript:

function roundToTwo(num) {
    return +(Math.round(num + "e+2") + "e-2");
}

//-Midpoint Issue
roundToTwo(2.155) --> 2.16           
roundToTwo(2.145) --> 2.15

//-Regular
roundToTwo(2.166) --> 2.17            
roundToTwo(2.146) --> 2.15