blob: 7864ee9011239df00a3de2b2fc6e2ff847391979 [file] [edit]
//===----------------------------------------------------------------------===//
//
// 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
/// Floating-point integer check functions.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_IS_INTEGER_H
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_IS_INTEGER_H
#include "src/__support/CPP/bit.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
// These helpers require finite inputs.
// Check if x is an odd integer: its lowest set significand bit must be at the
// unit position, so x_e + lsb == UNIT_EXPONENT.
template <typename T> LIBC_INLINE constexpr bool is_odd_integer(T x) {
using FPBits = FPBits<T>;
using StorageType = typename FPBits::StorageType;
FPBits xbits(x);
StorageType x_u = xbits.uintval();
unsigned x_e = static_cast<unsigned>(xbits.get_biased_exponent());
unsigned lsb = static_cast<unsigned>(
cpp::countr_zero(static_cast<StorageType>(x_u | FPBits::EXP_MASK)));
constexpr unsigned UNIT_EXPONENT =
static_cast<unsigned>(FPBits::EXP_BIAS + FPBits::FRACTION_LEN);
return x_e + lsb == UNIT_EXPONENT;
}
// Check if x is an integer: its lowest set significand bit must be at or above
// the unit position, so x_e + lsb >= UNIT_EXPONENT.
template <typename T> LIBC_INLINE constexpr bool is_integer(T x) {
using FPBits = FPBits<T>;
using StorageType = typename FPBits::StorageType;
FPBits xbits(x);
if (xbits.is_zero())
return true;
StorageType x_u = xbits.uintval();
unsigned x_e = static_cast<unsigned>(xbits.get_biased_exponent());
unsigned lsb = static_cast<unsigned>(
cpp::countr_zero(static_cast<StorageType>(x_u | FPBits::EXP_MASK)));
constexpr unsigned UNIT_EXPONENT =
static_cast<unsigned>(FPBits::EXP_BIAS + FPBits::FRACTION_LEN);
return x_e + lsb >= UNIT_EXPONENT;
}
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_IS_INTEGER_H