Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it better to perform n additions of a floating-point number or one integer multiplication?

Consider the two cases below:

// Case 1
double val { initial_value };
for (int i { 0 }; i < n; ++i) {
    val += step;
    foo(val);
}
// Case 2
for (int i { 0 }; i < n; ++i) {
    double val = initial_value + i * step;
    foo(val);
}

where n is the number of steps, initial_value is some given value of type double, step is some predetermined value of type double and val is a variable used in subsequent call for the function foo. Which of the cases produces less of floating-point error? My guess would be the second one, as there are only one addition and multiplication, while the first case incurs the floating-point representation error from all of the n additions. I am asking this question because I didn't know what to search for. Does there exists some good reference for cases like these?

In practice the variable val is to be used in the loop of the both cases. I didn't include any example for this as I'm only interested in the floating-point error.

like image 652
Epsilon Away Avatar asked Oct 28 '21 17:10

Epsilon Away


People also ask

Is floating-point multiplication faster than addition?

An integer multiplication always needs a "carry propagate add" step at the end. Consequently, addition is always faster because that's the final step of a multiplication. (Floating point is a little different, but not significantly so).

Is integer math faster than floating-point?

In computer systems, integer arithmetic is exact, but the possible range of values is limited. Integer arithmetic is generally faster than floating-point arithmetic. Floating-point numbers represent what were called in school “real” numbers (i.e., those that have a fractional part, such as 3.1415927).

How much faster is addition than multiplication?

Yes, according to http://www.agner.org/optimize/instruction_tables.pdf, add instruction is 3 times faster than mult instruction.

Is floating-point multiplication faster than division?

Multiplication is faster than division.


1 Answers

Considering the comment by supercat (emphasis mine):

The point is that in many scenarios one might want a sequence of values that are uniformly spaced between specified start and end points. Using the second approach would yield values that are as uniformly spaced as possible between the start point and an end value that's near a desired one, but may not quite match.

And the one by Bathsheba:

Both are flawed. You should compute the start and end, then compute each value as a function of those. The problem with the second way is you multiply the error in step. The former accumulates errors.

I'd suggest a couple of alternatives.

  • Since C++20, the Standard Library provides std::lerp where std::lerp(a, b, t) returns "the linear interpolation between a and b for the parameter t (or extrapolation, when t is outside the range [0,1])".

  • A formula like value = (a * (n - i) + b * i) / n; may result in a more uniform1 distribution of the intermediate values.

(1) Here I tried to test all those approaches for different extremes and number of sample points. The program compares the values generated by each algorithm when applied in the opposite directions (first from left to right, then from right to left). It shows the average and variance of the sum of the absolute difference between the values of the intermediate points.

Other metrics may yield different results.

like image 77
Bob__ Avatar answered Nov 14 '22 23:11

Bob__