[libc] Add implementations of round and roundf.
Reviewers: asteinhauser Differential Revision: https://reviews.llvm.org/D80779
This commit is contained in:
parent
9ec57cce62
commit
4be1c116ad
|
@ -160,6 +160,7 @@ def MathAPI : PublicAPI<"math.h"> {
|
||||||
"expf",
|
"expf",
|
||||||
"exp2f",
|
"exp2f",
|
||||||
"round",
|
"round",
|
||||||
|
"roundf",
|
||||||
"sincosf",
|
"sincosf",
|
||||||
"sinf",
|
"sinf",
|
||||||
"trunc",
|
"trunc",
|
||||||
|
|
|
@ -55,6 +55,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||||
libc.src.math.floor
|
libc.src.math.floor
|
||||||
libc.src.math.floorf
|
libc.src.math.floorf
|
||||||
libc.src.math.round
|
libc.src.math.round
|
||||||
|
libc.src.math.roundf
|
||||||
libc.src.math.sincosf
|
libc.src.math.sincosf
|
||||||
libc.src.math.sinf
|
libc.src.math.sinf
|
||||||
libc.src.math.trunc
|
libc.src.math.trunc
|
||||||
|
|
|
@ -9,9 +9,3 @@ add_entrypoint_library(
|
||||||
DEPENDS
|
DEPENDS
|
||||||
${TARGET_LIBM_ENTRYPOINTS}
|
${TARGET_LIBM_ENTRYPOINTS}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_redirector_library(
|
|
||||||
llvmlibc_redirectors
|
|
||||||
DEPENDS
|
|
||||||
round_redirector
|
|
||||||
)
|
|
||||||
|
|
|
@ -203,6 +203,7 @@ def StdC : StandardSpec<"stdc"> {
|
||||||
FunctionSpec<"exp2f", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
|
FunctionSpec<"exp2f", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
|
||||||
|
|
||||||
FunctionSpec<"round", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
|
FunctionSpec<"round", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
|
||||||
|
FunctionSpec<"roundf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
|
||||||
|
|
||||||
FunctionSpec<"trunc", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
|
FunctionSpec<"trunc", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
|
||||||
FunctionSpec<"truncf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
|
FunctionSpec<"truncf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
|
||||||
|
|
|
@ -20,21 +20,6 @@ add_object_library(
|
||||||
.math_utils
|
.math_utils
|
||||||
)
|
)
|
||||||
|
|
||||||
add_entrypoint_object(
|
|
||||||
round
|
|
||||||
REDIRECTED
|
|
||||||
SRCS
|
|
||||||
round.cpp
|
|
||||||
HDRS
|
|
||||||
round.h
|
|
||||||
)
|
|
||||||
|
|
||||||
add_redirector_object(
|
|
||||||
round_redirector
|
|
||||||
SRC
|
|
||||||
round_redirector.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_entrypoint_object(
|
add_entrypoint_object(
|
||||||
cosf
|
cosf
|
||||||
SRCS
|
SRCS
|
||||||
|
@ -151,6 +136,26 @@ add_entrypoint_object(
|
||||||
libc.utils.FPUtil.fputil
|
libc.utils.FPUtil.fputil
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_entrypoint_object(
|
||||||
|
round
|
||||||
|
SRCS
|
||||||
|
round.cpp
|
||||||
|
HDRS
|
||||||
|
round.h
|
||||||
|
DEPENDS
|
||||||
|
libc.utils.FPUtil.fputil
|
||||||
|
)
|
||||||
|
|
||||||
|
add_entrypoint_object(
|
||||||
|
roundf
|
||||||
|
SRCS
|
||||||
|
roundf.cpp
|
||||||
|
HDRS
|
||||||
|
roundf.h
|
||||||
|
DEPENDS
|
||||||
|
libc.utils.FPUtil.fputil
|
||||||
|
)
|
||||||
|
|
||||||
add_object_library(
|
add_object_library(
|
||||||
exp_utils
|
exp_utils
|
||||||
HDRS
|
HDRS
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//===-- Implementation of round -------------------------------------------===//
|
//===-- Implementation of round function ----------------------------------===//
|
||||||
//
|
//
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
@ -6,16 +6,11 @@
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "src/math/round.h"
|
|
||||||
|
|
||||||
#include "src/__support/common.h"
|
#include "src/__support/common.h"
|
||||||
|
#include "utils/FPUtil/FloatOperations.h"
|
||||||
|
|
||||||
namespace __llvm_libc {
|
namespace __llvm_libc {
|
||||||
|
|
||||||
double __round_redirector(double x);
|
double LLVM_LIBC_ENTRYPOINT(round)(double x) { return fputil::round(x); }
|
||||||
|
|
||||||
double LLVM_LIBC_ENTRYPOINT(round)(double x) {
|
|
||||||
return __round_redirector(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace __llvm_libc
|
} // namespace __llvm_libc
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//===-- Implementation of round redirector --------------------------------===//
|
//===-- Implementation of roundf function ---------------------------------===//
|
||||||
//
|
//
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
@ -6,14 +6,11 @@
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// Include okay for this redirector.
|
#include "src/__support/common.h"
|
||||||
// NOLINTNEXTLINE(llvmlibc-restrict-system-libc-headers)
|
#include "utils/FPUtil/FloatOperations.h"
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
namespace __llvm_libc {
|
namespace __llvm_libc {
|
||||||
|
|
||||||
double __round_redirector(double x) {
|
float LLVM_LIBC_ENTRYPOINT(roundf)(float x) { return fputil::round(x); }
|
||||||
return ::round(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace __llvm_libc
|
} // namespace __llvm_libc
|
18
libc/src/math/roundf.h
Normal file
18
libc/src/math/roundf.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
//===-- Implementation header for roundf ------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_LIBC_SRC_MATH_ROUNDF_H
|
||||||
|
#define LLVM_LIBC_SRC_MATH_ROUNDF_H
|
||||||
|
|
||||||
|
namespace __llvm_libc {
|
||||||
|
|
||||||
|
float roundf(float x);
|
||||||
|
|
||||||
|
} // namespace __llvm_libc
|
||||||
|
|
||||||
|
#endif // LLVM_LIBC_SRC_MATH_ROUNDF_H
|
|
@ -175,6 +175,32 @@ add_math_unittest(
|
||||||
libc.utils.FPUtil.fputil
|
libc.utils.FPUtil.fputil
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_math_unittest(
|
||||||
|
round_test
|
||||||
|
NEED_MPFR
|
||||||
|
SUITE
|
||||||
|
libc_math_unittests
|
||||||
|
SRCS
|
||||||
|
round_test.cpp
|
||||||
|
DEPENDS
|
||||||
|
libc.include.math
|
||||||
|
libc.src.math.round
|
||||||
|
libc.utils.FPUtil.fputil
|
||||||
|
)
|
||||||
|
|
||||||
|
add_math_unittest(
|
||||||
|
roundf_test
|
||||||
|
NEED_MPFR
|
||||||
|
SUITE
|
||||||
|
libc_math_unittests
|
||||||
|
SRCS
|
||||||
|
roundf_test.cpp
|
||||||
|
DEPENDS
|
||||||
|
libc.include.math
|
||||||
|
libc.src.math.roundf
|
||||||
|
libc.utils.FPUtil.fputil
|
||||||
|
)
|
||||||
|
|
||||||
add_math_unittest(
|
add_math_unittest(
|
||||||
expf_test
|
expf_test
|
||||||
NEED_MPFR
|
NEED_MPFR
|
||||||
|
|
84
libc/test/src/math/round_test.cpp
Normal file
84
libc/test/src/math/round_test.cpp
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
//===-- Unittests for round -----------------------------------------------===//
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "include/math.h"
|
||||||
|
#include "src/math/round.h"
|
||||||
|
#include "utils/FPUtil/BitPatterns.h"
|
||||||
|
#include "utils/FPUtil/FloatOperations.h"
|
||||||
|
#include "utils/FPUtil/FloatProperties.h"
|
||||||
|
#include "utils/MPFRWrapper/MPFRUtils.h"
|
||||||
|
#include "utils/UnitTest/Test.h"
|
||||||
|
|
||||||
|
using __llvm_libc::fputil::valueAsBits;
|
||||||
|
using __llvm_libc::fputil::valueFromBits;
|
||||||
|
|
||||||
|
using BitPatterns = __llvm_libc::fputil::BitPatterns<double>;
|
||||||
|
using Properties = __llvm_libc::fputil::FloatProperties<double>;
|
||||||
|
|
||||||
|
namespace mpfr = __llvm_libc::testing::mpfr;
|
||||||
|
|
||||||
|
// Zero tolerance; As in, exact match with MPFR result.
|
||||||
|
static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::doublePrecision, 0,
|
||||||
|
0};
|
||||||
|
|
||||||
|
TEST(RoundTest, SpecialNumbers) {
|
||||||
|
EXPECT_EQ(
|
||||||
|
BitPatterns::aQuietNaN,
|
||||||
|
valueAsBits(__llvm_libc::round(valueFromBits(BitPatterns::aQuietNaN))));
|
||||||
|
EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
|
||||||
|
valueAsBits(__llvm_libc::round(
|
||||||
|
valueFromBits(BitPatterns::aNegativeQuietNaN))));
|
||||||
|
|
||||||
|
EXPECT_EQ(BitPatterns::aSignallingNaN,
|
||||||
|
valueAsBits(__llvm_libc::round(
|
||||||
|
valueFromBits(BitPatterns::aSignallingNaN))));
|
||||||
|
EXPECT_EQ(BitPatterns::aNegativeSignallingNaN,
|
||||||
|
valueAsBits(__llvm_libc::round(
|
||||||
|
valueFromBits(BitPatterns::aNegativeSignallingNaN))));
|
||||||
|
|
||||||
|
EXPECT_EQ(BitPatterns::inf,
|
||||||
|
valueAsBits(__llvm_libc::round(valueFromBits(BitPatterns::inf))));
|
||||||
|
EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::round(
|
||||||
|
valueFromBits(BitPatterns::negInf))));
|
||||||
|
|
||||||
|
EXPECT_EQ(BitPatterns::zero,
|
||||||
|
valueAsBits(__llvm_libc::round(valueFromBits(BitPatterns::zero))));
|
||||||
|
EXPECT_EQ(BitPatterns::negZero, valueAsBits(__llvm_libc::round(
|
||||||
|
valueFromBits(BitPatterns::negZero))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RoundTest, RoundedNumbers) {
|
||||||
|
EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::round(1.0)));
|
||||||
|
EXPECT_EQ(valueAsBits(-1.0), valueAsBits(__llvm_libc::round(-1.0)));
|
||||||
|
EXPECT_EQ(valueAsBits(10.0), valueAsBits(__llvm_libc::round(10.0)));
|
||||||
|
EXPECT_EQ(valueAsBits(-10.0), valueAsBits(__llvm_libc::round(-10.0)));
|
||||||
|
EXPECT_EQ(valueAsBits(12345.0), valueAsBits(__llvm_libc::round(12345.0)));
|
||||||
|
EXPECT_EQ(valueAsBits(-12345.0), valueAsBits(__llvm_libc::round(-12345.0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RoundTest, CloseToZeroNumbers) {
|
||||||
|
EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::round(0.5)));
|
||||||
|
EXPECT_EQ(valueAsBits(-1.0), valueAsBits(__llvm_libc::round(-0.5)));
|
||||||
|
EXPECT_EQ(valueAsBits(0.0), valueAsBits(__llvm_libc::round(0.115)));
|
||||||
|
EXPECT_EQ(valueAsBits(-0.0), valueAsBits(__llvm_libc::round(-0.115)));
|
||||||
|
EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::round(0.715)));
|
||||||
|
EXPECT_EQ(valueAsBits(-1.0), valueAsBits(__llvm_libc::round(-0.715)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RoundTest, InDoubleRange) {
|
||||||
|
using BitsType = Properties::BitsType;
|
||||||
|
constexpr BitsType count = 1000000;
|
||||||
|
constexpr BitsType step = UINT64_MAX / count;
|
||||||
|
for (BitsType i = 0, v = 0; i <= count; ++i, v += step) {
|
||||||
|
double x = valueFromBits(v);
|
||||||
|
if (isnan(x) || isinf(x))
|
||||||
|
continue;
|
||||||
|
ASSERT_MPFR_MATCH(mpfr::Operation::Round, x, __llvm_libc::round(x),
|
||||||
|
tolerance);
|
||||||
|
}
|
||||||
|
}
|
85
libc/test/src/math/roundf_test.cpp
Normal file
85
libc/test/src/math/roundf_test.cpp
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
//===-- Unittests for roundf ----------------------------------------------===//
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "include/math.h"
|
||||||
|
#include "src/math/roundf.h"
|
||||||
|
#include "utils/FPUtil/BitPatterns.h"
|
||||||
|
#include "utils/FPUtil/FloatOperations.h"
|
||||||
|
#include "utils/FPUtil/FloatProperties.h"
|
||||||
|
#include "utils/MPFRWrapper/MPFRUtils.h"
|
||||||
|
#include "utils/UnitTest/Test.h"
|
||||||
|
|
||||||
|
using __llvm_libc::fputil::valueAsBits;
|
||||||
|
using __llvm_libc::fputil::valueFromBits;
|
||||||
|
|
||||||
|
using BitPatterns = __llvm_libc::fputil::BitPatterns<float>;
|
||||||
|
using Properties = __llvm_libc::fputil::FloatProperties<float>;
|
||||||
|
|
||||||
|
namespace mpfr = __llvm_libc::testing::mpfr;
|
||||||
|
|
||||||
|
// Zero tolerance; As in, exact match with MPFR result.
|
||||||
|
static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::doublePrecision, 0,
|
||||||
|
0};
|
||||||
|
|
||||||
|
TEST(RoundfTest, SpecialNumbers) {
|
||||||
|
EXPECT_EQ(
|
||||||
|
BitPatterns::aQuietNaN,
|
||||||
|
valueAsBits(__llvm_libc::roundf(valueFromBits(BitPatterns::aQuietNaN))));
|
||||||
|
EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
|
||||||
|
valueAsBits(__llvm_libc::roundf(
|
||||||
|
valueFromBits(BitPatterns::aNegativeQuietNaN))));
|
||||||
|
|
||||||
|
EXPECT_EQ(BitPatterns::aSignallingNaN,
|
||||||
|
valueAsBits(__llvm_libc::roundf(
|
||||||
|
valueFromBits(BitPatterns::aSignallingNaN))));
|
||||||
|
EXPECT_EQ(BitPatterns::aNegativeSignallingNaN,
|
||||||
|
valueAsBits(__llvm_libc::roundf(
|
||||||
|
valueFromBits(BitPatterns::aNegativeSignallingNaN))));
|
||||||
|
|
||||||
|
EXPECT_EQ(BitPatterns::inf,
|
||||||
|
valueAsBits(__llvm_libc::roundf(valueFromBits(BitPatterns::inf))));
|
||||||
|
EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::roundf(
|
||||||
|
valueFromBits(BitPatterns::negInf))));
|
||||||
|
|
||||||
|
EXPECT_EQ(BitPatterns::zero,
|
||||||
|
valueAsBits(__llvm_libc::roundf(valueFromBits(BitPatterns::zero))));
|
||||||
|
EXPECT_EQ(BitPatterns::negZero, valueAsBits(__llvm_libc::roundf(
|
||||||
|
valueFromBits(BitPatterns::negZero))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RoundfTest, RoundedNumbers) {
|
||||||
|
EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::roundf(1.0f)));
|
||||||
|
EXPECT_EQ(valueAsBits(-1.0f), valueAsBits(__llvm_libc::roundf(-1.0f)));
|
||||||
|
EXPECT_EQ(valueAsBits(10.0f), valueAsBits(__llvm_libc::roundf(10.0f)));
|
||||||
|
EXPECT_EQ(valueAsBits(-10.0f), valueAsBits(__llvm_libc::roundf(-10.0f)));
|
||||||
|
EXPECT_EQ(valueAsBits(12345.0f), valueAsBits(__llvm_libc::roundf(12345.0f)));
|
||||||
|
EXPECT_EQ(valueAsBits(-12345.0f),
|
||||||
|
valueAsBits(__llvm_libc::roundf(-12345.0f)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RoundTest, CloseToZeroNumbers) {
|
||||||
|
EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::roundf(0.5f)));
|
||||||
|
EXPECT_EQ(valueAsBits(-1.0f), valueAsBits(__llvm_libc::roundf(-0.5f)));
|
||||||
|
EXPECT_EQ(valueAsBits(0.0f), valueAsBits(__llvm_libc::roundf(0.115f)));
|
||||||
|
EXPECT_EQ(valueAsBits(-0.0f), valueAsBits(__llvm_libc::roundf(-0.115f)));
|
||||||
|
EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::roundf(0.715f)));
|
||||||
|
EXPECT_EQ(valueAsBits(-1.0f), valueAsBits(__llvm_libc::roundf(-0.715f)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RoundfTest, InFloatRange) {
|
||||||
|
using BitsType = Properties::BitsType;
|
||||||
|
constexpr BitsType count = 1000000;
|
||||||
|
constexpr BitsType step = UINT32_MAX / count;
|
||||||
|
for (BitsType i = 0, v = 0; i <= count; ++i, v += step) {
|
||||||
|
double x = valueFromBits(v);
|
||||||
|
if (isnan(x) || isinf(x))
|
||||||
|
continue;
|
||||||
|
ASSERT_MPFR_MATCH(mpfr::Operation::Round, x, __llvm_libc::roundf(x),
|
||||||
|
tolerance);
|
||||||
|
}
|
||||||
|
}
|
|
@ -214,6 +214,62 @@ static inline T floor(T x) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T,
|
||||||
|
cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
|
||||||
|
static inline T round(T x) {
|
||||||
|
using Properties = FloatProperties<T>;
|
||||||
|
using BitsType = typename FloatProperties<T>::BitsType;
|
||||||
|
|
||||||
|
BitsType bits = valueAsBits(x);
|
||||||
|
|
||||||
|
// If x is infinity, NaN or zero, return it.
|
||||||
|
if (bitsAreInfOrNaN(bits) || bitsAreZero(bits))
|
||||||
|
return x;
|
||||||
|
|
||||||
|
bool isNeg = bits & Properties::signMask;
|
||||||
|
int exponent = getExponentFromBits(bits);
|
||||||
|
|
||||||
|
// If the exponent is greater than the most negative mantissa
|
||||||
|
// exponent, then x is already an integer.
|
||||||
|
if (exponent >= static_cast<int>(Properties::mantissaWidth))
|
||||||
|
return x;
|
||||||
|
|
||||||
|
if (exponent == -1) {
|
||||||
|
// Absolute value of x is greater than equal to 0.5 but less than 1.
|
||||||
|
if (isNeg)
|
||||||
|
return T(-1.0);
|
||||||
|
else
|
||||||
|
return T(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exponent <= -2) {
|
||||||
|
// Absolute value of x is less than 0.5.
|
||||||
|
if (isNeg)
|
||||||
|
return T(-0.0);
|
||||||
|
else
|
||||||
|
return T(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t trimSize = Properties::mantissaWidth - exponent;
|
||||||
|
// If x is already an integer, return it.
|
||||||
|
if ((bits << (Properties::bitWidth - trimSize)) == 0)
|
||||||
|
return x;
|
||||||
|
|
||||||
|
BitsType truncBits = (bits >> trimSize) << trimSize;
|
||||||
|
T truncValue = valueFromBits(truncBits);
|
||||||
|
|
||||||
|
if ((bits & (BitsType(1) << (trimSize - 1))) == 0) {
|
||||||
|
// Franctional part is less than 0.5 so round value is the
|
||||||
|
// same as the trunc value.
|
||||||
|
return truncValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNeg)
|
||||||
|
return truncValue - T(1.0);
|
||||||
|
else
|
||||||
|
return truncValue + T(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace fputil
|
} // namespace fputil
|
||||||
} // namespace __llvm_libc
|
} // namespace __llvm_libc
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue