1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
15 #include <formula/errorcodes.hxx>
20 * If no boosts available, Unrolled KahanSum.
22 static inline KahanSum
executeUnrolled(size_t& i
, size_t nSize
, const double* pCurrent
)
24 size_t nRealSize
= nSize
- i
;
25 size_t nUnrolledSize
= nRealSize
- (nRealSize
% 4);
27 if (nUnrolledSize
> 0)
34 for (; i
+ 3 < nUnrolledSize
; i
+= 4)
41 // We are using pairwise summation alongside Kahan
42 return (sum0
+ sum1
) + (sum2
+ sum3
);
48 * This function task is to choose the fastest method available to perform the sum.
53 static inline KahanSum
executeFast(size_t& i
, size_t nSize
, const double* pCurrent
)
56 return executeSSE2(i
, nSize
, pCurrent
);
58 return executeUnrolled(i
, nSize
, pCurrent
);
63 * Performs the sum of an array.
64 * Note that align 16 will speed up the process.
68 inline KahanSum
sumArray(const double* pArray
, size_t nSize
)
71 const double* pCurrent
= pArray
;
72 KahanSum fSum
= executeFast(i
, nSize
, pCurrent
);
74 // sum rest of the array
75 for (; i
< nSize
; ++i
)
78 // If the sum is a NaN, some of the terms were empty cells, probably.
79 // Re-calculate, carefully
80 double fVal
= fSum
.get();
81 if (!std::isfinite(fVal
))
83 FormulaError nErr
= GetDoubleErrorValue(fVal
);
84 if (nErr
== FormulaError::NoValue
)
87 for (i
= 0; i
< nSize
; i
++)
89 if (!std::isfinite(pArray
[i
]))
91 nErr
= GetDoubleErrorValue(pArray
[i
]);
92 if (nErr
!= FormulaError::NoValue
)
93 fSum
+= pArray
[i
]; // Let errors encoded as NaNs propagate ???
103 } // end namespace sc::op
105 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */