我想根据以下条件进行自定义舍入到0.05附近,这很难解释,但是下面的例子很容易理解。
12.910 - 12.90
12.920 - 12.90
12.930 - 12.90
12.940 - 12.90
12.941 - 12.95
12.950 - 12.95
12.960 - 12.95
12.970 - 12.95
12.980 - 12.95
12.990 - 12.95
12.991 - 13.00
13.000 - 13.00
我尝试了几种功能,但将12.98舍入为13.00。
function customRound( num) {
return Math.round(num * 20) / 20;
}
答案 0 :(得分:2)
从视觉上来看,您的舍入算法看起来像这样:
该点是您要舍入到该间隔的位置。 (标记间隔的开放端,] 封闭端。(12.99属于红色间隔。)我们将通过操纵与{ {1}}。
首先,让我们处理整数。
DevExpress.XtraReports.v18.1
您的舍入间隔是左开和右开的,而Math.floor
是左开和右开的。我们可以乘以−1来翻转直线以进行匹配:
num * 100
您的舍入间隔的长度为5,因此我们需要将间隔的末端设为5的倍数...
Math.floor
...除以5以匹配 num * 100 * -1
⇒ num * -100
。
num * -100 - 1
现在我们可以发言。
Math.floor
乘以5可以放大到原始大小:
(num * -100 - 1 ) / 5
⇒ num * -20 - 0.2
通过添加4将返回值移到点上:
return Math.floor(num * -20 - 0.2);
撤消我们之前所做的对齐:
return Math.floor(num * -20 - 0.2) * 5;
撤消翻转:
return Math.floor(num * -20 - 0.2) * 5 + 4;
将整个结果除以100,即可恢复原始比例:
return Math.floor(num * -20 - 0.2) * 5 + 4 + 1;
⇒ return Math.floor(num * -20 - 0.2) * 5 + 5;
使用Robin Zigmond的测试框架,
return (Math.floor(num * -20 - 0.2) * 5 + 5) * -1;
⇒ return Math.floor(num * -20 - 0.2) * -5 - 5;
答案 1 :(得分:1)
如果您确实打算将所有数字舍入到.05的最接近的.01之内,请尝试以下操作,以获取其使用的数字的精度Is there a reliable way in JavaScript to obtain the number of decimal places of an arbitrary number?
function decimalPlaces(n) {
var s = "" + (+n);
var match = /(?:\.(\d+))?(?:[eE]([+\-]?\d+))?$/.exec(s);
if (!match) { return 0; }
return Math.max(
0, // lower limit.
(match[1] == '0' ? 0 : (match[1] || '').length)
- (match[2] || 0));
}
var test = 12.941;
var factor = Math.pow(10,decimalPlaces(test));
var remainder = ((test * factor) % (.05 * factor))/factor;
var result;
if (remainder>.04) {
result = Math.round(test*20)/20;
} else {
result = (test*factor - remainder*factor)/factor;
}
console.log('result is:',result);
答案 2 :(得分:1)
据我从您的示例可以看出,所需的行为似乎是“向上舍入到最接近的0.01,然后将结果舍入到最接近的0.05”。
这可以如下实现。如您所见,它与您的示例完全吻合(我什至都以相同的方式对其进行了格式设置)-但请告诉我,如果我的手法不对头。
function customRound(num) {
var intermediateResult = Math.ceil(num*100)/100;
return Math.floor(intermediateResult*20)/20;
}
// test desired results
var tests = [12.91, 12.92, 12.93, 12.94, 12.941, 12.95, 12.96, 12.97, 12.98, 12.99, 12.991, 13];
for (var i=0; i<tests.length; i++) {
console.log(`${tests[i].toFixed(3)} - ${customRound(tests[i]).toFixed(2)}`);
}