Skip to content

Commit 048800b

Browse files
SidLeungcalvinatintel
authored andcommitted
Jira-599. Routine, dtostrf, did not work with the latest toolchain. The call to sprintf in the routine crashed the system. Issue corrected by replacing the call. The routine, printfloat, in Print.cpp, is now usint dtostrf to print out double and float values.
1 parent 874c3ef commit 048800b

File tree

3 files changed

+63
-102
lines changed

3 files changed

+63
-102
lines changed

cores/arduino/Print.cpp

Lines changed: 3 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -288,62 +288,8 @@ size_t Print::printLongLong(unsigned long long n, uint8_t base) {
288288

289289
size_t Print::printFloat(double number, uint8_t digits)
290290
{
291-
size_t n = 0;
292-
int exponent = 0;
293-
double tmp;
294-
295-
if (isnan(number)) return print("nan");
296-
if (isinf(number)) return print("inf");
297-
298-
// Handle negative numbers
299-
if (number < 0.0) {
300-
n += print('-');
301-
number = -number;
302-
}
303-
304-
// Chk if integer part has more than 8 digits.
305-
tmp = number;
306-
while (true) {
307-
tmp /= 10.0;
308-
exponent++;
309-
if (tmp < 10.0) break;
310-
}
311-
if (exponent > 8)
312-
number = tmp;
313-
else
314-
exponent = 0;
315-
316-
// Round correctly so that print(1.999, 2) prints as "2.00"
317-
double rounding = 0.5;
318-
for (uint8_t i=0; i<digits; ++i)
319-
rounding /= 10.0;
320-
321-
number += rounding;
322-
323-
// Extract the integer part of the number and print it
324-
unsigned long int_part = (unsigned long)number;
325-
double remainder = number - (double)int_part;
326-
n += print(int_part);
327-
328-
// Print the decimal point, but only if there are digits beyond
329-
if (digits > 0) {
330-
n += print(".");
331-
}
332-
333-
// Extract digits from the remainder one at a time
334-
while (digits-- > 0)
335-
{
336-
remainder *= 10.0;
337-
int toPrint = int(remainder);
338-
n += print(toPrint);
339-
remainder -= toPrint;
340-
}
291+
char str[50];
341292

342-
// Print the exponent portion
343-
if (exponent) {
344-
n += print("e+");
345-
n += print(exponent);
346-
}
347-
348-
return n;
293+
dtostrf(number, 0, digits, str);
294+
return(print(str));
349295
}

cores/arduino/stdlib_noniso.cpp

Lines changed: 59 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,22 @@ char* ultoa( unsigned long val, char *string, int radix )
147147
return string;
148148
}
149149

150-
char * dtostrf(double number, unsigned char width, unsigned char prec, char *s) {
150+
void shiftOutDigit(double *number, int count, char *s)
151+
{
152+
double tmp = *number;
153+
int digit;
154+
155+
while( count ) {
156+
tmp *= 10.0;
157+
digit = (int)tmp;
158+
*s++ = '0' + digit;
159+
tmp -= (double)digit;
160+
count--;
161+
}
162+
*number = tmp;
163+
}
164+
165+
char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
151166

152167
if (isnan(number)) {
153168
strcpy(s, "nan");
@@ -158,62 +173,62 @@ char * dtostrf(double number, unsigned char width, unsigned char prec, char *s)
158173
return s;
159174
}
160175

161-
char* out = s;
162-
int exponent = 0;
163-
unsigned char len, expLen;
164-
double tmp;
176+
char *out = s;
177+
int expCnt = 0, digit, totalWidth;
178+
double tmp, rounding;
179+
180+
// Check for left adjustment (spaces)
181+
while(width < 0) {
182+
*out++ = ' ';
183+
width++;
184+
}
185+
totalWidth = (int)width;
165186

166187
// Handle negative numbers
167188
if (number < 0.0) {
168189
*out++ = '-';
169190
number = -number;
191+
if(totalWidth > 0) totalWidth--;
170192
}
171193

172-
// The integer portion has to be <= 8 digits. Otherwise, the
173-
// string is in exponent format.
194+
// Rounding up to the precision
174195
tmp = number;
175-
for (;;) {
196+
rounding = 0.5;
197+
for(int i=0; i < prec; i++)
198+
rounding /= 10.0;
199+
tmp += rounding;
200+
201+
// Shifting the number to the right
202+
while( tmp >= 10.0 ) {
176203
tmp /= 10.0;
177-
exponent++;
178-
if (tmp < 10.0) break;
204+
expCnt++;
179205
}
180-
if (exponent > 8)
181-
number = tmp;
182-
else
183-
exponent = 0;
184-
185-
// Round correctly so that print(1.999, 2) prints as "2.00"
186-
double rounding = 0.5;
187-
for (uint8_t i = 0; i < prec; ++i)
188-
rounding /= 10.0;
189-
190-
number += rounding;
191206

192-
// Extract the integer part of the number and print it
193-
unsigned long int_part = (unsigned long)number;
194-
double remainder = number - (double)int_part;
195-
out += sprintf(out, "%ld", int_part);
196-
197-
// Don't go beyond the given width of the string
198-
len = (unsigned char)(out - s);
199-
expLen = (exponent == 0) ? 0 : 5; // 5 places for exponent expression
200-
if ((prec + len + expLen) > width)
201-
prec = width - len - expLen;
202-
203-
// Print the decimal point, but only if there are digits beyond
204-
if (prec > 0) {
205-
*out++ = '.';
206-
// Copy character by character to 'out' string
207-
for (unsigned char decShift = prec; decShift > 0; decShift--) {
208-
remainder *= 10.0;
209-
out += sprintf(out, "%d", (int)remainder);
210-
remainder -= (double)(int)remainder;
211-
}
207+
// 1st, print the single digit left after shifting
208+
digit = (int)tmp;
209+
*out++ = '0' + digit;
210+
tmp -= (double)digit;
211+
if(totalWidth > 0) totalWidth--;
212+
213+
// Then the integer portion
214+
shiftOutDigit(&tmp, expCnt, out);
215+
out += expCnt;
216+
if(totalWidth > 0) totalWidth -= expCnt;
217+
218+
// Then the decimal portion
219+
if( prec ) {
220+
*out++ = '.';
221+
shiftOutDigit(&tmp, prec, out);
222+
if(totalWidth > 0) totalWidth -= (prec + 1);
223+
out += prec;
212224
}
213225

214-
// Print the exponent if exists
215-
if (exponent)
216-
sprintf(out, "e+%.3d", exponent);
226+
// Right adjustment
227+
while(totalWidth > 0) {
228+
*out++ = ' ';
229+
totalWidth--;
230+
}
217231

232+
*out = 0; // End of string
218233
return s;
219234
}

cores/arduino/stdlib_noniso.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ char* utoa (unsigned int val, char *s, int radix);
3737

3838
char* ultoa (unsigned long val, char *s, int radix);
3939

40-
char* dtostrf (double val, unsigned char width, unsigned char prec, char *s);
40+
char* dtostrf (double val, signed char width, unsigned char prec, char *s);
4141

4242
#ifdef __cplusplus
4343
} // extern "C"

0 commit comments

Comments
 (0)