tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / core / tool / subtotal.cxx
blob4c213893b14d02750fa14296047fba8943f26ab1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <subtotal.hxx>
21 #include <sal/mathconf.h>
22 #include <cfloat>
24 bool SubTotal::SafePlus(double& fVal1, double fVal2)
26 bool bOk = true;
27 SAL_MATH_FPEXCEPTIONS_OFF();
28 fVal1 += fVal2;
29 if (!std::isfinite(fVal1))
31 bOk = false;
32 if (fVal2 > 0.0)
33 fVal1 = DBL_MAX;
34 else
35 fVal1 = -DBL_MAX;
37 return bOk;
40 bool SubTotal::SafeMult(double& fVal1, double fVal2)
42 bool bOk = true;
43 SAL_MATH_FPEXCEPTIONS_OFF();
44 fVal1 *= fVal2;
45 if (!std::isfinite(fVal1))
47 bOk = false;
48 fVal1 = DBL_MAX;
50 return bOk;
53 bool SubTotal::SafeDiv(double& fVal1, double fVal2)
55 bool bOk = true;
56 SAL_MATH_FPEXCEPTIONS_OFF();
57 fVal1 /= fVal2;
58 if (!std::isfinite(fVal1))
60 bOk = false;
61 fVal1 = DBL_MAX;
63 return bOk;
66 void ScFunctionData::update(double fNewVal)
68 if (mbError)
69 return;
71 switch (meFunc)
73 case SUBTOTAL_FUNC_SUM:
74 if (!SubTotal::SafePlus(getValueRef(), fNewVal))
75 mbError = true;
76 break;
77 case SUBTOTAL_FUNC_PROD:
78 if (getCountRef() == 0) // copy first value (nVal is initialized to 0)
80 getValueRef() = fNewVal;
81 getCountRef() = 1; // don't care about further count
83 else if (!SubTotal::SafeMult(getValueRef(), fNewVal))
84 mbError = true;
85 break;
86 case SUBTOTAL_FUNC_CNT:
87 case SUBTOTAL_FUNC_CNT2:
88 ++getCountRef();
89 break;
90 case SUBTOTAL_FUNC_SELECTION_COUNT:
91 getCountRef() += fNewVal;
92 break;
93 case SUBTOTAL_FUNC_AVE:
94 if (!SubTotal::SafePlus(getValueRef(), fNewVal))
95 mbError = true;
96 else
97 ++getCountRef();
98 break;
99 case SUBTOTAL_FUNC_MAX:
100 if (getCountRef() == 0) // copy first value (nVal is initialized to 0)
102 getValueRef() = fNewVal;
103 getCountRef() = 1; // don't care about further count
105 else if (fNewVal > getValueRef())
106 getValueRef() = fNewVal;
107 break;
108 case SUBTOTAL_FUNC_MIN:
109 if (getCountRef() == 0) // copy first value (nVal is initialized to 0)
111 getValueRef() = fNewVal;
112 getCountRef() = 1; // don't care about further count
114 else if (fNewVal < getValueRef())
115 getValueRef() = fNewVal;
116 break;
117 case SUBTOTAL_FUNC_VAR:
118 case SUBTOTAL_FUNC_STD:
119 case SUBTOTAL_FUNC_VARP:
120 case SUBTOTAL_FUNC_STDP:
121 maWelford.update(fNewVal);
122 break;
123 default:
124 // unhandled unknown
125 mbError = true;
129 double ScFunctionData::getResult()
131 if (mbError)
132 return 0.0;
134 double fRet = 0.0;
135 switch (meFunc)
137 case SUBTOTAL_FUNC_CNT:
138 case SUBTOTAL_FUNC_CNT2:
139 case SUBTOTAL_FUNC_SELECTION_COUNT:
140 fRet = getCountRef();
141 break;
142 case SUBTOTAL_FUNC_SUM:
143 case SUBTOTAL_FUNC_MAX:
144 case SUBTOTAL_FUNC_MIN:
145 // Note that nVal is 0.0 for MAX and MIN if nCount==0, that's also
146 // how it is defined in ODFF.
147 fRet = getValueRef();
148 break;
149 case SUBTOTAL_FUNC_PROD:
150 fRet = (getCountRef() > 0) ? getValueRef() : 0.0;
151 break;
152 case SUBTOTAL_FUNC_AVE:
153 if (getCountRef() == 0)
154 mbError = true;
155 else
156 fRet = getValueRef() / getCountRef();
157 break;
158 case SUBTOTAL_FUNC_VAR:
159 case SUBTOTAL_FUNC_STD:
160 if (maWelford.getCount() < 2)
161 mbError = true;
162 else
164 fRet = maWelford.getVarianceSample();
165 if (fRet < 0.0)
166 mbError = true;
167 else if (meFunc == SUBTOTAL_FUNC_STD)
168 fRet = sqrt(fRet);
170 break;
171 case SUBTOTAL_FUNC_VARP:
172 case SUBTOTAL_FUNC_STDP:
173 if (maWelford.getCount() < 1)
174 mbError = true;
175 else if (maWelford.getCount() == 1)
176 fRet = 0.0;
177 else
179 fRet = maWelford.getVariancePopulation();
180 if (fRet < 0.0)
181 mbError = true;
182 else if (meFunc == SUBTOTAL_FUNC_STDP)
183 fRet = sqrt(fRet);
185 break;
186 default:
187 assert(!"unhandled unknown");
188 mbError = true;
189 break;
191 if (mbError)
192 fRet = 0.0;
193 return fRet;
196 void WelfordRunner::update(double fVal)
198 ++mnCount;
199 const double fDelta = fVal - mfMean;
200 mfMean += fDelta / mnCount;
201 mfM2 += fDelta * (fVal - mfMean);
204 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */