[goffice] fake-rounding: fix for very large numbers.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] fake-rounding: fix for very large numbers.
- Date: Tue, 15 Jun 2010 16:03:19 +0000 (UTC)
commit a384adbfd2c3cf72535d6f2474b90bfe48c26425
Author: Morten Welinder <terra gnome org>
Date: Tue Jun 15 12:02:45 2010 -0400
fake-rounding: fix for very large numbers.
ChangeLog | 7 +++++++
NEWS | 1 +
goffice/math/go-math.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 40 insertions(+), 0 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c99d058..6c91456 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2010-06-15 Morten Welinder <terra gnome org>
+
+ * goffice/math/go-math.c (go_fake_floor, go_fake_ceil,
+ go_fake_trunc, go_fake_floorl, go_fake_ceill, go_fake_truncl):
+ Handle very large numbers right. Handle ix86 excess precision for
+ "double" versions.
+
2010-06-11 Morten Welinder <terra gnome org>
* goffice/gtk/go-format-sel.c (funny_currency_order): Fix order.
diff --git a/NEWS b/NEWS
index 2dd34a0..d726557 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ Morten:
* Ensure format menu has yyyy-mm-dd.
* Improve docs.
* Fix currency ordering. [#621336]
+ * Fix rounding problems for very large numbers.
--------------------------------------------------------------------------
goffice 0.8.5:
diff --git a/goffice/math/go-math.c b/goffice/math/go-math.c
index 879b108..291c0f7 100644
--- a/goffice/math/go-math.c
+++ b/goffice/math/go-math.c
@@ -220,9 +220,22 @@ go_sub_epsilon (double x)
}
}
+static double
+go_d2d (double x)
+{
+ /* Kill excess precision by forcing a memory read. */
+ const volatile double *px = &x;
+ return *px;
+}
+
double
go_fake_floor (double x)
{
+ x = go_d2d (x);
+
+ if (x == floor (x))
+ return x;
+
return (x >= 0)
? floor (go_add_epsilon (x))
: floor (go_sub_epsilon (x));
@@ -231,6 +244,11 @@ go_fake_floor (double x)
double
go_fake_ceil (double x)
{
+ x = go_d2d (x);
+
+ if (x == floor (x))
+ return x;
+
return (x >= 0)
? ceil (go_sub_epsilon (x))
: ceil (go_add_epsilon (x));
@@ -246,6 +264,11 @@ go_fake_round (double x)
double
go_fake_trunc (double x)
{
+ x = go_d2d (x);
+
+ if (x == floor (x))
+ return x;
+
return (x >= 0)
? floor (go_add_epsilon (x))
: -floor (go_add_epsilon (-x));
@@ -636,6 +659,9 @@ go_sub_epsilonl (long double x)
long double
go_fake_floorl (long double x)
{
+ if (x == floorl (x))
+ return x;
+
return (x >= 0)
? floorl (go_add_epsilonl (x))
: floorl (go_sub_epsilonl (x));
@@ -644,6 +670,9 @@ go_fake_floorl (long double x)
long double
go_fake_ceill (long double x)
{
+ if (x == floorl (x))
+ return x;
+
return (x >= 0)
? ceill (go_sub_epsilonl (x))
: ceill (go_add_epsilonl (x));
@@ -659,6 +688,9 @@ go_fake_roundl (long double x)
long double
go_fake_truncl (long double x)
{
+ if (x == floorl (x))
+ return x;
+
return (x >= 0)
? floorl (go_add_epsilonl (x))
: -floorl (go_add_epsilonl (-x));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]