@@ -148,7 +148,8 @@ char* ultoa(unsigned long value, char* result, int base) {
148
148
}
149
149
150
150
char * dtostrf (double number , signed char width , unsigned char prec , char * s ) {
151
-
151
+ bool negative = false;
152
+
152
153
if (isnan (number )) {
153
154
strcpy (s , "nan" );
154
155
return s ;
@@ -158,54 +159,65 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
158
159
return s ;
159
160
}
160
161
161
- if (number > 4294967040.0 || number < -4294967040.0 ) {
162
- strcpy (s , "ovf" );
163
- return s ;
164
- }
165
162
char * out = s ;
163
+
164
+ int fillme = width ; // how many cells to fill for the integer part
165
+ if (prec > 0 ) {
166
+ fillme -= (prec + 1 );
167
+ }
168
+
166
169
// Handle negative numbers
167
170
if (number < 0.0 ) {
168
- * out ++ = '-' ;
171
+ negative = true;
172
+ fillme -- ;
169
173
number = - number ;
170
174
}
171
175
172
176
// Round correctly so that print(1.999, 2) prints as "2.00"
173
177
// I optimized out most of the divisions
174
178
double rounding = 2.0 ;
175
179
for (uint8_t i = 0 ; i < prec ; ++ i )
176
- rounding *= 10.0 ;
177
- rounding = 1.0 / rounding ;
180
+ rounding *= 10.0 ;
181
+ rounding = 1.0 / rounding ;
178
182
179
183
number += rounding ;
180
-
181
- // Extract the integer part of the number and print it
182
- unsigned long int_part = (unsigned long )number ;
183
- double remainder = number - (double )int_part ;
184
- out += sprintf (out , "%d" , int_part );
185
-
186
- // Print the decimal point, but only if there are digits beyond
187
- if (prec > 0 ) {
188
- * out ++ = '.' ;
184
+
185
+ // Figure out how big our number really is
186
+ double tenpow = 1.0 ;
187
+ int digitcount = 1 ;
188
+ while (number >= 10.0 * tenpow ) {
189
+ tenpow *= 10.0 ;
190
+ digitcount ++ ;
189
191
}
190
- // make sure the string is terminated before mesuring it length
191
- * out = 0 ;
192
- // Reduce minimum width accordingly
193
- width -= strlen (s );
194
-
195
- // Print the digits after the decimal point
192
+
193
+ number /= tenpow ;
194
+ fillme -= digitcount ;
195
+
196
+ // Pad unused cells with spaces
197
+ while (fillme -- > 0 ) {
198
+ * out ++ = ' ' ;
199
+ }
200
+
201
+ // Handle negative sign
202
+ if (negative ) * out ++ = '-' ;
203
+
204
+ // Print the digits, and if necessary, the decimal point
205
+ digitcount += prec ;
196
206
int8_t digit = 0 ;
197
- while (prec -- > 0 ) {
198
- remainder *= 10.0 ;
199
- digit = (int8_t )remainder ;
207
+ while (digitcount -- > 0 ) {
208
+ digit = (int8_t )number ;
200
209
if (digit > 9 ) digit = 9 ; // insurance
201
210
* out ++ = (char )('0' | digit );
202
- width -- ;
203
- remainder -= digit ;
211
+ if ((digitcount == prec ) && (prec > 0 )) {
212
+ * out ++ = '.' ;
213
+ }
214
+ number -= digit ;
215
+ number *= 10.0 ;
204
216
}
205
- // add '0' to fill minimum width requirement
206
- while (width -- > 0 ) * out ++ = ' ' ;
217
+
207
218
// make sure the string is terminated
208
219
* out = 0 ;
209
220
return s ;
210
221
}
211
222
223
+
0 commit comments