help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-smalltalk] [PATCH] Improve endianness detection for Floats


From: Paolo Bonzini
Subject: [Help-smalltalk] [PATCH] Improve endianness detection for Floats
Date: Thu, 29 Nov 2007 09:35:00 +0100
User-agent: Thunderbird 2.0.0.9 (Macintosh/20071031)

This detects the ARM's middle-endian format for FloatDs (issue 107). I don't know if it fixes the ia64 failure (and I don't think so).

Paolo
2007-11-29  Paolo Bonzini  <address@hidden>

        * kernel/FloatD.st: Fix #signByte, add #fromBytes:.
        * kernel/FloatE.st: Fix #signByte, add #fromBytes:.
        * kernel/FloatQ.st: Fix #signByte.
        * tests/floatmath.st: Use #fromBytes:.


--- orig/kernel/FloatD.st
+++ mod/kernel/FloatD.st
@@ -48,13 +48,33 @@ accuracy as C''s "double" numbers.'>
     FloatD class >> signByte [
        "Answer the byte of the receiver that contains the sign bit"
 
-       <category: 'byte-order dependancies'>
+       <category: 'byte-order dependencies'>
        ^##(| n k |
-       n := 0.0.
-       1 to: n size do: [:i | (n at: i) = 128 ifTrue: [k := i]].
+       n := -2.0.
+       1 to: n size do: [:i | (n at: i) >= 128 ifTrue: [k := i]].
        k)
     ]
 
+    FloatD class >> fromBytes: aByteArray [
+       "Answer a float with the bytes in aByteArray, which are in
+        big-endian format."
+
+       <category: 'byte-order dependencies'>
+       | b permutation |
+       permutation := ##(| signByte perm |
+           signByte := FloatD signByte.
+           signByte = 1 ifTrue: [ perm := #[1 2 3 4 5 6 7 8] ].
+           signByte = 4 ifTrue: [ perm := #[4 3 2 1 8 7 6 5] ].
+           signByte = 5 ifTrue: [ perm := #[5 6 7 8 1 2 3 4] ].
+           signByte = 8 ifTrue: [ perm := #[8 7 6 5 4 3 2 1] ].
+           perm).
+       b := FloatD new: 8.
+       1 to: 8 do: [ :i |
+           b at: i put: (aByteArray at: (permutation at: i)) ].
+       b makeReadOnly: true.
+       ^b
+    ]
+
     FloatD class >> precision [
        "Answer the number of bits in the mantissa. 1 + (2^-precision) = 1"
 


--- orig/kernel/FloatE.st
+++ mod/kernel/FloatE.st
@@ -50,11 +50,29 @@ accuracy as C''s "float" numbers.'>
 
        <category: 'byte-order dependancies'>
        ^##(| n k |
-       n := 0.0e.
-       1 to: n size do: [:i | (n at: i) = 128 ifTrue: [k := i]].
+       n := -2.0e.
+       1 to: n size do: [:i | (n at: i) >= 128 ifTrue: [k := i]].
        k)
     ]
 
+    FloatE class >> fromBytes: aByteArray [
+        "Answer a float with the bytes in aByteArray, which are in
+         big-endian format."
+
+        <category: 'byte-order dependencies'>
+        | b permutation |
+        permutation := ##(| signByte perm |
+            signByte := FloatE signByte.
+            signByte = 1 ifTrue: [ perm := #[1 2 3 4] ].
+            signByte = 4 ifTrue: [ perm := #[4 3 2 1] ].
+            perm).
+        b := FloatE new: 4.
+        1 to: 4 do: [ :i |
+            b at: i put: (aByteArray at: (permutation at: i)) ].
+        b makeReadOnly: true.
+        ^b
+    ]
+
     FloatE class >> e [
        "Returns the value of e. Hope is that it is precise enough"
 


--- orig/kernel/FloatQ.st
+++ mod/kernel/FloatQ.st
@@ -50,8 +50,8 @@ accuracy as C''s "long double" numbers.'
 
        <category: 'byte-order dependancies'>
        ^##(| n k |
-       n := 0.0q.
-       1 to: n size do: [:i | (n at: i) = 128 ifTrue: [k := i]].
+       n := -2.0q.
+       1 to: n size do: [:i | (n at: i) >= 128 ifTrue: [k := i]].
        k)
     ]
 


--- orig/tests/floatmath.st
+++ mod/tests/floatmath.st
@@ -173,10 +173,8 @@ Eval [
   
 Float class extend [
     test: bytes [
-       | b f |
-       b := Memory bigEndian ifTrue: [ bytes reverse ] ifFalse: [ bytes ].
-       f := self new: b size.
-       1 to: f size do: [ :i | f at: i put: (b at: i) ].
+       | f |  "for historical results this uses little endian, reverse here."
+       f := self fromBytes: bytes reverse.
         (true->f) printNl.
        ^f
     ]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]