如何将数字的值增加到下一个10,100,1000,10,000等的倍数

时间:2014-10-30 19:48:29

标签: javascript math max

你必须原谅这个问题的措辞,我确信有更好,更简洁的方式来提问,但我不知道。

我们说我有一个图表,所有的y轴值都是

[0,4,5,3,2,5,6]

最大值为6。所以我希望Y-Scale标记为0到10.

给出以下值

[33,26,54,23,86,23]

最大值为86,所以我希望Y-Scale从0到90.

现在让我们说我有以下数值

[98,253,87, 876,263]

最大值为876,因此Y标度应为0到900

现在我创建了以下函数,该函数应该为我提供到目前为止所需的所有最大y-scale值。

function padMaxValue(value){
        for(var i = 1; i < 1000000000000000000; i = i * 10){
            var decimalValue = value / i;

            if(value === i){
                return i;
            }

            if(decimalValue < 1 && decimalValue > 0.09){
                return i;
            }

        }
    }

但是,给出以下值

[99,123,82,189,45]

我的功能会将y-scale max设置为1000。但是max应该真的是200.我意识到我真正需要的是一种更聪明的方法来增加i的值而不是将它乘以10.我需要能够将i的值增加10 ,一直到100,然后增加100,一直增加到1000.然后增加1000,一直增加到10000,依此类推。

我觉得应该有一些干净整洁的数学方法来做到这一点。而且我也觉得我在for循环中的1000000000000000000数字背叛了我对数学的无知。

Anyhoot,这就是问题所在。有什么想法吗?

7 个答案:

答案 0 :(得分:82)

没有必要进入字符串的土地,如果你有一个十进制值,这可能会很尴尬。

function RoundedMax(a) {
    var mx = Math.max.apply(Math, a);
    if (mx == 0) {return 0};
    var size = Math.floor(Math.log(Math.abs(mx)) / Math.LN10);
    var magnitude = Math.pow(10, size);
    var yMax = Math.ceil(mx / magnitude) * magnitude;
    return yMax;
}

function RoundedMin(a) {
    var mn = Math.min.apply(Math, a);
    if (mn == 0) {return 0};
    var size = Math.floor(Math.log(Math.abs(mn)) / Math.LN10);
    var magnitude = Math.pow(10, size);
    var yMin = Math.floor(mn / magnitude) * magnitude;
    return yMin;
}

var arr = [-9.9,-1.23,-8.2,-2.01,-4.5,0];
document.write(RoundedMax(arr) + " " + RoundedMin(arr));

输出:0 -10

编辑根据评论进行了更新。现在甚至可以在IE8中使用。

答案 1 :(得分:22)

我不喜欢数学,所以这里有一个非常简单/搞笑的字符串操作解决方案:

找到最大值:

var max = Math.max.apply(Math, [98,253,87, 876,263]); // 876

拿第一个角色

var c = max.toString()[0] // "8"

将其设为整数并添加1

c = (c | 0) + 1 // 9

将其转换回字符串:

c = c.toString() // "9"

向其中添加N - 1个零,其中N是原始数字的长度:

c += Array(max.toString().length).join("0") // "900"

将其转换回整数:

c = (c | 0) // 900

完成!


严重的是,use math

答案 2 :(得分:11)

我相信这会为你做到这一点:

var data = [98, 253, 87, 876, 263, -155];
var max = Math.max.apply(null, data); // 
var factor = Math.pow(10, Math.floor(Math.log(Math.abs(max)) / Math.LN10)); 
if (factor == 0) { factor = 1; }                  
var magnitude = Math.ceil(max / (factor * 1.00)) * factor; 

基本上上面发生的是以下内容:

  1. 查找样本的最大值
  2. 获取最大值长度,然后将其提高到10的幂,即345,长度= 3,因此因子为100
  3. 确保我们不要除以0
  4. 将最大数除以系数得到一个小数,然后取该数字的上限,然后再乘以该系数得到正确数字0。
  5. 更新:如果要查找最小值(对于负值),只需将Math.ceil翻转为Math.floor即可。您还必须取最小值的绝对值,以确保不将负字符计算为字符串的一部分。

    var data = [98, 253, 87, 876, 263, -155];
    var min = Math.min.apply(null, data);
    var factor = Math.pow(10, Math.floor(Math.log(Math.abs(max)) / Math.LN10));
    if (factor == 0) { factor = 1; }
    var mag = Math.floor(min / (factor * 1.00)) * factor //  mag = -200;
    

    更新2:正如很多人在评论中所说,我们不应该使用字符串操作。我更新了代码以使用对数。

答案 3 :(得分:3)

我结束了:

function getGraphRange(data)
{
    var max=Math.max.apply(null, data);
    var min=Math.min.apply(null, data);
    var maxDigits=max.toString().length;
    var minDigits=min.toString().length;
    var maxD=Math.pow(10,Math.max((maxDigits-1),1));
    var minD=Math.pow(10,Math.max((minDigits-1),1));
    var maxR=(Math.ceil(max/maxD)*maxD);
    var minR=(Math.floor(min/minD)*minD);
    return [minR,maxR];
}
alert(getGraphRange([11, 20, 345, 99]).join(' - '));//10-400
alert(getGraphRange([0,4,5,3,2,5,6]).join(' - '));//0-10
alert(getGraphRange([98,253,87,876,263]).join(' - '));//80-900

http://jsfiddle.net/p4xjs9na/

答案 4 :(得分:0)

这里已经有了很好的答案。我用while循环来解决问题。该功能非常快,即使是非常大的数字,也可以在不到一秒的时间内返回值。

function padMaxValue(value)
{
    var i = 10;
    var counter = 0;
    var roundMax = 10;
    var copyValue = value;
    //If the value is negative, convert copyValue to positive
    if(value < 0) copyValue *= -1;
    while(roundMax <= copyValue)
    {
        roundMax += i;
        counter++;
        if(counter == 9)
        {
            i *= 10;
            counter = 0;
        }
    }
    if(value < 0) roundMax *= -1;
    return roundMax;
}
document.write(padMaxValue(8) + "<br>");
document.write(padMaxValue(77) + "<br>");
document.write(padMaxValue(889.65) + "<br>");
document.write(padMaxValue(-880.65) + "<br>");
document.write(padMaxValue(-765889.65) + "<br>");
document.write(padMaxValue(7888.88) + "<br>");
document.write(padMaxValue(88999887788899.099887) + "<br>");

输出:

10

80

900

-900

-800000

8000

900000亿

答案 5 :(得分:-1)

我不是数学家,但我认真对待编程!我提出了这个解决方案!

function getMax(max){
    var mCopy = max;
    var d=1;//Assuming everything is greater than 10, 
    while(Math.floor(mCopy) > 10){//if the number is not one digited 
        mCopy /= Math.pow(10,d);
        d++;
    }
    d--;//back one digit
    if(d<1)
       d++;
    if((Math.floor(max / Math.pow(10,d))*Math.pow(10,d))==max)
       return max;
    return Math.floor(max / Math.pow(10,d))*Math.pow(10,d) + Math.pow(10,d);
}

希望这有帮助

答案 6 :(得分:-1)

在我看来,给出的答案过于复杂。这是一个可以在MATLAB中使用的匿名函数:

next = @(x,n) ceil(x/n)*n;

>> next(11,10)    
ans =    
    20 %# 20 is the next "10" after "11")

>> next(110,100)    
ans =    
   200 %# 200 is the next "100" after "110"

>> next([98,253,87, 876,263],100)    
ans =    
   100   300   100   900   300

x是应处理的数字,n是请求的步长。

修改 确定下一个数量级的自动化也是可能的

>> nextOrder = @(x) ceil(x/10.^ceil(log10(x))) * 10.^ceil(log10(x));

>> nextOrder([98,253,87,876,263])    
ans =    
         100        1000         100        1000        1000