(flt -0.8) on OS X and Win

Started by Stefan, May 20, 2014, 09:22:48 AM

Previous topic - Next topic

Stefan

I need the integer representation of single-precision IEEE-754 floating-point value. My home machine is a Mac:

newLISP v.10.6.0 64-bit on OSX IPv4/6 UTF-8 libffi, options: newlisp -h

> (flt -0.8)
0

On my machine at work I get:

newLISP v.10.6.0 32-bit on Win32 IPv4/6 libffi, options: newlisp -h

> (flt -0.8)
-1085485875

which is precisely what I need (on my Mac).



Btw, in Java:

Float.floatToIntBits(-0.8f)

does exactly the same. it returns -1085485875



Is this different behavior "intended"? (I know Mac is 64-bit and Win is 32-bit)



However, how could I get the same result on my Mac? I tried several things but I had no success.



While experimenting I found also this:

newLISP v.10.6.0 32-bit on Win32 IPv4/6 libffi, options: newlisp -h

> (format "%f" -0.8)
"-0.800000"

and

newLISP v.10.6.0 64-bit on OSX IPv4/6 UTF-8 libffi, options: newlisp -h

> (format "%f" -0.8)

ERR: mismatch in number of arguments in function format : .8
>

Hmm!?



Stefan

Lutz

#1
this should work on all platforms:


>(first (unpack "ld" (pack "f" -0.8)))
-1085485875
>


In your last example, you seem to be on a locale which uses the comma ',' as decimal separator. Try:


newLISP v.10.6.0 32-bit on Win32 IPv4/6 UTF-8 libffi, options: newlisp -h

> (format "%f" -0.8)

ERR: mismatch in number of arguments in function format : .8

> (format "%f" -0,8)  ; use , as decimal separator
"-0,800000"
> (set-locale)
("German_Germany.1252" ",")

> (set-locale "C")
("C" ".")
> (format "%f" -0.8)
"-0.800000"
>


UTF8 versions don't goto to the "C" "." locale but to the locale of the current platform.

Stefan

#2
Thanks for the explanation and the code snippet for the integer representation. Although, I am not really sure what is happening there. "first" of the result of "unpack" - what is unpack in this case returning?



However, the locale dependency scares me a little bit. Should the parsing of literals not be locale independent?  Formatting and scanning of cause should be locale dependent.



Is there a possibility to automate the (set-locale "C")?



Stefan

Stefan

#3
After browsing the good documentation I found ".init.lsp" for automating this:

;; set local to the "C" locale on UTF8
(if utf8
(set-locale "C"))

;; test for 32-bit-ness
(define (bit32?)
(= (& (sys-info -1) (<< 1 9))))

;; define flt32 depending on the bit-ness
(if (bit32?)
(constant 'flt32 flt)
(define (flt32 f)
(first (unpack "ld" (pack "f" f)))))

While the locale stuff works nicely detecting the bitness does not work. It returns true on Win32 and OS X.

On OS X (sys-info -1) returns 1411 and on Win32 it returns 1030.

In both cases bit 9 is 0, i.e. 32 bit.

Is there another way for detecting this?



Stefan

Lutz

#4
Use (<< 1 8) => 256. It is bit 9 as in 1 ... 9, the 9th bit at offset 8, not bit at offset 9, which would be the 10th bit.


(define (bit32?)
    (= (& (sys-info -1) 256)))


Also the lower 32 bits will be the same for flt for 32bit newLISP and 64bit newLISP, but on 64bit newLISP and unsigned number is reported.



On both 32bit and 64bit newLISP you get the following:
> (format "%X" (flt -0.8))
"BF4CCCCD"
>


... but on 32bit versions the highest bit is taken as a sign bit giving you the negative -1085485875 while on 64bit versions you get the unsigned 3209481421. Remember the reason you got 0 was because working with a decimal dot in a comma locale on OSX UTF8.



Ps: may be the sign extension should be avoided in a future version on 32bit and an unsigned integer should always be reported.

Stefan

#5
Right! The (add 256) in
Quote
bit 9 will be set for 64-bit (changeable at runtime) versions (add 256)

(http://www.newlisp.org/downloads/newlisp_manual.html#sys-info">http://www.newlisp.org/downloads/newlis ... l#sys-info">http://www.newlisp.org/downloads/newlisp_manual.html#sys-info)

could have told me this. I really did not know how to interpret it.



ps: Currently I am glad that it is a signed integer. :-)



Thanks,

Stefan