11832Swollman/*- 21832Swollman * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG> 31832Swollman * All rights reserved. 41832Swollman * 51832Swollman * Redistribution and use in source and binary forms, with or without 61832Swollman * modification, are permitted provided that the following conditions 71832Swollman * are met: 81832Swollman * 1. Redistributions of source code must retain the above copyright 91832Swollman * notice, this list of conditions and the following disclaimer. 101832Swollman * 2. Redistributions in binary form must reproduce the above copyright 111832Swollman * notice, this list of conditions and the following disclaimer in the 121832Swollman * documentation and/or other materials provided with the distribution. 131832Swollman * 141832Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 151832Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 161832Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171832Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 181832Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191832Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 201832Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211832Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221832Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231832Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 241832Swollman * SUCH DAMAGE. 251832Swollman */ 261832Swollman 271832Swollman#include "namespace.h" 281832Swollman 291832Swollman#include <sys/cdefs.h> 301832Swollman#include <limits.h> 311832Swollman#include <fenv.h> 321832Swollman#include <math.h> 331832Swollman 341832Swollman#ifndef stype 351832Swollman#ifdef __FreeBSD__ 361832Swollman__FBSDID("$FreeBSD: head/lib/msun/src/s_lround.c 144770 2005-04-08 00:52:16Z das $"); 371832Swollman#else 381832Swollman__RCSID("$NetBSD: s_lround.c,v 1.1 2017/05/06 18:03:24 christos Exp $"); 391832Swollman#endif 401832Swollman#define stype double 411832Swollman#define roundit round 421832Swollman#define dtype long 431832Swollman#define DTYPE_MIN LONG_MIN 44114629Sobrien#define DTYPE_MAX LONG_MAX 45114629Sobrien#define fn lround 461832Swollman#endif 471832Swollman 481832Swollman/* 491832Swollman * If stype has more precision than dtype, the endpoints dtype_(min|max) are 501832Swollman * of the form xxx.5; they are "out of range" because lround() rounds away 511832Swollman * from 0. On the other hand, if stype has less precision than dtype, then 521832Swollman * all values that are out of range are integral, so we might as well assume 531832Swollman * that everything is in range. At compile time, INRANGE(x) should reduce to 541832Swollman * two floating-point comparisons in the former case, or TRUE otherwise. 551832Swollman */ 561832Swollmanstatic const stype dtype_min = DTYPE_MIN - 0.5; 571832Swollmanstatic const stype dtype_max = DTYPE_MAX + 0.5; 581832Swollman#define INRANGE(x) (dtype_max - DTYPE_MAX != 0.5 || \ 591832Swollman ((x) > dtype_min && (x) < dtype_max)) 601832Swollman 611832Swollmandtype 621832Swollmanfn(stype x) 631832Swollman{ 641832Swollman 651832Swollman if (INRANGE(x)) { 661832Swollman x = roundit(x); 671832Swollman return ((dtype)x); 681832Swollman } else { 691832Swollman feraiseexcept(FE_INVALID); 701832Swollman return (DTYPE_MAX); 711832Swollman } 721832Swollman} 731832Swollman