#include <stdio.h>
#include <stdint.h>
#include <math.h>
/* use FMA as correction*/
float foo1(float a, float k, float *res)
{
float ret=(a-k)/(a+k);
*res = fmaf(-ret,a+k,a-k)/(a+k);
return ret;
}
/* do double precision quote, divide the double precision quote two two floats*/
float foo2(float a, float k, float *res)
{
double rD=(double)(a-k)/(a+k);
float ret =rD;
*res = rD - ret;
return ret;
}
/* naive method*/
float fooFloat(float a, float k)
{
return (a-k)/(a+k);
}
/*reference*/
double fooDouble(float a, float k)
{
return ((double)a-(double)k)/((double)a+(double)k);
}
int main(void) {
// your code goes here
float res1, res2;
float a=1024*96/97.0f;
float b =1024.0f;
float ret1 = foo1(a, b, &res1);
float ret2 = foo2(a, b, &res2);
"diff_foo1 = %.40f\n"
"diff_foo2 = %0.40f\n\n",
fooDouble(a,b)-fooFloat(a, b),
fooDouble(a,b)-((double)(ret1)+(double)(res1)),
fooDouble(a,b)-((double)(ret2)+(double)(res2)));
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRpbnQuaD4KI2luY2x1ZGUgPG1hdGguaD4KLyogdXNlIEZNQSBhcyBjb3JyZWN0aW9uKi8KZmxvYXQgZm9vMShmbG9hdCBhLCBmbG9hdCBrLCBmbG9hdCAqcmVzKQp7CglmbG9hdCByZXQ9KGEtaykvKGErayk7CgkqcmVzID0gZm1hZigtcmV0LGErayxhLWspLyhhK2spOwoJcmV0dXJuIHJldDsKfQovKiBkbyBkb3VibGUgcHJlY2lzaW9uIHF1b3RlLCBkaXZpZGUgdGhlIGRvdWJsZSBwcmVjaXNpb24gcXVvdGUgdHdvIHR3byBmbG9hdHMqLwpmbG9hdCBmb28yKGZsb2F0IGEsIGZsb2F0IGssIGZsb2F0ICpyZXMpCnsKCWRvdWJsZSByRD0oZG91YmxlKShhLWspLyhhK2spOwoJZmxvYXQgcmV0ID1yRDsKCSpyZXMgPSByRCAtIHJldDsKCXJldHVybiByZXQ7Cn0KLyogbmFpdmUgbWV0aG9kKi8KZmxvYXQgZm9vRmxvYXQoZmxvYXQgYSwgZmxvYXQgaykKewoJcmV0dXJuIChhLWspLyhhK2spOwp9Ci8qcmVmZXJlbmNlKi8KZG91YmxlIGZvb0RvdWJsZShmbG9hdCBhLCBmbG9hdCBrKQp7CglyZXR1cm4gKChkb3VibGUpYS0oZG91YmxlKWspLygoZG91YmxlKWErKGRvdWJsZSlrKTsKfQppbnQgbWFpbih2b2lkKSB7CgkvLyB5b3VyIGNvZGUgZ29lcyBoZXJlCglmbG9hdCByZXMxLCByZXMyOwoJZmxvYXQgYT0xMDI0Kjk2Lzk3LjBmOwoJZmxvYXQgYiA9MTAyNC4wZjsKCWZsb2F0IHJldDEgPSBmb28xKGEsIGIsICZyZXMxKTsKCWZsb2F0IHJldDIgPSBmb28yKGEsIGIsICZyZXMyKTsKCQoJcHJpbnRmKCJkaWZmX2Zsb2F0ID0gJS40MGZcbiIKCSAgICAgICAiZGlmZl9mb28xICA9ICUuNDBmXG4iCgkgICAgICAgICJkaWZmX2ZvbzIgID0gJTAuNDBmXG5cbiIsCgkgICAgICAgIGZvb0RvdWJsZShhLGIpLWZvb0Zsb2F0KGEsIGIpLAoJICAgICAgICBmb29Eb3VibGUoYSxiKS0oKGRvdWJsZSkocmV0MSkrKGRvdWJsZSkocmVzMSkpLAoJICAgICAgICBmb29Eb3VibGUoYSxiKS0oKGRvdWJsZSkocmV0MikrKGRvdWJsZSkocmVzMikpKTsKCXJldHVybiAwOwp9Cg==