1140088Sdas/*- 2140088Sdas * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG> 3140088Sdas * All rights reserved. 4140088Sdas * 5140088Sdas * Redistribution and use in source and binary forms, with or without 6140088Sdas * modification, are permitted provided that the following conditions 7140088Sdas * are met: 8140088Sdas * 1. Redistributions of source code must retain the above copyright 9140088Sdas * notice, this list of conditions and the following disclaimer. 10140088Sdas * 2. Redistributions in binary form must reproduce the above copyright 11140088Sdas * notice, this list of conditions and the following disclaimer in the 12140088Sdas * documentation and/or other materials provided with the distribution. 13140088Sdas * 14140088Sdas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15140088Sdas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16140088Sdas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17140088Sdas * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18140088Sdas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19140088Sdas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20140088Sdas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21140088Sdas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22140088Sdas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23140088Sdas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24140088Sdas * SUCH DAMAGE. 25140088Sdas */ 26140088Sdas 27140088Sdas#include <sys/cdefs.h> 28140088Sdas#include <fenv.h> 29140088Sdas#include <math.h> 30140088Sdas 31140088Sdas#ifndef type 32140088Sdas__FBSDID("$FreeBSD$"); 33140088Sdas#define type double 34140088Sdas#define roundit rint 35140088Sdas#define dtype long 36140088Sdas#define fn lrint 37140088Sdas#endif 38140088Sdas 39140088Sdas/* 40140088Sdas * C99 says we should not raise a spurious inexact exception when an 41140088Sdas * invalid exception is raised. Unfortunately, the set of inputs 42140088Sdas * that overflows depends on the rounding mode when 'dtype' has more 43140088Sdas * significant bits than 'type'. Hence, we bend over backwards for the 44140088Sdas * sake of correctness; an MD implementation could be more efficient. 45140088Sdas */ 46140088Sdasdtype 47140088Sdasfn(type x) 48140088Sdas{ 49140088Sdas fenv_t env; 50140088Sdas dtype d; 51140088Sdas 52140088Sdas feholdexcept(&env); 53140088Sdas d = (dtype)roundit(x); 54140088Sdas if (fetestexcept(FE_INVALID)) 55140088Sdas feclearexcept(FE_INEXACT); 56140088Sdas feupdateenv(&env); 57140088Sdas return (d); 58140088Sdas} 59