Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 1 | // Copyright 2018 The Abseil Authors. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // https://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | #include "absl/strings/internal/pow10_helper.h" |
| 16 | |
| 17 | #include <cmath> |
| 18 | |
| 19 | #include "gtest/gtest.h" |
| 20 | #include "absl/strings/str_format.h" |
| 21 | |
| 22 | namespace absl { |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 23 | ABSL_NAMESPACE_BEGIN |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 24 | namespace strings_internal { |
| 25 | |
| 26 | namespace { |
| 27 | |
| 28 | struct TestCase { |
| 29 | int power; // Testing Pow10(power) |
| 30 | uint64_t significand; // Raw bits of the expected value |
| 31 | int radix; // significand is adjusted by 2^radix |
| 32 | }; |
| 33 | |
| 34 | TEST(Pow10HelperTest, Works) { |
| 35 | // The logic in pow10_helper.cc is so simple that theoretically we don't even |
| 36 | // need a test. However, we're paranoid and believe that there may be |
| 37 | // compilers that don't round floating-point literals correctly, even though |
| 38 | // it is specified by the standard. We check various edge cases, just to be |
| 39 | // sure. |
| 40 | constexpr TestCase kTestCases[] = { |
| 41 | // Subnormals |
| 42 | {-323, 0x2, -1074}, |
| 43 | {-322, 0x14, -1074}, |
| 44 | {-321, 0xca, -1074}, |
| 45 | {-320, 0x7e8, -1074}, |
| 46 | {-319, 0x4f10, -1074}, |
| 47 | {-318, 0x316a2, -1074}, |
| 48 | {-317, 0x1ee257, -1074}, |
| 49 | {-316, 0x134d761, -1074}, |
| 50 | {-315, 0xc1069cd, -1074}, |
| 51 | {-314, 0x78a42205, -1074}, |
| 52 | {-313, 0x4b6695433, -1074}, |
| 53 | {-312, 0x2f201d49fb, -1074}, |
| 54 | {-311, 0x1d74124e3d1, -1074}, |
| 55 | {-310, 0x12688b70e62b, -1074}, |
| 56 | {-309, 0xb8157268fdaf, -1074}, |
| 57 | {-308, 0x730d67819e8d2, -1074}, |
| 58 | // Values that are very close to rounding the other way. |
| 59 | // Comment shows difference of significand from the true value. |
| 60 | {-307, 0x11fa182c40c60d, -1072}, // -.4588 |
| 61 | {-290, 0x18f2b061aea072, -1016}, // .4854 |
| 62 | {-276, 0x11BA03F5B21000, -969}, // .4709 |
| 63 | {-259, 0x1899C2F6732210, -913}, // .4830 |
| 64 | {-252, 0x1D53844EE47DD1, -890}, // -.4743 |
| 65 | {-227, 0x1E5297287C2F45, -807}, // -.4708 |
| 66 | {-198, 0x1322E220A5B17E, -710}, // -.4714 |
| 67 | {-195, 0x12B010D3E1CF56, -700}, // .4928 |
| 68 | {-192, 0x123FF06EEA847A, -690}, // .4968 |
| 69 | {-163, 0x1708D0F84D3DE7, -594}, // -.4977 |
| 70 | {-145, 0x13FAAC3E3FA1F3, -534}, // -.4785 |
| 71 | {-111, 0x133D4032C2C7F5, -421}, // .4774 |
| 72 | {-106, 0x1D5B561574765B, -405}, // -.4869 |
| 73 | {-104, 0x16EF5B40C2FC77, -398}, // -.4741 |
| 74 | {-88, 0x197683DF2F268D, -345}, // -.4738 |
| 75 | {-86, 0x13E497065CD61F, -338}, // .4736 |
| 76 | {-76, 0x17288E1271F513, -305}, // -.4761 |
| 77 | {-63, 0x1A53FC9631D10D, -262}, // .4929 |
| 78 | {-30, 0x14484BFEEBC2A0, -152}, // .4758 |
| 79 | {-21, 0x12E3B40A0E9B4F, -122}, // -.4916 |
| 80 | {-5, 0x14F8B588E368F1, -69}, // .4829 |
| 81 | {23, 0x152D02C7E14AF6, 24}, // -.5000 (exactly, round-to-even) |
| 82 | {29, 0x1431E0FAE6D721, 44}, // -.4870 |
| 83 | {34, 0x1ED09BEAD87C03, 60}, // -.4721 |
| 84 | {70, 0x172EBAD6DDC73D, 180}, // .4733 |
| 85 | {105, 0x1BE7ABD3781ECA, 296}, // -.4850 |
| 86 | {126, 0x17A2ECC414A03F, 366}, // -.4999 |
| 87 | {130, 0x1CDA62055B2D9E, 379}, // .4855 |
| 88 | {165, 0x115D847AD00087, 496}, // -.4913 |
| 89 | {172, 0x14B378469B6732, 519}, // .4818 |
| 90 | {187, 0x1262DFEEBBB0F9, 569}, // -.4805 |
| 91 | {210, 0x18557F31326BBB, 645}, // -.4992 |
| 92 | {212, 0x1302CB5E6F642A, 652}, // -.4838 |
| 93 | {215, 0x1290BA9A38C7D1, 662}, // -.4881 |
| 94 | {236, 0x1F736F9B3494E9, 731}, // .4707 |
| 95 | {244, 0x176EC98994F489, 758}, // .4924 |
| 96 | {250, 0x1658E3AB795204, 778}, // -.4963 |
| 97 | {252, 0x117571DDF6C814, 785}, // .4873 |
| 98 | {254, 0x1B4781EAD1989E, 791}, // -.4887 |
| 99 | {260, 0x1A03FDE214CAF1, 811}, // .4784 |
| 100 | {284, 0x1585041B2C477F, 891}, // .4798 |
| 101 | {304, 0x1D2A1BE4048F90, 957}, // -.4987 |
| 102 | // Out-of-range values |
| 103 | {-324, 0x0, 0}, |
| 104 | {-325, 0x0, 0}, |
| 105 | {-326, 0x0, 0}, |
| 106 | {309, 1, 2000}, |
| 107 | {310, 1, 2000}, |
| 108 | {311, 1, 2000}, |
| 109 | }; |
| 110 | for (const TestCase& test_case : kTestCases) { |
| 111 | EXPECT_EQ(Pow10(test_case.power), |
| 112 | std::ldexp(test_case.significand, test_case.radix)) |
| 113 | << absl::StrFormat("Failure for Pow10(%d): %a vs %a", test_case.power, |
| 114 | Pow10(test_case.power), |
| 115 | std::ldexp(test_case.significand, test_case.radix)); |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | } // namespace |
| 120 | } // namespace strings_internal |
Austin Schuh | b4691e9 | 2020-12-31 12:37:18 -0800 | [diff] [blame^] | 121 | ABSL_NAMESPACE_END |
Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame] | 122 | } // namespace absl |