online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code    Language
#define INC_BITMATH #include <limits.h> #include <inttypes.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #define bitsof(T) (CHAR_BIT * sizeof(T)) #ifndef INC_BITMATH int test( int num, char *op, int val ); char *operations[] = { "==", "!=", ">", ">=", "<", "<=", "<<", ">>", "|", "&", "^", "+", "*", "-", "/", NULL, "%", NULL }; int main() { int num = 1024, val = 16, i; for ( i = 0; operations[i]; ++i ) { test( num, operations[i], val ); } return 0; } #endif typedef unsigned long mcc_int_seg_t; #define BI_SEG_END_BIT (~(ULONG_MAX >> 1)) typedef struct mcc_bit { mcc_int_seg_t i; mcc_int_seg_t *seg; mcc_int_seg_t b; mcc_int_seg_t bit; } mcc_bit_t; mcc_bit_t inc_mcc_bit( mcc_bit_t num ) { ++(num.b); num.bit <<= 1; if ( !(num.bit) ) { num.bit = 1; ++(num.i); ++(num.seg); } return num; } mcc_bit_t add_mcc_bit( mcc_bit_t num, mcc_int_seg_t bits ) { mcc_int_seg_t i = 0; if ( !(num.b) ) goto add_mcc_bit_bytes; while ( bits && num.b % bitsof(mcc_int_seg_t) ) { --bits; num = inc_mcc_bit(num); } add_mcc_bit_bytes: if ( !bits ) return num; i = bits / bitsof(mcc_int_seg_t); num.i += i; num.seg = &(num.seg[i]); num.bit = 1u << (bits % bitsof(mcc_int_seg_t)); if ( bits > bitsof(mcc_int_seg_t) && num.bit > 1u ) { ++(num.seg); ++(num.i); } num.b += bits; return num; } mcc_bit_t dec_mcc_bit( mcc_bit_t num ) { mcc_bit_t tmp = num; --(tmp.b); tmp.bit >>= 1; if ( !(tmp.bit) ) { tmp.bit = BI_SEG_END_BIT; --(tmp.i); --(tmp.seg); } return tmp; } mcc_bit_t sub_mcc_bit( mcc_bit_t num, mcc_int_seg_t bits ) { mcc_int_seg_t i = 0; if ( !(num.b) ) goto sub_mcc_bit_bytes; while ( bits && num.b % bitsof(mcc_int_seg_t) ) { --bits; num = dec_mcc_bit(num); } sub_mcc_bit_bytes: if ( !bits ) return num; i = bits / bitsof(mcc_int_seg_t); if ( bits % bitsof(mcc_int_seg_t) ) ++i; num.i -= i; while ( i-- ) --(num.seg); num.bit = BI_SEG_END_BIT; num.bit >>= (bits % bitsof(mcc_int_seg_t)); num.b -= bits; return num; } int cmp_mcc_bit( mcc_bit_t num, mcc_bit_t val ) { if ( num.b > val.b ) return 1; if ( num.b < val.b ) return -1; return 0; } typedef struct _bi { size_t size; mcc_bit_t zero, stop; } mcc_int_t; int mcc_int_validate( mcc_int_t const * const num ) { if ( !num || !(num->zero.seg) || !(num->stop.seg) ) return EADDRNOTAVAIL; if ( cmp_mcc_bit( num->zero, num->stop ) > 0 ) return ERANGE; return EXIT_SUCCESS; } int mcc_int_validate2( mcc_int_t const * const num, mcc_int_t const * const val ) { int ret = mcc_int_validate( num ); switch ( ret ) { case EXIT_SUCCESS: break; case EADDRNOTAVAIL: return EDESTADDRREQ; default: return ret; } return mcc_int_validate( val ); } int bitemp( mcc_int_t *dst, mcc_int_seg_t *src, size_t count ) { if ( !dst ) return EDESTADDRREQ; if ( !src ) return EADDRNOTAVAIL; if ( !count ) return ERANGE; (void)memset( dst, 0, sizeof(mcc_int_t) ); dst->size = count * sizeof(mcc_int_seg_t); dst->zero.seg = src; dst->zero.bit = 1; dst->stop = add_mcc_bit( dst->zero, dst->size * CHAR_BIT ); return EXIT_SUCCESS; } int mcc_int_size( mcc_int_t *dst, size_t size ) { mcc_int_seg_t *mem; size_t nodes; if ( !size ) { if ( dst->zero.seg ) free( dst->zero.seg ); memset( dst, 0, sizeof(mcc_int_seg_t) ); return EXIT_SUCCESS; } nodes = size / sizeof(mcc_int_seg_t); if ( size % sizeof(mcc_int_seg_t) ) ++nodes; ++nodes; size = nodes * sizeof(mcc_int_seg_t); if ( !(dst->zero.seg) ) mem = malloc( size ); else mem = realloc( dst->zero.seg, size ); if ( !mem ) ENOMEM; memset( &(dst->zero), 0, sizeof(mcc_bit_t) ); dst->zero.seg = mem; dst->zero.bit = 1; size -= sizeof(mcc_int_seg_t); dst->size = size; dst->stop = add_mcc_bit( dst->zero, size * CHAR_BIT ); return EXIT_SUCCESS; } int mcc_int_size_and_fill( mcc_int_t *dst, void const *src, size_t size ) { int ret = mcc_int_size( dst, size ); if ( ret != EXIT_SUCCESS ) return ret; (void)memset( dst->zero.seg, 0, dst->size ); (void)memcpy( dst->zero.seg, src, size ); return EXIT_SUCCESS; } int cmp__mcc_int( mcc_int_t const * const num, mcc_int_t const * const val ) { mcc_bit_t n, v; if ( !num || !(num->zero.seg) || !(num->size) ) { if ( !val ) return 0; v = val->stop; while ( v.b ) { v = dec_mcc_bit(v); if ( *(v.seg) & v.bit ) return -1; } return 0; } n = num->stop; if ( !val || !(val->zero.seg) || !(val->size) ) { while ( n.b ) { n = dec_mcc_bit(n); if ( *(n.seg) & n.bit ) return -1; } return 0; } v = val->stop; while ( n.b || v.b ) { while ( n.b ) { n = dec_mcc_bit(n); if ( *(n.seg) & n.bit ) break; } while ( v.b ) { v = dec_mcc_bit(v); if ( *(v.seg) & v.bit ) break; } if ( n.b != v.b ) return ( n.b > v.b ) ? 1 : -1; } return 0; } #define eql__mcc_int( num, val ) (cmp__mcc_int( num, val ) == 0) #define neq__mcc_int( num, val ) (cmp__mcc_int( num, val ) != 0) #define gth__mcc_int( num, val ) (cmp__mcc_int( num, val ) > 0) #define gte__mcc_int( num, val ) (cmp__mcc_int( num, val ) >= 0) #define lth__mcc_int( num, val ) (cmp__mcc_int( num, val ) < 0) #define lte__mcc_int( num, val ) (cmp__mcc_int( num, val ) <= 0) int biclamp1( mcc_int_t *num ) { int ret = mcc_int_validate(num); mcc_bit_t one, pos; if ( ret != EXIT_SUCCESS ) return ret; one = dec_mcc_bit(pos = num->stop); while ( pos.i == one.i ) { if ( !(*(pos.seg) & pos.bit) ) *(pos.seg) |= pos.bit; } return EXIT_SUCCESS; } int biclamp0( mcc_int_t *num ) { int ret = mcc_int_validate(num); mcc_bit_t one, pos; if ( ret != EXIT_SUCCESS ) return ret; one = dec_mcc_bit(pos = num->stop); while ( pos.i == one.i ) { if ( *(pos.seg) & pos.bit ) *(pos.seg) ^= pos.bit; } return EXIT_SUCCESS; } int add__mcc_int( mcc_int_t *num, mcc_int_t const * const val ) { mcc_bit_t n, v, stop; _Bool c = 0; int ret = mcc_int_validate2( num, val ); if ( ret != EXIT_SUCCESS ) return ret; stop = (cmp_mcc_bit(num->stop,val->stop) < 0) ? num->stop : val->stop; for ( n = num->zero, v = val->zero; n.b < stop.b && v.b < stop.b; n = inc_mcc_bit(n), v = inc_mcc_bit(v) ) { if ( c ) { *(n.seg) ^= n.bit; if ( *(n.seg) & n.bit ) c = 0; } if ( *(v.seg) & v.bit ) { *(n.seg) ^= n.bit; if ( !(*(n.seg) & n.bit) ) c = 1; } } if ( c ) { for ( ; n.b < stop.b; n = inc_mcc_bit(n) ) { *(n.seg) ^= n.bit; if ( *(n.seg) & n.bit ) { c = 0; break; } } } return c ? EOVERFLOW : EXIT_SUCCESS; } int add_uint( mcc_int_t *num, mcc_int_t *val ) { int ret = add__mcc_int( num, val ); if ( ret == EOVERFLOW ) { memset( num->zero.seg, -1, num->size ); ret = biclamp0( num ); } return ret; } int add_int( mcc_int_t *num, mcc_int_t *val ) { int ret = mcc_int_validate2(num,val); mcc_int_t tmp; if ( ret != EXIT_SUCCESS ) return ret; tmp = *num; tmp.stop = dec_mcc_bit(tmp.stop); ret = add__mcc_int( &tmp, val ); if ( ret == EOVERFLOW ) { memset( num->zero.seg, -1, num->size ); ret = biclamp0( &tmp ); } return ret; } int shl___mcc_int( mcc_int_t *num, mcc_int_seg_t bits ) { int ret = mcc_int_validate( num ); mcc_bit_t n, v; if ( ret != EXIT_SUCCESS ) return ret; if ( !bits ) return EXIT_SUCCESS; v = sub_mcc_bit( num->stop, bits - 1 ); n = num->stop; while ( v.b ) { n = dec_mcc_bit(n); v = dec_mcc_bit(v); if ( *(v.seg) & v.bit ) *(n.seg) |= n.bit; else if ( *(n.seg) & n.bit ) *(n.seg) ^= n.bit; } while ( n.bit >> 1 ) { n = dec_mcc_bit(n); if ( *(n.seg) & n.bit ) *(n.seg) ^= n.bit; } if ( n.i ) memset( num->zero.seg, 0, n.i * sizeof(mcc_int_seg_t) ); return EXIT_SUCCESS; } int shl__mcc_int( mcc_int_t *num, mcc_int_t const * const val ) { int ret = mcc_int_validate2( num, val ); mcc_int_t tmp = {0}; if ( ret != EXIT_SUCCESS ) return ret; ret = bitemp( &tmp, &(num->stop.b), 1 ); if ( ret != EXIT_SUCCESS ) return ret; if ( gte__mcc_int( val, &tmp ) ) { memset( num->zero.seg, 0, num->size ); return EXIT_SUCCESS; } return shl___mcc_int( num, *(val->zero.seg) ); } int shr___mcc_int( mcc_int_t *num, mcc_int_seg_t bits ) { int ret = mcc_int_validate( num ); mcc_bit_t n, v; if ( ret != EXIT_SUCCESS ) return ret; if ( !bits ) return EXIT_SUCCESS; v = add_mcc_bit( num->zero, bits ); n = num->zero; while ( v.b < num->stop.b ) { if ( *(v.seg) & v.bit ) *(n.seg) |= n.bit; else if ( *(n.seg) & n.bit ) *(n.seg) ^= n.bit; n = inc_mcc_bit(n); v = inc_mcc_bit(v); } while ( n.bit > 1u ) { if ( *(n.seg) & n.bit ) *(n.seg) ^= n.bit; n = inc_mcc_bit(n); } if ( n.i < num->stop.i ) { n.i = num->stop.i - n.i; memset( n.seg, 0, n.i * sizeof(mcc_int_seg_t) ); } return EXIT_SUCCESS; } int shr__mcc_int( mcc_int_t *num, mcc_int_t const * const val ) { int ret = mcc_int_validate2( num, val ); mcc_int_t tmp = {0}; if ( ret != EXIT_SUCCESS ) return ret; ret = bitemp( &tmp, &(num->stop.b), 1 ); if ( ret != EXIT_SUCCESS ) return ret; if ( gte__mcc_int( val, &tmp ) ) { memset( num->zero.seg, 0, num->size ); return EXIT_SUCCESS; } return shr___mcc_int(num, *(val->zero.seg) ); } int aor__mcc_int( mcc_int_t *num, mcc_int_t const * const val ) { int ret = mcc_int_validate2( num, val ); mcc_bit_t n, v, e; if ( ret != EXIT_SUCCESS ) return ret; n = num->zero; v = val->zero; e = (cmp_mcc_bit(num->stop, val->stop) < 0) ? num->stop : val->stop; while ( n.b < e.b && v.b < e.b ) { if ( *(v.seg) & v.bit ) *(n.seg) |= n.bit; n = inc_mcc_bit(n); v = inc_mcc_bit(v); } return EXIT_SUCCESS; } int xor__mcc_int( mcc_int_t *num, mcc_int_t const * const val ) { int ret = mcc_int_validate2( num, val ); mcc_bit_t n, v, e; if ( ret != EXIT_SUCCESS ) return ret; n = num->zero; v = val->zero; e = (cmp_mcc_bit(num->stop, val->stop) < 0) ? num->stop : val->stop; while ( n.b < e.b && v.b < e.b ) { if ( *(v.seg) & v.bit ) *(n.seg) ^= n.bit; n = inc_mcc_bit(n); v = inc_mcc_bit(v); } return EXIT_SUCCESS; } int and__mcc_int( mcc_int_t *num, mcc_int_t const * const val ) { int ret = mcc_int_validate2( num, val ); mcc_bit_t n, v, e; if ( ret != EXIT_SUCCESS ) return ret; n = num->zero; v = val->zero; e = (cmp_mcc_bit(num->stop, val->stop) < 0) ? num->stop : val->stop; while ( n.b < e.b && v.b < e.b ) { if ( !(*(v.seg) & v.bit) && *(n.seg) & n.bit ) *(n.seg) ^= n.bit; n = inc_mcc_bit(n); v = inc_mcc_bit(v); } while ( n.b < num->stop.b ) { if ( *(n.seg) & n.bit ) *(n.seg) ^= n.bit; n = inc_mcc_bit(n); } return EXIT_SUCCESS; } int mul__mcc_int( mcc_int_t *num, mcc_int_t const * const val ) { int ret = mcc_int_validate2( num, val ); mcc_int_t tmp = {0}; mcc_bit_t v; mcc_int_seg_t bits = 0; if ( ret != EXIT_SUCCESS ) return ret; ret = mcc_int_size_and_fill( &tmp, num->zero.seg, num->size ); if ( ret != EXIT_SUCCESS ) return ret; memset( num->zero.seg, 0, num->size ); for ( v = val->zero; v.b < val->stop.b; v = inc_mcc_bit(v) ) { if ( *(v.seg) & v.bit ) { (void)shl___mcc_int( &tmp, bits ); if ( add__mcc_int( num, &tmp ) == EOVERFLOW ) ret = EOVERFLOW; bits = 0; } ++bits; } (void)mcc_int_size( &tmp, 0 ); return ret; } int sub__mcc_int( mcc_int_t *num, mcc_int_t const * const val ) { mcc_bit_t n, v, stop; _Bool c = 0; int ret = mcc_int_validate2( num, val ); if ( ret != EXIT_SUCCESS ) return ret; stop = (cmp_mcc_bit(num->stop,val->stop) < 0) ? num->stop : val->stop; for ( n = num->zero, v = val->zero; n.b < stop.b && v.b < stop.b; n = inc_mcc_bit(n), v = inc_mcc_bit(v) ) { if ( c ) { *(n.seg) ^= n.bit; if ( !(*(n.seg) & n.bit) ) c = 0; } if ( *(v.seg) & v.bit ) { *(n.seg) ^= n.bit; if ( *(n.seg) & n.bit ) c = 1; } } if ( c ) { for ( ; n.b < stop.b; n = inc_mcc_bit(n) ) { *(n.seg) ^= n.bit; if ( !(*(n.seg) & n.bit) ) { c = 0; break; } } } return c ? EOVERFLOW : EXIT_SUCCESS; } int div__mcc_int( mcc_int_t *num, mcc_int_t const * const val, mcc_int_t *rem ) { int ret = mcc_int_validate2( num, val ); mcc_int_t seg = {0}; mcc_int_seg_t bits = 0; if ( ret != EXIT_SUCCESS ) return ret; ret = mcc_int_validate(rem); if ( ret != EXIT_SUCCESS ) return (ret == EADDRNOTAVAIL) ? EDESTADDRREQ : ret; if ( rem->size != num->size ) return ERANGE; (void)memcpy( rem->zero.seg, num->zero.seg, num->size ); (void)memset( num->zero.seg, 0, num->size ); if ( eql__mcc_int( val, NULL ) ) return EXIT_SUCCESS; seg = *rem; while ( seg.stop.b ) { seg.stop = dec_mcc_bit(seg.stop); if ( *(seg.stop.seg) & seg.stop.bit ) { seg.stop = inc_mcc_bit(seg.stop); break; } } seg.zero = seg.stop; seg.zero = dec_mcc_bit(seg.zero); while ( seg.zero.b ) { if ( gte__mcc_int( &seg, val ) ) { shl___mcc_int( num, bits ); sub__mcc_int( &seg, val ); *(num->zero.seg) |= num->zero.bit; bits = 0; } ++bits; seg.zero = dec_mcc_bit(seg.zero); } if ( bits ) shl___mcc_int( num, bits ); return EXIT_SUCCESS; } #ifndef INC_BITMATH int test( int num, char *op, int val ) { int ret = EXIT_FAILURE, rem = num, b4 = num; mcc_int_t _num = {0}, _val = {0}, _rem = {0}; (void)mcc_int_size_and_fill( &_num, &num, sizeof(int) ); (void)mcc_int_size_and_fill( &_val, &val, sizeof(int) ); (void)mcc_int_size_and_fill( &_rem, &num, sizeof(int) ); switch ( *op ) { case 0: ret = EILSEQ; goto fail; case '|': num |= val; aor__mcc_int( &_num, &_val ); goto done; case '^': num ^= val; xor__mcc_int( &_num, &_val ); goto done; case '&': num &= val; and__mcc_int( &_num, &_val ); goto done; case '+': num += val; add__mcc_int( &_num, &_val ); goto done; case '*': num *= val; mul__mcc_int( &_num, &_val ); goto done; case '-': num -= val; sub__mcc_int( &_num, &_val ); goto done; case '/': num /= val; rem %= val; div__mcc_int( &_num, &_val, &_rem ); goto done; case '=': if ( op[1] != '=' ) goto fail; num = (num == val); *(_num.zero.seg) = eql__mcc_int( &_num, &_val ); goto done; case '!': if ( op[1] != '=' ) goto fail; num = (num != val); *(_num.zero.seg) = neq__mcc_int( &_num, &_val ); goto done; case '>': if ( op[1] == '>' ) { num = (num >> val); shr__mcc_int( &_num, &_val ); } else if ( op[1] == '=' ) { num = (num >= val); *(_num.zero.seg) = gte__mcc_int( &_num, &_val ); } else { num = (num > val); *(_num.zero.seg) = gth__mcc_int( &_num, &_val ); } goto done; case '<': if ( op[1] == '<' ) { num = (num << val); shl__mcc_int( &_num, &_val ); } else if ( op[1] == '=' ) { num = (num <= val); *(_num.zero.seg) = lte__mcc_int( &_num, &_val ); } else { num = (num < val); *(_num.zero.seg) = lth__mcc_int( &_num, &_val ); } goto done; } done: if ( memcmp( _num.zero.seg, &num, sizeof(int) ) ) ret = EXIT_SUCCESS; printf( "_num = %08lX, num = %08X, b4 = %08X, val = %08X, " "_rem = %08lX, rem = %08X op = '%s'\n", *(_num.zero.seg), num, b4, val, *(_rem.zero.seg), rem, op ); fail: mcc_int_size( &_num, 0 ); mcc_int_size( &_val, 0 ); mcc_int_size( &_rem, 0 ); return ret; } #endif #include <float.h> #define INC_BITMATH #ifdef INC_BITMATH //#include "bimath.c" #else #define bitsof(T) (CHAR_BIT * sizeof(T)) #include <limits.h> #include <inttypes.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #endif typedef signed char schar; typedef unsigned char uchar; typedef unsigned long ulong; typedef signed long long sllong; typedef unsigned long long ullong; #define mcc_huge __int128 typedef signed mcc_huge mcc_huge_t; typedef unsigned mcc_huge mcc_uhuge_t; #ifdef HALF_MANT_DIG #define HALF_SCNa "%ha" #define HALF_SCNf "%hf" #define HALF_SCNe "%he" #define HALF_MAN_BIT (HALF_MANT_DIG - 1) #define HALF_EXP_BIT (bitsof(half) - HALF_MANT_DIG) #endif #define FLT_SCNa "%a" #define FLT_SCNf "%f" #define FLT_SCNe "%e" #define FLT_MAN_BIT (FLT_MANT_DIG - 1) #define FLT_EXP_BIT (bitsof(float) - FLT_MANT_DIG) typedef union FLT_UNION { float fpn; mcc_uhuge_t raw; struct { mcc_uhuge_t man:FLT_MAN_BIT; mcc_uhuge_t exp:FLT_EXP_BIT; mcc_uhuge_t sig:1; }; } FLT_UNION; #define DBL_SCNa "%la" #define DBL_SCNf "%lf" #define DBL_SCNe "%le" #define DBL_MAN_BIT (DBL_MANT_DIG - 1) #define DBL_EXP_BIT (bitsof(double) - DBL_MANT_DIG) typedef union DBL_UNION { double fpn; mcc_uhuge_t raw; struct { mcc_uhuge_t man:DBL_MAN_BIT; mcc_uhuge_t exp:DBL_EXP_BIT; mcc_uhuge_t sig:1; }; } DBL_UNION; #define LDBL_SCNa "%lla" #define LDBL_SCNf "%llf" #define LDBL_SCNe "%lle" #define LDBL_MAN_BIT (LDBL_MANT_DIG - 1) #define LDBL_EXP_BIT (bitsof(long double) - LDBL_MANT_DIG) typedef union LDBL_UNION { long double fpn; mcc_uhuge_t raw; struct { mcc_uhuge_t man:LDBL_MAN_BIT; mcc_uhuge_t exp:LDBL_EXP_BIT; mcc_uhuge_t sig:1; }; } LDBL_UNION; #define FPN_PFX(VAL) FLT##_##VAL #define FPN_MAX FPN_PFX(_MAX) #define FPN_SCNa FPN_PFX(SCNa) #define FPN_SCNf FPN_PFX(SCNf) #define FPN_SCNe FPN_PFX(SCNe) #define FPN_RADIX FPN_PFX(RADIX) #define FPN_ROUNDS FPN_PFX(ROUNDS) #define FPN_MAN_BIT FPN_PFX(MAN_BIT) #define FPN_MAN_DIG FPN_PFX(MANT_DIG) #define FPN_EXP_BIT FPN_PFX(EXP_BIT) #define FPN_MAX_EXP FPN_PFX(MAX_EXP) #define FPN_MIN_EXP FPN_PFX(MIN_EXP) #define FPN_MAX_EXP_DIG FPN_PFX(MAX_10_EXP) #define FPN_MIN_EXP_DIG FPN_PFX(MIN_10_EXP) typedef FPN_PFX(UNION) FPN_UNION; typedef struct mcc_flexable_fpn { long man_bits; long exp_bits; mcc_uhuge_t negative; mcc_uhuge_t num; mcc_uhuge_t one; mcc_uhuge_t fpn; long exp; long max_exp; long min_exp; long max_exp_digits; long min_exp_digits; ulong exp_bias; ulong base; mcc_uhuge_t raw; } mcc_flexable_fpn_t; #define FPN_MAKE big_make mcc_flexable_fpn_t fpn_make ( mcc_flexable_fpn_t flex ); mcc_flexable_fpn_t big_make ( mcc_flexable_fpn_t flex ); mcc_flexable_fpn_t fpn_read ( char *text, FPN_UNION *gcc, mcc_flexable_fpn_t flex ); char *fpn_text[] = { "0", "1", "10", "16", "100", "101", "0.1", "0.01", "0.001", "0.101", "1.1", "1.01", "1.001", "1.101", "3.14", "1e+1", "1e+8", "1e+10", "1e+100", "3e+1", "1e-1", "1e-8", "1e-10", "1e-100", "3e-1", ".1e+1", ".1e+8", ".1e+10", ".1e+100", ".3e+1", ".1e-1", ".1e-8", ".1e-10", ".1e-100", ".3e-1", "1.1e+1", "1.1e+8", "1.1e+10", "1.1e+100", "3.1e+1", "1.1e-1", "1.1e-8", "1.1e-10", "1.1e-100", "3.1e-1", "3.14e+1", "3.14e+8", "3.14e+10", "3.14e+100", "3.14e-1", "3.14e-8", "3.14e-10", "3.14e-100", "-0", "-1", "-10", "-16", "-100", "-101", "-0.1", "-0.01", "-0.001", "-0.101", "-1.1", "-1.01", "-1.001", "-1.101", "-3.14", "-1e+1", "-1e+8", "-1e+10", "-1e+100", "-3e+1", "-1e-1", "-1e-8", "-1e-10", "-1e-100", "-3e-1", "-0.1e+1", "-0.1e+8", "-0.1e+10", "-0.1e+100", "-0.3e+1", "-0.1e-1", "-0.1e-8", "-0.1e-10", "-0.1e-100", "-0.3e-1", "-1.1e+1", "-1.1e+8", "-1.1e+10", "-1.1e+100", "-3.1e+1", "-1.1e-1", "-1.1e-8", "-1.1e-10", "-1.1e-100", "-3.1e-1", "-3.14e+1", "-3.14e+8", "-3.14e+10", "-3.14e+100", "-3.14e-1", "-3.14e-8", "-3.14e-10", "-3.14e-100", "0xA", "0xA0", "0xA6", "0xA00", "0xA0A", "0x0.A", "0x0.0A", "0x0.00A", "0x0.A0A", "0xA.A", "0xA.0A", "0xA.00A", "0xA.A0A", "0xC.A4", "0xAp+A", "0xAp+F", "0xAp+A0", "0xAp+A00", "0xCp+A", "0xAp-A", "0xAp-F", "0xAp-A0", "0xAp-A00", "0xCp-A", "0x0.Ap+A", "0x0.Ap+F", "0x0.Ap+A0", "0x0.Ap+A00", "0x0.Cp+A", "0x0.Ap-A", "0x0.Ap-F", "0x0.Ap-A0", "0x0.Ap-A00", "0x0.Cp-A", "0xA.Ap+A", "0xA.Ap+F", "0xA.Ap+A0", "0xA.Ap+A00", "0xC.Ap+A", "0xA.Ap-A", "0xA.Ap-F", "0xA.Ap-A0", "0xA.Ap-A00", "0xC.Ap-A", "0xC.A4p+A", "0xC.A4p+F", "0xC.A4p+A0", "0xC.A4p+A00", "0xC.A4p-A", "0xC.A4p-F", "0xC.A4p-A0", "0xC.A4p-A00", "-0xA", "-0xA0", "-0x10", "-0xA00", "-0xA0A", "-0x0.A", "-0x0.0A", "-0x0.00A", "-0x0.A0A", "-0xA.A", "-0xA.0A", "-0xA.00A", "-0xA.A0A", "-0xC.A4", "-0xAp+A", "-0xAp+F", "-0xAp+A0", "-0xAp+A00", "-0xCp+A", "-0xAp-A", "-0xAp-F", "-0xAp-A0", "-0xAp-A00", "-0xCp-A", "-0x0.Ap+A", "-0x0.Ap+F", "-0x0.Ap+A0", "-0x0.Ap+A00", "-0x0.Cp+A", "-0x0.Ap-A", "-0x0.Ap-F", "-0x0.Ap-A0", "-0x0.Ap-A00", "-0x0.Cp-A", "-0xA.Ap+A", "-0xA.Ap+F", "-0xA.Ap+A0", "-0xA.Ap+A00", "-0xC.Ap+A", "-0xA.Ap-A", "-0xA.Ap-F", "-0xA.Ap-A0", "-0xA.Ap-A00", "-0xC.Ap-A", "-0xC.A4p+A", "-0xC.A4p+F", "-0xC.A4p+A0", "-0xC.A4p+A00", "-0xC.A4p-A", "-0xC.A4p-F", "-0xC.A4p-A0", "-0xC.A4p-A00", NULL }; void printb( char const *text, void const * addr, size_t const bits ) { size_t size = bits / CHAR_BIT, b = 0; uchar const *a = addr; uchar val, bit; if ( bits % CHAR_BIT ) ++size; printf("%s",text); while ( size-- ) { for ( val = a[size], bit = 1; bit; val <<= 1, bit <<= 1, ++b ) putchar( '0' + !!(val & SCHAR_MIN) ); if ( b >= bits ) return; } } mcc_flexable_fpn_t copy_of_temp = {0}; _Bool check( char *text, FPN_UNION gcc, FPN_UNION mcc, mcc_flexable_fpn_t flex ) { _Bool same = (gcc.raw == mcc.raw), similar; mcc_flexable_fpn_t temp = flex; ulong val; temp.raw--; similar = (gcc.raw == temp.raw); if ( !same && !similar ) { printb( "gcc = ", &gcc, bitsof(mcc_uhuge_t) ); putchar('\n'); printb( "mcc = ", &mcc, bitsof(mcc_uhuge_t) ); putchar('\n'); val = gcc.exp; printb( "gcc.exp = ", &val, 11 ); putchar('\n'); val = mcc.exp; printb( "mcc.exp = ", &val, 11 ); putchar('\n'); printf ("fpn t = " FPN_SCNe " m = " FPN_SCNe "\n", gcc.fpn, mcc.fpn ); printf("read as %s", flex.negative ? "-" : "" ); if ( flex.base == 10 ) { if ( flex.exp < 0 ) printf( "%llu.%llue%ld", (ullong)(flex.num), (ullong)(flex.fpn), flex.exp ); else printf( "%llu.%llue+%ld", (ullong)(flex.num), (ullong)(flex.fpn), flex.exp ); } else { if ( flex.exp < 0 ) printf( "%llX.%llXp-%lX", (ullong)(flex.num), (ullong)(flex.fpn), flex.exp ); else printf( "%llX.%llXp+%lX", (ullong)(flex.num), (ullong)(flex.fpn), flex.exp ); } printf(" with base %lu\n", flex.base ); printf ("value '%s'", text ); } else { temp = copy_of_temp; } return !same; } #define TEST_NEG 0 #define TEST_FPN 0 #define TEST_BOTH 0 void exponent( mcc_flexable_fpn_t flex, size_t limit ) { mcc_flexable_fpn_t temp; FPN_UNION gcc = {0}, mcc = {0}; size_t i = 0, wrong = 0, j = 0, total = 0; char text[128] = {0}, etxt[8] = {0}; if ( flex.exp > 0 ) snprintf(etxt, 8, "e+%02ld",flex.exp); else if ( flex.exp < 0 ) snprintf(etxt, 8, "e%02ld",flex.exp); flex.exp = 0; wrong = 0; for ( i = 0; i <= limit; ++i ) { snprintf(text,128,"%zu.000000%s",i,etxt); mcc.raw = (temp = fpn_read(text, &gcc, flex)).raw; wrong += check( text, gcc, mcc, temp ); putchar('\n'); #if TEST_NEG snprintf(text,128,"-%zu.000000%s",i,etxt); mcc.raw = (temp = fpn_read(text, &gcc, flex)).raw; wrong += check( text, gcc, mcc, temp ); putchar('\n'); #endif } j += i * (1 + TEST_NEG); total += wrong; if ( wrong ) printf( "Tried = %zu, Wrong = %zu\n", i, wrong ); #if TEST_FPN wrong = 0; for ( i = 0; i <= limit; ++i ) { snprintf(text,128,"0.%06zu%s",i,etxt); mcc.raw = (temp = fpn_read(text, &gcc, flex)).raw; wrong += check( text, gcc, mcc, temp ); putchar('\n'); #if TEST_NEG snprintf(text,128,"-0.%06zu%s",i,etxt); mcc.raw = (temp = fpn_read(text, &gcc, flex)).raw; wrong += check( text, gcc, mcc, temp ); putchar('\n'); #endif } j += i * (1 + TEST_NEG); total += wrong; if ( wrong ) printf( "Tried = %zu, Wrong = %zu\n", i, wrong ); #endif #if TEST_BOTH wrong = 0; for ( i = 0; i <= limit; ++i ) { snprintf(text,128,"%zu.%06zu%s",i,i,etxt); mcc.raw = (temp = fpn_read(text, &gcc, flex)).raw; wrong += check( text, gcc, mcc, temp ); putchar('\n'); #if TEST_NEG snprintf(text,128,"-%zu.%06zu%s",i,i,etxt); mcc.raw = (temp = fpn_read(text, &gcc, flex)).raw; wrong += check( text, gcc, mcc, temp ); putchar('\n'); #endif } j += i * (1 + TEST_NEG); total += wrong; if ( wrong ) printf( "Tried = %zu, Wrong = %zu\n", i, wrong ); #endif if ( total ) printf( "Total Tried = %zu, Total Wrong = %zu\n", j, total ); } int main () { size_t i = 0, limit = 35; #if 0 size_t wrong = 0; FPN_UNION gcc, mcc; #endif mcc_flexable_fpn_t flex = {0}, temp; printf("FLT_DIG %d\n", FLT_DIG ); printf("FLT_EXP_BIT %lu\n", FLT_EXP_BIT ); printf("FLT_EPSILON %le\n", FLT_EPSILON ); printf("FLT_MAX_EXP %d\n", FLT_MAX_EXP ); printf("FLT_MIN_EXP %d\n", FLT_MIN_EXP ); printf("FLT_MAX_10_EXP %d\n", FLT_MAX_10_EXP ); printf("FLT_MIN_10_EXP %d\n", FLT_MIN_10_EXP ); printf("FLT_MANT_DIG %d\n", FLT_MANT_DIG ); printf("FLT_MAN_BIT %d\n", FLT_MAN_BIT ); printf("FLT_RADIX %d\n", FLT_RADIX ); printf("FLT_ROUNDS %d\n", FLT_ROUNDS ); flex.exp_bias = FPN_MAX_EXP; flex.exp_bits = FPN_EXP_BIT; flex.max_exp_digits = FPN_MAX_EXP_DIG; flex.min_exp_digits = FPN_MIN_EXP_DIG; flex.max_exp = FPN_MAX_EXP; flex.min_exp = FPN_MIN_EXP; flex.man_bits = FPN_MAN_BIT; temp = flex; for ( i = 0; i <= FPN_MAX_EXP; ++i ) { temp.exp = i; exponent( temp, limit ); temp.exp = -(temp.exp); } #if 0 for ( i = 0; fpn_text[i] && i < 25; ++i ) { mcc.raw = (temp = fpn_read (fpn_text[i], &gcc, flex)); if ( check(fpn_text[i], gcc, mcc, temp) ) { printf (" index = %03zu\n", i ); ++wrong; } } printf( "Text Tried = %zu, ", i ); while (fpn_text[i]) ++i; printf( "Text Wrong = %zu", wrong ); #endif return 0; } mcc_flexable_fpn_t fpn_make ( mcc_flexable_fpn_t flex ) { mcc_flexable_fpn_t temp = flex; long pos = 0, pos_max = flex.man_bits; mcc_uhuge_t NUM; flex.raw = 0; temp.negative <<= temp.man_bits; temp.negative <<= temp.exp_bits; if ( !(temp.num) && !(temp.fpn) ) { flex.raw = temp.negative; copy_of_temp = temp; return flex; } if ( temp.exp < temp.min_exp || temp.exp > temp.max_exp ) { fpn_infinity: flex.raw = 0; flex.raw = ~(flex.raw); flex.raw <<= temp.exp_bits; flex.raw = ~(flex.raw); flex.raw <<= temp.man_bits; flex.raw |= temp.negative; copy_of_temp = temp; return flex; } /* Preserve exponent in case we need it later */ pos = temp.exp; while ( pos > 0 && temp.one > 1 ) { temp.num *= temp.base; temp.one /= temp.base; if ( temp.fpn >= temp.one ) { NUM = temp.fpn / temp.one; temp.fpn -= NUM * temp.one; temp.num += NUM; } --pos; } while ( pos > 0 ) { temp.num *= temp.base; --pos; } while ( pos < 0 ) { NUM = temp.num % temp.base; temp.fpn += NUM * temp.one; temp.one *= temp.base; temp.num /= temp.base; pos++; } if ( !(temp.num) && !(temp.fpn) ) goto fpn_infinity; /* Calculate normal exponent */ pos = 0; if ( temp.num ) { for ( NUM = temp.num; !(NUM & 1u); ++pos, NUM >>= 1 ); temp.raw = 0; temp.raw = ~(temp.raw); temp.raw <<= temp.man_bits + 1; temp.raw = ~(temp.raw); if ( pos > temp.max_exp_digits ) goto fpn_infinity; for ( ; NUM > 1; ++pos, NUM >>= 1 ); } else for ( NUM = temp.fpn; NUM && NUM < temp.one; --pos, NUM <<= 1 ); /* Set exponent and mantissa */ temp.raw = temp.exp_bias + pos - 1; flex.raw = temp.num; if ( pos <= temp.min_exp + 1 ) goto fpn_infinity; if ( pos >= temp.max_exp - 1 ) goto fpn_infinity; if ( pos > pos_max ) { pos -= pos_max; flex.raw >>= pos - 1; temp.fpn = flex.raw & 1u; flex.raw >>= 1; temp.one = 2; } else { for ( ; pos < pos_max; ++pos) { temp.fpn <<= 1; flex.raw <<= 1; if (temp.fpn >= temp.one) { flex.raw |= 1; temp.fpn -= temp.one; } } } temp.fpn *= 2; if ( temp.fpn >= temp.one ) flex.raw++; temp.one = bitsof(mcc_uhuge_t) - (temp.man_bits); flex.raw <<= temp.one; flex.raw >>= temp.one; flex.raw |= (temp.raw << temp.man_bits); flex.raw |= temp.negative; copy_of_temp = temp; return flex; } mcc_flexable_fpn_t fpn_read ( char *text, FPN_UNION *gcc, mcc_flexable_fpn_t flex ) { uchar *txt = (uchar*)text; ulong c; gcc->raw = 0; flex.raw = 0; flex.base = 10; flex.negative = (*txt == '-'); if ( flex.negative || *txt == '+' ) ++txt; if ( *txt =='0' ) { ++txt; if ( *txt == 'x' || *txt == 'X' ) { flex.base = 16; ++txt; } } if ( flex.base == 10 ) sscanf (text, FPN_SCNf, &(gcc->fpn)); else sscanf (text, FPN_SCNa, &(gcc->fpn)); while (*txt == '0') ++txt; for ( flex.num = 0; *txt; ++txt ) { if ( *txt >= '0' && *txt <= '9' ) c = *txt - '0'; else if ( *txt >= 'A' && *txt <= 'F' ) c = 10 + ( *txt - 'A' ); else if ( *txt >= 'a' && *txt <= 'f' ) c = 10 + ( *txt - 'a' ); else break; if ( c >= flex.base ) break; flex.num *= flex.base; flex.num += c; } flex.one = 1; flex.fpn = 0; if (*txt == '.') { for ( ++txt; *txt; ++txt) { if ( *txt >= '0' && *txt <= '9' ) c = *txt - '0'; else if ( *txt >= 'A' && *txt <= 'F' ) c = 10 + ( *txt - 'A' ); else if ( *txt >= 'a' && *txt <= 'f' ) c = 10 + ( *txt - 'a' ); else break; if ( c >= flex.base ) break; flex.one *= flex.base; flex.fpn *= flex.base; flex.fpn += c; } } if (*txt == 'e' || *txt == 'E') { if (*(++txt) == '-') { for (++txt; *txt; ++txt) { if ( *txt >= '0' && *txt <= '9' ) c = *txt - '0'; else if ( *txt >= 'A' && *txt <= 'F' ) c = 10 + ( *txt - 'A' ); else if ( *txt >= 'a' && *txt <= 'f' ) c = 10 + ( *txt - 'f' ); else break; if ( c >= flex.base ) break; flex.exp *= flex.base; flex.exp -= c; } } else { for (++txt; *txt; ++txt) { if ( *txt >= '0' && *txt <= '9' ) c = *txt - '0'; else if ( *txt >= 'A' && *txt <= 'F' ) c = 10 + ( *txt - 'A' ); else if ( *txt >= 'a' && *txt <= 'f' ) c = 10 + ( *txt - 'f' ); else break; if ( c >= flex.base ) break; flex.exp *= flex.base; flex.exp += c; } } } return FPN_MAKE(flex); } mcc_flexable_fpn_t big_make ( mcc_flexable_fpn_t flex ) { int ret = 0; mcc_flexable_fpn_t temp = flex; long pos = 0, pos_max = flex.man_bits; mcc_int_t NUM = {0}, num = {0}, fpn = {0}, one = {0}, base = {0}, cpy = {0}; flex.raw = 0; temp.negative <<= temp.man_bits; temp.negative <<= temp.exp_bits; ret = mcc_int_size( &num, 32 ); if ( ret != EXIT_SUCCESS ) goto big_zero; ret = mcc_int_size( &cpy, num.size ); if ( ret != EXIT_SUCCESS ) goto big_zero; ret = mcc_int_size( &fpn, num.size ); if ( ret != EXIT_SUCCESS ) goto big_zero; ret = mcc_int_size( &NUM, num.size ); if ( ret != EXIT_SUCCESS ) goto big_zero; ret = mcc_int_size( &one, num.size ); if ( ret != EXIT_SUCCESS ) goto big_zero; ret = mcc_int_size( &base, num.size ); if ( ret != EXIT_SUCCESS ) goto big_zero; memset( num.zero.seg, 0, num.size ); memcpy( num.zero.seg, &temp.num, sizeof(mcc_uhuge_t) ); memset( fpn.zero.seg, 0, fpn.size ); memcpy( fpn.zero.seg, &temp.fpn, sizeof(mcc_uhuge_t) ); memset( NUM.zero.seg, 0, NUM.size ); memset( one.zero.seg, 0, one.size ); memcpy( one.zero.seg, &temp.one, sizeof(mcc_uhuge_t) ); memset( base.zero.seg, 0, base.size ); memcpy( base.zero.seg, &temp.base, sizeof(ulong) ); if ( !(temp.num) && !(temp.fpn) ) { big_zero: flex.raw = temp.negative; copy_of_temp = temp; goto big_free_all; } if ( temp.exp < temp.min_exp || temp.exp > temp.max_exp ) { big_infinity: flex.raw = 0; flex.raw = ~(flex.raw); flex.raw <<= temp.exp_bits; flex.raw = ~(flex.raw); flex.raw <<= temp.man_bits; flex.raw |= temp.negative; copy_of_temp = temp; goto big_free_all; } /* Preserve exponent in case we need it later */ pos = temp.exp; while ( pos > 0 && temp.one > 1 ) { mul__mcc_int( &num, &base ); div__mcc_int( &num, &base, &cpy ); if ( gte__mcc_int( &fpn, &one ) ) { memcpy( NUM.zero.seg, fpn.zero.seg, fpn.size ); div__mcc_int( &NUM, &one, &cpy ); add__mcc_int( &num, &NUM ); mul__mcc_int( &NUM, &one ); sub__mcc_int( &fpn, &NUM ); } --pos; } while ( pos > 0 ) { mul__mcc_int( &num, &base ); --pos; } while ( pos < 0 ) { div__mcc_int( &num, &base, &NUM ); mul__mcc_int( &NUM, &one ); add__mcc_int( &fpn, &NUM ); mul__mcc_int( &one, &base ); pos++; } if ( eql__mcc_int(&num,NULL) && eql__mcc_int(&fpn,NULL) ) goto big_infinity; /* Calculate normal exponent */ pos = 0; if ( temp.num ) { memcpy( NUM.zero.seg, num.zero.seg, num.size ); while ( !(*(NUM.zero.seg) & 1u ) ) { shr___mcc_int( &NUM, 1 ); ++pos; } temp.raw = 0; temp.raw = ~(temp.raw); temp.raw <<= temp.man_bits + 1; temp.raw = ~(temp.raw); if ( pos > temp.max_exp_digits ) goto big_infinity; memset( cpy.zero.seg, 0, cpy.size ); *(cpy.zero.seg) = 1; while ( gth__mcc_int( &NUM, &cpy ) ) { shr___mcc_int( &NUM, 1 ); ++pos; } } else { memcpy( NUM.zero.seg, fpn.zero.seg, fpn.size ); while ( neq__mcc_int( &NUM, NULL ) && lth__mcc_int( &NUM, &one ) ) { shl___mcc_int( &NUM, 1 ); --pos; } } /* Set exponent and mantissa */ temp.raw = temp.exp_bias + pos - 1; memcpy( &(flex.raw), num.zero.seg, sizeof(mcc_uhuge_t) ); flex.raw = temp.num; if ( pos <= temp.min_exp + 1 ) goto big_infinity; if ( pos >= temp.max_exp - 1 ) goto big_infinity; if ( pos > pos_max ) { pos -= pos_max; flex.raw >>= pos - 1; temp.fpn = flex.raw & 1u; flex.raw >>= 1; temp.one = 2; } else { for ( ; pos < pos_max; ++pos) { shl___mcc_int( &fpn, 1 ); flex.raw <<= 1; if ( gte__mcc_int(&fpn, &one) ) { flex.raw |= 1; sub__mcc_int( &fpn, &one ); } } } shl___mcc_int( &fpn, 1 ); if ( gte__mcc_int(&fpn, &one) ) flex.raw++; temp.one = bitsof(mcc_uhuge_t) - (temp.man_bits); flex.raw <<= temp.one; flex.raw >>= temp.one; flex.raw |= (temp.raw << temp.man_bits); flex.raw |= temp.negative; copy_of_temp = temp; big_free_all: mcc_int_size( &base, 0 ); mcc_int_size( &one, 0 ); mcc_int_size( &NUM, 0 ); mcc_int_size( &fpn, 0 ); mcc_int_size( &cpy, 0 ); mcc_int_size( &num, 0 ); return flex; }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue