Формула для возврата бина 10-го или 100-го - PullRequest
0 голосов
/ 12 июня 2010

Мне нужна функция, которая должна дать мне 10-й или 100-й массив, например,

  • Если я пройду 5, он должен вернуть от 1 до 10
  • Если я пройду 67, он должен вернуть от 1 до 100
  • Если я пройду 126, он должен вернуть 101 к 200
  • Если я пройду 2524, он должен вернуть 2001 к 3000

Любое руководство?

Ответы [ 4 ]

5 голосов
/ 12 июня 2010

Другие люди дают вам хорошие ответы, но я не уверен, что они подчеркивают важный принцип, а именно:

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

База 10 журналов более или менее отвечает на вопрос "На какую наибольшую степень 10 делится это число?"или "Сколько раз я мог бы разделить это число на 10, прежде чем оно станет меньше единицы?"

Вы можете написать функцию, которая отвечает на этот вопрос вручную, конечно:

function divsBy10(n) {
   var i = 0;
   while(n > 1) {
     n = n/10;
     i++;
   }
   return i-1;
}

И издержки не будут высокими.Хотя я бы догадался немного быстрее использовать встроенные математические функции.Конечно, это не похоже на то, как если бы вы получили исходную базу журналов 10 в Actionscript ... похоже, Math.log - это естественный журнал (база журналов e).Есть математическая идентичность, которая говорит log_10 x = log_e x / log_e 10 ... и ActionScript действительно дает вам log_e 10 как константу (Math.LN10).Итак,

function log10(n) {
   return Math.log(n)/Math.LN10;
}

Теперь log10 не даст целочисленного ответа на вопросы, которые я упомянул выше («Сколько раз я мог бы разделить n на 10, прежде чем он станет меньше 1?»), Потому что на самом деле этообратное значение 10 ^ n, но неотъемлемая часть возвращаемого значения будет ответом на этот вопрос.Поэтому вам нужно выполнить Math.floor для значения, которое вы получите от него, и оттуда выполнить различные вычисления, которые вам понадобятся, чтобы получить конкретные диапазоны массивов, которые вам нужны.

3 голосов
/ 12 июня 2010

Это дает вам то, что вы просили:

function FunkyRange (TargNum)
{
    var OrderOfMag      = Math.floor (Math.log (TargNum-1) / Math.LN10);

    var NaturalLimLow   = Math.pow (10, OrderOfMag);
    var AdjustedLimLow  = Math.floor ((TargNum-1) / NaturalLimLow) * NaturalLimLow + 1;

    var AdjustedLimHigh = NaturalLimLow + AdjustedLimLow - 1;

    //-- Handle special cases For TargNum <= 10 and <= 100.

    if (AdjustedLimLow  <= 100)
        AdjustedLimLow  = 1;

    if (AdjustedLimHigh <= 10)
    {
        AdjustedLimHigh = 10;
    }
    else
    {
        if (AdjustedLimHigh < 100)
            AdjustedLimHigh = 100;
    }


    return [AdjustedLimLow, AdjustedLimHigh];
}

Что возвращает:

Input       Lim, Low     Lim, High
-----      ----------   -----------
   5             1           10
  67             1          100
  99             1          100
 100             1          100
 126           101          200
 200           101          200
 299           201          300
 473           401          500
2524          2001         3000
2 голосов
/ 12 июня 2010

Как отметили комментаторы, ваши диапазоны не совсем согласованы. Вот моя интерпретация, где 67 дает 61-70:

function range(n) {
    var digits = Math.ceil(Math.log(n) / Math.LN10);
    var spread = Math.max(Math.pow(10, digits - 1), 10);
    var low    = Math.floor((n - 1) / spread) * spread;
    var high   = low + spread;

    return [low + 1, high];
}

Результаты, включая некоторые крайние случаи:

5:    [1, 10]
67:   [61, 70]
126:  [101, 200]
2524: [2001, 3000]
100:  [91, 100]
1000: [901, 1000]
999:  [901, 1000]
1 голос
/ 12 июня 2010
p = floor(log10(N))
range = 10^p
base = floor(N/range) * range

например

  log10(258) => 2.4
  floor(2.4) => 2
  range := 10^2 => 100
  base := floor(258/100)*100 => 200

(за исключением того, что предполагается, что для 67 вы действительно хотите 60..70)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...