@@ -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