jhanna has asked for the wisdom of the Perl Monks concerning the following question:

This ought to be really easy, but i haven't found it in the docs. I need the log of a Math::BigInt number. Precision isn't important -- honestly all I really want is the number of bits requred for the bigint. I figured I could do:

$bits=int(log($bigint)/log(2))+1;

But, alas, Math::BigInt doesn't have log overloaded and I can't figure how to convert a bigint back to a float. :-(

Replies are listed 'Best First'.
Re: bigint - float?
by sifukurt (Hermit) on Nov 23, 2001 at 20:19 UTC
    If I understand your problem, then this works with the newest version of Math::BigInt. I'm fairly certain that it won't work with some earlier versions. I seem to remember having trouble with this sort of thing in the past.
    $x = Math::BigInt->bstr( $bigint ); $bits = int( log( $x ) / log( 2 ) ) + 1;
    ___________________
    Kurt
      I'm using whatever BigInt came with ActivePerl... It's likely not the latest. It does occur to me that I can probably do something like:

      $bits=int((length($bigint)-1) * 3.3219)+1;

      where 3.3219 is log(10)/log(2) and the length of $bigint is relatively large assuming that length($bigint) returns the length of the string / ie number of decimals.

      It also occurred to me that I could do a manual conversion to float by something like this:

      $float=substr($bigint,1,1).'.'.substr($bigint,2).'e'.(length($bigint)-2);

      where the point is to create a float string value out of the bigint string value...

      Either of these might work, but they're a bit ugly...

      j

        As long as you have a fairly recent ActivePerl, you should be ok. I think only relatively old versions of Math::BigInt did weird things sometimes with bstr(). The newest version of Math::BigInt installs like a charm on a Win32 system, btw. So either way, you might be better off installing the newest version.
        ___________________
        Kurt
Re: bigint - float?
by Zaxo (Archbishop) on Nov 24, 2001 at 00:55 UTC

    You can get what you want directly, without log(), using some bit-twiddling:

    my $the_num = Math::BigInt->new(1234567890123545678); sub numbits { my $tester = Math::BigInt->new(shift); my $i = 0; do {$i++} while ($tester >>= 1); $i; } print numbits($the_num);

    After Compline,
    Zaxo

      Hmm... I like the idea. It replaces a series of complex string operations with a simple loop. I'll have to run some benchmarks to see which is faster. But I do like this approach.