s_lrint.c revision 330897
1300113Sscottl/*-
2300113Sscottl * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3300113Sscottl *
4300113Sscottl * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
5300113Sscottl * All rights reserved.
6300113Sscottl *
7300113Sscottl * Redistribution and use in source and binary forms, with or without
8300113Sscottl * modification, are permitted provided that the following conditions
9300113Sscottl * are met:
10300113Sscottl * 1. Redistributions of source code must retain the above copyright
11300113Sscottl *    notice, this list of conditions and the following disclaimer.
12300113Sscottl * 2. Redistributions in binary form must reproduce the above copyright
13300113Sscottl *    notice, this list of conditions and the following disclaimer in the
14300113Sscottl *    documentation and/or other materials provided with the distribution.
15300113Sscottl *
16300113Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17300113Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18300113Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19300113Sscottl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20300113Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21300113Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22300113Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23300113Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24300113Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25300113Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26300113Sscottl * SUCH DAMAGE.
27300113Sscottl */
28300113Sscottl
29300113Sscottl#include <sys/cdefs.h>
30300113Sscottl#include <fenv.h>
31300113Sscottl#include <math.h>
32300113Sscottl
33300113Sscottl#ifndef type
34300113Sscottl__FBSDID("$FreeBSD: stable/11/lib/msun/src/s_lrint.c 330897 2018-03-14 03:19:51Z eadler $");
35300113Sscottl#define type		double
36300113Sscottl#define	roundit		rint
37300113Sscottl#define dtype		long
38300113Sscottl#define	fn		lrint
39300113Sscottl#endif
40300113Sscottl
41300113Sscottl/*
42300113Sscottl * C99 says we should not raise a spurious inexact exception when an
43300113Sscottl * invalid exception is raised.  Unfortunately, the set of inputs
44300113Sscottl * that overflows depends on the rounding mode when 'dtype' has more
45300113Sscottl * significant bits than 'type'.  Hence, we bend over backwards for the
46300113Sscottl * sake of correctness; an MD implementation could be more efficient.
47300113Sscottl */
48300113Sscottldtype
49300113Sscottlfn(type x)
50300113Sscottl{
51300113Sscottl	fenv_t env;
52300113Sscottl	dtype d;
53300113Sscottl
54300113Sscottl	feholdexcept(&env);
55300113Sscottl	d = (dtype)roundit(x);
56300113Sscottl	if (fetestexcept(FE_INVALID))
57300113Sscottl		feclearexcept(FE_INEXACT);
58300113Sscottl	feupdateenv(&env);
59300113Sscottl	return (d);
60300113Sscottl}
61300113Sscottl