1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
24 */
25/*
26 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
27 * Use is subject to license terms.
28 */
29
30#pragma weak __ceilf = ceilf
31#pragma weak __floorf = floorf
32
33/* INDENT OFF */
34/*
35 * ceilf(x)	return the biggest integral value (in float) below x
36 * floorf(x)	return the least integral value (in float) above x
37 *
38 * NOTE: ceilf(x) and floorf(x) return result
39 * with the same sign as x's,  including 0.0F.
40 */
41
42#include "libm.h"
43
44static const float xf[] = {
45/* ZEROF */	0.0f,
46/* ONEF */	1.0f,
47/* MONEF */	-1.0f,
48/* HUGEF */	1.0e30f,
49};
50
51#define	ZEROF	xf[0]
52#define	ONEF	xf[1]
53#define	MONEF	xf[2]
54#define	HUGEF	xf[3]
55/* INDENT ON */
56
57float
58ceilf(float x) {
59	volatile float dummy __unused;
60	int hx, k, j, ix;
61
62	hx = *(int *) &x;
63	ix = hx & ~0x80000000;
64	k = ix >> 23;
65	if (((k - 127) ^ (k - 150)) < 0) {
66		k = (1 << (150 - k)) - 1;
67		if ((k & hx) != 0)
68			dummy = HUGEF + x;	/* raise inexact */
69		j = k & (~(hx >> 31));
70		*(int *) &x = (hx + j) & ~k;
71		return (x);
72	} else if (k <= 126) {
73		dummy = HUGEF + x;
74		if (hx > 0)
75			return (ONEF);
76		else if (ix == 0)
77			return (x);
78		else
79			return (-ZEROF);
80	} else
81		/* signal invalid if x is a SNaN */
82		return (x * ONEF);		/* +0 -> *1 for Cheetah */
83}
84
85float
86floorf(float x) {
87	volatile float dummy __unused;
88	int hx, k, j, ix;
89
90	hx = *(int *) &x;
91	ix = hx & ~0x80000000;
92	k = ix >> 23;
93	if (((k - 127) ^ (k - 150)) < 0) {
94		k = (1 << (150 - k)) - 1;
95		if ((k & hx) != 0)
96			dummy = HUGEF + x;	/* raise inexact */
97		j = k & (hx >> 31);
98		*(int *) &x = (hx + j) & ~k;
99		return (x);
100	} else if (k <= 126) {
101		dummy = HUGEF + x;
102		if (hx > 0)
103			return (ZEROF);
104		else if (ix == 0)
105			return (x);
106		else
107			return (MONEF);
108	} else
109		/* signal invalid if x is a SNaN */
110		return (x * ONEF);		/* +0 -> *1 for Cheetah */
111}
112