How to increase the value of a number to the next multiple of 10, 100, 1000, 10000, etc.

You will have to forgive the wording of this question, I am sure that there is a better, more concise way to ask about it, but I do not know this.

Say I have a graph and all the y axis values

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

The maximum value is six. Therefore, I would like the Y-scale to be labeled from 0 to 10.

Given the following values

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

The maximum value is 86, so I would like the Y-scale to run from 0 to 90.

Now let's say that I have the following values

[98,253,87, 876,263]

The maximum is 876, so the Y scale should go from 0 to 900

Now I have created the following function, which should give me all the max y-scale values ​​that I need so far.

 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; } } } 

However, given the following values

[99,123,82,189,45]

My function would set max. max at 1000 . But max should really be 200. I understand that I really need a smart way to increase the value of i instead of just multiplying it by 10. I need to be able to increase the value of i by 10, all the way to 100. Then increase it by 100, right up to 1000. Then increase it by 1000, up to 10 000 and so on.

I feel that there must be some neat and tidy mathematical way to do this. And I also feel that the number 1000000000000000000 that I have in the for loop betrays my ignorance of mathematics.

Anyhoot, this problem. Any ideas?

+42
javascript math max
Oct 30 '14 at 19:48
source share
7 answers

There is no need to go into the ground of strings, which can be inconvenient if you have ever had a decimal value.

 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)); 

Outputs: 0 -10 .

EDIT Updated to reflect comments. Now works even in IE8.

+82
Oct 30 '14 at 20:26
source share
β€” -

I don't like math, so here is a pretty simple / fun solution for handling strings:

Find the maximum value:

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

Take the first character

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

Make it an integer and add 1

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

Convert it back to string:

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

Add to it N - 1 zeros, where N is the length of your original number:

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

Convert it back to an integer:

 c = (c | 0) // 900 

Done!




Seriously, use math .

+22
Oct 30 '14 at 20:03
source share

I believe this would do the trick for you:

 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; 

Basically what happens above:

  • Find the maximum sample
  • Get the maximum length of the values, and then raise it to a power of 10 ie 345, length = 3, so the coefficient is 100
  • Make sure we do not divide by 0
  • Divide the maximum number by a factor to get the decimal number, and take the ceiling of that number, then multiply it by a factor to get the desired number 0.

UPDATE: If you want to find the minimum value (for negative values), just flip Math.ceil to Math.floor . You must also accept the absolute minimum value to make sure that you do not count the negative character as part of the string.

 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; 

UPDATE 2:. As many people note in the comments, we should not use string manipulations. I updated the code to use logarithms.

+11
Oct 30 '14 at 20:02
source share

I ended up with:

 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/

+3
30 Oct '14 at 20:12
source share

There are already good answers here. I used a while loop to solve the problem. The function is very fast, and it can return a value in less than a second even for a very large number.

 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>"); 

Output:

10

80

900

-900

-800000

8000

90000000000000

0
Nov 19 '17 at 0:52
source share

I do not really like math, but I am serious about programming! I came up with this solution!

 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); } 

Hope this helps

-one
Nov 05 '14 at 6:25
source share

In my opinion, these answers are too complicated. Here is an anonymous function that can be used in 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 is the number to be processed, and n is the required step size.

change It is also possible automation to determine the next order of magnitude

 >> nextOrder = @(x) ceil(x/10.^ceil(log10(x))) * 10.^ceil(log10(x)); >> nextOrder([98,253,87,876,263]) ans = 100 1000 100 1000 1000 
-one
Nov 05 '14 at 7:56
source share



All Articles