[prev in list] [next in list] [prev in thread] [next in thread]
List: koffice-devel
Subject: Re: bug in waiting with bessel functions (kspread)
From: Andrew <andrew.dorrell () gmail ! com>
Date: 2008-11-17 3:24:41
Message-ID: 200811171424.41923.andrew.dorrell () gmail ! com
[Download RAW message or body]
On Mon, 17 Nov 2008 12:45:28 am Tomas Mecir wrote:
> Hi Andrew !
>
> 2008/11/16 Andrew <andrew.dorrell@gmail.com>:
> > The problem is that no range checking is performed on the parameters in
> > the wrappers. The ccmath functions will produce garbage for v>=29 due to
> > the ccmath_gaml function:
>
> The bessel* functions are called in kspread/functions/engineering.cpp,
> in functions func_besseli and similar. Error handling is basically
> something like
> if (x >= 30) return Value::errorVALUE();
> these would likely best be placed in ValueCalc, after the toFloat
> calls, as that's where the double-precision value is pulled out of the
> Value class, including conversion if needed.
OK... I'd do it as per the attached patch (which I have built and minimally
checked). Looking at the numbers it generates though I'm concerned there
might be a more fundamental issue... compare
http://en.wikipedia.org/wiki/Bessel_function.
In a quick test spreadsheet I can get some huge numbers back from the 1st
order bessel function (which should be bounded in [-1,1] at least). Not sure
what's up there...
["ValueCalc.patch" (text/x-patch)]
Index: ValueCalc.cpp
===================================================================
--- ValueCalc.cpp (revision 885321)
+++ ValueCalc.cpp (working copy)
@@ -1551,7 +1551,7 @@
*/
static double ccmath_gaml(double x)
-{ double g,h;
+{ double g,h=0; /* NB must be called with 0<=x<29 */
for(g=1.; x<30. ;g*=x,x+=1.) h=x*x;
g=(x-.5)*log(x)-x+.918938533204672-log(g);
g+=(1.-(1./6.-(1./3.-1./(4.*h))/(7.*h))/(5.*h))/(12.*x);
@@ -1679,35 +1679,42 @@
/* ---------- end of CCMATH code ---------- */
+template <typename func_ptr>
+Value CalcBessel(
+ func_ptr *func,
+ ValueConverter *converter,
+ Value v, Value x)
+{
+ double vv = numToDouble (converter->toFloat (v));
+ double xx = numToDouble (converter->toFloat (x));
+ // vv must be a non-negative integer and <29 for implementation reasons
+ // xx must be non-negative
+ if(xx>=0 && vv>=0 && vv<29 && vv == floor(vv))
+ return Value (func (vv, xx));
+ return Value::errorVALUE();
+}
Value ValueCalc::besseli (Value v, Value x)
{
- Number vv = converter->toFloat (v);
- Number xx = converter->toFloat (x);
- return Value (ccmath_ibes (numToDouble (vv), numToDouble (xx)));
+ return CalcBessel(ccmath_ibes, converter, v, x);
}
Value ValueCalc::besselj (Value v, Value x)
{
- Number vv = converter->toFloat (v);
- Number xx = converter->toFloat (x);
- return Value (ccmath_jbes (numToDouble (vv), numToDouble (xx)));
+ return CalcBessel(ccmath_jbes, converter, v, x);
}
Value ValueCalc::besselk (Value v, Value x)
{
- Number vv = converter->toFloat (v);
- Number xx = converter->toFloat (x);
- return Value (ccmath_kbes (numToDouble (vv), numToDouble (xx)));
+ return CalcBessel(ccmath_kbes, converter, v, x);
}
Value ValueCalc::besseln (Value v, Value x)
{
- Number vv = converter->toFloat (v);
- Number xx = converter->toFloat (x);
- return Value (ccmath_nbes (numToDouble (vv), numToDouble (xx)));
+ return CalcBessel(ccmath_nbes, converter, v, x);
}
+
// ------------------------------------------------------
Value ValueCalc::erf (Value x)
_______________________________________________
koffice-devel mailing list
koffice-devel@kde.org
https://mail.kde.org/mailman/listinfo/koffice-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic