19428e108SDavid Schultz /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 35e53a4f9SPedro F. Giffuni * 49428e108SDavid Schultz * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> 59428e108SDavid Schultz * All rights reserved. 69428e108SDavid Schultz * 79428e108SDavid Schultz * Redistribution and use in source and binary forms, with or without 89428e108SDavid Schultz * modification, are permitted provided that the following conditions 99428e108SDavid Schultz * are met: 109428e108SDavid Schultz * 1. Redistributions of source code must retain the above copyright 119428e108SDavid Schultz * notice, this list of conditions and the following disclaimer. 129428e108SDavid Schultz * 2. Redistributions in binary form must reproduce the above copyright 139428e108SDavid Schultz * notice, this list of conditions and the following disclaimer in the 149428e108SDavid Schultz * documentation and/or other materials provided with the distribution. 159428e108SDavid Schultz * 169428e108SDavid Schultz * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 179428e108SDavid Schultz * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 189428e108SDavid Schultz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 199428e108SDavid Schultz * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 209428e108SDavid Schultz * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 219428e108SDavid Schultz * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 229428e108SDavid Schultz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 239428e108SDavid Schultz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 249428e108SDavid Schultz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 259428e108SDavid Schultz * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 269428e108SDavid Schultz * SUCH DAMAGE. 279428e108SDavid Schultz */ 289428e108SDavid Schultz 299428e108SDavid Schultz #include <fenv.h> 309428e108SDavid Schultz #include <math.h> 319428e108SDavid Schultz 329428e108SDavid Schultz /* 339428e108SDavid Schultz * We save and restore the floating-point environment to avoid raising 349428e108SDavid Schultz * an inexact exception. We can get away with using fesetenv() 359428e108SDavid Schultz * instead of feclearexcept()/feupdateenv() to restore the environment 369428e108SDavid Schultz * because the only exception defined for rint() is overflow, and 379428e108SDavid Schultz * rounding can't overflow as long as emax >= p. 387dbbb6ddSDavid Schultz * 397dbbb6ddSDavid Schultz * The volatile keyword is needed below because clang incorrectly assumes 407dbbb6ddSDavid Schultz * that rint won't raise any floating-point exceptions. Declaring ret volatile 417dbbb6ddSDavid Schultz * is sufficient to trick the compiler into doing the right thing. 429428e108SDavid Schultz */ 439428e108SDavid Schultz #define DECL(type, fn, rint) \ 449428e108SDavid Schultz type \ 459428e108SDavid Schultz fn(type x) \ 469428e108SDavid Schultz { \ 477dbbb6ddSDavid Schultz volatile type ret; \ 489428e108SDavid Schultz fenv_t env; \ 499428e108SDavid Schultz \ 509428e108SDavid Schultz fegetenv(&env); \ 519428e108SDavid Schultz ret = rint(x); \ 529428e108SDavid Schultz fesetenv(&env); \ 539428e108SDavid Schultz return (ret); \ 549428e108SDavid Schultz } 559428e108SDavid Schultz 569428e108SDavid Schultz DECL(double, nearbyint, rint) 579428e108SDavid Schultz DECL(float, nearbyintf, rintf) 58d3f9671aSDavid Schultz DECL(long double, nearbyintl, rintl) 59