github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/runtime/complex.c (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include "runtime.h" 6 7 typedef struct Complex128 Complex128; 8 9 void 10 runtime·complex128div(Complex128 n, Complex128 d, Complex128 q) 11 { 12 int32 ninf, dinf, nnan, dnan; 13 float64 a, b, ratio, denom; 14 15 // Special cases as in C99. 16 ninf = n.real == runtime·posinf || n.real == runtime·neginf || 17 n.imag == runtime·posinf || n.imag == runtime·neginf; 18 dinf = d.real == runtime·posinf || d.real == runtime·neginf || 19 d.imag == runtime·posinf || d.imag == runtime·neginf; 20 21 nnan = !ninf && (ISNAN(n.real) || ISNAN(n.imag)); 22 dnan = !dinf && (ISNAN(d.real) || ISNAN(d.imag)); 23 24 if(nnan || dnan) { 25 q.real = runtime·nan; 26 q.imag = runtime·nan; 27 } else if(ninf && !dinf) { 28 q.real = runtime·posinf; 29 q.imag = runtime·posinf; 30 } else if(!ninf && dinf) { 31 q.real = 0; 32 q.imag = 0; 33 } else if(d.real == 0 && d.imag == 0) { 34 if(n.real == 0 && n.imag == 0) { 35 q.real = runtime·nan; 36 q.imag = runtime·nan; 37 } else { 38 q.real = runtime·posinf; 39 q.imag = runtime·posinf; 40 } 41 } else { 42 // Standard complex arithmetic, factored to avoid unnecessary overflow. 43 a = d.real; 44 if(a < 0) 45 a = -a; 46 b = d.imag; 47 if(b < 0) 48 b = -b; 49 if(a <= b) { 50 ratio = d.real/d.imag; 51 denom = d.real*ratio + d.imag; 52 q.real = (n.real*ratio + n.imag) / denom; 53 q.imag = (n.imag*ratio - n.real) / denom; 54 } else { 55 ratio = d.imag/d.real; 56 denom = d.imag*ratio + d.real; 57 q.real = (n.imag*ratio + n.real) / denom; 58 q.imag = (n.imag - n.real*ratio) / denom; 59 } 60 } 61 FLUSH(&q); 62 }