|
3 | 3 | #include <float.h>
|
4 | 4 |
|
5 | 5 | #include "xmlrpc-c/util.h"
|
| 6 | +#include "xmlrpc-c/util_int.h" |
6 | 7 |
|
7 | 8 | #include "double.h"
|
8 | 9 |
|
@@ -58,6 +59,23 @@ digitChar(unsigned int const digitValue) {
|
58 | 59 |
|
59 | 60 |
|
60 | 61 |
|
| 62 | +static unsigned int |
| 63 | +leadDigit(double const arg, |
| 64 | + double const precision) { |
| 65 | +/*---------------------------------------------------------------------------- |
| 66 | + Assuming 'arg' has one digit before the decimal point (which may be zero), |
| 67 | + return that digit. |
| 68 | +
|
| 69 | + We assume the precision of 'arg' is plus or minus 'precision', and bias our |
| 70 | + estimation of the first digit up. We do that bias in order to bias toward |
| 71 | + shorter decimal ciphers: It's cleaner to consider 2.9999999 to be 3 than to |
| 72 | + consider 3 to be 2.999999. |
| 73 | +-----------------------------------------------------------------------------*/ |
| 74 | + return MIN(9, (unsigned int)(arg + precision)); |
| 75 | +} |
| 76 | + |
| 77 | + |
| 78 | + |
61 | 79 | static void
|
62 | 80 | floatWhole(double const value,
|
63 | 81 | buffer * const formattedP,
|
@@ -88,7 +106,8 @@ floatWhole(double const value,
|
88 | 106 | */
|
89 | 107 | leastValue = 0;
|
90 | 108 | } else
|
91 |
| - leastValue = (unsigned int)(value - nonLeastAmount * 10); |
| 109 | + leastValue = leadDigit(value - nonLeastAmount * 10, |
| 110 | + nonLeastPrecision * 10); |
92 | 111 |
|
93 | 112 | bufferConcat(formattedP, digitChar(leastValue));
|
94 | 113 |
|
@@ -120,7 +139,7 @@ floatFractionPart(double const value,
|
120 | 139 | unsigned int digitValue;
|
121 | 140 |
|
122 | 141 | d *= 10;
|
123 |
| - digitValue = (unsigned int) d; |
| 142 | + digitValue = leadDigit(d, precision); |
124 | 143 |
|
125 | 144 | d -= digitValue;
|
126 | 145 |
|
@@ -154,7 +173,7 @@ floatFraction(double const value,
|
154 | 173 | precision = DBL_EPSILON;
|
155 | 174 |
|
156 | 175 | while (d > precision) {
|
157 |
| - unsigned int const digitValue = (unsigned int) d; |
| 176 | + unsigned int const digitValue = leadDigit(d, precision); |
158 | 177 |
|
159 | 178 | bufferConcat(formattedP, digitChar(digitValue));
|
160 | 179 |
|
|
0 commit comments