git clone https://git.lucas.co/go_mono.git
math/fixed: have Floor, Round and Ceil return int, not Int26_6.
Change-Id: I1714bfbaf355771fb5d01508ac1dfe11c3db927a
Reviewed-on: https://go-review.googlesource.com/21787
Reviewed-by: Rob Pike <r@golang.org>
math/fixed/fixed.go | 24 +++++++---
math/fixed/fixed_test.go | 117 +++++++++++++++++++++++++++++++++++++----------
2 files changed, 111 insertions(+), 30 deletions(-)
diff --git a/math/fixed/fixed.go b/math/fixed/fixed.go
index fe27934..df3540a 100644
--- a/math/fixed/fixed.go
+++ b/math/fixed/fixed.go
@@ -42,13 +42,19 @@ func (x Int26_6) String() string {
}
// Floor returns the greatest integer value less than or equal to x.
-func (x Int26_6) Floor() Int26_6 { return (x + 0x00) &^ 0x3f }
+//
+// Its return type is int, not Int26_6.
+func (x Int26_6) Floor() int { return int((x + 0x00) >> 6) }
// Round returns the nearest integer value to x. Ties are rounded up.
-func (x Int26_6) Round() Int26_6 { return (x + 0x20) &^ 0x3f }
+//
+// Its return type is int, not Int26_6.
+func (x Int26_6) Round() int { return int((x + 0x20) >> 6) }
// Ceil returns the least integer value greater than or equal to x.
-func (x Int26_6) Ceil() Int26_6 { return (x + 0x3f) &^ 0x3f }
+//
+// Its return type is int, not Int26_6.
+func (x Int26_6) Ceil() int { return int((x + 0x3f) >> 6) }
// Int52_12 is a signed 52.12 fixed-point number.
//
@@ -75,13 +81,19 @@ func (x Int52_12) String() string {
}
// Floor returns the greatest integer value less than or equal to x.
-func (x Int52_12) Floor() Int52_12 { return (x + 0x000) &^ 0xfff }
+//
+// Its return type is int, not Int52_12.
+func (x Int52_12) Floor() int { return int((x + 0x000) >> 12) }
// Round returns the nearest integer value to x. Ties are rounded up.
-func (x Int52_12) Round() Int52_12 { return (x + 0x800) &^ 0xfff }
+//
+// Its return type is int, not Int52_12.
+func (x Int52_12) Round() int { return int((x + 0x800) >> 12) }
// Ceil returns the least integer value greater than or equal to x.
-func (x Int52_12) Ceil() Int52_12 { return (x + 0xfff) &^ 0xfff }
+//
+// Its return type is int, not Int52_12.
+func (x Int52_12) Ceil() int { return int((x + 0xfff) >> 12) }
// P returns the integer values x and y as a Point26_6.
//
diff --git a/math/fixed/fixed_test.go b/math/fixed/fixed_test.go
index 464a449..065ab00 100644
--- a/math/fixed/fixed_test.go
+++ b/math/fixed/fixed_test.go
@@ -8,34 +8,103 @@ import (
"testing"
)
+var testCases = []struct {
+ x float64
+ s26_6 string
+ s52_12 string
+ floor int
+ round int
+ ceil int
+}{{
+ x: 0,
+ s26_6: "0:00",
+ s52_12: "0:0000",
+ floor: 0,
+ round: 0,
+ ceil: 0,
+}, {
+ x: 1,
+ s26_6: "1:00",
+ s52_12: "1:0000",
+ floor: 1,
+ round: 1,
+ ceil: 1,
+}, {
+ x: 1.25,
+ s26_6: "1:16",
+ s52_12: "1:1024",
+ floor: 1,
+ round: 1,
+ ceil: 2,
+}, {
+ x: 2.5,
+ s26_6: "2:32",
+ s52_12: "2:2048",
+ floor: 2,
+ round: 3,
+ ceil: 3,
+}, {
+ x: 63 / 64.0,
+ s26_6: "0:63",
+ s52_12: "0:4032",
+ floor: 0,
+ round: 1,
+ ceil: 1,
+}, {
+ x: -0.5,
+ s26_6: "-0:32",
+ s52_12: "-0:2048",
+ floor: -1,
+ round: +0,
+ ceil: +0,
+}, {
+ x: -4.125,
+ s26_6: "-4:08",
+ s52_12: "-4:0512",
+ floor: -5,
+ round: -4,
+ ceil: -4,
+}, {
+ x: -7.75,
+ s26_6: "-7:48",
+ s52_12: "-7:3072",
+ floor: -8,
+ round: -8,
+ ceil: -7,
+}}
+
func TestInt26_6(t *testing.T) {
- x := Int26_6(1<<6 + 1<<4)
- if got, want := x.String(), "1:16"; got != want {
- t.Errorf("String: got %q, want %q", got, want)
- }
- if got, want := x.Floor(), Int26_6(1<<6); got != want {
- t.Errorf("Floor: got %v, want %v", got, want)
- }
- if got, want := x.Round(), Int26_6(1<<6); got != want {
- t.Errorf("Round: got %v, want %v", got, want)
- }
- if got, want := x.Ceil(), Int26_6(2<<6); got != want {
- t.Errorf("Ceil: got %v, want %v", got, want)
+ for _, tc := range testCases {
+ x := Int26_6(tc.x * (1 << 6))
+ if got, want := x.String(), tc.s26_6; got != want {
+ t.Errorf("tc.x=%v: String: got %q, want %q", tc.x, got, want)
+ }
+ if got, want := x.Floor(), tc.floor; got != want {
+ t.Errorf("tc.x=%v: Floor: got %v, want %v", tc.x, got, want)
+ }
+ if got, want := x.Round(), tc.round; got != want {
+ t.Errorf("tc.x=%v: Round: got %v, want %v", tc.x, got, want)
+ }
+ if got, want := x.Ceil(), tc.ceil; got != want {
+ t.Errorf("tc.x=%v: Ceil: got %v, want %v", tc.x, got, want)
+ }
}
}
func TestInt52_12(t *testing.T) {
- x := Int52_12(1<<12 + 1<<10)
- if got, want := x.String(), "1:1024"; got != want {
- t.Errorf("String: got %q, want %q", got, want)
- }
- if got, want := x.Floor(), Int52_12(1<<12); got != want {
- t.Errorf("Floor: got %v, want %v", got, want)
- }
- if got, want := x.Round(), Int52_12(1<<12); got != want {
- t.Errorf("Round: got %v, want %v", got, want)
- }
- if got, want := x.Ceil(), Int52_12(2<<12); got != want {
- t.Errorf("Ceil: got %v, want %v", got, want)
+ for _, tc := range testCases {
+ x := Int52_12(tc.x * (1 << 12))
+ if got, want := x.String(), tc.s52_12; got != want {
+ t.Errorf("tc.x=%v: String: got %q, want %q", tc.x, got, want)
+ }
+ if got, want := x.Floor(), tc.floor; got != want {
+ t.Errorf("tc.x=%v: Floor: got %v, want %v", tc.x, got, want)
+ }
+ if got, want := x.Round(), tc.round; got != want {
+ t.Errorf("tc.x=%v: Round: got %v, want %v", tc.x, got, want)
+ }
+ if got, want := x.Ceil(), tc.ceil; got != want {
+ t.Errorf("tc.x=%v: Ceil: got %v, want %v", tc.x, got, want)
+ }
}
}