Since I'm learning Go, so rewrote reading IBM 32bit floating point as in last post in GO:
package ibmtools
import "math"
const p24 = 2 << 23
func Ibm32frombits(b [4]byte) float64 {
ui := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
sign := 1 - 2*float64(ui>>31&0x01)
exponent := math.Pow(16.0, float64(ui>>24&0x7f)-64.0)
mantissa := float64(ui&0x00ffffff) / float64(p24)
return math.Copysign(mantissa*exponent, sign)
}
You can go to https://github.com/jackielii/ibmtools to view the full source or use gointall to install it.
I also did some speed tests:
Python:
p24 = pow(2, 24)
def ibm2ieee(ibm):
""" read an IBM floating point number. """
sign = ibm >> 31 & 0x01
exponent = ibm >> 24 & 0x7f
mantissa = ibm & 0x00ffffff
mantissa = (mantissa * 1.0) / p24
ieee = (1 - 2 * sign) * mantissa * pow(16, exponent - 64)
return ieee
And run it using:
nemo@EliteBook:~/workspace$ python -m timeit "from testibm import ibm2ieee" "ibm2ieee(0b11000010011101101010000000000000)" 1000000 loops, best of 3: 1.62 usec per loop
Test Go using:
package ibmtools
import (
"testing"
// "strconv"
)
var (
bit = "11000010011101101010000000000000"
by = [4]byte{194, 118, 160, 0}
)
func BenchmarkIbm2ieee(b *testing.B) {
for i := 0; i < b.N; i++ {
Ibm32frombits(by)
}
}
nemo@EliteBook:~/workspace/ibmtools$ gomake bench gotest -test.bench=. -test.run="Do not run tests" rm -f _test/ibmtools.a 6g -p ibmtools -o _gotest_.6 ebcdic.go ibmfloat.go ibmtools_test.go rm -f _test/ibmtools.a gopack grc _test/ibmtools.a _gotest_.6 PASS ibmtools.BenchmarkIbm2ieee 20000000 90.3 ns/op
Result: Python 1.62 us = 1620 ns, and Go 90.3 ns. Go is around 17 times faster.
I know it's not a fair comparison, but it's illustrative.
No comments:
Post a Comment