Trylog10(max(abs(число), 0,5)) + 1 округлено в меньшую сторону.
Или, в реальном синтаксисе C#:
(int)(Math.Log10(Math.Max(Math.Abs(number), 0.5)) + 1)
Хорошо, как это работает?
Во-первых, p = log10(x) — это основание 10 логарифм от x; то есть такое значение, что 10, возведенное в p-ю степень (или 1, за которой следуют p нули), равно x. Логарифм, по сути, измеряет длину числа, за исключением того, что это гладкая функция x:
(Обратите внимание, что в языках, которые не предоставляют функцию логарифмирования по основанию 10, мы всегда можем вычислить ее как log10(x) = log(x< /em>) / log(10), где log() — функция логарифмирования по любому основанию.)
Например, у нас есть
log10(1) = 0,0
log10(10) = 1,0
log10(100) = 2,0
log10(1000) = 3,0
но также, например:
log10(5) = 0,69897
log10(50) = 1,69897
log10(500) = 2,69897
log10(5000) = 3,69897
Как правило,n ≤ log10(x) ‹ n+1whenever10n< /em> ≤ x ‹ 10n+1.
Глядя на приведенные выше значения, должно быть достаточно легко увидеть, что, чтобы получить количество цифр по основанию 10 в целом числе, мы должны округлить его логарифм по основанию 10 до ближайшего целого числа и добавить 1 (потому что мы хотим длина 10 должна быть 2, а не 1).
Тем не менее, есть еще несколько крайних случаев, которые следует учитывать:
Во-первых, первоначальный вопросник хотел, чтобы длина x равнялась длине x. Логарифм определяется только для положительных чисел, поэтому мы заменяем x его абсолютным значением, чтобы оно всегда было положительным.
Во-вторых, первоначальный вопросник также хотел, чтобы длина чисел от 0 до 1 была равна нулю. Однако логарифм может принимать сколь угодно большие отрицательные значения:
log10(0,1) = 1,0
log10(0,01) = 2,0
log10(0,001) = 3,0
log10(0,0001) = 4,0
и действительно, log10(0) = . Чтобы удовлетворить этому требованию, мы просто удостоверимся, что число, длина которого мы вычисляем, никогда не может опускаться ниже 0,5, используя его максимум и 0,5 в качестве входных данных для журнал10(). (Мы могли бы использовать любое число от 0,1 до 1 в качестве порога, но 0,5 — это хорошая круглая двоичная дробь.)
Кроме того, мы должны добавить +1 к логарифму перед его округлением, чтобы округляемое число всегда было неотрицательным. Это связано с тем, что (int)
в C# фактически округляет отрицательные числа в большую сторону до нуля. Например, поскольку log10(0,5) 0,3, выражение (int)Math.Log10(0.5) + 1
(округление перед сложением) будет оцениваться как 0+1 = 1, а не как ожидаемый 0.
person
Ilmari Karonen
schedule
28.07.2011