Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.94k stars 554 forks source link

oct()/hex() cannot handle infinity nor negative numbers #7705

Closed p5pRT closed 12 years ago

p5pRT commented 19 years ago

Migrated from rt.perl.org#33013 (status was 'rejected')

Searchable as RT33013$

p5pRT commented 19 years ago

From perl_dummy@bloodgate.com

Created by perl_dummy@bloodgate.com

  perl -wle 'print 2 ** 3333'   inf   perl -wle 'print 2 ** 3333 == 2 ** 3333'   1   perl -wle 'print oct(2 ** 3333)'   0   perl -wle 'print hex(2 ** 3333)'   Illegal hexadecimal digit 'i' ignored at -e line 1.   0

This effects BigInt and friends\, since oct() and hex() seem not to be overloadable​:

  perl -Mbignum -wle 'print oct(inf)'   0   perl -Mbignum -wle 'print hex(inf)'   Illegal hexadecimal digit 'i' ignored at -e line 1.   0

Compare to​:

  perl -Mbignum -wle 'print inf->as_hex()'   inf   perl -Mbignum -wle 'print inf->as_bin()'   inf

In addition\, oct() and hex() seem not to be able to handle negative numbers at all. That should either be documented or fixed (preferable to me)​:

  perl -wle 'print hex("-12")'   Illegal hexadecimal digit '-' ignored at -e line 1.   0   perl -wle 'print oct("-12")'   0   perl -wle 'print oct(-12)'   0   perl -wle 'print oct(-02)'   0
  perl -wle 'print -2 ** 3333'   -inf   perl -wle 'print oct(-2 ** 3333)'   0   perl -wle 'print hex(-2 ** 3333)'   Illegal hexadecimal digit '-' ignored at -e line 1.   0

Note​: rand() gets it right​:

  perl -wle 'print rand(2 ** 3333)'   inf   perl -wle 'print rand(-2 ** 3333)'   -inf   perl -wle 'print rand(-1)'   -0.174723732358874

Reed Wilson says​: "A number\, chosen uniformly between 0 and inf\, has no chance of being finite".

Best wishes\,

Tels

Perl Info ``` ----------------------------------------------------------------- - --- Flags: category=core severity=low - --- Site configuration information for perl v5.8.6: Configured by root at Sun Dec 12 14:25:01 CET 2004. Summary of my perl5 (revision 5 version 8 subversion 6) configuration: Platform: osname=linux, osvers=2.6.5-7.111.5-default, archname=i686-linux uname='linux linux 2.6.5-7.111.5-default #1 wed nov 17 11:08:17 utc 2004 i686 athlon i386 gnulinux ' config_args='-ds -e' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-fno-strict-aliasing -pipe -I/usr/local/include - -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2', cppflags='-fno-strict-aliasing -pipe -I/usr/local/include' ccversion='', gccversion='3.3.3 (SuSE Linux)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -ldl -lm -lcrypt -lutil -lc perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc libc=, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.3.3' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Locally applied patches: - --- @INC for perl v5.8.6: /usr/local/lib/perl5/5.8.6/i686-linux /usr/local/lib/perl5/5.8.6 /usr/local/lib/perl5/site_perl/5.8.6/i686-linux /usr/local/lib/perl5/site_perl/5.8.6 /usr/local/lib/perl5/site_perl . - --- Environment for perl v5.8.6: HOME=/home/te LANG=en_US.UTF-8 LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/te/bin:/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/opt/gnome/bin:/opt/kde3/bin PERL_BADLANG (unset) SHELL=/bin/bash -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iQEVAwUBQbxT4HcLPEOTuEwVAQGEcQf+LTTS0UMA1btB7C8T86DhyP2feKhoXMzt Ed8tWfOr+52vqTMLSpe8Xhs0yQ2ITJFiV4tYqZf5SylTpG1vqUOB5voHxm6hrZY8 n/A9OpT0dI1xKT5Qqsk5sfJ1TLGK4a2qFJDB/S1H5FJKYljNdpC1Y+XB2vjKid4+ CeRtXJe7MKsBuneefWK9+CCC9+7Hul94k4XG/DhXbXJG6gvU9BBLHcNG1ruevVef xOOexAa6CHBTqxi1O+WKJq5W+tDkKGR7QKwK+Mquy1nokEJPMkVcWHaxBtFida4f KnAjIJlVHTlsyN98RjsnTC2Jw3+a16G5QEFmHoKBb85SGLVrLrw/Rw== =i7Ur -----END PGP SIGNATURE----- ```
p5pRT commented 19 years ago

From @ysth

On Sun\, Dec 12\, 2004 at 02​:23​:23PM -0000\, Tels wrote​:

perl \-wle 'print 2 \*\* 3333'
inf
perl \-wle 'print 2 \*\* 3333 == 2 \*\* 3333'
1
perl \-wle 'print oct\(2 \*\* 3333\)'
0
perl \-wle 'print hex\(2 \*\* 3333\)'
Illegal hexadecimal digit 'i' ignored at \-e line 1\.
0

I'm a little confused as to what you want; oct and hex take octal and hex *strings* and return the equivalent number. There shouldn't be any need to accept an Inf *number* and return Inf.

p5pRT commented 19 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 19 years ago

From nospam-abuse@bloodgate.com

-----BEGIN PGP SIGNED MESSAGE-----

Moin\,

Yitzchak wrote​:

On Sun\, Dec 12\, 2004 at 02​:23​:23PM -0000\, Tels wrote​:

perl \-wle 'print 2 \*\* 3333'
inf
perl \-wle 'print 2 \*\* 3333 == 2 \*\* 3333'
1
perl \-wle 'print oct\(2 \*\* 3333\)'
0
perl \-wle 'print hex\(2 \*\* 3333\)'
Illegal hexadecimal digit 'i' ignored at \-e line 1\.
0

I'm a little confused as to what you want; oct and hex take octal and hex *strings* and return the equivalent number. There shouldn't be any need to accept an Inf *number* and return Inf.

You are of course right about the strings. However\, hex() and oct() take happily *numbers*\, too\, but they convert them first to their string form​:

  perl -wle 'print hex(123)'   291   perl -wle 'print oct(123)'   83

Plus and minus infinity are just a numbers. Granted\, they are special numbers\, but numbers still. And their *string form* is 'inf'\, '+inf' or '-inf'\, respectively. And since it is the same form in all bases\, their *hexadecimal string form* is 'inf'\, '-inf'\, and '+inf' respectively. (One could argue that '0xinf' should also be valid\, but I think that is a bit silly. Hm\, maybe not.)

So\, IMHO hex() and oct() should deal with the strings 'inf'\, '+inf' and 'inf'.

Likewise\, minus 0x123 should be "-0x123" and therefore "-0x123" should be a valid hex string\, and therefore IMHO hex() should be able to deal with it.

One might argue that Perl's hex()/oct() should not be changed. However\, at least under bignum they _should_ be able to deal with these kinds of inputs. (bignum is all about enhancing the math support for long numbers\, inf\, NaN etc).

AFAIK hex()/oct() are _not_ overloadable\, though\, so BigInt can't fix these things easily. That might be worth a second bug report. If people think I should file one\, just says so :) Just watch​:

  perl -Mbignum -le 'print hex( 123456789012345678->as_hex() )'   Integer overflow in hexadecimal number at -e line 1.   1.23456789012346e+17

Best wishes\,

Tels

- -- Signed on Sun Dec 19 13​:33​:39 2004 with key 0x93B84C15. Visit my photo gallery at http​://bloodgate.com/photos/ PGP key on http​://bloodgate.com/tels.asc or per email.

"Where shall I put you? Under H\, like Hot\, Sexy Mama?"

-----BEGIN PGP SIGNATURE----- Version​: GnuPG v1.2.4 (GNU/Linux)

iQEVAwUBQcV19HcLPEOTuEwVAQFGKwf/S68gVUNxTm29ZaYHzWmNtPEq6iB9o0Mf hwMy2m51yjf+TsLPiALAmicYpElCsZQkjU3TXbCBjVuQZfiQzWxWJzuiKdrInVA/ rMlP013ZQHrEyaTHjm7wZ96L/hFtN5vw7E7UuAxO7XqDhVOxSekYzeoqH6Ns4Yul my04CfiSMYdMfsh7SyDTHGDrKC7GpiXaWopGOqvCNn4rhbvIvrt5337hCjH/33pP y9ys4EZvKBGxjmk4m0QxA3chkzqQb1YbQULr2jCwjIkLHJVXlhgugOO3kryXpMtO 0/hWFWIFgyaQKJP5gpunUWO39Vtqfpx6GjIX/Wlw4jwp6pAz9x7NVA== =Q9ot -----END PGP SIGNATURE-----

p5pRT commented 19 years ago

From @iabyn

On Sun\, Dec 19\, 2004 at 01​:37​:00PM +0100\, Tels wrote​:

You are of course right about the strings. However\, hex() and oct() take happily *numbers*\, too\, but they convert them first to their string form​:

perl \-wle 'print hex\(123\)'
291
perl \-wle 'print oct\(123\)'
83

Plus and minus infinity are just a numbers. Granted\, they are special numbers\, but numbers still. And their *string form* is 'inf'\, '+inf' or '-inf'\, respectively. And since it is the same form in all bases\, their *hexadecimal string form* is 'inf'\, '-inf'\, and '+inf' respectively. (One could argue that '0xinf' should also be valid\, but I think that is a bit silly. Hm\, maybe not.)

So\, IMHO hex() and oct() should deal with the strings 'inf'\, '+inf' and 'inf'.

What about​:

  $ perl -wle '$a=1e70; $b = "$a"; $c = hex $a; print $b; print $c'   Illegal hexadecimal digit '+' ignored at -e line 1.   1e+70   30

hex() doesn't handle arbitrary stringifications of numbers\, it just handles strings containing 0-9\,a-f or thereabouts. I don't see why inf should be special-cased.

-- Wesley Crusher gets beaten up by his classmates for being a smarmy git\, and consequently has a go at making some friends of his own age for a change.   -- Things That Never Happen in "Star Trek" #18

p5pRT commented 12 years ago

@cpansprout - Status changed from 'open' to 'rejected'