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  }