| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| //===-- Implementation header for logbf -------------------------*- 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_LOGBF_H | ||
| #define LLVM_LIBC_SRC_MATH_LOGBF_H | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| float logbf(float x); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_MATH_LOGBF_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| //===-- Implementation of modf function -----------------------------------===// | ||
| // | ||
| // 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 "src/__support/common.h" | ||
| #include "utils/FPUtil/ManipulationFunctions.h" | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| double LLVM_LIBC_ENTRYPOINT(modf)(double x, double *iptr) { | ||
| return fputil::modf(x, *iptr); | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| //===-- Implementation header for modf --------------------------*- 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_MODF_H | ||
| #define LLVM_LIBC_SRC_MATH_MODF_H | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| double modf(double x, double *iptr); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_MATH_MODF_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| //===-- Implementation of modf function -----------------------------------===// | ||
| // | ||
| // 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 "src/__support/common.h" | ||
| #include "utils/FPUtil/ManipulationFunctions.h" | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| float LLVM_LIBC_ENTRYPOINT(modff)(float x, float *iptr) { | ||
| return fputil::modf(x, *iptr); | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| //===-- Implementation header for modff -------------------------*- 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_MODFF_H | ||
| #define LLVM_LIBC_SRC_MATH_MODFF_H | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| float modff(float x, float *iptr); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_MATH_MODFF_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| //===-- Unittests for copysign --------------------------------------------===// | ||
| // | ||
| // 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/copysign.h" | ||
| #include "utils/FPUtil/BitPatterns.h" | ||
| #include "utils/FPUtil/FloatOperations.h" | ||
| #include "utils/FPUtil/FloatProperties.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>; | ||
|
|
||
| TEST(CopySignTest, SpecialNumbers) { | ||
| EXPECT_EQ(BitPatterns::aNegativeQuietNaN, | ||
| valueAsBits(__llvm_libc::copysign( | ||
| valueFromBits(BitPatterns::aQuietNaN), -1.0))); | ||
| EXPECT_EQ(BitPatterns::aQuietNaN, | ||
| valueAsBits(__llvm_libc::copysign( | ||
| valueFromBits(BitPatterns::aNegativeQuietNaN), 1.0))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::aNegativeSignallingNaN, | ||
| valueAsBits(__llvm_libc::copysign( | ||
| valueFromBits(BitPatterns::aSignallingNaN), -1.0))); | ||
| EXPECT_EQ(BitPatterns::aSignallingNaN, | ||
| valueAsBits(__llvm_libc::copysign( | ||
| valueFromBits(BitPatterns::aNegativeSignallingNaN), 1.0))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::copysign( | ||
| valueFromBits(BitPatterns::inf), -1.0))); | ||
| EXPECT_EQ(BitPatterns::inf, valueAsBits(__llvm_libc::copysign( | ||
| valueFromBits(BitPatterns::negInf), 1.0))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negZero, valueAsBits(__llvm_libc::copysign( | ||
| valueFromBits(BitPatterns::zero), -1.0))); | ||
| EXPECT_EQ(BitPatterns::zero, valueAsBits(__llvm_libc::copysign( | ||
| valueFromBits(BitPatterns::negZero), 1.0))); | ||
| } | ||
|
|
||
| TEST(CopySignTest, 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) || x == 0) | ||
| continue; | ||
|
|
||
| double res1 = __llvm_libc::copysign(x, -x); | ||
| ASSERT_TRUE(res1 == -x); | ||
|
|
||
| double res2 = __llvm_libc::copysign(x, x); | ||
| ASSERT_TRUE(res2 == x); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| //===-- Unittests for copysignf | ||
| //--------------------------------------------===// | ||
| // | ||
| // 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/copysignf.h" | ||
| #include "utils/FPUtil/BitPatterns.h" | ||
| #include "utils/FPUtil/FloatOperations.h" | ||
| #include "utils/FPUtil/FloatProperties.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>; | ||
|
|
||
| TEST(CopySignFTest, SpecialNumbers) { | ||
| EXPECT_EQ(BitPatterns::aNegativeQuietNaN, | ||
| valueAsBits(__llvm_libc::copysignf( | ||
| valueFromBits(BitPatterns::aQuietNaN), -1.0f))); | ||
| EXPECT_EQ(BitPatterns::aQuietNaN, | ||
| valueAsBits(__llvm_libc::copysignf( | ||
| valueFromBits(BitPatterns::aNegativeQuietNaN), 1.0f))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::aNegativeSignallingNaN, | ||
| valueAsBits(__llvm_libc::copysignf( | ||
| valueFromBits(BitPatterns::aSignallingNaN), -1.0f))); | ||
| EXPECT_EQ(BitPatterns::aSignallingNaN, | ||
| valueAsBits(__llvm_libc::copysignf( | ||
| valueFromBits(BitPatterns::aNegativeSignallingNaN), 1.0f))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::copysignf( | ||
| valueFromBits(BitPatterns::inf), -1.0f))); | ||
| EXPECT_EQ(BitPatterns::inf, valueAsBits(__llvm_libc::copysignf( | ||
| valueFromBits(BitPatterns::negInf), 1.0f))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::copysignf(valueFromBits(BitPatterns::zero), | ||
| -1.0f))); | ||
| EXPECT_EQ(BitPatterns::zero, valueAsBits(__llvm_libc::copysignf( | ||
| valueFromBits(BitPatterns::negZero), 1.0f))); | ||
| } | ||
|
|
||
| TEST(CopySignFTest, InDoubleRange) { | ||
| 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) { | ||
| float x = valueFromBits(v); | ||
| if (isnan(x) || isinf(x) || x == 0) | ||
| continue; | ||
|
|
||
| float res1 = __llvm_libc::copysignf(x, -x); | ||
| ASSERT_TRUE(res1 == -x); | ||
|
|
||
| float res2 = __llvm_libc::copysignf(x, x); | ||
| ASSERT_TRUE(res2 == x); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| //===-- Unittests for frexp -----------------------------------------------===// | ||
| // | ||
| // 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/frexp.h" | ||
| #include "utils/FPUtil/BitPatterns.h" | ||
| #include "utils/FPUtil/FloatOperations.h" | ||
| #include "utils/FPUtil/FloatProperties.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>; | ||
|
|
||
| TEST(FrexpTest, SpecialNumbers) { | ||
| int exponent; | ||
|
|
||
| EXPECT_EQ(BitPatterns::aQuietNaN, | ||
| valueAsBits(__llvm_libc::frexp( | ||
| valueFromBits(BitPatterns::aQuietNaN), &exponent))); | ||
| EXPECT_EQ(BitPatterns::aNegativeQuietNaN, | ||
| valueAsBits(__llvm_libc::frexp( | ||
| valueFromBits(BitPatterns::aNegativeQuietNaN), &exponent))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::aSignallingNaN, | ||
| valueAsBits(__llvm_libc::frexp( | ||
| valueFromBits(BitPatterns::aSignallingNaN), &exponent))); | ||
| EXPECT_EQ( | ||
| BitPatterns::aNegativeSignallingNaN, | ||
| valueAsBits(__llvm_libc::frexp( | ||
| valueFromBits(BitPatterns::aNegativeSignallingNaN), &exponent))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::inf, valueAsBits(__llvm_libc::frexp( | ||
| valueFromBits(BitPatterns::inf), &exponent))); | ||
| EXPECT_EQ(BitPatterns::negInf, | ||
| valueAsBits(__llvm_libc::frexp(valueFromBits(BitPatterns::negInf), | ||
| &exponent))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::zero, | ||
| valueAsBits(__llvm_libc::frexp(valueFromBits(BitPatterns::zero), | ||
| &exponent))); | ||
| EXPECT_EQ(exponent, 0); | ||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::frexp(valueFromBits(BitPatterns::negZero), | ||
| &exponent))); | ||
| EXPECT_EQ(exponent, 0); | ||
| } | ||
|
|
||
| TEST(FrexpTest, PowersOfTwo) { | ||
| int exponent; | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(1.0, &exponent))); | ||
| EXPECT_EQ(exponent, 1); | ||
| EXPECT_EQ(valueAsBits(-0.5), | ||
| valueAsBits(__llvm_libc::frexp(-1.0, &exponent))); | ||
| EXPECT_EQ(exponent, 1); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(2.0, &exponent))); | ||
| EXPECT_EQ(exponent, 2); | ||
| EXPECT_EQ(valueAsBits(-0.5), | ||
| valueAsBits(__llvm_libc::frexp(-2.0, &exponent))); | ||
| EXPECT_EQ(exponent, 2); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(4.0, &exponent))); | ||
| EXPECT_EQ(exponent, 3); | ||
| EXPECT_EQ(valueAsBits(-0.5), | ||
| valueAsBits(__llvm_libc::frexp(-4.0, &exponent))); | ||
| EXPECT_EQ(exponent, 3); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(8.0, &exponent))); | ||
| EXPECT_EQ(exponent, 4); | ||
| EXPECT_EQ(valueAsBits(-0.5), | ||
| valueAsBits(__llvm_libc::frexp(-8.0, &exponent))); | ||
| EXPECT_EQ(exponent, 4); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(16.0, &exponent))); | ||
| EXPECT_EQ(exponent, 5); | ||
| EXPECT_EQ(valueAsBits(-0.5), | ||
| valueAsBits(__llvm_libc::frexp(-16.0, &exponent))); | ||
| EXPECT_EQ(exponent, 5); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(32.0, &exponent))); | ||
| EXPECT_EQ(exponent, 6); | ||
| EXPECT_EQ(valueAsBits(-0.5), | ||
| valueAsBits(__llvm_libc::frexp(-32.0, &exponent))); | ||
| EXPECT_EQ(exponent, 6); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(64.0, &exponent))); | ||
| EXPECT_EQ(exponent, 7); | ||
| EXPECT_EQ(valueAsBits(-0.5), | ||
| valueAsBits(__llvm_libc::frexp(-64.0, &exponent))); | ||
| EXPECT_EQ(exponent, 7); | ||
| } | ||
|
|
||
| TEST(FrexpTest, SomeIntegers) { | ||
| int exponent; | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.75), | ||
| valueAsBits(__llvm_libc::frexp(24.0, &exponent))); | ||
| EXPECT_EQ(exponent, 5); | ||
| EXPECT_EQ(valueAsBits(-0.75), | ||
| valueAsBits(__llvm_libc::frexp(-24.0, &exponent))); | ||
| EXPECT_EQ(exponent, 5); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.625), | ||
| valueAsBits(__llvm_libc::frexp(40.0, &exponent))); | ||
| EXPECT_EQ(exponent, 6); | ||
| EXPECT_EQ(valueAsBits(-0.625), | ||
| valueAsBits(__llvm_libc::frexp(-40.0, &exponent))); | ||
| EXPECT_EQ(exponent, 6); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.78125), | ||
| valueAsBits(__llvm_libc::frexp(800.0, &exponent))); | ||
| EXPECT_EQ(exponent, 10); | ||
| EXPECT_EQ(valueAsBits(-0.78125), | ||
| valueAsBits(__llvm_libc::frexp(-800.0, &exponent))); | ||
| EXPECT_EQ(exponent, 10); | ||
| } | ||
|
|
||
| TEST(FrexpTest, 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) || x == 0.0) | ||
| continue; | ||
| int exponent; | ||
| double frac = __llvm_libc::frexp(x, &exponent); | ||
|
|
||
| ASSERT_TRUE(__llvm_libc::fputil::abs(frac) < 1.0); | ||
| ASSERT_TRUE(__llvm_libc::fputil::abs(frac) >= 0.5); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| //===-- Unittests for frexpf | ||
| //-----------------------------------------------===// | ||
| // | ||
| // 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/frexpf.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>; | ||
|
|
||
| TEST(FrexpfTest, SpecialNumbers) { | ||
| int exponent; | ||
|
|
||
| EXPECT_EQ(BitPatterns::aQuietNaN, | ||
| valueAsBits(__llvm_libc::frexpf( | ||
| valueFromBits(BitPatterns::aQuietNaN), &exponent))); | ||
| EXPECT_EQ(BitPatterns::aNegativeQuietNaN, | ||
| valueAsBits(__llvm_libc::frexpf( | ||
| valueFromBits(BitPatterns::aNegativeQuietNaN), &exponent))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::aSignallingNaN, | ||
| valueAsBits(__llvm_libc::frexpf( | ||
| valueFromBits(BitPatterns::aSignallingNaN), &exponent))); | ||
| EXPECT_EQ( | ||
| BitPatterns::aNegativeSignallingNaN, | ||
| valueAsBits(__llvm_libc::frexpf( | ||
| valueFromBits(BitPatterns::aNegativeSignallingNaN), &exponent))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::inf, valueAsBits(__llvm_libc::frexpf( | ||
| valueFromBits(BitPatterns::inf), &exponent))); | ||
| EXPECT_EQ(BitPatterns::negInf, | ||
| valueAsBits(__llvm_libc::frexpf(valueFromBits(BitPatterns::negInf), | ||
| &exponent))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::zero, | ||
| valueAsBits(__llvm_libc::frexpf(valueFromBits(BitPatterns::zero), | ||
| &exponent))); | ||
| EXPECT_EQ(exponent, 0); | ||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::frexpf(valueFromBits(BitPatterns::negZero), | ||
| &exponent))); | ||
| EXPECT_EQ(exponent, 0); | ||
| } | ||
|
|
||
| TEST(FrexpfTest, PowersOfTwo) { | ||
| int exponent; | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(1.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 1); | ||
| EXPECT_EQ(valueAsBits(-0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(-1.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 1); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(2.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 2); | ||
| EXPECT_EQ(valueAsBits(-0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(-2.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 2); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(4.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 3); | ||
| EXPECT_EQ(valueAsBits(-0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(-4.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 3); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(8.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 4); | ||
| EXPECT_EQ(valueAsBits(-0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(-8.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 4); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(16.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 5); | ||
| EXPECT_EQ(valueAsBits(-0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(-16.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 5); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(32.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 6); | ||
| EXPECT_EQ(valueAsBits(-0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(-32.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 6); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(64.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 7); | ||
| EXPECT_EQ(valueAsBits(-0.5f), | ||
| valueAsBits(__llvm_libc::frexpf(-64.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 7); | ||
| } | ||
|
|
||
| TEST(FrexpTest, SomeIntegers) { | ||
| int exponent; | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.75f), | ||
| valueAsBits(__llvm_libc::frexpf(24.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 5); | ||
| EXPECT_EQ(valueAsBits(-0.75f), | ||
| valueAsBits(__llvm_libc::frexpf(-24.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 5); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.625f), | ||
| valueAsBits(__llvm_libc::frexpf(40.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 6); | ||
| EXPECT_EQ(valueAsBits(-0.625f), | ||
| valueAsBits(__llvm_libc::frexpf(-40.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 6); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.78125f), | ||
| valueAsBits(__llvm_libc::frexpf(800.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 10); | ||
| EXPECT_EQ(valueAsBits(-0.78125f), | ||
| valueAsBits(__llvm_libc::frexpf(-800.0f, &exponent))); | ||
| EXPECT_EQ(exponent, 10); | ||
| } | ||
|
|
||
| TEST(FrexpfTest, 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) { | ||
| float x = valueFromBits(v); | ||
| if (isnan(x) || isinf(x) || x == 0.0) | ||
| continue; | ||
| int exponent; | ||
| float frac = __llvm_libc::frexpf(x, &exponent); | ||
|
|
||
| ASSERT_TRUE(__llvm_libc::fputil::abs(frac) < 1.0f); | ||
| ASSERT_TRUE(__llvm_libc::fputil::abs(frac) >= 0.5f); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| //===-- Unittests for logb ------------------------------------------------===// | ||
| // | ||
| // 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/logb.h" | ||
| #include "utils/FPUtil/BitPatterns.h" | ||
| #include "utils/FPUtil/FloatOperations.h" | ||
| #include "utils/FPUtil/FloatProperties.h" | ||
| #include "utils/FPUtil/ManipulationFunctions.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>; | ||
|
|
||
| TEST(LogbTest, SpecialNumbers) { | ||
| EXPECT_EQ( | ||
| BitPatterns::aQuietNaN, | ||
| valueAsBits(__llvm_libc::logb(valueFromBits(BitPatterns::aQuietNaN)))); | ||
| EXPECT_EQ(BitPatterns::aNegativeQuietNaN, | ||
| valueAsBits(__llvm_libc::logb( | ||
| valueFromBits(BitPatterns::aNegativeQuietNaN)))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::aSignallingNaN, | ||
| valueAsBits( | ||
| __llvm_libc::logb(valueFromBits(BitPatterns::aSignallingNaN)))); | ||
| EXPECT_EQ(BitPatterns::aNegativeSignallingNaN, | ||
| valueAsBits(__llvm_libc::logb( | ||
| valueFromBits(BitPatterns::aNegativeSignallingNaN)))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::inf, | ||
| valueAsBits(__llvm_libc::logb(valueFromBits(BitPatterns::inf)))); | ||
| EXPECT_EQ(BitPatterns::inf, | ||
| valueAsBits(__llvm_libc::logb(valueFromBits(BitPatterns::negInf)))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negInf, | ||
| valueAsBits(__llvm_libc::logb(valueFromBits(BitPatterns::zero)))); | ||
| EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::logb( | ||
| valueFromBits(BitPatterns::negZero)))); | ||
| } | ||
|
|
||
| TEST(LogbTest, PowersOfTwo) { | ||
| EXPECT_EQ(valueAsBits(0.0), valueAsBits(__llvm_libc::logb(1.0))); | ||
| EXPECT_EQ(valueAsBits(0.0), valueAsBits(__llvm_libc::logb(-1.0))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::logb(2.0))); | ||
| EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::logb(-2.0))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(2.0), valueAsBits(__llvm_libc::logb(4.0))); | ||
| EXPECT_EQ(valueAsBits(2.0), valueAsBits(__llvm_libc::logb(-4.0))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(3.0), valueAsBits(__llvm_libc::logb(8.0))); | ||
| EXPECT_EQ(valueAsBits(3.0), valueAsBits(__llvm_libc::logb(-8.0))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(4.0), valueAsBits(__llvm_libc::logb(16.0))); | ||
| EXPECT_EQ(valueAsBits(4.0), valueAsBits(__llvm_libc::logb(-16.0))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(5.0), valueAsBits(__llvm_libc::logb(32.0))); | ||
| EXPECT_EQ(valueAsBits(5.0), valueAsBits(__llvm_libc::logb(-32.0))); | ||
| } | ||
|
|
||
| TEST(LogbTest, SomeIntegers) { | ||
| EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::logb(3.0))); | ||
| EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::logb(-3.0))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(2.0), valueAsBits(__llvm_libc::logb(7.0))); | ||
| EXPECT_EQ(valueAsBits(2.0), valueAsBits(__llvm_libc::logb(-7.0))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(3.0), valueAsBits(__llvm_libc::logb(10.0))); | ||
| EXPECT_EQ(valueAsBits(3.0), valueAsBits(__llvm_libc::logb(-10.0))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(4.0), valueAsBits(__llvm_libc::logb(31.0))); | ||
| EXPECT_EQ(valueAsBits(4.0), valueAsBits(__llvm_libc::logb(-31.0))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(5.0), valueAsBits(__llvm_libc::logb(55.0))); | ||
| EXPECT_EQ(valueAsBits(5.0), valueAsBits(__llvm_libc::logb(-55.0))); | ||
| } | ||
|
|
||
| TEST(LogbTest, InDoubleRange) { | ||
| using BitsType = Properties::BitsType; | ||
| constexpr BitsType count = 10000000; | ||
| 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) || x == 0.0) | ||
| continue; | ||
|
|
||
| int exponent; | ||
| __llvm_libc::fputil::frexp(x, exponent); | ||
| ASSERT_TRUE(double(exponent) == __llvm_libc::logb(x) + 1.0); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| //===-- Unittests for logbf -----------------------------------------------===// | ||
| // | ||
| // 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/logbf.h" | ||
| #include "utils/FPUtil/BitPatterns.h" | ||
| #include "utils/FPUtil/FloatOperations.h" | ||
| #include "utils/FPUtil/FloatProperties.h" | ||
| #include "utils/FPUtil/ManipulationFunctions.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>; | ||
|
|
||
| TEST(LogbfTest, SpecialNumbers) { | ||
| EXPECT_EQ( | ||
| BitPatterns::aQuietNaN, | ||
| valueAsBits(__llvm_libc::logbf(valueFromBits(BitPatterns::aQuietNaN)))); | ||
| EXPECT_EQ(BitPatterns::aNegativeQuietNaN, | ||
| valueAsBits(__llvm_libc::logbf( | ||
| valueFromBits(BitPatterns::aNegativeQuietNaN)))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::aSignallingNaN, | ||
| valueAsBits(__llvm_libc::logbf( | ||
| valueFromBits(BitPatterns::aSignallingNaN)))); | ||
| EXPECT_EQ(BitPatterns::aNegativeSignallingNaN, | ||
| valueAsBits(__llvm_libc::logbf( | ||
| valueFromBits(BitPatterns::aNegativeSignallingNaN)))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::inf, | ||
| valueAsBits(__llvm_libc::logbf(valueFromBits(BitPatterns::inf)))); | ||
| EXPECT_EQ(BitPatterns::inf, valueAsBits(__llvm_libc::logbf( | ||
| valueFromBits(BitPatterns::negInf)))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negInf, | ||
| valueAsBits(__llvm_libc::logbf(valueFromBits(BitPatterns::zero)))); | ||
| EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::logbf( | ||
| valueFromBits(BitPatterns::negZero)))); | ||
| } | ||
|
|
||
| TEST(LogbfTest, PowersOfTwo) { | ||
| EXPECT_EQ(valueAsBits(0.0f), valueAsBits(__llvm_libc::logbf(1.0f))); | ||
| EXPECT_EQ(valueAsBits(0.0f), valueAsBits(__llvm_libc::logbf(-1.0f))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::logbf(2.0f))); | ||
| EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::logbf(-2.0f))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(2.0f), valueAsBits(__llvm_libc::logbf(4.0f))); | ||
| EXPECT_EQ(valueAsBits(2.0f), valueAsBits(__llvm_libc::logbf(-4.0f))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(3.0f), valueAsBits(__llvm_libc::logbf(8.0f))); | ||
| EXPECT_EQ(valueAsBits(3.0f), valueAsBits(__llvm_libc::logbf(-8.0f))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(4.0f), valueAsBits(__llvm_libc::logbf(16.0f))); | ||
| EXPECT_EQ(valueAsBits(4.0f), valueAsBits(__llvm_libc::logbf(-16.0f))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(5.0f), valueAsBits(__llvm_libc::logbf(32.0f))); | ||
| EXPECT_EQ(valueAsBits(5.0f), valueAsBits(__llvm_libc::logbf(-32.0f))); | ||
| } | ||
|
|
||
| TEST(LogbTest, SomeIntegers) { | ||
| EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::logbf(3.0f))); | ||
| EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::logbf(-3.0f))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(2.0f), valueAsBits(__llvm_libc::logbf(7.0f))); | ||
| EXPECT_EQ(valueAsBits(2.0f), valueAsBits(__llvm_libc::logbf(-7.0f))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(3.0f), valueAsBits(__llvm_libc::logbf(10.0f))); | ||
| EXPECT_EQ(valueAsBits(3.0f), valueAsBits(__llvm_libc::logbf(-10.0f))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(4.0f), valueAsBits(__llvm_libc::logbf(31.0f))); | ||
| EXPECT_EQ(valueAsBits(4.0f), valueAsBits(__llvm_libc::logbf(-31.0f))); | ||
|
|
||
| EXPECT_EQ(valueAsBits(5.0f), valueAsBits(__llvm_libc::logbf(55.0f))); | ||
| EXPECT_EQ(valueAsBits(5.0f), valueAsBits(__llvm_libc::logbf(-55.0f))); | ||
| } | ||
|
|
||
| TEST(LogbfTest, InDoubleRange) { | ||
| using BitsType = Properties::BitsType; | ||
| constexpr BitsType count = 10000000; | ||
| constexpr BitsType step = UINT32_MAX / count; | ||
| for (BitsType i = 0, v = 0; i <= count; ++i, v += step) { | ||
| float x = valueFromBits(v); | ||
| if (isnan(x) || isinf(x) || x == 0.0) | ||
| continue; | ||
|
|
||
| int exponent; | ||
| __llvm_libc::fputil::frexp(x, exponent); | ||
| ASSERT_TRUE(float(exponent) == __llvm_libc::logbf(x) + 1.0); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| //===-- Unittests for modf ------------------------------------------------===// | ||
| // | ||
| // 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/modf.h" | ||
| #include "utils/FPUtil/BitPatterns.h" | ||
| #include "utils/FPUtil/FloatOperations.h" | ||
| #include "utils/FPUtil/FloatProperties.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>; | ||
|
|
||
| TEST(ModfTest, SpecialNumbers) { | ||
| double integral; | ||
|
|
||
| EXPECT_EQ(BitPatterns::aQuietNaN, | ||
| valueAsBits(__llvm_libc::modf(valueFromBits(BitPatterns::aQuietNaN), | ||
| &integral))); | ||
| EXPECT_EQ(BitPatterns::aNegativeQuietNaN, | ||
| valueAsBits(__llvm_libc::modf( | ||
| valueFromBits(BitPatterns::aNegativeQuietNaN), &integral))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::aSignallingNaN, | ||
| valueAsBits(__llvm_libc::modf( | ||
| valueFromBits(BitPatterns::aSignallingNaN), &integral))); | ||
| EXPECT_EQ( | ||
| BitPatterns::aNegativeSignallingNaN, | ||
| valueAsBits(__llvm_libc::modf( | ||
| valueFromBits(BitPatterns::aNegativeSignallingNaN), &integral))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::zero, | ||
| valueAsBits( | ||
| __llvm_libc::modf(valueFromBits(BitPatterns::inf), &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), BitPatterns::inf); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::modf(valueFromBits(BitPatterns::negInf), | ||
| &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), BitPatterns::negInf); | ||
|
|
||
| EXPECT_EQ(BitPatterns::zero, | ||
| valueAsBits(__llvm_libc::modf(valueFromBits(BitPatterns::zero), | ||
| &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), BitPatterns::zero); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::modf(valueFromBits(BitPatterns::negZero), | ||
| &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), BitPatterns::negZero); | ||
| } | ||
|
|
||
| TEST(ModfTest, Integers) { | ||
| double integral; | ||
|
|
||
| EXPECT_EQ(BitPatterns::zero, valueAsBits(__llvm_libc::modf(1.0, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(1.0)); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::modf(-1.0, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(-1.0)); | ||
|
|
||
| EXPECT_EQ(BitPatterns::zero, valueAsBits(__llvm_libc::modf(10.0, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(10.0)); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::modf(-10.0, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(-10.0)); | ||
|
|
||
| EXPECT_EQ(BitPatterns::zero, | ||
| valueAsBits(__llvm_libc::modf(12345.0, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(12345.0)); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::modf(-12345.0, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(-12345.0)); | ||
| } | ||
|
|
||
| TEST(ModfTest, Fractions) { | ||
| double integral; | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::modf(1.5, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(1.0)); | ||
|
|
||
| EXPECT_EQ(valueAsBits(-0.5), valueAsBits(__llvm_libc::modf(-1.5, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(-1.0)); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.75), | ||
| valueAsBits(__llvm_libc::modf(10.75, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(10.0)); | ||
|
|
||
| EXPECT_EQ(valueAsBits(-0.75), | ||
| valueAsBits(__llvm_libc::modf(-10.75, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(-10.0)); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.125), | ||
| valueAsBits(__llvm_libc::modf(100.125, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(100.0)); | ||
|
|
||
| EXPECT_EQ(valueAsBits(-0.125), | ||
| valueAsBits(__llvm_libc::modf(-100.125, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(-100.0)); | ||
| } | ||
|
|
||
| TEST(ModfTest, InDoubleRange) { | ||
| using BitsType = Properties::BitsType; | ||
| constexpr BitsType count = 10000000; | ||
| 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) || x == 0.0) { | ||
| // These conditions have been tested in other tests. | ||
| continue; | ||
| } | ||
|
|
||
| double integral; | ||
| double frac = __llvm_libc::modf(x, &integral); | ||
| ASSERT_TRUE(__llvm_libc::fputil::abs(frac) < 1.0); | ||
| ASSERT_TRUE(__llvm_libc::fputil::trunc(x) == integral); | ||
| ASSERT_TRUE(integral + frac == x); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| //===-- Unittests for modfff | ||
| //-----------------------------------------------===// | ||
| // | ||
| // 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/modff.h" | ||
| #include "utils/FPUtil/BitPatterns.h" | ||
| #include "utils/FPUtil/FloatOperations.h" | ||
| #include "utils/FPUtil/FloatProperties.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>; | ||
|
|
||
| TEST(ModffTest, SpecialNumbers) { | ||
| float integral; | ||
|
|
||
| EXPECT_EQ(BitPatterns::aQuietNaN, | ||
| valueAsBits(__llvm_libc::modff( | ||
| valueFromBits(BitPatterns::aQuietNaN), &integral))); | ||
| EXPECT_EQ(BitPatterns::aNegativeQuietNaN, | ||
| valueAsBits(__llvm_libc::modff( | ||
| valueFromBits(BitPatterns::aNegativeQuietNaN), &integral))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::aSignallingNaN, | ||
| valueAsBits(__llvm_libc::modff( | ||
| valueFromBits(BitPatterns::aSignallingNaN), &integral))); | ||
| EXPECT_EQ( | ||
| BitPatterns::aNegativeSignallingNaN, | ||
| valueAsBits(__llvm_libc::modff( | ||
| valueFromBits(BitPatterns::aNegativeSignallingNaN), &integral))); | ||
|
|
||
| EXPECT_EQ(BitPatterns::zero, | ||
| valueAsBits(__llvm_libc::modff(valueFromBits(BitPatterns::inf), | ||
| &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), BitPatterns::inf); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::modff(valueFromBits(BitPatterns::negInf), | ||
| &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), BitPatterns::negInf); | ||
|
|
||
| EXPECT_EQ(BitPatterns::zero, | ||
| valueAsBits(__llvm_libc::modff(valueFromBits(BitPatterns::zero), | ||
| &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), BitPatterns::zero); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::modff(valueFromBits(BitPatterns::negZero), | ||
| &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), BitPatterns::negZero); | ||
| } | ||
|
|
||
| TEST(ModffTest, Integers) { | ||
| float integral; | ||
|
|
||
| EXPECT_EQ(BitPatterns::zero, | ||
| valueAsBits(__llvm_libc::modff(1.0f, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(1.0f)); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::modff(-1.0f, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(-1.0f)); | ||
|
|
||
| EXPECT_EQ(BitPatterns::zero, | ||
| valueAsBits(__llvm_libc::modff(10.0f, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(10.0f)); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::modff(-10.0f, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(-10.0f)); | ||
|
|
||
| EXPECT_EQ(BitPatterns::zero, | ||
| valueAsBits(__llvm_libc::modff(12345.0f, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(12345.0f)); | ||
|
|
||
| EXPECT_EQ(BitPatterns::negZero, | ||
| valueAsBits(__llvm_libc::modff(-12345.0f, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(-12345.0f)); | ||
| } | ||
|
|
||
| TEST(ModfTest, Fractions) { | ||
| float integral; | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.5f), | ||
| valueAsBits(__llvm_libc::modff(1.5f, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(1.0f)); | ||
|
|
||
| EXPECT_EQ(valueAsBits(-0.5f), | ||
| valueAsBits(__llvm_libc::modff(-1.5f, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(-1.0f)); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.75f), | ||
| valueAsBits(__llvm_libc::modff(10.75f, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(10.0f)); | ||
|
|
||
| EXPECT_EQ(valueAsBits(-0.75f), | ||
| valueAsBits(__llvm_libc::modff(-10.75f, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(-10.0f)); | ||
|
|
||
| EXPECT_EQ(valueAsBits(0.125f), | ||
| valueAsBits(__llvm_libc::modff(100.125f, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(100.0f)); | ||
|
|
||
| EXPECT_EQ(valueAsBits(-0.125f), | ||
| valueAsBits(__llvm_libc::modff(-100.125f, &integral))); | ||
| EXPECT_EQ(valueAsBits(integral), valueAsBits(-100.0f)); | ||
| } | ||
|
|
||
| TEST(ModffTest, InDoubleRange) { | ||
| using BitsType = Properties::BitsType; | ||
| constexpr BitsType count = 10000000; | ||
| constexpr BitsType step = UINT32_MAX / count; | ||
| for (BitsType i = 0, v = 0; i <= count; ++i, v += step) { | ||
| float x = valueFromBits(v); | ||
| if (isnan(x) || isinf(x) || x == 0.0f) { | ||
| // These conditions have been tested in other tests. | ||
| continue; | ||
| } | ||
|
|
||
| float integral; | ||
| float frac = __llvm_libc::modff(x, &integral); | ||
| ASSERT_TRUE(__llvm_libc::fputil::abs(frac) < 1.0f); | ||
| ASSERT_TRUE(__llvm_libc::fputil::trunc(x) == integral); | ||
| ASSERT_TRUE(integral + frac == x); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| //===-- Common operations on floating point numbers -------------*- 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 | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "BitPatterns.h" | ||
| #include "FloatOperations.h" | ||
| #include "FloatProperties.h" | ||
|
|
||
| #include "utils/CPP/TypeTraits.h" | ||
|
|
||
| #ifndef LLVM_LIBC_UTILS_FPUTIL_MANIPULATION_FUNCTIONS_H | ||
| #define LLVM_LIBC_UTILS_FPUTIL_MANIPULATION_FUNCTIONS_H | ||
|
|
||
| namespace __llvm_libc { | ||
| namespace fputil { | ||
|
|
||
| template <typename T, | ||
| cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0> | ||
| static inline T frexp(T x, int &exp) { | ||
| using Properties = FloatProperties<T>; | ||
| using BitsType = typename Properties::BitsType; | ||
|
|
||
| auto bits = valueAsBits(x); | ||
| if (bitsAreInfOrNaN(bits)) | ||
| return x; | ||
| if (bitsAreZero(bits)) { | ||
| exp = 0; | ||
| return x; | ||
| } | ||
|
|
||
| exp = getExponentFromBits(bits) + 1; | ||
|
|
||
| static constexpr BitsType resultExponent = | ||
| Properties::exponentOffset - BitsType(1); | ||
| // Capture the sign and mantissa part. | ||
| bits &= (Properties::mantissaMask | Properties::signMask); | ||
| // Insert the new exponent. | ||
| bits |= (resultExponent << Properties::mantissaWidth); | ||
|
|
||
| return valueFromBits(bits); | ||
| } | ||
|
|
||
| template <typename T, | ||
| cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0> | ||
| static inline T modf(T x, T &iptr) { | ||
| auto bits = valueAsBits(x); | ||
| if (bitsAreZero(bits) || bitsAreNaN(bits)) { | ||
| iptr = x; | ||
| return x; | ||
| } else if (bitsAreInf(bits)) { | ||
| iptr = x; | ||
| return bits & FloatProperties<T>::signMask | ||
| ? valueFromBits(BitPatterns<T>::negZero) | ||
| : valueFromBits(BitPatterns<T>::zero); | ||
| } else { | ||
| iptr = trunc(x); | ||
| if (x == iptr) { | ||
| // If x is already an integer value, then return zero with the right | ||
| // sign. | ||
| return bits & FloatProperties<T>::signMask | ||
| ? valueFromBits(BitPatterns<T>::negZero) | ||
| : valueFromBits(BitPatterns<T>::zero); | ||
| } else { | ||
| return x - iptr; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| template <typename T, | ||
| cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0> | ||
| static inline T copysign(T x, T y) { | ||
| constexpr auto signMask = FloatProperties<T>::signMask; | ||
| auto xbits = valueAsBits(x); | ||
| auto ybits = valueAsBits(y); | ||
| return valueFromBits((xbits & ~signMask) | (ybits & signMask)); | ||
| } | ||
|
|
||
| template <typename T, | ||
| cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0> | ||
| static inline T logb(T x) { | ||
| auto bits = valueAsBits(x); | ||
| if (bitsAreZero(bits)) { | ||
| // TODO(Floating point exception): Raise div-by-zero exception. | ||
| // TODO(errno): POSIX requires setting errno to ERANGE. | ||
| return valueFromBits(BitPatterns<T>::negInf); | ||
| } else if (bitsAreInf(bits)) { | ||
| return valueFromBits(BitPatterns<T>::inf); | ||
| } else if (bitsAreNaN(bits)) { | ||
| return x; | ||
| } else { | ||
| return getExponentFromBits(bits); | ||
| } | ||
| } | ||
|
|
||
| } // namespace fputil | ||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_UTILS_FPUTIL_MANIPULATION_FUNCTIONS_H |