Exemple #1
0
void
bn_cx_sqrt(bn_complex_t *op, const bn_complex_t *ip)
{
    const fastf_t re = ip->re;
    const fastf_t im = ip->im;

    /* special cases are not necessary; they are here for speed */
    if (ZERO(re)) {
	if (ZERO(im)) {
	    op->re = op->im = 0.0;
	} else if (im > 0.0) {
	    op->re = op->im = sqrt(im * 0.5);
	} else {
	    /* ip->im < 0.0 */
	    op->re = -(op->im = sqrt(im * -0.5));
	}
    } else if (ZERO(im)) {
	if (re > 0.0) {
	    op->re = sqrt(re);
	    op->im = 0.0;
	} else {
	    /* ip->re < 0.0 */
	    op->im = sqrt(-re);
	    op->re = 0.0;
	}
    } else {
	fastf_t ampl, temp;

	/* no shortcuts */
	ampl = bn_cx_ampl(ip);
	if ((temp = (ampl - re) * 0.5) < 0.0) {
	    /* This case happens rather often, when the hypot() in
	     * bn_cx_ampl() returns an ampl ever so slightly smaller
	     * than ip->re.  This can easily happen when ip->re ~=
	     * 10**20.  Just ignore the imaginary part.
	     */
	    op->im = 0.0;
	} else {
	    op->im = sqrt(temp);
	}

	if ((temp = (ampl + re) * 0.5) < 0.0) {
	    op->re = 0.0;
	} else {
	    if (im > 0.0) {
		op->re = sqrt(temp);
	    } else {
		/* ip->im < 0.0 */
		op->re = -sqrt(temp);
	    }
	}
    }
}
Exemple #2
0
/**
 *			B N _ C X _ S Q R T
 *@brief
 *  Compute square root of complex number
 *
 *	bn_cx_sqrt( &out, &c )	replaces  out  by  sqrt(c)
 *
 *	Note:	This is a double-valued function; the result of
 *		bn_cx_sqrt() always has nonnegative imaginary part.
 */
void
bn_cx_sqrt(bn_complex_t *op, register const bn_complex_t *ip)
{
    register fastf_t	ampl, temp;
    /* record signs of original real & imaginary parts */
    register int	re_sign;
    register int	im_sign;

    /* special cases are not necessary; they are here for speed */
    im_sign = SIGN( ip->im );
    if ( (re_sign = SIGN(ip->re))  == 0 )  {
	if ( im_sign == 0 )
	    op->re = op->im = 0;
	else if ( im_sign > 0 )
	    op->re = op->im = sqrt( ip->im * 0.5 );
	else			/* im_sign < 0 */
	    op->re = -(op->im = sqrt( ip->im * -0.5 ));
    } else if ( im_sign == 0 )  {
	if ( re_sign > 0 )  {
	    op->re = sqrt( ip->re );
	    op->im = 0.0;
	}  else  {
	    /* re_sign < 0 */
	    op->im = sqrt( -ip->re );
	    op->re = 0.0;
	}
    }  else  {
	/* no shortcuts */
	ampl = bn_cx_ampl( ip );
	if ( (temp = (ampl - ip->re) * 0.5) < 0.0 )  {
	    /* This case happens rather often, when the
	     *  hypot() in bn_cx_ampl() returns an ampl ever so
	     *  slightly smaller than ip->re.  This can easily
	     *  happen when ip->re ~= 10**20.
	     *  Just ignore the imaginary part.
	     */
	    op->im = 0;
	} else
	    op->im = sqrt( temp );

	if ( (temp = (ampl + ip->re) * 0.5) < 0.0 )  {
	    op->re = 0.0;
	} else {
	    if ( im_sign > 0 )
		op->re = sqrt(temp);
	    else			/* im_sign < 0 */
		op->re = -sqrt(temp);
	}
    }
}