On 2022-11-03, Lieven Marchand <
m...@wyrd.be> wrote:
> James Cloos <
cl...@jhcloos.com> writes:
>
>> does cl offer a better way to do? :
>>
>> (defun decimal-length (+integer)
>> (length (format nil "~d" +integer)))
>
> One can argue about better but (1+ (floor (log +integer 10))) would also
> work.
Here is another idea. Let's restrict to nonnegative integers.
Or, well, I see that's already implied by the +integer naming.
Further, let's suppose we just need an lower bound on the number of
digits, but one that is fairly tight: say not excessive by more than 1.
To get that we can avoid taking a logarithm of an integer, which could
be a bignum.
We can use integer-length to get the number of binary digits, and
then estimat the decimal digits required to represent that many
binary digits.
There are (/ (log 10) (log 2)) binary digits in a decimal digit,
so we just have to divide by this value and make a little adjustment.
Or let's reciprocate it:
(defconstant %bit-digits% (/ (log 2) (log 10)))
(defun decimal-length (+integer)
(coerce (ceiling (* (integer-length +integer) %bit-digits%)) 'integer))
(loop for i = 3 then (coerce (truncate (* i (sqrt 2))) 'integer)
while (< i 100000000)
do (format t "~s ~s~%" i (decimal-length i)))
3 1
4 1
5 1
7 1
9 2
12 2
16 2
22 2
31 2
43 2
60 2
84 3
118 3
166 3
234 3
330 3
466 3
659 4
931 4
1316 4
1861 4
2631 4
3720 4
5260 4
7438 4
10518 5
14874 5
21035 5
29747 5
42068 5
59493 5
84135 6
118984 6
168268 6
237966 6
336534 6
475930 6
673066 7
951859 7
1346131 7
1903716 7
2692261 7
3807432 7
5384522 7
7614864 7
10769044 8
15229728 8
21538088 8
30459456 8
43076176 8
60918912 8
86152352 9
Floating-point could be eliminated if we use a rational approximation
for the factor.
--
TXR Programming Language:
http://nongnu.org/txr
Cygnal: Cygwin Native Application Library:
http://kylheku.com/cygnal