[Top][All Lists]
[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
]
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Help-smalltalk] [PATCH] Improve endianness detection for Floats,
Paolo Bonzini <=