One Of These Things Is Not Like The Others

davorg on 2007-10-23T14:36:07

This was brought up in a discussion at work today. Spot the odd one out.

(Oracle)
SQL> select BITAND(1798729892926983663,268435455) from dual;

BITAND(1798729892926983663,268435455)
-------------------------------------
                            181013999

$ python
>>> 1798729892926983663 & 268435455
181013999

$ ruby
print 1798729892926983663 & 268435455
181013999

$ perl -le 'print 1798729892926983663 & 268435455'
268435455

Of course, you can always use:

$ perl -Mbignum -le 'print 1798729892926983663 & 268435455'
181013999

But it's a bit embarassing that it doesn't Just Work.


Agreed...

bluto on 2007-10-23T17:46:45

FWIW this also works fine when 64-bit ints are compiled in -- which IMO should be the default whenever it's available.

Re:Agreed...

davorg on 2007-10-23T18:06:21

Oh, I hadn't thought of that. I wonder if it's just that Perl hasn't been built with 64-bit support but the others have.

Re:Agreed...

btilly on 2007-10-25T00:10:45

No, it is not how the language is compiled.

Ruby borrowed an idea from Smalltalk. Small integers are of type Fixnum, and it automatically promotes results above about a billion to Bignum on the fly. (IIRC, it has to reserve one bit for the sign and one for some internal bookkeeping.) As a result integer operations with Ruby are always exact. There is some overhead for this scheme, but there are tricks that make it less than you think. (Again, these tricks were worked out for Smalltalk.)

Given that Python and Ruby both give the same answer for 2**100 & 3**100 (namely 1267650600228229401496703205376) I'm confident that Python is doing exact arithmetic as well.

Hmm

acme on 2007-10-24T14:52:53

I did wonder how hard it'd be to make Perl's numbers use the equivalent of bignum/bigfloat internally...

Who needs bignums?

n1vux on 2007-10-27T00:25:43

Works for me on a 10+ year old system with the default perl.

wdr@tropo:~$ perl -le 'print 1798729892926983663 & 268435455'
181013999

Of course, I cheat a little ...

wdr@tropo:~$  perl -MConfig -le 'print "$_:$Config{$_}" for sort grep /use64/, keys %Config'
use64bitall:define
use64bitint:define

wdr@tropo:~$ perl -v | head -2

This is perl, v5.8.4 built for alpha-linux-thread-multi
DEC Alpha was born 64bit pure, so Debian installs Perl 64bit on Alpha.