C#与JS中Decimal正负值舍入函数适配有效性确认
C#与JavaScript Decimal正负值舍入函数正确性验证
C# 函数分析
原函数问题
原RoundUp函数仅适配正值:Math.Ceiling对负数会向正方向取整(如Math.Ceiling(-1.2)返回-1),不符合"总是向上舍入(向远离零方向)"的需求。而RoundAwayFromZero和RoundEven依赖.NET内置的Math.Round,本身已支持正负值,无需修改。
适配后函数(正确)
public static decimal RoundAwayFromZero(decimal number, int precision) { return Math.Round(number, precision, MidpointRounding.AwayFromZero); } public static decimal RoundEven(decimal number, int precision) { return Math.Round(number, precision, MidpointRounding.ToEven); } public static decimal RoundUp(decimal number, int precision) { var negativeFactor = number < default(decimal) ? -1 : 1; var factor = Convert.ToDecimal(Math.Pow(10, precision)); return negativeFactor * Math.Ceiling(number * negativeFactor * factor) / factor; }
验证要点
RoundAwayFromZero:Math.Round的MidpointRounding.AwayFromZero会对正负值的中点向远离零方向舍入(如RoundAwayFromZero(-1.5, 0)返回-2,RoundAwayFromZero(1.5, 0)返回2),逻辑正确。RoundEven:MidpointRounding.ToEven实现银行家舍入,中点时取最近偶数(如RoundEven(-1.5, 0)返回-2,RoundEven(-2.5, 0)返回-2),正确支持正负值。RoundUp:通过符号转换将负数转为正数,用Math.Ceiling取整后恢复符号,实现"向远离零方向舍入"(如RoundUp(-1.2, 0)返回-2,RoundUp(1.2, 0)返回2),逻辑正确。
JavaScript 函数分析
原函数问题
原三个函数均仅适配正值:
roundAwayFromZero对负数中点的舍入不符合"远离零"规则(如roundAwayFromZero(-1.5, 0)原函数返回-1,正确结果应为-2);roundEven依赖JS原生Math.round(中点向正无穷舍入),对负数的银行家舍入逻辑存在隐患;roundUp同样因Math.ceil对负数的取整规则,无法实现"远离零向上舍入"。
适配后函数(正确)
function roundAwayFromZero(number, precision) { var negativeFactor = number < 0.0 ? -1 : 1; var factor = Math.pow(10, precision); var n = precision < 0 ? number : 0.01 / factor + number; return negativeFactor * Math.round(n * negativeFactor * factor) / factor; } function roundEven(number, precision) { var negativeFactor = number < 0.0 ? -1 : 1; var factor = Math.pow(10, precision); var x = number * negativeFactor * factor; var r = Math.round(x); var br = Math.abs(x) % 1 === 0.5 ? (r % 2 === 0 ? r : r - 1) : r; return br * negativeFactor / factor; } function roundUp(number, precision) { var negativeFactor = number < 0.0 ? -1 : 1; var factor = Math.pow(10, precision); return negativeFactor * Math.ceil(number * negativeFactor * factor) / factor; }
验证要点
roundAwayFromZero:将负数转为正数处理,恢复符号后得到符合"远离零"规则的结果(如roundAwayFromZero(-1.5, 0)返回-2),正确适配正负值。roundEven:通过符号转换统一处理正负值的银行家舍入,避免JS原生Math.round的规则影响(如roundEven(-2.5, 0)返回-2,roundEven(2.5, 0)返回2),逻辑正确。roundUp:与C#RoundUp逻辑一致,实现正负值的"远离零向上舍入"(如roundUp(-1.001, 2)返回-1.01),结果符合预期。
结论
所有适配后的函数均能正确处理正负decimal值,完全满足对应的舍入需求。
内容的提问来源于stack exchange,提问作者user11378344
相关产品推荐
相关产品推荐

