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

Sorry, but I still don't understand. See XY Problem - what I was asking is what practical requirement you have such that you are required to use unsigned ints.

use_integer literally turns all the values into IV's.

No, see integer: It changes the way the operators work.

At some point though it seems like somewhere somebody decided that, well, before we can do that we have to convert this thing we call 1 into some more complicated thing called an integer with a respective value of 1, that can then be added to itself to produce the answer to this question. To this I say, cool now we're doing computing, but, can we just add 1 to 1 first, without turning into one of those.. uhm integer thingys?

If by "integer thingys" you mean Perl's data types, then yes, Perl does abstract out the underlying representation of the values. Perl is a higher-level language, and there is only a limited amount of sense in trying to work with Perl on a lower level - if there is a requirement to work with specific data types (or you just want to learn more about the underlying data types), then it's usually best to use a language that works more closely to the machine level, such as C. Perl abstracting these things removes a lot of the complexity that can arise in languages such as C, such as having to cast between different data types manually, at the cost of some performance and memory usage relative to C. But the lower complexity also means less chance to introduce bugs due to incorrect typecasts (not to mention all the complexities that are avoided by having dynamic string and array sizing, references instead of pointers, and automatic memory management).

One relating to Perl is in the difference between return values. Perl returns undef, zero or > zero, whereas C can return negative one. Does this mean that Perl returns unsigned int values, whereas C returns signed int values?

Many C functions do return ints, i.e. signed ints. However, as I said above, Perl functions return Perl's own variable types, and there are also Perl functions that mirror the underlying C API and return negative values.

From an educational aspect, it is a bit like saying, ok I get we are all using signed ints as the basis of our computing because it leads to a lot of efficiencies and optimisations, but where are those intermediate steps we took to go from using a byte as a 7 bit bit field to using it as an 128 decimal mapping to a non-symmetric range around zero.

Modern processors can handle unsigned and signed integers of varying widths (64 bits on modern architectures) natively, there are no "intermediate steps" there. If your goal here is to learn more about the underlying operations, it might be best if you take some time to look at C. You might also be interested in Two's complement math - the great thing about it is that there isn't really a "mapping" necessary to do many of the operations.

This helps, but I do wonder what this strange signed char thingy is.

It's (pretty much always) an octet that stores the values -128 to 127 instead of 0 to 255 (unsigned char).

$ perl -e 'print"unsigned signed\n";printf"%-3d %08b %4d\n",$_,$_,un +pack"c",pack"C",$_ for 0..255' unsigned signed 0 00000000 0 1 00000001 1 2 00000010 2 3 00000011 3 ... 125 01111101 125 126 01111110 126 127 01111111 127 128 10000000 -128 129 10000001 -127 130 10000010 -126 ... 253 11111101 -3 254 11111110 -2 255 11111111 -1

It's the same bits, just different interpretations. The difference of how which bits are treated happens at the at the lowest level, in the assembly instructions provided to the microprocessor. In C, when you say that a variable is a signed int or an unsigned int, that will tell the C compiler which assembly instructions to emit when doing operations with those variables. Perl's runtime abstracts that out even more, so that you don't have to worry about signed vs. unsigned or even int vs. float.

Replies are listed 'Best First'.
Re^4: Can I access and use UV types from perl?
by Don Coyote (Hermit) on Nov 17, 2019 at 21:00 UTC

    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.

      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