Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions fixed.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"io"
"math"
"math/bits"
"strconv"
"strings"
)
Expand Down Expand Up @@ -231,10 +232,29 @@ func (f Fixed) Mul(f0 Fixed) Fixed {

// Div divides f by f0 returning a Fixed. If either operand is NaN, NaN is returned
func (f Fixed) Div(f0 Fixed) Fixed {
if f.IsNaN() || f0.IsNaN() {
if f.IsNaN() || f0.IsNaN() || f0.fp == 0 {
return NaN
}
return NewF(f.Float() / f0.Float())

sign, fp, fp0 := int64(1), f.fp, f0.fp

if fp < 0 {
fp, sign = -fp, -sign
}
if fp0 < 0 {
fp0, sign = -fp0, -sign
}

// Use 128-bit math to calculate fp * scale / fp0.
hi, lo := bits.Mul64(uint64(fp), uint64(scale))
quo, rem := bits.Div64(hi, lo, uint64(fp0))

// Round if remainder >= divisor/2
if rem >= uint64(fp0)/2 {
quo++
}

return Fixed{fp: int64(quo) * sign}
}

func sign(fp int64) int64 {
Expand Down
50 changes: 25 additions & 25 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,33 @@ The fixed.Fixed API uses NaN for reporting errors in the common case, since ofte
and this would be a huge pain with error handling. Since all operations involving a NaN result in a NaN,
any errors quickly surface anyway.

**Performance**
**Performance**

<pre>
using Go 1.21.5
cpu: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
BenchmarkAddFixed-8 1000000000 0.9627 ns/op 0 B/op 0 allocs/op
BenchmarkAddDecimal-8 17871763 66.52 ns/op 80 B/op 2 allocs/op
BenchmarkAddBigInt-8 125826048 9.562 ns/op 0 B/op 0 allocs/op
BenchmarkAddBigFloat-8 18763552 63.51 ns/op 48 B/op 1 allocs/op
BenchmarkMulFixed-8 335886367 3.538 ns/op 0 B/op 0 allocs/op
BenchmarkMulDecimal-8 18164803 66.12 ns/op 80 B/op 2 allocs/op
BenchmarkMulBigInt-8 100000000 10.41 ns/op 0 B/op 0 allocs/op
BenchmarkMulBigFloat-8 50151100 23.93 ns/op 0 B/op 0 allocs/op
BenchmarkDivFixed-8 328157694 3.722 ns/op 0 B/op 0 allocs/op
BenchmarkDivDecimal-8 2558497 461.7 ns/op 384 B/op 12 allocs/op
BenchmarkDivBigInt-8 33726384 34.68 ns/op 8 B/op 1 allocs/op
BenchmarkDivBigFloat-8 10757650 110.1 ns/op 24 B/op 2 allocs/op
BenchmarkCmpFixed-8 1000000000 0.2519 ns/op 0 B/op 0 allocs/op
BenchmarkCmpDecimal-8 171236422 6.926 ns/op 0 B/op 0 allocs/op
BenchmarkCmpBigInt-8 250970304 4.791 ns/op 0 B/op 0 allocs/op
BenchmarkCmpBigFloat-8 271898336 4.428 ns/op 0 B/op 0 allocs/op
BenchmarkStringFixed-8 23637406 50.30 ns/op 24 B/op 1 allocs/op
BenchmarkStringNFixed-8 23457960 51.85 ns/op 24 B/op 1 allocs/op
BenchmarkStringDecimal-8 5763308 210.2 ns/op 56 B/op 4 allocs/op
BenchmarkStringBigInt-8 11742596 114.0 ns/op 16 B/op 1 allocs/op
BenchmarkStringBigFloat-8 3003280 395.3 ns/op 176 B/op 7 allocs/op
BenchmarkWriteTo-8 38573978 43.13 ns/op 27 B/op 0 allocs/op
using Go 1.25.3
cpu: Intel(R) Core(TM) i9-10850K CPU @ 3.60GHz
BenchmarkAddFixed-20 1000000000 0.7317 ns/op 0 B/op 0 allocs/op
BenchmarkAddDecimal-20 23494767 50.49 ns/op 80 B/op 2 allocs/op
BenchmarkAddBigInt-20 146968544 8.481 ns/op 0 B/op 0 allocs/op
BenchmarkAddBigFloat-20 19393024 59.52 ns/op 48 B/op 1 allocs/op
BenchmarkMulFixed-20 233557537 4.824 ns/op 0 B/op 0 allocs/op
BenchmarkMulDecimal-20 22572376 51.77 ns/op 80 B/op 2 allocs/op
BenchmarkMulBigInt-20 100000000 10.03 ns/op 0 B/op 0 allocs/op
BenchmarkMulBigFloat-20 56131700 21.59 ns/op 0 B/op 0 allocs/op
BenchmarkDivFixed-20 57347422 20.90 ns/op 0 B/op 0 allocs/op
BenchmarkDivDecimal-20 2935522 408.3 ns/op 384 B/op 12 allocs/op
BenchmarkDivBigInt-20 42439080 27.72 ns/op 8 B/op 1 allocs/op
BenchmarkDivBigFloat-20 14065242 84.40 ns/op 8 B/op 1 allocs/op
BenchmarkCmpFixed-20 1000000000 0.2113 ns/op 0 B/op 0 allocs/op
BenchmarkCmpDecimal-20 203959459 5.651 ns/op 0 B/op 0 allocs/op
BenchmarkCmpBigInt-20 311228709 3.796 ns/op 0 B/op 0 allocs/op
BenchmarkCmpBigFloat-20 319646821 3.756 ns/op 0 B/op 0 allocs/op
BenchmarkStringFixed-20 29299454 40.59 ns/op 24 B/op 1 allocs/op
BenchmarkStringNFixed-20 29791072 39.66 ns/op 24 B/op 1 allocs/op
BenchmarkStringDecimal-20 6768283 178.1 ns/op 56 B/op 4 allocs/op
BenchmarkStringBigInt-20 12304304 93.86 ns/op 16 B/op 1 allocs/op
BenchmarkStringBigFloat-20 3670106 325.5 ns/op 152 B/op 6 allocs/op
BenchmarkWriteTo-20 46491169 27.41 ns/op 23 B/op 0 allocs/op
</pre>

The "decimal" above is the common [shopspring decimal](https://github.com/shopspring/decimal) library
Expand Down