# 浮点乘法对重复添加[英] floating point multiplication vs repeated addition

### 问题描述

GCC可以优化

```unsigned sum = 0;
for(unsigned i=0; i<N; i++) sum += a; // a is an unsigned integer
```

```float sum = 0;
for(unsigned i=0; i<N; i++) sum += a;  // a is a float
```

to a*(float)N.

```sum = a + a
sum = sum + sum // (a + a) + (a + a)
sum = sum + sum // ((a + a) + (a + a)) + ((a + a) + (a + a))
```

```//gcc -O3 foo.c
//don't use -Ofast or -ffast-math or -fassociative-math
#include <stdio.h>
float sumf(float a, int n)
{
float sum = 0;
for(int i=0; i<n; i++) sum += a;
return sum;
}

float sumf_kahan(float a, int n)
{
float sum = 0;
float c = 0;
for(int i=0; i<n; i++) {
float y = a - c;
float t = sum + y;
c = (t -sum) - y;
sum = t;
}
return sum;
}

float mulf(float a, int n)
{
return a*n;
}

int main(void)
{
int n = 1<<24;
float a = 3.14159;
float t1 = sumf(a,n);
float t2 = sumf_kahan(a,n);
float t3 = mulf(a,n);
printf("%f %f %f\n",t1,t2,t3);
}
```

## 推荐答案

``` float funct( int N, float sum )
{
float value = 10.0;
for( i = 0; i < N ;i ++ ) {
sum += value;
}
return sum;
}
```

```float funct( int N, float sum )
{
float value = 10.0;
sum += value * N;
return sum;
}
```