X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc.so_src%2Fprintf.c;h=1b61cba85175df614bcda571c3cfa3b681c1a522;hb=49e5712c717c8960e12097e976335ed955e6cd50;hp=869ba227812bcb184bddbf5732bc7781001506c6;hpb=f3e1eb04c7af39e90eebf712ca5bf346cb86045b;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libc.so_src/printf.c b/Usermode/Libraries/libc.so_src/printf.c index 869ba227..1b61cba8 100644 --- a/Usermode/Libraries/libc.so_src/printf.c +++ b/Usermode/Libraries/libc.so_src/printf.c @@ -1,4 +1,4 @@ -/* +#include /* * Acess2 C Library * - By John Hodge (thePowersGang) * @@ -200,7 +200,7 @@ EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *for _addchar('0'); _addchar(c); } - arg = bLongLong ? va_arg(args, int64_t) : va_arg(args, int32_t); + arg = bLongLong ? va_arg(args, uint64_t) : va_arg(args, uint32_t); pos += _printf_itoa(putch_cb, putch_h, arg, 16, c=='X', FALSE, '\0', precision, minSize,cNumPad,bJustifyLeft); break; @@ -240,6 +240,13 @@ EXPORT int _vcprintf_int(printf_putch_t putch_cb, void *putch_h, const char *for pos += _printf_ftoa(putch_cb, putch_h, arg_f, 10, FPN_SCI, precision, 0, bJustifyLeft, c == 'E'); break; + // Scientific Float + case 'g': + case 'G': + arg_f = bLong ? va_arg(args, long double) : va_arg(args, double); + pos += _printf_ftoa(putch_cb, putch_h, arg_f, 10, FPN_SHORTEST, + precision, 0, bJustifyLeft, c == 'G'); + break; // Hexadecimal Scientific case 'a': case 'A': @@ -417,7 +424,8 @@ size_t _printf_itoa(printf_putch_t putch_cb, void *putch_h, uint64_t num, tmpBuf[pos++] = map[ num % base ]; // Last digit of {number} // length of number, minus the sign character - PadLength -= pos - sign_is_neg - (SignChar != '\0'); + PadLength -= pos + (sign_is_neg || SignChar != '\0'); + Precision -= pos + (sign_is_neg || SignChar != '\0'); if( !bPadRight ) { while(PadLength-- > 0) @@ -465,13 +473,13 @@ int expand_double(double num, uint64_t *Significand, int16_t *Exponent, int *Sig // printf("%llx %i %i %llx\n", *bit_rep, (int)*SignIsNeg, (int)*Exponent, *Significand); // Subnormals - if( *Exponent == -1023 && *Significand != 0 ) + if( *Exponent == -0x3FF && *Significand != 0 ) return 1; // Infinity - if( *Exponent == 0x800 && *Significand == 0) + if( *Exponent == 0x400 && *Significand == 0) return 2; // NaNs - if( *Exponent == 0x800 && *Significand != 0) + if( *Exponent == 0x400 && *Significand != 0) return 3; return 0; @@ -573,12 +581,111 @@ size_t _printf_ftoa_hex(printf_putch_t putch_cb, void *putch_h, long double num, return ret; } +#if 0 +size_t _printf_itoa_fixed(printf_putch_t putch_cb, void *putch_h, uint64_t num, size_t Base) +{ + uint64_t den; + size_t ret = 0; + + den = 1ULL << (64-1); + + while( den ) + { + putch_cb(putch_h, cDIGITS[num / den]); + ret ++; + num %= den; + den /= Base; + } + + return ret; +} + +size_t _printf_ftoa_dec(printf_putch_t putch_cb, void *putch_h, long double num, enum eFPN Notation, int Precision, int bForcePoint, int bForceSign, int bCapitals) +{ + size_t ret = 0; + int i; + + #define _putch(_ch) do{\ + putch_cb(putch_h, bCapitals ? toupper(_ch) : _ch), ret++;\ + }while(0) + + uint64_t significand; + int16_t exponent; + int signisneg; + int rv = expand_double(num, &significand, &exponent, &signisneg); + switch(rv) + { + // 0: No errors, nothing special + case 0: + break; + // 1: Subnormals + case 1: + // TODO: Subnormal = 0? + break; + // 2: Infinity + case 2: + _putch('i'); + _putch('n'); + _putch('f'); + return 3; + case 3: + _putch('N'); + _putch('a'); + _putch('N'); + return 3; + } + + uint64_t whole, part; + int pre_zeros, post_zeros; + + #define XXX 0 + if( Notation == FPN_SCI ) + { + } + else if( exponent < 0 ) + { + whole = 0; + part = XXX; + pre_zeros = 0; + post_zeros = XXX; + } + else if( exponent >= 64 ) + { + part = 0; + whole = XXX; + pre_zeros = XXX; + post_zeros = 0; + } + else + { + // Split into fixed point + whole = (1 << exponent) | (significand >> (64-exponent)); + part = significand << exponent; + pre_zeros = 0; + post_zeros = 0; + } + + + // Whole portion + ret += _printf_itoa(putch_cb, putch_h, whole, 10, FALSE, FALSE, '\0', 0, 0, '\0', FALSE); + for(i = pre_zeros; i --; ) _putch('0'); + // TODO: Conditional point + _putch('-'); + for(i = post_zeros; i--; ) _putch('0'); + ret += _printf_itoa_fixed(putch_cb, putch_h, part, 10); + + #undef _putch + + return 0; +} +#endif + size_t _printf_ftoa(printf_putch_t putch_cb, void *putch_h, long double num, size_t Base, enum eFPN Notation, int Precision, int bForcePoint, int bForceSign, int bCapitals) { uint64_t significand; int16_t exponent; int signisneg; - int rv; + int rv, i; size_t ret = 0; #define _putch(_ch) do{\ @@ -631,12 +738,24 @@ size_t _printf_ftoa(printf_putch_t putch_cb, void *putch_h, long double num, siz { //TODO: //int first_set_sig = BSL(significand); - // TODO: if( num > pos(Base, 2+Precision+2+log_base(exponent) ) - Notation = FPN_SCI; + // bSign+log10(num)+1+precision vs. bSign+1+1+precision+1+1+log10(exponent) + int log10_num = exponent * 301 / 1000; // log_10(2) = 0.30102999566... + int log10_exp10 = 2; + int sci_len = (signisneg || bForceSign) + 2 + (Precision-1) + 2 + log10_exp10; + int std_whole_len = (log10_num > 0 ? log10_num : 1); + int std_len = (signisneg || bForceSign) + std_whole_len + 1 + (Precision-std_whole_len); + if( sci_len > std_len ) { + Precision -= std_whole_len; + Notation = FPN_STD; + } + else { + Precision -= 1; + Notation = FPN_SCI; + } } double precision_max = 1; - while(Precision--) + for(i = Precision; i--; ) precision_max /= Base; // Determine scientific's exponent and starting denominator @@ -666,9 +785,9 @@ size_t _printf_ftoa(printf_putch_t putch_cb, void *putch_h, long double num, siz } den = 1; } - else + else if( num != 0.0 ) { - while( den < num ) + while( den <= num ) den *= Base; den /= Base; } @@ -680,6 +799,8 @@ size_t _printf_ftoa(printf_putch_t putch_cb, void *putch_h, long double num, siz _putch('+'); else { } + + num += precision_max/10 * 4.999; int value; // Whole section @@ -691,10 +812,10 @@ size_t _printf_ftoa(printf_putch_t putch_cb, void *putch_h, long double num, siz } while( den >= 1 ); // Decimal point (if needed/forced) - if( den >= precision_max || bForcePoint ) + if( Precision > 0 || bForcePoint ) _putch('.'); // Decimal section - while( den >= precision_max ) + for(i = Precision; i--; ) { num = _longdiv(num, den, &value); _putch(cDIGITS[value]); @@ -707,7 +828,7 @@ size_t _printf_ftoa(printf_putch_t putch_cb, void *putch_h, long double num, siz _putch('p'); else _putch('e'); - ret += _printf_itoa(putch_cb, putch_h, sci_exponent, Base, FALSE, TRUE, '+', 0, 0, '\0', FALSE); + ret += _printf_itoa(putch_cb, putch_h, sci_exponent, Base, FALSE, TRUE, '+', 3, 0, '\0', FALSE); } #undef _putch