double ScanDoubleT(const T *p, const T **endptr, bool accept_comma) { const T *begin = p; while(*p && (byte)*p <= ' ') p++; bool neg = false; if(endptr) *endptr = p; if(*p == '+' || *p == '-') neg = (*p++ == '-'); if((byte)(*p - '0') >= 10 && !((*p == '.' || accept_comma && *p == ',') && (byte)(p[1] - '0') < 10)) { if(endptr) *endptr = begin; return Null; } double mantissa = 0; T c; int exp = 0; while((byte)(*p - '0') < 10) if((c = *p++) != '0') { if(exp) { mantissa *= ipow10(exp); exp = 0; } mantissa = 10 * mantissa + c - '0'; } else exp++; int raise = exp; if(*p == '.' || accept_comma && *p == ',') // decimal part while((byte)((c = *++p) - '0') < 10) { if(c != '0') { if(raise) { mantissa *= ipow10(raise); exp -= raise; raise = 0; } exp--; mantissa = 10 * mantissa + c - '0'; if(!IsFin(mantissa)) return Null; } else raise++; } if(*p == 'E' || *p == 'e') { // exponent int vexp = ScanInt(p + 1, &p); if(IsNull(vexp)) return Null; exp += vexp; } if(endptr) *endptr = p; if(exp) { double e = ipow10(tabs(exp)); mantissa = (exp > 0 ? mantissa * e : mantissa / e); } if(!IsFin(mantissa)) return Null; return neg ? -mantissa : mantissa; }
long fx_numeric_field::change_on_digit(int sign) { FXString txt = getText(); int pos = getCursorPos(); int pow_exp, dot_pos; int norm = get_normalized_int (txt.text(), pow_exp, dot_pos); if (dot_pos < 0) return 0; int pos_exp = dot_pos - pos; if (pos_exp < 0) pos_exp ++; int inc_abs = ipow10 (pos_exp + pow_exp); norm += sign * inc_abs; FXString new_txt = denormalize (norm, pow_exp, dot_pos); int new_pos = dot_pos - pos_exp; if (pos_exp < 0) new_pos ++; setText(new_txt); setCursorPos(new_pos); if (target) target->tryHandle(this, FXSEL(SEL_CHANGED,message), (void*)new_txt.text()); return 1; }
double ceilr(double d, int digits) { int i = ilog10(d); if(IsNull(i)) return d; double fac = ipow10(i - digits); return ceil(d / fac) * fac; }
double roundr(double d, int digits) { int i = ilog10(d); if(IsNull(i)) return d; double fac = ipow10(i - digits); return floor(d / fac + 0.5) * fac; }
void lcdPrintInt(int inum, char width) { char len = (inum == 0? 1 : (ilog10(inum) + 1)); int i; for(i = 0; i < width - len; i++) lcdWrite('0', 1, 1); for(i = ipow10(len - 1); i > 0; inum %= i, i /= 10, len--) lcdWrite('0' + inum/i, 1, 1); }
void Math_pow10(void *fp) { F_Math_pow10 *f; f = fp; *f->ret = ipow10(f->p); }
static int get_normalized_int (const char* txt, int& pow_exp, int& dot_pos) { char const *tail; int int_part, frac_part, sign; dot_pos = parse_number (txt, int_part, frac_part, sign, pow_exp, &tail); if (dot_pos < 0) return 0; int_part *= ipow10 (pow_exp); return sign * (int_part + frac_part); }
void lcdPrintFloat(float fnum, char width, short prec) { long i , j; char len; if(fnum < 0) { lcdWrite('-', 1, 1); i = -fnum; } else { i = fnum; } len = (i == 0 ? 1 : (ilog10(i) + 1)) + prec; i = fnum * ipow10(prec); for(j = 0; j < width - len - (prec != 0); j++) lcdWrite('0', 1, 1); for(j = ipow10(len - 1); j > 0; i %= j, j /= 10, len--) { lcdWrite('0' + i/j, 1, 1); if(prec > 0 && len - 1 == prec) lcdWrite('.', 1, 1); } }
double normalize(double d, int& exp) { if(IsNull(d) || d == 0) { exp = Null; return d; } bool sign = (d < 0); if(sign) d = -d; exp = minmax<int>(ilog10(d), -300, +300); // 8-byte double! d /= ipow10(exp); if(d >= 10) { d /= 10; exp++; } if(d < 1) { d *= 10; exp--; } return sign ? -d : d; }
static FXString denormalize (int norm, int pow_exp, int& dot_pos) { int nsign = (norm < 0 ? -1 : 1); int p = ipow10 (pow_exp); if (norm < 0) norm = -norm; int int_part = norm / p, frac_part = norm % p; char buf[64]; sprintf (buf, "%s%d", nsign < 0 ? "-" : "", int_part); dot_pos = strlen (buf); if (pow_exp == 0) return FXString(buf); return FXStringFormat("%s.%.*d", buf, pow_exp, frac_part); }