change cell numeric value type from long double to double, closes #201

This commit is contained in:
Thomas Fussell 2017-09-08 21:05:34 -04:00
parent 7d0cf59286
commit 12007fe2d8
20 changed files with 80 additions and 100 deletions

View File

@ -156,11 +156,6 @@ public:
/// </summary>
void value(double float_value);
/// <summary>
/// Sets the value of this cell to the given value.
/// </summary>
void value(long double float_value);
/// <summary>
/// Sets the value of this cell to the given value.
/// </summary>
@ -671,9 +666,6 @@ float cell::value<float>() const;
template<>
double cell::value<double>() const;
template<>
long double cell::value<long double>() const;
template<>
date cell::value<date>() const;

View File

@ -242,7 +242,7 @@ public:
/// Returns number formatted according to this number format's format code
/// with the given base date.
/// </summary>
std::string format(long double number, calendar base_date) const;
std::string format(double number, calendar base_date) const;
/// <summary>
/// Returns true if this format code returns a number formatted as a date.

View File

@ -54,7 +54,7 @@ struct XLNT_API datetime
/// a date and the fractional part into a time according to date::from_number
/// and time::from_number.
/// </summary>
static datetime from_number(long double number, calendar base_date);
static datetime from_number(double number, calendar base_date);
/// <summary>
/// Returns a datetime equivalent to the ISO-formatted string iso_string.
@ -84,7 +84,7 @@ struct XLNT_API datetime
/// <summary>
/// Returns this datetime as a number of seconds since 1900 or 1904 (depending on base_date provided).
/// </summary>
long double to_number(calendar base_date) const;
double to_number(calendar base_date) const;
/// <summary>
/// Returns true if this datetime is equivalent to comparand.

View File

@ -46,7 +46,7 @@ struct XLNT_API time
/// The integer part of number will be ignored.
/// 0.5 would return time(12, 0, 0, 0) or noon, halfway through the day.
/// </summary>
static time from_number(long double number);
static time from_number(double number);
/// <summary>
/// Constructs a time object from an optional hour, minute, second, and microsecond.
@ -62,7 +62,7 @@ struct XLNT_API time
/// Returns a numeric representation of the time in the range 0-1 where the value
/// is equal to the fraction of the day elapsed.
/// </summary>
long double to_number() const;
double to_number() const;
/// <summary>
/// Returns true if this time is equivalent to comparand.

View File

@ -38,7 +38,7 @@ struct XLNT_API timedelta
/// <summary>
/// Returns a timedelta from a number representing the factional number of days elapsed.
/// </summary>
static timedelta from_number(long double number);
static timedelta from_number(double number);
/// <summary>
/// Constructs a timedelta equal to zero.
@ -53,7 +53,7 @@ struct XLNT_API timedelta
/// <summary>
/// Returns a numeric representation of this timedelta as a fractional number of days.
/// </summary>
long double to_number() const;
double to_number() const;
/// <summary>
/// The days

View File

@ -56,17 +56,17 @@
namespace {
std::pair<bool, long double> cast_numeric(const std::string &s)
std::pair<bool, double> cast_numeric(const std::string &s)
{
auto str_end = static_cast<char *>(nullptr);
auto result = std::strtold(s.c_str(), &str_end);
return (str_end != s.c_str() + s.size())
? std::make_pair(false, 0.0L)
? std::make_pair(false, 0.0)
: std::make_pair(true, result);
}
std::pair<bool, long double> cast_percentage(const std::string &s)
std::pair<bool, double> cast_percentage(const std::string &s)
{
if (s.back() == '%')
{
@ -78,7 +78,7 @@ std::pair<bool, long double> cast_percentage(const std::string &s)
}
}
return {false, 0};
return {false, 0.0};
}
std::pair<bool, xlnt::time> cast_time(const std::string &s)
@ -206,48 +206,42 @@ void cell::value(std::nullptr_t)
void cell::value(bool boolean_value)
{
d_->type_ = type::boolean;
d_->value_numeric_ = boolean_value ? 1.0L : 0.0L;
d_->value_numeric_ = boolean_value ? 1.0 : 0.0;
}
void cell::value(int int_value)
{
d_->value_numeric_ = static_cast<long double>(int_value);
d_->value_numeric_ = static_cast<double>(int_value);
d_->type_ = type::number;
}
void cell::value(unsigned int int_value)
{
d_->value_numeric_ = static_cast<long double>(int_value);
d_->value_numeric_ = static_cast<double>(int_value);
d_->type_ = type::number;
}
void cell::value(long long int int_value)
{
d_->value_numeric_ = static_cast<long double>(int_value);
d_->value_numeric_ = static_cast<double>(int_value);
d_->type_ = type::number;
}
void cell::value(unsigned long long int int_value)
{
d_->value_numeric_ = static_cast<long double>(int_value);
d_->value_numeric_ = static_cast<double>(int_value);
d_->type_ = type::number;
}
void cell::value(float float_value)
{
d_->value_numeric_ = static_cast<long double>(float_value);
d_->value_numeric_ = static_cast<double>(float_value);
d_->type_ = type::number;
}
void cell::value(double float_value)
{
d_->value_numeric_ = static_cast<long double>(float_value);
d_->type_ = type::number;
}
void cell::value(long double d)
{
d_->value_numeric_ = d;
d_->value_numeric_ = static_cast<double>(float_value);
d_->type_ = type::number;
}
@ -261,7 +255,7 @@ void cell::value(const rich_text &text)
check_string(text.plain_text());
d_->type_ = type::shared_string;
d_->value_numeric_ = static_cast<long double>(workbook().add_shared_string(text));
d_->value_numeric_ = static_cast<double>(workbook().add_shared_string(text));
}
void cell::value(const char *c)
@ -574,12 +568,6 @@ XLNT_API double cell::value() const
return static_cast<double>(d_->value_numeric_);
}
template <>
XLNT_API long double cell::value() const
{
return d_->value_numeric_;
}
template <>
XLNT_API time cell::value() const
{
@ -672,14 +660,14 @@ std::string cell::to_string() const
return "";
case cell::type::date:
case cell::type::number:
return nf.format(value<long double>(), base_date());
return nf.format(value<double>(), base_date());
case cell::type::inline_string:
case cell::type::shared_string:
case cell::type::formula_string:
case cell::type::error:
return nf.format(value<std::string>());
case cell::type::boolean:
return value<long double>() == 0.L ? "FALSE" : "TRUE";
return value<double>() == 0.0 ? "FALSE" : "TRUE";
}
return "";

View File

@ -51,7 +51,7 @@ struct cell_impl
bool is_merged_;
rich_text value_text_;
long double value_numeric_;
double value_numeric_;
optional<std::string> formula_;
optional<std::string> hyperlink_;

View File

@ -83,7 +83,7 @@ void unhandled_case(bool error)
namespace xlnt {
namespace detail {
bool format_condition::satisfied_by(long double number) const
bool format_condition::satisfied_by(double number) const
{
switch (type)
{
@ -1075,7 +1075,7 @@ number_formatter::number_formatter(const std::string &format_string, xlnt::calen
format_ = parser_.result();
}
std::string number_formatter::format_number(long double number)
std::string number_formatter::format_number(double number)
{
if (format_[0].has_condition)
{
@ -1154,7 +1154,7 @@ std::string number_formatter::format_text(const std::string &text)
return format_text(format_[3], text);
}
std::string number_formatter::fill_placeholders(const format_placeholders &p, long double number)
std::string number_formatter::fill_placeholders(const format_placeholders &p, double number)
{
std::string result;
@ -1230,7 +1230,7 @@ std::string number_formatter::fill_placeholders(const format_placeholders &p, lo
else if (p.type == format_placeholders::placeholders_type::fractional_part)
{
auto fractional_part = number - integer_part;
result = std::fabs(fractional_part) < std::numeric_limits<long double>::min()
result = std::fabs(fractional_part) < std::numeric_limits<double>::min()
? std::string(".")
: std::to_string(fractional_part).substr(1);
@ -1259,7 +1259,7 @@ std::string number_formatter::fill_placeholders(const format_placeholders &p, lo
}
std::string number_formatter::fill_scientific_placeholders(const format_placeholders &integer_part,
const format_placeholders &fractional_part, const format_placeholders &exponent_part, long double number)
const format_placeholders &fractional_part, const format_placeholders &exponent_part, double number)
{
std::size_t logarithm = 0;
@ -1312,7 +1312,7 @@ std::string number_formatter::fill_scientific_placeholders(const format_placehol
}
std::string number_formatter::fill_fraction_placeholders(const format_placeholders & /*numerator*/,
const format_placeholders &denominator, long double number, bool /*improper*/)
const format_placeholders &denominator, double number, bool /*improper*/)
{
auto fractional_part = number - static_cast<int>(number);
auto original_fractional_part = fractional_part;
@ -1337,7 +1337,7 @@ std::string number_formatter::fill_fraction_placeholders(const format_placeholde
{
auto numerator_full = original_fractional_part * i;
auto numerator_rounded = static_cast<int>(std::round(numerator_full));
auto difference = std::fabs(original_fractional_part - (numerator_rounded / static_cast<long double>(i)));
auto difference = std::fabs(original_fractional_part - (numerator_rounded / static_cast<double>(i)));
if (difference < best_difference)
{
@ -1350,7 +1350,7 @@ std::string number_formatter::fill_fraction_placeholders(const format_placeholde
return std::to_string(numerator_rounded) + "/" + std::to_string(best_denominator);
}
std::string number_formatter::format_number(const format_code &format, long double number)
std::string number_formatter::format_number(const format_code &format, double number)
{
static const std::vector<std::string> *month_names = new std::vector<std::string>{"January", "February", "March",
"April", "May", "June", "July", "August", "September", "October", "November", "December"};

View File

@ -222,9 +222,9 @@ struct XLNT_API format_condition
greater_or_equal
} type = condition_type::not_equal;
long double value = 0;
double value = 0.0;
bool satisfied_by(long double number) const;
bool satisfied_by(double number) const;
};
struct format_placeholders
@ -352,17 +352,17 @@ class XLNT_API number_formatter
{
public:
number_formatter(const std::string &format_string, xlnt::calendar calendar);
std::string format_number(long double number);
std::string format_number(double number);
std::string format_text(const std::string &text);
private:
std::string fill_placeholders(const format_placeholders &p, long double number);
std::string fill_placeholders(const format_placeholders &p, double number);
std::string fill_fraction_placeholders(const format_placeholders &numerator,
const format_placeholders &denominator, long double number, bool improper);
const format_placeholders &denominator, double number, bool improper);
std::string fill_scientific_placeholders(const format_placeholders &integer_part,
const format_placeholders &fractional_part, const format_placeholders &exponent_part,
long double number);
std::string format_number(const format_code &format, long double number);
double number);
std::string format_number(const format_code &format, double number);
std::string format_text(const format_code &format, const std::string &text);
number_format_parser parser_;

View File

@ -110,7 +110,7 @@ struct number_converter
stream.imbue(std::locale("C"));
}
long double stold(const std::string &s)
double stold(const std::string &s)
{
stream.str(s);
stream.clear();
@ -119,7 +119,7 @@ struct number_converter
};
std::istringstream stream;
long double result;
double result;
};
} // namespace

View File

@ -47,9 +47,9 @@ namespace {
/// <summary>
/// Returns true if d is exactly equal to an integer.
/// </summary>
bool is_integral(long double d)
bool is_integral(double d)
{
return std::fabs(d - static_cast<long double>(static_cast<long long int>(d))) == 0.L;
return std::fabs(d - static_cast<double>(static_cast<long long int>(d))) == 0.L;
}
std::vector<std::pair<std::string, std::string>> core_property_namespace(xlnt::core_property type)
@ -2330,15 +2330,15 @@ void xlsx_producer::write_worksheet(const relationship &rel)
case cell::type::number:
write_start_element(xmlns, "v");
if (is_integral(cell.value<long double>()))
if (is_integral(cell.value<double>()))
{
write_characters(static_cast<std::int64_t>(cell.value<long double>()));
write_characters(static_cast<std::int64_t>(cell.value<double>()));
}
else
{
std::stringstream ss;
ss.precision(20);
ss << cell.value<long double>();
ss << cell.value<double>();
write_characters(ss.str());
}

View File

@ -344,7 +344,7 @@ std::string number_format::format(const std::string &text) const
return detail::number_formatter(format_string_, calendar::windows_1900).format_text(text);
}
std::string number_format::format(long double number, calendar base_date) const
std::string number_format::format(double number, calendar base_date) const
{
return detail::number_formatter(format_string_, base_date).format_number(number);
}

View File

@ -43,7 +43,7 @@ std::string fill(const std::string &string, std::size_t length = 2)
namespace xlnt {
datetime datetime::from_number(long double raw_time, calendar base_date)
datetime datetime::from_number(double raw_time, calendar base_date)
{
auto date_part = date::from_number(static_cast<int>(raw_time), base_date);
auto time_part = time::from_number(raw_time);
@ -54,13 +54,19 @@ datetime datetime::from_number(long double raw_time, calendar base_date)
bool datetime::operator==(const datetime &comparand) const
{
return year == comparand.year && month == comparand.month && day == comparand.day && hour == comparand.hour
&& minute == comparand.minute && second == comparand.second && microsecond == comparand.microsecond;
return year == comparand.year
&& month == comparand.month
&& day == comparand.day
&& hour == comparand.hour
&& minute == comparand.minute
&& second == comparand.second
&& microsecond == comparand.microsecond;
}
long double datetime::to_number(calendar base_date) const
double datetime::to_number(calendar base_date) const
{
return date(year, month, day).to_number(base_date) + time(hour, minute, second, microsecond).to_number();
return date(year, month, day).to_number(base_date)
+ time(hour, minute, second, microsecond).to_number();
}
std::string datetime::to_string() const

View File

@ -43,7 +43,7 @@ std::tm safe_localtime(std::time_t raw_time)
namespace xlnt {
time time::from_number(long double raw_time)
time time::from_number(double raw_time)
{
time result;
@ -110,7 +110,7 @@ time::time(const std::string &time_string)
}
}
long double time::to_number() const
double time::to_number() const
{
std::uint64_t microseconds = static_cast<std::uint64_t>(microsecond);
microseconds += static_cast<std::uint64_t>(second * 1e6);

View File

@ -37,27 +37,27 @@ timedelta::timedelta(int days_, int hours_, int minutes_, int seconds_, int micr
{
}
long double timedelta::to_number() const
double timedelta::to_number() const
{
std::uint64_t total_microseconds = static_cast<std::uint64_t>(microseconds);
total_microseconds += static_cast<std::uint64_t>(seconds * 1e6);
total_microseconds += static_cast<std::uint64_t>(minutes * 1e6 * 60);
auto microseconds_per_hour = static_cast<std::uint64_t>(1e6) * 60 * 60;
total_microseconds += static_cast<std::uint64_t>(hours) * microseconds_per_hour;
auto number = total_microseconds / (24.0L * microseconds_per_hour);
auto number = total_microseconds / (24.0 * microseconds_per_hour);
auto hundred_billion = static_cast<std::uint64_t>(1e9) * 100;
number = std::floor(number * hundred_billion + 0.5L) / hundred_billion;
number = std::floor(number * hundred_billion + 0.5) / hundred_billion;
number += days;
return number;
}
timedelta timedelta::from_number(long double raw_time)
timedelta timedelta::from_number(double raw_time)
{
timedelta result;
result.days = static_cast<int>(raw_time);
long double fractional_part = raw_time - result.days;
double fractional_part = raw_time - result.days;
fractional_part *= 24;
result.hours = static_cast<int>(fractional_part);

View File

@ -671,7 +671,7 @@ bool worksheet::compare(const worksheet &other, bool reference) const
}
if (this_cell.data_type() == xlnt::cell::type::number
&& std::fabs(this_cell.value<long double>() - other_cell.value<long double>()) > 0.L)
&& std::fabs(this_cell.value<double>() - other_cell.value<double>()) > 0.0)
{
return false;
}

View File

@ -76,7 +76,7 @@ private:
auto cell = ws.cell("A1");
cell.value("4.2", true);
xlnt_assert_delta(cell.value<long double>(), 4.2L, 1E-9);
xlnt_assert_delta(cell.value<double>(), 4.2, 1E-9);
cell.value("-42.000", true);
xlnt_assert(cell.value<int>() == -42);
@ -85,10 +85,10 @@ private:
xlnt_assert(cell.value<int>() == 0);
cell.value("0.9999", true);
xlnt_assert(cell.value<long double>() == 0.9999L);
xlnt_assert(cell.value<double>() == 0.9999);
cell.value("99E-02", true);
xlnt_assert(cell.value<long double>() == 0.99L);
xlnt_assert(cell.value<double>() == 0.99);
cell.value("4", true);
xlnt_assert(cell.value<int>() == 4);
@ -100,7 +100,7 @@ private:
xlnt_assert(cell.value<int>() == 200);
cell.value("3.1%", true);
xlnt_assert_delta(cell.value<long double>(), 0.031L, 1E-9);
xlnt_assert_delta(cell.value<double>(), 0.031, 1E-9);
cell.value("03:40:16", true);
xlnt_assert(cell.value<xlnt::time>() == xlnt::time(3, 40, 16));
@ -256,7 +256,7 @@ private:
cell.value(xlnt::datetime(2010, 7, 13, 6, 37, 41));
xlnt_assert(cell.data_type() == xlnt::cell::type::number);
xlnt_assert_delta(cell.value<long double>(), 40372.27616898148L, 1E-9);
xlnt_assert_delta(cell.value<double>(), 40372.27616898148, 1E-9);
xlnt_assert(cell.is_date());
xlnt_assert(cell.number_format().format_string() == "yyyy-mm-dd h:mm:ss");
}
@ -269,7 +269,7 @@ private:
cell.value(xlnt::date(2010, 7, 13));
xlnt_assert(cell.data_type() == xlnt::cell::type::number);
xlnt_assert(cell.value<long double>() == 40372.L);
xlnt_assert(cell.value<double>() == 40372.0);
xlnt_assert(cell.is_date());
xlnt_assert(cell.number_format().format_string() == "yyyy-mm-dd");
}
@ -282,7 +282,7 @@ private:
cell.value(xlnt::time(1, 3));
xlnt_assert(cell.data_type() == xlnt::cell::type::number);
xlnt_assert_delta(cell.value<long double>(), 0.04375L, 1E-9);
xlnt_assert_delta(cell.value<double>(), 0.04375, 1E-9);
xlnt_assert(cell.is_date());
xlnt_assert(cell.number_format().format_string() == "h:mm:ss");
}
@ -356,7 +356,7 @@ private:
cell.value(xlnt::timedelta(1, 3, 0, 0, 0));
xlnt_assert(cell.value<long double>() == 1.125);
xlnt_assert(cell.value<double>() == 1.125);
xlnt_assert(cell.data_type() == xlnt::cell::type::number);
xlnt_assert(!cell.is_date());
xlnt_assert(cell.number_format().format_string() == "[hh]:mm:ss");
@ -612,11 +612,8 @@ private:
cell.value(static_cast<float>(3.14));
xlnt_assert_delta(cell.value<float>(), 3.14, 0.001);
cell.value(static_cast<double>(4.1415));
xlnt_assert_equals(cell.value<double>(), 4.1415);
cell.value(static_cast<long double>(3.141592));
xlnt_assert_equals(cell.value<long double>(), 3.141592);
cell.value(static_cast<double>(3.141592));
xlnt_assert_equals(cell.value<double>(), 3.141592);
auto cell2 = ws.cell("A2");
cell2.value(std::string(100000, 'a'));

View File

@ -769,9 +769,9 @@ public:
void format_and_test(const xlnt::number_format &nf, const std::array<std::string, 4> &expect)
{
long double positive = 42503.1234;
long double negative = -1 * positive;
long double zero = 0;
double positive = 42503.1234;
double negative = -1 * positive;
double zero = 0;
const std::string text = "text";
xlnt::calendar calendar = xlnt::calendar::windows_1900;

View File

@ -51,7 +51,7 @@ public:
void test_round_trip()
{
long double time = 3.14159265359L;
double time = 3.14159265359;
auto td = xlnt::timedelta::from_number(time);
auto time_rt = td.to_number();
xlnt_assert_delta(time, time_rt, 1E-9);

View File

@ -120,9 +120,6 @@ public:
ws.cell("A14").value("number (double)");
ws.cell("B14").value(std::numeric_limits<double>::max());
ws.cell("A15").value("number (long double)");
ws.cell("B15").value(std::numeric_limits<long double>::max());
ws.cell("A16").value("text (char *)");
ws.cell("B16").value("string");