feat(fixed): add Q32.32 deterministic fixed-point arithmetic
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
67
pkg/fixed/fixed_test.go
Normal file
67
pkg/fixed/fixed_test.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package fixed
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestFromIntAndBack(t *testing.T) {
|
||||
if got := FromInt(7).Int(); got != 7 {
|
||||
t.Fatalf("FromInt(7).Int() = %d, want 7", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMulIsExact(t *testing.T) {
|
||||
half := One / 2
|
||||
if got := half.Mul(half); got != One/4 {
|
||||
t.Fatalf("0.5*0.5 = %d, want %d", got, One/4)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMulDoesNotOverflowAtScale(t *testing.T) {
|
||||
// A naive (a*b)>>32 overflows well below this. The 128-bit intermediate
|
||||
// must handle it exactly.
|
||||
a := FromInt(100000)
|
||||
if got := a.Mul(FromInt(2)); got != FromInt(200000) {
|
||||
t.Fatalf("100000*2 = %v, want 200000", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDivIsExact(t *testing.T) {
|
||||
if got := FromInt(1).Div(FromInt(4)); got != One/4 {
|
||||
t.Fatalf("1/4 = %d, want %d", got, One/4)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNegativeMulAndDiv(t *testing.T) {
|
||||
if got := FromInt(-3).Mul(FromInt(4)); got != FromInt(-12) {
|
||||
t.Fatalf("-3*4 = %v, want -12", got)
|
||||
}
|
||||
if got := FromInt(-12).Div(FromInt(4)); got != FromInt(-3) {
|
||||
t.Fatalf("-12/4 = %v, want -3", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSqrt(t *testing.T) {
|
||||
for _, n := range []int64{0, 1, 4, 9, 16, 100, 10000} {
|
||||
want := FromInt(isqrt(n))
|
||||
got := Sqrt(FromInt(n))
|
||||
if got != want {
|
||||
t.Fatalf("Sqrt(%d) = %v, want %v", n, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isqrt(n int64) int64 {
|
||||
var r int64
|
||||
for r*r <= n {
|
||||
r++
|
||||
}
|
||||
return r - 1
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
if got := (One + One/2).String(); got != "1.500000" {
|
||||
t.Fatalf("1.5.String() = %q", got)
|
||||
}
|
||||
if got := FromInt(-2).String(); got != "-2.000000" {
|
||||
t.Fatalf("-2.String() = %q", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user