unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* calc-eval and lsh/logand of large numbers
@ 2014-10-27 22:58 Sam Halliday
  2014-10-28  9:34 ` Sam Halliday
  0 siblings, 1 reply; 2+ messages in thread
From: Sam Halliday @ 2014-10-27 22:58 UTC (permalink / raw)
  To: help-gnu-emacs

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


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: calc-eval and lsh/logand of large numbers
  2014-10-27 22:58 calc-eval and lsh/logand of large numbers Sam Halliday
@ 2014-10-28  9:34 ` Sam Halliday
  0 siblings, 0 replies; 2+ messages in thread
From: Sam Halliday @ 2014-10-28  9:34 UTC (permalink / raw)
  To: help-gnu-emacs

On Monday, 27 October 2014 22:58:39 UTC, Sam Halliday  wrote:
>   (require 'calc)
>   (defmath bitIndex (i)
>     (lsh 1 i))
> 
>   (calc-eval "bitIndex(64)") ; "0"
> 
> I would have expected this to return "18446744073709551616".

I got it. The default word length is 32 bits and needs to be specified explicitly for left-shift.

http://www.gnu.org/software/emacs/manual/html_node/calc/Binary-Functions.html

  (defmath bitIndex (i) 
    (lsh 1 i (+ 1 i)))




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-10-28  9:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-27 22:58 calc-eval and lsh/logand of large numbers Sam Halliday
2014-10-28  9:34 ` Sam Halliday

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).