Skip to content

Commit

Permalink
Fixes #113: Making the number of Taylor series terms we use for `log1…
Browse files Browse the repository at this point in the history
…0()` approximation controllable by a CMake option, and changed the default from 2 to 4 (which is the maximum supported at the moment).
  • Loading branch information
eyalroz committed Feb 11, 2022
1 parent 3a6d95f commit 317c50b
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ set(PRINTF_INTEGER_BUFFER_SIZE "32" CACHE STRING "Integer to string conversi
set(PRINTF_DECIMAL_BUFFER_SIZE "32" CACHE STRING "Floating-point to decimal conversion buffer size")
set(DEFAULT_FLOAT_PRECISION "6" CACHE STRING "Default precision when printing floating-point values")
set(MAX_INTEGRAL_DIGITS_FOR_DECIMAL "9" CACHE STRING "Maximum number of integral-part digits of a floating-point value for which printing with %f uses decimal (non-exponential) notation")
set(LOG10_TAYLOR_TERMS "4" CACHE STRING "The number of terms in a Taylor series expansion of log_10(x) to use for approximation")

# Checks related to the 'j', 'z' and 't' size modifiers

Expand Down
1 change: 1 addition & 0 deletions printf_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define PRINTF_DECIMAL_BUFFER_SIZE @PRINTF_DECIMAL_BUFFER_SIZE@
#define PRINTF_DEFAULT_FLOAT_PRECISION @DEFAULT_FLOAT_PRECISION@
#define PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL @MAX_INTEGRAL_DIGITS_FOR_DECIMAL@
#define PRINTF_LOG10_TAYLOR_TERMS @LOG10_TAYLOR_TERMS@

#endif // PRINTF_CONFIG_H_

26 changes: 22 additions & 4 deletions src/printf/printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,18 @@ extern "C" {
#define PRINTF_SUPPORT_LONG_LONG 1
#endif

// The number of terms in a Taylor series expansion of log_10(x) to
// use for approximation - including the power-zero term (i.e. the
// value at the point of expansion).
#ifndef PRINTF_LOG10_TAYLOR_TERMS
#define PRINTF_LOG10_TAYLOR_TERMS 4
#endif

#if PRINTF_LOG10_TAYLOR_TERMS <= 1
#error "At least one non-constant Taylor expansion is necessary for the log10() calculation"
#endif


#define PRINTF_PREFER_DECIMAL false
#define PRINTF_PREFER_EXPONENTIAL true

Expand Down Expand Up @@ -795,14 +807,20 @@ static double log10_of_positive(double positive_number)
// drop the exponent, so dwba.F comes into the range [1,2)
dwba.U = (dwba.U & (((double_uint_t) (1) << DOUBLE_STORED_MANTISSA_BITS) - 1U)) |
((double_uint_t) DOUBLE_BASE_EXPONENT << DOUBLE_STORED_MANTISSA_BITS);
double z = (dwba.F - 1.5);
return (
// Taylor expansion around 1.5:
0.176091259055681242 // Expansion term 0: log_10(1.5) = ln(1.5)/ln(10)
+ (dwba.F - 1.5) * 0.2895296546021678851 // Expansion term 1: (M - 1.5) * 1/(1.5 ln(10)) = (M/1.5 - 1) / ln(10)
// exact log_2 of the exponent x, with logarithm base change
0.1760912590556812420 // Expansion term 0: ln(1.5) / ln(10)
+ z * 0.2895296546021678851 // Expansion term 1: (M - 1.5) * 2/3 / ln(10)
#if PRINTF_LOG10_TAYLOR_TERMS > 2
- z*z * 0.0965098848673892950 // Expansion term 2: (M - 1.5)^2 * 2/9 / ln(10)
#if PRINTF_LOG10_TAYLOR_TERMS > 3
+ z*z*z * 0.0428932821632841311 // Expansion term 2: (M - 1.5)^3 * 8/81 / ln(10)
#endif
#endif
// exact log_2 of the exponent x, with logarithm base change
+ exp2 * 0.30102999566398119521 // = exp2 * log_10(2) = exp2 * ln(2)/ln(10)
);

}


Expand Down

0 comments on commit 317c50b

Please sign in to comment.