[libc-commits] [libc] 1caedd0 - [libc] Add implementations of ceil[f], floor[f] and trunc[f] from math.h.

Siva Chandra Reddy via libc-commits libc-commits at lists.llvm.org
Mon Jun 1 08:37:10 PDT 2020


Author: Siva Chandra Reddy
Date: 2020-06-01T08:36:59-07:00
New Revision: 1caedd0c550646557d8d2feb97b3cbba8c48b2d7

URL: https://github.com/llvm/llvm-project/commit/1caedd0c550646557d8d2feb97b3cbba8c48b2d7
DIFF: https://github.com/llvm/llvm-project/commit/1caedd0c550646557d8d2feb97b3cbba8c48b2d7.diff

LOG: [libc] Add implementations of ceil[f], floor[f] and trunc[f] from math.h.

Reviewers: abrachet

Differential Revision: https://reviews.llvm.org/D80612

Added: 
    libc/src/math/ceil.cpp
    libc/src/math/ceil.h
    libc/src/math/ceilf.cpp
    libc/src/math/ceilf.h
    libc/src/math/floor.cpp
    libc/src/math/floor.h
    libc/src/math/floorf.cpp
    libc/src/math/floorf.h
    libc/src/math/trunc.cpp
    libc/src/math/trunc.h
    libc/src/math/truncf.cpp
    libc/src/math/truncf.h
    libc/test/src/math/ceil_test.cpp
    libc/test/src/math/ceilf_test.cpp
    libc/test/src/math/floor_test.cpp
    libc/test/src/math/floorf_test.cpp
    libc/test/src/math/trunc_test.cpp
    libc/test/src/math/truncf_test.cpp

Modified: 
    libc/lib/CMakeLists.txt
    libc/src/math/CMakeLists.txt
    libc/test/src/math/CMakeLists.txt
    libc/utils/FPUtil/FloatOperations.h
    libc/utils/FPUtil/FloatProperties.h
    libc/utils/MPFRWrapper/MPFRUtils.cpp
    libc/utils/MPFRWrapper/MPFRUtils.h

Removed: 
    


################################################################################
diff  --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt
index 51f587a2a70a..e0921d93d410 100644
--- a/libc/lib/CMakeLists.txt
+++ b/libc/lib/CMakeLists.txt
@@ -50,14 +50,20 @@ add_entrypoint_library(
   llvmlibm
   DEPENDS
     # math.h entrypoints
+    libc.src.math.ceil
+    libc.src.math.ceilf
     libc.src.math.cosf
     libc.src.math.fabs
     libc.src.math.fabsf
+    libc.src.math.floor
+    libc.src.math.floorf
     libc.src.math.expf
     libc.src.math.exp2f
     libc.src.math.round
     libc.src.math.sincosf
     libc.src.math.sinf
+    libc.src.math.trunc
+    libc.src.math.truncf
 )
 
 add_redirector_library(

diff  --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 41a20b31996f..a3b1b4f6ec01 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -91,6 +91,66 @@ add_entrypoint_object(
     libc.utils.FPUtil.fputil
 )
 
+add_entrypoint_object(
+  trunc
+  SRCS
+    trunc.cpp
+  HDRS
+    trunc.h
+  DEPENDS
+    libc.utils.FPUtil.fputil
+)
+
+add_entrypoint_object(
+  truncf
+  SRCS
+    truncf.cpp
+  HDRS
+    truncf.h
+  DEPENDS
+    libc.utils.FPUtil.fputil
+)
+
+add_entrypoint_object(
+  ceil
+  SRCS
+    ceil.cpp
+  HDRS
+    ceil.h
+  DEPENDS
+    libc.utils.FPUtil.fputil
+)
+
+add_entrypoint_object(
+  ceilf
+  SRCS
+    ceilf.cpp
+  HDRS
+    ceilf.h
+  DEPENDS
+    libc.utils.FPUtil.fputil
+)
+
+add_entrypoint_object(
+  floor
+  SRCS
+    floor.cpp
+  HDRS
+    floor.h
+  DEPENDS
+    libc.utils.FPUtil.fputil
+)
+
+add_entrypoint_object(
+  floorf
+  SRCS
+    floorf.cpp
+  HDRS
+    floorf.h
+  DEPENDS
+    libc.utils.FPUtil.fputil
+)
+
 add_object_library(
   exp_utils
   HDRS

diff  --git a/libc/src/math/ceil.cpp b/libc/src/math/ceil.cpp
new file mode 100644
index 000000000000..c9af520d1f1f
--- /dev/null
+++ b/libc/src/math/ceil.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of ceil 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/FloatOperations.h"
+
+namespace __llvm_libc {
+
+double LLVM_LIBC_ENTRYPOINT(ceil)(double x) { return fputil::ceil(x); }
+
+} // namespace __llvm_libc

diff  --git a/libc/src/math/ceil.h b/libc/src/math/ceil.h
new file mode 100644
index 000000000000..98188de20e40
--- /dev/null
+++ b/libc/src/math/ceil.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for ceil --------------------------*- 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_CEIL_H
+#define LLVM_LIBC_SRC_MATH_CEIL_H
+
+namespace __llvm_libc {
+
+double ceil(double x);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_MATH_CEIL_H

diff  --git a/libc/src/math/ceilf.cpp b/libc/src/math/ceilf.cpp
new file mode 100644
index 000000000000..2d2fb90c47fd
--- /dev/null
+++ b/libc/src/math/ceilf.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of ceilf 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/FloatOperations.h"
+
+namespace __llvm_libc {
+
+float LLVM_LIBC_ENTRYPOINT(ceilf)(float x) { return fputil::ceil(x); }
+
+} // namespace __llvm_libc

diff  --git a/libc/src/math/ceilf.h b/libc/src/math/ceilf.h
new file mode 100644
index 000000000000..e8e64565052a
--- /dev/null
+++ b/libc/src/math/ceilf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for ceilf -------------------------*- 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_CEILF_H
+#define LLVM_LIBC_SRC_MATH_CEILF_H
+
+namespace __llvm_libc {
+
+float ceilf(float x);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_MATH_CEILF_H

diff  --git a/libc/src/math/floor.cpp b/libc/src/math/floor.cpp
new file mode 100644
index 000000000000..b2d5f872b453
--- /dev/null
+++ b/libc/src/math/floor.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of floor 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/FloatOperations.h"
+
+namespace __llvm_libc {
+
+double LLVM_LIBC_ENTRYPOINT(floor)(double x) { return fputil::floor(x); }
+
+} // namespace __llvm_libc

diff  --git a/libc/src/math/floor.h b/libc/src/math/floor.h
new file mode 100644
index 000000000000..88a76ebf7d80
--- /dev/null
+++ b/libc/src/math/floor.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for floor -------------------------*- 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_FLOOR_H
+#define LLVM_LIBC_SRC_MATH_FLOOR_H
+
+namespace __llvm_libc {
+
+double floor(double x);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_MATH_FLOOR_H

diff  --git a/libc/src/math/floorf.cpp b/libc/src/math/floorf.cpp
new file mode 100644
index 000000000000..397602eacf98
--- /dev/null
+++ b/libc/src/math/floorf.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of floorf 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/FloatOperations.h"
+
+namespace __llvm_libc {
+
+float LLVM_LIBC_ENTRYPOINT(floorf)(float x) { return fputil::floor(x); }
+
+} // namespace __llvm_libc

diff  --git a/libc/src/math/floorf.h b/libc/src/math/floorf.h
new file mode 100644
index 000000000000..029df3ac5c9f
--- /dev/null
+++ b/libc/src/math/floorf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for floorf ------------------------*- 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_FLOORF_H
+#define LLVM_LIBC_SRC_MATH_FLOORF_H
+
+namespace __llvm_libc {
+
+float floorf(float x);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_MATH_FLOORF_H

diff  --git a/libc/src/math/trunc.cpp b/libc/src/math/trunc.cpp
new file mode 100644
index 000000000000..7e42fe47d2e7
--- /dev/null
+++ b/libc/src/math/trunc.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of trunc 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/FloatOperations.h"
+
+namespace __llvm_libc {
+
+double LLVM_LIBC_ENTRYPOINT(trunc)(double x) { return fputil::trunc(x); }
+
+} // namespace __llvm_libc

diff  --git a/libc/src/math/trunc.h b/libc/src/math/trunc.h
new file mode 100644
index 000000000000..f7fed01f30d2
--- /dev/null
+++ b/libc/src/math/trunc.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for trunc -------------------------*- 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_TRUNC_H
+#define LLVM_LIBC_SRC_MATH_TRUNC_H
+
+namespace __llvm_libc {
+
+double trunc(double x);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_MATH_TRUNC_H

diff  --git a/libc/src/math/truncf.cpp b/libc/src/math/truncf.cpp
new file mode 100644
index 000000000000..c567865f7227
--- /dev/null
+++ b/libc/src/math/truncf.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation of truncf 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/FloatOperations.h"
+
+namespace __llvm_libc {
+
+float LLVM_LIBC_ENTRYPOINT(truncf)(float x) { return fputil::trunc(x); }
+
+} // namespace __llvm_libc

diff  --git a/libc/src/math/truncf.h b/libc/src/math/truncf.h
new file mode 100644
index 000000000000..b4f1cd7ea72f
--- /dev/null
+++ b/libc/src/math/truncf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for truncf ------------------------*- 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_TRUNCF_H
+#define LLVM_LIBC_SRC_MATH_TRUNCF_H
+
+namespace __llvm_libc {
+
+float truncf(float x);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_MATH_TRUNCF_H

diff  --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index ed36faaee4d8..3568b20a537c 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -97,6 +97,84 @@ add_math_unittest(
     libc.utils.FPUtil.fputil
 )
 
+add_math_unittest(
+  trunc_test
+  NEED_MPFR
+  SUITE
+    libc_math_unittests
+  SRCS
+    trunc_test.cpp
+  DEPENDS
+    libc.include.math
+    libc.src.math.trunc
+    libc.utils.FPUtil.fputil
+)
+
+add_math_unittest(
+  truncf_test
+  NEED_MPFR
+  SUITE
+    libc_math_unittests
+  SRCS
+    truncf_test.cpp
+  DEPENDS
+    libc.include.math
+    libc.src.math.truncf
+    libc.utils.FPUtil.fputil
+)
+
+add_math_unittest(
+  ceil_test
+  NEED_MPFR
+  SUITE
+    libc_math_unittests
+  SRCS
+    ceil_test.cpp
+  DEPENDS
+    libc.include.math
+    libc.src.math.ceil
+    libc.utils.FPUtil.fputil
+)
+
+add_math_unittest(
+  ceilf_test
+  NEED_MPFR
+  SUITE
+    libc_math_unittests
+  SRCS
+    ceilf_test.cpp
+  DEPENDS
+    libc.include.math
+    libc.src.math.ceilf
+    libc.utils.FPUtil.fputil
+)
+
+add_math_unittest(
+  floor_test
+  NEED_MPFR
+  SUITE
+    libc_math_unittests
+  SRCS
+    floor_test.cpp
+  DEPENDS
+    libc.include.math
+    libc.src.math.floor
+    libc.utils.FPUtil.fputil
+)
+
+add_math_unittest(
+  floorf_test
+  NEED_MPFR
+  SUITE
+    libc_math_unittests
+  SRCS
+    floorf_test.cpp
+  DEPENDS
+    libc.include.math
+    libc.src.math.floorf
+    libc.utils.FPUtil.fputil
+)
+
 add_math_unittest(
   expf_test
   NEED_MPFR

diff  --git a/libc/test/src/math/ceil_test.cpp b/libc/test/src/math/ceil_test.cpp
new file mode 100644
index 000000000000..fdb45a81db97
--- /dev/null
+++ b/libc/test/src/math/ceil_test.cpp
@@ -0,0 +1,75 @@
+//===-- Unittests for ceil ------------------------------------------------===//
+//
+// 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/ceil.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(ceilTest, SpecialNumbers) {
+  EXPECT_EQ(
+      BitPatterns::aQuietNaN,
+      valueAsBits(__llvm_libc::ceil(valueFromBits(BitPatterns::aQuietNaN))));
+  EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
+            valueAsBits(__llvm_libc::ceil(
+                valueFromBits(BitPatterns::aNegativeQuietNaN))));
+
+  EXPECT_EQ(BitPatterns::aSignallingNaN,
+            valueAsBits(
+                __llvm_libc::ceil(valueFromBits(BitPatterns::aSignallingNaN))));
+  EXPECT_EQ(BitPatterns::aNegativeSignallingNaN,
+            valueAsBits(__llvm_libc::ceil(
+                valueFromBits(BitPatterns::aNegativeSignallingNaN))));
+
+  EXPECT_EQ(BitPatterns::inf,
+            valueAsBits(__llvm_libc::ceil(valueFromBits(BitPatterns::inf))));
+  EXPECT_EQ(BitPatterns::negInf,
+            valueAsBits(__llvm_libc::ceil(valueFromBits(BitPatterns::negInf))));
+
+  EXPECT_EQ(BitPatterns::zero,
+            valueAsBits(__llvm_libc::ceil(valueFromBits(BitPatterns::zero))));
+  EXPECT_EQ(BitPatterns::negZero, valueAsBits(__llvm_libc::ceil(
+                                      valueFromBits(BitPatterns::negZero))));
+}
+
+TEST(ceilTest, RoundedNumbers) {
+  EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::ceil(1.0)));
+  EXPECT_EQ(valueAsBits(-1.0), valueAsBits(__llvm_libc::ceil(-1.0)));
+  EXPECT_EQ(valueAsBits(10.0), valueAsBits(__llvm_libc::ceil(10.0)));
+  EXPECT_EQ(valueAsBits(-10.0), valueAsBits(__llvm_libc::ceil(-10.0)));
+  EXPECT_EQ(valueAsBits(12345.0), valueAsBits(__llvm_libc::ceil(12345.0)));
+  EXPECT_EQ(valueAsBits(-12345.0), valueAsBits(__llvm_libc::ceil(-12345.0)));
+}
+
+TEST(ceilTest, 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::Ceil, x, __llvm_libc::ceil(x),
+                      tolerance);
+  }
+}

diff  --git a/libc/test/src/math/ceilf_test.cpp b/libc/test/src/math/ceilf_test.cpp
new file mode 100644
index 000000000000..7bfb2ac15b6a
--- /dev/null
+++ b/libc/test/src/math/ceilf_test.cpp
@@ -0,0 +1,75 @@
+//===-- Unittests for ceilf -----------------------------------------------===//
+//
+// 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/ceilf.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(CeilfTest, SpecialNumbers) {
+  EXPECT_EQ(
+      BitPatterns::aQuietNaN,
+      valueAsBits(__llvm_libc::ceilf(valueFromBits(BitPatterns::aQuietNaN))));
+  EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
+            valueAsBits(__llvm_libc::ceilf(
+                valueFromBits(BitPatterns::aNegativeQuietNaN))));
+
+  EXPECT_EQ(BitPatterns::aSignallingNaN,
+            valueAsBits(__llvm_libc::ceilf(
+                valueFromBits(BitPatterns::aSignallingNaN))));
+  EXPECT_EQ(BitPatterns::aNegativeSignallingNaN,
+            valueAsBits(__llvm_libc::ceilf(
+                valueFromBits(BitPatterns::aNegativeSignallingNaN))));
+
+  EXPECT_EQ(BitPatterns::inf,
+            valueAsBits(__llvm_libc::ceilf(valueFromBits(BitPatterns::inf))));
+  EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::ceilf(
+                                     valueFromBits(BitPatterns::negInf))));
+
+  EXPECT_EQ(BitPatterns::zero,
+            valueAsBits(__llvm_libc::ceilf(valueFromBits(BitPatterns::zero))));
+  EXPECT_EQ(BitPatterns::negZero, valueAsBits(__llvm_libc::ceilf(
+                                      valueFromBits(BitPatterns::negZero))));
+}
+
+TEST(ceilfTest, RoundedNumbers) {
+  EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::ceilf(1.0f)));
+  EXPECT_EQ(valueAsBits(-1.0f), valueAsBits(__llvm_libc::ceilf(-1.0f)));
+  EXPECT_EQ(valueAsBits(10.0f), valueAsBits(__llvm_libc::ceilf(10.0f)));
+  EXPECT_EQ(valueAsBits(-10.0f), valueAsBits(__llvm_libc::ceilf(-10.0f)));
+  EXPECT_EQ(valueAsBits(12345.0f), valueAsBits(__llvm_libc::ceilf(12345.0f)));
+  EXPECT_EQ(valueAsBits(-12345.0f), valueAsBits(__llvm_libc::ceilf(-12345.0f)));
+}
+
+TEST(ceilfTest, 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::Ceil, x, __llvm_libc::ceilf(x),
+                      tolerance);
+  }
+}

diff  --git a/libc/test/src/math/floor_test.cpp b/libc/test/src/math/floor_test.cpp
new file mode 100644
index 000000000000..a45d75710b8a
--- /dev/null
+++ b/libc/test/src/math/floor_test.cpp
@@ -0,0 +1,75 @@
+//===-- Unittests for floor -----------------------------------------------===//
+//
+// 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/floor.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(FloorTest, SpecialNumbers) {
+  EXPECT_EQ(
+      BitPatterns::aQuietNaN,
+      valueAsBits(__llvm_libc::floor(valueFromBits(BitPatterns::aQuietNaN))));
+  EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
+            valueAsBits(__llvm_libc::floor(
+                valueFromBits(BitPatterns::aNegativeQuietNaN))));
+
+  EXPECT_EQ(BitPatterns::aSignallingNaN,
+            valueAsBits(__llvm_libc::floor(
+                valueFromBits(BitPatterns::aSignallingNaN))));
+  EXPECT_EQ(BitPatterns::aNegativeSignallingNaN,
+            valueAsBits(__llvm_libc::floor(
+                valueFromBits(BitPatterns::aNegativeSignallingNaN))));
+
+  EXPECT_EQ(BitPatterns::inf,
+            valueAsBits(__llvm_libc::floor(valueFromBits(BitPatterns::inf))));
+  EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::floor(
+                                     valueFromBits(BitPatterns::negInf))));
+
+  EXPECT_EQ(BitPatterns::zero,
+            valueAsBits(__llvm_libc::floor(valueFromBits(BitPatterns::zero))));
+  EXPECT_EQ(BitPatterns::negZero, valueAsBits(__llvm_libc::floor(
+                                      valueFromBits(BitPatterns::negZero))));
+}
+
+TEST(floorTest, RoundedNumbers) {
+  EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::floor(1.0)));
+  EXPECT_EQ(valueAsBits(-1.0), valueAsBits(__llvm_libc::floor(-1.0)));
+  EXPECT_EQ(valueAsBits(10.0), valueAsBits(__llvm_libc::floor(10.0)));
+  EXPECT_EQ(valueAsBits(-10.0), valueAsBits(__llvm_libc::floor(-10.0)));
+  EXPECT_EQ(valueAsBits(12345.0), valueAsBits(__llvm_libc::floor(12345.0)));
+  EXPECT_EQ(valueAsBits(-12345.0), valueAsBits(__llvm_libc::floor(-12345.0)));
+}
+
+TEST(floorTest, 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::Floor, x, __llvm_libc::floor(x),
+                      tolerance);
+  }
+}

diff  --git a/libc/test/src/math/floorf_test.cpp b/libc/test/src/math/floorf_test.cpp
new file mode 100644
index 000000000000..c25014da1257
--- /dev/null
+++ b/libc/test/src/math/floorf_test.cpp
@@ -0,0 +1,76 @@
+//===-- Unittests for floorf ----------------------------------------------===//
+//
+// 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/floorf.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(FloorfTest, SpecialNumbers) {
+  EXPECT_EQ(
+      BitPatterns::aQuietNaN,
+      valueAsBits(__llvm_libc::floorf(valueFromBits(BitPatterns::aQuietNaN))));
+  EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
+            valueAsBits(__llvm_libc::floorf(
+                valueFromBits(BitPatterns::aNegativeQuietNaN))));
+
+  EXPECT_EQ(BitPatterns::aSignallingNaN,
+            valueAsBits(__llvm_libc::floorf(
+                valueFromBits(BitPatterns::aSignallingNaN))));
+  EXPECT_EQ(BitPatterns::aNegativeSignallingNaN,
+            valueAsBits(__llvm_libc::floorf(
+                valueFromBits(BitPatterns::aNegativeSignallingNaN))));
+
+  EXPECT_EQ(BitPatterns::inf,
+            valueAsBits(__llvm_libc::floorf(valueFromBits(BitPatterns::inf))));
+  EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::floorf(
+                                     valueFromBits(BitPatterns::negInf))));
+
+  EXPECT_EQ(BitPatterns::zero,
+            valueAsBits(__llvm_libc::floorf(valueFromBits(BitPatterns::zero))));
+  EXPECT_EQ(BitPatterns::negZero, valueAsBits(__llvm_libc::floorf(
+                                      valueFromBits(BitPatterns::negZero))));
+}
+
+TEST(floorfTest, RoundedNumbers) {
+  EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::floorf(1.0f)));
+  EXPECT_EQ(valueAsBits(-1.0f), valueAsBits(__llvm_libc::floorf(-1.0f)));
+  EXPECT_EQ(valueAsBits(10.0f), valueAsBits(__llvm_libc::floorf(10.0f)));
+  EXPECT_EQ(valueAsBits(-10.0f), valueAsBits(__llvm_libc::floorf(-10.0f)));
+  EXPECT_EQ(valueAsBits(12345.0f), valueAsBits(__llvm_libc::floorf(12345.0f)));
+  EXPECT_EQ(valueAsBits(-12345.0f),
+            valueAsBits(__llvm_libc::floorf(-12345.0f)));
+}
+
+TEST(floorfTest, 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::Floor, x, __llvm_libc::floorf(x),
+                      tolerance);
+  }
+}

diff  --git a/libc/test/src/math/trunc_test.cpp b/libc/test/src/math/trunc_test.cpp
new file mode 100644
index 000000000000..55f34a649e9f
--- /dev/null
+++ b/libc/test/src/math/trunc_test.cpp
@@ -0,0 +1,75 @@
+//===-- Unittests for trunc -----------------------------------------------===//
+//
+// 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/trunc.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(TruncTest, SpecialNumbers) {
+  EXPECT_EQ(
+      BitPatterns::aQuietNaN,
+      valueAsBits(__llvm_libc::trunc(valueFromBits(BitPatterns::aQuietNaN))));
+  EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
+            valueAsBits(__llvm_libc::trunc(
+                valueFromBits(BitPatterns::aNegativeQuietNaN))));
+
+  EXPECT_EQ(BitPatterns::aSignallingNaN,
+            valueAsBits(__llvm_libc::trunc(
+                valueFromBits(BitPatterns::aSignallingNaN))));
+  EXPECT_EQ(BitPatterns::aNegativeSignallingNaN,
+            valueAsBits(__llvm_libc::trunc(
+                valueFromBits(BitPatterns::aNegativeSignallingNaN))));
+
+  EXPECT_EQ(BitPatterns::inf,
+            valueAsBits(__llvm_libc::trunc(valueFromBits(BitPatterns::inf))));
+  EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::trunc(
+                                     valueFromBits(BitPatterns::negInf))));
+
+  EXPECT_EQ(BitPatterns::zero,
+            valueAsBits(__llvm_libc::trunc(valueFromBits(BitPatterns::zero))));
+  EXPECT_EQ(BitPatterns::negZero, valueAsBits(__llvm_libc::trunc(
+                                      valueFromBits(BitPatterns::negZero))));
+}
+
+TEST(TruncTest, RoundedNumbers) {
+  EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::trunc(1.0)));
+  EXPECT_EQ(valueAsBits(-1.0), valueAsBits(__llvm_libc::trunc(-1.0)));
+  EXPECT_EQ(valueAsBits(10.0), valueAsBits(__llvm_libc::trunc(10.0)));
+  EXPECT_EQ(valueAsBits(-10.0), valueAsBits(__llvm_libc::trunc(-10.0)));
+  EXPECT_EQ(valueAsBits(12345.0), valueAsBits(__llvm_libc::trunc(12345.0)));
+  EXPECT_EQ(valueAsBits(-12345.0), valueAsBits(__llvm_libc::trunc(-12345.0)));
+}
+
+TEST(truncTest, 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::Trunc, x, __llvm_libc::trunc(x),
+                      tolerance);
+  }
+}

diff  --git a/libc/test/src/math/truncf_test.cpp b/libc/test/src/math/truncf_test.cpp
new file mode 100644
index 000000000000..90fc84a5b5f9
--- /dev/null
+++ b/libc/test/src/math/truncf_test.cpp
@@ -0,0 +1,77 @@
+//===-- Unittests for truncf ----------------------------------------------===//
+//
+// 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/truncf.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::floatPrecision, 0,
+                                           0};
+
+namespace mpfr = __llvm_libc::testing::mpfr;
+TEST(TruncfTest, SpecialNumbers) {
+  EXPECT_EQ(
+      BitPatterns::aQuietNaN,
+      valueAsBits(__llvm_libc::truncf(valueFromBits(BitPatterns::aQuietNaN))));
+  EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
+            valueAsBits(__llvm_libc::truncf(
+                valueFromBits(BitPatterns::aNegativeQuietNaN))));
+
+  EXPECT_EQ(BitPatterns::aSignallingNaN,
+            valueAsBits(__llvm_libc::truncf(
+                valueFromBits(BitPatterns::aSignallingNaN))));
+  EXPECT_EQ(BitPatterns::aNegativeSignallingNaN,
+            valueAsBits(__llvm_libc::truncf(
+                valueFromBits(BitPatterns::aNegativeSignallingNaN))));
+
+  EXPECT_EQ(BitPatterns::inf,
+            valueAsBits(__llvm_libc::truncf(valueFromBits(BitPatterns::inf))));
+  EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::truncf(
+                                     valueFromBits(BitPatterns::negInf))));
+
+  EXPECT_EQ(BitPatterns::zero,
+            valueAsBits(__llvm_libc::truncf(valueFromBits(BitPatterns::zero))));
+  EXPECT_EQ(BitPatterns::negZero, valueAsBits(__llvm_libc::truncf(
+                                      valueFromBits(BitPatterns::negZero))));
+}
+
+TEST(TruncTest, RoundedNumbers) {
+  EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::truncf(1.0f)));
+  EXPECT_EQ(valueAsBits(-1.0f), valueAsBits(__llvm_libc::truncf(-1.0f)));
+  EXPECT_EQ(valueAsBits(10.0f), valueAsBits(__llvm_libc::truncf(10.0f)));
+  EXPECT_EQ(valueAsBits(-10.0f), valueAsBits(__llvm_libc::truncf(-10.0f)));
+  EXPECT_EQ(valueAsBits(12345.0f), valueAsBits(__llvm_libc::truncf(12345.0f)));
+  EXPECT_EQ(valueAsBits(-12345.0f),
+            valueAsBits(__llvm_libc::truncf(-12345.0f)));
+}
+
+TEST(truncfTest, 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::Trunc, x, __llvm_libc::truncf(x),
+                      tolerance);
+  }
+}

diff  --git a/libc/utils/FPUtil/FloatOperations.h b/libc/utils/FPUtil/FloatOperations.h
index ff7604bc8102..a378903c38b4 100644
--- a/libc/utils/FPUtil/FloatOperations.h
+++ b/libc/utils/FPUtil/FloatOperations.h
@@ -40,18 +40,23 @@ static inline typename FloatProperties<T>::BitsType absBits(T x) {
   return valueAsBits(x) & (~FloatProperties<T>::signMask);
 }
 
-// Return the zero adjusted exponent value of x.
-template <typename T,
-          cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
-int getExponent(T x) {
-  using Properties = FloatProperties<T>;
-  using BitsType = typename Properties::BitsType;
-  BitsType bits = absBits(x);
+template <typename BitsType>
+static inline int getExponentFromBits(BitsType bits) {
+  using FPType = typename FloatType<BitsType>::Type;
+  using Properties = FloatProperties<FPType>;
+  bits &= Properties::exponentMask;
   int e = (bits >> Properties::mantissaWidth); // Shift out the mantissa.
   e -= Properties::exponentOffset;             // Zero adjust.
   return e;
 }
 
+// Return the zero adjusted exponent value of x.
+template <typename T,
+          cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline int getExponent(T x) {
+  return getExponentFromBits(valueAsBits(x));
+}
+
 // Return true if x is infinity (positive or negative.)
 template <typename T,
           cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
@@ -74,6 +79,24 @@ static inline bool isNaN(T x) {
          ((bits & Properties::mantissaMask) != 0);
 }
 
+template <typename BitsType> static inline bool bitsAreInfOrNaN(BitsType bits) {
+  using FPType = typename FloatType<BitsType>::Type;
+  return (bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf;
+}
+
+template <typename BitsType> static inline bool bitsAreZero(BitsType bits) {
+  using FPType = typename FloatType<BitsType>::Type;
+  return (bits == BitPatterns<FPType>::zero) ||
+         (bits == BitPatterns<FPType>::negZero);
+}
+
+// Return true if x is any kind of NaN or infinity.
+template <typename T,
+          cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline bool isInfOrNaN(T x) {
+  return bitsAreInfOrNaN(valueAsBits(x));
+}
+
 // Return true if x is a quiet NAN.
 template <typename T,
           cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
@@ -103,6 +126,94 @@ static inline T abs(T x) {
   return valueFromBits(absBits(x));
 }
 
+// Return the trucated value of x. If x is non-negative, then the return value
+// is greatest integer less than or equal to x. Otherwise, return the smallest
+// integer greater than or equal to x. That is, return the integer value rounded
+// toward zero.
+template <typename T,
+          cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline T trunc(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;
+
+  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 the exponent is such that abs(x) is less than 1, then return 0.
+  if (exponent <= -1) {
+    if (Properties::signMask & bits)
+      return T(-0.0);
+    else
+      return T(0.0);
+  }
+
+  uint32_t trimSize = Properties::mantissaWidth - exponent;
+  return valueFromBits((bits >> trimSize) << trimSize);
+}
+
+template <typename T,
+          cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline T ceil(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) {
+    if (isNeg)
+      return T(-0.0);
+    else
+      return T(1.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 x is negative, the ceil operation is equivalent to the trunc operation.
+  if (isNeg)
+    return truncValue;
+
+  return truncValue + T(1.0);
+}
+
+template <typename T,
+          cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
+static inline T floor(T x) {
+  auto bits = valueAsBits(x);
+  if (FloatProperties<T>::signMask & bits) {
+    return -ceil(-x);
+  } else {
+    return trunc(x);
+  }
+}
+
 } // namespace fputil
 } // namespace __llvm_libc
 

diff  --git a/libc/utils/FPUtil/FloatProperties.h b/libc/utils/FPUtil/FloatProperties.h
index a9584c7428a1..fb0917259b91 100644
--- a/libc/utils/FPUtil/FloatProperties.h
+++ b/libc/utils/FPUtil/FloatProperties.h
@@ -21,9 +21,12 @@ template <> struct FloatProperties<float> {
   static_assert(sizeof(BitsType) == sizeof(float),
                 "Unexpected size of 'float' type.");
 
+  static constexpr uint32_t bitWidth = sizeof(BitsType) << 3;
+
   static constexpr uint32_t mantissaWidth = 23;
   static constexpr BitsType mantissaMask = 0x007fffffU;
   static constexpr BitsType signMask = 0x80000000U;
+  static constexpr BitsType exponentMask = ~(signMask | mantissaMask);
   static constexpr uint32_t exponentOffset = 127;
 
   // If a number x is a NAN, then it is a quiet NAN if:
@@ -37,9 +40,12 @@ template <> struct FloatProperties<double> {
   static_assert(sizeof(BitsType) == sizeof(double),
                 "Unexpected size of 'double' type.");
 
+  static constexpr uint32_t bitWidth = sizeof(BitsType) << 3;
+
   static constexpr uint32_t mantissaWidth = 52;
   static constexpr BitsType mantissaMask = 0x000fffffffffffffU;
   static constexpr BitsType signMask = 0x8000000000000000ULL;
+  static constexpr BitsType exponentMask = ~(signMask | mantissaMask);
   static constexpr uint32_t exponentOffset = 1023;
 
   // If a number x is a NAN, then it is a quiet NAN if:

diff  --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index 51c8c3759292..1bbc84d554c0 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -89,6 +89,9 @@ class MPFRNumber {
     case Operation::Abs:
       mpfr_abs(value, mpfrInput.value, MPFR_RNDN);
       break;
+    case Operation::Ceil:
+      mpfr_ceil(value, mpfrInput.value);
+      break;
     case Operation::Cos:
       mpfr_cos(value, mpfrInput.value, MPFR_RNDN);
       break;
@@ -98,9 +101,18 @@ class MPFRNumber {
     case Operation::Exp2:
       mpfr_exp2(value, mpfrInput.value, MPFR_RNDN);
       break;
+    case Operation::Floor:
+      mpfr_floor(value, mpfrInput.value);
+      break;
+    case Operation::Round:
+      mpfr_round(value, mpfrInput.value);
+      break;
     case Operation::Sin:
       mpfr_sin(value, mpfrInput.value, MPFR_RNDN);
       break;
+    case Operation::Trunc:
+      mpfr_trunc(value, mpfrInput.value);
+      break;
     }
   }
 

diff  --git a/libc/utils/MPFRWrapper/MPFRUtils.h b/libc/utils/MPFRWrapper/MPFRUtils.h
index e39ed91281a9..562816565332 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.h
+++ b/libc/utils/MPFRWrapper/MPFRUtils.h
@@ -39,7 +39,17 @@ struct Tolerance {
   uint32_t bits;
 };
 
-enum class Operation : int { Abs, Cos, Exp, Exp2, Sin };
+enum class Operation : int {
+  Abs,
+  Ceil,
+  Cos,
+  Exp,
+  Exp2,
+  Floor,
+  Round,
+  Sin,
+  Trunc
+};
 
 namespace internal {
 


        


More information about the libc-commits mailing list