Просмотр исходного кода

[libc] Add isqrt() function to find integer square roots

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 лет назад
Родитель
Сommit
3ffd309375
3 измененных файлов: 77 добавлений и 0 удалений
  1. 52
    0
      src/core/isqrt.c
  2. 14
    0
      src/include/ipxe/isqrt.h
  3. 11
    0
      src/tests/math_test.c

+ 52
- 0
src/core/isqrt.c Просмотреть файл

@@ -0,0 +1,52 @@
1
+/*
2
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17
+ * 02110-1301, USA.
18
+ */
19
+
20
+FILE_LICENCE ( GPL2_OR_LATER );
21
+
22
+/** @file
23
+ *
24
+ * Integer square root
25
+ *
26
+ */
27
+
28
+#include <ipxe/isqrt.h>
29
+
30
+/**
31
+ * Find integer square root
32
+ *
33
+ * @v value		Value
34
+ * @v isqrt		Integer square root of value
35
+ */
36
+unsigned long isqrt ( unsigned long value ) {
37
+	unsigned long result = 0;
38
+	unsigned long bit = ( 1UL << ( ( 8 * sizeof ( bit ) ) - 2 ) );
39
+
40
+	while ( bit > value )
41
+		bit >>= 2;
42
+	while ( bit ) {
43
+		if ( value >= ( result + bit ) ) {
44
+			value -= ( result + bit );
45
+			result = ( ( result >> 1 ) + bit );
46
+		} else {
47
+			result >>= 1;
48
+		}
49
+		bit >>= 2;
50
+	}
51
+	return result;
52
+}

+ 14
- 0
src/include/ipxe/isqrt.h Просмотреть файл

@@ -0,0 +1,14 @@
1
+#ifndef _IPXE_ISQRT_H
2
+#define _IPXE_ISQRT_H
3
+
4
+/** @file
5
+ *
6
+ * Integer square root
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+extern unsigned long isqrt ( unsigned long value );
13
+
14
+#endif /* _IPXE_ISQRT_H */

+ 11
- 0
src/tests/math_test.c Просмотреть файл

@@ -32,6 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
32 32
 #include <strings.h>
33 33
 #include <assert.h>
34 34
 #include <ipxe/test.h>
35
+#include <ipxe/isqrt.h>
35 36
 
36 37
 /**
37 38
  * Force a call to the non-constant implementation of flsl()
@@ -269,6 +270,16 @@ static void math_test_exec ( void ) {
269 270
 		       -1LL, -0x9cb7d9d78556fb9LL );
270 271
 	u64divmod_ok ( 0, 0x5b2f2737f4ffULL, 0, 0 );
271 272
 	s64divmod_ok ( 0, 0xbb00ded72766207fULL, 0, 0 );
273
+
274
+	/* Test integer square root */
275
+	ok ( isqrt ( 0 ) == 0 );
276
+	ok ( isqrt ( 1 ) == 1 );
277
+	ok ( isqrt ( 255 ) == 15 );
278
+	ok ( isqrt ( 256 ) == 16 );
279
+	ok ( isqrt ( 257 ) == 16 );
280
+	ok ( isqrt ( 0xa53df2adUL ) == 52652 );
281
+	ok ( isqrt ( 0x123793c6UL ) == 17482 );
282
+	ok ( isqrt ( -1UL ) == ( -1UL >> ( 8 * sizeof ( unsigned long ) / 2 )));
272 283
 }
273 284
 
274 285
 /** Mathematical self-tests */

Загрузка…
Отмена
Сохранить