1 /* 2 * Copyright (C) 2024 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 <cmath> 18 #include <functional> 19 20 namespace android::audio_utils::test { 21 22 /* 23 Tests for float precision. 24 25 ... w/o subnormals on an x86-64 -ffast-math -fhonor-infinities -fhonor-nans 26 27 float32 without subnormals: 28 max_exponent: 127 29 min_exponent: -126 30 mantissa: 23 31 32 float64 without subnormals: 33 max_exponent: 1023 34 min_exponent: -1022 35 mantissa: 52 36 37 ... with subnormals ARM and x86-64 normal compilation 38 39 float32 with subnormals: 40 max_exponent: 127 41 min_exponent: -149 42 mantissa: 23 43 44 float64 with subnormals: 45 max_exponent: 1023 46 min_exponent: -1074 47 mantissa: 52 48 49 */ 50 51 // This requires a functor that doubles the input. 52 template <typename D> 53 int test_max_exponent(const std::function<D(D)>& twice = [](D x) -> D { return x + x; }) { 54 D d = 1; 55 for (int i = 0; i < 16384; ++i) { 56 d = twice(d); 57 // std::cout << i << " " << d << "\n"; 58 if (std::isinf(d)) { 59 return i; 60 } 61 } 62 return 0; 63 } 64 65 // This requires a functor that halves the input. 66 template <typename D> 67 int test_min_exponent(const std::function<D(D)>& half =[](D x) { return x * 0.5; } ) { 68 D d = 1; 69 for (int i = 0; i < 16384; ++i) { 70 d = half(d); 71 // std::cout << i << " " << d << "\n"; 72 if (d == 0) { 73 return -i; 74 } 75 } 76 return 0; 77 } 78 79 // This requires a functor that increments the input. 80 template <typename D> 81 int test_mantissa(const std::function<D(D)>& inc = [](D x) { return x + 1; }) { 82 D d = 1; 83 for (int i = 0; i < 128; ++i) { 84 d = d + d; 85 // std::cout << i << " " << d << "\n"; 86 if (d == inc(d)) { 87 return i; 88 } 89 } 90 return 0; 91 } 92 93 } // namespace android::audio_utils::test 94