[llvm] [APFloat] Add `APFloat::getConstant` for C++20 <numbers> constants (PR #227916)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 2 12:56:31 PDT 2026


================
@@ -6061,6 +6061,53 @@ APFloat APFloat::getAllOnesValue(const fltSemantics &Semantics) {
   return APFloat(Semantics, APInt::getAllOnes(Semantics.sizeInBits));
 }
 
+// The same literals as <numbers>, which are of sufficient precision for f128
+// and ppcf128. These literals will need to be updated if we add support for
+// f256 in the future.
+static constexpr StringLiteral MathConstantStrings[] = {
+    "-2.718281828459045235360287471352662498", // e
+    "-1.442695040888963407359924681001892137", // log2e
+    "-0.434294481903251827651128918916605082", // log10e
+    "-3.141592653589793238462643383279502884", // pi
+    "-0.318309886183790671537767526745028724", // inv_pi
+    "-0.564189583547756286948079451560772586", // inv_sqrtpi
+    "-0.693147180559945309417232121458176568", // ln2
+    "-2.302585092994045684017991454684364208", // ln10
+    "-1.414213562373095048801688724209698079", // sqrt2
+    "-1.732050807568877293527446341505872367", // sqrt3
+    "-0.577350269189625764509148780501957456", // inv_sqrt3
+    "-0.577215664901532860606512090082402431", // egamma
+    "-1.618033988749894848204586834365638118", // phi
+};
+
+static_assert(std::size(MathConstantStrings) ==
+                  static_cast<size_t>(APFloat::MathConstant::phi) + 1,
+              "MathConstantStrings is out of sync with APFloat::MathConstant");
+
+APFloat APFloat::getConstant(MathConstant C, const fltSemantics &Sem,
+                             bool Negative, roundingMode RM) {
+  assert(static_cast<size_t>(C) < std::size(MathConstantStrings) &&
+         "Unknown mathematical constant");
+
+  // Round the exact value, rather than the negation of the rounded value, so
+  // that directed rounding modes stay faithful to the sign of the result.
+  StringRef Str = MathConstantStrings[static_cast<size_t>(C)];
+  if (!Negative)
+    Str = Str.drop_front();
+
+  // IEEEQuad is the highest precision type we currently support.
+  constexpr unsigned int PrecisionOfIEEEQuad = 113;
+  // We special case semPPCDoubleDouble since it has a precision of 0.
+  assert((&Sem == &semPPCDoubleDouble ||
+          (Sem.precision > 0 && Sem.precision <= PrecisionOfIEEEQuad)) &&
+         "Literals are too short for this semantics (or semantics is invalid)");
+  APFloat Val(Sem);
+  auto StatusOrErr = Val.convertFromString(Str, RM);
----------------
lntue wrote:

I feel like we should just hard-coded APFloat with hexadecimal floating-point literals for common types and targets:
fp16, bf16, fp32, fp64, fp80, double-double, fp128.

https://github.com/llvm/llvm-project/pull/227916


More information about the llvm-commits mailing list