Extracting bits out of huge numbers

Discussion in 'Perl Misc' started by hofer, Jul 29, 2008.

  1. hofer

    hofer Guest

    Hi,

    I'd like to work with huge integers (> 64 bit precision)

    Thus I can't use ordinary perl integers.

    I thought Math::BigInt wouldn't be a too bad choice.


    It's easy enough go create BigInts.
    my $a = Math::BigInt->new("0x7777666655544443333222211110000");
    my $b = Math::BigInt->new("0x1111111111111111111111111111111");

    Calculating with them is also fine:
    $a->badd($b); # $a = $a + $b


    Now I would like to extract certain bits out of this huge number:

    Example Bits 16 bis 12 should result in 0b00001 == 0x1 == 1
    Bits 17 bis 12 should result in 0b100001 == 0x21 == 33



    So far I see two ways of doing this conversion.

    However I'm not really appealed by either solution.

    Do you know anything faster / better or even another CPAN module?

    # extract bits out of binary string
    sub extbits { #
    my ($val,$msb,$lsb) = @_; # $val must be Math::BigInt;
    my $asbinstr = $val->as_bin(); # nun als binaer string
    my $withoutprefix = substr($asbinstr,2); # fuehrendes '0b'
    entfernen
    my $substr = substr($withoutprefix,-$msb-1,$msb-$lsb+1); # den
    substring extrahieren
    $substr = 0 if $substr eq ""; # sollte mindestens einen character
    enthalten
    my $result = Mat::BigInt->new("0b".$substr); # zurueck in
    Math::BigInt verwandeln
    return $result;
    } #

    # extract bits via shifts operations follwed by a bit wise and
    sub extbits { #/*{{{*/
    my ($val,$msb,$lsb) = @_; # $val must be Math::BigInt;
    my $mask = Math::BigInt->new(1); # create a 1
    $mask->blsft($msb-$lsb+1); # 2 ^ (number of bits to extract)
    $mask->bsub(1); # now we have a mask
    my $tmp = $val->copy->brsft($lsb); # shift input value to the
    right
    return $tmp->band($mask);
    } #/*}}}*/



    Thanks in advance for any other suggestions
    like rewriting the function to accelerate it or using another module.


    bye


    H
     
    hofer, Jul 29, 2008
    #1
    1. Advertising

  2. hofer

    sisyphus Guest

    On Jul 29, 10:28 pm, hofer <> wrote:
    > Hi,
    >
    > I'd like to work with huge integers (> 64 bit precision)
    >
    > Thus I can't use ordinary perl integers.
    >
    > I thought Math::BigInt wouldn't be a too bad choice.
    >
    > It's easy enough go create BigInts.
    > my $a = Math::BigInt->new("0x7777666655544443333222211110000");
    > my $b = Math::BigInt->new("0x1111111111111111111111111111111");
    >
    > Calculating with them is also fine:
    > $a->badd($b); # $a = $a + $b
    >
    > Now I would like to extract certain bits out of this huge number:
    >
    > Example Bits 16 bis 12 should result in  0b00001 == 0x1 == 1
    >             Bits 17 bis 12 should result in 0b100001 == 0x21 == 33
    >
    > So far I see two ways of doing this conversion.
    >
    > However I'm not really appealed by either solution.
    >
    > Do you know anything faster / better or even another CPAN module?
    >


    Math::GMP will allow you to access individual bits. I would expect it
    to be siginificantly faster than Math::BigInt, though I haven't done
    any benchmarking.

    use warnings;
    use Math::GMP;

    $x = Math::GMP->new('12344' x 7);

    # print the 10 least siginificant bits:

    print Math::GMP::gmp_tstbit($x, $_) for reverse(0..9);
    print "\n";

    Cheers,
    Rob
     
    sisyphus, Jul 30, 2008
    #2
    1. Advertising

  3. hofer

    hofer Guest

    On Jul 30, 1:23 am, "Thrill5" <> wrote:
    > "hofer" <> wrote in message
    >
    > news:...
    >
    >
    >
    > > Hi,

    >
    > > I'd like to work with huge integers (> 64 bit precision)

    >
    > > Thus I can't use ordinary perl integers.

    >
    > > I thought Math::BigInt wouldn't be a too bad choice.

    >
    > > It's easy enough go create BigInts.
    > > my $a = Math::BigInt->new("0x7777666655544443333222211110000");
    > > my $b = Math::BigInt->new("0x1111111111111111111111111111111");

    >
    > > Calculating with them is also fine:
    > > $a->badd($b); # $a = $a + $b

    >
    > > Now I would like to extract certain bits out of this huge number:

    >
    > > Example Bits 16 bis 12 should result in 0b00001 == 0x1 == 1
    > > Bits 17 bis 12 should result in 0b100001 == 0x21 == 33

    >
    > > So far I see two ways of doing this conversion.

    >
    > > However I'm not really appealed by either solution.

    >
    > > Do you know anything faster / better or even another CPAN module?

    >
    > > # extract bits out of binary string
    > > sub extbits { #
    > > my ($val,$msb,$lsb) = @_; # $val must be Math::BigInt;
    > > my $asbinstr = $val->as_bin(); # nun als binaer string
    > > my $withoutprefix = substr($asbinstr,2); # fuehrendes '0b'
    > > entfernen
    > > my $substr = substr($withoutprefix,-$msb-1,$msb-$lsb+1); # den
    > > substring extrahieren
    > > $substr = 0 if $substr eq ""; # sollte mindestens einen character
    > > enthalten
    > > my $result = Mat::BigInt->new("0b".$substr); # zurueck in
    > > Math::BigInt verwandeln
    > > return $result;
    > > } #

    >
    > > # extract bits via shifts operations follwed by a bit wise and
    > > sub extbits { #/*{{{*/
    > > my ($val,$msb,$lsb) = @_; # $val must be Math::BigInt;
    > > my $mask = Math::BigInt->new(1); # create a 1
    > > $mask->blsft($msb-$lsb+1); # 2 ^ (number of bits to extract)
    > > $mask->bsub(1); # now we have a mask
    > > my $tmp = $val->copy->brsft($lsb); # shift input value to the
    > > right
    > > return $tmp->band($mask);
    > > } #/*}}}*/

    >
    > > Thanks in advance for any other suggestions
    > > like rewriting the function to accelerate it or using another module.

    >
    > > bye

    >
    > > H

    >
    > How about using 'unpack'?


    Hi, Thrill5,

    Thanks for the answer.

    If I don't miss something, then pack and unpack allow to (hmmm) pack
    and
    unpack binary strings into a byte structure.

    My second requirement is to perform operations like + - * / and or xor
    % on these numbers.
    I think this wouldn't be possible.

    bye

    H
     
    hofer, Jul 31, 2008
    #3
  4. hofer

    hofer Guest

    Hi sisiphus,

    I'll look at Math::GMP

    In the doc I saw an interesting suggestion, which is to use
    Math::BigInt, but let it use the faster libraries of Math::GMP.

    This means probably, that I would run faste, but would stay backwards
    compatible for the ones not having Math::GMP.

    The suggested use statement is:

    use Math::BigInt lib => 'GMP';

    The function Math::GMP::gmp_tstbit() sounds very appealing to test a
    few
    bits of a big number.

    However if I want to extract for example bits [967:13] , then the
    approach to shift to the right and logical and then with a mask might
    be
    faster.
    I have to try.


    thanks and bye


    H


    On Jul 30, 4:12 am, sisyphus <> wrote:
    > On Jul 29, 10:28 pm, hofer <> wrote:
    >
    >
    >
    > > Hi,

    >
    > > I'd like to work with huge integers (> 64 bit precision)

    >
    > > Thus I can't use ordinary perl integers.

    >
    > > I thought Math::BigInt wouldn't be a too bad choice.

    >
    > > It's easy enough go create BigInts.
    > > my $a = Math::BigInt->new("0x7777666655544443333222211110000");
    > > my $b = Math::BigInt->new("0x1111111111111111111111111111111");

    >
    > > Calculating with them is also fine:
    > > $a->badd($b); # $a = $a + $b

    >
    > > Now I would like to extract certain bits out of this huge number:

    >
    > > Example Bits 16 bis 12 should result in 0b00001 == 0x1 == 1
    > > Bits 17 bis 12 should result in 0b100001 == 0x21 == 33

    >
    > > So far I see two ways of doing this conversion.

    >
    > > However I'm not really appealed by either solution.

    >
    > > Do you know anything faster / better or even another CPAN module?

    >
    > Math::GMP will allow you to access individual bits. I would expect it
    > to be siginificantly faster than Math::BigInt, though I haven't done
    > any benchmarking.
    >
    > use warnings;
    > use Math::GMP;
    >
    > $x = Math::GMP->new('12344' x 7);
    >
    > # print the 10 least siginificant bits:
    >
    > print Math::GMP::gmp_tstbit($x, $_) for reverse(0..9);
    > print "\n";
    >
    > Cheers,
    > Rob
     
    hofer, Jul 31, 2008
    #4
  5. hofer

    hofer Guest

    Hi Bugbear,

    I'm not that gifted in explaining, but I t'll try.

    First if your question concerns the representation of binary numbers:
    Then look at http://en.wikipedia.org/wiki/Binary_numeral_system

    Second:
    ust a small example however just with 8 bit numbers.
    Please keep in mind, that I really want to work with really big
    numbers.

    well an unsigned 8 bit number can have values from
    0 to 255

    The number 26 for example would be represented as
    00011010 in binary format
    For small numbers I could just use
    printf("%08b",26) to get the binary string
    # result should be 00011010

    going from binary string representation to decimal could be done with
    the oct() function
    I just have to prefix the bit string with "0b" and pass it to the
    oct() function.
    print oct("0b"."00011010");
    # result shoud be 26

    the bits of this number are number from right to left so the bt on the
    right is bit 0 and the bit on the left is bit7
    the number 26

    would have
    bit 0 = 0
    bit 1 = 1
    bit 2 = 0
    bit 3 = 1
    bit 4 = 1
    bit 5 = 0
    bit 6 = 0
    bit 7 = 0

    if I want to extract bits 4 to bits 2 from my number 26 it would mean
    taking
    bit 2 = 0
    bit 3 = 1
    bit 4 = 1
    which is 110 or 0b110 (0b marks a binary number in perl)
    and would be equivalent to number 6 in decimal.

    so I could do for example

    $num = 26; #
    $size=8; # tha value has a max size of 8 bits
    $bitfrom=4;
    $bitto=2;
    $bitstring = sprintf("%0%sizeb",$num); # -> "00011010"
    # the first character in this string is bit 7, tha last one is bit 0
    so to get bits 4 to 2 I could now do
    $bits4to2 = substr($bitstring,-$from,$from-$to+1); # -> "110"
    $num4to2 = oct("0b".$bits4to2); # -> 6

    I hope that clarified a little.

    bye H


    On Jul 30, 10:32 am, bugbear <bugbear@trim_papermule.co.uk_trim>
    wrote:
    > hofer wrote:
    > > Hi,

    >
    > > Now I would like to extract certain bits out of this huge number:

    >
    > > Example Bits 16 bis 12 should result in 0b00001 == 0x1 == 1
    > > Bits 17 bis 12 should result in 0b100001 == 0x21 == 33

    >
    > I don't understand your examples :-(
    >
    > BugBear
     
    hofer, Jul 31, 2008
    #5
  6. hofer

    Ben Morrow Guest

    Quoth bugbear <bugbear@trim_papermule.co.uk_trim>:
    > hofer wrote:
    > >>
    > >>Example Bits 16 bis 12 should result in 0b00001 == 0x1 == 1
    > >> Bits 17 bis 12 should result in 0b100001 == 0x21 == 33

    >
    >
    > what do you mean by
    > "Bits 16 bis 12"
    >
    > and
    >
    > "Bit 17s bis 12"
    >
    > what is "bis" ?


    'To' in English, 'through' or 'thru' in American. So, the OP wishes to
    look at only the bits from bit 16 to bit 12; something like

    my $num = ...;

    my $mask = 0;
    $mask |= 1<<$_ for 12..16;
    $num &= $mask;
    $num >>= 12;

    would do what he wants, but slowly, and with small(ish) integers only.

    Ben

    --
    And if you wanna make sense / Whatcha looking at me for? (Fiona Apple)
    * *
     
    Ben Morrow, Jul 31, 2008
    #6
  7. hofer

    hofer Guest

    Apologies,


    I posted the same message to a German and en ENglish news group.
    'bis' is the word I forgot to translate to Englisch :-( shame on me.



    I wanted to extrect the bits 12 to 16, assuming, that the lsb is
    numbereed 0


    bye

    H

    On Jul 31, 6:55 am, bugbear <bugbear@trim_papermule.co.uk_trim> wrote:
    > hofer wrote:
    > > Hi Bugbear,

    >
    > > I'm not that gifted in explaining, but I t'll try.

    >
    > > First if your question concerns the representation of binary numbers:
    > > Then look athttp://en.wikipedia.org/wiki/Binary_numeral_system

    >
    > I am familiar with multi precision and multi base concepts.
    >
    > >>Example Bits 16 bis 12 should result in 0b00001 == 0x1 == 1
    > >> Bits 17 bis 12 should result in 0b100001 == 0x21 == 33

    >
    > what do you mean by
    > "Bits 16 bis 12"
    >
    > and
    >
    > "Bit 17s bis 12"
    >
    > what is "bis" ?
    >
    > BugBear
     
    hofer, Jul 31, 2008
    #7
  8. hofer

    sisyphus Guest

    On Aug 1, 7:18 am, hofer <> wrote:

    >
    > I wanted to extrect the bits 12 to 16, assuming, that the lsb is
    > numbereed 0
    >


    If it's the same bits each and every time, then a combination of
    bitwise & and right-shifting (as already suggested) would be best:

    $and = (2 ** 16) + (2 ** 15) + (2 ** 14) + (2 ** 13) + (2 ** 12);
    for(@nums) {
    $wanted = ($_ & $and) >> 12;
    # do additional stuff
    }

    where both $wanted and the elements of @nums could be Math::BigInt or
    Math::GMP or Math::pari or Bit::Vector objects (to name a few
    options). Each of those modules overloads both '&' and '>>', so the
    above (untested) code should work as is - irrespective of which module
    you use.

    Cheers,
    Rob
     
    sisyphus, Aug 1, 2008
    #8
  9. hofer

    Dr.Ruud Guest

    sisyphus schreef:

    > $and = (2 ** 16) + (2 ** 15) + (2 ** 14) + (2 ** 13) + (2 ** 12);


    Or as Ben Morrow suggested:

    my $mask = 0;
    $mask |= 1 << $_ for 12 .. 16;

    or just

    my $mask = 0x0001_F000;

    --
    Affijn, Ruud

    "Gewoon is een tijger."
     
    Dr.Ruud, Aug 1, 2008
    #9
  10. hofer

    Ben Morrow Guest

    Quoth "Dr.Ruud" <>:
    > sisyphus schreef:
    >
    > > $and = (2 ** 16) + (2 ** 15) + (2 ** 14) + (2 ** 13) + (2 ** 12);

    >
    > Or as Ben Morrow suggested:
    >
    > my $mask = 0;
    > $mask |= 1 << $_ for 12 .. 16;


    I particularly don't like using 2**$N for bit operations, as it returns
    a floating-point result.

    > or just
    >
    > my $mask = 0x0001_F000;


    Well, yes :), but I was assuming the bits to mask in were not known
    until runtime.

    Ben

    --
    Heracles: Vulture! Here's a titbit for you / A few dried molecules of the gall
    From the liver of a friend of yours. / Excuse the arrow but I have no spoon.
    (Ted Hughes, [ Heracles shoots Vulture with arrow. Vulture bursts into ]
    'Alcestis') [ flame, and falls out of sight. ]
     
    Ben Morrow, Aug 1, 2008
    #10
  11. hofer

    Dr.Ruud Guest

    Ben Morrow schreef:
    > Ruud:
    >> sisyphus:


    >>> $and = (2 ** 16) + (2 ** 15) + (2 ** 14) + (2 ** 13) + (2 ** 12);

    >>
    >> Or as Ben Morrow suggested:
    >>
    >> my $mask = 0;
    >> $mask |= 1 << $_ for 12 .. 16;

    >
    > I particularly don't like using 2**$N for bit operations, as it
    > returns a floating-point result.
    >
    >> or just
    >>
    >> my $mask = 0x0001_F000;

    >
    > Well, yes :), but I was assuming the bits to mask in were not known
    > until runtime.


    Yeah, my "Or" was to be read as "Rather" and my "or just" was to be read
    as "or if feasible".

    --
    Affijn, Ruud

    "Gewoon is een tijger."
     
    Dr.Ruud, Aug 1, 2008
    #11
  12. On 2008-08-01 09:10, Dr.Ruud <> wrote:
    > sisyphus schreef:
    >
    >> $and = (2 ** 16) + (2 ** 15) + (2 ** 14) + (2 ** 13) + (2 ** 12);

    >
    > Or as Ben Morrow suggested:
    >
    > my $mask = 0;
    > $mask |= 1 << $_ for 12 .. 16;


    Or use the formula used by hofer in his original posting which doesn't
    need a loop ;-)

    hp
     
    Peter J. Holzer, Aug 1, 2008
    #12
  13. hofer

    Guest

    On Tue, 29 Jul 2008 05:28:56 -0700 (PDT), hofer <> wrote:

    >Hi,
    >
    >I'd like to work with huge integers (> 64 bit precision)
    >
    >Thus I can't use ordinary perl integers.
    >
    >I thought Math::BigInt wouldn't be a too bad choice.
    >
    >
    >It's easy enough go create BigInts.
    >my $a = Math::BigInt->new("0x7777666655544443333222211110000");
    >my $b = Math::BigInt->new("0x1111111111111111111111111111111");
    >
    >Calculating with them is also fine:
    >$a->badd($b); # $a = $a + $b
    >
    >
    >Now I would like to extract certain bits out of this huge number:
    >
    >Example Bits 16 bis 12 should result in 0b00001 == 0x1 == 1
    > Bits 17 bis 12 should result in 0b100001 == 0x21 == 33
    >
    >
    >
    >So far I see two ways of doing this conversion.
    >
    >However I'm not really appealed by either solution.
    >
    >Do you know anything faster / better or even another CPAN module?
    >
    ># extract bits out of binary string
    >sub extbits { #
    > my ($val,$msb,$lsb) = @_; # $val must be Math::BigInt;
    > my $asbinstr = $val->as_bin(); # nun als binaer string
    > my $withoutprefix = substr($asbinstr,2); # fuehrendes '0b'
    >entfernen
    > my $substr = substr($withoutprefix,-$msb-1,$msb-$lsb+1); # den
    >substring extrahieren
    > $substr = 0 if $substr eq ""; # sollte mindestens einen character
    >enthalten
    > my $result = Mat::BigInt->new("0b".$substr); # zurueck in
    >Math::BigInt verwandeln
    > return $result;
    >} #
    >
    ># extract bits via shifts operations follwed by a bit wise and
    >sub extbits { #/*{{{*/
    > my ($val,$msb,$lsb) = @_; # $val must be Math::BigInt;
    > my $mask = Math::BigInt->new(1); # create a 1
    > $mask->blsft($msb-$lsb+1); # 2 ^ (number of bits to extract)
    > $mask->bsub(1); # now we have a mask
    > my $tmp = $val->copy->brsft($lsb); # shift input value to the
    >right
    > return $tmp->band($mask);
    >} #/*}}}*/
    >
    >
    >
    >Thanks in advance for any other suggestions
    >like rewriting the function to accelerate it or using another module.
    >
    >
    >bye
    >
    >
    >H



    0x7777666655544443333222211110000

    Hex Bits Bytes
    ------------------------------------
    7777666 64 8 (really: 63 7)
    65554444 64 8
    33332222 64 8
    11110000 64 8
    ------------------------------------
    Total 256 32


    0x1111111111111111111111111111111

    Hex Bits Bytes
    ------------------------------------
    1111111 64 8 (really: 63 7)
    11111111 64 8
    11111111 64 8
    11111111 64 8
    ------------------------------------
    Total 256 32


    I count 256 bits here. This is strange.
    In reality, there is no use in having integers that
    specific unless you need unique identifiers.

    In the case of that many individuals, and I can only
    think on a macro level here, it would be the amount
    of stars in the universe. In that case, I believe it
    still falls short, not sure.

    On the atomic level, and you mention "precision", probably
    this is a misnomer as a macro, there is no measurement below
    sub-micron (1/10), a simple 6 decimal places.

    I don't know but there are other possiblilites here though.
    Like, in a weird way, you are somehow running a piramyd simulation,
    statistics, where every digit counts, jacking up all intermediate
    calculations to whole numbers until the final result.

    Regardless, you need to do work on and have a big matissa, so to speak.
    The Calculator program under windows is very interresting, you may
    want to take a look at it.

    There is a function (enable advanced scientific) x^y.
    If you put in 2^100 you get 1267650600228229401496703205376.
    That would be 100 bits on my 32 bit integer machine.

    Apparently "BigInt" means it, but is it so hard to do?
    Why don't you do your own?

    Binary math is simple, you don't need 100 bit registers to do it.
    That module simply uses the available machine register width, the
    wider the better, to simulate extended integer arithmatic.

    On the hardware side, if my data register were 16 bit, I would use 8x8 bit
    chunks for calculations, 32 bit, 16x16, 64 bit, 32x32, etc..

    Doesen't matter how big the width is of the input. I'm sure this is
    nothing new, this is a simulation, intermediate results, the way it
    was before 80 bit data registers in floating point chips doing similar
    things by example.

    For example, if my machine were 32 bit integer data width registers,
    I would create an array of 16 bit integers large enough to represent
    the largest number of bits needed in the calculation.
    Doesen't matter how big the array is.

    The logical binary math progresses upward, from one 16 bit frame to the next,
    until the resultant array is populated.

    So it is possible to do binary calculations for as much as you have memory
    to create an array of integers. I haven't calculate 2^4,000,000 but I assume
    its very large array.

    Concerning retreiveing bits of that very large number, how hard would it
    be to shift the frame, knowing its size, to the index of the array, of the
    bits in question? Not hard at all, its simple, and that bit number will fit
    into a 32 bit register. Its quick. If bits are on adjacent frames, algorithmacally
    its easy.

    Remember, this does not use strings at all. Integer arithmatic is the easiest
    thing in the world. But your not doing trig are you...

    This would be trivial... So I suggest you roll your own. I won't do it, although
    I could.

    --

    256 bit example (from above) ADDITION, 16 bit Frame pseudocode:

    @a = (0x0000,0x0777,0x7666,0x6555,0x4444,0x3333,0x2222,0x1111,0x0000);
    @b = (0x0000,0x1111,0x1111,0x1111,0x1111,0x1111,0x1111,0x1111,0x1111);
    @c = ();

    In this case you would work the array frame (index) from the largest to smallest.
    In reality, the array's should be reversed, but thats details when thier populated.
    Do the frame calculation, carry over remainder to next frame, continue, populate
    array @c.

    Given the frame size, its trivial to find a sequential series of bits, even if overlapping
    frames.


    Let me know if this sounds about right.

    sln
     
    , Aug 4, 2008
    #13
  14. hofer

    Guest

    On Mon, 04 Aug 2008 19:38:54 GMT, wrote:

    >On Tue, 29 Jul 2008 05:28:56 -0700 (PDT), hofer <> wrote:
    >
    >>Hi,
    >>

    >On the atomic level, and you mention "precision", probably
    >this is a misnomer as a macro, there is no measurement below
    >sub-micron (1/10), a simple 6 decimal places.
    >

    To clarify... that can be manufactured.

    sln
     
    , Aug 4, 2008
    #14
  15. hofer

    hofer Guest

    Hi,

    Just some update:

    The solution, that works without any additional perl modules and that
    will benefit from Math::BigInt::GMP if it is installed is:

    use Math::BigInt lib => 'GMP';

    # extract bits via a shift operations follwed by a bit wise and
    sub extbits { #/*{{{*/
    my ($val,$msb,$lsb) = @_; # $val must be Math::BigInt;
    my $mask = Math::BigInt->bone()->blsft($msb-$lsb+1)->bsub(1);
    return $val->copy->brsft($lsb)->band($mask);

    } #/*}}}*/

    following example runs now for me in 15 seconds if Math::BigInt::GMP
    doesn't exist and in 10 secodns if it does.

    my $v1 = Math::BigInt->new("0x".( "76543210"x6));
    print $v1->as_hex(),"\n";
    my $v2;
    for(my $i=0;$i<300;$i++){
    for(my $j = 0; $j < 64;$j++){
    $v2 = extbits($v1,$j+66,$j+50);
    print($v2->as_hex(),"\n") if($i==0);
    }
    }


    The other option I found is the CPAN module

    Bit::Vector

    I didn't try how fast it is for arithmetics, but for bit field
    extraction /
    copying / concatenation it's rather quick (run time 1 s)

    Disadvantage / advantage:
    The max size (in bits) for a bit vector has to be set during the
    vector creation.

    use Bit::Vector;

    ub extbitsbv { #
    my($v,$from,$to) = @_;
    my $len = $from-$to+1;
    my $v2 = Bit::Vector->new($len);
    $v2->Interval_Copy($v,0,$to,$len);
    return $v2;
    } #

    my $v1 = Bit::Vector->new_Hex(32*6,"76543210"x6);
    my $v2;
    print $v1->to_Hex(),"\n";
    for(my $i=0;$i<300;$i++){
    for(my $j = 0; $j < 64;$j++){
    $v2 = extbitsbv($v1,$j+66,$j+50);
    print($v2->to_Hex(),"\n") if($i==0);
    }
    }


    bye


    H






    On Jul 29, 8:28 am, hofer <> wrote:
    > Hi,
    >
    > I'd like to work with huge integers (> 64 bit precision)
    >
    > Thus I can't use ordinary perl integers.
    >
    > I thought Math::BigInt wouldn't be a too bad choice.
    >
    > It's easy enough go create BigInts.
    > my $a = Math::BigInt->new("0x7777666655544443333222211110000");
    > my $b = Math::BigInt->new("0x1111111111111111111111111111111");
    >
    > Calculating with them is also fine:
    > $a->badd($b); # $a = $a + $b
    >
    > Now I would like to extract certain bits out of this huge number:
    >
    > Example Bits 16 bis 12 should result in 0b00001 == 0x1 == 1
    > Bits 17 bis 12 should result in 0b100001 == 0x21 == 33
    >
    > So far I see two ways of doing this conversion.
    >
    > However I'm not really appealed by either solution.
    >
    > Do you know anything faster / better or even another CPAN module?
    >
    > # extract bits out of binary string
    > sub extbits { #
    > my ($val,$msb,$lsb) = @_; # $val must be Math::BigInt;
    > my $asbinstr = $val->as_bin(); # nun als binaer string
    > my $withoutprefix = substr($asbinstr,2); # fuehrendes '0b'
    > entfernen
    > my $substr = substr($withoutprefix,-$msb-1,$msb-$lsb+1); # den
    > substring extrahieren
    > $substr = 0 if $substr eq ""; # sollte mindestens einen character
    > enthalten
    > my $result = Mat::BigInt->new("0b".$substr); # zurueck in
    > Math::BigInt verwandeln
    > return $result;
    >
    > } #
    >
    > # extract bits via shifts operations follwed by a bit wise and
    > sub extbits { #/*{{{*/
    > my ($val,$msb,$lsb) = @_; # $val must be Math::BigInt;
    > my $mask = Math::BigInt->new(1); # create a 1
    > $mask->blsft($msb-$lsb+1); # 2 ^ (number of bits to extract)
    > $mask->bsub(1); # now we have a mask
    > my $tmp = $val->copy->brsft($lsb); # shift input value to the
    > right
    > return $tmp->band($mask);
    >
    > } #/*}}}*/
    >
    > Thanks in advance for any other suggestions
    > like rewriting the function to accelerate it or using another module.
    >
    > bye
    >
    > H
     
    hofer, Aug 5, 2008
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. GGG
    Replies:
    10
    Views:
    12,565
    Donar
    Jul 6, 2006
  2. sarmin kho
    Replies:
    2
    Views:
    828
    A. Lloyd Flanagan
    Jun 15, 2004
  3. Miki Tebeka
    Replies:
    1
    Views:
    446
    Marcin 'Qrczak' Kowalczyk
    Jun 14, 2004
  4. sergey

    "casting" bits to bits?

    sergey, Nov 8, 2006, in forum: VHDL
    Replies:
    1
    Views:
    709
    sergey
    Nov 8, 2006
  5. Replies:
    3
    Views:
    501
Loading...

Share This Page