blob: 865e9df70f7dfe0ae6ed2e250e8a0c6ba2fb50f5 [file]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Unit tests for floating-point integer check functions.
///
//===----------------------------------------------------------------------===//
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/bfloat16.h"
#include "src/__support/FPUtil/float128.h"
#include "src/__support/FPUtil/is_integer.h"
#include "src/__support/macros/properties/types.h"
#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
using LIBC_NAMESPACE::fputil::BFloat16;
using LIBC_NAMESPACE::fputil::Float128;
using LIBC_NAMESPACE::fputil::is_integer;
using LIBC_NAMESPACE::fputil::is_odd_integer;
template <typename T>
class IsIntegerTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
static T get_two_pow_frac() {
T result = T(1.0);
for (int i = 0; i < FPBits::FRACTION_LEN; ++i)
result *= T(2.0);
return result;
}
public:
void test_is_integer() {
EXPECT_TRUE(is_integer(zero));
EXPECT_TRUE(is_integer(neg_zero));
EXPECT_TRUE(is_integer(T(1.0)));
EXPECT_TRUE(is_integer(T(-1.0)));
EXPECT_TRUE(is_integer(T(2.0)));
EXPECT_TRUE(is_integer(T(-2.0)));
EXPECT_TRUE(is_integer(T(3.0)));
EXPECT_TRUE(is_integer(T(-3.0)));
EXPECT_TRUE(is_integer(T(10.0)));
EXPECT_TRUE(is_integer(T(-10.0)));
EXPECT_TRUE(is_integer(T(100.0)));
EXPECT_TRUE(is_integer(T(-100.0)));
EXPECT_FALSE(is_integer(T(0.5)));
EXPECT_FALSE(is_integer(T(-0.5)));
EXPECT_FALSE(is_integer(T(1.5)));
EXPECT_FALSE(is_integer(T(-1.5)));
EXPECT_FALSE(is_integer(T(0.25)));
EXPECT_FALSE(is_integer(T(-0.25)));
EXPECT_FALSE(is_integer(T(0.75)));
EXPECT_FALSE(is_integer(T(-0.75)));
EXPECT_FALSE(is_integer(min_denormal));
EXPECT_FALSE(is_integer(neg_min_denormal));
EXPECT_FALSE(is_integer(max_denormal));
T two_pow_frac = get_two_pow_frac();
EXPECT_TRUE(is_integer(two_pow_frac));
EXPECT_TRUE(is_integer(-two_pow_frac));
EXPECT_TRUE(is_integer(T(two_pow_frac - T(1.0))));
EXPECT_TRUE(is_integer(T(-(two_pow_frac - T(1.0)))));
EXPECT_TRUE(is_integer(T(two_pow_frac + T(1.0))));
EXPECT_TRUE(is_integer(T(-(two_pow_frac + T(1.0)))));
EXPECT_FALSE(is_integer(T(two_pow_frac - T(1.0) + T(0.5))));
EXPECT_FALSE(is_integer(T(-(two_pow_frac - T(1.0) + T(0.5)))));
}
void test_is_odd_integer() {
EXPECT_FALSE(is_odd_integer(zero));
EXPECT_FALSE(is_odd_integer(neg_zero));
EXPECT_TRUE(is_odd_integer(T(1.0)));
EXPECT_TRUE(is_odd_integer(T(-1.0)));
EXPECT_FALSE(is_odd_integer(T(2.0)));
EXPECT_FALSE(is_odd_integer(T(-2.0)));
EXPECT_TRUE(is_odd_integer(T(3.0)));
EXPECT_TRUE(is_odd_integer(T(-3.0)));
EXPECT_FALSE(is_odd_integer(T(4.0)));
EXPECT_FALSE(is_odd_integer(T(-4.0)));
EXPECT_TRUE(is_odd_integer(T(5.0)));
EXPECT_TRUE(is_odd_integer(T(-5.0)));
EXPECT_FALSE(is_odd_integer(T(10.0)));
EXPECT_FALSE(is_odd_integer(T(-10.0)));
EXPECT_TRUE(is_odd_integer(T(11.0)));
EXPECT_TRUE(is_odd_integer(T(-11.0)));
EXPECT_FALSE(is_odd_integer(T(0.5)));
EXPECT_FALSE(is_odd_integer(T(-0.5)));
EXPECT_FALSE(is_odd_integer(T(1.5)));
EXPECT_FALSE(is_odd_integer(T(-1.5)));
EXPECT_FALSE(is_odd_integer(T(2.5)));
EXPECT_FALSE(is_odd_integer(T(-2.5)));
EXPECT_FALSE(is_odd_integer(min_denormal));
EXPECT_FALSE(is_odd_integer(neg_min_denormal));
EXPECT_FALSE(is_odd_integer(max_denormal));
T two_pow_frac = get_two_pow_frac();
EXPECT_FALSE(is_odd_integer(two_pow_frac));
EXPECT_FALSE(is_odd_integer(-two_pow_frac));
EXPECT_TRUE(is_odd_integer(T(two_pow_frac - T(1.0))));
EXPECT_TRUE(is_odd_integer(T(-(two_pow_frac - T(1.0)))));
EXPECT_TRUE(is_odd_integer(T(two_pow_frac + T(1.0))));
EXPECT_TRUE(is_odd_integer(T(-(two_pow_frac + T(1.0)))));
EXPECT_FALSE(is_odd_integer(T(two_pow_frac + T(2.0))));
EXPECT_FALSE(is_odd_integer(T(-(two_pow_frac + T(2.0)))));
T two_pow_frac_plus_1 = two_pow_frac * T(2.0);
EXPECT_FALSE(is_odd_integer(two_pow_frac_plus_1));
EXPECT_FALSE(is_odd_integer(-two_pow_frac_plus_1));
}
};
#define TEST_IS_INTEGER(Name, Type) \
using LlvmLibc##Name##IsIntegerTest = IsIntegerTest<Type>; \
TEST_F(LlvmLibc##Name##IsIntegerTest, IsInteger) { test_is_integer(); } \
TEST_F(LlvmLibc##Name##IsIntegerTest, IsOddInteger) { test_is_odd_integer(); }
TEST_IS_INTEGER(Float, float)
TEST_IS_INTEGER(Double, double)
TEST_IS_INTEGER(LongDouble, long double)
#ifdef LIBC_TYPES_HAS_FLOAT16
TEST_IS_INTEGER(Float16, float16)
#endif // LIBC_TYPES_HAS_FLOAT16
#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
TEST_IS_INTEGER(DFloat128, float128)
#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
TEST_IS_INTEGER(Float128, Float128)
TEST_IS_INTEGER(BFloat16, BFloat16)
TEST(LlvmLibcIsIntegerConstexprTest, ConstexprEval) {
static_assert(is_integer(0.0));
static_assert(is_integer(-0.0));
static_assert(is_integer(1.0));
static_assert(is_integer(-1.0));
static_assert(is_integer(2.0));
static_assert(is_integer(-2.0));
static_assert(!is_integer(0.5));
static_assert(!is_integer(-0.5));
static_assert(!is_integer(1.5));
static_assert(!is_integer(-1.5));
static_assert(!is_odd_integer(0.0));
static_assert(!is_odd_integer(-0.0));
static_assert(is_odd_integer(1.0));
static_assert(is_odd_integer(-1.0));
static_assert(!is_odd_integer(2.0));
static_assert(!is_odd_integer(-2.0));
static_assert(is_odd_integer(3.0));
static_assert(is_odd_integer(-3.0));
static_assert(!is_odd_integer(0.5));
static_assert(!is_odd_integer(-0.5));
static_assert(!is_odd_integer(1.5));
static_assert(!is_odd_integer(-1.5));
static_assert(is_integer(0.0f));
static_assert(is_integer(-0.0f));
static_assert(is_integer(1.0f));
static_assert(is_integer(-1.0f));
static_assert(is_integer(2.0f));
static_assert(!is_integer(0.5f));
static_assert(!is_odd_integer(0.0f));
static_assert(is_odd_integer(1.0f));
static_assert(!is_odd_integer(2.0f));
static_assert(is_odd_integer(3.0f));
static_assert(!is_odd_integer(0.5f));
}