error on decode-int32 #20

Closed
opened 2024-01-01 15:05:51 +00:00 by byulparan · 9 comments
byulparan commented 2024-01-01 15:05:51 +00:00 (Migrated from github.com)

I met this error

(ql:quickload :osc)
(osc::decode-float32 #(127 255 255 255))

get error below

The value
-2147483649
is not of type
(SIGNED-BYTE 32)
[Condition of type TYPE-ERROR]

It seems wrong covert on osc::decode-int32.
(osc::decode-int32 (osc::encode-int32 2147483647)) ;; result is -2147483649

I think correct value of (osc::decode-int32 #(127 255 255 255)) is 2147483647

I test it other language and I got 2147483647.

;;; guile
(bytevector->sint-list
 (uint-list->bytevector '(127 255 255 255) (endianness big) 1)
 (endianness big) 4)
#include <stdio.h>
#include <string.h>

int main(int argc, char** argv) {

  char bv[4] = {127, 255, 255, 255};
  int result;
  memcpy(&result, bv, sizeof(result));

  printf("decode value: %d\n", htonl(result));
  
  return 0;  
}
I met this error ```lisp (ql:quickload :osc) (osc::decode-float32 #(127 255 255 255)) ``` get error below ``` The value -2147483649 is not of type (SIGNED-BYTE 32) [Condition of type TYPE-ERROR] ``` It seems wrong covert on `osc::decode-int32`. `(osc::decode-int32 (osc::encode-int32 2147483647)) ;; result is -2147483649` I think correct value of `(osc::decode-int32 #(127 255 255 255))` is `2147483647` I test it other language and I got `2147483647`. ```scheme ;;; guile (bytevector->sint-list (uint-list->bytevector '(127 255 255 255) (endianness big) 1) (endianness big) 4) ``` ```c #include <stdio.h> #include <string.h> int main(int argc, char** argv) { char bv[4] = {127, 255, 255, 255}; int result; memcpy(&result, bv, sizeof(result)); printf("decode value: %d\n", htonl(result)); return 0; } ```
zzkt commented 2024-01-01 22:09:34 +00:00 (Migrated from github.com)

Thanks for the report. there may be some issues with signed/unsigned ints...

(osc::decode-int32 #(127 255 255 255)) => -2147483649

(osc::decode-uint32 #(127 255 255 255)) => 2147483647

I'll have a closer look at how this works with the recent changes to floats.

Thanks for the report. there may be some issues with signed/unsigned ints... `(osc::decode-int32 #(127 255 255 255))` => `-2147483649` `(osc::decode-uint32 #(127 255 255 255))` => `2147483647` I'll have a closer look at how this works with the recent changes to floats.
PuercoPop commented 2024-01-02 00:09:14 +00:00 (Migrated from github.com)

I think correct value of (osc::decode-int32 #(127 255 255 255)) is 2147483647

I test it other language and I got 2147483647.

The tests in other languages (htonl) convert the array to unsigned int. If you use decode-uint32 you'll get the result you are expecting. However even if we use uint32

(ieee-floats:decode-float32 (osc::decode-uint32 #(127 255 255 255)))

We get

arithmetic error FLOATING-POINT-OVERFLOW signalled
Operation was (SCALE-FLOAT 1.6777215e7 105).
   [Condition of type FLOATING-POINT-OVERFLOW]

Restarts:
 0: [RETRY] Retry SLY mREPL evaluation request.
 1: [*ABORT] Return to SLY's top level.
 2: [ABORT] abort thread (#<THREAD tid=20923 "sly-channel-1-mrepl-remote-1" RUNNING {100868D6B3}>)

Backtrace:
 0: (SB-KERNEL::SCALE-SINGLE-FLOAT-MAYBE-OVERFLOW 1.6777215e7 105)
 1: (IEEE-FLOATS:DECODE-FLOAT32 2147483647)
 2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (IEEE-FLOATS:DECODE-FLOAT32 (OSC::DECODE-UINT32 #(127 255 255 255))) #<NULL-LEXENV>)

By bits does the ieee-float API means it expects an unsigned-integer?

> I think correct value of (osc::decode-int32 #(127 255 255 255)) is 2147483647 > > I test it other language and I got 2147483647. The tests in other languages (htonl) convert the array to unsigned int. If you use decode-uint32 you'll get the result you are expecting. However even if we use uint32 > (ieee-floats:decode-float32 (osc::decode-uint32 #(127 255 255 255))) We get ``` arithmetic error FLOATING-POINT-OVERFLOW signalled Operation was (SCALE-FLOAT 1.6777215e7 105). [Condition of type FLOATING-POINT-OVERFLOW] Restarts: 0: [RETRY] Retry SLY mREPL evaluation request. 1: [*ABORT] Return to SLY's top level. 2: [ABORT] abort thread (#<THREAD tid=20923 "sly-channel-1-mrepl-remote-1" RUNNING {100868D6B3}>) Backtrace: 0: (SB-KERNEL::SCALE-SINGLE-FLOAT-MAYBE-OVERFLOW 1.6777215e7 105) 1: (IEEE-FLOATS:DECODE-FLOAT32 2147483647) 2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (IEEE-FLOATS:DECODE-FLOAT32 (OSC::DECODE-UINT32 #(127 255 255 255))) #<NULL-LEXENV>) ``` By bits does the ieee-float API means it expects an unsigned-integer?
PuercoPop commented 2024-01-02 02:44:55 +00:00 (Migrated from github.com)

The vector in question basically is every bit but the sign bit set to 1. Using sbcl's API I get

(sb-kernel:make-single-float 2147483647)
#<SINGLE-FLOAT quiet NaN> (<error echoing>)

so it does look the array does not encode a valid float

@byulparan What number are you expecting 2147483647 (#x7FFF ) to represent?

The vector in question basically is every bit but the sign bit set to 1. Using sbcl's API I get ``` (sb-kernel:make-single-float 2147483647) #<SINGLE-FLOAT quiet NaN> (<error echoing>) ``` so it does look the array does not encode a valid float @byulparan What number are you expecting 2147483647 (`#x7FFF `) to represent?
byulparan commented 2024-01-02 11:45:47 +00:00 (Migrated from github.com)

I think (osc::decode-float32 #(127 255 255 255)) should be return NaN.

I think `(osc::decode-float32 #(127 255 255 255))` should be return `NaN`.
zzkt commented 2024-01-02 12:29:47 +00:00 (Migrated from github.com)

I've updated the code to use ieee-floats and floats should work more reliably since f9625946fd. If you can checkout the recent changes on the core branch let me know if it works for you...

so, (osc::decode-float32 #(127 255 255 255)) should now return :NOT-A-NUMBER (ieee-floats returns :keywords since there isn't a standard representation of NaN) it also means that -0e0, -0d0, :positive-infinity and :negative-infinity should be decoded correctly.

There are some more extensive tests for float32 and float64 in osc-tests.lisp

I've updated the code to use [ieee-floats](https://ieee-floats.common-lisp.dev/) and floats should work more reliably since f9625946fd06d9015247fe5902586638d51213a8. If you can checkout the recent changes on the `core` branch let me know if it works for you... so, `(osc::decode-float32 #(127 255 255 255))` should now return `:NOT-A-NUMBER` (ieee-floats returns :keywords since there isn't a standard representation of NaN) it also means that -0e0, -0d0, `:positive-infinity` and `:negative-infinity` should be decoded correctly. There are some more extensive tests for float32 and float64 in [osc-tests.lisp](https://github.com/zzkt/osc/blob/core/osc-tests.lisp)
byulparan commented 2024-01-02 17:34:32 +00:00 (Migrated from github.com)

I checkout recent version and (osc::decode-float32 #(127 255 255 255)) is return :NOT-A-NUMBER now😄

I'll wait resolve issues with signed/unsigned ints.
(osc::decode-int32 #(127 255 255 255)) != (osc::decode-uint32 #(127 255 255 255))

I checkout recent version and `(osc::decode-float32 #(127 255 255 255))` is return `:NOT-A-NUMBER` now😄 I'll wait resolve issues with signed/unsigned ints. `(osc::decode-int32 #(127 255 255 255))` != `(osc::decode-uint32 #(127 255 255 255))`
PuercoPop commented 2024-01-02 18:13:12 +00:00 (Migrated from github.com)

I'll wait resolve issues with signed/unsigned ints.
(osc::decode-int32 #(127 255 255 255)) != (osc::decode-uint32 #(127 255 255 255))

iiuc the issue is that 127 255 255 255 has the sign bit set to 0 so it should not be a negative number. If that is so the issue is an off by 1 error.

modified   osc.lisp
@@ -310,7 +310,7 @@ (defint-encoder 8 "Convert an integer into a sequence of 8 bytes in network byte
 (defun decode-int32 (s)
   "4 byte -> 32 bit int -> two's complement (in network byte order)"
   (let ((i (decode-uint32 s)))
-    (if (>= i #.(1- (expt 2 31)))
+    (if (>= i #.(expt 2 31))
         (- (- #.(expt 2 32) i))
         i)))
> I'll wait resolve issues with signed/unsigned ints. (osc::decode-int32 #(127 255 255 255)) != (osc::decode-uint32 #(127 255 255 255)) iiuc the issue is that 127 255 255 255 has the sign bit set to 0 so it should not be a negative number. If that is so the issue is an off by 1 error. ```patch modified osc.lisp @@ -310,7 +310,7 @@ (defint-encoder 8 "Convert an integer into a sequence of 8 bytes in network byte (defun decode-int32 (s) "4 byte -> 32 bit int -> two's complement (in network byte order)" (let ((i (decode-uint32 s))) - (if (>= i #.(1- (expt 2 31))) + (if (>= i #.(expt 2 31)) (- (- #.(expt 2 32) i)) i))) ```
zzkt commented 2024-01-02 19:19:09 +00:00 (Migrated from github.com)

yes @PuercoPop is correct, changes added at f647738ccc, both the following should now be true...

 (equalp (osc::decode-int32 #(127 255 255 255)) (osc::decode-uint32 #(127 255 255 255))))
(equalp (osc::decode-int32 #(127 255 255 255)) #x7FFFFFFF))
yes @PuercoPop is correct, changes added at f647738ccc22925ed740a8ca9132fda76a05baeb, both the following should now be true... ```lisp (equalp (osc::decode-int32 #(127 255 255 255)) (osc::decode-uint32 #(127 255 255 255)))) ``` ```lisp (equalp (osc::decode-int32 #(127 255 255 255)) #x7FFFFFFF)) ```
byulparan commented 2024-01-02 21:05:18 +00:00 (Migrated from github.com)

Thank you! I will close this issue 😃

Thank you! I will close this issue 😃
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: zzkt/osc#20
No description provided.