[Libreoffice-commits] core.git: sc/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Jul 27 07:52:14 UTC 2018


 sc/source/core/opencl/formulagroupcl.cxx |   42 +++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)

New commits:
commit 2abdcdfae6eddb08de8fade2392963fda81851ab
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Jul 24 12:04:13 2018 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Fri Jul 27 09:51:43 2018 +0200

    make opencl also use approximate add and sub
    
    Code basically taken from rtl::math::approxAdd() and friends. Without this
    OpenCL will sometimes not get results as 0 because of rounding errors
    (sc/qa/.../linest.fods with minimum formula size disabled).
    
    Change-Id: Ib66f5eb1c6aeb9c95047406de1442b388ccc7f5f
    Reviewed-on: https://gerrit.libreoffice.org/57911
    Tested-by: Jenkins
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index 7067ec0fa5c8..fa5b37e969f2 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -83,6 +83,44 @@ static const char* const publicFunc =
  "double fsub(double a, double b) { return a-b; }\n"
  "double fdiv(double a, double b) { return a/b; }\n"
  "double strequal(unsigned a, unsigned b) { return (a==b)?1.0:0; }\n"
+ "int is_representable_integer(double a) {\n"
+ "    long kMaxInt = (1L << 53) - 1;\n"
+ "    if (a <= as_double(kMaxInt))\n"
+ "    {\n"
+ "        long nInt = as_long(a);\n"
+ "        double fInt;\n"
+ "        return (nInt <= kMaxInt &&\n"
+ "                (!((fInt = as_double(nInt)) < a) && !(fInt > a)));\n"
+ "    }\n"
+ "    return 0;\n"
+ "}\n"
+ "int approx_equal(double a, double b) {\n"
+ "    double e48 = 1.0 / (16777216.0 * 16777216.0);\n"
+ "    double e44 = e48 * 16.0;\n"
+ "    if (a == b)\n"
+ "        return 1;\n"
+ "    if (a == 0.0 || b == 0.0)\n"
+ "        return 0;\n"
+ "    double d = fabs(a - b);\n"
+ "    if (!isfinite(d))\n"
+ "        return 0;   // Nan or Inf involved\n"
+ "    if (d > ((a = fabs(a)) * e44) || d > ((b = fabs(b)) * e44))\n"
+ "        return 0;\n"
+ "    if (is_representable_integer(d) && is_representable_integer(a) && is_representable_integer(b))\n"
+ "        return 0;   // special case for representable integers.\n"
+ "    return (d < a * e48 && d < b * e48);\n"
+ "}\n"
+ "double fsum_approx(double a, double b) {\n"
+ "    if ( ((a < 0.0 && b > 0.0) || (b < 0.0 && a > 0.0))\n"
+ "         && approx_equal( a, -b ) )\n"
+ "        return 0.0;\n"
+ "    return a + b;\n"
+ "}\n"
+ "double fsub_approx(double a, double b) {\n"
+ "    if ( ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0)) && approx_equal( a, b ) )\n"
+ "        return 0.0;\n"
+ "    return a - b;\n"
+ "}\n"
  ;
 
 #include <vector>
@@ -1670,7 +1708,7 @@ public:
     virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
     {
         std::stringstream ss;
-        ss << "((" << lhs << ")+(" << rhs << "))";
+        ss << "fsum_approx((" << lhs << "),(" << rhs << "))";
         return ss.str();
     }
     virtual std::string BinFuncName() const override { return "fsum"; }
@@ -1700,7 +1738,7 @@ public:
     virtual std::string GetBottom() override { return "0"; }
     virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
     {
-        return lhs + "-" + rhs;
+        return "fsub_approx(" + lhs + "," + rhs + ")";
     }
     virtual std::string BinFuncName() const override { return "fsub"; }
 };


More information about the Libreoffice-commits mailing list