fixed GH #1128: Poco::NumberFormatter::format(float, precision) rounding changed

This commit is contained in:
Guenter Obiltschnig
2016-02-28 13:32:54 +01:00
parent 2c6a74c4f5
commit 4e85aa4df2
6 changed files with 178 additions and 24 deletions

View File

@@ -208,6 +208,15 @@ public:
/// Formats a float value in decimal floating-point notation,
/// according to std::printf's %g format with a precision of 8 fractional digits.
static std::string format(float value, int precision);
/// Formats a double value in decimal floating-point notation,
/// according to std::printf's %f format with the given precision.
static std::string format(float value, int width, int precision);
/// Formats a double value in decimal floating-point notation,
/// right justified in a field of the specified width,
/// with the number of fractional digits given in precision.
static std::string format(double value);
/// Formats a double value in decimal floating-point notation,
/// according to std::printf's %g format with a precision of 16 fractional digits.
@@ -368,6 +377,15 @@ public:
/// Formats a float value in decimal floating-point notation,
/// according to std::printf's %g format with a precision of 8 fractional digits.
static void append(std::string& str, float value, int precision);
/// Formats a double value in decimal floating-point notation,
/// according to std::printf's %f format with the given precision.
static void append(std::string& str, float value, int width, int precision);
/// Formats a double value in decimal floating-point notation,
/// right justified in a field of the specified width,
/// with the number of fractional digits given in precision.
static void append(std::string& str, double value);
/// Formats a double value in decimal floating-point notation,
/// according to std::printf's %g format with a precision of 16 fractional digits.
@@ -641,33 +659,49 @@ inline std::string NumberFormatter::formatHex(UInt64 value, int width, bool pref
inline std::string NumberFormatter::format(float value)
{
char buffer[POCO_MAX_FLT_STRING_LEN];
floatToStr(buffer, POCO_MAX_FLT_STRING_LEN, value);
return std::string(buffer);
}
inline std::string NumberFormatter::format(float value, int precision)
{
char buffer[POCO_MAX_FLT_STRING_LEN];
floatToFixedStr(buffer, POCO_MAX_FLT_STRING_LEN, value, precision);
return std::string(buffer);
}
inline std::string NumberFormatter::format(float value, int width, int precision)
{
std::string result;
floatToStr(result, value);
floatToFixedStr(result, value, precision, width);
return result;
}
inline std::string NumberFormatter::format(double value)
{
std::string result;
doubleToStr(result, value);
return result;
char buffer[POCO_MAX_FLT_STRING_LEN];
doubleToStr(buffer, POCO_MAX_FLT_STRING_LEN, value);
return std::string(buffer);
}
inline std::string NumberFormatter::format(double value, int precision)
{
std::string result;
doubleToStr(result, value, precision);
return result;
char buffer[POCO_MAX_FLT_STRING_LEN];
doubleToFixedStr(buffer, POCO_MAX_FLT_STRING_LEN, value, precision);
return std::string(buffer);
}
inline std::string NumberFormatter::format(double value, int width, int precision)
{
std::string result;
doubleToStr(result, value, precision, width);
doubleToFixedStr(result, value, precision, width);
return result;
}

View File

@@ -35,6 +35,7 @@
#include <locale>
#endif
// binary numbers are supported, thus 64 (bits) + 1 (string terminating zero)
#define POCO_MAX_INT_STRING_LEN 65
// value from strtod.cc (double_conversion::kMaxSignificantDecimalDigits)
@@ -441,16 +442,25 @@ bool uIntToStr (T number, unsigned short base, std::string& result, bool prefix
// http://florian.loitsch.com/publications/dtoa-pldi2010.pdf
//
Foundation_API void floatToStr(char* buffer,
int bufferSize,
float value,
int lowDec = -std::numeric_limits<double>::digits10,
int highDec = std::numeric_limits<double>::digits10);
int lowDec = -std::numeric_limits<float>::digits10,
int highDec = std::numeric_limits<float>::digits10);
/// Converts a float value to string. Converted string must be shorter than bufferSize.
/// Conversion is done by computing the shortest string of digits that correctly represents
/// the input number. Depending on lowDec and highDec values, the function returns
/// decimal or exponential representation.
Foundation_API void floatToFixedStr(char* buffer,
int bufferSize,
float value,
int precision);
/// Converts a float value to string. Converted string must be shorter than bufferSize.
/// Computes a decimal representation with a fixed number of digits after the
/// decimal point.
Foundation_API std::string& floatToStr(std::string& str,
float value,
@@ -464,6 +474,17 @@ Foundation_API std::string& floatToStr(std::string& str,
/// and width (total length of formatted string).
Foundation_API std::string& floatToFixedStr(std::string& str,
float value,
int precision,
int width = 0,
char thSep = 0,
char decSep = 0);
/// Converts a float value, assigns it to the supplied string and returns the reference.
/// This function calls floatToFixedStr(char*, int, float, int) and formats the result according to
/// precision (total number of digits after the decimal point) and width (total length of formatted string).
Foundation_API void doubleToStr(char* buffer,
int bufferSize,
double value,
@@ -475,6 +496,15 @@ Foundation_API void doubleToStr(char* buffer,
/// decimal or exponential representation.
Foundation_API void doubleToFixedStr(char* buffer,
int bufferSize,
double value,
int precision);
/// Converts a double value to string. Converted string must be shorter than bufferSize.
/// Computes a decimal representation with a fixed number of digits after the
/// decimal point.
Foundation_API std::string& doubleToStr(std::string& str,
double value,
int precision = -1,
@@ -482,11 +512,22 @@ Foundation_API std::string& doubleToStr(std::string& str,
char thSep = 0,
char decSep = 0);
/// Converts a double value, assigns it to the supplied string and returns the reference.
/// This function calls doubleToStr(char*, int, float, int, int) and formats the result according to
/// This function calls doubleToStr(char*, int, double, int, int) and formats the result according to
/// precision (total number of digits after the decimal point, -1 means ignore precision argument)
/// and width (total length of formatted string).
Foundation_API std::string& doubleToFixedStr(std::string& str,
double value,
int precision = -1,
int width = 0,
char thSep = 0,
char decSep = 0);
/// Converts a double value, assigns it to the supplied string and returns the reference.
/// This function calls doubleToFixedStr(char*, int, double, int) and formats the result according to
/// precision (total number of digits after the decimal point) and width (total length of formatted string).
Foundation_API float strToFloat(const char* str);
/// Converts the string of characters into single-precision floating point number.
/// Function uses double_convesrion::DoubleToStringConverter to do the conversion.
@@ -513,10 +554,6 @@ Foundation_API bool strToDouble(const std::string& str, double& result, char dec
///
/// Returns true if successful, false otherwise.
//
// end double-conversion functions declarations
//
} // namespace Poco