float SDot(int n, const float *sx, const float *sy) { double_t sum = 0.0; if (n > 0) { // skip empty vectors for (int i = 0; i < n % 5; i++) sum += (double_t) *sx++ * *sy++; for (int i = 0; i < n / 5; i++) { sum += (double_t) *sx++ * *sy++; sum += (double_t) *sx++ * *sy++; sum += (double_t) *sx++ * *sy++; sum += (double_t) *sx++ * *sy++; sum += (double_t) *sx++ * *sy++; } } return sum; }
A key feature of the function is the type cast in the inner loop:
NOTE
Opinions differ regarding the "right way" for compilers to treat mixed-format expressions; the various standards leave the issue open. Casting is a portable technique to ensure that a narrow innermost expression is evaluated to a wider type.
On CommonPoint platforms with processors from the PowerPC and X86 families, which evaluate all expressions to double_t, the cast has no effect. However, on platforms such as PA-RISC, with orthogonal sets of instructions for each floating-point type, the product sum += (double_t) *sx++ * *sy++;
*sx++
*
*sy++
is evaluated in the float format without the cast, sacrificing some accuracy and protection against overflow and underflow.
[Contents]
[Previous]
[Next]
Click the icon to mail questions or corrections about this material to Taligent personnel.