There's some bits in sv.c that I'd like to ask about: if (SvNOKp(sv)) { /* See note in sv_2uv() */ /* XXXX 64-bit? IV may have better precision... */ /* I tried changing this to be 64-bit-aware and * the t/op/numconvert.t became very, very, angry. * --jhi Sep 1999 */ Is it something like Ilya put a dragon in there which usually lies sleeping? And did that sv_2uv used to read sv_2iv until a global search-and-replace was done when sv_2uv was cloned and then mutated from sv_2iv? [I'm guessing that is what happened] if (s - nbegin >= TYPE_DIGITS(IV)) /* Cannot cache ato[ul]() */ numtype |= IS_NUMBER_TO_INT_BY_ATOF | IS_NUMBER_NOT_IV; else numtype |= IS_NUMBER_TO_INT_BY_ATOL; I think I see what it's doing. If there are less digits than the number eof digits in the maximum value (signed? unsigned: 31 10.332 32 10.633 35 11.5361 36 11.8371 63 19.9649 64 20.266 95 29.5979 96 29.899 127 39.2309 128 39.532 255 77.7629 256 78.0639 looks like we're safe for most things until 256 bit integers) then the conversion defaults to going via atof, as there's this inbuilt assumption that NV preserves UV. viz (32 bit IV, 64 bit NV): nick@Bagpuss [bleadperl]$ ./perl -Ilib -MDevel::Peek -we '$a = "999999999"; $a |= 1; Dump ($a)' SV = PVIV(0x20d2f50) at 0x20dcf20 REFCNT = 1 FLAGS = (IOK,pIOK,IsUV) UV = 999999999 PV = 0x20e1ac0 "999999999"\0 CUR = 9 LEN = 10 nick@Bagpuss [bleadperl]$ ./perl -Ilib -MDevel::Peek -we '$a = "1000000000"; $a |= 1; Dump ($a)' SV = PVNV(0x20d35d8) at 0x20dcf20 REFCNT = 1 FLAGS = (IOK,pIOK,IsUV) UV = 1000000001 NV = 1000000000 PV = 0x20e1ac0 "1000000000"\0 CUR = 10 LEN = 11 Easily fooled into thinking an NV would be needed: nick@Bagpuss [bleadperl]$ ./perl -Ilib -MDevel::Peek -we '$a = "0999999999"; $a |= 1; Dump ($a)' SV = PVNV(0x20d35d8) at 0x20dcf20 REFCNT = 1 FLAGS = (IOK,pIOK,IsUV) UV = 999999999 NV = 999999999 PV = 0x20e1ac0 "0999999999"\0 CUR = 10 LEN = 11 [this might just be an issue. maybe the count should skip leading zeros.] So does this mean that to change from "IV good, NV better" to "all ?Vs are equal" some more effort with trying both integer and float conversion and seeing what flies is going to be needed for numbers which looks_like_number() counts to have the same number of digits as the largest value? I think numbers with less digits are safe with the current looks_like_number() [even for systems where NV doesn't preserve IV] as long as sv_2iv/sv_2uv/sv_2nv ensure that things that could cause trouble like "123456789123456789.2" are converted to both NV and IV when either NV or IV is requested [approximated as IV 123456789123456789 and NV 1.23456789123457e+17 say] sv_2iv will be able to tell as it will be told IS_NUMBER_NOT_IV, do the NV conversion, check, find that the NV is less than IV_MAX, and hence also do the direct PV->IV conversion. Hmm. I think that will actually work for all borderline cases, such as the "1000000000" above. Nick PS I don't like floating point numbers. printf can give you numbers such as NaN and Infinity, so why can't scanf read 'em? :-(Thread Previous | Thread Next