Lisp HUG Maillist Archive

Re: Convert integer to signed 32bits representation

Hi,

   I did it this way:

  The result of the crc32 calculation is always a integer with the
  length of 32. I presume the sign bit is on bit position 32 so i
  did it this way:

  (defconstant 2^31 (expt 2 31))
  (defun uint32-to-sint32 (num)
         (if (< num 2^31)
             num                ; bit 32 not set
             (- (- num 2^31)))  ; bit 32 set

  (UINT32-TO-SINT32 2581689048) => -434205400
             
  simon hickley sent me this (thanks simon)

(defconstant 2^32 (expt 2 32))

(defun get-crc (num)
   (let ((val (rem num 2^32))
         (sign (floor (coerce (/ num 2^32) 'float))))
     (if (evenp sign)
         val
       (- val))))

  (get-crc 2581689048) => 2581689048

  and Paul sent this (also thanks paul:
  (logior (ash -1 31) 2581689048) => -1713278248

  aha, but who's right?
  

-- 
Met vriendelijke groet,
 Steven
www.interstudio.nl

Re: Convert integer to signed 32bits representation

Steven Manschot <steven@manschot.net> writes:

> Hi,
>
>    I did it this way:
>
>   The result of the crc32 calculation is always a integer with the
>   length of 32. I presume the sign bit is on bit position 32 so i
>   did it this way:
>
>   (defconstant 2^31 (expt 2 31))
>   (defun uint32-to-sint32 (num)
>          (if (< num 2^31)
>              num                ; bit 32 not set
>              (- (- num 2^31)))  ; bit 32 set

No need to presume where the sign bit is, that's how 2's complement
works.  I like your solution because it follows the definition of
2's complement.  You can simplify that last term, though. 

;; I *think* I typed these right.
(declaim (ftype (function ((integer 0 4294967296)) 
                           (integer -2147483648 2147483647)) 
                 uint32-to-sint32)
         (inline uint32-to-sint32))

(defun uint32-to-sint32 (num)
  (declare (type (integer 0 4294967296) num))
  (if (>= num 2^31)
      (- 2^31 num)  ; by definition of 2's complement
      num))         

Don't forget the declarations.

>   (UINT32-TO-SINT32 2581689048) => -434205400
>              
>   simon hickley sent me this (thanks simon)
>
> (defconstant 2^32 (expt 2 32))
>
> (defun get-crc (num)
>    (let ((val (rem num 2^32))
>          (sign (floor (coerce (/ num 2^32) 'float))))
>      (if (evenp sign)
>          val
>        (- val))))
>
>   (get-crc 2581689048) => 2581689048
>
>   and Paul sent this (also thanks paul:
>   (logior (ash -1 31) 2581689048) => -1713278248
>
>   aha, but who's right?

logior is wrong.  logxor would be right.


Updated at: 2020-12-10 08:58 UTC