Округлить до (1, 2 или 5) x 10 ^ n в Objective-C? - PullRequest
13 голосов
/ 16 июня 2011

Существует ли простой способ округления значения до или до ближайшего значения (1, 2 или 5) x 10 ^ n, где n - целое число?Как в одном из {..., .05 .1, .2, .5, 1, 2, 5, 10, 20, 50, 100 ...}

Спасибо.

Ответы [ 4 ]

14 голосов
/ 16 июня 2011

Вы можете взять d=floor(log10(n)) вашего номера n, чтобы получить шкалу, а затем разделить на 10 до d, чтобы нормализовать число в диапазоне [1.0,10.0). С этого момента должно быть легко округлить, потому что есть очень ограниченные возможности. Как только вы это сделаете, умножьте на 10 до d, чтобы восстановить исходный диапазон.

Следующая функция в C, я не знаю достаточно о Objective-C, чтобы знать, идиоматична ли она.

double RoundTo125(double value)
{
   double magnitude;
   magnitude = floor(log10(value));
   value /= pow(10.0, magnitude);
   if (value < 1.5)
      value = 1.0;
   else if (value < 3.5)
      value = 2.0;
   else if (value < 7.5)
      value = 5.0;
   else
      value = 10.0;
   value *= pow(10.0, magnitude);
   return value;
}
7 голосов
/ 16 июня 2011

Чтобы округлить x до ближайшего значения c * 10^n, используйте

f(c) = c * 10^(floor(log(x/c)))

(при условии x положительно). Чтобы округлить до ближайшего из них, просто найдите

max(f(1), f(2), f(5))

Чтобы округлить x до ближайшего значения c * 10^n, используйте

g(c) = c * 10^(ceiling(log(x/c)))

(снова при условии, что x положительно). Чтобы округлить до ближайшего из них, просто найдите

min(g(1), g(2), g(5))

Теперь, чтобы просто округлить до ближайшего из этих значений, найдите ближайшее округление вниз (первый абзац) и ближайшее округление вверх (второй абзац) и выберите тот, который ближе к x.

0 голосов
/ 16 июня 2011

Подойдет логарифмический подход, но я бы поэкспериментировал с преобразованием строк. Я не знаю Цель C, хотя Google подразумевает, что вы хотите что-то под названием stringWithFormat. В Java код будет

String s = String.format("%f", theNumber);
StringBuffer buf = new StringBuffer(s);
int len = buf.length()-1;
char c = buf.getCharAt(len);
switch (c)
{
case '9': case '8': case '7': case '6':
buf.setCharAt(len) = '5'; break;
case '4' : case '3':
buf.setCharAt(len) = '2' break;
default: break; /* don't change '0', '1', '2', '5' */
}
double roundNumber = Double.parseDouble(buf.toString());

Может быть быстрее. (Возможно, будет медленнее!) Вы также можете попытаться найти в строке десятичную точку и вычесть приращение из исходного числа, как только вы зададите величину последнего десятичного знака.

0 голосов
/ 16 июня 2011

Как я вижу, вы работаете с числами с плавающей запятой.Я хочу отметить, что в стандартной библиотеке C есть две функции, которые могут вам помочь:

double floor(double); //round down
double ceil(double);  //round up

Они возвращают округленное числоТакже есть еще функции округления.Вы можете найти ссылку на них здесь .После того, как вы узнаете, как они работают, вы можете написать свою собственную функцию округления.Который будет использовать нормализацию.Посмотрите на пример:

// this function will round to tens
float my_floor(float d)
{
    return floor(d/10)*10;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...