in reply to Re: Integer vs Float during addition
in thread Integer vs Float during addition

I'm just trying to understand the internals a bit more

It's often enlightening (and fun) to use Devel::Peek to get a glimpse of what the scalar actually looks like:
use warnings; use Devel::Peek; $int = 17; #print "\$int: $int\n"; Dump($int); print "##############\n\n"; $double_1 = 1.23456789; #print "\$double_1: $double_1\n"; Dump($double_1); print "##############\n\n"; $double_2 = 1.0000; #print "\$double_2: $double_2\n"; Dump($double_2); print "##############\n\n"; $ul = 2 ** 31 + 16; # too big for an IV #print "\$ul: $ul\n"; Dump($ul); print "##############\n\n"; $double_3 = 2 ** 46 + 19; # too big for a UV or IV #print "\$double_3: $double_3\n"; Dump($double_3); print "##############\n\n"; $int += 0.0123; # $int no longer an IV #print "\$int: $int\n"; Dump($int); print "##############\n\n";
Which outputs:
D:\pscrpt>perl try.pl SV = IV(0x89c7cc) at 0x3f5d3c REFCNT = 1 FLAGS = (IOK,pIOK) IV = 17 ############## SV = NV(0x8afcb4) at 0x3f5d24 REFCNT = 1 FLAGS = (NOK,pNOK) NV = 1.23456789 ############## SV = NV(0x8afcbc) at 0x8a3204 REFCNT = 1 FLAGS = (NOK,pNOK) NV = 1 ############## SV = IV(0x89c7c8) at 0x8ba4d8 REFCNT = 1 FLAGS = (IOK,pIOK,IsUV) UV = 2147483664 ############## SV = NV(0x8afcc4) at 0x8a2fdc REFCNT = 1 FLAGS = (NOK,pNOK) NV = 70368744177683 ############## SV = PVNV(0x3f8714) at 0x3f5d3c REFCNT = 1 FLAGS = (NOK,pNOK) IV = 17 NV = 17.0123 PV = 0 ##############
Note that $double_2 (assigned a value of 1.000) is an NV (perl's idea of a double) as you expected, but the actual value in the NV slot has been truncated to simply '1' ... when you 'print $double_2;', it's the value in the NV slot that gets printed.

$ul is assigned a value that's too big to be a signed int, so it gets assigned to the UV slot, and the IsUV flag gets set. And $double_3 is assigned an integer value that can only fit into a double ... so, naturally, it has to be an NV.

Note also that $int, which starts out as an IV, becomes an NV as soon as you add a float to it - and that the original IV value remains in the IV slot. It's the fact that the NOK and pNOK flags are set that determines that the NV value (rather than the value in the IV slot) will be displayed if you then 'print $int;'.

Furthermore, if you enable those print statements that are currently commented out, you'll see that the various Dump() outputs change.

Devel::Peek doesn't really explain anything, but it does let you see how the scalars are changing - and from that you can often come to a "good enough" understanding of what's happening. If you want a thorough understanding then you probably need to examine the perl source code.

(And, of course, I always find that Devel::Peek throws up something unexpected - eg I don't know why doing '$int += 0.0123;' sets the PV slot to 0.)

Cheers,
Rob