1143213Sdas/*- 2143213Sdas * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG> 3143213Sdas * All rights reserved. 4143213Sdas * 5143213Sdas * Redistribution and use in source and binary forms, with or without 6143213Sdas * modification, are permitted provided that the following conditions 7143213Sdas * are met: 8143213Sdas * 1. Redistributions of source code must retain the above copyright 9143213Sdas * notice, this list of conditions and the following disclaimer. 10143213Sdas * 2. Redistributions in binary form must reproduce the above copyright 11143213Sdas * notice, this list of conditions and the following disclaimer in the 12143213Sdas * documentation and/or other materials provided with the distribution. 13143213Sdas * 14143213Sdas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15143213Sdas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16143213Sdas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17143213Sdas * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18143213Sdas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19143213Sdas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20143213Sdas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21143213Sdas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22143213Sdas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23143213Sdas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24143213Sdas * SUCH DAMAGE. 25143213Sdas * 26143213Sdas * $FreeBSD$ 27143213Sdas */ 28143213Sdas 29143213Sdas#include <float.h> 30143213Sdas#include <math.h> 31143213Sdas 32143213Sdas#include "fpmath.h" 33143213Sdas 34143213Sdas#if LDBL_MAX_EXP != 0x4000 35143213Sdas#error "Unsupported long double format" 36143213Sdas#endif 37143213Sdas 38143213Sdaslong double 39143213Sdasfrexpl(long double x, int *ex) 40143213Sdas{ 41143213Sdas union IEEEl2bits u; 42143213Sdas 43143213Sdas u.e = x; 44143213Sdas switch (u.bits.exp) { 45143213Sdas case 0: /* 0 or subnormal */ 46143213Sdas if ((u.bits.manl | u.bits.manh) == 0) { 47143213Sdas *ex = 0; 48143213Sdas } else { 49143213Sdas u.e *= 0x1.0p514; 50143213Sdas *ex = u.bits.exp - 0x4200; 51143213Sdas u.bits.exp = 0x3ffe; 52143213Sdas } 53143213Sdas break; 54143213Sdas case 0x7fff: /* infinity or NaN; value of *ex is unspecified */ 55143213Sdas break; 56143213Sdas default: /* normal */ 57143213Sdas *ex = u.bits.exp - 0x3ffe; 58143213Sdas u.bits.exp = 0x3ffe; 59143213Sdas break; 60143213Sdas } 61143213Sdas return (u.e); 62143213Sdas} 63