http://qs1969.pair.com?node_id=11108831


in reply to Re^3: Can I access and use UV types from perl?
in thread Can I access and use UV types from perl?

Thank you haukex this is a good explanation.

In a sense am I being a little bit confused around what Devel:Peek is telling me, bearing in mind I am using a 5.14 version.

$n = unpack "C", pack "B", 128; &print_val; $n += $n; &print_val; #output #SV = IV(0xe28558) at 0xe2855c # REFCNT = 1 # FLAGS = (PADMY,IOK,pIOK) # IV = 128 # ### #SV = IV(0xe28558) at 0xe2855c # REFCNT = 1 # FLAGS = (PADMY,IOK,pIOK) # IV = 256 # ###

These are actually UV values then? but Perl is storing them as IV's. and the sum at the microprocessor level, adding 128 to itself, is carrying out a binary addition of a natural number.

I have only just found out about two's complement a couple of weeks ago, and I'm not sure where I stand on that just yet.

Replies are listed 'Best First'.
Re^5: Can I access and use UV types from perl?
by haukex (Archbishop) on Nov 17, 2019 at 21:58 UTC
    In a sense am I being a little bit confused around what Devel:Peek is telling me

    If you want to dive into that rabbit hole, see perlguts and the rest of the internals documentation, although be warned, that's not light reading.

    These are actually UV values then? but Perl is storing them as IV's.

    Those values will fit fine into a signed integer, so as per dave_the_m's explanation, Perl has no need to upgrade them to a UV. It might be interesting to note that Perl can store pretty big integer values. As per ikegami's post here:

    1. Largest integer value that can be stored as a signed integer: ~0 >> 1 (on my machine: 9,223,372,036,854,775,807), and the smallest: -(~0 >> 1)-1
    2. Largest integer value that can be stored as an unsigned integer: ~0 (on my machine: 18,446,744,073,709,551,615)
    3. All integer values from 0 to this number can be stored without loss as a floating point number: $Config{nv_overflows_integers_at} (on my machine: 9,007,199,254,740,992)
    two's complement

    One of the things that really helped it click for me back then was this graphic, along with looking at different 2's complement mathematical operations (Update 2: as I showed in my reply below):

    0 -1 0000 1 1111 0001 -2 2 1110 0010 -3 3 1101 0011 -4 4 1100 0100 -5 5 1011 0101 -6 6 1010 0110 -7 7 1001 -8 0111 1000

    Update: In the graphic I accidentally wrote "8" when it should have been "-8", sorry, fixed.

      More information about Perl's largest integer can be found here

      Yes the image helped, I can see from that that perhaps this is what happens. To calculate a two's complement number take the difference of the highbit masked number, with the complement mask of the highbit number. The number being negative when the highbit is set, essentially saying complement mask minus the highbit mask number.

      We could use pairs of numbers, such that the 'highbit' could be any binary number and the difference found between that and its pair then resolves into an integer. It's a different way of storing and operating on the numbers.

      update added example code

      =head1 polynumber binary pairs (bifields?) 0 00_00 -1 1 00_01 01_00 -2 2 00_10 10_00 -3 3 00_11 11_00 =cut

      But, we get overlaps.

      =head1 polynumber binary pairs (bifields?) overlaps 1 -2 10_01 01_10 -1 1 01_10 10_01 -3 0 00_11 11_11 =cut

      note: row polynumbers are read opposite significant highbit first. That is, if these are 'N'etwork order they should be read 'V'ax order. This illustrates the concept.

      edit added whitespace, and note

        Sorry, I'm afraid I don't follow... but since you mention the high bit, note how in two's complement, the high bit is basically the sign bit. And the other nice thing is that the binary math still works well:

        • -8+1 is 1000+0001, which =1001, which is -7
        • -2-2 is 1110+1110, which =11100, drop the overflow and 1100 is -4
        • -2+5 is 1110+0101, which =10011, drop the overflow and 0011 is 3

        Of course, there are still overflow issues, e.g. 7+1 turns out as -8, but those will always happen with any fixed number of bits. Of course, the advantage of Perl's scalars here is that they will upgrade themselves automatically! (At the risk of losing some precision)