123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- // C source file with functions to deal with integers
- /***********************************************************
- * functions to print the value of bean primite integer types
- ************************************************************/
- // print_byte_num() function
- umax print_byte_num(void * ptr, umax size) {
- if (size < 1)
- return 0;
- printf("%u", *((byte *) ptr));
- return size;
- }
- // print_byte_hex() function
- umax print_byte_hex(void * ptr, umax size) {
- if (size < 1)
- return 0;
- printf("%02X", *((byte *) ptr));
- return size;
- }
- // print_char_num() function
- umax print_char_num(void * ptr, umax size) {
- if (size < 1)
- return 0;
- printf("%d", *((char *) ptr));
- return size;
- }
- // print_umax_num() function
- umax print_umax_num(void * ptr, umax size) {
- if (size < sizeof(umax))
- return 0;
- printf("%llu", *((umax *) ptr));
- return size;
- }
- // print_umax_hex() function
- umax print_umax_hex(void * ptr, umax size) {
- if (size < sizeof(umax))
- return 0;
- printf("%08llX", *((umax *) ptr));
- return size;
- }
- // print_smax_num() function
- umax print_smax_num(void * ptr, umax size) {
- if (size < sizeof(smax))
- return 0;
- printf("%lld", *((smax *) ptr));
- return size;
- }
- /***********************************************
- * powerof functions for signed/unsigned integers
- ************************************************/
- // powerof_uint() function
- // function to calculate the power of an unsigned integer to an unsigned
- // exponent (an unsigned integer that is limited to umax container)
- umax powerof_uint(umax base, byte exponent)
- {
- // base equals 0
- if (base == 0)
- return 0;
- // exponent equals 0
- if (exponent == 0)
- return 1;
-
- // otherwise, calculate (base ^ (exponent))
- umax result = base;
- for (umax i = 2; i <= exponent; i++)
- result *= base;
- return result;
- }
- // powerof_sint() function
- // function to calculate the power of a signed integer to an unsigned
- // exponent (a signed integer limited to smax container)
- smax powerof_sint(smax base, byte exponent)
- {
- // base equals 0
- if (base == 0)
- return 0;
- // exponent equals 0
- if (exponent == 0)
- return 1;
-
- // calculate result
- smax result = 1;
- for (umax i = 1; i <= exponent; i++)
- result *= base;
- return result;
- }
- // get_max_uint() function
- // return the maximum of 2 umaxs
- umax get_max_uint(umax uint_1, umax uint_2)
- {
- return uint_1 > uint_2 ? uint_1 : uint_2;
- }
- // get_min_uint() function
- // return the minimum of 2 umaxs
- umax get_min_uint(umax uint_1, umax uint_2)
- {
- return uint_1 > uint_2 ? uint_2 : uint_1;
- }
- /********************************************************************************
- * functions to calculate some types of integers from bits in the BIT_HOLDER array
- *********************************************************************************/
- /*********
- * UNSIGNED
- * Example: 10011101 (binary, 8 bits long)
- * 1*(2)^7 + 0*(2)^6 + 0*(2)^5 + 1*(2)^4 + 1*(2)^3 + 1*(2)^2 + 0*(2)^1 + 1*(2)^0 = 157 (decimal)
- ***********************************************************************************************/
- // bits_to_std_uint() function
- // function to calculate an unsigned integer using the standard
- // calculation method. It will read the bits on the BIT_HOLDER array
- // (overflow will occur if the integer calculated goes outside umax!)
- umax bits_to_std_uint(umax bit_holder_pos)
- {
- umax result = 0;
- umax int_bit_size = BIT_HOLDER_LENGTH - bit_holder_pos;
- for (umax i = 0; i < int_bit_size; i++)
- result += BIT_HOLDER[BIT_HOLDER_LENGTH - i - 1] * powerof_uint(2, i);
- return result;
- }
- // tbh idk about another unsigned representation, if you do, let me know
- /*******
- * SIGNED
- * Info about each representation here
- * https://en.wikipedia.org/wiki/Signed_number_representations
- *************************************************************/
- // bits_to_sign_mag_sint() function
- // treat the n-1 bits to the right of the binary number as an unsigned integer
- // then add the sign from the leftmost bit to the left (1 = minus, 0 = plus)
- smax bits_to_sign_mag_sint(umax bit_holder_pos)
- {
- smax result = 0;
- umax int_bit_size = BIT_HOLDER_LENGTH - bit_holder_pos;
-
- // get the magnitude of the number
- for (umax i = 0; i < int_bit_size - 1; i++)
- result += BIT_HOLDER[BIT_HOLDER_LENGTH - i - 1] * powerof_uint(2, i);
-
- // get the sign
- result *= BIT_HOLDER[BIT_HOLDER_LENGTH - int_bit_size] == 1 ? -1 : 1;
-
- return result;
- }
- // bits_to_1_compl_sint() function
- // is like 2's compl but with a twist (what a description by me)
- smax bits_to_1_compl_sint(umax bit_holder_pos)
- {
- smax result = 0;
- umax int_bit_size = BIT_HOLDER_LENGTH - bit_holder_pos;
-
- // get the substraction done already
- if (BIT_HOLDER[BIT_HOLDER_LENGTH - int_bit_size] == 1)
- result -= 1 * powerof_uint(2, int_bit_size - 1) - 1;
-
- // calculate the rest of the number as an unsigned int
- for (umax i = 0; i < int_bit_size - 1; i++)
- result += BIT_HOLDER[BIT_HOLDER_LENGTH - i - 1] * powerof_uint(2, i);
-
- return result;
- }
- // bits_to_2_compl_sint() function
- // the one that is used on most systems from today
- smax bits_to_2_compl_sint(umax bit_holder_pos)
- {
- smax result = 0;
- umax int_bit_size = BIT_HOLDER_LENGTH - bit_holder_pos;
-
- // get the substraction done already
- if (BIT_HOLDER[BIT_HOLDER_LENGTH - int_bit_size] == 1)
- result -= 1 * powerof_uint(2, int_bit_size - 1);
-
- // get the rest of the number as an unsigned integer and add it to result
- for (umax i = 0; i < int_bit_size - 1; i++)
- result += BIT_HOLDER[BIT_HOLDER_LENGTH - i - 1] * powerof_uint(2, i);
-
- return result;
- }
- // bits_to_off_bin_sint() function
- // 0 is just placed at the 1000....0000 binary number
- smax bits_to_off_bin_sint(umax bit_holder_pos)
- {
- smax result = 0;
- umax int_bit_size = BIT_HOLDER_LENGTH - bit_holder_pos;
-
- // get the bias and subtract it right away
- result -= 1 * powerof_uint(2, int_bit_size - 1) - 1;
-
- // get the complete number as an unsigned integer and add it to result
- for (umax i = 0; i < int_bit_size; i++)
- result += BIT_HOLDER[BIT_HOLDER_LENGTH - i - 1] * powerof_uint(2, i);
-
- return result;
- }
- // bits_to_bminus2_sint() function
- // just like the unsigned integer calculation but using the -2 base
- smax bits_to_bminus2_sint(umax bit_holder_pos)
- {
- smax result = 0;
- umax int_bit_size = BIT_HOLDER_LENGTH - bit_holder_pos;
-
- // calculate the number as an unsigned integer but use base -2 instead of +2
- for (umax i = 0; i < int_bit_size; i++)
- result += BIT_HOLDER[BIT_HOLDER_LENGTH - i - 1] * powerof_sint(-2, i);
-
- return result;
- }
- /**********************************************************************
- * functions to calculate different type of integers from bits in memory
- ***********************************************************************/
- // UNSIGNED
- // calc_mem_std_uint() function
- umax calc_mem_std_uint(umax byte_cnt, umax lshifts, umax bit_cnt, umax lpad_cnt, void * src, ENDIAN_T endian)
- {
- return bits_to_std_uint(get_byte_bits(byte_cnt, lshifts, bit_cnt, lpad_cnt, src, endian));
- }
- // SIGNED
- // calc_mem_sign_mag_sint() function
- smax calc_mem_sign_mag_sint(umax byte_cnt, umax lshifts, umax bit_cnt, umax lpad_cnt, void * src, ENDIAN_T endian)
- {
- return bits_to_sign_mag_sint(get_byte_bits(byte_cnt, lshifts, bit_cnt, lpad_cnt, src, endian));
- }
- // calc_mem_1_compl_sint() function
- smax calc_mem_1_compl_sint(umax byte_cnt, umax lshifts, umax bit_cnt, umax lpad_cnt, void * src, ENDIAN_T endian)
- {
- return bits_to_1_compl_sint(get_byte_bits(byte_cnt, lshifts, bit_cnt, lpad_cnt, src, endian));
- }
- // calc_mem_2_compl_sint() function
- smax calc_mem_2_compl_sint(umax byte_cnt, umax lshifts, umax bit_cnt, umax lpad_cnt, void * src, ENDIAN_T endian)
- {
- return bits_to_2_compl_sint(get_byte_bits(byte_cnt, lshifts, bit_cnt, lpad_cnt, src, endian));
- }
- // calc_mem_off_bin_sint() function
- smax calc_mem_off_bin_sint(umax byte_cnt, umax lshifts, umax bit_cnt, umax lpad_cnt, void * src, ENDIAN_T endian)
- {
- return bits_to_off_bin_sint(get_byte_bits(byte_cnt, lshifts, bit_cnt, lpad_cnt, src, endian));
- }
- // calc_mem_bminus2_sint() function
- smax calc_mem_bminus2_sint(umax byte_cnt, umax lshifts, umax bit_cnt, umax lpad_cnt, void * src, ENDIAN_T endian)
- {
- return bits_to_bminus2_sint(get_byte_bits(byte_cnt, lshifts, bit_cnt, lpad_cnt, src, endian));
- }
- /********************************************
- * functions to get usual integers from memory
- * (not byte aligned, it is assumed the system
- * uses these types of integers)
- * - standard unsigned integer
- * - 2-complement signed integer
- *******************************/
- // get_uint() function
- // function to get a standard unsigned integer from memory without a manual calculation
- // method (assumes the system uses the std unsigned integer representation)
- // be careful with bit sizes that overflow umax!
- umax get_uint(umax byte_cnt, umax lshifts, umax bit_cnt, umax lpad_cnt, void * src, ENDIAN_T endian)
- {
- // variable to return
- umax result = 0;
- // get the bits from src
- get_byte_bits(byte_cnt, lshifts, bit_cnt, lpad_cnt, src, endian);
- // copy the bits into result
- cp_mem_bytes(BYTE_HOLDER + BYTE_HOLDER_LENGTH - sizeof(umax), sizeof(umax), &result);
- // modify byte order depending on SYS_ENDIAN
- if (SYS_ENDIAN == LITTLE)
- reverse_array(&result, sizeof(umax), sizeof(byte));
- // ^ as the bytes are already in big endian there is no need to
- // manage them after the copy process if the system is in big endian
- return result;
- }
- // get_sint() function
- // same as the above function but for signed integers
- // (2-complement ints are assumed to be used by the system)
- smax get_sint(umax byte_cnt, umax lshifts, umax bit_cnt, umax lpad_cnt, void * src, ENDIAN_T endian)
- {
- // variable to return and temp var
- smax result = 0, temp = 0;
-
- // get the bits from src
- result = get_uint(byte_cnt, lshifts, bit_cnt, lpad_cnt, src, endian);
-
- // get the left binary digits of the number container to be 1 and
- // make the binary digits ocupied by the actual integer to 0
- // then, add that binary digit result to the integer (to result)
- temp = (~ result) >> bit_cnt;
- temp = (temp << bit_cnt) + result;
- // check which one of the variables (result or temp) is outside the
- // signed integer range and return the one thats in (compare magnitude)
- result = (~ temp) > result ? result : temp;
- // bruh moment
- return result;
- }
- /****************************************
- * functions to get byte aligned and
- * specific sized usual integers in memory
- * I will call them "standard" (common)
- * integers (8, 16 and 32 bits long ints)
- *****************************************/
- // std_int_check() function
- // function to be used in the below functions
- bool std_int_check(umax bit_cnt);
- bool std_int_check(umax bit_cnt)
- {
- // return 0 if the bit size is not 8, 16 or 32
- if ((bit_cnt % 8) != 0 || bit_cnt > 32)
- return 0;
- return 1;
- }
- // get_std_uint() function
- // special case of the get_uint() function. bit_size is
- // limited to 8, 16 and 32 and the integer bits are byte aligned
- umax get_std_uint(umax bit_cnt, void * src, ENDIAN_T endian)
- {
- // get the unsigned integer if the bit size is valid
- if (std_int_check(bit_cnt))
- return get_uint(0, 0, bit_cnt, 0, src, endian);
- return 0;
- }
- // get_std_sint() function
- // same as get_std_uint() but for signed integers
- smax get_std_sint(umax bit_cnt, void * src, ENDIAN_T endian)
- {
- // get the signed integer if the bit size is valid
- if (std_int_check(bit_cnt))
- return get_sint(0, 0, bit_cnt, 0, src, endian);
- return 0;
- }
- // functions to print std integers
- // print_uint8() function
- umax print_uint8(void * ptr, umax size)
- {
- return print_byte_num(ptr, size);
- }
- // print_uint16be() function
- umax print_uint16be(void * ptr, umax size)
- {
- if (size < 2)
- return 0;
- printf("%llu", get_std_uint(16, ptr, BIG));
- return size;
- }
- // print_uint16le() function
- umax print_uint16le(void * ptr, umax size)
- {
- if (size < 2)
- return 0;
- printf("%llu", get_std_uint(16, ptr, LITTLE));
- return size;
- }
- // print_uint32be() function
- umax print_uint32be(void * ptr, umax size)
- {
- if (size < 4)
- return 0;
- printf("%llu", get_std_uint(32, ptr, BIG));
- return size;
- }
- // print_uint32le() function
- umax print_uint32le(void * ptr, umax size)
- {
- if (size < 4)
- return 0;
- printf("%llu", get_std_uint(32, ptr, LITTLE));
- return size;
- }
- // print_sint8() function
- umax print_sint8(void * ptr, umax size)
- {
- return print_char_num(ptr, size);
- }
- // print_sint16be() function
- umax print_sint16be(void * ptr, umax size)
- {
- if (size < 2)
- return 0;
- printf("%llu", get_std_sint(16, ptr, BIG));
- return size;
- }
- // print_sint16le() function
- umax print_sint16le(void * ptr, umax size)
- {
- if (size < 2)
- return 0;
- printf("%llu", get_std_sint(16, ptr, LITTLE));
- return size;
- }
- // print_sint32be() function
- umax print_sint32be(void * ptr, umax size)
- {
- if (size < 4)
- return 0;
- printf("%llu", get_std_sint(32, ptr, BIG));
- return size;
- }
- // print_sint32le() function
- umax print_sint32le(void * ptr, umax size)
- {
- if (size < 4)
- return 0;
- printf("%llu", get_std_sint(32, ptr, LITTLE));
- return size;
- }
- // Comparison functions
- // umax_equal() function
- // function to check if 2 umax integers are the same
- bool umax_equal(void * umax1, void * umax2)
- {
- return ((umax *) umax1)[0] == ((umax *) umax2)[0];
- }
|