【问题标题】:How to round smoothly percentage in JS如何在JS中平滑百分比
【发布时间】:2015-06-04 14:00:48
【问题描述】:

我有一个包含小数值的对象:evometeousage 我尝试用三个条件显示这个值:

  • 值可以是正数和负数
  • 值必须以百分比形式显示,不带任何小数
  • (A) 必须为真

(A):Math.round(meteo*100)+Math.round(usage*100) = Math.round(evo*100)

例如,如果我们将 A with 应用于这些值

{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 递增/递减。 我很确定我正在努力做到这一点。

有没有更简单的方法来完成这项任务?

【问题讨论】:

  • 如果你先四舍五入然后添加我不相信你可以保证平等(你所说的“A必须是真的”。)
  • Math.round(val*100)/100;
  • 您是否有理由不能以更高的精度显示百分比?
  • 你有没有你的函数不能正常工作的例子?
  • @RowlandShaw,可用的UX空间只能显示两位数,MaximePeloquin,我已经给了一个,

标签: javascript math rounding


【解决方案1】:

试试这个:

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 上出现 calc 错误,我们将不会使用此界面看到它。
  • @BigDong 只检查调用级别
  • 我已经将其作为报告日志进行了,但仍然需要操作员注意。
  • @BigDong 您可以在错误情况下覆盖 evo,但您可能想做一些不同于向操作员显示错误结果的事情...
【解决方案2】:

如果您想保持evo 的值的准确度,而不是根据meteousage 的总和来计算,这里有一种不同的方法。 (比用evo = metro + usage丑一点)

查看meteousage 的小数点是多少,然后根据结果使用.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 价值的东西。
  • 现在改了,但是越来越丑了。
  • 应该这样做,但最好的方法仍然是你之前回答的那样。只是出于好奇,试图利用 evo 的真正价值来做到这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-02
  • 1970-01-01
  • 2019-06-24
  • 2022-01-12
  • 2015-05-09
  • 1970-01-01
相关资源
最近更新 更多