问题
有没有人知道在JavaScript中将浮点数舍入到最接近的0.05的方法?
示例
BEFORE | AFTER
2.51 | 2.55
2.50 | 2.50
2.56 | 2.60
当前代码
var _ceil = Math.ceil;
Math.ceil = function(number, decimals){
if (arguments.length == 1)
return _ceil(number);
multiplier = Math.pow(10, decimals);
return _ceil(number * multiplier) / multiplier;
}
然后在其他地方......
return (Math.ceil((amount - 0.05), 1) + 0.05).toFixed(2);
导致......
BEFORE | AFTER
2.51 | 2.55
2.50 | 2.55
2.56 | 2.65
答案 0 :(得分:28)
乘以20,然后除以20:
(Math.ceil(number*20)/20).toFixed(2)
答案 1 :(得分:8)
我会选择实际除以你将其分解的数字的标准,并将其四舍五入然后再将其再次乘以。这似乎是一种适当的工作方法,你可以使用任何数字,并保持你想要实现的目标的心理形象。
var val = 26.14,
factor = 0.05;
val = Math.round(val / factor) * factor;
这将适用于数十,数百或任何数字。如果您特别舍入到较高的数字,请使用Math.ceil
代替Math.round
。
另一种专门用于舍入到一个或多个小数位(而不是半个位置)的方法如下:
Number(Number(1.5454545).toFixed(1));
它会创建一个固定数字字符串,然后将其转换为真实的Number
。
答案 2 :(得分:7)
Rob的回答是我的补充:
(Math.ceil(number*20 - 0.5)/20).toFixed(2)
否则它总是向上舍入到最接近的0.05。
**更新**
很抱歉有人指出这不是原创海报想要的。
答案 3 :(得分:2)
I would write a function that does it for you by
%
) that inflatedNumber
by 5 and get the remainderremainder
from 5 so that you know what the 'gap'(ceilGap
) is between your number and the next closest .05finally, divide your inflatedNumber
by 100 so that it goes back to your original float, and voila, your num will be rounded up to the nearest .05.
function calcNearestPointZeroFive(num){
var inflatedNumber = num*100,
remainder = inflatedNumber % 5;
ceilGap = 5 - remainder
return (inflatedNumber + ceilGap)/100
}
If you want to leave numbers like 5.50 untouched you can always add this checker:
if (remainder===0){
return num
} else {
var ceilGap = 5 - remainder
return (inflatedNumber + ceilGap)/100
}
答案 4 :(得分:0)
你需要把-1放到下半轮然后再乘以-1,就像下面的示例一样。
<script type="text/javascript">
function roundNumber(number, precision, isDown) {
var factor = Math.pow(10, precision);
var tempNumber = number * factor;
var roundedTempNumber = 0;
if (isDown) {
tempNumber = -tempNumber;
roundedTempNumber = Math.round(tempNumber) * -1;
} else {
roundedTempNumber = Math.round(tempNumber);
}
return roundedTempNumber / factor;
}
</script>
<div class="col-sm-12">
<p>Round number 1.25 down: <script>document.write(roundNumber(1.25, 1, true));</script>
</p>
<p>Round number 1.25 up: <script>document.write(roundNumber(1.25, 1, false));</script></p>
</div>
答案 5 :(得分:0)
我最终在项目中成功使用了此功能:
roundToNearestFiveCents( number: any ) {
return parseFloat((Math.round(number / 0.05) * 0.05).toFixed(2));
}
对于那些希望简单地将其货币结果四舍五入至最接近的5美分,使结果保持数字的人可能会有用,因此,如果对它进一步执行加法运算,则不会导致字符串串联;也不必像其他一些答案所指出的那样不必要地四舍五入。还将其限制为两位小数,这是金融惯例。
答案 6 :(得分:0)
我的解决方案和测试:
let round = function(number, precision = 2, rounding = 0.05) {
let multiply = 1 / rounding;
return parseFloat((Math.round(number * multiply) / multiply)).toFixed(precision);
};
答案 7 :(得分:0)
即使 OP 没有明确说明银行家四舍五入,四舍五入到最接近的 0.05 美元(5 美分)应该与银行家四舍五入兼容。 Arth 的建议比 Rob W 接受的答案更准确。
(Math.ceil(number*20 - 0.5)/20).toFixed(2)
对于银行家舍入,您需要一个基本的银行家舍入函数,如 Gaussian/banker's rounding in JavaScript 所建议的,我用 TypeScript 重写:
static bankerRound(num: number, decimalPlaces?: number) {
const d = decimalPlaces || 0;
const m = Math.pow(10, d);
const n = +(d ? num * m : num).toFixed(8);
const i = Math.floor(n), f = n - i;
const e = 1e-8;
const r = (f > 0.5 - e && f < 0.5 + e) ?
((i % 2 === 0) ? i : i + 1) : Math.round(n);
return d ? r / m : r;
}
static roundTo5cents(num: number) {
const r = bankerRound(Math.ceil(num * 20 - 0.5) / 20, 2);
return r;
}
该算法的正确性可以通过 MBS Online 进行验证,例如http://www9.health.gov.au/mbs/ready_reckoner.cfm?item_num=60