aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/complex.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-11-11 17:07:06 -0500
committerRuss Cox <rsc@golang.org>2014-11-11 17:07:06 -0500
commit0c3c2c17243545e9bc7c5d158c5230fe299e8b73 (patch)
treedd4e6270a830a226f66f924b8e91616dba4bc310 /src/runtime/complex.go
parent7b3ebb131f4a03c02f8f7723b26d55dd98bc702f (diff)
downloadgo-0c3c2c17243545e9bc7c5d158c5230fe299e8b73.tar.xz
[dev.cc] runtime: convert basic library routines from C to Go
float.c held bit patterns for special float64 values, hiding from the real uses. Rewrite Go code not to refer to those values directly. Convert library routines in runtime.c and string.c. LGTM=r R=r, dave CC=austin, dvyukov, golang-codereviews, iant, khr https://golang.org/cl/170330043
Diffstat (limited to 'src/runtime/complex.go')
-rw-r--r--src/runtime/complex.go39
1 files changed, 29 insertions, 10 deletions
diff --git a/src/runtime/complex.go b/src/runtime/complex.go
index ec50f89470..73f1161a50 100644
--- a/src/runtime/complex.go
+++ b/src/runtime/complex.go
@@ -4,28 +4,47 @@
package runtime
+func isposinf(f float64) bool { return f > maxFloat64 }
+func isneginf(f float64) bool { return f < -maxFloat64 }
+func isnan(f float64) bool { return f != f }
+
+func nan() float64 {
+ var f float64 = 0
+ return f / f
+}
+
+func posinf() float64 {
+ var f float64 = maxFloat64
+ return f * f
+}
+
+func neginf() float64 {
+ var f float64 = maxFloat64
+ return -f * f
+}
+
func complex128div(n complex128, d complex128) complex128 {
// Special cases as in C99.
- ninf := real(n) == posinf || real(n) == neginf ||
- imag(n) == posinf || imag(n) == neginf
- dinf := real(d) == posinf || real(d) == neginf ||
- imag(d) == posinf || imag(d) == neginf
+ ninf := isposinf(real(n)) || isneginf(real(n)) ||
+ isposinf(imag(n)) || isneginf(imag(n))
+ dinf := isposinf(real(d)) || isneginf(real(d)) ||
+ isposinf(imag(d)) || isneginf(imag(d))
- nnan := !ninf && (real(n) != real(n) || imag(n) != imag(n))
- dnan := !dinf && (real(d) != real(d) || imag(d) != imag(d))
+ nnan := !ninf && (isnan(real(n)) || isnan(imag(n)))
+ dnan := !dinf && (isnan(real(d)) || isnan(imag(d)))
switch {
case nnan || dnan:
- return complex(nan, nan)
+ return complex(nan(), nan())
case ninf && !dinf:
- return complex(posinf, posinf)
+ return complex(posinf(), posinf())
case !ninf && dinf:
return complex(0, 0)
case real(d) == 0 && imag(d) == 0:
if real(n) == 0 && imag(n) == 0 {
- return complex(nan, nan)
+ return complex(nan(), nan())
} else {
- return complex(posinf, posinf)
+ return complex(posinf(), posinf())
}
default:
// Standard complex arithmetic, factored to avoid unnecessary overflow.