Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to get 64 bit integer in common lisp?

I want to write a bitboard in common lisp, so I need a 64 bit integer. How do I get a 64 bit integer in common lisp? Also, are there any libraries that could help me accomplish this without writing everything from scratch?

like image 331
Mark Avatar asked Dec 30 '11 00:12

Mark


People also ask

What is the 64-bit integer number?

A 64-bit signed integer. It has a minimum value of -9,223,372,036,854,775,808 and a maximum value of 9,223,372,036,854,775,807 (inclusive).

Can Python handle 64-bit integers?

Unlike NumPy, the size of Python's int is flexible. This means Python integers may expand to accommodate any integer and will not overflow. If 64-bit integers are still too small the result may be cast to a floating point number. Floating point numbers offer a larger, but inexact, range of possible values.

What is 64-bit integer in C?

The long long data type makes handling 64 bit integers easy. In C language, an unsigned number over 32 bits cannot exceed the value of 4,294,967,295. You may find you are required to handle larger numbers and for this you need these numbers to be coded in 64-bit.

What is 64-bit integer in Java?

The size of an int in Java is completely independent of the 32-bitness or 64-bitness of a JDK. It is always 4 bytes = 32 bits = −2,147,483,648 to 2,147,483,647. If you want a 64-bit integer, use a long , which is always 64 bits = 8 bytes.


1 Answers

You can declare your variables to be of type (signed-byte 64) or (unsigned-byte 64):

CL-USER> (typexpand '(unsigned-byte 64))
(INTEGER 0 18446744073709551615)
T
CL-USER> (typexpand '(signed-byte 64))
(INTEGER -9223372036854775808 9223372036854775807)
T

It depends upon your implementation if it is actually clever enough to really stuff this in 8 consecutive bytes or if it will use a bignum for this. Appropriate optimize-declarations might help.

Here's a (very simple) example of such type declarations, and handling integers in binary:

(let* ((x #b01)
       (y #b10)
       (z (logior x y)))
  (declare ((signed-byte 64) x y z))
  (format t "~a~%" (logbitp 1 x))
  (format t "~a~%" (logbitp 1 (logior x (ash 1 1))))
  (format t "~b~%" z))

Output:
NIL
T
11

Here's a setf-expander definition to get a simple setter for bits in integers, and a corresponding getter:

(define-setf-expander logbit (index place &environment env)
  (multiple-value-bind (temps vals stores store-form access-form)
      (get-setf-expansion place env)
    (let ((i (gensym))
          (store (gensym))
          (stemp (first stores)))
      (values `(,i ,@temps)
              `(,index ,@vals)
              `(,store)
              `(let ((,stemp (dpb ,store (byte 1 ,i) ,access-form))
                     ,@(cdr stores))
                 ,store-form
                 ,store)
              `(logbit ,i ,access-form)))))

(defun logbit (index integer)
  (ldb (byte 1 index) integer))

These can be used like this:

(let ((x 1))
  (setf (logbit 3 x) 1)
  x)
==> 9
(let ((x 9))
  (setf (logbit 3 x) 0)
  x)
==> 1

(logbit 3 1)
==> 0
(logbit 3 9)
==> 1
like image 169
Rörd Avatar answered Sep 28 '22 04:09

Rörd