all_close_f.cpp 46.8 KB
Newer Older
1
//*****************************************************************************
2
// Copyright 2017-2019 Intel Corporation
3 4 5 6 7 8 9 10 11 12 13 14 15
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//*****************************************************************************
16

17
#include <algorithm>
18 19 20 21 22 23 24 25 26
#include <bitset>
#include <cmath>
#include <limits>
#include <sstream>

#include "gtest/gtest.h"

#include "ngraph/ngraph.hpp"
#include "util/all_close_f.hpp"
27
#include "util/float_util.hpp"
28 29 30 31

using namespace std;
using namespace ngraph;

32
class all_close_f_param_test : public testing::TestWithParam<::std::tuple<float, int>>
33 34 35 36 37 38 39 40
{
protected:
    all_close_f_param_test()
        : upper_bound(FLT_MAX)
        , lower_bound(-FLT_MAX)
        , past_upper_bound(FLT_MAX)
        , past_lower_bound(-FLT_MAX)
    {
41
        std::tie(expected, tolerance_bits) = GetParam();
42 43 44
    }
    void SetUp() override
    {
45
        constexpr int mantissa_bits = 24;
46
        uint32_t expected_as_int = test::FloatUnion(expected).i;
47 48 49 50 51 52 53 54 55 56 57

        // Turn on targeted bit
        // e.g. for float with 24 bit mantissa, 2 bit accuracy, and hard-coded 8 bit exponent_bits
        // tolerance_bit_shift = 32 -           (1 +  8 + (24 -     1         ) - 2             )
        //                       float_length    sign exp  mantissa implicit 1    tolerance_bits
        uint32_t tolerance_bit_shift = 32 - (1 + 8 + (mantissa_bits - 1) - tolerance_bits);
        uint32_t targeted_bit = (1u << tolerance_bit_shift);

        if (expected > 0.f)
        {
            uint32_t upper_bound_as_int = expected_as_int + targeted_bit;
58 59
            upper_bound = test::FloatUnion(upper_bound_as_int).f;
            past_upper_bound = test::FloatUnion(upper_bound_as_int + 1).f;
60
            min_signal_too_low = expected;
61
            min_signal_enables_passing = test::FloatUnion(upper_bound_as_int + 2).f;
62 63

            uint32_t lower_bound_as_int = expected_as_int - targeted_bit;
64 65
            lower_bound = test::FloatUnion(lower_bound_as_int).f;
            past_lower_bound = test::FloatUnion(lower_bound_as_int - 1).f;
66 67 68 69 70
        }
        else if (expected < 0.f)
        {
            // Same logic/math as above, but reversed variable name order
            uint32_t lower_bound_as_int = expected_as_int + targeted_bit;
71 72
            lower_bound = test::FloatUnion(lower_bound_as_int).f;
            past_lower_bound = test::FloatUnion(lower_bound_as_int + 1).f;
73
            min_signal_too_low = expected;
74
            min_signal_enables_passing = test::FloatUnion(lower_bound_as_int + 2).f;
75 76

            uint32_t upper_bound_as_int = expected_as_int - targeted_bit;
77 78
            upper_bound = test::FloatUnion(upper_bound_as_int).f;
            past_upper_bound = test::FloatUnion(upper_bound_as_int - 1).f;
79 80 81 82 83
        }
        else // (expected == 0.f) || (expected == -0.f)
        {
            // Special handling of 0 / -0 which get same bounds
            uint32_t upper_bound_as_int = targeted_bit;
84
            upper_bound = test::FloatUnion(upper_bound_as_int).f;
85
            uint32_t past_upper_bound_as_int = upper_bound_as_int + 1;
86
            past_upper_bound = test::FloatUnion(past_upper_bound_as_int).f;
87
            min_signal_too_low = expected;
88
            min_signal_enables_passing = test::FloatUnion(upper_bound_as_int + 2).f;
89

90 91
            lower_bound = test::FloatUnion(upper_bound_as_int | 0x80000000).f;
            past_lower_bound = test::FloatUnion(past_upper_bound_as_int | 0x80000000).f;
92 93 94
        }
    }

95 96
    float expected{0};
    int tolerance_bits{0};
97 98 99 100
    float upper_bound;
    float lower_bound;
    float past_upper_bound;
    float past_lower_bound;
101 102
    float min_signal_too_low{0};
    float min_signal_enables_passing{0};
103 104 105 106
};

TEST_P(all_close_f_param_test, test_boundaries)
{
107 108 109
    if (std::getenv("NGRAPH_GTEST_INFO") != nullptr)
    {
        // Print short string documenting which test is being run
110
        std::cout << "[   INFO   ] Test params: (" << expected << ", " << tolerance_bits << ")\n";
111
    }
112 113 114

    // Format verbose info to only print out in case of test failure
    stringstream ss;
115
    ss << "Testing target of: " << expected << " (" << test::float_to_bits(expected) << ")\n";
116
    ss << "Matching to targets with: " << tolerance_bits << " tolerance_bits\n";
117 118 119
    ss << "upper_bound: " << upper_bound << " (" << test::float_to_bits(upper_bound) << ")\n";
    ss << "lower_bound: " << lower_bound << " (" << test::float_to_bits(lower_bound) << ")\n";
    ss << "past_upper_bound: " << past_upper_bound << " (" << test::float_to_bits(past_upper_bound)
120
       << ")\n";
121
    ss << "past_lower_bound: " << past_lower_bound << " (" << test::float_to_bits(past_lower_bound)
122 123
       << ")\n";

124 125 126
    EXPECT_TRUE(test::close_f(expected, upper_bound, tolerance_bits)) << ss.str();
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({upper_bound}), tolerance_bits))
127
        << ss.str();
128 129 130
    EXPECT_TRUE(test::close_f(expected, lower_bound, tolerance_bits)) << ss.str();
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({lower_bound}), tolerance_bits))
131
        << ss.str();
132
    EXPECT_FALSE(test::close_f(expected, past_upper_bound, tolerance_bits)) << ss.str();
133 134 135 136 137
    EXPECT_FALSE(test::close_f(expected, past_upper_bound, tolerance_bits, min_signal_too_low))
        << ss.str();
    EXPECT_TRUE(
        test::close_f(expected, past_upper_bound, tolerance_bits, min_signal_enables_passing))
        << ss.str();
138 139
    EXPECT_FALSE(test::all_close_f(
        vector<float>({expected}), vector<float>({past_upper_bound}), tolerance_bits))
140
        << ss.str();
141 142 143 144 145 146 147 148 149 150
    EXPECT_FALSE(test::all_close_f(vector<float>({expected}),
                                   vector<float>({past_upper_bound}),
                                   tolerance_bits,
                                   min_signal_too_low))
        << ss.str();
    EXPECT_TRUE(test::all_close_f(vector<float>({expected}),
                                  vector<float>({past_upper_bound}),
                                  tolerance_bits,
                                  min_signal_enables_passing))
        << ss.str();
151
    EXPECT_FALSE(test::close_f(expected, past_lower_bound, tolerance_bits)) << ss.str();
152 153 154 155 156
    EXPECT_FALSE(test::close_f(expected, past_lower_bound, tolerance_bits, min_signal_too_low))
        << ss.str();
    EXPECT_TRUE(
        test::close_f(expected, past_lower_bound, tolerance_bits, min_signal_enables_passing))
        << ss.str();
157 158
    EXPECT_FALSE(test::all_close_f(
        vector<float>({expected}), vector<float>({past_lower_bound}), tolerance_bits))
159
        << ss.str();
160 161 162 163 164 165 166 167 168 169
    EXPECT_FALSE(test::all_close_f(vector<float>({expected}),
                                   vector<float>({past_lower_bound}),
                                   tolerance_bits,
                                   min_signal_too_low))
        << ss.str();
    EXPECT_TRUE(test::all_close_f(vector<float>({expected}),
                                  vector<float>({past_lower_bound}),
                                  tolerance_bits,
                                  min_signal_enables_passing))
        << ss.str();
170 171
}

172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
INSTANTIATE_TEST_CASE_P(test_simple_floats_with_range_of_precisions,
                        all_close_f_param_test,
                        testing::Combine(testing::Values(0.f,
                                                         -0.f,
                                                         1.f,
                                                         -1.f,
                                                         10.f,
                                                         -10.f,
                                                         0.75f,
                                                         -0.75f,
                                                         0.5f,
                                                         -0.5f,
                                                         0.25f,
                                                         -0.25f,
                                                         0.125f,
                                                         -0.125f),
                                         testing::Range(0, 5)), );
189 190 191 192 193

class all_close_f_double_param_test : public testing::TestWithParam<::std::tuple<double, int>>
{
protected:
    all_close_f_double_param_test()
194
        : upper_bound(DBL_MAX)
195 196 197 198 199 200 201 202
        , lower_bound(-DBL_MAX)
        , past_upper_bound(DBL_MAX)
        , past_lower_bound(-DBL_MAX)
    {
        std::tie(expected, tolerance_bits) = GetParam();
    }
    void SetUp() override
    {
203
        constexpr int mantissa_bits = 53;
204
        uint64_t expected_as_int = test::DoubleUnion(expected).i;
205 206 207 208 209 210 211 212 213 214
        // Turn on targeted bit
        // e.g. for double with 52 bit mantissa, 2 bit accuracy, and hard-coded 11 bit exponent_bits
        // tolerance_bit_shift = 64 -           (1 +  11 + (52 -     1         ) - 2             )
        //                       double_length   sign exp   mantissa implicit 1    tolerance_bits
        uint64_t tolerance_bit_shift = 64 - (1 + 11 + (mantissa_bits - 1) - tolerance_bits);
        uint64_t targeted_bit = (1ull << tolerance_bit_shift);

        if (expected > 0.)
        {
            uint64_t upper_bound_as_int = expected_as_int + targeted_bit;
215 216
            upper_bound = test::DoubleUnion(upper_bound_as_int).d;
            past_upper_bound = test::DoubleUnion(upper_bound_as_int + 1).d;
217
            min_signal_too_low = expected;
218
            min_signal_enables_passing = test::DoubleUnion(upper_bound_as_int + 2).d;
219 220

            uint64_t lower_bound_as_int = expected_as_int - targeted_bit;
221 222
            lower_bound = test::DoubleUnion(lower_bound_as_int).d;
            past_lower_bound = test::DoubleUnion(lower_bound_as_int - 1).d;
223 224 225 226 227
        }
        else if (expected < 0.)
        {
            // Same logic/math as above, but reversed variable name order
            uint64_t lower_bound_as_int = expected_as_int + targeted_bit;
228 229
            lower_bound = test::DoubleUnion(lower_bound_as_int).d;
            past_lower_bound = test::DoubleUnion(lower_bound_as_int + 1).d;
230
            min_signal_too_low = expected;
231
            min_signal_enables_passing = test::DoubleUnion(lower_bound_as_int + 2).d;
232 233

            uint64_t upper_bound_as_int = expected_as_int - targeted_bit;
234 235
            upper_bound = test::DoubleUnion(upper_bound_as_int).d;
            past_upper_bound = test::DoubleUnion(upper_bound_as_int - 1).d;
236 237 238 239 240
        }
        else // (expected == 0.) || (expected == -0.)
        {
            // Special handling of 0 / -0 which get same bounds
            uint64_t upper_bound_as_int = targeted_bit;
241
            upper_bound = test::DoubleUnion(upper_bound_as_int).d;
242
            uint64_t past_upper_bound_as_int = upper_bound_as_int + 1;
243
            past_upper_bound = test::DoubleUnion(past_upper_bound_as_int).d;
244
            min_signal_too_low = expected;
245
            min_signal_enables_passing = test::DoubleUnion(upper_bound_as_int + 2).d;
246

247 248
            lower_bound = test::DoubleUnion(upper_bound_as_int | 0x8000000000000000).d;
            past_lower_bound = test::DoubleUnion(past_upper_bound_as_int | 0x8000000000000000).d;
249 250 251
        }
    }

252 253
    double expected{0};
    int tolerance_bits{0};
254 255 256 257
    double upper_bound;
    double lower_bound;
    double past_upper_bound;
    double past_lower_bound;
258 259
    double min_signal_too_low{0};
    double min_signal_enables_passing{0};
260 261 262 263
};

TEST_P(all_close_f_double_param_test, test_boundaries)
{
264 265 266 267 268
    if (std::getenv("NGRAPH_GTEST_INFO") != nullptr)
    {
        // Print short string documenting which test is being run
        std::cout << "[   INFO   ] Test params: (" << expected << ", " << tolerance_bits << ")\n";
    }
269 270 271

    // Format verbose info to only print out in case of test failure
    stringstream ss;
272
    ss << "Testing target of: " << expected << " (" << test::double_to_bits(expected) << ")\n";
273
    ss << "Matching to targets with: " << tolerance_bits << " tolerance_bits\n";
274 275 276
    ss << "upper_bound: " << upper_bound << " (" << test::double_to_bits(upper_bound) << ")\n";
    ss << "lower_bound: " << lower_bound << " (" << test::double_to_bits(lower_bound) << ")\n";
    ss << "past_upper_bound: " << past_upper_bound << " (" << test::double_to_bits(past_upper_bound)
277
       << ")\n";
278
    ss << "past_lower_bound: " << past_lower_bound << " (" << test::double_to_bits(past_lower_bound)
279 280 281 282 283 284 285 286 287 288 289
       << ")\n";

    EXPECT_TRUE(test::close_f(expected, upper_bound, tolerance_bits)) << ss.str();
    EXPECT_TRUE(test::all_close_f(
        vector<double>({expected}), vector<double>({upper_bound}), tolerance_bits))
        << ss.str();
    EXPECT_TRUE(test::close_f(expected, lower_bound, tolerance_bits)) << ss.str();
    EXPECT_TRUE(test::all_close_f(
        vector<double>({expected}), vector<double>({lower_bound}), tolerance_bits))
        << ss.str();
    EXPECT_FALSE(test::close_f(expected, past_upper_bound, tolerance_bits)) << ss.str();
290 291 292 293 294
    EXPECT_FALSE(test::close_f(expected, past_upper_bound, tolerance_bits, min_signal_too_low))
        << ss.str();
    EXPECT_TRUE(
        test::close_f(expected, past_upper_bound, tolerance_bits, min_signal_enables_passing))
        << ss.str();
295 296 297
    EXPECT_FALSE(test::all_close_f(
        vector<double>({expected}), vector<double>({past_upper_bound}), tolerance_bits))
        << ss.str();
298 299 300 301 302 303 304 305 306 307
    EXPECT_FALSE(test::all_close_f(vector<double>({expected}),
                                   vector<double>({past_upper_bound}),
                                   tolerance_bits,
                                   min_signal_too_low))
        << ss.str();
    EXPECT_TRUE(test::all_close_f(vector<double>({expected}),
                                  vector<double>({past_upper_bound}),
                                  tolerance_bits,
                                  min_signal_enables_passing))
        << ss.str();
308
    EXPECT_FALSE(test::close_f(expected, past_lower_bound, tolerance_bits)) << ss.str();
309 310 311 312 313
    EXPECT_FALSE(test::close_f(expected, past_lower_bound, tolerance_bits, min_signal_too_low))
        << ss.str();
    EXPECT_TRUE(
        test::close_f(expected, past_lower_bound, tolerance_bits, min_signal_enables_passing))
        << ss.str();
314 315 316
    EXPECT_FALSE(test::all_close_f(
        vector<double>({expected}), vector<double>({past_lower_bound}), tolerance_bits))
        << ss.str();
317 318 319 320 321 322 323 324 325 326
    EXPECT_FALSE(test::all_close_f(vector<double>({expected}),
                                   vector<double>({past_lower_bound}),
                                   tolerance_bits,
                                   min_signal_too_low))
        << ss.str();
    EXPECT_TRUE(test::all_close_f(vector<double>({expected}),
                                  vector<double>({past_lower_bound}),
                                  tolerance_bits,
                                  min_signal_enables_passing))
        << ss.str();
327 328 329 330 331 332 333 334 335 336
}

INSTANTIATE_TEST_CASE_P(
    test_simple_doubles_with_range_of_precisions,
    all_close_f_double_param_test,
    testing::Combine(
        testing::Values(
            0., -0., 1., -1., 10., -10., 0.75, -0.75, 0.5, -0.5, 0.25, -0.25, 0.125, -0.125),
        testing::Range(0, 17)), );

337 338
// Test the exact bounds near +0.f
//
339 340
// With tolerance_bits = 18
// (equivalent to testing bfloat precision with 2 bits tolerance)
341 342 343 344
//
//                           Targeted bit
//                           |
//                           v
345
//                   2 3 4 5 6    (error allowed in 6th bit or later, w/ implicit leading bit)
346
// s e e e e e e e e m m m m m m m m m m m m m m m m m m m m m m m
347 348 349
//                =>|      8      |    (8 w/ implicit leading bit)
//                           ^
//                           |  2 |<=
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
//
// [Upper bound]
//                           Add 1 at this bit
//                           |
//                           v
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// +                         1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// ---------------------------------------------------------------
// 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
//
// [Lower bound]
//                           Minus 1 at this bit
//                           |
//                           v
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// -                         1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// ---------------------------------------------------------------
// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
//
// Convert to 2's compliment
// 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
//
// Mask the sign bit
// 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
TEST(all_close_f, mantissa_8_near_0)
{
376 377
    constexpr int tolerance_bits = (FLOAT_MANTISSA_BITS - BFLOAT_MANTISSA_BITS + 2);

378
    // 0.f, the ground-truth value
379
    float expected = test::bits_to_float("0  00000000  000 0000 0000 0000 0000 0000");
380
    float computed;
381 382 383
    float min_signal_too_low = test::bits_to_float("0  00000000  000 0100 0000 0000 0000 0001");
    float min_signal_enables_passing =
        test::bits_to_float("0  00000000  000 0100 0000 0000 0000 0010");
384 385

    // ~3.67342E-40, the exact upper bound
386
    computed = test::bits_to_float("0  00000000  000 0100 0000 0000 0000 0000");
387 388 389
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
390 391

    // ~3.67343E-40, the next representable number bigger than upper bound
392
    computed = test::bits_to_float("0  00000000  000 0100 0000 0000 0000 0001");
393
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
394 395
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits, min_signal_too_low));
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits, min_signal_enables_passing));
396 397
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
398 399 400 401 402 403
    EXPECT_FALSE(test::all_close_f(
        vector<float>({expected}), vector<float>({computed}), tolerance_bits, min_signal_too_low));
    EXPECT_TRUE(test::all_close_f(vector<float>({expected}),
                                  vector<float>({computed}),
                                  tolerance_bits,
                                  min_signal_enables_passing));
404 405

    // ~-3.67342E-40, the exact lower bound
406
    computed = test::bits_to_float("1  00000000  000 0100 0000 0000 0000 0000");
407 408 409
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
410 411

    // ~-3.67343E-40, the next representable number smaller than lower bound
412
    computed = test::bits_to_float("1  00000000  000 0100 0000 0000 0000 0001");
413
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
414 415
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits, min_signal_too_low));
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits, min_signal_enables_passing));
416 417
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
418 419 420 421 422 423
    EXPECT_FALSE(test::all_close_f(
        vector<float>({expected}), vector<float>({computed}), tolerance_bits, min_signal_too_low));
    EXPECT_TRUE(test::all_close_f(vector<float>({expected}),
                                  vector<float>({computed}),
                                  tolerance_bits,
                                  min_signal_enables_passing));
424 425 426 427
}

// Test the exact bounds near -0.f
//
428 429
// With tolerance_bits = 18
// (equivalent to testing bfloat precision with 2 bits tolerance)
430 431 432 433
//
//                           Targeted bit
//                           |
//                           v
434
//                   2 3 4 5 6    (error allowed in 6th bit or later, w/ implicit leading bit)
435
// s e e e e e e e e m m m m m m m m m m m m m m m m m m m m m m m
436 437 438
//                =>|      8      |    (8 w/ implicit leading bit)
//                           ^
//                           |  2 |<=
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
//
// [Upper bound]
//                           Minus 1 at this bit
//                           |
//                           v
// 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// -                         1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// ---------------------------------------------------------------
// 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
//
// Convert to 2's compliment
// 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
//
// Mask off sign bit
// 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
//
// [Lower bound]
//                           Add 1 at this bit
//                           |
//                           v
// 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// +                         1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// ---------------------------------------------------------------
// 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
TEST(all_close_f, mantissa_8_near_n0)
{
465 466
    constexpr int tolerance_bits = (FLOAT_MANTISSA_BITS - BFLOAT_MANTISSA_BITS + 2);

467
    // 0.f, the ground-truth value
468
    float expected = test::bits_to_float("1  00000000  000 0000 0000 0000 0000 0000");
469
    float computed;
470 471 472
    float min_signal_too_low = test::bits_to_float("0  00000000  000 0100 0000 0000 0000 0001");
    float min_signal_enables_passing =
        test::bits_to_float("0  00000000  000 0100 0000 0000 0000 0010");
473 474

    // ~3.67342E-40, the exact upper bound
475
    computed = test::bits_to_float("0  00000000  000 0100 0000 0000 0000 0000");
476 477 478
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
479 480

    // ~3.67343E-40, the next representable number bigger than upper bound
481
    computed = test::bits_to_float("0  00000000  000 0100 0000 0000 0000 0001");
482
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
483 484
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits, min_signal_too_low));
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits, min_signal_enables_passing));
485 486
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
487 488 489 490 491 492
    EXPECT_FALSE(test::all_close_f(
        vector<float>({expected}), vector<float>({computed}), tolerance_bits, min_signal_too_low));
    EXPECT_TRUE(test::all_close_f(vector<float>({expected}),
                                  vector<float>({computed}),
                                  tolerance_bits,
                                  min_signal_enables_passing));
493 494

    // ~-3.67342E-40, the exact lower bound
495
    computed = test::bits_to_float("1  00000000  000 0100 0000 0000 0000 0000");
496 497 498
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
499 500

    // ~-3.67343E-40, the next representable number smaller than lower bound
501
    computed = test::bits_to_float("1  00000000  000 0100 0000 0000 0000 0001");
502
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
503 504
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits, min_signal_too_low));
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits, min_signal_enables_passing));
505 506
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
507 508 509 510 511 512
    EXPECT_FALSE(test::all_close_f(
        vector<float>({expected}), vector<float>({computed}), tolerance_bits, min_signal_too_low));
    EXPECT_TRUE(test::all_close_f(vector<float>({expected}),
                                  vector<float>({computed}),
                                  tolerance_bits,
                                  min_signal_enables_passing));
513 514 515 516
}

// Test the exact bounds near 1.f
//
517 518
// With tolerance_bits = 18
// (equivalent to testing bfloat precision with 2 bits tolerance)
519 520 521 522
//
//                           Targeted bit
//                           |
//                           v
523
//                   2 3 4 5 6    (error allowed in 6th bit or later, w/ implicit leading bit)
524
// s e e e e e e e e m m m m m m m m m m m m m m m m m m m m m m m
525 526 527
//                =>|      8      |    (8 w/ implicit leading bit)
//                           ^
//                           |  2 |<=
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
//
// [Upper bound]
//                           Add 1 at this bit to get upper bound
//                           |
//                           v
// 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// +                         1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// ---------------------------------------------------------------
// 0 0 1 1 1 1 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
//
// [Lower bound]
//                           Minus 1 at this bit to get lower bound
//                           |
//                           v
// 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// -                         1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// ---------------------------------------------------------------
// 0 0 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
TEST(all_close_f, mantissa_8_near_1)
{
548 549
    constexpr int tolerance_bits = (FLOAT_MANTISSA_BITS - BFLOAT_MANTISSA_BITS + 2);

550
    // 1.f, the ground-truth value
551
    float expected = test::bits_to_float("0  01111111  000 0000 0000 0000 0000 0000");
552 553 554
    float computed;

    // 1.03125f, the exact upper bound
555
    computed = test::bits_to_float("0  01111111  000 0100 0000 0000 0000 0000");
556 557 558
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
559 560

    // 1.031250119f, the next representable number bigger than upper bound
561
    computed = test::bits_to_float("0  01111111  000 0100 0000 0000 0000 0001");
562 563 564
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
565 566

    // 0.984375f, the exact lower bound
567
    computed = test::bits_to_float("0  01111110  111 1100 0000 0000 0000 0000");
568 569 570
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
571 572

    // 0.9843749404f, the next representable number smaller than lower bound
573
    computed = test::bits_to_float("0  01111110  111 1011 1111 1111 1111 1111");
574 575 576
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
577 578 579 580
}

// Test the exact bounds near -1.f
//
581 582
// With tolerance_bits = 18
// (equivalent to testing bfloat precision with 2 bits tolerance)
583 584 585 586
//
//                           Targeted bit
//                           |
//                           v
587
//                   2 3 4 5 6    (error allowed in 6th bit or later, w/ implicit leading bit)
588
// s e e e e e e e e m m m m m m m m m m m m m m m m m m m m m m m
589 590 591
//                =>|      8      |    (8 w/ implicit leading bit)
//                           ^
//                           |  2 |<=
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
//
// [Upper bound]
//                           Minus 1 at this bit
//                           |
//                           v
// 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// -                         1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// ---------------------------------------------------------------
// 1 0 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
//
// [Lower bound]
//                           Add 1 at this bit
//                           |
//                           v
// 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// +                         1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// ---------------------------------------------------------------
// 1 0 1 1 1 1 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
TEST(all_close_f, mantissa_8_near_n1)
{
612 613
    constexpr int tolerance_bits = (FLOAT_MANTISSA_BITS - BFLOAT_MANTISSA_BITS + 2);

614
    // -1.f, the ground-truth value
615
    float expected = test::bits_to_float("1  01111111  000 0000 0000 0000 0000 0000");
616 617 618
    float computed;

    // -0.984375f, the exact upper bound
619
    computed = test::bits_to_float("1  01111110  111 1100 0000 0000 0000 0000");
620 621 622
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
623 624

    // -0.984374940395355224609375f, the next representable number bigger than upper bound
625
    computed = test::bits_to_float("1  01111110  111 1011 1111 1111 1111 1111");
626 627 628
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
629 630

    // -1.03125f, the exact lower bound
631
    computed = test::bits_to_float("1  01111111  000 0100 0000 0000 0000 0000");
632 633 634
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
635 636

    // -1.03125011920928955078125f, the next representable number smaller than lower bound
637
    computed = test::bits_to_float("1  01111111  000 0100 0000 0000 0000 0001");
638 639 640
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
641 642 643
}

// For intuitive understanding of tightness of bounds in decimal
644
// Test bounds near 0, 1, 10, 100, 1000 with tolerance_bits = 18
645 646 647 648
//
//                           Targeted bit
//                           |
//                           v
649
//                   2 3 4 5 6    (error allowed in 6th bit or later, w/ implicit leading bit)
650
// s e e e e e e e e m m m m m m m m m m m m m m m m m m m m m m m
651 652 653
//                =>|      8      |    (8 w/ implicit leading bit)
//                           ^
//                           |  2 |<=
654 655
TEST(all_close_f, mantissa_8_near_0_1_10_100_1000)
{
656 657
    constexpr int tolerance_bits = (FLOAT_MANTISSA_BITS - BFLOAT_MANTISSA_BITS + 2);

658 659 660 661 662 663 664
    float expected;
    float upper_bound;
    float bigger_than_upper_bound;
    float lower_bound;
    float smaller_than_lower_bound;

    // Bounds around 0: 0 +- 3.67e-40
665 666 667 668 669 670 671
    expected = 0.f;             // 0  00000000  000 0000 0000 0000 0000 0000
    upper_bound = 3.67342e-40f; // 0  00000000  000 0100 0000 0000 0000 0000, approximated
    bigger_than_upper_bound =
        3.67343e-40f;            // 0  00000000  000 0100 0000 0000 0000 0001, approximated
    lower_bound = -3.67342e-40f; // 1  00000000  000 0100 0000 0000 0000 0000, approximated
    smaller_than_lower_bound =
        3.67343e-40f; // 1  00000000  000 0100 0000 0000 0000 0001, approximated
672 673 674 675
    EXPECT_TRUE(test::close_f(expected, upper_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({upper_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, bigger_than_upper_bound, tolerance_bits));
676
    EXPECT_FALSE(test::all_close_f(
677 678 679 680 681
        vector<float>({expected}), vector<float>({bigger_than_upper_bound}), tolerance_bits));
    EXPECT_TRUE(test::close_f(expected, lower_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({lower_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, smaller_than_lower_bound, tolerance_bits));
682
    EXPECT_FALSE(test::all_close_f(
683
        vector<float>({expected}), vector<float>({smaller_than_lower_bound}), tolerance_bits));
684 685

    // Bounds around 1: 1 +- 0.03
686 687 688 689 690
    expected = 1.f;                           // 0  01111111  000 0000 0000 0000 0000 0000
    upper_bound = 1.03125f;                   // 0  01111111  000 0100 0000 0000 0000 0000
    bigger_than_upper_bound = 1.031250119f;   // 0  01111111  000 0100 0000 0000 0000 0001
    lower_bound = 0.984375f;                  // 0  01111110  111 1100 0000 0000 0000 0000
    smaller_than_lower_bound = 0.9843749404f; // 0  01111110  111 1011 1111 1111 1111 1111
691 692 693 694
    EXPECT_TRUE(test::close_f(expected, upper_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({upper_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, bigger_than_upper_bound, tolerance_bits));
695
    EXPECT_FALSE(test::all_close_f(
696 697 698 699 700
        vector<float>({expected}), vector<float>({bigger_than_upper_bound}), tolerance_bits));
    EXPECT_TRUE(test::close_f(expected, lower_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({lower_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, smaller_than_lower_bound, tolerance_bits));
701
    EXPECT_FALSE(test::all_close_f(
702
        vector<float>({expected}), vector<float>({smaller_than_lower_bound}), tolerance_bits));
703 704

    // Bounds around 10: 10 +- 0.25
705 706 707 708 709
    expected = 10.f;                                    // 0  10000010  010 0000 0000 0000 0000 0000
    upper_bound = 10.25f;                               // 0  10000010  010 0100 0000 0000 0000 0000
    bigger_than_upper_bound = 10.25000095367431640625f; // 0  10000010  010 0100 0000 0000 0000 0001
    lower_bound = 9.75f;                                // 0  10000010  001 1100 0000 0000 0000 0000
    smaller_than_lower_bound = 9.74999904632568359375f; // 0  10000010  001 1011 1111 1111 1111 1111
710 711 712 713
    EXPECT_TRUE(test::close_f(expected, upper_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({upper_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, bigger_than_upper_bound, tolerance_bits));
714
    EXPECT_FALSE(test::all_close_f(
715 716 717 718 719
        vector<float>({expected}), vector<float>({bigger_than_upper_bound}), tolerance_bits));
    EXPECT_TRUE(test::close_f(expected, lower_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({lower_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, smaller_than_lower_bound, tolerance_bits));
720
    EXPECT_FALSE(test::all_close_f(
721
        vector<float>({expected}), vector<float>({smaller_than_lower_bound}), tolerance_bits));
722 723

    // Bounds around 100: 100 +- 2
724 725 726 727 728
    expected = 100.f;                                 // 0  10000101  100 1000 0000 0000 0000 0000
    upper_bound = 102.f;                              // 0  10000101  100 1100 0000 0000 0000 0000
    bigger_than_upper_bound = 102.00000762939453125f; // 0  10000101  100 1100 0000 0000 0000 0001
    lower_bound = 98.0f;                              // 0  10000101  100 0100 0000 0000 0000 0000
    smaller_than_lower_bound = 97.99999237060546875f; // 0  10000101  100 0011 1111 1111 1111 1111
729 730 731 732
    EXPECT_TRUE(test::close_f(expected, upper_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({upper_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, bigger_than_upper_bound, tolerance_bits));
733
    EXPECT_FALSE(test::all_close_f(
734 735 736 737 738
        vector<float>({expected}), vector<float>({bigger_than_upper_bound}), tolerance_bits));
    EXPECT_TRUE(test::close_f(expected, lower_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({lower_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, smaller_than_lower_bound, tolerance_bits));
739
    EXPECT_FALSE(test::all_close_f(
740
        vector<float>({expected}), vector<float>({smaller_than_lower_bound}), tolerance_bits));
741 742

    // Bounds around 1000: 1000 +- 16
743 744 745 746 747
    expected = 1000.f;                              // 0  10001000  111 1010 0000 0000 0000 0000
    upper_bound = 1016.f;                           // 0  10001000  111 1110 0000 0000 0000 0000
    bigger_than_upper_bound = 1016.00006103515625f; // 0  10001000  111 1110 0000 0000 0000 0001
    lower_bound = 984.0f;                           // 0  10001000  111 0110 0000 0000 0000 0000
    smaller_than_lower_bound = 983.99993896484375f; // 0  10001000  111 0101 1111 1111 1111 1111
748 749 750 751
    EXPECT_TRUE(test::close_f(expected, upper_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({upper_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, bigger_than_upper_bound, tolerance_bits));
752
    EXPECT_FALSE(test::all_close_f(
753 754 755 756 757
        vector<float>({expected}), vector<float>({bigger_than_upper_bound}), tolerance_bits));
    EXPECT_TRUE(test::close_f(expected, lower_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({lower_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, smaller_than_lower_bound, tolerance_bits));
758
    EXPECT_FALSE(test::all_close_f(
759
        vector<float>({expected}), vector<float>({smaller_than_lower_bound}), tolerance_bits));
760 761 762
}

// For intuitive understanding of tightness of bounds in decimal
763
// Test bounds near 0, 1, 10, 100, 1000 with tolerance_bits = 2
764 765 766
//
//                                                           Targeted bit
//                                                           |
767 768
//            (22 bits must match, w/ implicit leading bit)  v
//                   2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
769
// s e e e e e e e e m m m m m m m m m m m m m m m m m m m m m m m
770 771 772
//                =>|        24 (w/ implicit leading bit)         |
//                                                           ^
//                                                           | 2  |<=
773 774
TEST(all_close_f, mantissa_24_near_0_1_10_100_1000)
{
775 776
    constexpr int tolerance_bits = 2;

777 778 779 780 781 782 783 784
    float expected;
    float upper_bound;
    float bigger_than_upper_bound;
    float lower_bound;
    float smaller_than_lower_bound;

    // Bounds around 0: 0 +- 5.6e-45
    expected = 0.f;
785 786 787 788
    upper_bound = test::bits_to_float("0  00000000  000 0000 0000 0000 0000 0100");
    bigger_than_upper_bound = test::bits_to_float("0  00000000  000 0000 0000 0000 0000 0101");
    lower_bound = test::bits_to_float("1  00000000  000 0000 0000 0000 0000 0100");
    smaller_than_lower_bound = test::bits_to_float("1  00000000  000 0000 0000 0000 0000 0101");
789 790 791 792
    EXPECT_TRUE(test::close_f(expected, upper_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({upper_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, bigger_than_upper_bound, tolerance_bits));
793
    EXPECT_FALSE(test::all_close_f(
794 795 796 797 798
        vector<float>({expected}), vector<float>({bigger_than_upper_bound}), tolerance_bits));
    EXPECT_TRUE(test::close_f(expected, lower_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({lower_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, smaller_than_lower_bound, tolerance_bits));
799
    EXPECT_FALSE(test::all_close_f(
800
        vector<float>({expected}), vector<float>({smaller_than_lower_bound}), tolerance_bits));
801 802 803

    // Bounds around 1: 1 +- 4.77e-7
    expected = 1.f;
804 805 806 807
    upper_bound = test::bits_to_float("0  01111111  000 0000 0000 0000 0000 0100");
    bigger_than_upper_bound = test::bits_to_float("0  01111111  000 0000 0000 0000 0000 0101");
    lower_bound = test::bits_to_float("0  01111110  111 1111 1111 1111 1111 1100");
    smaller_than_lower_bound = test::bits_to_float("0  01111110  111 1111 1111 1111 1111 1011");
808 809 810 811
    EXPECT_TRUE(test::close_f(expected, upper_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({upper_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, bigger_than_upper_bound, tolerance_bits));
812
    EXPECT_FALSE(test::all_close_f(
813 814 815 816 817
        vector<float>({expected}), vector<float>({bigger_than_upper_bound}), tolerance_bits));
    EXPECT_TRUE(test::close_f(expected, lower_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({lower_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, smaller_than_lower_bound, tolerance_bits));
818
    EXPECT_FALSE(test::all_close_f(
819
        vector<float>({expected}), vector<float>({smaller_than_lower_bound}), tolerance_bits));
820 821 822

    // Bounds around 10: 10 +- 3.81e-6
    expected = 10.f;
823 824 825 826
    upper_bound = test::bits_to_float("0  10000010  010 0000 0000 0000 0000 0100");
    bigger_than_upper_bound = test::bits_to_float("0  10000010  010 0000 0000 0000 0000 0101");
    lower_bound = test::bits_to_float("0  10000010  001 1111 1111 1111 1111 1100");
    smaller_than_lower_bound = test::bits_to_float("0  10000010  001 1111 1111 1111 1111 1011");
827 828 829 830
    EXPECT_TRUE(test::close_f(expected, upper_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({upper_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, bigger_than_upper_bound, tolerance_bits));
831
    EXPECT_FALSE(test::all_close_f(
832 833 834 835 836
        vector<float>({expected}), vector<float>({bigger_than_upper_bound}), tolerance_bits));
    EXPECT_TRUE(test::close_f(expected, lower_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({lower_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, smaller_than_lower_bound, tolerance_bits));
837
    EXPECT_FALSE(test::all_close_f(
838
        vector<float>({expected}), vector<float>({smaller_than_lower_bound}), tolerance_bits));
839 840 841

    // Bounds around 100: 100 +- 3.05e-5
    expected = 100.f;
842 843 844 845
    upper_bound = test::bits_to_float("0  10000101  100 1000 0000 0000 0000 0100");
    bigger_than_upper_bound = test::bits_to_float("0  10000101  100 1000 0000 0000 0000 0101");
    lower_bound = test::bits_to_float("0  10000101  100 0111 1111 1111 1111 1100");
    smaller_than_lower_bound = test::bits_to_float("0  10000101  100 0111 1111 1111 1111 1011");
846 847 848 849
    EXPECT_TRUE(test::close_f(expected, upper_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({upper_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, bigger_than_upper_bound, tolerance_bits));
850
    EXPECT_FALSE(test::all_close_f(
851 852 853 854 855
        vector<float>({expected}), vector<float>({bigger_than_upper_bound}), tolerance_bits));
    EXPECT_TRUE(test::close_f(expected, lower_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({lower_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, smaller_than_lower_bound, tolerance_bits));
856
    EXPECT_FALSE(test::all_close_f(
857
        vector<float>({expected}), vector<float>({smaller_than_lower_bound}), tolerance_bits));
858 859 860

    // Bounds around 1000: 1000 +- 2.44e-4
    expected = 1000.f;
861 862 863 864
    upper_bound = test::bits_to_float("0  10001000  111 1010 0000 0000 0000 0100");
    bigger_than_upper_bound = test::bits_to_float("0  10001000  111 1010 0000 0000 0000 0101");
    lower_bound = test::bits_to_float("0  10001000  111 1001 1111 1111 1111 1100");
    smaller_than_lower_bound = test::bits_to_float("0  10001000  111 1001 1111 1111 1111 1011");
865 866 867 868
    EXPECT_TRUE(test::close_f(expected, upper_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({upper_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, bigger_than_upper_bound, tolerance_bits));
869
    EXPECT_FALSE(test::all_close_f(
870 871 872 873 874
        vector<float>({expected}), vector<float>({bigger_than_upper_bound}), tolerance_bits));
    EXPECT_TRUE(test::close_f(expected, lower_bound, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({lower_bound}), tolerance_bits));
    EXPECT_FALSE(test::close_f(expected, smaller_than_lower_bound, tolerance_bits));
875
    EXPECT_FALSE(test::all_close_f(
876
        vector<float>({expected}), vector<float>({smaller_than_lower_bound}), tolerance_bits));
877 878 879 880 881 882 883 884 885 886 887
}

TEST(all_close_f, inf_nan)
{
    float zero = 0.f;
    float infinity = numeric_limits<float>::infinity();
    float neg_infinity = -numeric_limits<float>::infinity();
    float quiet_nan = numeric_limits<float>::quiet_NaN();
    float signaling_nan = numeric_limits<float>::signaling_NaN();

    EXPECT_FALSE(test::close_f(zero, infinity));
888
    EXPECT_FALSE(test::all_close_f(vector<float>({zero}), vector<float>({infinity})));
889
    EXPECT_FALSE(test::close_f(zero, neg_infinity));
890
    EXPECT_FALSE(test::all_close_f(vector<float>({zero}), vector<float>({neg_infinity})));
891
    EXPECT_FALSE(test::close_f(zero, quiet_nan));
892
    EXPECT_FALSE(test::all_close_f(vector<float>({zero}), vector<float>({quiet_nan})));
893
    EXPECT_FALSE(test::close_f(zero, signaling_nan));
894
    EXPECT_FALSE(test::all_close_f(vector<float>({zero}), vector<float>({signaling_nan})));
895

896 897 898 899 900 901 902 903
    EXPECT_TRUE(test::close_f(infinity, infinity));
    EXPECT_TRUE(test::all_close_f(vector<float>({infinity}), vector<float>({infinity})));
    EXPECT_TRUE(test::close_f(neg_infinity, neg_infinity));
    EXPECT_TRUE(test::all_close_f(vector<float>({neg_infinity}), vector<float>({neg_infinity})));
    EXPECT_TRUE(test::close_f(quiet_nan, quiet_nan));
    EXPECT_TRUE(test::all_close_f(vector<float>({quiet_nan}), vector<float>({quiet_nan})));
    EXPECT_TRUE(test::close_f(signaling_nan, signaling_nan));
    EXPECT_TRUE(test::all_close_f(vector<float>({signaling_nan}), vector<float>({signaling_nan})));
904
}
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922

TEST(all_close_f, double_inf_nan)
{
    double zero = 0.f;
    double infinity = numeric_limits<double>::infinity();
    double neg_infinity = -numeric_limits<double>::infinity();
    double quiet_nan = numeric_limits<double>::quiet_NaN();
    double signaling_nan = numeric_limits<double>::signaling_NaN();

    EXPECT_FALSE(test::close_f(zero, infinity));
    EXPECT_FALSE(test::all_close_f(vector<double>({zero}), vector<double>({infinity})));
    EXPECT_FALSE(test::close_f(zero, neg_infinity));
    EXPECT_FALSE(test::all_close_f(vector<double>({zero}), vector<double>({neg_infinity})));
    EXPECT_FALSE(test::close_f(zero, quiet_nan));
    EXPECT_FALSE(test::all_close_f(vector<double>({zero}), vector<double>({quiet_nan})));
    EXPECT_FALSE(test::close_f(zero, signaling_nan));
    EXPECT_FALSE(test::all_close_f(vector<double>({zero}), vector<double>({signaling_nan})));

923 924 925 926 927 928 929 930
    EXPECT_TRUE(test::close_f(infinity, infinity));
    EXPECT_TRUE(test::all_close_f(vector<double>({infinity}), vector<double>({infinity})));
    EXPECT_TRUE(test::close_f(neg_infinity, neg_infinity));
    EXPECT_TRUE(test::all_close_f(vector<double>({neg_infinity}), vector<double>({neg_infinity})));
    EXPECT_TRUE(test::close_f(quiet_nan, quiet_nan));
    EXPECT_TRUE(test::all_close_f(vector<double>({quiet_nan}), vector<double>({quiet_nan})));
    EXPECT_TRUE(test::close_f(signaling_nan, signaling_nan));
    EXPECT_TRUE(
931 932
        test::all_close_f(vector<double>({signaling_nan}), vector<double>({signaling_nan})));
}