25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * CDDL HEADER START
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * The contents of this file are subject to the terms of the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Common Development and Distribution License (the "License").
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * You may not use this file except in compliance with the License.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * or http://www.opensolaris.org/os/licensing.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * See the License for the specific language governing permissions
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * and limitations under the License.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * CDDL HEADER END
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Use is subject to license terms.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#pragma weak frexp = __frexp
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * frexp(x, exp) returns the normalized significand of x and sets
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * *exp so that x = r*2^(*exp) where r is the return value. If x
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * is finite and nonzero, 1/2 <= |r| < 1.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * If x is zero, infinite or NaN, frexp returns x and sets *exp = 0.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * (The relevant standards do not specify *exp when x is infinite or
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * NaN, but this code sets it anyway.)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * If x is a signaling NaN, this code returns x without attempting
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * to raise the invalid operation exception. If x is subnormal,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * this code treats it as nonzero regardless of nonstandard mode.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include "libm.h"
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisdouble
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis__frexp(double x, int *exp) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis union {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis unsigned i[2];
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis double d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } xx, yy;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis double t;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis unsigned hx;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis int e;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis xx.d = x;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis hx = xx.i[HIWORD] & ~0x80000000;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (hx >= 0x7ff00000) { /* x is infinite or NaN */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *exp = 0;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (x);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis e = 0;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (hx < 0x00100000) { /* x is subnormal or zero */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((hx | xx.i[LOWORD]) == 0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *exp = 0;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (x);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * normalize x by regarding it as an integer
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Here we use 32-bit integer arithmetic to avoid trapping
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * or emulating 64-bit arithmetic. If 64-bit arithmetic is
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * available (e.g., in SPARC V9), do this instead:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * long lx = ((long) hx << 32) | xx.i[LOWORD];
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * xx.d = (xx.i[HIWORD] < 0)? -lx : lx;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * If subnormal arithmetic doesn't trap, just multiply x by
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * a power of two.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis yy.i[HIWORD] = 0x43300000 | hx;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis yy.i[LOWORD] = xx.i[LOWORD];
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis t = yy.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis yy.i[HIWORD] = 0x43300000;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis yy.i[LOWORD] = 0;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis t -= yy.d; /* t = |x| scaled */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis xx.d = ((int)xx.i[HIWORD] < 0)? -t : t;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis hx = xx.i[HIWORD] & ~0x80000000;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis e = -1074;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* now xx.d is normal */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis xx.i[HIWORD] = (xx.i[HIWORD] & ~0x7ff00000) | 0x3fe00000;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *exp = e + (hx >> 20) - 0x3fe;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (xx.d);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis}