diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2006-01-10 02:08:29 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2006-01-10 02:08:29 +0000 |
commit | b8af672ee635422fb4317936e30897a85f3cd535 (patch) | |
tree | e84cac88a28f2ecd4cc175117704a43a2f9af667 | |
parent | 44cfb68e3189707686b8edff8642a37e6e637f9b (diff) |
Nan and Infinity can be negative
Decimal point was missing for some exponential output
Only divide sign by 10 once per loop
Add a missing NUL terminator for one case
If there is no whole number portion, print a leading zero (e.g. 0.1 not .1)
-rw-r--r-- | lib/libc/stdlib/gcvt.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/lib/libc/stdlib/gcvt.c b/lib/libc/stdlib/gcvt.c index 849af60304f..87bd843307b 100644 --- a/lib/libc/stdlib/gcvt.c +++ b/lib/libc/stdlib/gcvt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gcvt.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */ +/* $OpenBSD: gcvt.c,v 1.7 2006/01/10 02:08:28 millert Exp $ */ /* * Copyright (c) 2002, 2003 Todd C. Miller <Todd.Miller@courtesan.com> @@ -40,7 +40,7 @@ gcvt(double value, int ndigit, char *buf) digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL); if (decpt == 9999) { /* Infinity or NaN, assume buffer is at least ndigit long. */ - strlcpy(buf, digits, ndigit + 1); + snprintf(buf, ndigit + 1, "%s%s", sign ? "-" : "", digits); return (buf); } @@ -49,13 +49,16 @@ gcvt(double value, int ndigit, char *buf) *dst++ = '-'; if (decpt < 0 || decpt > ndigit) { - /* exponential format */ + /* exponential format (e.g. 1.2345e+13) */ if (--decpt < 0) { sign = 1; decpt = -decpt; } else sign = 0; - for (src = digits; *src != '\0'; ) + src = digits; + *dst++ = *src++; + *dst++ = '.'; /* XXX - locale-specific */ + while (*src != '\0') *dst++ = *src++; *dst++ = 'e'; if (sign) @@ -69,7 +72,8 @@ gcvt(double value, int ndigit, char *buf) } else { /* XXX - optimize */ for (sign = decpt, i = 0; (sign /= 10) != 0; i++) - sign /= 10; + continue; + dst[i + 1] = '\0'; while (decpt != 0) { dst[i--] = '0' + decpt % 10; decpt /= 10; @@ -84,7 +88,9 @@ gcvt(double value, int ndigit, char *buf) *dst++ = '0'; } if (*src != '\0') { - *dst++ = '.'; /* XXX - locale-specific (LC_NUMERIC) */ + if (src == digits) + *dst++ = '0'; /* zero before decimal point */ + *dst++ = '.'; /* XXX - locale-specific */ for (i = decpt; digits[i] != '\0'; i++) { *dst++ = digits[i]; } |