Fixed amb1163: float printing broke on large values.
This commit is contained in:
parent
01f3d729de
commit
36db059672
|
@ -160,71 +160,125 @@ void AddString(U **buf_p, size_t &maxlen, const cell *string, int width, int pre
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
void AddFloat(U **buf_p, size_t &maxlen, double fval, int width, int prec)
|
void AddFloat(U **buf_p, size_t &maxlen, double fval, int width, int prec, int flags)
|
||||||
{
|
{
|
||||||
U text[32];
|
int digits; // non-fraction part digits
|
||||||
int digits;
|
double tmp; // temporary
|
||||||
double signedVal;
|
U *buf = *buf_p; // output buffer pointer
|
||||||
U *buf;
|
int val; // temporary
|
||||||
int val;
|
int sign = 0; // 0: positive, 1: negative
|
||||||
|
int fieldlength; // for padding
|
||||||
|
int significant_digits = 0; // number of significant digits written
|
||||||
|
const int MAX_SIGNIFICANT_DIGITS = 16;
|
||||||
|
|
||||||
|
// default precision
|
||||||
|
if (prec < 0)
|
||||||
|
{
|
||||||
|
prec = 6;
|
||||||
|
}
|
||||||
|
|
||||||
// get the sign
|
// get the sign
|
||||||
signedVal = fval;
|
|
||||||
if (fval < 0)
|
if (fval < 0)
|
||||||
fval = -fval;
|
|
||||||
|
|
||||||
// write the float number
|
|
||||||
digits = 0;
|
|
||||||
val = (int)fval;
|
|
||||||
do {
|
|
||||||
text[digits++] = '0' + val % 10;
|
|
||||||
val /= 10;
|
|
||||||
} while (val);
|
|
||||||
|
|
||||||
if (signedVal < 0)
|
|
||||||
text[digits++] = '-';
|
|
||||||
|
|
||||||
buf = *buf_p;
|
|
||||||
|
|
||||||
while (digits < width && maxlen)
|
|
||||||
{
|
{
|
||||||
|
fval = -fval;
|
||||||
|
sign = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute whole-part digits count
|
||||||
|
digits = (int)log10(fval) + 1;
|
||||||
|
|
||||||
|
// Only print 0.something if 0 < fval < 1
|
||||||
|
if (digits < 1)
|
||||||
|
{
|
||||||
|
digits = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the field length
|
||||||
|
fieldlength = digits + prec + ((prec > 0) ? 1 : 0) + sign;
|
||||||
|
|
||||||
|
// minus sign BEFORE left padding if padding with zeros
|
||||||
|
if (sign && maxlen && (flags & ZEROPAD))
|
||||||
|
{
|
||||||
|
*buf++ = '-';
|
||||||
|
maxlen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// right justify if required
|
||||||
|
if ((flags & LADJUST) == 0)
|
||||||
|
{
|
||||||
|
while ((fieldlength < width) && maxlen)
|
||||||
|
{
|
||||||
|
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
|
||||||
|
width--;
|
||||||
|
maxlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// minus sign AFTER left padding if padding with spaces
|
||||||
|
if (sign && maxlen && !(flags & ZEROPAD))
|
||||||
|
{
|
||||||
|
*buf++ = '-';
|
||||||
|
maxlen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the whole part
|
||||||
|
tmp = pow(10.0, digits-1);
|
||||||
|
while ((digits--) && maxlen)
|
||||||
|
{
|
||||||
|
if (++significant_digits > MAX_SIGNIFICANT_DIGITS)
|
||||||
|
{
|
||||||
|
*buf++ = '0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val = (int)(fval / tmp);
|
||||||
|
*buf++ = '0' + val;
|
||||||
|
fval -= val * tmp;
|
||||||
|
tmp *= 0.1;
|
||||||
|
}
|
||||||
|
maxlen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the fraction part
|
||||||
|
if (maxlen)
|
||||||
|
{
|
||||||
|
*buf++ = '.';
|
||||||
|
maxlen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = pow(10.0, prec);
|
||||||
|
|
||||||
|
fval *= tmp;
|
||||||
|
while (prec-- && maxlen)
|
||||||
|
{
|
||||||
|
if (++significant_digits > MAX_SIGNIFICANT_DIGITS)
|
||||||
|
{
|
||||||
|
*buf++ = '0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tmp *= 0.1;
|
||||||
|
val = (int)(fval / tmp);
|
||||||
|
*buf++ = '0' + val;
|
||||||
|
fval -= val * tmp;
|
||||||
|
}
|
||||||
|
maxlen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// left justify if required
|
||||||
|
if (flags & LADJUST)
|
||||||
|
{
|
||||||
|
while ((fieldlength < width) && maxlen)
|
||||||
|
{
|
||||||
|
// right-padding only with spaces, ZEROPAD is ignored
|
||||||
*buf++ = ' ';
|
*buf++ = ' ';
|
||||||
width--;
|
width--;
|
||||||
maxlen--;
|
maxlen--;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (digits-- && maxlen)
|
|
||||||
{
|
|
||||||
*buf++ = text[digits];
|
|
||||||
maxlen--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update parent's buffer pointer
|
||||||
*buf_p = buf;
|
*buf_p = buf;
|
||||||
|
|
||||||
if (prec < 0)
|
|
||||||
prec = 6;
|
|
||||||
// write the fraction
|
|
||||||
digits = 0;
|
|
||||||
while (digits < prec)
|
|
||||||
{
|
|
||||||
fval -= (int) fval;
|
|
||||||
fval *= 10.0;
|
|
||||||
val = (int) fval;
|
|
||||||
text[digits++] = '0' + val % 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (digits > 0 && maxlen)
|
|
||||||
{
|
|
||||||
buf = *buf_p;
|
|
||||||
*buf++ = '.';
|
|
||||||
maxlen--;
|
|
||||||
for (prec = 0; maxlen && prec < digits; prec++)
|
|
||||||
{
|
|
||||||
*buf++ = text[prec];
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
*buf_p = buf;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
|
@ -481,7 +535,7 @@ reswitch:
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
CHECK_ARGS(0);
|
CHECK_ARGS(0);
|
||||||
AddFloat(&buf_p, llen, amx_ctof(*get_amxaddr(amx, params[arg])), width, prec);
|
AddFloat(&buf_p, llen, amx_ctof(*get_amxaddr(amx, params[arg])), width, prec, flags);
|
||||||
arg++;
|
arg++;
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
|
|
Loading…
Reference in New Issue
Block a user