From 43db25440ca40cd9752d8465c8cb1fed6e8ebc4e Mon Sep 17 00:00:00 2001 From: benibus Date: Mon, 11 Sep 2023 18:04:11 -0400 Subject: [PATCH] Additions to `arrow.float16` pkg --- go/arrow/float16/float16.go | 29 +++++++++++++++++++++++ go/arrow/float16/float16_test.go | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/go/arrow/float16/float16.go b/go/arrow/float16/float16.go index 4e03d13df0cae..184cf9d153287 100644 --- a/go/arrow/float16/float16.go +++ b/go/arrow/float16/float16.go @@ -17,6 +17,7 @@ package float16 import ( + "encoding/binary" "math" "strconv" ) @@ -29,6 +30,11 @@ type Num struct { bits uint16 } +var ( + MaxNum = Num{bits: 0b0111101111111111} + MinNum = MaxNum.Negate() +) + // New creates a new half-precision floating point value from the provided // float32 value. func New(f float32) Num { @@ -86,6 +92,11 @@ func (n Num) Div(rhs Num) Num { return New(n.Float32() / rhs.Float32()) } +// Equal returns true if the value represented by n is == other +func (n Num) Equal(other Num) bool { + return n.Float32() == other.Float32() +} + // Greater returns true if the value represented by n is > other func (n Num) Greater(other Num) bool { return n.Float32() > other.Float32() @@ -161,5 +172,23 @@ func (n Num) Sign() int { return -1 } +func (n Num) Signbit() bool { return (n.bits & 0x8000) != 0 } + +func (n Num) IsNaN() bool { return (n.bits & 0x7fff) > 0x7c00 } + func (f Num) Uint16() uint16 { return f.bits } func (f Num) String() string { return strconv.FormatFloat(float64(f.Float32()), 'g', -1, 32) } + +func FromLEBytes(src []byte) Num { + return Num{bits: binary.LittleEndian.Uint16(src)} +} + +func (f Num) PutLEBytes(dst []byte) { + binary.LittleEndian.PutUint16(dst, f.bits) +} + +func (f Num) ToLEBytes() []byte { + dst := make([]byte, 2) + f.PutLEBytes(dst) + return dst +} diff --git a/go/arrow/float16/float16_test.go b/go/arrow/float16/float16_test.go index 55c3ea8b30404..c1d1f4f2e3c50 100644 --- a/go/arrow/float16/float16_test.go +++ b/go/arrow/float16/float16_test.go @@ -248,3 +248,43 @@ func TestSign(t *testing.T) { }) } } + +func TestSignbit(t *testing.T) { + for _, tc := range []struct { + n Num + want bool + }{ + {Num{bits: 0x4580}, false}, // 5.5 + {Num{bits: 0x0000}, false}, // 0 + {Num{bits: 0x8000}, true}, // -0 + {Num{bits: 0xC580}, true}, // -5.5 + } { + t.Run("signbit", func(t *testing.T) { + n := tc.n.Signbit() + if got, want := n, tc.want; got != want { + t.Fatalf("invalid value. got=%v, want=%v", got, want) + } + }) + } +} + +func TestIsNaN(t *testing.T) { + for _, tc := range []struct { + n Num + want bool + }{ + {Num{bits: 0x7c00}, false}, // inf + {Num{bits: 0xfc00}, false}, // -inf + {Num{bits: 0x7c01}, true}, // nan + {Num{bits: 0xfc01}, true}, // -nan + {Num{bits: 0x7e00}, true}, // nan + {Num{bits: 0xfe00}, true}, // -nan + } { + t.Run("isnan", func(t *testing.T) { + n := tc.n.IsNaN() + if got, want := n, tc.want; got != want { + t.Fatalf("invalid value. got=%v, want=%v", got, want) + } + }) + } +}