| #ifndef H_FIOBJ_NUMBERS_H |
| #define H_FIOBJ_NUMBERS_H |
| /* |
| Copyright: Boaz Segev, 2017-2018 |
| License: MIT |
| */ |
| |
| #include <fiobject.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /* ***************************************************************************** |
| Numbers API (Integers) |
| ***************************************************************************** */ |
| |
| /** Creates a Number object. Remember to use `fiobj_free`. */ |
| FIO_INLINE FIOBJ fiobj_num_new(intptr_t num); |
| |
| /** Creates a temporary Number object. Avoid using `fiobj_free`. */ |
| FIOBJ fiobj_num_tmp(intptr_t num); |
| |
| /* ***************************************************************************** |
| Float API (Double) |
| ***************************************************************************** */ |
| |
| /** Creates a Float object. Remember to use `fiobj_free`. */ |
| FIOBJ fiobj_float_new(double num); |
| |
| /** Mutates a Float object's value. Effects every object's reference! */ |
| void fiobj_float_set(FIOBJ obj, double num); |
| |
| /** Creates a temporary Float object. Avoid using `fiobj_free`. */ |
| FIOBJ fiobj_float_tmp(double num); |
| |
| /* ***************************************************************************** |
| Numerical Helpers: not FIOBJ specific, but included as part of the library |
| ***************************************************************************** */ |
| |
| /** |
| * A helper function that converts between String data to a signed int64_t. |
| * |
| * Numbers are assumed to be in base 10. |
| * |
| * The `0x##` (or `x##`) and `0b##` (or `b##`) are recognized as base 16 and |
| * base 2 (binary MSB first) respectively. |
| * |
| * The pointer will be updated to point to the first byte after the number. |
| */ |
| int64_t fio_atol(char **pstr); |
| |
| /** A helper function that converts between String data to a signed double. */ |
| double fio_atof(char **pstr); |
| |
| /** |
| * A helper function that converts between a signed int64_t to a string. |
| * |
| * No overflow guard is provided, make sure there's at least 66 bytes available |
| * (for base 2). |
| * |
| * Supports base 2, base 10 and base 16. An unsupported base will silently |
| * default to base 10. Prefixes aren't added (i.e., no "0x" or "0b" at the |
| * beginning of the string). |
| * |
| * Returns the number of bytes actually written (excluding the NUL terminator). |
| */ |
| size_t fio_ltoa(char *dest, int64_t num, uint8_t base); |
| |
| /** |
| * A helper function that converts between a double to a string. |
| * |
| * No overflow guard is provided, make sure there's at least 130 bytes available |
| * (for base 2). |
| * |
| * Supports base 2, base 10 and base 16. An unsupported base will silently |
| * default to base 10. Prefixes aren't added (i.e., no "0x" or "0b" at the |
| * beginning of the string). |
| * |
| * Returns the number of bytes actually written (excluding the NUL terminator). |
| */ |
| size_t fio_ftoa(char *dest, double num, uint8_t base); |
| |
| /** Converts a number to a temporary, thread safe, C string object */ |
| fio_str_info_s fio_ltocstr(long); |
| |
| /** Converts a float to a temporary, thread safe, C string object */ |
| fio_str_info_s fio_ftocstr(double); |
| |
| /* ***************************************************************************** |
| Pointer Wrapping Helper MACROs (uses integers) |
| ***************************************************************************** */ |
| |
| #define fiobj_ptr_wrap(ptr) fiobj_num_new((uintptr_t)(ptr)) |
| #define fiobj_ptr_unwrap(obj) ((void *)fiobj_obj2num((obj))) |
| |
| /* ***************************************************************************** |
| Inline Number Initialization |
| ***************************************************************************** */ |
| |
| FIOBJ fiobj_num_new_bignum(intptr_t num); |
| |
| /** Creates a Number object. Remember to use `fiobj_free`. */ |
| FIO_INLINE FIOBJ fiobj_num_new(intptr_t num) { |
| if ((((uintptr_t)num & |
| (FIOBJ_NUMBER_SIGN_BIT | FIOBJ_NUMBER_SIGN_EXCLUDE_BIT)) == 0) || |
| (((uintptr_t)num & |
| (FIOBJ_NUMBER_SIGN_BIT | FIOBJ_NUMBER_SIGN_EXCLUDE_BIT)) == |
| (FIOBJ_NUMBER_SIGN_BIT | FIOBJ_NUMBER_SIGN_EXCLUDE_BIT))) { |
| const uintptr_t num_abs = (uintptr_t)num & FIOBJ_NUMBER_SIGN_MASK; |
| const uintptr_t num_sign = (uintptr_t)num & FIOBJ_NUMBER_SIGN_BIT; |
| return ((num_abs << 1) | num_sign | FIOBJECT_NUMBER_FLAG); |
| } |
| return fiobj_num_new_bignum(num); |
| } |
| |
| #if DEBUG |
| void fiobj_test_numbers(void); |
| #endif |
| |
| #ifdef __cplusplus |
| } /* extern "C" */ |
| #endif |
| |
| #endif |