Fix #181: float32 accuracy issue (#196)

* Fix #181: float32 accuracy issue

* Fix go fmt failure

* Add the unit test case for Issue181

* Add encFloat32 in double.go to encode float32 type

- Call encFloat32 to encode float32 while encoding
- Add unit test case to test float32 encoding

* Improve encFloat32 of double.go

* Fix git fmt failure
diff --git a/double.go b/double.go
index d70c682..376a1f4 100644
--- a/double.go
+++ b/double.go
@@ -20,6 +20,7 @@
 import (
 	"encoding/binary"
 	"math"
+	"strconv"
 )
 
 import (
@@ -62,6 +63,38 @@
 		byte(bits>>32), byte(bits>>24), byte(bits>>16), byte(bits>>8), byte(bits))
 }
 
+func encFloat32(b []byte, v float32) []byte {
+	fv := float32(int32(v))
+	if fv == v {
+		iv := int32(v)
+		switch iv {
+		case 0:
+			return encByte(b, BC_DOUBLE_ZERO)
+		case 1:
+			return encByte(b, BC_DOUBLE_ONE)
+		}
+		if iv >= -0x80 && iv < 0x80 {
+			return encByte(b, BC_DOUBLE_BYTE, byte(iv))
+		} else if iv >= -0x8000 && iv < 0x8000 {
+			return encByte(b, BC_DOUBLE_SHORT, byte(iv>>8), byte(iv))
+		}
+
+		goto END
+	}
+
+END:
+	if float32(int32(v*1000)) == v*1000 {
+		iv := int32(v * 1000)
+		return encByte(b, BC_DOUBLE_MILL, byte(iv>>24), byte(iv>>16), byte(iv>>8), byte(iv))
+	} else {
+		str := strconv.FormatFloat(float64(v), 'f', -1, 32)
+		d, _ := strconv.ParseFloat(str, 64)
+		bits := math.Float64bits(d)
+		return encByte(b, BC_DOUBLE, byte(bits>>56), byte(bits>>48), byte(bits>>40),
+			byte(bits>>32), byte(bits>>24), byte(bits>>16), byte(bits>>8), byte(bits))
+	}
+}
+
 /////////////////////////////////////////
 // Double
 /////////////////////////////////////////
diff --git a/double_test.go b/double_test.go
index 111124b..43e9391 100644
--- a/double_test.go
+++ b/double_test.go
@@ -42,6 +42,33 @@
 	t.Logf("decode(%v) = %v, %v\n", v, res, err)
 }
 
+func TestIssue181(t *testing.T) {
+	var (
+		v   float32
+		err error
+		e   *Encoder
+		d   *Decoder
+		res interface{}
+	)
+
+	e = NewEncoder()
+	v = 99.8
+	e.Encode(v)
+	if len(e.Buffer()) == 0 {
+		t.Fail()
+	}
+
+	// res would be '99.800003' without patches in PR #196
+	d = NewDecoder(e.Buffer())
+	res, err = d.Decode()
+	f := res.(float64)
+	if float32(f) != v {
+		t.Errorf("decode(%v) = %v, %v\n", v, res, err)
+		return
+	}
+	t.Logf("decode(%v) = %v\n", v, res)
+}
+
 func TestDouble(t *testing.T) {
 	testDecodeFramework(t, "replyDouble_0_0", 0.0)
 	testDecodeFramework(t, "replyDouble_0_001", 0.001)
diff --git a/encode.go b/encode.go
index fbeae99..ad9d5c6 100644
--- a/encode.go
+++ b/encode.go
@@ -112,7 +112,7 @@
 		}
 
 	case float32:
-		e.buffer = encFloat(e.buffer, float64(val))
+		e.buffer = encFloat32(e.buffer, val)
 
 	case float64:
 		e.buffer = encFloat(e.buffer, val)