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

Hi All, Am trying to find out if it is possible to represent the numbers between 10 and 100 in such a way that when their size is measured it will be equal to one byte. So, 1.any ideas how to represent the above numbers as one byte. 2. IF number 1 is possible-is there a specific way to measure the size of the number Thanks, Val

Replies are listed 'Best First'.
Re: Number size equal to one byte
by Abigail-II (Bishop) on Jul 04, 2002 at 18:00 UTC
    What do you mean by "size"? If you mean it in the way as in C, the answer is no. It takes quite some bytes just to represent anything in Perl.

    Here's a schematic view of an integer in Perl:

          SvIV            xpviv 
        +--------+      +--------+
        | Any +--+----->| (PVX)  |
        +--------+      +--------+
        | RefCo  |      | (CUR)  |
        +--------+      +--------+
        | Fl  |T |      | (LEN)  |
        +--------+      +--------+
                        |  IVX   |
                        +--------+
    
    All fields are 32 bits wide. Note that there are other ways integers can be stored in Perl, in might have been used as a float or a string; then the size will increase. But the minimum size is 28 bytes.

    Abigail

      Could you elaborate on your design and explain what the acronym's mean? Thanks.
        Could you elaborate on your design and explain what the acronym's mean?
        Any:    A pointer to anything.
        Refco:  Reference counter.
        Fl:     Flags.
        T:      Type.
        PVX:    Pointer value (a pointer to a string).
        CUR:    Length of above string.    
        LEN:    Size of allocated area for string.
        IVX:    Integer value.
        
        For an SvIV, the PVX, CUR and LEN values are unused.

        For much more details, visit Gisles PerlGuts Illustrated.

        Abigail

      Er, actually, the minimum is 16 bytes. Not only are the PVX, CUR and LEN not used, they're not even allocated on any scalar that has never been used as a string. The allocator actually allocates a block of contiguous integers, and returns a fake Any pointer to where the PVX would be if there were one, so that the access code doesn't have to have a conditional offset. If you looked in the PVX, CUR and LEN of a bare integer, you'd actually find the integers of other previously constructed values.

      Larry

•Re: Number size equal to one byte
by merlyn (Sage) on Jul 04, 2002 at 22:33 UTC
    my $storage = ""; foreach my $which (0..1023) { vec($storage, $which, 8) = 10 + rand(90); } print "stored in ".length($storage)." bytes\n"; foreach my $which (0..1023) { print "item $which is ", vec($storage, $which, 8), "\n"; }

    -- Randal L. Schwartz, Perl hacker

Re: Number size equal to one byte
by chromatic (Archbishop) on Jul 04, 2002 at 18:04 UTC

    Yes, but not in Perl. Perl stores data in internal types, such as SVs, NVs, and IVs. Since it also tracks other things, such as any magic applied to a variable and the number of references pointing to it, there's not a one to one correspondence between numbers and bytes. Besides that, with Unicode, it's usually not very helpful to think about bytes anyway.

    If you could outline what you're attempting to accomplish, perhaps someone would tell you a more Perlish way.

      Besides that, with Unicode, it's usually not very helpful to think about bytes anyway.
      What's got Unicode to do with it? The question was about storage size of numbers, not strings. Unicode doesn't influence numbers - just strings.

      Abigail

        Absolutely true. I waved my hands right over that point.
Re: Number size equal to one byte
by samtregar (Abbot) on Jul 05, 2002 at 05:27 UTC
    You might find my Tie::IntegerArray module useful. With it you could do:

    use Tie::IntegerArray; tie my @array, 'Tie::IntegerArray', bits => 8, signed => 0; @array = (10 .. 100);

    This will result in @array containing 90 integers each taking up only 8 bits. Actually, for your example you can get away with just 7 bits which might save some memory for very large sized arrays.

    Tie::IntegerArray is just a convenient wrapper around the fantastic Bit::Vector module. You could get similar functionality with a little more effort directly from that module.

    -sam

Re: Number size equal to one byte
by tadman (Prior) on Jul 05, 2002 at 15:39 UTC
    There's a few completely correct, but strange answers given here to what I thought would be a simple question.

    The short answer is to use the vec function, which can store numbers 0-255 (i.e. unsigned 8-bit numbers) in a single byte. You can store 16-bit, 32-bit or any other length that comes to mind as well.

    A simple way is to use a scalar as an array, and just direct-assign to it:
    my $n; my $foo; my @offsets = (0, 1, 3950122); foreach (@offsets) { vec($foo,$_,8) = $n++; } foreach (@offsets) { print "$_ = ",vec($foo,$_,8),"\n"; }
    Remember, though, that like an array, if you use bits that are really far out in left field (i.e. millions), you are going to use a ton of memory.

    This is just like what merlyn said but with a bit of explanation.
Re: Number size equal to one byte
by Juerd (Abbot) on Jul 04, 2002 at 19:46 UTC

    A byte holds 8 bits, and with 8 bits, you can have 2**8 == 256 different options. For normal 0..255 numbers, you can use ord and chr.

    - Yes, I reinvent wheels.
    - Spam: Visit eurotraQ.
    

Re: Number size equal to one byte
by dada (Chaplain) on Jul 05, 2002 at 08:41 UTC
    I'm not sure I understand what do you mean, but I'll give it a try.

    1.any ideas how to represent the above numbers as one byte.

    $number10 = pack('C', 10); # ... $number100 = pack('C', 100);

    eg. pack a C char, it's one byte (plus the perl variable overhead itself in memory, as Abigail-II points out).

    2. IF number 1 is possible-is there a specific way to measure the size of the number

    $size = length($number100);
    cheers,
    Aldo
    __END__ $_=q,just perl,,s, , another ,,s,$, hacker,,print;