@@ -1038,6 +1038,84 @@ static inline size_t sys_count_bits(const void *value, size_t len)
10381038 */
10391039#define SIGN (x ) (((x) > 0) - ((x) < 0))
10401040
1041+ /**
1042+ * @brief Compute the Greatest Common Divisor (GCD) of two integers
1043+ * using the Euclidean algorithm.
1044+ *
1045+ * @param a First integer
1046+ * @param b Second integer
1047+ *
1048+ * @return The greatest common divisor of a and b, always returns a positive value.
1049+ * If one of the parameters is 0, returns the absolute value of the other parameter.
1050+ */
1051+ #define gcd (a , b ) \
1052+ _Generic((a), \
1053+ int8_t : gcd_s, \
1054+ int16_t : gcd_s, \
1055+ int32_t : gcd_s, \
1056+ uint8_t : gcd_u, \
1057+ uint16_t : gcd_u, \
1058+ uint32_t : gcd_u)(a, b)
1059+
1060+ static ALWAYS_INLINE uint32_t gcd_u (uint32_t a , uint32_t b )
1061+ {
1062+ uint32_t c ;
1063+
1064+ if (a == 0 ) {
1065+ return b ;
1066+ }
1067+
1068+ if (b == 0 ) {
1069+ return a ;
1070+ }
1071+
1072+ c = a % b ;
1073+ while (c != 0 ) {
1074+ a = b ;
1075+ b = c ;
1076+ c = a % b ;
1077+ }
1078+
1079+ return b ;
1080+ }
1081+
1082+ static ALWAYS_INLINE int32_t gcd_s (int32_t a , int32_t b )
1083+ {
1084+ return gcd_u (a < 0 ? - a : a , b < 0 ? - b : b );
1085+ }
1086+
1087+ /**
1088+ * @brief Compute the Least Common Multiple (LCM) of two integers.
1089+ *
1090+ * @param a First integer
1091+ * @param b Second integer
1092+ *
1093+ * @retval The least common multiple of a and b.
1094+ * @retval 0 if either input is 0.
1095+ */
1096+ #define lcm (a , b ) \
1097+ _Generic((a), \
1098+ int8_t : lcm_s, \
1099+ int16_t : lcm_s, \
1100+ int32_t : lcm_s, \
1101+ uint8_t : lcm_u, \
1102+ uint16_t : lcm_u, \
1103+ uint32_t : lcm_u)(a, b)
1104+
1105+ static ALWAYS_INLINE uint64_t lcm_u (uint32_t a , uint32_t b )
1106+ {
1107+ if (a == 0 || b == 0 ) {
1108+ return 0 ;
1109+ }
1110+
1111+ return (uint64_t )(a / gcd_u (a , b )) * (uint64_t )b ;
1112+ }
1113+
1114+ static ALWAYS_INLINE int64_t lcm_s (int32_t a , int32_t b )
1115+ {
1116+ return lcm_u (a < 0 ? - a : a , b < 0 ? - b : b );
1117+ }
1118+
10411119#ifdef __cplusplus
10421120}
10431121#endif
0 commit comments