(import scheme)
(import (chicken base))
(import (chicken bitwise))
(import (chicken foreign))
(import (srfi 4))

(define double->uint64
  (foreign-lambda* unsigned-integer64 ((double d))
    "uint64_t dest; memcpy(&dest, &d, sizeof(d)); C_return(dest);"))

(define (uint64->u8vector-big i)
  (u8vector (bitwise-and (arithmetic-shift i -56) #xff)
            (bitwise-and (arithmetic-shift i -48) #xff)
            (bitwise-and (arithmetic-shift i -40) #xff)
            (bitwise-and (arithmetic-shift i -32) #xff)
            (bitwise-and (arithmetic-shift i -24) #xff)
            (bitwise-and (arithmetic-shift i -16) #xff)
            (bitwise-and (arithmetic-shift i -8) #xff)
            (bitwise-and i #xff)))

(for-each
 (lambda (double)
   (let* ((integer64 (double->uint64 double))
          (fraction (bitwise-and integer64 #xfffffffffffff))
          (exponent (bitwise-and (arithmetic-shift integer64 -52) #x7ff))
          (sign (if (negative? double) '- '+))
          (binary (uint64->u8vector-big integer64)))
     (write (list double (u8vector->list binary) sign exponent fraction))
     (newline)))
 (list (atan -1) (atan 1) (expt 2.0 64) (- (expt 2.0 64))))