2016年12月14日 星期三

智能电表IEEE754 32位浮点格式

非常关键:其中尾数等于frac/2^23

下面的实例,尾数部分都计算错误了
实例1
实例二

=>3C F5 C2 8F
=> 0011 1100 1111 0101 1100 0010 1000 1111
=> 0011 1100 1111 0101 1100 0010 1000 1111
=>0 01111001  111 0101 1100 0010 1000 1111
=>+ 121 0.7717519
=>(1+0.7717519)*2^(121-127)
=>1.7717519*(1/64)
=>0.0276836
=>0.03


=>3D 23 D7 0A
=> 0011 1101 0010 0011 1101 0111 0000 1010
=>0 01111010  010 0011 1101 0111 0000 1010
=>+ 122 0.2348810
=>(1+0.2348810)*2^(122-127)
=>1.2348810*(1/32)
=>0.03859
=>0.04

==>62 25 153 153
==>3E 19 99 99
==>0011 1110 0001 1001 1001 1001 1001 1001
==>0 01111100  001 1001 1001 1001 1001 1001
==>+ 11001110  001 1001 1001 1001 1001 1001
==>+ 124 0.1677721
==>(1+0.1677721)*2^(124-127)
==>1.1677721*(1/8)
==>0.1459715125
==>0.15

==>61 117 194 143
==>0011 1101 0
==>0 01111010 111 0101 11000010 1000 1111
==>0 01111010 111 0101 11000010 1000 1111
==>+ 122 0.7717519
==>(1+0.7717519)*2(122-127)
==>1.7717519*(1/32)
==>0.055367246875
==>0.06

下面go语言实现的ieee 754 1985 32位单精度 16进制转转换算法
package util

import (
	"math"
)

/*
	ieee 754 1985 32位单精度 16进制转转换算法
	程子清
	2015-04-15
*/
type Dec32 uint32

type Dec64 uint64

const (
	S_MASK64 = 0x8000000000000000
	E_MASK64 = 0x7FF0000000000000
	M_MASK64 = 0xFFFFFFFFFFFFF

	S_OFFSET64 = 63
	E_OFFSET64 = 52

	S_MASK32 = 0x80000000
	E_MASK32 = 0x7F800000
	M_MASK32 = 0x7FFFFF

	S_OFFSET32 = 31
	E_OFFSET32 = 23
)

func (d Dec32) s() float64 {
	return float64((uint32(d) & S_MASK32) >> S_OFFSET32)
}
func (d Dec32) e() int {
	return int((uint32(d) & E_MASK32) >> E_OFFSET32)
}
func (d Dec32) m() float64 {
	fraction := uint32(d) & M_MASK32
	m := float64(fraction) / math.Pow(2, E_OFFSET32)
	return m
}
func (d Dec32) Float32() float32 {
	S, E, M := d.s(), d.e(), d.m()
	if E != 0 && E != 255 {
		return float32(math.Pow(-1, S) * math.Pow(2, float64(E-127)) * (1 + M))
	}
	return 0
}

func (d Dec64) s() float64 {
	return float64((uint64(d) & S_MASK64) >> S_OFFSET64)
}
func (d Dec64) e() int {
	return int((uint64(d) & E_MASK64) >> E_OFFSET64)
}
func (d Dec64) m() float64 {
	fraction := uint64(d) & M_MASK64
	m := float64(fraction) / math.Pow(2, E_OFFSET64)
	return m
}
func (d Dec64) Float64() float64 {
	S, E, M := d.s(), d.e(), d.m()
	if E != 0 && E != 255 {
		return float64(math.Pow(-1, S) * math.Pow(2, float64(E-1023)) * (1 + M))
	}
	return 0
}