| Elliott Hughes | 90e10d4 | 2012-11-02 17:05:20 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2012 The Android Open Source Project | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
 | 16 |  | 
 | 17 | #include <gtest/gtest.h> | 
 | 18 |  | 
 | 19 | #include <fenv.h> | 
 | 20 | #include <stdint.h> | 
 | 21 |  | 
 | 22 | static void TestRounding(float expectation1, float expectation2) { | 
 | 23 |   // volatile to prevent compiler optimizations. | 
 | 24 |   volatile float f = 1.968750f; | 
 | 25 |   volatile float m = 0x1.0p23f; | 
 | 26 |   volatile float x = f + m; | 
 | 27 |   ASSERT_FLOAT_EQ(expectation1, x); | 
 | 28 |   x -= m; | 
 | 29 |   ASSERT_EQ(expectation2, x); | 
 | 30 | } | 
 | 31 |  | 
 | 32 | static void DivideByZero() { | 
 | 33 |   // volatile to prevent compiler optimizations. | 
 | 34 |   volatile float zero = 0.0f; | 
 | 35 |   volatile float result __attribute__((unused)) = 123.0f / zero; | 
 | 36 | } | 
 | 37 |  | 
 | 38 | TEST(fenv, fesetround_fegetround_FE_TONEAREST) { | 
 | 39 |   fesetround(FE_TONEAREST); | 
 | 40 |   ASSERT_EQ(FE_TONEAREST, fegetround()); | 
 | 41 |   TestRounding(8388610.0f, 2.0f); | 
 | 42 | } | 
 | 43 |  | 
 | 44 | TEST(fenv, fesetround_fegetround_FE_TOWARDZERO) { | 
 | 45 |   fesetround(FE_TOWARDZERO); | 
 | 46 |   ASSERT_EQ(FE_TOWARDZERO, fegetround()); | 
 | 47 |   TestRounding(8388609.0f, 1.0f); | 
 | 48 | } | 
 | 49 |  | 
 | 50 | TEST(fenv, fesetround_fegetround_FE_UPWARD) { | 
 | 51 |   fesetround(FE_UPWARD); | 
 | 52 |   ASSERT_EQ(FE_UPWARD, fegetround()); | 
 | 53 |   TestRounding(8388610.0f, 2.0f); | 
 | 54 | } | 
 | 55 |  | 
 | 56 | TEST(fenv, fesetround_fegetround_FE_DOWNWARD) { | 
 | 57 |   fesetround(FE_DOWNWARD); | 
 | 58 |   ASSERT_EQ(FE_DOWNWARD, fegetround()); | 
 | 59 |   TestRounding(8388609.0f, 1.0f); | 
 | 60 | } | 
 | 61 |  | 
 | 62 | TEST(fenv, feclearexcept_fetestexcept) { | 
 | 63 |   // Clearing clears. | 
 | 64 |   feclearexcept(FE_ALL_EXCEPT); | 
 | 65 |   ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT)); | 
 | 66 |  | 
 | 67 |   // Dividing by zero sets FE_DIVBYZERO. | 
 | 68 |   DivideByZero(); | 
 | 69 |   int raised = fetestexcept(FE_DIVBYZERO | FE_OVERFLOW); | 
 | 70 |   ASSERT_TRUE((raised & FE_OVERFLOW) == 0); | 
 | 71 |   ASSERT_TRUE((raised & FE_DIVBYZERO) != 0); | 
 | 72 |  | 
 | 73 |   // Clearing an unset bit is a no-op. | 
 | 74 |   feclearexcept(FE_OVERFLOW); | 
 | 75 |   ASSERT_TRUE((raised & FE_OVERFLOW) == 0); | 
 | 76 |   ASSERT_TRUE((raised & FE_DIVBYZERO) != 0); | 
 | 77 |  | 
 | 78 |   // Clearing a set bit works. | 
 | 79 |   feclearexcept(FE_DIVBYZERO); | 
 | 80 |   ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT)); | 
 | 81 | } | 
| Elliott Hughes | a0ee078 | 2013-01-30 19:06:37 -0800 | [diff] [blame] | 82 |  | 
 | 83 | TEST(fenv, FE_DFL_ENV_macro) { | 
 | 84 |   ASSERT_EQ(0, fesetenv(FE_DFL_ENV)); | 
 | 85 | } |