Skip to content
Permalink
Browse files

prf.c: fix wrong results with %g conversion

The precision parameter to the %g conversion indicates the maximum
number of significant digits and not the number of digits to appear
after the radix character. Here's a few examples this patch fixes:

                                expected        before
----------------------------------------------------------
printf("%.3g", 150.12)          150             150.12
printf("%.2g", 150.1)           1.5e+02         150.1
printf("%#.3g", 150.)           150.            150.000
printf("%#.2g", 15e-5)          0.00015         0.00
printf("%#.4g", 1505e-7)        0.0001505       0.0002
printf("%#.4g", 1505e-8)        1.505e-05       1.5050e-05

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
  • Loading branch information...
Nicolas Pitre authored and nashif committed Jun 19, 2019
1 parent 132a286 commit 90ec5360beb237c47b31149c8f7652997f7782e2
Showing with 39 additions and 5 deletions.
  1. +8 −4 lib/libc/minimal/source/stdout/prf.c
  2. +31 −1 tests/lib/sprintf/src/main.c
@@ -313,13 +313,17 @@ static int _to_float(char *buf, uint64_t double_temp, char c,

prune_zero = false; /* Assume trailing 0's allowed */
if ((c == 'g') || (c == 'G')) {
if (!falt && (precision > 0)) {
prune_zero = true;
}
if ((decexp < (-4 + 1)) || (decexp > (precision + 1))) {
if (decexp < (-4 + 1) || decexp > precision) {
c += 'e' - 'g';
if (precision > 0) {
precision--;
}
} else {
c = 'f';
precision -= decexp;
}
if (!falt && (precision > 0)) {
prune_zero = true;
}
}

@@ -61,7 +61,7 @@ union raw_double_u {

void test_sprintf_double(void)
{
char buffer[100];
char buffer[400];
union raw_double_u var;

#ifndef CONFIG_FLOAT
@@ -284,6 +284,36 @@ void test_sprintf_double(void)
zassert_true((strcmp(buffer, "1.234E+09") == 0),
"sprintf(1.234E+09) - incorrect "
"output '%s'\n", buffer);

var.d = 150.0;
sprintf(buffer, "%#.3g", var.d);
zassert_true((strcmp(buffer, "150.") == 0),
"sprintf(150.) - incorrect "
"output '%s'\n", buffer);

var.d = 150.1;
sprintf(buffer, "%.2g", var.d);
zassert_true((strcmp(buffer, "1.5e+02") == 0),
"sprintf(1.5e+02) - incorrect "
"output '%s'\n", buffer);

var.d = 150.567;
sprintf(buffer, "%.3g", var.d);
zassert_true((strcmp(buffer, "151") == 0),
"sprintf(151) - incorrect "
"output '%s'\n", buffer);

var.d = 15e-5;
sprintf(buffer, "%#.3g", var.d);
zassert_true((strcmp(buffer, "0.000150") == 0),
"sprintf(0.000150) - incorrect "
"output '%s'\n", buffer);

var.d = 1505e-7;
sprintf(buffer, "%.4g", var.d);
zassert_true((strcmp(buffer, "0.0001505") == 0),
"sprintf(0.0001505) - incorrect "
"output '%s'\n", buffer);
}

/**

0 comments on commit 90ec536

Please sign in to comment.
You can’t perform that action at this time.