FreeCalypso > hg > freecalypso-citrine
comparison sprintf/float.c @ 46:38cf7fa65976
sprintf/float.c: rounding corner case bug
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 29 Sep 2017 03:23:01 +0000 |
parents | a2d5d622e19e |
children |
comparison
equal
deleted
inserted
replaced
45:a2d5d622e19e | 46:38cf7fa65976 |
---|---|
41 if (*end == '.') | 41 if (*end == '.') |
42 --end; | 42 --end; |
43 if (++*end <= '9') | 43 if (++*end <= '9') |
44 break; | 44 break; |
45 *end = '0'; | 45 *end = '0'; |
46 if (end == start) { | |
47 *--end = '1'; | |
48 return(1); | |
49 } | |
46 } | 50 } |
47 /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */ | 51 /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */ |
48 else if (sign == '-') | 52 else if (sign == '-') |
49 for (;; --end) { | 53 for (;; --end) { |
50 if (*end == '.') | 54 if (*end == '.') |
51 --end; | 55 --end; |
52 if (*end != '0') | 56 if (*end != '0') |
53 break; | 57 break; |
54 if (end == start) | 58 if (end == start) |
55 return(1); /* clear the -ve */ | 59 return(-1); /* clear the -ve */ |
56 } | 60 } |
57 return(0); | 61 return(0); |
58 } | 62 } |
59 | 63 |
60 u_char * | 64 u_char * |
62 double number, int prec) | 66 double number, int prec) |
63 { | 67 { |
64 char buf[MAX_INT_DIGITS + 1 + MAXFRACT]; | 68 char buf[MAX_INT_DIGITS + 1 + MAXFRACT]; |
65 int extra_prec = 0; | 69 int extra_prec = 0; |
66 int origsign = sign; | 70 int origsign = sign; |
71 int round_stat; | |
67 double fract, tmp; | 72 double fract, tmp; |
68 char *start, *t; | 73 char *start, *t; |
69 | 74 |
70 /* first order of business: weed out infinities and NaNs */ | 75 /* first order of business: weed out infinities and NaNs */ |
71 if (isinf(number)) { | 76 if (isinf(number)) { |
102 if (prec) | 107 if (prec) |
103 do { | 108 do { |
104 fract = modf(fract * 10, &tmp); | 109 fract = modf(fract * 10, &tmp); |
105 *t++ = tochar((int)tmp); | 110 *t++ = tochar((int)tmp); |
106 } while (--prec && fract); | 111 } while (--prec && fract); |
107 if (fract && f_round(fract, start, t - 1, sign)) | 112 if (fract) { |
108 sign = origsign; | 113 round_stat = f_round(fract, start, t - 1, sign); |
114 if (round_stat == 1) | |
115 start--; | |
116 else if (round_stat == -1) | |
117 sign = origsign; | |
118 } | |
109 } | 119 } |
110 return _sprintf_field(op, width, flags, sign, start, t - start, | 120 return _sprintf_field(op, width, flags, sign, start, t - start, |
111 0, prec + extra_prec); | 121 0, prec + extra_prec); |
112 } | 122 } |