diff --git a/README.md b/README.md index 2f3242bd..ff0dff66 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,7 @@ int length = sprintf(NULL, "Hello, world"); // length is set to 12 | PRINTF_NTOA_BUFFER_SIZE | 32 | ntoa (integer) conversion buffer size. This must be big enough to hold one converted numeric number _including_ leading zeros, normally 32 is a sufficient value. Created on the stack | | PRINTF_FTOA_BUFFER_SIZE | 32 | ftoa (float) conversion buffer size. This must be big enough to hold one converted float number _including_ leading zeros, normally 32 is a sufficient value. Created on the stack | | PRINTF_DEFAULT_FLOAT_PRECISION | 6 | Define the default floating point precision | -| PRINTF_MAX_FLOAT | 1e9 | Define the largest suitable value to be printed with %f, before using exponential representation | +| PRINTF_MAX_FLOAT | 1e9 | Define the largest suitable value to be printed with %f, before using exponential representation. Note that this must be set to a value which fits in a 64-bit signed integer (i.e. less than 2^63) | | PRINTF_DISABLE_SUPPORT_FLOAT | undefined | Define this to disable floating point (%f) support | | PRINTF_DISABLE_SUPPORT_EXPONENTIAL | undefined | Define this to disable exponential floating point (%e) support | | PRINTF_DISABLE_SUPPORT_LONG_LONG | undefined | Define this to disable long long (%ll) support | diff --git a/printf.c b/printf.c index 0e9494e8..b77a1df5 100644 --- a/printf.c +++ b/printf.c @@ -382,7 +382,7 @@ static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d prec--; } - int whole = (int)value; + int_fast64_t whole = (int_fast64_t)value; double tmp = (value - whole) * pow10[prec]; unsigned long frac = (unsigned long)tmp; diff = tmp - (double)frac; diff --git a/test/test_suite.cpp b/test/test_suite.cpp index bffc3891..ca4d02bc 100644 --- a/test/test_suite.cpp +++ b/test/test_suite.cpp @@ -1225,6 +1225,48 @@ TEST_CASE("float", "[]" ) { test::sprintf(buffer, "%.3f", 30343.1415354); REQUIRE(!strcmp(buffer, "30343.142")); + // switch from decimal to exponential representation + // + test::sprintf(buffer, "%.0f", (double) ((int64_t)1 * 1000 ) ); + if (PRINTF_MAX_FLOAT < 10e+2) { + REQUIRE(!strcmp(buffer, "10e+2")); + } + else { + REQUIRE(!strcmp(buffer, "1000")); + } + + test::sprintf(buffer, "%.0f", (double) ((int64_t)1 * 1000 * 1000 ) ); + if (PRINTF_MAX_FLOAT < 10e+5) { + REQUIRE(!strcmp(buffer, "10e+5")); + } + else { + REQUIRE(!strcmp(buffer, "1000000")); + } + + test::sprintf(buffer, "%.0f", (double) ((int64_t)1 * 1000 * 1000 * 1000 ) ); + if (PRINTF_MAX_FLOAT < 10e+8) { + REQUIRE(!strcmp(buffer, "10e+8")); + } + else { + REQUIRE(!strcmp(buffer, "1000000000")); + } + + test::sprintf(buffer, "%.0f", (double) ((int64_t)1 * 1000 * 1000 * 1000 * 1000) ); + if (PRINTF_MAX_FLOAT < 10e+11) { + REQUIRE(!strcmp(buffer, "10e+11")); + } + else { + REQUIRE(!strcmp(buffer, "1000000000000")); + } + + test::sprintf(buffer, "%.0f", (double) ((int64_t)1 * 1000 * 1000 * 1000 * 1000 * 1000) ); + if (PRINTF_MAX_FLOAT < 10e+14) { + REQUIRE(!strcmp(buffer, "10e+14")); + } + else { + REQUIRE(!strcmp(buffer, "1000000000000000")); + } + test::sprintf(buffer, "%.0f", 34.1415354); REQUIRE(!strcmp(buffer, "34"));