2012-04-29 5 views
0

Ребята, я делаю простой графический ящик и хочу найти красивые значения для горизонтальных линий. Например, если у меня есть значение равное 72089.601562, красивое 70000, или 75000. Так что, я думаю, что beautifulNumber% 5 = 0. У вас есть идеи?Round to "beautiful" value

+0

вы хотите округлить до ближайшей 5 000-й? –

+1

Methinks [NSNumberFormatter] (https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Fou...) будет работать. – CodaFi

+0

Округление должно быть динамическим. Например, 7 следует преобразовать в 10. – werbary

ответ

2

Как насчет этого?

#import <math.h> 
#import <stdio.h> 

#define ROUNDING 5000 

int beautify(float input) 
{ 
    // Cast to int, losing the decimal value. 
    int value = (int)input; 

    value = (value/ROUNDING) * ROUNDING; 

    if ((int)input % ROUNDING > ROUNDING/2) 
    { 
     value += ROUNDING; 
    } 

    return value; 
} 

int main() 
{ 
    printf("%d\n", beautify(70000.601562)); // 70000 
    printf("%d\n", beautify(72089.601562)); // 70000 
    printf("%d\n", beautify(76089.601562)); // 75000 
    printf("%d\n", beautify(79089.601562)); // 80000 
    printf("%d\n", beautify(70000.601562)); // 70000 

    return 0; 
} 
+0

это объектив-c?) – werbary

+3

Да. Функция 'beatify' является простой C, которую вы можете использовать в своем проекте Objective-C. Помните, что Objective-C - это просто C с некоторыми дополнениями. Если вы хотите, вы можете превратить его в метод Obj-C, но на самом деле нет необходимости. Вы можете сохранить его как функцию C, просто поместите его вне своего класса. – Joe

+0

Я попробую, спасибо. – werbary

1

Это зависит от того, хотите ли вы значение пола, значение потолка или просто округлять до ближайшего 5000.

Для значения пола:

int beautiful = (int)(floor(ugly/5000.0) * 5000.0);

Для значения потолка:

int beautiful = (int)(ceil(ugly/5000.0) * 5000.0);

Для округления:

int beautiful = (int)(round(ugly/5000.0) * 5000.0);

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

Например:

float minValue = 2.34; 
float maxValue = 7.72; 
int interval = 1; 
NSMutableArray *horizLines = [NSMutableArray array]; 
int line = (int)(floor(minValue/interval) * interval); 
[horizLines addObject:[NSNumber numberWithInt:line]]; 
do { 
    line = (int)(ceil(minValue/interval) * interval); 
    [horizLines addObject:[NSNumber numberWithInt:line]]; 
    if (minValue >= maxValue) break; 
    minValue = minValue + interval; 
} 

использовать по мере необходимости!

+0

Если уродливое число равно 0,3, то это будет работать? Я думаю, что нет. – werbary

+1

Что значит «не сработает»? В вашем примере вы говорили о округлении на 5000, и это то, что делают его примеры. –

+0

Я хочу динамическое округление для всех чисел. От 0.0000000003 до 99999 – werbary

0

Ну, похоже, вы хотите, чтобы он масштабировался в зависимости от размера номера. Если диапазон достигает 10, то, очевидно, округление до ближайших 5000 не имеет смысла. Там, наверное, действительно элегантный способ кодировать его, используя немного сдвигая, но только что-то вроде этого будет делать трюк:

float value = 72089.601562 
int beautiful = 0; 

// EDIT to support returning a float for small numbers: 
if (value < 0.2) beautiful = int(value*100)/100.; 
else if (value < 2.) beautiful = int(value*10)/10.; 

// Anything bigger is easy: 
else if (value < 20) beautiful = (int)value; 
else if (value < 200) beautiful = (int)value/10; 
else if (value < 2000) beautiful = (int)value/100; 
else if (value < 20000) beautiful = (int)value/1000; 
// etc 
+0

он возвращает полное число, но он должен быть делимым на 5, и ваш метод не работает для очень маленьких чисел. Например: 0.042. Красиво для него: 0.05 – werbary

+0

Это довольно тривиально расширить алгоритм для меньших значений ... – buildsucceeded

+0

да, но он возвращает только полное значение. Это не моя цель. – werbary

0

Похоже, что вы хотите сделать, это круглый 1 или, возможно, 2 значащих цифр. Округление до п значащих цифр довольно легко:

double roundToNDigits(double x, int n) { 
    double basis = pow(10.0, floor(log10(x)) - (n-1)); 
    return basis * round(x/basis); 
} 

Это даст вам roundToNDigits(74518.7, 1) == 70000.0 и roundToNDigits(7628.54, 1) == 8000.00

Если вы хотите, чтобы округлить до 1 или 2 цифр (только 2, где вторая цифра 5), вы хотите что-то вроде:

double roundSpecial(double x) { 
    double basis = pow(10.0, floor(log10(x)))/2.0; 
    return basis * round(x/basis); 
} 
+0

Aw man ... ты сделал это умным способом. – buildsucceeded