blob: 73f1161a50de5d91c257fbb1ce2f24a0ef5b7f73 [file] [log] [blame]
Keith Randallc403af82014-07-25 15:12:45 -07001// 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
5package runtime
6
Russ Cox0c3c2c12014-11-11 17:07:06 -05007func isposinf(f float64) bool { return f > maxFloat64 }
8func isneginf(f float64) bool { return f < -maxFloat64 }
9func isnan(f float64) bool { return f != f }
10
11func nan() float64 {
12 var f float64 = 0
13 return f / f
14}
15
16func posinf() float64 {
17 var f float64 = maxFloat64
18 return f * f
19}
20
21func neginf() float64 {
22 var f float64 = maxFloat64
23 return -f * f
24}
25
Keith Randallc403af82014-07-25 15:12:45 -070026func complex128div(n complex128, d complex128) complex128 {
27 // Special cases as in C99.
Russ Cox0c3c2c12014-11-11 17:07:06 -050028 ninf := isposinf(real(n)) || isneginf(real(n)) ||
29 isposinf(imag(n)) || isneginf(imag(n))
30 dinf := isposinf(real(d)) || isneginf(real(d)) ||
31 isposinf(imag(d)) || isneginf(imag(d))
Keith Randallc403af82014-07-25 15:12:45 -070032
Russ Cox0c3c2c12014-11-11 17:07:06 -050033 nnan := !ninf && (isnan(real(n)) || isnan(imag(n)))
34 dnan := !dinf && (isnan(real(d)) || isnan(imag(d)))
Keith Randallc403af82014-07-25 15:12:45 -070035
36 switch {
37 case nnan || dnan:
Russ Cox0c3c2c12014-11-11 17:07:06 -050038 return complex(nan(), nan())
Keith Randallc403af82014-07-25 15:12:45 -070039 case ninf && !dinf:
Russ Cox0c3c2c12014-11-11 17:07:06 -050040 return complex(posinf(), posinf())
Keith Randallc403af82014-07-25 15:12:45 -070041 case !ninf && dinf:
42 return complex(0, 0)
43 case real(d) == 0 && imag(d) == 0:
44 if real(n) == 0 && imag(n) == 0 {
Russ Cox0c3c2c12014-11-11 17:07:06 -050045 return complex(nan(), nan())
Keith Randallc403af82014-07-25 15:12:45 -070046 } else {
Russ Cox0c3c2c12014-11-11 17:07:06 -050047 return complex(posinf(), posinf())
Keith Randallc403af82014-07-25 15:12:45 -070048 }
49 default:
50 // Standard complex arithmetic, factored to avoid unnecessary overflow.
51 a := real(d)
52 if a < 0 {
53 a = -a
54 }
55 b := imag(d)
56 if b < 0 {
57 b = -b
58 }
59 if a <= b {
60 ratio := real(d) / imag(d)
61 denom := real(d)*ratio + imag(d)
62 return complex((real(n)*ratio+imag(n))/denom,
63 (imag(n)*ratio-real(n))/denom)
64 } else {
65 ratio := imag(d) / real(d)
66 denom := imag(d)*ratio + real(d)
67 return complex((imag(n)*ratio+real(n))/denom,
68 (imag(n)-real(n)*ratio)/denom)
69 }
70 }
71}