Commit b1893d27 authored by Kirill Smelkov's avatar Kirill Smelkov

xmath: Addon math routines

So far only one of them: CeilPow2 to return min(y) >= x: y = 2^i - i.e.
next power of two >= x. This is handy to have in reallocation routines
to allocate buffers from 2^i classes.

Two implementations:

- fast for go19
- slower fallback for go18
parent 7deb28a5
// Copyright (C) 2017 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Open Source Initiative approved licenses and Convey
// the resulting work. Corresponding source of such a combination shall include
// the source code for all other software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
// +build !go1.9
package xmath
// CeilPow2 returns minimal y >= x, such that y = 2^i
func CeilPow2(x uint64) uint64 {
if x == 0 {
return x
}
l := uint(0)
h := uint(63)
for l < h {
i := (l + h) / 2
y := uint64(1) << i
switch {
case y < x:
l = i + 1
case y > x:
h = i
default:
// y == x
return y
}
}
return 1 << h
}
// Copyright (C) 2017 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Open Source Initiative approved licenses and Convey
// the resulting work. Corresponding source of such a combination shall include
// the source code for all other software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
// +build go1.9
// Package xmath provides addons to std math package
package xmath
import (
"math/bits"
)
// CeilPow2 returns minimal y >= x, such that y = 2^i
func CeilPow2(x uint64) uint64 {
switch bits.OnesCount64(x) {
case 0, 1:
return x // either 0 or 2^i already
default:
return 1 << uint(bits.Len64(x))
}
}
// XXX if needed: NextPow2 (y > x, such that y = 2^i) is
// 1 << bits.Len64(x)
// Copyright (C) 2017 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Open Source Initiative approved licenses and Convey
// the resulting work. Corresponding source of such a combination shall include
// the source code for all other software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
package xmath
import (
"testing"
)
func TestCeilPow2(t *testing.T) {
testv := []struct {in, out uint64} {
{0, 0},
{1, 1},
{2, 2},
{3, 4},
{4, 4},
{5, 8},
{5, 8},
{6, 8},
{7, 8},
{8, 8},
{9, 16},
{10, 16},
{11, 16},
{12, 16},
{13, 16},
{14, 16},
{15, 16},
{16, 16},
{1<<62 - 1, 1<<62},
{1<<62, 1<<62},
{1<<62+1, 1<<63},
{1<<63 - 1, 1<<63},
{1<<63, 1<<63},
}
for _, tt := range testv {
out := CeilPow2(tt.in)
if out != tt.out {
t.Errorf("CeilPow2(%v) -> %v ; want %v", tt.in, out, tt.out)
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment