Как я могу получить следующий самый высокий кратный 5 или 10 - PullRequest
3 голосов
/ 23 ноября 2011

Из данного double Я хочу получить следующее наибольшее число в соответствии с некоторыми правилами, которые, поскольку у меня возникли трудности с их описанием, я проиллюстрирую примерами:

Input      Desired output
-------    --------------
   0.08         0.1
   0.2          0.5
   5           10
   7           10
  99          100
 100          500
2345         5000

Вывод должен бытьв некотором смысле «следующий по величине кратный 5 или 10».

Надеюсь, это понятно;если нет, дайте мне знать.

Реализация будет в Java, и ввод будет положительным double s.

Ответы [ 4 ]

4 голосов
/ 23 ноября 2011
function top5_10 (x) {
  var ten = Math.pow(10, Math.ceiling(Math.ln(x)/Math.LN10)));
  if (ten > 10 * x) { ten = ten / 10; }
  else if (ten <= x) { ten = 10 * ten; }
  return x < ten / 2 ? ten / 2 : ten;
}

или как-то так: -)

2 голосов
/ 23 ноября 2011

Псевдокод должен выглядеть примерно так:

If number > 1
    n = 1
    While(true)
        If(number < n)
            return n
        If(number < n*5)
            return n*5
        n = n*10
Else
    n = 1.0
    While(true)
        If(number > n/2)
            return n
        If(number > n/10)
            return n*2
        n = n/10.0

Для чисел> 1 он проверяется следующим образом: если <5, 5. если <10, 10, если <50, 50. Для чисел<1, проверяется следующим образом: если> 0,5 1. если> 0,1, 0,5.и т.д.

2 голосов
/ 23 ноября 2011

Вот функция, которая работает с образцами данных:

def f(x):
    lx = log10(x)
    e = floor(lx)
    if (lx - e) < log10(5):
        return 5 * 10 ** e
    else:
        return 10 ** (e+1)
0 голосов
/ 23 ноября 2011

Если вы намереваетесь использовать удвоения и хотите получить точный результат, все методы, использующие умножение / деление / log10 с двойной точностью, не работают (или, по крайней мере, сложны в реализации и подтверждают правильность). Здесь может помочь арифметика с высокой точностью. Или воспользуйтесь поиском так:

powers = [1.e-309, 1.e-308, ..., 1.e309]
p = search_first_greater(powers, number)
if (number < p / 2.) return p / 2.
return p

search_first_greater может быть реализован как:

  • линейный поиск,
  • или бинарный поиск,
  • или прямой расчет индекса массива по n=round(log10(number)) и проверка только powers[n-1 .. n]
  • или с использованием логарифмической аппроксимации, такой как вырезание части степени из числа и проверка 4 элементов степеней [].
...