in reply to Power of two round up.

With a little help from POSIX, and remembering some basics about polyadic number systems, i.e. with the help of the natural logarithm, an IMHO straightforward implementation can be made:

use POSIX qw(ceil); sub powround { my ( $x, $base ) = @_; return ( $base ** ceil(log($x)/log($base))); }

That is, ln(a) / ln(b) gives you the number of digits needed to represent the number a relative to the base b (and ln() is the natural logarithm, i.e. to the base e (Euler's number)).

Then round that up to the next greater or equal integer (POSIX::ceil), and exponentiate the base with it. Voilą, you have the next greater or equal power of the base.

p.s.: using `POSIX::ceil` covers all corner cases, whereas using `int(...) + 1` as suggested in previous responses, does not.

Replies are listed 'Best First'.
Re^2: Power of two round up.
by syphilis (Archbishop) on Aug 27, 2023 at 01:03 UTC
    ...and ln() is the natural logarithm

    Note that it doesn't have to be the natural logarithm. You can use a log to any base.
    D:\>perl -MPOSIX="log10,log2" -le "$r1=log(1234)/log(2);$r2=log10(1234 +)/log10(2);$r3=log2(1234)/log2(2);print $r1; print $r2; print $r3;" 10.269126679149417887862906163471 10.269126679149417887862906163471 10.269126679149417887862906163471
    Cheers,
    Rob

      You can use a log to any base, indeed, for as long as you use the same base for both dividend and divisor.

      And, coincidentally, the log to the base Euler's number is the only one one available as part of core Perl. So as to minimize the readers' confusion, I opted to using that.