develooper Front page | perl.perl5.porters | Postings from February 2012

Re: [perl #109542] $1 handled differently in integer arithmetics

Thread Previous | Thread Next
From:
Abhijit Menon-Sen
Date:
February 1, 2012 09:55
Subject:
Re: [perl #109542] $1 handled differently in integer arithmetics
Message ID:
20120201175541.GA28067@toroid.org
At 2012-01-31 23:20:24 -0800, perlbug-followup@perl.org wrote:
>
>  perl -e '$s = "976562500000"; $s =~ /(\d+)/; printf "%s = %s\n", ($1 * 1024), int ($1 * 1024)'
> 
> Expected (at least on amd64):
> 
>  1000000000000000 = 1000000000000000
> 
> Got:
> 
>  1e+15 = 1000000000000000

I understand superficially why this happens, but I'm not sure what we
can do about it, or if I'm missing something deeper. Look at this code
in pp.c/pp_multiply:

1262     svr = TOPs;
1263     svl = TOPm1s;
1264 #ifdef PERL_PRESERVE_IVUV
1265     SvIV_please_nomg(svr);
1266     if (SvIOK(svr)) {
1267         /* Unless the left argument is integer in range we are going to have to
1268            use NV maths. Hence only attempt to coerce the right argument if
1269            we know the left is integer.  */
1270         /* Left operand is defined, so is it IV? */
1271         SvIV_please_nomg(svl);
1272         if (SvIOK(svl)) {

The SvIV_please_nomg(svl) line doesn't do anything to $1 because it's
not NOK||POK, so SvIOK(svl) is not true afterwards, and svl is treated
as an NV. $+{match} is also magical, but POK is set, so it's passed to
sv_2iv_flags, which calculates the correct IV and sets IOK. So it uses
integer math. Same with copying $1, except it's only POK, no magic.

-- ams

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About