summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2022-09-22 09:55:05 +0200
committerLuboš Luňák <l.lunak@collabora.com>2022-09-22 17:59:53 +0200
commitaf5aaddee5e752fcb38cf1550d8152089443196e (patch)
treecf61941b041465884999005cc95ac309e785ed83 /sc
parent43f2cdb3b41ff4f5e99500f0c0082d4bfa4bc97c (diff)
fix opencl ocMod
Basically copied from core. Change-Id: Ic46e6ed77d1e75fcd4dfb8c641a8f592d577cab0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140370 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'sc')
-rw-r--r--sc/source/core/opencl/op_math.cxx34
-rw-r--r--sc/source/core/opencl/op_math.hxx1
-rw-r--r--sc/source/core/opencl/op_math_helpers.hxx26
3 files changed, 47 insertions, 14 deletions
diff --git a/sc/source/core/opencl/op_math.cxx b/sc/source/core/opencl/op_math.cxx
index cd2f2f8b5396..5e88f8f67a8e 100644
--- a/sc/source/core/opencl/op_math.cxx
+++ b/sc/source/core/opencl/op_math.cxx
@@ -391,23 +391,29 @@ void OpCombin::GenerateCode( outputstream& ss ) const
ss << " return result;\n";
}
+void OpMod::BinInlineFun(std::set<std::string>& decls,std::set<std::string>& funs)
+{
+ decls.insert(is_representable_integerDecl);
+ funs.insert(is_representable_integer);
+ decls.insert(approx_equalDecl);
+ funs.insert(approx_equal);
+ decls.insert(fsub_approxDecl);
+ funs.insert(fsub_approx);
+ decls.insert(value_approxDecl);
+ funs.insert(value_approx);
+}
+
void OpMod::GenerateCode( outputstream& ss ) const
{
- ss << " if(isnan(arg0)||arg0 == 0)\n";
- ss << " return 0;\n";
- ss << " if(isnan(arg1) || arg1 ==0)\n";
+ ss << " double fNum = arg0;\n";
+ ss << " double fDenom = arg1;\n";
+ ss << " if(fDenom == 0)\n";
ss << " return CreateDoubleError(DivisionByZero);\n";
- ss << " double tem;\n";
- ss << " if(arg0 < 0 && arg1 > 0)\n";
- ss << " while(arg0 < 0)\n";
- ss << " arg0 += arg1;\n";
- ss << " else if (arg0 > 0 && arg1 < 0)\n";
- ss << " while(arg0 > 0)\n";
- ss << " arg0 += arg1;\n";
- ss << " tem = fmod(arg0,arg1);\n";
- ss << " if(arg1 < 0 && tem > 0)\n";
- ss << " tem = -tem;\n";
- ss << " return tem;\n";
+ ss << " double fRes = fsub_approx( fNum, floor( value_approx( fNum / fDenom )) * fDenom );\n";
+ ss << " if ( ( fDenom > 0 && fRes >= 0 && fRes < fDenom ) ||\n";
+ ss << " ( fDenom < 0 && fRes <= 0 && fRes > fDenom ) )\n";
+ ss << " return fRes;\n";
+ ss << " return CreateDoubleError(NoValue);\n";
}
void OpPower::GenerateCode( outputstream& ss ) const
diff --git a/sc/source/core/opencl/op_math.hxx b/sc/source/core/opencl/op_math.hxx
index 9ff5253d0ad5..a5adec2cb8aa 100644
--- a/sc/source/core/opencl/op_math.hxx
+++ b/sc/source/core/opencl/op_math.hxx
@@ -405,6 +405,7 @@ class OpMod: public OpMathTwoArguments
public:
virtual std::string BinFuncName() const override { return "Mod"; }
virtual void GenerateCode( outputstream& ss ) const override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
};
class OpProduct: public Normal
diff --git a/sc/source/core/opencl/op_math_helpers.hxx b/sc/source/core/opencl/op_math_helpers.hxx
index 015afcf547fb..6a751dd9c35b 100644
--- a/sc/source/core/opencl/op_math_helpers.hxx
+++ b/sc/source/core/opencl/op_math_helpers.hxx
@@ -163,4 +163,30 @@ const char fsub_approx[] =
" return a - b;\n"
"}\n";
+const char value_approxDecl[] = "double value_approx( double fValue );\n";
+const char value_approx[] =
+"double value_approx( double fValue )\n"
+"{\n"
+" const double fBigInt = 2199023255552.0;\n"
+" if (fValue == 0.0 || fValue == HUGE_VAL || !isfinite(fValue))\n"
+" return fValue;\n"
+" double fOrigValue = fValue;\n"
+" fValue = fabs(fValue);\n"
+" if (fValue > fBigInt)\n"
+" return fOrigValue;\n"
+" if (is_representable_integer(fValue))\n" // TODO? || getBitsInFracPart(fValue) <= 11)\n"
+" return fOrigValue;\n"
+" int nExp = (int)(floor(log10(fValue)));\n"
+" nExp = 14 - nExp;\n"
+" double fExpValue = pow(10.0,nExp);\n"
+" fValue *= fExpValue;\n"
+" if (!isfinite(fValue))\n"
+" return fOrigValue;\n"
+" fValue = round(fValue);\n"
+" fValue /= fExpValue;\n"
+" if (!isfinite(fValue))\n"
+" return fOrigValue;\n"
+" return copysign(fValue, fOrigValue);\n"
+"}\n";
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */