mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Make float database operations more consistent.
We don't use floats in GnuCash, we use doubles (and those as little as possible), but dbd-sqlite3 is broken in that it stores only floats. Simply casting floats to doubles introduces bogus additional digits that can cause round-trip tests to fail. Instead convert floats to doubles by multiplying by 10E6, rounding, then dividing by 10E6.
This commit is contained in:
parent
3e052e8dac
commit
9db60ca63c
@ -30,6 +30,7 @@ extern "C"
|
|||||||
/* For direct access to dbi data structs, sadly needed for datetime */
|
/* For direct access to dbi data structs, sadly needed for datetime */
|
||||||
#include <dbi/dbi-dev.h>
|
#include <dbi/dbi-dev.h>
|
||||||
}
|
}
|
||||||
|
#include <cmath>
|
||||||
#include <gnc-datetime.hpp>
|
#include <gnc-datetime.hpp>
|
||||||
#include "gnc-dbisqlresult.hpp"
|
#include "gnc-dbisqlresult.hpp"
|
||||||
#include "gnc-dbisqlconnection.hpp"
|
#include "gnc-dbisqlconnection.hpp"
|
||||||
@ -109,7 +110,7 @@ GncDbiSqlResult::IteratorImpl::get_int_at_col(const char* col) const
|
|||||||
return dbi_result_get_longlong (m_inst->m_dbi_result, col);
|
return dbi_result_get_longlong (m_inst->m_dbi_result, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
double
|
||||||
GncDbiSqlResult::IteratorImpl::get_float_at_col(const char* col) const
|
GncDbiSqlResult::IteratorImpl::get_float_at_col(const char* col) const
|
||||||
{
|
{
|
||||||
auto type = dbi_result_get_field_type (m_inst->m_dbi_result, col);
|
auto type = dbi_result_get_field_type (m_inst->m_dbi_result, col);
|
||||||
@ -118,8 +119,9 @@ GncDbiSqlResult::IteratorImpl::get_float_at_col(const char* col) const
|
|||||||
(attrs & DBI_DECIMAL_SIZEMASK) != DBI_DECIMAL_SIZE4)
|
(attrs & DBI_DECIMAL_SIZEMASK) != DBI_DECIMAL_SIZE4)
|
||||||
throw (std::invalid_argument{"Requested float from non-float column."});
|
throw (std::invalid_argument{"Requested float from non-float column."});
|
||||||
auto locale = gnc_push_locale (LC_NUMERIC, "C");
|
auto locale = gnc_push_locale (LC_NUMERIC, "C");
|
||||||
auto retval = dbi_result_get_float(m_inst->m_dbi_result, col);
|
auto interim = dbi_result_get_float(m_inst->m_dbi_result, col);
|
||||||
gnc_pop_locale (LC_NUMERIC, locale);
|
gnc_pop_locale (LC_NUMERIC, locale);
|
||||||
|
double retval = static_cast<double>(round(interim * 1000000.0)) / 1000000.0;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ protected:
|
|||||||
virtual GncSqlRow& operator++(int) { return ++(*this); };
|
virtual GncSqlRow& operator++(int) { return ++(*this); };
|
||||||
virtual GncSqlResult* operator*() { return m_inst; }
|
virtual GncSqlResult* operator*() { return m_inst; }
|
||||||
virtual int64_t get_int_at_col (const char* col) const;
|
virtual int64_t get_int_at_col (const char* col) const;
|
||||||
virtual float get_float_at_col (const char* col) const;
|
virtual double get_float_at_col (const char* col) const;
|
||||||
virtual double get_double_at_col (const char* col) const;
|
virtual double get_double_at_col (const char* col) const;
|
||||||
virtual std::string get_string_at_col (const char* col)const;
|
virtual std::string get_string_at_col (const char* col)const;
|
||||||
virtual time64 get_time64_at_col (const char* col) const;
|
virtual time64 get_time64_at_col (const char* col) const;
|
||||||
|
@ -283,7 +283,7 @@ GncSqlColumnTableEntryImpl<CT_DOUBLE>::load (const GncSqlBackend* sql_be,
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
val = static_cast<double>(row.get_float_at_col(m_col_name));
|
val = row.get_float_at_col(m_col_name);
|
||||||
}
|
}
|
||||||
catch (std::invalid_argument&)
|
catch (std::invalid_argument&)
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ protected:
|
|||||||
virtual GncSqlRow& operator++() = 0;
|
virtual GncSqlRow& operator++() = 0;
|
||||||
virtual GncSqlResult* operator*() = 0;
|
virtual GncSqlResult* operator*() = 0;
|
||||||
virtual int64_t get_int_at_col (const char* col) const = 0;
|
virtual int64_t get_int_at_col (const char* col) const = 0;
|
||||||
virtual float get_float_at_col (const char* col) const = 0;
|
virtual double get_float_at_col (const char* col) const = 0;
|
||||||
virtual double get_double_at_col (const char* col) const = 0;
|
virtual double get_double_at_col (const char* col) const = 0;
|
||||||
virtual std::string get_string_at_col (const char* col) const = 0;
|
virtual std::string get_string_at_col (const char* col) const = 0;
|
||||||
virtual time64 get_time64_at_col (const char* col) const = 0;
|
virtual time64 get_time64_at_col (const char* col) const = 0;
|
||||||
@ -88,7 +88,7 @@ public:
|
|||||||
friend bool operator!=(const GncSqlRow&, const GncSqlRow&);
|
friend bool operator!=(const GncSqlRow&, const GncSqlRow&);
|
||||||
int64_t get_int_at_col (const char* col) const {
|
int64_t get_int_at_col (const char* col) const {
|
||||||
return m_iter->get_int_at_col (col); }
|
return m_iter->get_int_at_col (col); }
|
||||||
float get_float_at_col (const char* col) const {
|
double get_float_at_col (const char* col) const {
|
||||||
return m_iter->get_float_at_col (col); }
|
return m_iter->get_float_at_col (col); }
|
||||||
double get_double_at_col (const char* col) const {
|
double get_double_at_col (const char* col) const {
|
||||||
return m_iter->get_double_at_col (col); }
|
return m_iter->get_double_at_col (col); }
|
||||||
|
@ -66,7 +66,7 @@ protected:
|
|||||||
virtual GncSqlResult* operator*() { return m_inst; }
|
virtual GncSqlResult* operator*() { return m_inst; }
|
||||||
virtual int64_t get_int_at_col (const char* col) const
|
virtual int64_t get_int_at_col (const char* col) const
|
||||||
{ return 1LL; }
|
{ return 1LL; }
|
||||||
virtual float get_float_at_col (const char* col) const
|
virtual double get_float_at_col (const char* col) const
|
||||||
{ return 1.0; }
|
{ return 1.0; }
|
||||||
virtual double get_double_at_col (const char* col) const
|
virtual double get_double_at_col (const char* col) const
|
||||||
{ return 1.0; }
|
{ return 1.0; }
|
||||||
|
Loading…
Reference in New Issue
Block a user