mirror of https://gerrit.osmocom.org/libosmocore
Add osmo_isqrt32() to compute 32bit integer square root
Change-Id: I2b96db6e037e72e92317fec874877e473a1cf909
This commit is contained in:
parent
dfb0b97f55
commit
15a5f8de00
|
@ -128,4 +128,6 @@ const char *osmo_escape_str_buf(const char *str, int in_len, char *buf, size_t b
|
||||||
const char *osmo_quote_str(const char *str, int in_len);
|
const char *osmo_quote_str(const char *str, int in_len);
|
||||||
const char *osmo_quote_str_buf(const char *str, int in_len, char *buf, size_t bufsize);
|
const char *osmo_quote_str_buf(const char *str, int in_len, char *buf, size_t bufsize);
|
||||||
|
|
||||||
|
uint32_t osmo_isqrt32(uint32_t x);
|
||||||
|
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
40
src/utils.c
40
src/utils.c
|
@ -592,4 +592,44 @@ const char *osmo_quote_str(const char *str, int in_len)
|
||||||
return osmo_quote_str_buf(str, in_len, namebuf, sizeof(namebuf));
|
return osmo_quote_str_buf(str, in_len, namebuf, sizeof(namebuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! perform an integer square root operation on unsigned 32bit integer.
|
||||||
|
* This implementation is taken from "Hacker's Delight" Figure 11-1 "Integer square root, Newton's
|
||||||
|
* method", which can also be found at http://www.hackersdelight.org/hdcodetxt/isqrt.c.txt */
|
||||||
|
uint32_t osmo_isqrt32(uint32_t x)
|
||||||
|
{
|
||||||
|
uint32_t x1;
|
||||||
|
int s, g0, g1;
|
||||||
|
|
||||||
|
if (x <= 1)
|
||||||
|
return x;
|
||||||
|
|
||||||
|
s = 1;
|
||||||
|
x1 = x - 1;
|
||||||
|
if (x1 > 0xffff) {
|
||||||
|
s = s + 8;
|
||||||
|
x1 = x1 >> 16;
|
||||||
|
}
|
||||||
|
if (x1 > 0xff) {
|
||||||
|
s = s + 4;
|
||||||
|
x1 = x1 >> 8;
|
||||||
|
}
|
||||||
|
if (x1 > 0xf) {
|
||||||
|
s = s + 2;
|
||||||
|
x1 = x1 >> 4;
|
||||||
|
}
|
||||||
|
if (x1 > 0x3) {
|
||||||
|
s = s + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
g0 = 1 << s; /* g0 = 2**s */
|
||||||
|
g1 = (g0 + (x >> s)) >> 1; /* g1 = (g0 + x/g0)/2 */
|
||||||
|
|
||||||
|
/* converges after four to five divisions for arguments up to 16,785,407 */
|
||||||
|
while (g1 < g0) {
|
||||||
|
g0 = g1;
|
||||||
|
g1 = (g0 + (x/g0)) >> 1;
|
||||||
|
}
|
||||||
|
return g0;
|
||||||
|
}
|
||||||
|
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
static void hexdump_test(void)
|
static void hexdump_test(void)
|
||||||
{
|
{
|
||||||
|
@ -425,6 +426,26 @@ static void str_quote_test(void)
|
||||||
printf("'%s'\n", osmo_quote_str_buf(NULL, -1, out_buf, 10));
|
printf("'%s'\n", osmo_quote_str_buf(NULL, -1, out_buf, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void isqrt_test(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("\nTesting integer square-root\n");
|
||||||
|
srand(time(NULL));
|
||||||
|
for (i = 0; i < 1024; i++) {
|
||||||
|
uint16_t x;
|
||||||
|
uint32_t r = rand();
|
||||||
|
if (RAND_MAX < UINT16_MAX)
|
||||||
|
x = r * (UINT16_MAX/RAND_MAX);
|
||||||
|
else
|
||||||
|
x = r;
|
||||||
|
uint32_t sq = x*x;
|
||||||
|
uint32_t y = osmo_isqrt32(sq);
|
||||||
|
if (y != x)
|
||||||
|
printf("ERROR: x=%u, sq=%u, osmo_isqrt(%u) = %u\n", x, sq, sq, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
static const struct log_info log_info = {};
|
static const struct log_info log_info = {};
|
||||||
|
@ -437,5 +458,6 @@ int main(int argc, char **argv)
|
||||||
bcd_test();
|
bcd_test();
|
||||||
str_escape_test();
|
str_escape_test();
|
||||||
str_quote_test();
|
str_quote_test();
|
||||||
|
isqrt_test();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,3 +137,5 @@ NOT passed through. '"printable"'
|
||||||
'<buf-too-small>'
|
'<buf-too-small>'
|
||||||
- NULL string becomes a "NULL" literal:
|
- NULL string becomes a "NULL" literal:
|
||||||
'NULL'
|
'NULL'
|
||||||
|
|
||||||
|
Testing integer square-root
|
||||||
|
|
Loading…
Reference in New Issue