Skip to main content
deleted 1013 characters in body
Source Link
John Kitchin
  • 12.1k
  • 1
  • 23
  • 45

I need to convert a vector of float numbers to bytes. I can't seem to find a way to do that in emacs-lisp. Is it possible?

For example how do I convert this vector [3.14] to bytes?

[Update] See this comment by @dalanicolai, especially for the function IEEE-float-2-hex.

Then, see https://stackoverflow.com/questions/12003231/how-do-i-convert-a-string-of-hex-into-ascii-using-elisp for how to convert a hex string to chars.

With those two functions I can run this:

(cl-loop for char across (reverse (decode-hex-string (IEEE-float-2-hex 3.14)))
       concat (byte-to-string char))

to get a byte string (the original question), or this to write it to a file.

(with-temp-file "bin3"
  (cl-loop for char across (reverse (decode-hex-string (IEEE-float-2-hex 3.14)))
       do (insert (byte-to-string char))))

WhichThe reverse here seems related to big vs little endian. Otherwise, that seems to write a byte string to a file that represents 3.

And then this14. This python can read it correctly. I still don't know how to read it in to emacs-lisp, but that isn't something I need at the moment (I just would like to know).

#+BEGIN_SRC jupyter-python
import struct
with open('bin3', 'rb') as f:
    print(struct.unpack('f', f.read()))
#+END_SRC

#+RESULTS:
:RESULTS:
(3.1399998664855957,)
:END:

The small difference from 3.14 is from not being able to exactly represent a float number in 32 bits.

I need to convert a vector of float numbers to bytes. I can't seem to find a way to do that in emacs-lisp. Is it possible?

For example how do I convert this vector [3.14] to bytes?

[Update] See this comment by @dalanicolai, especially for the function IEEE-float-2-hex.

Then, see https://stackoverflow.com/questions/12003231/how-do-i-convert-a-string-of-hex-into-ascii-using-elisp for how to convert a hex string to chars.

With those two functions I can run this:

(with-temp-file "bin3"
  (cl-loop for char across (reverse (decode-hex-string (IEEE-float-2-hex 3.14)))
       do (insert (byte-to-string char))))

Which seems to write a byte string to a file.

And then this python can read it correctly.

#+BEGIN_SRC jupyter-python
import struct
with open('bin3', 'rb') as f:
    print(struct.unpack('f', f.read()))
#+END_SRC

#+RESULTS:
:RESULTS:
(3.1399998664855957,)
:END:

I need to convert a vector of float numbers to bytes. I can't seem to find a way to do that in emacs-lisp. Is it possible?

For example how do I convert this vector [3.14] to bytes?

[Update] See this comment by @dalanicolai, especially for the function IEEE-float-2-hex.

Then, see https://stackoverflow.com/questions/12003231/how-do-i-convert-a-string-of-hex-into-ascii-using-elisp for how to convert a hex string to chars.

With those two functions I can run this:

(cl-loop for char across (reverse (decode-hex-string (IEEE-float-2-hex 3.14)))
       concat (byte-to-string char))

to get a byte string (the original question), or this to write it to a file.

(with-temp-file "bin3"
  (cl-loop for char across (reverse (decode-hex-string (IEEE-float-2-hex 3.14)))
       do (insert (byte-to-string char))))

The reverse here seems related to big vs little endian. Otherwise, that seems to write a byte string to a file that represents 3.14. This python can read it correctly. I still don't know how to read it in to emacs-lisp, but that isn't something I need at the moment (I just would like to know).

#+BEGIN_SRC jupyter-python
import struct
with open('bin3', 'rb') as f:
    print(struct.unpack('f', f.read()))
#+END_SRC

#+RESULTS:
:RESULTS:
(3.1399998664855957,)
:END:

The small difference from 3.14 is from not being able to exactly represent a float number in 32 bits.

deleted 1013 characters in body
Source Link
John Kitchin
  • 12.1k
  • 1
  • 23
  • 45

[Update] No solution, but I have madeSee this progress.

This Python code writescomment by @dalanicolai, especially for the binary string I want:function IEEE-float-2-hex.

from struct import pack

with open('bin', 'wb') as f:
    f.write(pack('f', 3.14))

andThen, if I read this back in like this I get:see https://stackoverflow.com/questions/12003231/how-do-i-convert-a-string-of-hex-into-ascii-using-elisp for how to convert a hex string to chars.

#+BEGIN_SRC jupyter-python 
with open('bin', 'rb') as f:    
    print(int.from_bytes(f.read(1)))
    print(int.from_bytes(f.read(1)))
    print(int.from_bytes(f.read(1)))
    print(int.from_bytes(f.read(1)))
#+END_SRC

#+RESULTS:
:RESULTS:
195
245
72
64
:END:

I am not totally sure how to getWith those numbers yet, maybe they come from the link in the answer from @dalanicolai below. Nevertheless, iftwo functions I usecan run this code in elisp to make a new file:

(with-temp-file "bin2""bin3"
  (insert (byte-tocl-string 195)
 loop for char across (reverse (bytedecode-tohex-string 245)
      (byteIEEE-tofloat-string2-hex 723.14)))
       do (insert (byte-to-string 64char)))
#+END_SRC)

and IWhich seems to write a byte string to a file.

And then this python can read it correctly with.

#+BEGIN_SRC jupyter-python
import struct
with open('bin2''bin3', 'rb') as f:
    print(struct.unpack('f', f.read()))
#+END_SRC

#+RESULTS:
:RESULTS:
(3.1400001049041751399998664855957,)
:END:

So, I need to figure out how to get those integers, and then it seems like I can write binary files or make binary strings.

I don't know how to read them though. This should be correct:

#+BEGIN_SRC emacs-lisp :results code
(let ((chars '()))
  (with-temp-buffer
    (insert-file-contents-literally "bin")
    (while (not (eobp))
      (push  (char-to-string  (char-after)) chars)
      (forward-char)))
  (mapcar 'string-to-char (reverse chars)))
#+END_SRC

#+RESULTS:
#+begin_src emacs-lisp
(4194243 4194293 72 64)
#+end_src

but it reads the first two numbers incorrectly. I can't tell why.

[Update] No solution, but I have made this progress.

This Python code writes the binary string I want:

from struct import pack

with open('bin', 'wb') as f:
    f.write(pack('f', 3.14))

and, if I read this back in like this I get:

#+BEGIN_SRC jupyter-python 
with open('bin', 'rb') as f:    
    print(int.from_bytes(f.read(1)))
    print(int.from_bytes(f.read(1)))
    print(int.from_bytes(f.read(1)))
    print(int.from_bytes(f.read(1)))
#+END_SRC

#+RESULTS:
:RESULTS:
195
245
72
64
:END:

I am not totally sure how to get those numbers yet, maybe they come from the link in the answer from @dalanicolai below. Nevertheless, if I use this code in elisp to make a new file:

(with-temp-file "bin2"
  (insert (byte-to-string 195)
      (byte-to-string 245)
      (byte-to-string 72)
      (byte-to-string 64)))
#+END_SRC

and I can read it correctly with

#+BEGIN_SRC jupyter-python
import struct
with open('bin2', 'rb') as f:
    print(struct.unpack('f', f.read()))
#+END_SRC

#+RESULTS:
:RESULTS:
(3.140000104904175,)
:END:

So, I need to figure out how to get those integers, and then it seems like I can write binary files or make binary strings.

I don't know how to read them though. This should be correct:

#+BEGIN_SRC emacs-lisp :results code
(let ((chars '()))
  (with-temp-buffer
    (insert-file-contents-literally "bin")
    (while (not (eobp))
      (push  (char-to-string  (char-after)) chars)
      (forward-char)))
  (mapcar 'string-to-char (reverse chars)))
#+END_SRC

#+RESULTS:
#+begin_src emacs-lisp
(4194243 4194293 72 64)
#+end_src

but it reads the first two numbers incorrectly. I can't tell why.

[Update] See this comment by @dalanicolai, especially for the function IEEE-float-2-hex.

Then, see https://stackoverflow.com/questions/12003231/how-do-i-convert-a-string-of-hex-into-ascii-using-elisp for how to convert a hex string to chars.

With those two functions I can run this:

(with-temp-file "bin3"
  (cl-loop for char across (reverse (decode-hex-string (IEEE-float-2-hex 3.14)))
       do (insert (byte-to-string char))))

Which seems to write a byte string to a file.

And then this python can read it correctly.

#+BEGIN_SRC jupyter-python
import struct
with open('bin3', 'rb') as f:
    print(struct.unpack('f', f.read()))
#+END_SRC

#+RESULTS:
:RESULTS:
(3.1399998664855957,)
:END:
Became Hot Network Question
added 1757 characters in body
Source Link
John Kitchin
  • 12.1k
  • 1
  • 23
  • 45

I need to convert a vector of float numbers to bytes. I can't seem to find a way to do that in emacs-lisp. Is it possible?

For example how do I convert this vector [3.14] to bytes?

[Update] No solution, but I have made this progress.

This Python code writes the binary string I want:

from struct import pack

with open('bin', 'wb') as f:
    f.write(pack('f', 3.14))

and, if I read this back in like this I get:

#+BEGIN_SRC jupyter-python 
with open('bin', 'rb') as f:    
    print(int.from_bytes(f.read(1)))
    print(int.from_bytes(f.read(1)))
    print(int.from_bytes(f.read(1)))
    print(int.from_bytes(f.read(1)))
#+END_SRC

#+RESULTS:
:RESULTS:
195
245
72
64
:END:

I am not totally sure how to get those numbers yet, maybe they come from the link in the answer from @dalanicolai below. Nevertheless, if I use this code in elisp to make a new file:

(with-temp-file "bin2"
  (insert (byte-to-string 195)
      (byte-to-string 245)
      (byte-to-string 72)
      (byte-to-string 64)))
#+END_SRC

and I can read it correctly with

#+BEGIN_SRC jupyter-python
import struct
with open('bin2', 'rb') as f:
    print(struct.unpack('f', f.read()))
#+END_SRC

#+RESULTS:
:RESULTS:
(3.140000104904175,)
:END:

So, I need to figure out how to get those integers, and then it seems like I can write binary files or make binary strings.

I don't know how to read them though. This should be correct:

#+BEGIN_SRC emacs-lisp :results code
(let ((chars '()))
  (with-temp-buffer
    (insert-file-contents-literally "bin")
    (while (not (eobp))
      (push  (char-to-string  (char-after)) chars)
      (forward-char)))
  (mapcar 'string-to-char (reverse chars)))
#+END_SRC

#+RESULTS:
#+begin_src emacs-lisp
(4194243 4194293 72 64)
#+end_src

but it reads the first two numbers incorrectly. I can't tell why.

I need to convert a vector of float numbers to bytes. I can't seem to find a way to do that in emacs-lisp. Is it possible?

For example how do I convert this vector [3.14] to bytes?

I need to convert a vector of float numbers to bytes. I can't seem to find a way to do that in emacs-lisp. Is it possible?

For example how do I convert this vector [3.14] to bytes?

[Update] No solution, but I have made this progress.

This Python code writes the binary string I want:

from struct import pack

with open('bin', 'wb') as f:
    f.write(pack('f', 3.14))

and, if I read this back in like this I get:

#+BEGIN_SRC jupyter-python 
with open('bin', 'rb') as f:    
    print(int.from_bytes(f.read(1)))
    print(int.from_bytes(f.read(1)))
    print(int.from_bytes(f.read(1)))
    print(int.from_bytes(f.read(1)))
#+END_SRC

#+RESULTS:
:RESULTS:
195
245
72
64
:END:

I am not totally sure how to get those numbers yet, maybe they come from the link in the answer from @dalanicolai below. Nevertheless, if I use this code in elisp to make a new file:

(with-temp-file "bin2"
  (insert (byte-to-string 195)
      (byte-to-string 245)
      (byte-to-string 72)
      (byte-to-string 64)))
#+END_SRC

and I can read it correctly with

#+BEGIN_SRC jupyter-python
import struct
with open('bin2', 'rb') as f:
    print(struct.unpack('f', f.read()))
#+END_SRC

#+RESULTS:
:RESULTS:
(3.140000104904175,)
:END:

So, I need to figure out how to get those integers, and then it seems like I can write binary files or make binary strings.

I don't know how to read them though. This should be correct:

#+BEGIN_SRC emacs-lisp :results code
(let ((chars '()))
  (with-temp-buffer
    (insert-file-contents-literally "bin")
    (while (not (eobp))
      (push  (char-to-string  (char-after)) chars)
      (forward-char)))
  (mapcar 'string-to-char (reverse chars)))
#+END_SRC

#+RESULTS:
#+begin_src emacs-lisp
(4194243 4194293 72 64)
#+end_src

but it reads the first two numbers incorrectly. I can't tell why.

edited tags
Link
Drew
  • 79.1k
  • 10
  • 123
  • 257
Loading
Source Link
John Kitchin
  • 12.1k
  • 1
  • 23
  • 45
Loading