aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartijn Jasperse <m.jasperse@gmail.com>2019-02-01 14:07:26 +1100
committerMartijn Jasperse <m.jasperse@gmail.com>2019-02-01 14:07:26 +1100
commit56d9df0bd3ff3161c86b387c36823a62472980e2 (patch)
tree714351d2fe1e71631acf2c554253cee0a4e8d881
parent2019bc0192a1b69036b0659f642a9e7e6c426a32 (diff)
downloadprintf-56d9df0bd3ff3161c86b387c36823a62472980e2.tar.gz
printf-56d9df0bd3ff3161c86b387c36823a62472980e2.tar.bz2
printf-56d9df0bd3ff3161c86b387c36823a62472980e2.zip
Added special-case handling to %E, added +inf and -inf handling, test cases
-rw-r--r--printf.c17
-rw-r--r--test/test_suite.cpp12
2 files changed, 23 insertions, 6 deletions
diff --git a/printf.c b/printf.c
index 0ee5c3e..62cc52c 100644
--- a/printf.c
+++ b/printf.c
@@ -316,6 +316,7 @@ static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t
#if defined(PRINTF_SUPPORT_FLOAT)
+#include <math.h>
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT
static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags);
@@ -330,10 +331,13 @@ static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d
// powers of 10
static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
- // test for NaN
- if (value != value) {
- return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); // ensure value is padded as required
- }
+ // test for special values
+ if (value != value)
+ return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags);
+ if (value < -DBL_MAX)
+ return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags);
+ if (value > DBL_MAX)
+ return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4 : 3, width, flags);
// test for very large values
// standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
@@ -448,9 +452,12 @@ static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d
}
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
-#include <math.h>
static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
{
+ // check for special values
+ if ((value != value)||(value > DBL_MAX)||(value < -DBL_MAX))
+ return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags);
+
// determine the sign
bool negative = value < 0;
if (negative) value = -value;
diff --git a/test/test_suite.cpp b/test/test_suite.cpp
index 875fa82..27efa4e 100644
--- a/test/test_suite.cpp
+++ b/test/test_suite.cpp
@@ -1045,9 +1045,19 @@ TEST_CASE("length", "[]" ) {
TEST_CASE("float", "[]" ) {
char buffer[100];
- test::sprintf(buffer, "%8f", NAN); // using the NAN macro of math.h
+ // test special-case floats using math.h macros
+ test::sprintf(buffer, "%8f", NAN);
REQUIRE(!strcmp(buffer, " nan"));
+ test::sprintf(buffer, "%8f", INFINITY);
+ REQUIRE(!strcmp(buffer, " inf"));
+
+ test::sprintf(buffer, "%-8f", -INFINITY);
+ REQUIRE(!strcmp(buffer, "-inf "));
+
+ test::sprintf(buffer, "%+8e", INFINITY);
+ REQUIRE(!strcmp(buffer, " +inf"));
+
test::sprintf(buffer, "%.4f", 3.1415354);
REQUIRE(!strcmp(buffer, "3.1415"));