/* error_demo1.c */ #include void add(float v, float *ans); int main(int argc, char * argv[]) { float v[3]; float ans = 0.0f; int i; printf("error_demo1.c 1.0e10f*((1.0f+1.0e-7f)-1.0f) \n"); printf("only about 7 digits accuracy, power of 10 not exact \n"); v[0] = 1.0f; /* same as 1.0 double constant into float memory */ v[1] = 1.0e-7f; v[2] = -1.0f; for(i=0; i<3; i++) { ans = ans + v[i]; /* should be kept in register */ } ans = 1.0e10f * ans; printf("ans= %e \n", ans); printf("force store, break optimization, no difference here \n"); ans = 0.0f; add(v[0], &ans); add(v[1], &ans); add(v[2], &ans); ans = 1.0e10f * ans; printf("ans= %e \n\n", ans); printf("expression with float ans=%g \n", 1.0e10f*((1.0f+1.0e-7f)-1.0f)); printf("expression with double ans=%g \n\n", 1.0e10*((1.0+1.0e-7)-1.0)); printf("error_demo1.c (1.0f+0.5e-7f)+1.0f too small \n"); v[1] = 0.5e-7; ans = 0.0f; for(i=0; i<3; i++){ ans = ans + v[i]; } ans = 1.0e10f * ans; printf("ans= %e \n", ans); printf("force store, break optimization, no difference here \n"); ans = 0.0f; add(v[0], &ans); add(v[1], &ans); add(v[2], &ans); ans = 1.0e10f * ans; printf("ans= %e \n", ans); return 0; } void add(float v, float *ans) { *ans = *ans + v; }