[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
calc-eval and lsh/logand of large numbers
From: |
Sam Halliday |
Subject: |
calc-eval and lsh/logand of large numbers |
Date: |
Mon, 27 Oct 2014 15:58:37 -0700 (PDT) |
User-agent: |
G2/1.0 |
Hi all,
I was playing with calc-eval to get a feel for the arbitrary precision support
and decided to see if it could be used to represent a BitSet. If you're not
familiar with the concept, imagine a list of bits and if the N'th bit is true
then the set contains the integer N. It's reasonably efficient at storing
arbitrary collections of integers: memory requirement is specified by the
maximum value rather than the number of entries in the set.
This looked promising:
(require 'calc)
(defmath bitIndex (i)
(lsh 1 i))
(calc-eval "bitIndex(10)") ; "1024"
but when I went to a number that would be shifted beyond the 64 bit length of
an integer it all fell apart
(calc-eval "bitIndex(64)") ; "0"
I would have expected this to return "18446744073709551616".
Is this a known limitation or have I simply not understood something?
BTW, if anybody is interested I was planning on doing something like the
following. If you have a cleaner way of doing this, please let me know as I'll
be interested to hear about it. The reason I'm doing this is because I am
writing an S-Exp serialisation layer in Scala and this notation works well for
serialising Scala's BitSet's... I was curious to see if I could get it to work
in elisp:
https://github.com/fommil/ensime-server/blob/sexp/src/main/scala/org/ensime/sexp/formats/CollectionFormats.scala#L131
(defmath bitsetAnd (bitset i)
(logand (lsh 1 i) bitset))
(defun bitsetContains (bitset i)
(<= 1 (calc-eval "bitsetAnd($, $$)" 'raw bitset i)))
(bitsetContains "10#3" 0) ; 't
(bitsetContains "10#3" 1) ; 't
(bitsetContains "10#3" 2) ; nil
(bitsetContains "16#10000000000000000" 64) ; nil
(bitsetContains "16#10000000000000001" 0) ; t
(bitsetContains "16#10000000000000001" 64) ; t WRONG
(bitsetContains "16#10000000000000002" 1) ; t
(bitsetContains "16#10000000000000002" 64) ; t WRONG
(bitsetContains "16#10000000000000002" 0) ; nil
Best regards,
Sam
- calc-eval and lsh/logand of large numbers,
Sam Halliday <=