- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
countDigits :: (Integral a) => a -> Int
{-# INLINE countDigits #-}
countDigits v0 = go 1 (fromIntegral v0 :: Word64)
where go !k v
| v < 10 = k
| v < 100 = k + 1
| v < 1000 = k + 2
| v < 1000000000000 =
k + if v < 100000000
then if v < 1000000
then if v < 10000
then 3
else 4 + fin v 100000
else 6 + fin v 10000000
else if v < 10000000000
then 8 + fin v 1000000000
else 10 + fin v 100000000000
| otherwise = go (k + 12) (v `quot` 1000000000000)
fin v n = if v >= n then 1 else 0
Прям дельфи
Хаски к нам давно не заглядывал
Макросы - ни асилили.
Достаточно вспомнить объявление типа кортежа в стандартной библиотеке.
Там совсем макросов нет, или народ не использует? Где-то видел разговоры про #define, но либо это для констант, либо я ничего не понял, поскольку хаскель почти не знаю.
Тут, судя по всему, считают количество цифр в числе, причём операции деления экономят (т.к. целые числа могут быть любой длины), используют только в 18 строке и делят сразу на 1000000000000.
В коде имеется "обрубок числа" v и количество цифр k в обрубленной части. Когда число большое, от него отрезают по 12 разрядов, увеличивая k на 12. Когда остаётся менее 12 разрядов, в зависимости от раскидистых условий k увеличивается на нужное число.
константы вида 1000000000000 доставляют
Оптимизация, мать ее.
Можно было хотя бы константы привести к удобоваримому виду.
one ten hundreed... что ли ?:)
Если пофиг на скорость: countDigits = length . takeWhile (>0) . iterate (`div` 10)
Похоже на что-то вроде:
на первый взгляд - а не проще ли перевести в текст и работать с ним?
Может потому, что эта функция и используется для перевода в текст?