def wrapper(context, builder, sig, args): [typ] = sig.args [value] = args z = context.make_complex(builder, typ, value=value) x = z.real y = z.imag # Same as above: math.isfinite() is unavailable on 2.x so we precompute # its value and pass it to the pure Python implementation. x_is_finite = mathimpl.is_finite(builder, x) y_is_finite = mathimpl.is_finite(builder, y) inner_sig = signature(sig.return_type, *(typ.underlying_float,) * 2 + (types.boolean,) * 2) res = context.compile_internal(builder, inner_func, inner_sig, (x, y, x_is_finite, y_is_finite)) return impl_ret_untracked(context, builder, sig, res)
def rect_impl(context, builder, sig, args): [r, phi] = args # We can't call math.isfinite() inside rect() below because it # only exists on 3.2+. phi_is_finite = mathimpl.is_finite(builder, phi) def rect(r, phi, phi_is_finite): if not phi_is_finite: if not r: # cmath.rect(0, phi={inf, nan}) = 0 return abs(r) if math.isinf(r): # cmath.rect(inf, phi={inf, nan}) = inf + j phi return complex(r, phi) real = math.cos(phi) imag = math.sin(phi) if real == 0. and math.isinf(r): # 0 * inf would return NaN, we want to keep 0 but xor the sign real /= r else: real *= r if imag == 0. and math.isinf(r): # ditto imag /= r else: imag *= r return complex(real, imag) inner_sig = signature(sig.return_type, *sig.args + (types.boolean, )) res = context.compile_internal(builder, rect, inner_sig, args + [phi_is_finite]) return impl_ret_untracked(context, builder, sig, res)
def is_finite(builder, z): return builder.and_(mathimpl.is_finite(builder, z.real), mathimpl.is_finite(builder, z.imag))