valuecalc.cc
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "valuecalc.h"
00021
00022 #include "valueconverter.h"
00023
00024 #include <math.h>
00025
00026 using namespace KSpread;
00027
00028 ValueCalc::ValueCalc (ValueConverter* conv): converter( conv )
00029 {
00030 }
00031
00032 KSpreadValue ValueCalc::add (const KSpreadValue &a, const KSpreadValue &b)
00033 {
00034 double aa, bb;
00035 aa = converter->asFloat (a).asFloat();
00036 bb = converter->asFloat (b).asFloat();
00037 KSpreadValue res = KSpreadValue (aa + bb);
00038
00039 if (a.isNumber())
00040 res.setFormat (format (a.format(), b.format()));
00041
00042 return res;
00043 }
00044
00045 KSpreadValue ValueCalc::sub (const KSpreadValue &a, const KSpreadValue &b)
00046 {
00047 double aa, bb;
00048 aa = converter->asFloat (a).asFloat();
00049 bb = converter->asFloat (b).asFloat();
00050 KSpreadValue res = KSpreadValue (aa - bb);
00051
00052 if (a.isNumber())
00053 res.setFormat (format (a.format(), b.format()));
00054
00055 return res;
00056 }
00057
00058 KSpreadValue ValueCalc::mul (const KSpreadValue &a, const KSpreadValue &b)
00059 {
00060 double aa, bb;
00061 aa = converter->asFloat (a).asFloat();
00062 bb = converter->asFloat (b).asFloat();
00063 KSpreadValue res = KSpreadValue (aa * bb);
00064
00065 if (a.isNumber())
00066 res.setFormat (format (a.format(), b.format()));
00067
00068 return res;
00069 }
00070
00071 KSpreadValue ValueCalc::div (const KSpreadValue &a, const KSpreadValue &b)
00072 {
00073 double aa, bb;
00074 aa = converter->asFloat (a).asFloat();
00075 bb = converter->asFloat (b).asFloat();
00076 KSpreadValue res;
00077 if (bb == 0.0)
00078 return KSpreadValue::errorDIV0();
00079 else
00080 res = KSpreadValue (aa / bb);
00081
00082 if (a.isNumber())
00083 res.setFormat (format (a.format(), b.format()));
00084
00085 return res;
00086 }
00087
00088 KSpreadValue ValueCalc::pow (const KSpreadValue &a, const KSpreadValue &b)
00089 {
00090 double aa, bb;
00091 aa = converter->asFloat (a).asFloat();
00092 bb = converter->asFloat (b).asFloat();
00093 KSpreadValue res = KSpreadValue (::pow (aa, bb));
00094
00095 if (a.isNumber())
00096 res.setFormat (format (a.format(), b.format()));
00097
00098 return res;
00099 }
00100
00101 KSpreadValue ValueCalc::add (const KSpreadValue &a, double b)
00102 {
00103 KSpreadValue res = KSpreadValue (converter->asFloat(a).asFloat() + b);
00104
00105 if (a.isNumber())
00106 res.setFormat (a.format());
00107
00108 return res;
00109 }
00110
00111 KSpreadValue ValueCalc::sub (const KSpreadValue &a, double b)
00112 {
00113 KSpreadValue res = KSpreadValue (converter->asFloat(a).asFloat() - b);
00114
00115 if (a.isNumber())
00116 res.setFormat (a.format());
00117
00118 return res;
00119 }
00120
00121 KSpreadValue ValueCalc::mul (const KSpreadValue &a, double b)
00122 {
00123 KSpreadValue res = KSpreadValue (converter->asFloat(a).asFloat() * b);
00124
00125 if (a.isNumber())
00126 res.setFormat (a.format());
00127
00128 return res;
00129 }
00130
00131 KSpreadValue ValueCalc::div (const KSpreadValue &a, double b)
00132 {
00133 KSpreadValue res;
00134 if (b == 0.0)
00135 return KSpreadValue::errorDIV0();
00136
00137 res = KSpreadValue (converter->asFloat(a).asFloat() / b);
00138
00139 if (a.isNumber())
00140 res.setFormat (a.format());
00141
00142 return res;
00143 }
00144
00145 KSpreadValue ValueCalc::pow (const KSpreadValue &a, double b)
00146 {
00147 KSpreadValue res = KSpreadValue (::pow (converter->asFloat(a).asFloat(), b));
00148
00149 if (a.isNumber())
00150 res.setFormat (a.format());
00151
00152 return res;
00153 }
00154
00155 KSpreadValue ValueCalc::log (const KSpreadValue &number,
00156 const KSpreadValue &base)
00157 {
00158 double logbase = converter->asFloat (base).asFloat();
00159 if (logbase == 1.0)
00160 return KSpreadValue::errorDIV0();
00161 if (logbase <= 0.0)
00162 return KSpreadValue::errorNA();
00163
00164 logbase = log10 (logbase);
00165 KSpreadValue res = KSpreadValue (log10 (converter->asFloat (number).asFloat()) / logbase);
00166
00167 if (number.isNumber())
00168 res.setFormat (number.format());
00169
00170 return res;
00171 }
00172
00173 KSpreadValue ValueCalc::ln (const KSpreadValue &number)
00174 {
00175 KSpreadValue res = KSpreadValue (::log (converter->asFloat (number).asFloat()));
00176
00177 if (number.isNumber())
00178 res.setFormat (number.format());
00179
00180 return res;
00181 }
00182
00183 KSpreadValue ValueCalc::log (const KSpreadValue &number, double base)
00184 {
00185 if (base <= 0.0)
00186 return KSpreadValue::errorNA();
00187 if (base == 1.0)
00188 return KSpreadValue::errorDIV0();
00189
00190 double num = converter->asFloat (number).asFloat();
00191 KSpreadValue res = KSpreadValue (log10 (num) / log10 (base));
00192
00193 if (number.isNumber())
00194 res.setFormat (number.format());
00195
00196 return res;
00197 }
00198
00199
00200
00201 KSpreadValue ValueCalc::sum (const KSpreadValue &range)
00202 {
00203 if (!range.isArray())
00204 return converter->asFloat (range);
00205
00206
00207 KSpreadValue res;
00208 KSpreadValue::Format fmt = KSpreadValue::fmt_None;
00209
00210 int rows = range.rows ();
00211 int cols = range.columns ();
00212 for (int r = 0; r < rows; r++)
00213 for (int c = 0; c < cols; c++)
00214 {
00215 KSpreadValue v = range.element (c, r);
00216 if (v.isArray())
00217 res = add (res, sum (v));
00218 else
00219 res = add (res, v);
00220 if (fmt == KSpreadValue::fmt_None)
00221 fmt = range.element (c, r).format ();
00222 }
00223
00224 res.setFormat (fmt);
00225 return res;
00226 }
00227
00228 int ValueCalc::count (const KSpreadValue &range)
00229 {
00230 if (!range.isArray())
00231 return range.isEmpty() ? 0 : 1;
00232
00233 int res = 0;
00234
00235 int cols = range.columns ();
00236 int rows = range.rows ();
00237 for (int r = 0; r < rows; r++)
00238 for (int c = 0; c < cols; c++)
00239 {
00240 KSpreadValue v = range.element (c, r);
00241 if (v.isArray())
00242 res += count (v);
00243 else
00244 if (!v.isEmpty() && !v.isString())
00245 res++;
00246 }
00247
00248 return res;
00249 }
00250
00251 int ValueCalc::countA (const KSpreadValue &range)
00252 {
00253 if (!range.isArray())
00254 return range.isEmpty() ? 0 : 1;
00255
00256 int res = 0;
00257
00258 int cols = range.columns ();
00259 int rows = range.rows ();
00260 for (int r = 0; r < rows; r++)
00261 for (int c = 0; c < cols; c++)
00262 {
00263 KSpreadValue v = range.element (c, r);
00264 if (v.isArray())
00265 res += countA (v);
00266 else
00267 if (!v.isEmpty())
00268 res++;
00269 }
00270
00271 return res;
00272 }
00273
00274
00275 KSpreadValue ValueCalc::avg (const KSpreadValue &range)
00276 {
00277 int cnt = count (range);
00278 if (cnt)
00279 return div (sum (range), cnt);
00280 return KSpreadValue (0.0);
00281 }
00282
00283 KSpreadValue ValueCalc::max (const KSpreadValue &range)
00284 {
00285 if (!range.isArray())
00286 return converter->asFloat (range);
00287
00288
00289 KSpreadValue res;
00290
00291 int rows = range.rows ();
00292 int cols = range.columns ();
00293 bool got = false;
00294 for (int r = 0; r < rows; r++)
00295 for (int c = 0; c < cols; c++)
00296 {
00297 KSpreadValue v = range.element (c, r);
00298 if (v.isArray())
00299 v = max (v);
00300 if (!v.isEmpty ())
00301 if (got)
00302 {
00303 if (v.greater (res))
00304 res = v;
00305 }
00306 else
00307 {
00308 res = v;
00309 got = true;
00310 }
00311 }
00312
00313 return res;
00314 }
00315
00316 KSpreadValue ValueCalc::min (const KSpreadValue &range)
00317 {
00318 if (!range.isArray())
00319 return converter->asFloat (range);
00320
00321
00322 KSpreadValue res;
00323
00324 int rows = range.rows ();
00325 int cols = range.columns ();
00326 bool got = false;
00327 for (int r = 0; r < rows; r++)
00328 for (int c = 0; c < cols; c++)
00329 {
00330 KSpreadValue v = range.element (c, r);
00331 if (v.isArray())
00332 v = max (v);
00333 if (!v.isEmpty ())
00334 if (got)
00335 {
00336 if (v.less (res))
00337 res = v;
00338 }
00339 else
00340 {
00341 res = v;
00342 got = true;
00343 }
00344 }
00345
00346 return res;
00347 }
00348
00349 KSpreadValue::Format ValueCalc::format (KSpreadValue::Format a,
00350 KSpreadValue::Format b)
00351 {
00352 if ((a == KSpreadValue::fmt_None) || (a == KSpreadValue::fmt_Boolean))
00353 return b;
00354 return a;
00355 }
00356
This file is part of the documentation for kspread Library Version 1.4.2.