all_close_f.cpp 42 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 27 28 29 30 31
#include <bitset>
#include <cmath>
#include <limits>
#include <sstream>

#include "gtest/gtest.h"

#include "ngraph/ngraph.hpp"
#include "util/all_close_f.hpp"

using namespace std;
using namespace ngraph;

union FloatUnion {
32 33 34
    FloatUnion() { i = 0; }
    FloatUnion(float val) { f = val; }
    FloatUnion(uint32_t val) { i = val; }
35 36 37 38
    float f;
    uint32_t i;
};

39 40 41 42 43 44 45 46
union DoubleUnion {
    DoubleUnion() { i = 0; }
    DoubleUnion(double val) { d = val; }
    DoubleUnion(uint64_t val) { i = val; }
    double d;
    uint64_t i;
};

47 48 49 50 51
string float_to_bits(float f)
{
    FloatUnion fu{f};
    stringstream ss;
    ss << bitset<32>(fu.i);
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
    string unformatted = ss.str();
    string formatted;
    formatted.reserve(41);
    // Sign
    formatted.push_back(unformatted[0]);
    formatted.append("  ");
    // Exponent
    formatted.append(unformatted, 1, 8);
    formatted.append("  ");
    // Mantissa
    formatted.append(unformatted, 9, 3);
    for (int i = 12; i < 32; i += 4)
    {
        formatted.push_back(' ');
        formatted.append(unformatted, i, 4);
    }
    return formatted;
69 70
}

71 72 73 74 75
string double_to_bits(double d)
{
    DoubleUnion du{d};
    stringstream ss;
    ss << bitset<64>(du.i);
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
    string unformatted = ss.str();
    string formatted;
    formatted.reserve(80);
    // Sign
    formatted.push_back(unformatted[0]);
    formatted.append("  ");
    // Exponent
    formatted.append(unformatted, 1, 11);
    formatted.push_back(' ');
    // Mantissa
    for (int i = 12; i < 64; i += 4)
    {
        formatted.push_back(' ');
        formatted.append(unformatted, i, 4);
    }
    return formatted;
92 93
}

94 95
float bits_to_float(const string& s)
{
96 97 98 99 100
    string unformatted = s;
    unformatted.erase(remove_if(unformatted.begin(), unformatted.end(), ::isspace),
                      unformatted.end());

    if (unformatted.size() != 32)
101 102 103
    {
        throw ngraph_error("Input length must be 32");
    }
104
    bitset<32> bs(unformatted);
105 106 107 108 109
    FloatUnion fu;
    fu.i = static_cast<uint32_t>(bs.to_ulong());
    return fu.f;
}

110 111
double bits_to_double(const string& s)
{
112 113 114 115 116
    string unformatted = s;
    unformatted.erase(remove_if(unformatted.begin(), unformatted.end(), ::isspace),
                      unformatted.end());

    if (unformatted.size() != 64)
117 118 119
    {
        throw ngraph_error("Input length must be 64");
    }
120
    bitset<64> bs(unformatted);
121 122 123 124 125
    DoubleUnion du;
    du.i = static_cast<uint64_t>(bs.to_ullong());
    return du.d;
}

126
class all_close_f_param_test : public testing::TestWithParam<::std::tuple<float, int>>
127 128 129 130 131 132 133 134
{
protected:
    all_close_f_param_test()
        : upper_bound(FLT_MAX)
        , lower_bound(-FLT_MAX)
        , past_upper_bound(FLT_MAX)
        , past_lower_bound(-FLT_MAX)
    {
135
        std::tie(expected, tolerance_bits) = GetParam();
136 137 138
    }
    void SetUp() override
    {
139
        constexpr int mantissa_bits = 24;
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
        uint32_t expected_as_int = FloatUnion(expected).i;

        // 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;
            upper_bound = FloatUnion(upper_bound_as_int).f;
            past_upper_bound = FloatUnion(upper_bound_as_int + 1).f;

            uint32_t lower_bound_as_int = expected_as_int - targeted_bit;
            lower_bound = FloatUnion(lower_bound_as_int).f;
            past_lower_bound = FloatUnion(lower_bound_as_int - 1).f;
        }
        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;
            lower_bound = FloatUnion(lower_bound_as_int).f;
            past_lower_bound = FloatUnion(lower_bound_as_int + 1).f;

            uint32_t upper_bound_as_int = expected_as_int - targeted_bit;
            upper_bound = FloatUnion(upper_bound_as_int).f;
            past_upper_bound = FloatUnion(upper_bound_as_int - 1).f;
        }
        else // (expected == 0.f) || (expected == -0.f)
        {
            // Special handling of 0 / -0 which get same bounds
            uint32_t upper_bound_as_int = targeted_bit;
            upper_bound = FloatUnion(upper_bound_as_int).f;
            uint32_t past_upper_bound_as_int = upper_bound_as_int + 1;
            past_upper_bound = FloatUnion(past_upper_bound_as_int).f;

            lower_bound = FloatUnion(upper_bound_as_int | 0x80000000).f;
            past_lower_bound = FloatUnion(past_upper_bound_as_int | 0x80000000).f;
        }
    }

    float expected;
    int tolerance_bits;
    float upper_bound;
    float lower_bound;
    float past_upper_bound;
    float past_lower_bound;
};

TEST_P(all_close_f_param_test, test_boundaries)
{
193 194 195
    if (std::getenv("NGRAPH_GTEST_INFO") != nullptr)
    {
        // Print short string documenting which test is being run
196
        std::cout << "[   INFO   ] Test params: (" << expected << ", " << tolerance_bits << ")\n";
197
    }
198 199 200 201

    // Format verbose info to only print out in case of test failure
    stringstream ss;
    ss << "Testing target of: " << expected << " (" << float_to_bits(expected) << ")\n";
202
    ss << "Matching to targets with: " << tolerance_bits << " tolerance_bits\n";
203 204 205 206 207 208 209
    ss << "upper_bound: " << upper_bound << " (" << float_to_bits(upper_bound) << ")\n";
    ss << "lower_bound: " << lower_bound << " (" << float_to_bits(lower_bound) << ")\n";
    ss << "past_upper_bound: " << past_upper_bound << " (" << float_to_bits(past_upper_bound)
       << ")\n";
    ss << "past_lower_bound: " << past_lower_bound << " (" << float_to_bits(past_lower_bound)
       << ")\n";

210 211 212
    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))
213
        << ss.str();
214 215 216
    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))
217
        << ss.str();
218 219 220
    EXPECT_FALSE(test::close_f(expected, past_upper_bound, tolerance_bits)) << ss.str();
    EXPECT_FALSE(test::all_close_f(
        vector<float>({expected}), vector<float>({past_upper_bound}), tolerance_bits))
221
        << ss.str();
222 223 224
    EXPECT_FALSE(test::close_f(expected, past_lower_bound, tolerance_bits)) << ss.str();
    EXPECT_FALSE(test::all_close_f(
        vector<float>({expected}), vector<float>({past_lower_bound}), tolerance_bits))
225 226 227
        << ss.str();
}

228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
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)), );
245 246 247 248 249

class all_close_f_double_param_test : public testing::TestWithParam<::std::tuple<double, int>>
{
protected:
    all_close_f_double_param_test()
250
        : upper_bound(DBL_MAX)
251 252 253 254 255 256 257 258
        , lower_bound(-DBL_MAX)
        , past_upper_bound(DBL_MAX)
        , past_lower_bound(-DBL_MAX)
    {
        std::tie(expected, tolerance_bits) = GetParam();
    }
    void SetUp() override
    {
259
        constexpr int mantissa_bits = 53;
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
        uint64_t expected_as_int = DoubleUnion(expected).i;
        // 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;
            upper_bound = DoubleUnion(upper_bound_as_int).d;
            past_upper_bound = DoubleUnion(upper_bound_as_int + 1).d;

            uint64_t lower_bound_as_int = expected_as_int - targeted_bit;
            lower_bound = DoubleUnion(lower_bound_as_int).d;
            past_lower_bound = DoubleUnion(lower_bound_as_int - 1).d;
        }
        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;
            lower_bound = DoubleUnion(lower_bound_as_int).d;
            past_lower_bound = DoubleUnion(lower_bound_as_int + 1).d;

            uint64_t upper_bound_as_int = expected_as_int - targeted_bit;
            upper_bound = DoubleUnion(upper_bound_as_int).d;
            past_upper_bound = DoubleUnion(upper_bound_as_int - 1).d;
        }
        else // (expected == 0.) || (expected == -0.)
        {
            // Special handling of 0 / -0 which get same bounds
            uint64_t upper_bound_as_int = targeted_bit;
            upper_bound = DoubleUnion(upper_bound_as_int).d;
            uint64_t past_upper_bound_as_int = upper_bound_as_int + 1;
            past_upper_bound = DoubleUnion(past_upper_bound_as_int).d;

            lower_bound = DoubleUnion(upper_bound_as_int | 0x8000000000000000).d;
            past_lower_bound = DoubleUnion(past_upper_bound_as_int | 0x8000000000000000).d;
        }
    }

    double expected;
    int tolerance_bits;
    double upper_bound;
    double lower_bound;
    double past_upper_bound;
    double past_lower_bound;
};

TEST_P(all_close_f_double_param_test, test_boundaries)
{
312 313 314 315 316
    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";
    }
317 318 319 320 321

    // Format verbose info to only print out in case of test failure

    stringstream ss;
    ss << "Testing target of: " << expected << " (" << double_to_bits(expected) << ")\n";
322
    ss << "Matching to targets with: " << tolerance_bits << " tolerance_bits\n";
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
    ss << "upper_bound: " << upper_bound << " (" << double_to_bits(upper_bound) << ")\n";
    ss << "lower_bound: " << lower_bound << " (" << double_to_bits(lower_bound) << ")\n";
    ss << "past_upper_bound: " << past_upper_bound << " (" << double_to_bits(past_upper_bound)
       << ")\n";
    ss << "past_lower_bound: " << past_lower_bound << " (" << double_to_bits(past_lower_bound)
       << ")\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();
    EXPECT_FALSE(test::all_close_f(
        vector<double>({expected}), vector<double>({past_upper_bound}), tolerance_bits))
        << ss.str();
    EXPECT_FALSE(test::close_f(expected, past_lower_bound, tolerance_bits)) << ss.str();
    EXPECT_FALSE(test::all_close_f(
        vector<double>({expected}), vector<double>({past_lower_bound}), tolerance_bits))
        << ss.str();
}

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)), );

356 357
// Test the exact bounds near +0.f
//
358 359
// With tolerance_bits = 18
// (equivalent to testing bfloat precision with 2 bits tolerance)
360 361 362 363
//
//                           Targeted bit
//                           |
//                           v
364
//                   2 3 4 5 6    (error allowed in 6th bit or later, w/ implicit leading bit)
365
// 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
366 367 368
//                =>|      8      |    (8 w/ implicit leading bit)
//                           ^
//                           |  2 |<=
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
//
// [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)
{
395 396
    constexpr int tolerance_bits = (FLOAT_MANTISSA_BITS - BFLOAT_MANTISSA_BITS + 2);

397
    // 0.f, the ground-truth value
398
    float expected = bits_to_float("0  00000000  000 0000 0000 0000 0000 0000");
399 400 401
    float computed;

    // ~3.67342E-40, the exact upper bound
402
    computed = bits_to_float("0  00000000  000 0100 0000 0000 0000 0000");
403 404 405
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
406 407

    // ~3.67343E-40, the next representable number bigger than upper bound
408
    computed = bits_to_float("0  00000000  000 0100 0000 0000 0000 0001");
409 410 411
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
412 413

    // ~-3.67342E-40, the exact lower bound
414
    computed = bits_to_float("1  00000000  000 0100 0000 0000 0000 0000");
415 416 417
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
418 419

    // ~-3.67343E-40, the next representable number smaller than lower bound
420
    computed = bits_to_float("1  00000000  000 0100 0000 0000 0000 0001");
421 422 423
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
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 = bits_to_float("1  00000000  000 0000 0000 0000 0000 0000");
469 470 471
    float computed;

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

    // ~3.67343E-40, the next representable number bigger than upper bound
478
    computed = bits_to_float("0  00000000  000 0100 0000 0000 0000 0001");
479 480 481
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
482 483

    // ~-3.67342E-40, the exact lower bound
484
    computed = bits_to_float("1  00000000  000 0100 0000 0000 0000 0000");
485 486 487
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
488 489

    // ~-3.67343E-40, the next representable number smaller than lower bound
490
    computed = bits_to_float("1  00000000  000 0100 0000 0000 0000 0001");
491 492 493
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
494 495 496 497
}

// Test the exact bounds near 1.f
//
498 499
// With tolerance_bits = 18
// (equivalent to testing bfloat precision with 2 bits tolerance)
500 501 502 503
//
//                           Targeted bit
//                           |
//                           v
504
//                   2 3 4 5 6    (error allowed in 6th bit or later, w/ implicit leading bit)
505
// 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
506 507 508
//                =>|      8      |    (8 w/ implicit leading bit)
//                           ^
//                           |  2 |<=
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
//
// [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)
{
529 530
    constexpr int tolerance_bits = (FLOAT_MANTISSA_BITS - BFLOAT_MANTISSA_BITS + 2);

531
    // 1.f, the ground-truth value
532
    float expected = bits_to_float("0  01111111  000 0000 0000 0000 0000 0000");
533 534 535
    float computed;

    // 1.03125f, the exact upper bound
536
    computed = bits_to_float("0  01111111  000 0100 0000 0000 0000 0000");
537 538 539
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
540 541

    // 1.031250119f, the next representable number bigger than upper bound
542
    computed = bits_to_float("0  01111111  000 0100 0000 0000 0000 0001");
543 544 545
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
546 547

    // 0.984375f, the exact lower bound
548
    computed = bits_to_float("0  01111110  111 1100 0000 0000 0000 0000");
549 550 551
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
552 553

    // 0.9843749404f, the next representable number smaller than lower bound
554
    computed = bits_to_float("0  01111110  111 1011 1111 1111 1111 1111");
555 556 557
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
558 559 560 561
}

// Test the exact bounds near -1.f
//
562 563
// With tolerance_bits = 18
// (equivalent to testing bfloat precision with 2 bits tolerance)
564 565 566 567
//
//                           Targeted bit
//                           |
//                           v
568
//                   2 3 4 5 6    (error allowed in 6th bit or later, w/ implicit leading bit)
569
// 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
570 571 572
//                =>|      8      |    (8 w/ implicit leading bit)
//                           ^
//                           |  2 |<=
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
//
// [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)
{
593 594
    constexpr int tolerance_bits = (FLOAT_MANTISSA_BITS - BFLOAT_MANTISSA_BITS + 2);

595
    // -1.f, the ground-truth value
596
    float expected = bits_to_float("1  01111111  000 0000 0000 0000 0000 0000");
597 598 599
    float computed;

    // -0.984375f, the exact upper bound
600
    computed = bits_to_float("1  01111110  111 1100 0000 0000 0000 0000");
601 602 603
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
604 605

    // -0.984374940395355224609375f, the next representable number bigger than upper bound
606
    computed = bits_to_float("1  01111110  111 1011 1111 1111 1111 1111");
607 608 609
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
610 611

    // -1.03125f, the exact lower bound
612
    computed = bits_to_float("1  01111111  000 0100 0000 0000 0000 0000");
613 614 615
    EXPECT_TRUE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_TRUE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
616 617

    // -1.03125011920928955078125f, the next representable number smaller than lower bound
618
    computed = bits_to_float("1  01111111  000 0100 0000 0000 0000 0001");
619 620 621
    EXPECT_FALSE(test::close_f(expected, computed, tolerance_bits));
    EXPECT_FALSE(
        test::all_close_f(vector<float>({expected}), vector<float>({computed}), tolerance_bits));
622 623 624
}

// For intuitive understanding of tightness of bounds in decimal
625
// Test bounds near 0, 1, 10, 100, 1000 with tolerance_bits = 18
626 627 628 629
//
//                           Targeted bit
//                           |
//                           v
630
//                   2 3 4 5 6    (error allowed in 6th bit or later, w/ implicit leading bit)
631
// 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
632 633 634
//                =>|      8      |    (8 w/ implicit leading bit)
//                           ^
//                           |  2 |<=
635 636
TEST(all_close_f, mantissa_8_near_0_1_10_100_1000)
{
637 638
    constexpr int tolerance_bits = (FLOAT_MANTISSA_BITS - BFLOAT_MANTISSA_BITS + 2);

639 640 641 642 643 644 645
    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
646 647 648 649 650 651 652
    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
653 654 655 656
    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));
657
    EXPECT_FALSE(test::all_close_f(
658 659 660 661 662
        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));
663
    EXPECT_FALSE(test::all_close_f(
664
        vector<float>({expected}), vector<float>({smaller_than_lower_bound}), tolerance_bits));
665 666

    // Bounds around 1: 1 +- 0.03
667 668 669 670 671
    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
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 10: 10 +- 0.25
686 687 688 689 690
    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
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 100: 100 +- 2
705 706 707 708 709
    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
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 1000: 1000 +- 16
724 725 726 727 728
    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
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 743
}

// For intuitive understanding of tightness of bounds in decimal
744
// Test bounds near 0, 1, 10, 100, 1000 with tolerance_bits = 2
745 746 747
//
//                                                           Targeted bit
//                                                           |
748 749
//            (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
750
// 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
751 752 753
//                =>|        24 (w/ implicit leading bit)         |
//                                                           ^
//                                                           | 2  |<=
754 755
TEST(all_close_f, mantissa_24_near_0_1_10_100_1000)
{
756 757
    constexpr int tolerance_bits = 2;

758 759 760 761 762 763 764 765
    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;
766 767 768 769
    upper_bound = bits_to_float("0  00000000  000 0000 0000 0000 0000 0100");
    bigger_than_upper_bound = bits_to_float("0  00000000  000 0000 0000 0000 0000 0101");
    lower_bound = bits_to_float("1  00000000  000 0000 0000 0000 0000 0100");
    smaller_than_lower_bound = bits_to_float("1  00000000  000 0000 0000 0000 0000 0101");
770 771 772 773
    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));
774
    EXPECT_FALSE(test::all_close_f(
775 776 777 778 779
        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));
780
    EXPECT_FALSE(test::all_close_f(
781
        vector<float>({expected}), vector<float>({smaller_than_lower_bound}), tolerance_bits));
782 783 784

    // Bounds around 1: 1 +- 4.77e-7
    expected = 1.f;
785 786 787 788
    upper_bound = bits_to_float("0  01111111  000 0000 0000 0000 0000 0100");
    bigger_than_upper_bound = bits_to_float("0  01111111  000 0000 0000 0000 0000 0101");
    lower_bound = bits_to_float("0  01111110  111 1111 1111 1111 1111 1100");
    smaller_than_lower_bound = bits_to_float("0  01111110  111 1111 1111 1111 1111 1011");
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 10: 10 +- 3.81e-6
    expected = 10.f;
804 805 806 807
    upper_bound = bits_to_float("0  10000010  010 0000 0000 0000 0000 0100");
    bigger_than_upper_bound = bits_to_float("0  10000010  010 0000 0000 0000 0000 0101");
    lower_bound = bits_to_float("0  10000010  001 1111 1111 1111 1111 1100");
    smaller_than_lower_bound = bits_to_float("0  10000010  001 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 100: 100 +- 3.05e-5
    expected = 100.f;
823 824 825 826
    upper_bound = bits_to_float("0  10000101  100 1000 0000 0000 0000 0100");
    bigger_than_upper_bound = bits_to_float("0  10000101  100 1000 0000 0000 0000 0101");
    lower_bound = bits_to_float("0  10000101  100 0111 1111 1111 1111 1100");
    smaller_than_lower_bound = bits_to_float("0  10000101  100 0111 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 1000: 1000 +- 2.44e-4
    expected = 1000.f;
842 843 844 845
    upper_bound = bits_to_float("0  10001000  111 1010 0000 0000 0000 0100");
    bigger_than_upper_bound = bits_to_float("0  10001000  111 1010 0000 0000 0000 0101");
    lower_bound = bits_to_float("0  10001000  111 1001 1111 1111 1111 1100");
    smaller_than_lower_bound = bits_to_float("0  10001000  111 1001 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 861 862 863 864 865 866 867 868
}

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));
869
    EXPECT_FALSE(test::all_close_f(vector<float>({zero}), vector<float>({infinity})));
870
    EXPECT_FALSE(test::close_f(zero, neg_infinity));
871
    EXPECT_FALSE(test::all_close_f(vector<float>({zero}), vector<float>({neg_infinity})));
872
    EXPECT_FALSE(test::close_f(zero, quiet_nan));
873
    EXPECT_FALSE(test::all_close_f(vector<float>({zero}), vector<float>({quiet_nan})));
874
    EXPECT_FALSE(test::close_f(zero, signaling_nan));
875
    EXPECT_FALSE(test::all_close_f(vector<float>({zero}), vector<float>({signaling_nan})));
876 877

    EXPECT_FALSE(test::close_f(infinity, infinity));
878
    EXPECT_FALSE(test::all_close_f(vector<float>({infinity}), vector<float>({infinity})));
879
    EXPECT_FALSE(test::close_f(neg_infinity, neg_infinity));
880
    EXPECT_FALSE(test::all_close_f(vector<float>({neg_infinity}), vector<float>({neg_infinity})));
881
    EXPECT_FALSE(test::close_f(quiet_nan, quiet_nan));
882
    EXPECT_FALSE(test::all_close_f(vector<float>({quiet_nan}), vector<float>({quiet_nan})));
883
    EXPECT_FALSE(test::close_f(signaling_nan, signaling_nan));
884
    EXPECT_FALSE(test::all_close_f(vector<float>({signaling_nan}), vector<float>({signaling_nan})));
885
}
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913

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})));

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