-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[libc][math] Implement nan(f|l) functions #76690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-libc Author: Nishant Mittal (nishantwrp) ChangesPatch is 21.78 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/76690.diff 23 Files Affected:
diff --git a/libc/config/darwin/arm/entrypoints.txt b/libc/config/darwin/arm/entrypoints.txt
index da4a2345f389c4..02a09256606956 100644
--- a/libc/config/darwin/arm/entrypoints.txt
+++ b/libc/config/darwin/arm/entrypoints.txt
@@ -193,6 +193,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.modf
libc.src.math.modff
libc.src.math.modfl
+ libc.src.math.nan
+ libc.src.math.nanf
+ libc.src.math.nanl
libc.src.math.nearbyint
libc.src.math.nearbyintf
libc.src.math.nearbyintl
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index e29e75ec92dadc..91493cb77b1d86 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -172,6 +172,9 @@ set(TARGET_LIBM_ENTRYPOINTS
#libc.src.math.modf
#libc.src.math.modff
#libc.src.math.modfl
+ #libc.src.math.nan
+ #libc.src.math.nanf
+ #libc.src.math.nanl
#libc.src.math.nearbyint
#libc.src.math.nearbyintf
#libc.src.math.nearbyintl
diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index ba86e31ee0adcd..b333c6be144627 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -215,6 +215,8 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.lroundf
libc.src.math.modf
libc.src.math.modff
+ libc.src.math.nan
+ libc.src.math.nanf
libc.src.math.nearbyint
libc.src.math.nearbyintf
libc.src.math.nextafter
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 77c9a50b8b7e5d..ce3f5eb40e38aa 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -313,6 +313,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.modf
libc.src.math.modff
libc.src.math.modfl
+ libc.src.math.nan
+ libc.src.math.nanf
+ libc.src.math.nanl
libc.src.math.nearbyint
libc.src.math.nearbyintf
libc.src.math.nearbyintl
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index e389936ffca1ef..ec2a16f5cf473b 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -322,6 +322,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.modf
libc.src.math.modff
libc.src.math.modfl
+ libc.src.math.nan
+ libc.src.math.nanf
+ libc.src.math.nanl
libc.src.math.nearbyint
libc.src.math.nearbyintf
libc.src.math.nearbyintl
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 3adcd57d0c0849..30900de365bf95 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -323,6 +323,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.modf
libc.src.math.modff
libc.src.math.modfl
+ libc.src.math.nan
+ libc.src.math.nanf
+ libc.src.math.nanl
libc.src.math.nearbyint
libc.src.math.nearbyintf
libc.src.math.nearbyintl
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 4c0a6ec37fe4cc..5c3a2e287b9529 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -192,6 +192,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.modf
libc.src.math.modff
libc.src.math.modfl
+ libc.src.math.nan
+ libc.src.math.nanf
+ libc.src.math.nanl
libc.src.math.nearbyint
libc.src.math.nearbyintf
libc.src.math.nearbyintl
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index eaa7a40a29ae73..3668524af03c27 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -212,11 +212,11 @@ Basic Operations
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| modfl | |check| | |check| | | |check| | |check| | | | |check| | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
-| nan | | | | | | | | | | | | |
+| nan | |check| | |check| | | |check| | |check| | | | |check| | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
-| nanf | | | | | | | | | | | | |
+| nanf | |check| | |check| | | |check| | |check| | | | |check| | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
-| nanl | | | | | | | | | | | | |
+| nanl | |check| | |check| | | |check| | |check| | | | |check| | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nearbyint | |check| | |check| | | |check| | |check| | | | |check| | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 58c95b856535a1..78095eb23f0711 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -515,6 +515,10 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"scalbn", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>]>,
FunctionSpec<"scalbnf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>]>,
FunctionSpec<"scalbnl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>]>,
+
+ FunctionSpec<"nanf", RetValSpec<FloatType>, [ArgSpec<ConstCharPtr>]>,
+ FunctionSpec<"nan", RetValSpec<DoubleType>, [ArgSpec<ConstCharPtr>]>,
+ FunctionSpec<"nanl", RetValSpec<LongDoubleType>, [ArgSpec<ConstCharPtr>]>,
]
>;
diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h
index 36b512d6972a93..555f65707b4e41 100644
--- a/libc/src/__support/str_to_float.h
+++ b/libc/src/__support/str_to_float.h
@@ -1206,6 +1206,34 @@ LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) {
return {T(result), index, error};
}
+LIBC_INLINE const char *nan_str_to_floatingpoint_str(const char *arg) {
+ ptrdiff_t index = 0;
+ while (isalnum(arg[index]) || arg[index] == '_')
+ ++index;
+
+ if (arg[index] == '\0') {
+ // 5 is the number of characters in string "NAN()".
+ ptrdiff_t size = 5 + index;
+ char *output_str = new char[size + 1];
+
+ output_str[0] = 'N';
+ output_str[1] = 'A';
+ output_str[2] = 'N';
+ output_str[3] = '(';
+
+ for (ptrdiff_t i = 0; i < index; ++i) {
+ output_str[4 + i] = arg[i];
+ }
+
+ output_str[size - 1] = ')';
+ output_str[size] = '\0';
+
+ return output_str;
+ }
+
+ return "NAN";
+}
+
} // namespace internal
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index ffabc27bc00abc..e2b1026fcad7e5 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -179,6 +179,10 @@ add_math_entrypoint_object(modf)
add_math_entrypoint_object(modff)
add_math_entrypoint_object(modfl)
+add_math_entrypoint_object(nan)
+add_math_entrypoint_object(nanf)
+add_math_entrypoint_object(nanl)
+
add_math_entrypoint_object(nearbyint)
add_math_entrypoint_object(nearbyintf)
add_math_entrypoint_object(nearbyintl)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 214d57842d93b5..eeb09652961fd5 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1437,6 +1437,45 @@ add_entrypoint_object(
-O3
)
+add_entrypoint_object(
+ nan
+ SRCS
+ nan.cpp
+ HDRS
+ ../nan.h
+ DEPENDS
+ libc.src.__support.str_to_float
+ libc.src.errno.errno
+ COMPILE_OPTIONS
+ -O3
+)
+
+add_entrypoint_object(
+ nanf
+ SRCS
+ nanf.cpp
+ HDRS
+ ../nanf.h
+ DEPENDS
+ libc.src.__support.str_to_float
+ libc.src.errno.errno
+ COMPILE_OPTIONS
+ -O3
+)
+
+add_entrypoint_object(
+ nanl
+ SRCS
+ nanl.cpp
+ HDRS
+ ../nanl.h
+ DEPENDS
+ libc.src.__support.str_to_float
+ libc.src.errno.errno
+ COMPILE_OPTIONS
+ -O3
+)
+
add_entrypoint_object(
nextafter
SRCS
diff --git a/libc/src/math/generic/nan.cpp b/libc/src/math/generic/nan.cpp
new file mode 100644
index 00000000000000..9d591dcd3d091b
--- /dev/null
+++ b/libc/src/math/generic/nan.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of nan 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/math/nan.h"
+#include "src/__support/common.h"
+#include "src/__support/str_to_float.h"
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, nan, (const char *arg)) {
+ const char *fp_str = internal::nan_str_to_floatingpoint_str(arg);
+ auto result = internal::strtofloatingpoint<double>(fp_str);
+
+ if (result.has_error())
+ libc_errno = result.error;
+
+ return result.value;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nanf.cpp b/libc/src/math/generic/nanf.cpp
new file mode 100644
index 00000000000000..b83e715485e471
--- /dev/null
+++ b/libc/src/math/generic/nanf.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of nanf 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/math/nanf.h"
+#include "src/__support/common.h"
+#include "src/__support/str_to_float.h"
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, nanf, (const char *arg)) {
+ const char *fp_str = internal::nan_str_to_floatingpoint_str(arg);
+ auto result = internal::strtofloatingpoint<float>(fp_str);
+
+ if (result.has_error())
+ libc_errno = result.error;
+
+ return result.value;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nanl.cpp b/libc/src/math/generic/nanl.cpp
new file mode 100644
index 00000000000000..6f70af9957b426
--- /dev/null
+++ b/libc/src/math/generic/nanl.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of nanl 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/math/nanl.h"
+#include "src/__support/common.h"
+#include "src/__support/str_to_float.h"
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long double, nanl, (const char *arg)) {
+ const char *fp_str = internal::nan_str_to_floatingpoint_str(arg);
+ auto result = internal::strtofloatingpoint<long double>(fp_str);
+
+ if (result.has_error())
+ libc_errno = result.error;
+
+ return result.value;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/nan.h b/libc/src/math/nan.h
new file mode 100644
index 00000000000000..463940b01a2720
--- /dev/null
+++ b/libc/src/math/nan.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nan ---------------------------*- 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_NAN_H
+#define LLVM_LIBC_SRC_MATH_NAN_H
+
+namespace LIBC_NAMESPACE {
+
+double nan(const char *arg);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NAN_H
diff --git a/libc/src/math/nanf.h b/libc/src/math/nanf.h
new file mode 100644
index 00000000000000..f05d60e3a96718
--- /dev/null
+++ b/libc/src/math/nanf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nanf --------------------------*- 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_NANF_H
+#define LLVM_LIBC_SRC_MATH_NANF_H
+
+namespace LIBC_NAMESPACE {
+
+float nanf(const char *arg);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NANF_H
diff --git a/libc/src/math/nanl.h b/libc/src/math/nanl.h
new file mode 100644
index 00000000000000..d8bbce7cc1bcc3
--- /dev/null
+++ b/libc/src/math/nanl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nanl --------------------------*- 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_NANL_H
+#define LLVM_LIBC_SRC_MATH_NANL_H
+
+namespace LIBC_NAMESPACE {
+
+long double nanl(const char *arg);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NANL_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 6ebd374d04a5ba..6488f9f86f1fd3 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1203,6 +1203,42 @@ add_fp_unittest(
libc.src.__support.FPUtil.fp_bits
)
+add_fp_unittest(
+ nanf_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nanf_test.cpp
+ DEPENDS
+ libc.include.math
+ libc.src.math.nanf
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
+ nan_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nan_test.cpp
+ DEPENDS
+ libc.include.math
+ libc.src.math.nan
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
+ nanl_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nanl_test.cpp
+ DEPENDS
+ libc.include.math
+ libc.src.math.nanl
+ libc.src.__support.FPUtil.fp_bits
+)
+
# FIXME: These tests are currently spurious for NVPTX.
if(NOT LIBC_GPU_TARGET_ARCHITECTURE_IS_NVPTX)
add_fp_unittest(
diff --git a/libc/test/src/math/smoke/nan_test.cpp b/libc/test/src/math/smoke/nan_test.cpp
new file mode 100644
index 00000000000000..6ff60be92e045b
--- /dev/null
+++ b/libc/test/src/math/smoke/nan_test.cpp
@@ -0,0 +1,40 @@
+//===-- Unittests for nan -------------------------------------------------===//
+//
+// 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/FPUtil/FPBits.h"
+#include "src/math/nan.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+class LlvmLibcNanTest : public LIBC_NAMESPACE::testing::Test {
+public:
+ using StorageType = LIBC_NAMESPACE::fputil::FPBits<double>::StorageType;
+
+ void run_test(const char *input_str, StorageType bits) {
+ double result = LIBC_NAMESPACE::nan(input_str);
+ auto actual_fp = LIBC_NAMESPACE::fputil::FPBits<double>(result);
+ auto expected_fp = LIBC_NAMESPACE::fputil::FPBits<double>(bits);
+ EXPECT_EQ(actual_fp.bits, expected_fp.bits);
+ };
+};
+
+TEST_F(LlvmLibcNanTest, NCharSeq) {
+ run_test("", 0x7ff8000000000000);
+ run_test("1234", 0x7ff80000000004d2);
+ run_test("0x1234", 0x7ff8000000001234);
+ run_test("1a", 0x7ff8000000000000);
+ run_test("1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_",
+ 0x7ff8000000000000);
+}
+
+TEST_F(LlvmLibcNanTest, RandomString) {
+ run_test(" 1234", 0x7ff8000000000000);
+ run_test("-1234", 0x7ff8000000000000);
+ run_test("asd&f", 0x7ff8000000000000);
+ run_test("123 ", 0x7ff8000000000000);
+}
diff --git a/libc/test/src/math/smoke/nanf_test.cpp b/libc/test/src/math/smoke/nanf_test.cpp
new file mode 100644
index 00000000000000..a8ff2f6b019c49
--- /dev/null
+++ b/libc/test/src/math/smoke/nanf_test.cpp
@@ -0,0 +1,40 @@
+//===-- Unittests for nanf ------------------------------------------------===//
+//
+// 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/FPUtil/FPBits.h"
+#include "src/math/nanf.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+class LlvmLibcNanfTest : public LIBC_NAMESPACE::testing::Test {
+public:
+ using StorageType = LIBC_NAMESPACE::fputil::FPBits<float>::StorageType;
+
+ void run_test(const char *input_str, StorageType bits) {
+ float result = LIBC_NAMESPACE::nanf(input_str);
+ auto actual_fp = LIBC_NAMESPACE::fputil::FPBits<float>(result);
+ auto expected_fp = LIBC_NAMESPACE::fputil::FPBits<float>(bits);
+ EXPECT_EQ(actual_fp.bits, expected_fp.bits);
+ };
+};
+
+TEST_F(LlvmLibcNanfTest, NCharSeq) {
+ run_test("", 0x7fc00000);
+ run_test("1234", 0x7fc004d2);
+ run_test("0x1234", 0x7fc01234);
+ run_test("1a", 0x7fc00000);
+ run_test("1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_",
+ 0x7fc00000);
+}
+
+TEST_F(LlvmLibcNanfTest, RandomString) {
+ run_test(" 1234", 0x7fc00000);
+ run_test("-1234", 0x7fc00000);
+ run_test("asd&f", 0x7fc00000);
+ run_test("123 ", 0x7fc00000);
+}
diff --git a/libc/test/src/math/smoke/nanl_test.cpp b/libc/test/src/math/smoke/nanl_test.cpp
new file mode 100644
index 00000000000000..a4283b0dcabc25
--- /dev/null
+++ b/libc/test/src/math/smoke/nanl_test.cpp
@@ -0,0 +1,64 @@
+//===-- Unittests for nanl ------------------------------------------------===//
+//
+// 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/FPUtil/FPBits.h"
+#include "src/math/nanl.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#if defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#define SELECT_LONG_DOUBLE(val, _, __) val
+#elif defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#define SELECT_LONG_DOUBLE(_, val, __) val
+#else
+#define SELECT_LONG_DOUBLE(_, __, val) val
+#endif
+
+class LlvmLibcNanlTest : public LIBC_NAMESPACE::testing::Test {
+public:
+ using StorageType = LIBC_NAMESPACE::fputil::FPBits<long double>::StorageType;
+
+ void run_test(const char *input_str, StorageType bits) {
+ long double result = LIBC_NAMESPACE::nanl(input_str);
+ auto actual_fp = LIBC_NAMESPACE::fputil::FPBits<long double>(result);
+ auto expected_fp = LIBC_NAMESPACE::fputil::FPBits<long double>(bits);
+ EXPECT_EQ(actual_fp.bits, expected_fp.bits);
+ };
+};
+
+TEST_F(LlvmLibcNanlTest, NCharSeq) {
+ run_test("",
+ SELECT_LONG_DOUBLE(0x7ff8000000000000, (UInt128(0x7fffc00000) << 40),
+ (UInt128(0x7fff800000000000) << 64)));
...
[truncated]
|
@lntue please review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The standard says that the implementation should be like passing "NAN(n-character-sequence)" to string to float, but actually generating the string to pass to string to float is not an efficient design. I'd recommend you look at str_to_float.h
lines 1141-1169 to see how the n-character-sequence is currently parsed, then try to refactor that code into something that can be reused for these new functions.
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM once Tue's comments are addressed.
@lntue ptal! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved with nits. Feel free to land after fixing.
libc/src/__support/str_to_float.h
Outdated
nan_mantissa_from_ncharseq(const cpp::string_view ncharseq) { | ||
uint64_t nan_mantissa = 0; | ||
|
||
if (ncharseq.data() != nullptr && isdigit(*ncharseq.data())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: *ncharseq.data()
should be ncharseq[0]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
libc/src/__support/str_to_float.h
Outdated
if (!strtoint_result.has_error()) | ||
nan_mantissa = strtoint_result.value; | ||
|
||
if (strtoint_result.parsed_len != (ptrdiff_t)ncharseq.size()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This should be a C++ style cast
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Specification: https://en.cppreference.com/w/c/numeric/math/nan