Skip to content

Commit

Permalink
dec_arith: merge 32/64 bits versions of decTrailingZeros
Browse files Browse the repository at this point in the history
Also fix edge cases in TestDec_ntz.
  • Loading branch information
db47h committed May 5, 2020
1 parent 9fea708 commit 34943d7
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 38 deletions.
5 changes: 3 additions & 2 deletions dec.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ const (
// word and 19 per 64 bits word.
_WD = _W * 30103 / 100000
// Decimal base for a word. 1e9 for 32 bits words and 1e19 for 64 bits
// words. TODO(db47h): We want this value to be a const. This is a dirty
// hack to avoid conditional compilation that will break if bits.UintSize>64
// words.
// TODO(db47h): We want this value to be a const. This is a dirty hack to
// avoid conditional compilation that will break if bits.UintSize>64
_BD = 9999999998000000000*(_WD/19) + 1000000000*(_WD/9)
)

Expand Down
35 changes: 5 additions & 30 deletions dec_arith.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,37 +75,12 @@ func shr10VU(z, x dec, s uint) (r Word) {
}

func decTrailingZeros(n uint) uint {
if bits.UintSize == 32 {
return dec32TrailingZeros(n)
}
return dec64TrailingZeros(uint64(n))
}

func dec32TrailingZeros(n uint) uint {
var d uint
if n%100000000 == 0 {
n /= 100000000
d += 8
}
if n%10000 == 0 {
n /= 10000
d += 4
}
if n%100 == 0 {
n /= 100
d += 2
}
if n%10 == 0 {
d += 1
}
return d
}

func dec64TrailingZeros(n uint64) uint {
var d uint
if n%10000000000000000 == 0 {
n /= 10000000000000000
d += 16
if bits.UintSize > 32 {
if uint64(n)%10000000000000000 == 0 {
n = uint(uint64(n) / uint64(10000000000000000))
d += 16
}
}
if n%100000000 == 0 {
n /= 100000000
Expand Down
13 changes: 7 additions & 6 deletions dec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,19 @@ import (
func TestDec_ntz(t *testing.T) {
rand.Seed(time.Now().UnixNano())
for i := 0; i < 10000; i++ {
again:
w := uint(rand.Uint64()) % _BD
// TODO: WTF? ignore anything divisible by ten since decDigits(10) = 2 but dec{100000000...}.digits() = 1
if w%10 == 0 {
goto again
}
e := uint(rand.Intn(_WD + 1))
h, l := bits.Mul(w, pow10(e))
h, l = bits.Div(h, l, _BD)
d := dec{Word(l), Word(h)}.norm()
// adjust e if w == 0 or w%10 == 0
if w == 0 {
e = 0
} else {
e += decTrailingZeros(w)
}
if d.ntz() != e {
t.Fatalf("dec{%v}.digits() = %d, expected %d", d, d.ntz(), e)
t.Fatalf("dec{%v}.ntz() = %d, expected %d", d, d.ntz(), e)
}
}
}
Expand Down

0 comments on commit 34943d7

Please sign in to comment.