1 /*-------------------------------------------------------------------------
2 * drawElements Base Portability Library
3 * -------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Basic mathematical operations.
22 *//*--------------------------------------------------------------------*/
26 #if (DE_COMPILER == DE_COMPILER_MSC)
30 #if (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
34 deRoundingMode deGetRoundingMode (void)
36 #if (DE_COMPILER == DE_COMPILER_MSC)
37 unsigned int status = 0;
40 ret = _controlfp_s(&status, 0, 0);
43 switch (status & _MCW_RC)
45 case _RC_CHOP: return DE_ROUNDINGMODE_TO_ZERO;
46 case _RC_UP: return DE_ROUNDINGMODE_TO_POSITIVE_INF;
47 case _RC_DOWN: return DE_ROUNDINGMODE_TO_NEGATIVE_INF;
48 case _RC_NEAR: return DE_ROUNDINGMODE_TO_NEAREST;
49 default: return DE_ROUNDINGMODE_LAST;
51 #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
52 int mode = fegetround();
55 case FE_TOWARDZERO: return DE_ROUNDINGMODE_TO_ZERO;
56 case FE_UPWARD: return DE_ROUNDINGMODE_TO_POSITIVE_INF;
57 case FE_DOWNWARD: return DE_ROUNDINGMODE_TO_NEGATIVE_INF;
58 case FE_TONEAREST: return DE_ROUNDINGMODE_TO_NEAREST;
59 default: return DE_ROUNDINGMODE_LAST;
62 # error Implement deGetRoundingMode().
66 deBool deSetRoundingMode (deRoundingMode mode)
68 #if (DE_COMPILER == DE_COMPILER_MSC)
69 unsigned int flag = 0;
70 unsigned int oldState;
75 case DE_ROUNDINGMODE_TO_ZERO: flag = _RC_CHOP; break;
76 case DE_ROUNDINGMODE_TO_POSITIVE_INF: flag = _RC_UP; break;
77 case DE_ROUNDINGMODE_TO_NEGATIVE_INF: flag = _RC_DOWN; break;
78 case DE_ROUNDINGMODE_TO_NEAREST: flag = _RC_NEAR; break;
83 ret = _controlfp_s(&oldState, flag, _MCW_RC);
85 #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
91 case DE_ROUNDINGMODE_TO_ZERO: flag = FE_TOWARDZERO; break;
92 case DE_ROUNDINGMODE_TO_POSITIVE_INF: flag = FE_UPWARD; break;
93 case DE_ROUNDINGMODE_TO_NEGATIVE_INF: flag = FE_DOWNWARD; break;
94 case DE_ROUNDINGMODE_TO_NEAREST: flag = FE_TONEAREST; break;
99 ret = fesetround(flag);
102 # error Implement deSetRoundingMode().
106 double deFractExp (double x, int* exponent)
116 double fract = frexp(x, &tmpExp);
117 *exponent = tmpExp - 1;
122 /* We could use frexpf, if available. */
123 float deFloatFractExp (float x, int* exponent)
125 return (float)deFractExp(x, exponent);
128 double deRoundEven (double a)
131 double fract = modf(a, &integer);
132 if (fabs(fract) == 0.5)
133 return 2.0 * deRound(a / 2.0);