diff options
author | Martin Möhrmann <moehrmann@google.com> | 2017-02-25 23:50:56 +0100 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2017-03-15 22:45:17 +0000 |
commit | 16200c73331a679b43efc4699b5806c64a556f09 (patch) | |
tree | 652e78ca9384630ac9411ec6446d9cdaea397fb6 /test/cmplxdivide.c | |
parent | 4b8f41daa63154949104d27d70acc3857a0b4b0b (diff) | |
download | go-16200c73331a679b43efc4699b5806c64a556f09.tar.gz go-16200c73331a679b43efc4699b5806c64a556f09.zip |
runtime: make complex division c99 compatible
- changes tests to check that the real and imaginary part of the go complex
division result is equal to the result gcc produces for c99
- changes complex division code to satisfy new complex division test
- adds float functions isNan, isFinite, isInf, abs and copysign
in the runtime package
Fixes #14644.
name old time/op new time/op delta
Complex128DivNormal-4 21.8ns ± 6% 13.9ns ± 6% -36.37% (p=0.000 n=20+20)
Complex128DivNisNaN-4 14.1ns ± 1% 15.0ns ± 1% +5.86% (p=0.000 n=20+19)
Complex128DivDisNaN-4 12.5ns ± 1% 16.7ns ± 1% +33.79% (p=0.000 n=19+20)
Complex128DivNisInf-4 10.1ns ± 1% 13.0ns ± 1% +28.25% (p=0.000 n=20+19)
Complex128DivDisInf-4 11.0ns ± 1% 20.9ns ± 1% +90.69% (p=0.000 n=16+19)
ComplexAlgMap-4 86.7ns ± 1% 86.8ns ± 2% ~ (p=0.804 n=20+20)
Change-Id: I261f3b4a81f6cc858bc7ff48f6fd1b39c300abf0
Reviewed-on: https://go-review.googlesource.com/37441
Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'test/cmplxdivide.c')
-rw-r--r-- | test/cmplxdivide.c | 72 |
1 files changed, 38 insertions, 34 deletions
diff --git a/test/cmplxdivide.c b/test/cmplxdivide.c index a475cc24c9..89a2868b75 100644 --- a/test/cmplxdivide.c +++ b/test/cmplxdivide.c @@ -23,50 +23,63 @@ #define nelem(x) (sizeof(x)/sizeof((x)[0])) double f[] = { - 0, - 1, - -1, - 2, + 0.0, + -0.0, + 1.0, + -1.0, + 2.0, NAN, INFINITY, -INFINITY, }; -char* -fmt(double g) -{ +char* fmt(double g) { static char buf[10][30]; static int n; char *p; - + p = buf[n++]; - if(n == 10) + if(n == 10) { n = 0; + } + sprintf(p, "%g", g); - if(strcmp(p, "-0") == 0) - strcpy(p, "negzero"); - return p; -} -int -iscnan(double complex d) -{ - return !isinf(creal(d)) && !isinf(cimag(d)) && (isnan(creal(d)) || isnan(cimag(d))); -} + if(strcmp(p, "0") == 0) { + strcpy(p, "zero"); + return p; + } + + if(strcmp(p, "-0") == 0) { + strcpy(p, "-zero"); + return p; + } -double complex zero; // attempt to hide zero division from gcc + return p; +} -int -main(void) -{ +int main(void) { int i, j, k, l; double complex n, d, q; - + printf("// skip\n"); printf("// # generated by cmplxdivide.c\n"); printf("\n"); printf("package main\n"); - printf("var tests = []Test{\n"); + printf("\n"); + printf("import \"math\"\n"); + printf("\n"); + printf("var (\n"); + printf("\tnan = math.NaN()\n"); + printf("\tinf = math.Inf(1)\n"); + printf("\tzero = 0.0\n"); + printf(")\n"); + printf("\n"); + printf("var tests = []struct {\n"); + printf("\tf, g complex128\n"); + printf("\tout complex128\n"); + printf("}{\n"); + for(i=0; i<nelem(f); i++) for(j=0; j<nelem(f); j++) for(k=0; k<nelem(f); k++) @@ -74,17 +87,8 @@ main(void) n = f[i] + f[j]*I; d = f[k] + f[l]*I; q = n/d; - - // BUG FIX. - // Gcc gets the wrong answer for NaN/0 unless both sides are NaN. - // That is, it treats (NaN+NaN*I)/0 = NaN+NaN*I (a complex NaN) - // but it then computes (1+NaN*I)/0 = Inf+NaN*I (a complex infinity). - // Since both numerators are complex NaNs, it seems that the - // results should agree in kind. Override the gcc computation in this case. - if(iscnan(n) && d == 0) - q = (NAN+NAN*I) / zero; - printf("\tTest{complex(%s, %s), complex(%s, %s), complex(%s, %s)},\n", + printf("\t{complex(%s, %s), complex(%s, %s), complex(%s, %s)},\n", fmt(creal(n)), fmt(cimag(n)), fmt(creal(d)), fmt(cimag(d)), fmt(creal(q)), fmt(cimag(q))); |