Last active
June 21, 2026 21:24
-
-
Save Eczbek/34456f94b163d89a1c359ecfc9c5f79b to your computer and use it in GitHub Desktop.
generic math
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef DETAIL_META_HEADER_MATH | |
| #define DETAIL_META_HEADER_MATH | |
| #include <stddef.h> | |
| #define meta_int_cmp(X, ...) \ | |
| meta_int_cmp(sizeof(X), sizeof(__VA_ARGS__), (typeof(X))-1 < 0, (typeof(__VA_ARGS__))-1 < 0, (unsigned char*)&(typeof(X)){ (X) }, (unsigned char*)&(typeof(__VA_ARGS__)){ (__VA_ARGS__) }) | |
| [[maybe_unused]] static inline int (meta_int_cmp)(size_t a_size, size_t b_size, bool a_signed, bool b_signed, unsigned char* a_data, unsigned char* b_data) { | |
| static constexpr int sign_mask = ~((unsigned char)-1 >> 1); | |
| bool a_sign = a_signed && (a_data[a_size - 1] & sign_mask); | |
| bool b_sign = b_signed && (b_data[b_size - 1] & sign_mask); | |
| if (a_sign != b_sign) { | |
| return b_sign - a_sign; | |
| } | |
| for (size_t i = (a_size < b_size) ? b_size : a_size; i--;) { | |
| unsigned char a = (i < a_size) ? a_data[i] : (unsigned char)-a_sign; | |
| unsigned char b = (i < b_size) ? b_data[i] : (unsigned char)-b_sign; | |
| if (a < b) { | |
| return -1; | |
| } | |
| if (b < a) { | |
| return 1; | |
| } | |
| } | |
| return 0; | |
| } | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <limits.h> | |
| #include <stdio.h> | |
| #define TEST(X, ...) \ | |
| printf("%s %c %s\n", #X, "<=>"[meta_int_cmp((X), (__VA_ARGS__)) + 1], #__VA_ARGS__) | |
| int main() { | |
| TEST(0, 0); | |
| TEST(1, 0); | |
| TEST(0, 1); | |
| TEST(-1, 0); | |
| TEST(-5, 5u); | |
| TEST(5u, -5); | |
| TEST(INT_MIN, (unsigned)INT_MIN); | |
| TEST((char)0, 0ull); | |
| TEST((char)0, ULLONG_MAX); | |
| TEST(LLONG_MAX, (ULLONG_MAX >> 1)); | |
| TEST(SCHAR_MIN, LLONG_MIN); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment