Подтвердить что ты не робот

Как увеличить значение числа до следующего кратного 10, 100, 1000, 10000 и т.д.

Вам придется простить формулировку этого вопроса, я уверен, что есть лучший, более лаконичный способ спросить об этом, но я этого не знаю.

Скажем, у меня есть график, и все значения оси y

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

Максимальное значение - шесть. Поэтому я хотел бы, чтобы Y-масштаб был помечен от 0 до 10.

Учитывая следующие значения

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

Максимальное значение - 86, поэтому я хотел бы, чтобы Y-масштаб выполнялся от 0 до 90.

Теперь скажем, что у меня есть следующие значения

[98,253,87, 876,263]

Максимум составляет 876, поэтому шкала Y должна идти от 0 до 900

Теперь я создал следующую функцию, которая должна дать мне все значения max 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]

Моя функция установила бы макс. макс в 1000. Но max должен быть действительно 200. Я понимаю, что мне действительно нужен умный способ увеличить значение i вместо того, чтобы просто умножить его на 10. Мне нужно уметь увеличивать значение я на 10, все путь до 100. Затем увеличьте его на 100, вплоть до 1000. Затем увеличьте его на 1000, вплоть до 10 000 и так далее.

Я чувствую, что должен быть какой-то аккуратный и аккуратный математический способ сделать это. И я также чувствую, что число 1000000000000000000, которое я имею в цикле for, предает моему незнанию математики.

Anyhoot, эта проблема. Любые идеи?

4b9b3361

Ответ 1

Нет необходимости заходить в землю струн, что может быть неудобно, если вы когда-либо имели десятичное значение.

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.

EDIT Обновлено с учетом комментариев. Теперь работает даже в IE8.

Ответ 2

Мне не нравится математика, поэтому вот довольно простое/веселое решение для обработки строк:

Найти максимальное значение:

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

Готово!


Серьезно, использовать математику.

Ответ 3

Я считаю, что это сделало бы трюк для вас:

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; 

В основном, что происходит выше:

  • Найти максимум образца
  • Получите максимальную длину значений, а затем поднимите ее на мощность 10 i.e 345, length = 3, поэтому коэффициент равен 100
  • Убедитесь, что мы не делим на 0
  • Разделите максимальное число на коэффициент, чтобы получить десятичное число, и возьмите потолок этого числа, затем умножьте его на коэффициент, чтобы получить нужное число 0.

ОБНОВЛЕНИЕ: Если вы хотите найти минимальное значение (для отрицательных значений), просто переверните 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:. Как замечают многие люди в комментариях, мы не должны использовать строковые манипуляции. Я обновил код, чтобы использовать логарифмы.

Ответ 4

Я закончил с:

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/

Ответ 5

Здесь уже есть хорошие ответы. Я использовал цикл 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

90000000000000

Ответ 6

Я не очень люблю математику, но серьезно отношусь к программированию! Я придумал это решение!

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

Надеюсь, что это поможет

Ответ 7

По-моему, данные ответы слишком сложны. Вот анонимная функция, которая может использоваться в 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