git.lucas.co / go_mono
git clone https://git.lucas.co/go_mono.git

commitc4e9f1b429ee836dd44e8437890c55f4b9106687
parent0991244d9d
authorNigel Tao <nigeltao@golang.org>
date2016-04-10 13:59
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)
+		}
 	}
 }