Skip to content

Commit 713dafb

Browse files
authored
Merge pull request #651 from sanpeqf/feat-math
Feat math
2 parents ea4919c + 3c65b81 commit 713dafb

5 files changed

Lines changed: 132 additions & 0 deletions

File tree

examples/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ add_subdirectory(levenshtein)
3030
add_subdirectory(list)
3131
add_subdirectory(log)
3232
add_subdirectory(log2)
33+
add_subdirectory(math)
3334
add_subdirectory(matrix)
3435
add_subdirectory(mpi)
3536
add_subdirectory(notifier)

examples/math/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SPDX-License-Identifier: GPL-2.0-or-later
2+
/math-abs

examples/math/CMakeLists.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# SPDX-License-Identifier: GPL-2.0-or-later
2+
#
3+
# Copyright(c) 2023 ffashion <helloworldffashion@gmail.com>
4+
#
5+
6+
add_executable(math-abs abs.c)
7+
target_link_libraries(math-abs bfdev)
8+
add_test(math-abs math-abs)
9+
10+
if(${CMAKE_PROJECT_NAME} STREQUAL "bfdev")
11+
install(FILES
12+
abs.c
13+
DESTINATION
14+
${CMAKE_INSTALL_DOCDIR}/examples/list
15+
)
16+
17+
install(TARGETS
18+
math-abs
19+
DESTINATION
20+
${CMAKE_INSTALL_DOCDIR}/bin
21+
)
22+
endif()

examples/math/abs.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* SPDX-License-Identifier: LGPL-3.0-or-later */
2+
/*
3+
* Copyright(c) 2024 John Sanpe <sanpeqf@gmail.com>
4+
*/
5+
6+
#define MODULE_NAME "math-abs"
7+
#define bfdev_log_fmt(fmt) MODULE_NAME ": " fmt
8+
9+
#include <bfdev/log.h>
10+
#include <bfdev/math.h>
11+
#include <bfdev/limits.h>
12+
13+
#define ABS_TEST(name, min, max) ({ \
14+
long long __result; \
15+
__result = (long long)bfdev_abs(min); \
16+
bfdev_log_info(name " %lld -> %lld\n", \
17+
(long long)min, __result); \
18+
if (max != __result) { \
19+
bfdev_log_err("test failed"); \
20+
return 1; \
21+
} \
22+
})
23+
24+
int
25+
main(int argc, const char *argv[])
26+
{
27+
ABS_TEST("char", BFDEV_CHAR_MIN + 1, BFDEV_CHAR_MAX);
28+
ABS_TEST("short", BFDEV_SHRT_MIN + 1, BFDEV_SHRT_MAX);
29+
ABS_TEST("int", BFDEV_INT_MIN + 1, BFDEV_INT_MAX);
30+
ABS_TEST("long", BFDEV_LONG_MIN + 1, BFDEV_LONG_MAX);
31+
ABS_TEST("long long", BFDEV_LLONG_MIN + 1, BFDEV_LLONG_MAX);
32+
33+
return 0;
34+
}

include/bfdev/math.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,79 @@ BFDEV_BEGIN_DECLS
3838
(x) & ~bfdev_round_mask(x, y) \
3939
)
4040

41+
#define bfdev_abs_expr(var, type, other) __builtin_choose_expr( \
42+
__builtin_types_compatible_p(typeof(var), signed type) || \
43+
__builtin_types_compatible_p(typeof(var), unsigned type), \
44+
({ \
45+
signed type __var; \
46+
__var = (signed type)(var); \
47+
__var < 0 ? - __var : __var; \
48+
}), other \
49+
)
50+
51+
/**
52+
* bfdev_abs - return absolute value of an argument.
53+
*
54+
* If it is unsigned type, it is converted to signed type first.
55+
* char is treated as if it was signed but the macro's
56+
* return type is preserved as char.
57+
*/
58+
#define bfdev_abs(var) \
59+
bfdev_abs_expr(var, long long, \
60+
bfdev_abs_expr(var, long, \
61+
bfdev_abs_expr(var, int, \
62+
bfdev_abs_expr(var, short, \
63+
bfdev_abs_expr(var, char, \
64+
__builtin_choose_expr( \
65+
__builtin_types_compatible_p( \
66+
typeof(var), char), \
67+
(char) ({ \
68+
signed char __var; \
69+
__var = (signed char)(var); \
70+
__var < 0 ? - __var : __var; \
71+
}), \
72+
((void)0) \
73+
) \
74+
)))) \
75+
)
76+
77+
/**
78+
* bfdev_abs_diff - return absolute value of the difference between the args.
79+
* @var1: the first argument.
80+
* @var2: the second argument.
81+
*/
82+
#define bfdev_abs_diff(var1, var2) ({ \
83+
typeof(var1) __var1, __var2; \
84+
\
85+
__var1 = (typeof(var1))(var1); \
86+
__var2 = (typeof(var1))(var2); \
87+
\
88+
__var1 > __var2 \
89+
? (__var1 - __var2) \
90+
: (__var2 - __var1); \
91+
})
92+
93+
/**
94+
* BFDEV_MULT_FRAC
95+
*
96+
* Calculate "value * numer / denom"
97+
* without unnecessary overflow or loss of precision.
98+
*/
99+
#define BFDEV_MULT_FRAC(value, numer, denom) ({ \
100+
typeof(value) __value, __numer, __denom; \
101+
typeof(value) __quot, __rem; \
102+
\
103+
__value = (typeof(value))(value); \
104+
__numer = (typeof(value))(numer); \
105+
__denom = (typeof(value))(denom); \
106+
\
107+
__quot = (__value) / (__denom); \
108+
__rem = (__value) % (__denom); \
109+
\
110+
(__quot * (__numer)) + \
111+
((__rem * (__numer)) / (__denom)); \
112+
})
113+
41114
/**
42115
* BFDEV_DIV_ROUND_UP - round up division.
43116
* @n: divisor number.

0 commit comments

Comments
 (0)