2017-02-10 24 views
1

Я работаю над приложением статистики, и у меня есть проблема с округлением. Я хочу отобразить диаграмму с несколькими точками, все связанные с линиями. Чтобы настроить масштаб автоматически, я хочу выполнить какой-то расчет. Я понял, что делать, но я не могу правильно его перевести на код.Число округлений до ближайшего кратного 5 или 10 в том же диапазоне в зависимости от того, что первое

Итак, вот что я хочу сделать: Я просматриваю свой список значений, чтобы найти наибольшее значение. В моей графике у меня есть 6 опорных линий. Таким образом, я делю свое значение на единицы, а не на количество позиций, чтобы получить значение, которое (при умножении на фактическое количество позиций) будет больше, чем моя наибольшая сумма, так что моя строка не будет Не заходите за пределы моей графики.

Как только у меня есть это значение, мне нужно будет получить ближайшее целое число 5 или 10 (в зависимости от того, что на первом месте) в том же диапазоне.

Так, чтобы дать вам несколько примеров:

example 1: 
initial value = 685425 
divided value = 685425/5 = 137085 => rounded value = 150000 

example 2: 
initial value = 53 
divided value = 53/5 = 10.6 => rounded value = 15 

example 3: 
initial value = 8215 
divided value = 8215/5 = 1643 => rounded value = 2000 

Так что я всегда округлением до ближайшего кратного 5 или 10, но в том же диапазоне.

Как я могу поместить это в код?

Спасибо, Кеннет

ответ

1
public static int GetLimit(int v) 
{ 
    int by5 = v/5; 

    // for too small numbers we return early 
    if (by5 < 0) return 0; 
    if (by5 < 5) return 5; 
    if (by5 < 10) return 10; 

    int log = (int)Math.Log10(by5) - 1; 
    int scope = (int)Math.Pow(10, log); 
    int tmp = by5/scope; 
    tmp = 5 * ((tmp/5) + 1); 
    return tmp * scope; 
} 

Это использует десятичный логарифм, чтобы получить "диапазон" (scope). Затем он делит число на эту область, чтобы получить первые две цифры, «округляет» их до следующего кратного 5 (5*((tmp/5) + 1)) и снова умножается на область, чтобы вернуться в диапазон.

Для слишком маленьких номеров (ниже 50) оно возвращается раньше, потому что scope станет 0, что приведет к DivideByZeroException.

Console.WriteLine(GetLimit(685425)); 
Console.WriteLine(GetLimit(53)); 
Console.WriteLine(GetLimit(8215)); 
Console.WriteLine(GetLimit(11)); 
Console.WriteLine(GetLimit(2)); 

приводит к

150000 
15 
2000 
5 
5 

альтернативы использованию Math.Log и Math.Pow бы, чтобы преобразовать разделенное число в строке работу с thefirst два цифр и длиной. Я не тестировал, может ли это быть быстрее, но я так не думаю. Если это критическая производительность, вам нужно будет ее протестировать.