Skip to content

Commit 46273aa

Browse files
sytsereitsmaSytse Reitsma
authored andcommitted
Fixed floating point formatting
When dec_precision > 0 round the decimals before printing the int value (and increase/decrease the int value if rounding carries over to the int value). When dec_precision == 0 subtract 1 when a negative number needs to be rounded to a smaller value
1 parent 14175fb commit 46273aa

File tree

1 file changed

+34
-25
lines changed

1 file changed

+34
-25
lines changed

platform/source/minimal-printf/mbed_printf_implementation.c

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -267,20 +267,53 @@ static void mbed_minimal_formatted_string_double(char *buffer, size_t length, in
267267
{
268268
/* get integer part */
269269
MBED_SIGNED_STORAGE integer = value;
270+
/* fractional part represented as the int that will be formatted after the dot, e.g. 95 for 1.95 */
271+
MBED_SIGNED_STORAGE decimal = 0;
270272

271273
if (dec_precision == PRECISION_DEFAULT) {
272274
dec_precision = MBED_CONF_PLATFORM_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS;
273275
}
274276

275277
if (dec_precision != 0) {
278+
/* get decimal part */
279+
MBED_SIGNED_STORAGE precision = 1;
280+
for (int index = 0; index < dec_precision; index++) {
281+
precision *= 10;
282+
}
283+
284+
/* Multiply the frac part so we get an int value with the required accuracy.
285+
E.g. For 0.1234 and dec_precision=3 you'd get 123.4 */
286+
double decimal_double = (value - integer) * precision;
287+
if (value < 0) {
288+
/* The part after the dot does not have a sign, so negate the value before rounding */
289+
decimal = -decimal_double + 0.5;
290+
if (decimal >= precision)
291+
{
292+
/* Rounding carries over to value's integer part (e.g. -1.95 with dec_precision=1 -> -2.0) */
293+
integer--;
294+
decimal = 0;
295+
}
296+
} else {
297+
/* Round the value */
298+
decimal = decimal_double + 0.5;
299+
if (decimal >= precision)
300+
{
301+
/* Rounding carries over to value's integer part (e.g. 1.95 with dec_precision=1 -> 2.0) */
302+
integer++;
303+
decimal = 0;
304+
}
305+
}
306+
276307
width_size -= dec_precision + 1; // decimal precision plus '.'
277308
if (width_size < 0) {
278309
width_size = 0;
279310
}
280311
} else {
281312
value = (value - integer) * 1.0;
282-
if (!((value > -0.5) && (value < 0.5))) {
313+
if (value > 0.5) {
283314
integer++;
315+
} else if (value < -0.5) {
316+
integer--;
284317
}
285318
}
286319

@@ -294,30 +327,6 @@ static void mbed_minimal_formatted_string_double(char *buffer, size_t length, in
294327
if (dec_precision != 0) {
295328
/* write decimal point */
296329
mbed_minimal_putchar(buffer, length, result, '.', stream);
297-
298-
/* get decimal part */
299-
double precision = 1.0;
300-
301-
for (size_t index = 0; index < dec_precision; index++) {
302-
precision *= 10;
303-
}
304-
305-
value = (value - integer) * precision;
306-
307-
/* convert to positive number */
308-
if (value < 0.0) {
309-
value *= -1.0;
310-
}
311-
312-
MBED_UNSIGNED_STORAGE decimal = value;
313-
314-
/* round up or down */
315-
value -= decimal;
316-
317-
if (!((value > -0.5) && (value < 0.5))) {
318-
decimal++;
319-
}
320-
321330
/* write decimal part */
322331
mbed_minimal_formatted_string_integer(buffer, length, result, decimal, INT_UNSIGNED, dec_precision, true, stream);
323332
}

0 commit comments

Comments
 (0)