Ecmascript bigint,四舍五入
Ecmascript bigint, round to even
我正在使用 ESNext 的 bigint
功能。做除法时,bigint
四舍五入为0,举个例子:
有数字:
> 3000 / 1578
1.9011406844106464
使用 bigint:
3000n / 1578n
1n
我不想四舍五入到 0,而是想编写一个可以进行除法但使用银行家四舍五入(四舍五入为偶数)的函数。
例子
function divide(a, b) {
return a/b;
}
我只是有点困惑如何编写 divide
函数,并使用余数四舍五入。这是我试过的:
function divide(a, b) {
let result = a/b;
// if modulo is over half the divisor
if ((a % b) * 2n > b) {
// Add 1 if result is odd
if (result % 2n === 1n) result++;
} else {
// Remove 1 if result is even
if (result % 2n !== 1n) result--;
}
return result;
}
这为我提供了 divide(3000n, 1578n)
的正确结果,但我注意到这将为我提供 divide(7n, 2n)
的错误结果,我希望将其四舍五入为 4n
。
银行家四舍五入只影响余数正好是除数一半的除法。所有其他情况都正常舍入。
我觉得你的函数应该修改如下:
function divide(a, b) {
// Make A and B positive
const aAbs = a > 0 ? a : -a;
const bAbs = b > 0 ? b : -b;
let result = aAbs/bAbs;
const rem = aAbs % bAbs;
// if remainder > half divisor, should have rounded up instead of down, so add 1
if (rem * 2n > bAbs) {
result ++;
} else if (rem * 2n === bAbs) {
// Add 1 if result is odd to get an even return value
if (result % 2n === 1n) result++;
}
if (a > 0 !== b > 0) {
// Either a XOR b is negative, so the result has to be
// negative as well.
return -result;
} else {
return result;
}
}
console.log(divide(3000n, 1578n));
console.log(divide(7n, 2n));
console.log(divide(-7n, 2n));
我正在使用 ESNext 的 bigint
功能。做除法时,bigint
四舍五入为0,举个例子:
有数字:
> 3000 / 1578
1.9011406844106464
使用 bigint:
3000n / 1578n
1n
我不想四舍五入到 0,而是想编写一个可以进行除法但使用银行家四舍五入(四舍五入为偶数)的函数。
例子
function divide(a, b) {
return a/b;
}
我只是有点困惑如何编写 divide
函数,并使用余数四舍五入。这是我试过的:
function divide(a, b) {
let result = a/b;
// if modulo is over half the divisor
if ((a % b) * 2n > b) {
// Add 1 if result is odd
if (result % 2n === 1n) result++;
} else {
// Remove 1 if result is even
if (result % 2n !== 1n) result--;
}
return result;
}
这为我提供了 divide(3000n, 1578n)
的正确结果,但我注意到这将为我提供 divide(7n, 2n)
的错误结果,我希望将其四舍五入为 4n
。
银行家四舍五入只影响余数正好是除数一半的除法。所有其他情况都正常舍入。
我觉得你的函数应该修改如下:
function divide(a, b) {
// Make A and B positive
const aAbs = a > 0 ? a : -a;
const bAbs = b > 0 ? b : -b;
let result = aAbs/bAbs;
const rem = aAbs % bAbs;
// if remainder > half divisor, should have rounded up instead of down, so add 1
if (rem * 2n > bAbs) {
result ++;
} else if (rem * 2n === bAbs) {
// Add 1 if result is odd to get an even return value
if (result % 2n === 1n) result++;
}
if (a > 0 !== b > 0) {
// Either a XOR b is negative, so the result has to be
// negative as well.
return -result;
} else {
return result;
}
}
console.log(divide(3000n, 1578n));
console.log(divide(7n, 2n));
console.log(divide(-7n, 2n));