如何在 JS 中平滑地舍入百分比
How to round smoothly percentage in JS
我有一个包含小数值的对象:evo
、meteo
和 usage
我尝试在三个条件下显示此值:
- 值可以是正数也可以是负数
- 值必须显示为不带任何小数的百分比
- (A) 必须为真
(A): Math.round(meteo*100)+Math.round(usage*100) = Math.round(evo*100)
例如,如果我们将 A 应用于这些值
{evo: 0.1466, meteo: 0.1231, usage: 0.0235}
我们将得到无效的百分比:
evo: 15%
meteo: 12%
usage: 2%
由于值是四舍五入的,有时 (A) 未被验证。
我正在研究 getSmooth 函数来调整舍入值以使等式 (A) 始终得到验证。
var smooth = getSmooth(Math.round(evo*100), Math.round(meteo*100), Math.round(usage*100);
function getSmooth(evo, meteo, usage){
// case we need to incremente something
if( Math.abs(evo) > Math.abs(meteo) + Math.abs(usage) ){
// case we need to incremente usage
if( Math.abs(meteo) > Math.abs(usage) ){
(usage > 0) ? usage++ : usage--;
}
// case we need to incremente meteo
else{
(meteo > 0) ? meteo++ : meteo--;
}
}
// case we need to decremente something
else{
// case we need to decremente usage
if( Math.abs(meteo) > Math.abs(usage) ){
(usage > 0) ? usage-- : usage++;
}
// case we need to decremente meteo
else{
(meteo > 0) ? meteo-- : meteo++;
}
}
return {
evo: evo,
meteo: meteo,
usage: usage
};
}
我的函数工作不正常,它只能处理 +1 incrementation/decrementation。
我很确定我正在努力做到这一点。
是否有更简单的方法来完成该任务?
试试这个:
function getSmooth(meteo, usage) {
meteo = Math.round(meteo*100);
usage = Math.round(usage*100);
return {
evo: (meteo + usage) / 100,
meteo: meteo / 100,
usage: usage / 100
};
}
测试 evo
中与您的可视化逻辑分开的计算错误:
var evo, meteo, usage;
// ...
// do the error handling
var eps = 1e-4; // some float precision epsilon
if(Math.abs(evo - (meteo + usage)) > eps) {
// there's an error in evo...
}
// now do the processing
var smooth = getSmooth(meteo, usage);
// continue with smooth...
如果你想保持 evo
值的 准确性 而不是根据 [=12] 的总和来计算它,这里有一个不同的方法=] 和 usage
。 (比用evo = metro + usage
丑了点)
看看meteo
和usage
的小数点是多少,然后根据结果使用.ceil()
或.floor()
。
var smooth = getSmooth(evo, meteo, usage);
function getSmooth(evo, meteo, usage){
evo *= 100;
meteo *= 100;
usage *= 100;
var meteo_decimal = meteo % 1;
var usage_decimal = usage % 1;
evo = Math.round(evo);
if( meteo_decimal > usage_decimal ) {
meteo = Math.ceil(meteo);
usage = Math.floor(usage);
} else {
meteo = Math.floor(meteo);
usage = Math.ceil(usage);
}
return {
evo: evo / 100,
meteo: meteo / 100,
usage: usage / 100
};
}
我有一个包含小数值的对象:evo
、meteo
和 usage
我尝试在三个条件下显示此值:
- 值可以是正数也可以是负数
- 值必须显示为不带任何小数的百分比
- (A) 必须为真
(A): Math.round(meteo*100)+Math.round(usage*100) = Math.round(evo*100)
例如,如果我们将 A 应用于这些值
{evo: 0.1466, meteo: 0.1231, usage: 0.0235}
我们将得到无效的百分比:
evo: 15%
meteo: 12%
usage: 2%
由于值是四舍五入的,有时 (A) 未被验证。 我正在研究 getSmooth 函数来调整舍入值以使等式 (A) 始终得到验证。
var smooth = getSmooth(Math.round(evo*100), Math.round(meteo*100), Math.round(usage*100);
function getSmooth(evo, meteo, usage){
// case we need to incremente something
if( Math.abs(evo) > Math.abs(meteo) + Math.abs(usage) ){
// case we need to incremente usage
if( Math.abs(meteo) > Math.abs(usage) ){
(usage > 0) ? usage++ : usage--;
}
// case we need to incremente meteo
else{
(meteo > 0) ? meteo++ : meteo--;
}
}
// case we need to decremente something
else{
// case we need to decremente usage
if( Math.abs(meteo) > Math.abs(usage) ){
(usage > 0) ? usage-- : usage++;
}
// case we need to decremente meteo
else{
(meteo > 0) ? meteo-- : meteo++;
}
}
return {
evo: evo,
meteo: meteo,
usage: usage
};
}
我的函数工作不正常,它只能处理 +1 incrementation/decrementation。 我很确定我正在努力做到这一点。
是否有更简单的方法来完成该任务?
试试这个:
function getSmooth(meteo, usage) {
meteo = Math.round(meteo*100);
usage = Math.round(usage*100);
return {
evo: (meteo + usage) / 100,
meteo: meteo / 100,
usage: usage / 100
};
}
测试 evo
中与您的可视化逻辑分开的计算错误:
var evo, meteo, usage;
// ...
// do the error handling
var eps = 1e-4; // some float precision epsilon
if(Math.abs(evo - (meteo + usage)) > eps) {
// there's an error in evo...
}
// now do the processing
var smooth = getSmooth(meteo, usage);
// continue with smooth...
如果你想保持 evo
值的 准确性 而不是根据 [=12] 的总和来计算它,这里有一个不同的方法=] 和 usage
。 (比用evo = metro + usage
丑了点)
看看meteo
和usage
的小数点是多少,然后根据结果使用.ceil()
或.floor()
。
var smooth = getSmooth(evo, meteo, usage);
function getSmooth(evo, meteo, usage){
evo *= 100;
meteo *= 100;
usage *= 100;
var meteo_decimal = meteo % 1;
var usage_decimal = usage % 1;
evo = Math.round(evo);
if( meteo_decimal > usage_decimal ) {
meteo = Math.ceil(meteo);
usage = Math.floor(usage);
} else {
meteo = Math.floor(meteo);
usage = Math.ceil(usage);
}
return {
evo: evo / 100,
meteo: meteo / 100,
usage: usage / 100
};
}