mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-20 01:11:18 +00:00
[math] Add some bit-op functions
Just 32-bit rounding to next higher power of two, and base 2 logarithm. Most importantly, they are suitable for use in initializers as they are constant in, constant out.
This commit is contained in:
parent
f72e8ef551
commit
cfaf158ebc
4 changed files with 134 additions and 0 deletions
|
@ -115,6 +115,7 @@ include_qf_input = \
|
|||
include/QF/input/imt.h
|
||||
|
||||
include_qf_math = \
|
||||
include/QF/math/bitop.h \
|
||||
include/QF/math/dual.h \
|
||||
include/QF/math/half.h \
|
||||
include/QF/math/matrix3.h \
|
||||
|
|
73
include/QF/math/bitop.h
Normal file
73
include/QF/math/bitop.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
bitop.h
|
||||
|
||||
bit-op functions
|
||||
|
||||
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2022/1/23
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __QF_math_bitop_h
|
||||
#define __QF_math_bitop_h
|
||||
|
||||
/** \defgroup mathlib_bitop Bit-op functions
|
||||
\ingroup utils
|
||||
*/
|
||||
///@{
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
#define BITOP_RUP1__(x) ( (x) | ( (x) >> 1))
|
||||
#define BITOP_RUP2__(x) (BITOP_RUP1__(x) | (BITOP_RUP1__(x) >> 2))
|
||||
#define BITOP_RUP4__(x) (BITOP_RUP2__(x) | (BITOP_RUP2__(x) >> 4))
|
||||
#define BITOP_RUP8__(x) (BITOP_RUP4__(x) | (BITOP_RUP4__(x) >> 8))
|
||||
#define BITOP_RUP16__(x) (BITOP_RUP8__(x) | (BITOP_RUP8__(x) >> 16))
|
||||
/** Round x up to the next power of two.
|
||||
|
||||
Rounds x up to the next power of two leaving exact powers of two
|
||||
untouched.
|
||||
|
||||
\param x The value to round
|
||||
\return The next higher power of two or x if it already is a power
|
||||
of two.
|
||||
*/
|
||||
#define BITOP_RUP(x) (BITOP_RUP16__((uint32_t)(x) - 1) + 1)
|
||||
|
||||
#define BITOP_LOG2__(x) (((((x) & 0xffff0000) != 0) << 4) \
|
||||
|((((x) & 0xff00ff00) != 0) << 3) \
|
||||
|((((x) & 0xf0f0f0f0) != 0) << 2) \
|
||||
|((((x) & 0xcccccccc) != 0) << 1) \
|
||||
|((((x) & 0xaaaaaaaa) != 0) << 0))
|
||||
/** Log base 2 rounded up.
|
||||
|
||||
Finds the base 2 logarithm of x rounded up (ceil(log2(x))).
|
||||
|
||||
\param x The value for which to find the base 2 logarithm.
|
||||
\return Log base 2 of x, rounded up (2 -> 1, 3 -> 2, 4 -> 2)
|
||||
*/
|
||||
#define BITOP_LOG2(x) BITOP_LOG2__(BITOP_RUP(x))
|
||||
|
||||
///@}
|
||||
|
||||
#endif // __QF_math_bitop_h
|
|
@ -1,6 +1,7 @@
|
|||
libs_util_tests = \
|
||||
libs/util/test/test-bary \
|
||||
libs/util/test/test-baryvf \
|
||||
libs/util/test/test-bitop \
|
||||
libs/util/test/test-bsearch \
|
||||
libs/util/test/test-cexpr \
|
||||
libs/util/test/test-cmem \
|
||||
|
@ -36,6 +37,10 @@ libs_util_test_test_baryvf_SOURCES=libs/util/test/test-baryvf.c
|
|||
libs_util_test_test_baryvf_LDADD=libs/util/libQFutil.la
|
||||
libs_util_test_test_baryvf_DEPENDENCIES=libs/util/libQFutil.la
|
||||
|
||||
libs_util_test_test_bitop_SOURCES=libs/util/test/test-bitop.c
|
||||
libs_util_test_test_bitop_LDADD=libs/util/libQFutil.la
|
||||
libs_util_test_test_bitop_DEPENDENCIES=libs/util/libQFutil.la
|
||||
|
||||
libs_util_test_test_bsearch_SOURCES=libs/util/test/test-bsearch.c
|
||||
libs_util_test_test_bsearch_LDADD=libs/util/libQFutil.la
|
||||
libs_util_test_test_bsearch_DEPENDENCIES=libs/util/libQFutil.la
|
||||
|
|
55
libs/util/test/test-bitop.c
Normal file
55
libs/util/test/test-bitop.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
#include "QF/math/bitop.h"
|
||||
|
||||
struct {
|
||||
uint32_t value;
|
||||
uint32_t expect;
|
||||
} tests [] = {
|
||||
{BITOP_RUP(1), 1},
|
||||
{BITOP_RUP(2), 2},
|
||||
{BITOP_RUP(3), 4},
|
||||
{BITOP_RUP(4), 4},
|
||||
{BITOP_RUP(5), 8},
|
||||
{BITOP_RUP(7), 8},
|
||||
{BITOP_RUP(8), 8},
|
||||
{BITOP_RUP(0x40000000), 0x40000000},
|
||||
{BITOP_RUP(0x40000001), 0x80000000},
|
||||
{BITOP_LOG2(1), 0},
|
||||
{BITOP_LOG2(2), 1},
|
||||
{BITOP_LOG2(3), 2},
|
||||
{BITOP_LOG2(4), 2},
|
||||
{BITOP_LOG2(5), 3},
|
||||
{BITOP_LOG2(7), 3},
|
||||
{BITOP_LOG2(8), 3},
|
||||
{BITOP_LOG2(9), 4},
|
||||
{BITOP_LOG2(15), 4},
|
||||
{BITOP_LOG2(16), 4},
|
||||
{BITOP_LOG2(17), 5},
|
||||
{BITOP_LOG2(31), 5},
|
||||
{BITOP_LOG2(32), 5},
|
||||
{BITOP_LOG2(33), 6},
|
||||
{BITOP_LOG2(0x40000000), 30},
|
||||
{BITOP_LOG2(0x40000001), 31},
|
||||
};
|
||||
#define num_tests (sizeof (tests) / sizeof (tests[0]))
|
||||
|
||||
int
|
||||
main (int argc, const char **argv)
|
||||
{
|
||||
size_t i;
|
||||
int res = 0;
|
||||
|
||||
for (i = 0; i < num_tests; i++) {
|
||||
if (tests[i].value != tests[i].expect) {
|
||||
res |= 1;
|
||||
printf ("test %d failed\n", (int) i);
|
||||
printf ("expect: %8x\n", tests[i].expect);
|
||||
printf ("got : %8x\n", tests[i].value);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
Loading…
Reference in a new issue