[PATCH] Improve endianness detection for Floats

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] Improve endianness detection for Floats

Paolo Bonzini
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  <[hidden email]>

        * 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
     ]




_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk