1//===-- Double-precision log(x) function ----------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "src/math/log.h"
10#include "src/__support/FPUtil/FEnvImpl.h"
11#include "src/__support/FPUtil/FPBits.h"
12#include "src/__support/FPUtil/PolyEval.h"
13#include "src/__support/FPUtil/double_double.h"
14#include "src/__support/FPUtil/dyadic_float.h"
15#include "src/__support/FPUtil/multiply_add.h"
16#include "src/__support/common.h"
17#include "src/__support/integer_literals.h"
18#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
19
20#include "common_constants.h"
21#include "log_range_reduction.h"
22
23namespace LIBC_NAMESPACE {
24
25// 128-bit precision dyadic floating point numbers.
26using Float128 = typename fputil::DyadicFloat<128>;
27
28using LIBC_NAMESPACE::operator""_u128;
29
30namespace {
31
32// A simple upper bound for the error of e_x * log(2) - log(r).
33constexpr double HI_ERR = 0x1.0p-85;
34
35// Extra errors from P is from using x^2 to reduce evaluation latency.
36constexpr double P_ERR = 0x1.0p-50;
37
38// log(2) with 128-bit precision generated by SageMath with:
39// def format_hex(value):
40// l = hex(value)[2:]
41// n = 8
42// x = [l[i:i + n] for i in range(0, len(l), n)]
43// return "0x" + "'".join(x) + "_u128"
44// (s, m, e) = RealField(128)(2).log().sign_mantissa_exponent();
45// print(format_hex(m));
46constexpr Float128 LOG_2(Sign::POS, /*exponent=*/-128, /*mantissa=*/
47 0xb17217f7'd1cf79ab'c9e3b398'03f2f6af_u128);
48
49alignas(64) constexpr LogRR LOG_TABLE = {
50 // -log(r) with 128-bit precision generated by SageMath with:
51 // for i in range(128):
52 // r = 2^-8 * ceil( 2^8 * (1 - 2^(-8)) / (1 + i*2^(-7)) );
53 // s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
54 // print("{Sign::POS,", e, ", format_hex(m), "},");
55 /* .step_1= */ {
56 {Sign::POS, 0, 0_u128},
57 {Sign::POS, -134, 0x8080abac'46f38946'662d417c'ed007a46_u128},
58 {Sign::POS, -133, 0x8102b2c4'9ac23a4f'91d082dc'e3ddcd38_u128},
59 {Sign::POS, -133, 0xc2492946'4655f45c'da5f3cc0'b3251dbd_u128},
60 {Sign::POS, -132, 0x820aec4f'3a222380'b9e3aea6'c444ef07_u128},
61 {Sign::POS, -132, 0xa33576a1'6f1f4c64'521016bd'904dc968_u128},
62 {Sign::POS, -132, 0xc4a550a4'fd9a19a8'be97660a'23cc540d_u128},
63 {Sign::POS, -132, 0xe65b9e6e'ed965c36'e09f5fe2'058d6006_u128},
64 {Sign::POS, -131, 0x842cc5ac'f1d03445'1fecdfa8'19b96098_u128},
65 {Sign::POS, -131, 0x8cb9de8a'32ab368a'a7c98595'30a45153_u128},
66 {Sign::POS, -131, 0x9defad3e'8f73217a'976d3b5b'45f6ca0b_u128},
67 {Sign::POS, -131, 0xaf4ad26c'bc8e5be7'0e8b8b88'a14ff0ce_u128},
68 {Sign::POS, -131, 0xb8069857'560707a3'6a677b4c'8bec22e1_u128},
69 {Sign::POS, -131, 0xc99af2ea'ca4c4570'eaf51f66'692844ba_u128},
70 {Sign::POS, -131, 0xdb56446d'6ad8deff'a8112e35'a60e6375_u128},
71 {Sign::POS, -131, 0xe442c00d'e2591b47'196ab34c'e0bccd12_u128},
72 {Sign::POS, -131, 0xf639cc18'5088fe5d'4066e87f'2c0f7340_u128},
73 {Sign::POS, -131, 0xff4489ce'deab2ca6'c17bd40d'8d9291ec_u128},
74 {Sign::POS, -130, 0x88bc7411'3f23def1'9c5a0fe3'96f40f1e_u128},
75 {Sign::POS, -130, 0x8d515bf1'1fb94f1c'88713268'840cbcc0_u128},
76 {Sign::POS, -130, 0x968b0864'3409ceb6'65c0da50'6a088484_u128},
77 {Sign::POS, -130, 0x9b2fe580'ac80b17d'411a5b94'4aca8708_u128},
78 {Sign::POS, -130, 0xa489ec19'9dab06f2'a9fb6cf0'ecb411b7_u128},
79 {Sign::POS, -130, 0xa93f2f25'0dac67d1'cad2fb8d'48054ae0_u128},
80 {Sign::POS, -130, 0xb2ba75f4'6099cf8b'2c3c2e77'904afa78_u128},
81 {Sign::POS, -130, 0xb780945b'ab55dce4'34c7bc3d'32750fde_u128},
82 {Sign::POS, -130, 0xc11e0b2a'8d1e0ddb'9a631e83'0fd30904_u128},
83 {Sign::POS, -130, 0xc5f57f59'c7f46155'aa8b6997'a402bf30_u128},
84 {Sign::POS, -130, 0xcad2d6e7'b80bf914'2c507fb7'a3d0bf6a_u128},
85 {Sign::POS, -130, 0xd49f69e4'56cf1b79'5f53bd2e'406e66e7_u128},
86 {Sign::POS, -130, 0xd98ec2ba'de71e539'58a98f2a'd65bee9b_u128},
87 {Sign::POS, -130, 0xde8439c1'dec56877'4d57da94'5b5d0aaa_u128},
88 {Sign::POS, -130, 0xe881bf93'2af3dac0'c524848e'3443e040_u128},
89 {Sign::POS, -130, 0xed89ed86'a44a01aa'11d49f96'cb88317b_u128},
90 {Sign::POS, -130, 0xf29877ff'38809091'3b020fa1'820c9492_u128},
91 {Sign::POS, -130, 0xf7ad6f26'e7ff2ef7'54d2238f'75f969b1_u128},
92 {Sign::POS, -130, 0xfcc8e365'9d9bcbec'ca0cdf30'1431b60f_u128},
93 {Sign::POS, -129, 0x8389c302'6ac3139b'62dda9d2'270fa1f4_u128},
94 {Sign::POS, -129, 0x86216b3b'0b17188b'163ceae8'8f720f1e_u128},
95 {Sign::POS, -129, 0x88bc7411'3f23def1'9c5a0fe3'96f40f1e_u128},
96 {Sign::POS, -129, 0x8b5ae65d'67db9acd'f7a51681'26a58b9a_u128},
97 {Sign::POS, -129, 0x8dfccb1a'd35ca6ed'5147bdb6'ddcaf59c_u128},
98 {Sign::POS, -129, 0x934b1089'a6dc93c1'df5bb3b6'0554e152_u128},
99 {Sign::POS, -129, 0x95f783e6'e49a9cfa'4a5004f3'ef063313_u128},
100 {Sign::POS, -129, 0x98a78f0e'9ae71d85'2cdec347'84707839_u128},
101 {Sign::POS, -129, 0x9b5b3bb5'f088b766'd878bbe3'd392be25_u128},
102 {Sign::POS, -129, 0x9e1293b9'998c1daa'5b035eae'273a855f_u128},
103 {Sign::POS, -129, 0xa0cda11e'af46390d'bb243827'3918db7e_u128},
104 {Sign::POS, -129, 0xa38c6e13'8e20d831'f698298a'dddd7f32_u128},
105 {Sign::POS, -129, 0xa64f04f0'b961df76'e4f5275c'2d15c21f_u128},
106 {Sign::POS, -129, 0xa9157039'c51ebe70'8164c759'686a2209_u128},
107 {Sign::POS, -129, 0xabdfba9e'468fd6f6'f72ea077'49ce6bd3_u128},
108 {Sign::POS, -129, 0xaeadeefa'caf97d35'7dd6e688'ebb13b03_u128},
109 {Sign::POS, -129, 0xb1801859'd56249dc'18ce51ff'f99479cd_u128},
110 {Sign::POS, -129, 0xb45641f4'e350a0d3'2756eba0'0bc33978_u128},
111 {Sign::POS, -129, 0xb7307735'78cb90b2'be1116c3'466beb6d_u128},
112 {Sign::POS, -129, 0xba0ec3b6'33dd8b09'49dc60b2'b059a60b_u128},
113 {Sign::POS, -129, 0xbcf13343'e7d9ec7d'2efd1778'1bb3afec_u128},
114 {Sign::POS, -129, 0xbfd7d1de'c0a8df6f'37eda996'244bccb0_u128},
115 {Sign::POS, -129, 0xc2c2abbb'6e5fd56f'33337789'd592e296_u128},
116 {Sign::POS, -129, 0xc5b1cd44'596fa51e'1a18fb8f'9f9ef280_u128},
117 {Sign::POS, -129, 0xc8a5431a'dfb44ca5'688ce7c1'a75e341a_u128},
118 {Sign::POS, -129, 0xcb9d1a18'9ab56e76'2d7e9307'c70c0668_u128},
119 {Sign::POS, -129, 0xce995f50'af69d861'ef2f3f4f'861ad6a9_u128},
120 {Sign::POS, -129, 0xd19a2011'27d3c645'7f9d79f5'1dcc7301_u128},
121 {Sign::POS, -129, 0xd19a2011'27d3c645'7f9d79f5'1dcc7301_u128},
122 {Sign::POS, -129, 0xd49f69e4'56cf1b79'5f53bd2e'406e66e7_u128},
123 {Sign::POS, -129, 0xd7a94a92'466e833a'ad88bba7'd0cee8e0_u128},
124 {Sign::POS, -129, 0xdab7d022'31484a92'96c20cca'6efe2ac5_u128},
125 {Sign::POS, -129, 0xddcb08dc'0717d85b'f40a666c'87842843_u128},
126 {Sign::POS, -129, 0xe0e30349'fd1cec80'7fe8e180'2aba24d6_u128},
127 {Sign::POS, -129, 0xe0e30349'fd1cec80'7fe8e180'2aba24d6_u128},
128 {Sign::POS, -129, 0xe3ffce3a'2aa64922'3eadb651'b49ac53a_u128},
129 {Sign::POS, -129, 0xe72178c0'323a1a0f'304e1653'e71d9973_u128},
130 {Sign::POS, -129, 0xea481236'f7d35baf'e9a767a8'0d6d97e8_u128},
131 {Sign::POS, -129, 0xed73aa42'64b0ade9'4f91cf4b'33e42998_u128},
132 {Sign::POS, -129, 0xf0a450d1'39366ca6'fc66eb64'08ff6433_u128},
133 {Sign::POS, -129, 0xf0a450d1'39366ca6'fc66eb64'08ff6433_u128},
134 {Sign::POS, -129, 0xf3da161e'ed6b9aaf'ac8d42f7'8d3e65d3_u128},
135 {Sign::POS, -129, 0xf7150ab5'a09f27f4'5a470250'd40ebe90_u128},
136 {Sign::POS, -129, 0xfa553f70'18c966f2'b780a545'a1b54dcf_u128},
137 {Sign::POS, -129, 0xfa553f70'18c966f2'b780a545'a1b54dcf_u128},
138 {Sign::POS, -129, 0xfd9ac57b'd244217e'8f05924d'258c14c5_u128},
139 {Sign::POS, -128, 0x8072d72d'903d588b'89d1b09c'70c4010a_u128},
140 {Sign::POS, -128, 0x821b05f3'b01d6774'030d58c3'f7e2ea1f_u128},
141 {Sign::POS, -128, 0x821b05f3'b01d6774'030d58c3'f7e2ea1f_u128},
142 {Sign::POS, -128, 0x83c5f829'9e2b4091'20f6fafe'8fbb68b9_u128},
143 {Sign::POS, -128, 0x8573b716'82a7d21a'e21f9f89'c1ab80b2_u128},
144 {Sign::POS, -128, 0x8573b716'82a7d21a'e21f9f89'c1ab80b2_u128},
145 {Sign::POS, -128, 0x87244c30'8e670a66'01e005d0'6dbfa8f8_u128},
146 {Sign::POS, -128, 0x88d7c11e'3ad53cdc'223111a7'07b6de2c_u128},
147 {Sign::POS, -128, 0x88d7c11e'3ad53cdc'223111a7'07b6de2c_u128},
148 {Sign::POS, -128, 0x8a8e1fb7'94b09134'2eb628db'a173c82d_u128},
149 {Sign::POS, -128, 0x8c477207'91e53313'be2ad194'15fe25a5_u128},
150 {Sign::POS, -128, 0x8c477207'91e53313'be2ad194'15fe25a5_u128},
151 {Sign::POS, -128, 0x8e03c24d'73003959'bddae1cc'ce247838_u128},
152 {Sign::POS, -128, 0x8fc31afe'30b2c6de'9b00bf16'7e95da67_u128},
153 {Sign::POS, -128, 0x8fc31afe'30b2c6de'9b00bf16'7e95da67_u128},
154 {Sign::POS, -128, 0x918586c5'f5e4bf01'9b92199e'd1a4bab1_u128},
155 {Sign::POS, -128, 0x934b1089'a6dc93c1'df5bb3b6'0554e152_u128},
156 {Sign::POS, -128, 0x934b1089'a6dc93c1'df5bb3b6'0554e152_u128},
157 {Sign::POS, -128, 0x9513c368'76083695'f3cbc416'a2418012_u128},
158 {Sign::POS, -128, 0x96dfaabd'86fa1646'be1188fb'c94e2f15_u128},
159 {Sign::POS, -128, 0x96dfaabd'86fa1646'be1188fb'c94e2f15_u128},
160 {Sign::POS, -128, 0x98aed221'a03458b6'1d2f8932'1647b358_u128},
161 {Sign::POS, -128, 0x98aed221'a03458b6'1d2f8932'1647b358_u128},
162 {Sign::POS, -128, 0x9a81456c'ec642e0f'e549f9aa'ea3cb5e1_u128},
163 {Sign::POS, -128, 0x9c5710b8'cbb73a42'a2554b2d'd4619e63_u128},
164 {Sign::POS, -128, 0x9c5710b8'cbb73a42'a2554b2d'd4619e63_u128},
165 {Sign::POS, -128, 0x9e304061'b5fda919'30603d87'b6df81ad_u128},
166 {Sign::POS, -128, 0x9e304061'b5fda919'30603d87'b6df81ad_u128},
167 {Sign::POS, -128, 0xa00ce109'2e5498c3'67879c5a'30cd1242_u128},
168 {Sign::POS, -128, 0xa1ecff97'c91e267b'0b7efae0'8e597e16_u128},
169 {Sign::POS, -128, 0xa1ecff97'c91e267b'0b7efae0'8e597e16_u128},
170 {Sign::POS, -128, 0xa3d0a93f'45169a4a'83594fab'088c0d65_u128},
171 {Sign::POS, -128, 0xa3d0a93f'45169a4a'83594fab'088c0d65_u128},
172 {Sign::POS, -128, 0xa5b7eb7c'b860fb88'af6a62a0'dec6e073_u128},
173 {Sign::POS, -128, 0xa5b7eb7c'b860fb88'af6a62a0'dec6e073_u128},
174 {Sign::POS, -128, 0xa7a2d41a'd270c9d7'49362382'a768847a_u128},
175 {Sign::POS, -128, 0xa7a2d41a'd270c9d7'49362382'a768847a_u128},
176 {Sign::POS, -128, 0xa9917134'33c2b998'8ba4aea6'14d05701_u128},
177 {Sign::POS, -128, 0xa9917134'33c2b998'8ba4aea6'14d05701_u128},
178 {Sign::POS, -128, 0xab83d135'dc633301'7fe6607b'a902ef3c_u128},
179 {Sign::POS, -128, 0xab83d135'dc633301'7fe6607b'a902ef3c_u128},
180 {Sign::POS, -128, 0xad7a02e1'b24efd31'd60864fd'949b4bd3_u128},
181 {Sign::POS, -128, 0xad7a02e1'b24efd31'd60864fd'949b4bd3_u128},
182 {Sign::POS, -128, 0xaf741551'20c9011c'066d235e'e63073dd_u128},
183 {Sign::POS, 0, 0_u128},
184 },
185 // -log(r) for the second step, generated by SageMath with:
186 //
187 // for i in range(-2^6, 2^7 + 1):
188 // r = 2^-16 * round( 2^16 / (1 + i*2^(-14)) );
189 // s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
190 // print("{Sign::POS," if s == -1 else "{Sign::NEG,", e, ",
191 // format_hex(m), "},");
192 /* .step_2 = */
193 {
194 {Sign::NEG, -135, 0x803faaca'c419abf2'a1c6f3fc'242ef8d0_u128},
195 {Sign::NEG, -136, 0xfc834da1'6f0d9f57'a225ebc0'2e6d9dd4_u128},
196 {Sign::NEG, -136, 0xf88735cc'c7433381'c33f6ad3'40ae18a9_u128},
197 {Sign::NEG, -136, 0xf48b0e17'1249b6bc'70b2a4d3'8a242244_u128},
198 {Sign::NEG, -136, 0xf08ed67f'd190e280'1d548190'48b811b0_u128},
199 {Sign::NEG, -136, 0xec928f06'86828706'aee59837'01d2a02b_u128},
200 {Sign::NEG, -136, 0xe89637aa'b2828aed'40abb8ab'72afa2d2_u128},
201 {Sign::NEG, -136, 0xe499d06b'd6eeead5'deb547a0'd4a26ef9_u128},
202 {Sign::NEG, -136, 0xe09d5949'751fb909'39c5bdfb'cf6087a0_u128},
203 {Sign::NEG, -136, 0xdca0d243'0e671d18'53ea9bf1'52de635f_u128},
204 {Sign::NEG, -136, 0xd8a43b58'2411537e'25b82043'6f5f4352_u128},
205 {Sign::NEG, -136, 0xd4a79488'3764ad41'3c2d13ea'1d0be058_u128},
206 {Sign::NEG, -136, 0xd0aaddd2'c9a18f95'4f3cfa62'bcb3ce3a_u128},
207 {Sign::NEG, -136, 0xccae1737'5c02737c'd0fff6cd'f14a86c7_u128},
208 {Sign::NEG, -136, 0xc8b140b5'6fbbe56a'7587b5f0'453ac3d2_u128},
209 {Sign::NEG, -136, 0xc4b45a4c'85fc84e2'b358ad16'dfd0d085_u128},
210 {Sign::NEG, -136, 0xc0b763fc'1fed041d'3c86fdce'5dbe7314_u128},
211 {Sign::NEG, -136, 0xbcba5dc3'beb027a6'70764e46'ac18a96d_u128},
212 {Sign::NEG, -136, 0xb8bd47a2'e362c600'c63be62b'8f285882_u128},
213 {Sign::NEG, -136, 0xb3c0d59a'244325a4'72e7b5a3'86e5e31b_u128},
214 {Sign::NEG, -136, 0xafc39bac'66434f27'c3ea2cd9'3f316b34_u128},
215 {Sign::NEG, -136, 0xabc651d4'91a7b438'1dfb11a7'cc892843_u128},
216 {Sign::NEG, -136, 0xa7c8f812'2773f38d'fc679a28'e9d9f212_u128},
217 {Sign::NEG, -136, 0xa3cb8e64'a8a5bbe6'e7bc977e'eec42254_u128},
218 {Sign::NEG, -136, 0x9fce14cb'9634cba6'b20f215b'd3b58c61_u128},
219 {Sign::NEG, -136, 0x9bd08b46'7112f078'abe28625'08d67a98_u128},
220 {Sign::NEG, -136, 0x97d2f1d4'ba2c06f0'd1aacedc'efe9d377_u128},
221 {Sign::NEG, -136, 0x93d54875'f265fa2c'f1eb25e7'7d05f58d_u128},
222 {Sign::NEG, -136, 0x8fd78f29'9aa0c375'cbef6fac'33691e95_u128},
223 {Sign::NEG, -136, 0x8bd9c5ef'33b669e0'27206404'62a0f8ad_u128},
224 {Sign::NEG, -136, 0x87dbecc6'3e7b01ed'e2f17751'34c8da75_u128},
225 {Sign::NEG, -136, 0x83de03ae'3bbcad2e'ff67e201'c8c50d67_u128},
226 {Sign::NEG, -137, 0xffc0154d'588733c5'3c742a7c'76356396_u128},
227 {Sign::NEG, -137, 0xf7c4035e'21a4052f'f90dd6b2'4aa686ec_u128},
228 {Sign::NEG, -137, 0xefc7d18d'd4485b9e'ca47c52b'7d7ffce2_u128},
229 {Sign::NEG, -137, 0xe7cb7fdb'71e0db36'3703617a'd3d8311f_u128},
230 {Sign::NEG, -137, 0xdfcf0e45'fbce3e80'7e4cfbd8'30393b88_u128},
231 {Sign::NEG, -137, 0xd7d27ccc'736555af'4f7a29cf'0fc2c38e_u128},
232 {Sign::NEG, -137, 0xcfd5cb6d'd9ef05dd'7370ae83'f9e72748_u128},
233 {Sign::NEG, -137, 0xc7d8fa29'30a84850'671486eb'4cd76f65_u128},
234 {Sign::NEG, -137, 0xbfdc08fd'78c229b9'e6dbb624'f9739782_u128},
235 {Sign::NEG, -137, 0xb7def7e9'b361c979'6b866e09'e57d9079_u128},
236 {Sign::NEG, -137, 0xafe1c6ec'e1a058dd'97fa2fd0'c9dc723e_u128},
237 {Sign::NEG, -137, 0xa7e47606'048b1a65'983e8089'7cf1e60f_u128},
238 {Sign::NEG, -137, 0x9fe70534'1d236102'7199cd06'ae5d39b3_u128},
239 {Sign::NEG, -137, 0x97e97476'2c5e8f58'43cd18a7'2a051a96_u128},
240 {Sign::NEG, -137, 0x8febc3cb'332616ff'7b6d1248'c3e1fd40_u128},
241 {Sign::NEG, -137, 0x87edf332'325777c5'f5572a88'14c703af_u128},
242 {Sign::NEG, -138, 0xffe00554'55887de0'26828c92'649a3a39_u128},
243 {Sign::NEG, -138, 0xefe3e464'3a640cf3'82c550bd'1216d82a_u128},
244 {Sign::NEG, -138, 0xdfe78392'14b4e8ae'da6959f7'f0e01bf0_u128},
245 {Sign::NEG, -138, 0xcfeae2db'e5d6736d'da93e2fa'85a8f214_u128},
246 {Sign::NEG, -138, 0xbfee023f'af0c2480'b47505bf'a5a03b06_u128},
247 {Sign::NEG, -138, 0xaff0e1bb'718186ad'b1475a51'80a43520_u128},
248 {Sign::NEG, -138, 0x9ff3814d'2e4a36b2'a8740b91'c95df537_u128},
249 {Sign::NEG, -138, 0x8ff5e0f2'e661e1c6'57d895d3'5921b59c_u128},
250 {Sign::NEG, -139, 0xfff00155'35588833'3c56c598'c659c2a3_u128},
251 {Sign::NEG, -139, 0xdff3c0e4'97ea4eb1'2ef8ec33'ed9d782a_u128},
252 {Sign::NEG, -139, 0xbff7008f'f5e0c257'379eba7e'6465ff63_u128},
253 {Sign::NEG, -139, 0x9ff9c053'5073a370'3f972b78'3fcab757_u128},
254 {Sign::NEG, -140, 0xfff80055'51558885'de026e27'1ee0549d_u128},
255 {Sign::NEG, -140, 0xbffb8023'febc0c25'eceb47ea'01f6c632_u128},
256 {Sign::NEG, -141, 0xfffc0015'54d55888'7333c578'57e1ed52_u128},
257 {Sign::NEG, -142, 0xfffe0005'55455588'87dde026'fa704374_u128},
258 {Sign::NEG, 0, 0_u128},
259 {Sign::POS, -141, 0x80010002'aab2aac4'44999abe'2fe2cc65_u128},
260 {Sign::POS, -140, 0x8002000a'aaeaac44'4eef3815'81464ccb_u128},
261 {Sign::POS, -140, 0xc0048024'01440c26'dfeb4850'85f6f454_u128},
262 {Sign::POS, -139, 0x8004002a'acaac445'99abe3be'3a1c6e93_u128},
263 {Sign::POS, -139, 0xa0064053'5a37a37a'6bc1e20e'ac8448b4_u128},
264 {Sign::POS, -139, 0xc0090090'0a20c275'979eedc0'64c242fd_u128},
265 {Sign::POS, -139, 0xe00c40e4'bd6e4efd'c72446cc'1bf728bd_u128},
266 {Sign::POS, -138, 0x800800aa'baac446e'f381b821'bbb569e5_u128},
267 {Sign::POS, -138, 0x900a20f3'19a3e273'569b26aa'a485ea5c_u128},
268 {Sign::POS, -138, 0xa00c814d'7c6a37f8'2dcf56c8'3c80b028_u128},
269 {Sign::POS, -138, 0xb00f21bb'e3e388ee'5f697682'84463b9b_u128},
270 {Sign::POS, -138, 0xc0120240'510c284c'b48ea6c0'5e2773a1_u128},
271 {Sign::POS, -138, 0xd01522dc'c4f87991'14d9d761'96d8043a_u128},
272 {Sign::POS, -138, 0xe0188393'40d4f241'e016a611'a4415d72_u128},
273 {Sign::POS, -138, 0xf01c2465'c5e61b6f'661e135f'49a47c40_u128},
274 {Sign::POS, -137, 0x801002ab'2ac4499a'be6bf0fa'435e8383_u128},
275 {Sign::POS, -137, 0x88121333'7898871e'9a31ba0c'bc030353_u128},
276 {Sign::POS, -137, 0x901443cc'cd362c9f'54b57dfe'0c4c840f_u128},
277 {Sign::POS, -137, 0x98169478'296fad41'7ad1e9c3'15328f7e_u128},
278 {Sign::POS, -137, 0xa0190536'8e2389b3'1f3f686c'f3d6be22_u128},
279 {Sign::POS, -137, 0xa81b9608'fc3c50ec'f105b66e'c4703ede_u128},
280 {Sign::POS, -137, 0xb01e46f0'74b0a0f3'610848c6'8df4d233_u128},
281 {Sign::POS, -137, 0xb82117ed'f8832797'd6aef30c'd312169a_u128},
282 {Sign::POS, -137, 0xc0240902'88c2a339'f3ac3796'08053d9d_u128},
283 {Sign::POS, -137, 0xc8271a2f'2689e388'e6e2acf8'f4d4c24a_u128},
284 {Sign::POS, -137, 0xd02a4b74'd2ffca44'ce6ae474'd860359f_u128},
285 {Sign::POS, -137, 0xd82d9cd4'8f574c00'28bb3cd9'f2a65fb5_u128},
286 {Sign::POS, -137, 0xe0310e4f'5ccf70e1'54f30dbe'f38a8066_u128},
287 {Sign::POS, -137, 0xe8349fe6'3cb35564'224a96f5'a7471c46_u128},
288 {Sign::POS, -137, 0xf038519a'305a2b1b'6ea92059'1aa02e1b_u128},
289 {Sign::POS, -137, 0xf83c236c'39273972'd462b637'56c87e80_u128},
290 {Sign::POS, -136, 0x80200aae'ac44ef38'338f7760'5fe77f2a_u128},
291 {Sign::POS, -136, 0x842213b7'47fec7bb'3ff51287'882500ed_u128},
292 {Sign::POS, -136, 0x88242cd0'7084ed02'cc394b3e'f0ebeb12_u128},
293 {Sign::POS, -136, 0x8c2655fa'a6a1323f'1ab9679b'55f78a6b_u128},
294 {Sign::POS, -136, 0x90288f36'6b237771'7025697d'10af0436_u128},
295 {Sign::POS, -136, 0x942ad884'3ee1a9cd'17e4b7ac'6c600cb4_u128},
296 {Sign::POS, -136, 0x982d31e4'a2b7c418'7013925a'9a8da7f3_u128},
297 {Sign::POS, -136, 0x9c2f9b58'1787cf0d'fd1a09c8'48e3950e_u128},
298 {Sign::POS, -136, 0xa03214df'1e39e1bd'84dd2de6'e3d90a37_u128},
299 {Sign::POS, -136, 0xa4349e7a'37bc21ed'318b2ddd'9d0a33b4_u128},
300 {Sign::POS, -136, 0xa8373829'e502c47a'bc031e6f'5acfd4a8_u128},
301 {Sign::POS, -136, 0xac39e1ee'a7080dbc'9dd91e52'c79fd070_u128},
302 {Sign::POS, -136, 0xb03c9bc8'fecc51e3'4af78fa1'cb48a12d_u128},
303 {Sign::POS, -136, 0xb43f65b9'6d55f55a'72de1d99'ce252efd_u128},
304 {Sign::POS, -136, 0xb74187bc'8ccffa84'efb1dbe7'21934877_u128},
305 {Sign::POS, -136, 0xbb446dd4'd9bca499'b4b080f2'30c87598_u128},
306 {Sign::POS, -136, 0xbf476404'a05f88f2'da6a7cd1'9c7fa4f2_u128},
307 {Sign::POS, -136, 0xc34a6a4c'61d5cc3c'df00e378'3b50ecfb_u128},
308 {Sign::POS, -136, 0xc74d80ac'9f42a52d'da2e5e02'ab4e183c_u128},
309 {Sign::POS, -136, 0xcb50a725'd9cf5ce6'ea5f6ee9'9d30c626_u128},
310 {Sign::POS, -136, 0xcf53ddb8'92ab4f55'a96d5956'531d7d8b_u128},
311 {Sign::POS, -136, 0xd3572465'4b0beb95'a8fc636e'b36afa75_u128},
312 {Sign::POS, -136, 0xd75a7b2c'842cb451'f67e2b82'7bfc4421_u128},
313 {Sign::POS, -136, 0xdb5de20e'bf4f4026'a6d8c817'516303e6_u128},
314 {Sign::POS, -136, 0xdf61590c'7dbb3a02'69b36ae5'962e85f4_u128},
315 {Sign::POS, -136, 0xe364e026'40be6188'24693eec'2a831cc3_u128},
316 {Sign::POS, -136, 0xe768775c'89ac8b70'94a339d5'6a55ab4a_u128},
317 {Sign::POS, -136, 0xeb6c1eaf'd9dfa1eb'fa9998fb'f9703bf4_u128},
318 {Sign::POS, -136, 0xef6fd620'b2b7a503'cafdc272'27b71eaa_u128},
319 {Sign::POS, -136, 0xf3739daf'959aaafc'688d4282'f6026aa3_u128},
320 {Sign::POS, -136, 0xf777755d'03f4e0b6'e54e9e38'04464cdd_u128},
321 {Sign::POS, -136, 0xfb7b5d29'7f388a12'cb78b383'f4b59dce_u128},
322 {Sign::POS, -136, 0xff7f5515'88de024f'ee055fc5'15062c04_u128},
323 {Sign::POS, -135, 0x81c1ae90'd131de38'207812b4'3382acdd_u128},
324 {Sign::POS, -135, 0x83c3baa7'26a721cc'dc90c4c4'b61f3a87_u128},
325 {Sign::POS, -135, 0x85c5cece'05941dbc'1a03f13f'b2c978b1_u128},
326 {Sign::POS, -135, 0x87c7eb05'aec1304f'b36f282e'83a7dc36_u128},
327 {Sign::POS, -135, 0x89ca0f4e'62f9c476'6ad14c3d'fa414391_u128},
328 {Sign::POS, -135, 0x8bcc3ba8'630c51f4'e8dd4ea0'd48b88e5_u128},
329 {Sign::POS, -135, 0x8dce7013'efca5d96'c02515af'e8caeb90_u128},
330 {Sign::POS, -135, 0x8fd0ac91'4a08795f'741ceaf3'349f3cf1_u128},
331 {Sign::POS, -135, 0x91d2f120'b29e44bb'83f7cd49'29d2c28c_u128},
332 {Sign::POS, -135, 0x93d53dc2'6a666cb1'795d03eb'c2fd03fa_u128},
333 {Sign::POS, -135, 0x95d79276'b23eac12'faf74f1d'1ad16acc_u128},
334 {Sign::POS, -135, 0x97d9ef3d'cb07cbad'e2de134f'72fee429_u128},
335 {Sign::POS, -135, 0x99dc5417'f5a5a27d'58d8dba6'cadac5d5_u128},
336 {Sign::POS, -135, 0x9bdec105'72ff15da'f07d90bc'5aae40a4_u128},
337 {Sign::POS, -135, 0x9d609804'6659ea6b'1deaf79d'9fc40374_u128},
338 {Sign::POS, -135, 0x9f631314'50b07988'7ba63e67'69b81999_u128},
339 {Sign::POS, -135, 0xa1659638'404d5f92'59ebfc93'35094e59_u128},
340 {Sign::POS, -135, 0xa3682170'7622f97a'16aae012'b5026f71_u128},
341 {Sign::POS, -135, 0xa56ab4bd'3326b378'ff5d4f2c'0e4b9cae_u128},
342 {Sign::POS, -135, 0xa76d501e'b8510941'855838b5'119dcb28_u128},
343 {Sign::POS, -135, 0xa96ff395'469d8630'75f70cbb'e9cf1603_u128},
344 {Sign::POS, -135, 0xab729f21'1f0ac57e'36a53ad4'd5541cc9_u128},
345 {Sign::POS, -135, 0xad7552c2'829a7270'04c5934e'c32d20d9_u128},
346 {Sign::POS, -135, 0xaf780e79'b2514889'3977e89a'ec59bfa2_u128},
347 {Sign::POS, -135, 0xb17ad246'ef3713bc'913d4e3d'c55c3e6e_u128},
348 {Sign::POS, -135, 0xb37d9e2a'7a56b09d'777b52a9'e70d8bcc_u128},
349 {Sign::POS, -135, 0xb5807224'94be0c91'55de916f'd30591de_u128},
350 {Sign::POS, -135, 0xb7834e35'7f7e2600'e79cfb37'be2861e4_u128},
351 {Sign::POS, -135, 0xb986325d'7bab0c89'90983104'd3805389_u128},
352 {Sign::POS, -135, 0xbb891e9c'ca5be12e'b860504b'aa6f984d_u128},
353 {Sign::POS, -135, 0xbd8c12f3'acaad68b'29178d6f'f5712b96_u128},
354 {Sign::POS, -135, 0xbf8f0f62'63b53102'7236fa47'ba19a198_u128},
355 {Sign::POS, -135, 0xc19213e9'309b46f2'4f34d64c'afcc50e3_u128},
356 {Sign::POS, -135, 0xc3952088'548080e4'120cc62e'b0a8db3e_u128},
357 {Sign::POS, -135, 0xc5983540'108b59be'11aa5084'779060e3_u128},
358 {Sign::POS, -135, 0xc79b5210'a5e55ef5'1c35fd62'36c8dcf1_u128},
359 {Sign::POS, -135, 0xc99e76fa'55bb30bd'ed4576a7'e4b878fe_u128},
360 {Sign::POS, -135, 0xcb20d7fa'3a336081'6caf4bb8'fd2c1131_u128},
361 {Sign::POS, -135, 0xcd240b10'753e78de'3f24a6cb'b09c654f_u128},
362 {Sign::POS, -135, 0xcf274640'7e0ff09f'78bc003b'b81e40f3_u128},
363 {Sign::POS, -135, 0xd12a898a'95dff002'56647301'edfd8e8b_u128},
364 {Sign::POS, -135, 0xd32dd4ee'fde9b2ef'28fe1c4d'04ca4ed9_u128},
365 {Sign::POS, -135, 0xd531286d'f76b892a'e1ea9ea6'cbf57379_u128},
366 {Sign::POS, -135, 0xd7348407'c3a6d688'a3832028'141a5cc2_u128},
367 {Sign::POS, -135, 0xd937e7bc'a3e0131b'557421dd'379d3ead_u128},
368 {Sign::POS, -135, 0xdb3b538c'd95ecb67'3cff8e87'a99bcaf0_u128},
369 {Sign::POS, -135, 0xdd3ec778'a56da093'99255ef3'4bd0801f_u128},
370 {Sign::POS, -135, 0xdf424380'495a489c'42b33220'abfa15cd_u128},
371 {Sign::POS, -135, 0xe145c7a4'06758e83'503b378f'aa97dbc0_u128},
372 {Sign::POS, -135, 0xe34953e4'1e135282'bdf2ca00'6f59b544_u128},
373 {Sign::POS, -135, 0xe54ce840'd18a8a3e'1979190a'f37ed16f_u128},
374 {Sign::POS, -135, 0xe75084ba'623540f4'31863ff7'cf898c9c_u128},
375 {Sign::POS, -135, 0xe9542951'117097b0'c983284f'60293647_u128},
376 {Sign::POS, -135, 0xeb57d605'209cc57e'510a969e'be03f804_u128},
377 {Sign::POS, -135, 0xed5b8ad6'd11d1797'9f53bffc'6d23fe30_u128},
378 {Sign::POS, -135, 0xef5f47c6'6457f199'b286c6e1'13337886_u128},
379 {Sign::POS, -135, 0xf0e21acd'd6e7d412'b6ed8085'2ae6fd63_u128},
380 {Sign::POS, -135, 0xf2e5e5f2'5450c5a2'df437fb0'f616082d_u128},
381 {Sign::POS, -135, 0xf4e9b935'685dbe0b'f237cff1'acb306b3_u128},
382 {Sign::POS, -135, 0xf6ed9497'5480b696'52dbfafb'4121a092_u128},
383 {Sign::POS, -135, 0xf8f17818'5a2ebfd9'0d816482'49cece4c_u128},
384 {Sign::POS, -135, 0xfaf563b8'bae001eb'ad95e6b0'b96903d3_u128},
385 {Sign::POS, -135, 0xfcf95778'b80fbc98'176cd568'87ac7fe9_u128},
386 {Sign::POS, -135, 0xfefd5358'933c478c'65f4c739'7f1f478d_u128},
387 },
388 // -log(r) for the third step, generated by SageMath with:
389 //
390 // for i in range(-80, 81):
391 // r = 2^-21 * round( 2^21 / (1 + i*2^(-21)) );
392 // s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
393 // print("{Sign::POS," if (s == -1) else "{Sign::NEG,", e, ",
394 // format_hex(m), "},");
395 /* .step_3 = */
396 {
397 {Sign::NEG, -142, 0x9fff3801'4d52e45a'374b2940'76d669c3_u128},
398 {Sign::NEG, -142, 0x9dff3cf9'40fad85a'7f6f05dc'dbeb776e_u128},
399 {Sign::NEG, -142, 0x9bff41e1'34f1cb36'3d55e21d'41bbadf9_u128},
400 {Sign::NEG, -142, 0x99ff46b9'2936bcf4'ccdba2d5'4aadbc5c_u128},
401 {Sign::NEG, -142, 0x97ff4b81'1dc8ad9d'71dd16d3'073f79b2_u128},
402 {Sign::NEG, -142, 0x95ff5039'12a69d37'5837f3df'1a58dd48_u128},
403 {Sign::NEG, -142, 0x93ff54e1'07cf8bc9'93cad3bc'dd26fd6d_u128},
404 {Sign::NEG, -142, 0x91ff5978'fd42795b'2075312a'827f14fa_u128},
405 {Sign::NEG, -142, 0x8fff5e00'f2fe65f2'e21764e1'39c98f60_u128},
406 {Sign::NEG, -142, 0x8dff6278'e9025197'a492a295'51751b4c_u128},
407 {Sign::NEG, -142, 0x8bff66e0'df4d3c50'1bc8f5f6'58f1c3a2_u128},
408 {Sign::NEG, -142, 0x89ff6b38'd5de2622'e39d3faf'42340ed7_u128},
409 {Sign::NEG, -142, 0x87ff6f80'ccb40f16'7ff33266'82c02485_u128},
410 {Sign::NEG, -142, 0x85ff73b8'c3cdf731'5caf4fbe'343cf928_u128},
411 {Sign::NEG, -142, 0x83ff77e0'bb2ade79'cdb6e554'348f7fe8_u128},
412 {Sign::NEG, -142, 0x81ff7bf8'b2c9c4f6'0ef009c2'457de25d_u128},
413 {Sign::NEG, -143, 0xffff0001'55535558'8883333c'57b57c74_u128},
414 {Sign::NEG, -143, 0xfbff07f1'45931f44'f32668f3'9c70d183_u128},
415 {Sign::NEG, -143, 0xf7ff0fc1'3650e7bd'459a73c6'a6486fe3_u128},
416 {Sign::NEG, -143, 0xf3ff1771'278aaecd'37b18cca'7dd3a29f_u128},
417 {Sign::NEG, -143, 0xefff1f01'193e7480'513f610d'21bcfc78_u128},
418 {Sign::NEG, -143, 0xebff2671'0b6a38e1'ea190b95'c0690b7b_u128},
419 {Sign::NEG, -143, 0xe7ff2dc0'fe0bfbfd'2a150f64'f0ad1743_u128},
420 {Sign::NEG, -143, 0xe3ff34f0'f121bddd'090b5174'e995e9d1_u128},
421 {Sign::NEG, -143, 0xdfff3c00'e4a97e8c'4ed512b9'b93ea2bf_u128},
422 {Sign::NEG, -143, 0xdbff42f0'd8a13e15'934cea21'7ab794a2_u128},
423 {Sign::NEG, -143, 0xd7ff49c0'cd06fc83'3e4ebe94'8afd2c76_u128},
424 {Sign::NEG, -143, 0xd3ff5070'c1d8b9df'87b7c0f5'bcfee2e1_u128},
425 {Sign::NEG, -143, 0xcfff5700'b7147634'77666622'8cb6371b_u128},
426 {Sign::NEG, -143, 0xcbff5d70'acb8318b'e53a60f3'514db358_u128},
427 {Sign::NEG, -143, 0xc7ff63c0'a2c1ebef'79149c3b'6e57fa86_u128},
428 {Sign::NEG, -143, 0xc3ff69f0'992fa568'aad734c9'8416df2a_u128},
429 {Sign::NEG, -143, 0xbfff7000'8fff5e00'c2657367'9ed28334_u128},
430 {Sign::NEG, -143, 0xbbff75f0'872f15c0'd7a3c6db'6540809f_u128},
431 {Sign::NEG, -143, 0xb7ff7bc0'7ebcccb1'd277bde6'45fb1aad_u128},
432 {Sign::NEG, -143, 0xb3ff8170'76a682dc'6ac80145'a4087793_u128},
433 {Sign::NEG, -143, 0xafff8700'6eea3849'287c4db3'0271e265_u128},
434 {Sign::NEG, -143, 0xabff8c70'6785ed00'637d6de4'2eeb151e_u128},
435 {Sign::NEG, -143, 0xa7ff91c0'6077a10a'43b5348b'6b898a8c_u128},
436 {Sign::NEG, -143, 0xa3ff96f0'59bd546e'c10e7657'978bd7f6_u128},
437 {Sign::NEG, -143, 0x9fff9c00'53550735'a37503f4'57310e59_u128},
438 {Sign::NEG, -143, 0x9bffa0f0'4d3cb966'82d5a40a'3aa022ff_u128},
439 {Sign::NEG, -143, 0x97ffa5c0'47726b08'c71e0d3e'e3df5f4d_u128},
440 {Sign::NEG, -143, 0x93ffaa70'41f41c23'a83ce035'2bdbd79b_u128},
441 {Sign::NEG, -143, 0x8fffaf00'3cbfccbe'2e21a18d'4680e8e4_u128},
442 {Sign::NEG, -143, 0x8bffb370'37d37cdf'30bcb3e4'e5dfbd28_u128},
443 {Sign::NEG, -143, 0x87ffb7c0'332d2c8d'57ff51d7'5c66d64a_u128},
444 {Sign::NEG, -143, 0x83ffbbf0'2ecadbcf'1bdb87fd'be299f43_u128},
445 {Sign::NEG, -144, 0xffff8000'55551555'88885dde'02700703_u128},
446 {Sign::NEG, -144, 0xf7ff87e0'4d94724c'd259ca80'3a0c1870_u128},
447 {Sign::NEG, -144, 0xefff8f80'464fce8f'e5141308'51c7070a_u128},
448 {Sign::NEG, -144, 0xe7ff96e0'3f832a2a'30a16898'f3073a64_u128},
449 {Sign::NEG, -144, 0xdfff9e00'392a8526'c4ed6451'7b2949ce_u128},
450 {Sign::NEG, -144, 0xd7ffa4e0'3341df90'51e4fb4e'32cf6350_u128},
451 {Sign::NEG, -144, 0xcfffab80'2dc53971'277672a8'8350bcce_u128},
452 {Sign::NEG, -144, 0xc7ffb1e0'28b092d3'35915377'2a490f06_u128},
453 {Sign::NEG, -144, 0xbfffb800'23ffebc0'0c265ece'6b481a0e_u128},
454 {Sign::NEG, -144, 0xb7ffbde0'1faf4440'db2781c0'3fa132f6_u128},
455 {Sign::NEG, -144, 0xafffc380'1bba9c5e'7287c95c'845ada33_u128},
456 {Sign::NEG, -144, 0xa7ffc8e0'181df421'423b56b1'263e5a77_u128},
457 {Sign::NEG, -144, 0x9fffce00'14d54b91'5a3752ca'4c076fa3_u128},
458 {Sign::NEG, -144, 0x97ffd2e0'11dca2b6'6a71e2b2'7eb3f573_u128},
459 {Sign::NEG, -144, 0x8fffd780'0f2ff997'c2e21b72'cff39d8f_u128},
460 {Sign::NEG, -144, 0x87ffdbe0'0ccb503c'537ff612'feb7ac9e_u128},
461 {Sign::NEG, -145, 0xffffc000'15554d55'58888733'33c57c18_u128},
462 {Sign::NEG, -145, 0xefffc7c0'1193f9d1'fa514218'42311c42_u128},
463 {Sign::NEG, -145, 0xdfffcf00'0e4aa5fa'2c4ed6de'475b942c_u128},
464 {Sign::NEG, -145, 0xcfffd5c0'0b7151d8'ce77678c'bb6fcb88_u128},
465 {Sign::NEG, -145, 0xbfffdc00'08fffd78'00c26629'a679ed3b_u128},
466 {Sign::NEG, -145, 0xafffe1c0'06eea8e1'23287cb9'd3072728_u128},
467 {Sign::NEG, -145, 0x9fffe700'0535541c'd5a37540'fd057315_u128},
468 {Sign::NEG, -145, 0x8fffebc0'03cbff32'f82e21c1'fce36810_u128},
469 {Sign::NEG, -146, 0xffffe000'05555455'5588887d'dde02702_u128},
470 {Sign::NEG, -146, 0xdfffe780'0392aa14'9ac4ed72'adf5b295_u128},
471 {Sign::NEG, -146, 0xbfffee00'023fffaf'000c2664'8066b482_u128},
472 {Sign::NEG, -146, 0x9ffff380'014d552e'455a3754'b292c077_u128},
473 {Sign::NEG, -147, 0xfffff000'01555535'55588888'33333c58_u128},
474 {Sign::NEG, -147, 0xbffff700'008ffff5'e000c266'5736679f_u128},
475 {Sign::NEG, -148, 0xfffff800'00555551'55558888'85ddde02_u128},
476 {Sign::NEG, -149, 0xfffffc00'00155554'd5555888'88733334_u128},
477 {Sign::POS, 0, 0_u128},
478 {Sign::POS, -148, 0x80000200'000aaaaa'eaaaac44'444eeeef_u128},
479 {Sign::POS, -147, 0x80000400'002aaaac'aaaac444'459999ac_u128},
480 {Sign::POS, -147, 0xc0000900'0090000a'2000c266'7596679f_u128},
481 {Sign::POS, -146, 0x80000800'00aaaaba'aaac4444'6eeef381_u128},
482 {Sign::POS, -146, 0xa0000c80'014d557c'655a3755'f81815cc_u128},
483 {Sign::POS, -146, 0xc0001200'02400051'000c2668'4c66b482_u128},
484 {Sign::POS, -146, 0xe0001880'0392ab40'bac4ed7c'40fb07eb_u128},
485 {Sign::POS, -145, 0x80001000'02aaab2a'aac44449'999abe2c_u128},
486 {Sign::POS, -145, 0x90001440'03cc00cd'082e21d7'9cbb6812_u128},
487 {Sign::POS, -145, 0xa0001900'0535568d'd5a37569'adb01dc3_u128},
488 {Sign::POS, -145, 0xb0001e40'06eeac74'33287d01'e8c9d1d9_u128},
489 {Sign::POS, -145, 0xc0002400'09000288'00c266a3'2679ed48_u128},
490 {Sign::POS, -145, 0xd0002a40'0b7158d1'de776851'22b2764b_u128},
491 {Sign::POS, -145, 0xe0003100'0e4aaf5b'2c4ed810'a8063f03_u128},
492 {Sign::POS, -145, 0xf0003840'1194062e'0a5143e7'be891c8f_u128},
493 {Sign::POS, -144, 0x80002000'0aaaaeaa'ac4444ee'ef3813a1_u128},
494 {Sign::POS, -144, 0x88002420'0ccb5a6e'5b7ff7fe'1339025b_u128},
495 {Sign::POS, -144, 0x90002880'0f300668'42e21e26'caf39e33_u128},
496 {Sign::POS, -144, 0x98002d20'11dcb29e'f271e66f'a5554bc6_u128},
497 {Sign::POS, -144, 0xa0003200'14d55f19'5a3757e0'615cc676_u128},
498 {Sign::POS, -144, 0xa8003720'181e0bde'ca3b5d82'10ca5cab_u128},
499 {Sign::POS, -144, 0xb0003c80'1bbab8f6'f287d25f'3cb032bb_u128},
500 {Sign::POS, -144, 0xb8004220'1faf6669'e3278d84'0be28cdb_u128},
501 {Sign::POS, -144, 0xc0004800'24001440'0c266dfe'6b482076_u128},
502 {Sign::POS, -144, 0xc8004e20'28b0c282'3d9166de'380a6d3d_u128},
503 {Sign::POS, -144, 0xd0005480'2dc57139'a7768b35'6ba61e4b_u128},
504 {Sign::POS, -144, 0xd8005b20'3342206f'd9e51a18'49db73c1_u128},
505 {Sign::POS, -144, 0xe0006200'392ad02e'c4ed8a9d'907eb521_u128},
506 {Sign::POS, -144, 0xe8006920'3f838080'b8a197de'a928acd7_u128},
507 {Sign::POS, -144, 0xf0007080'46503170'65144cf7'dcc72d3b_u128},
508 {Sign::POS, -144, 0xf8007820'4d94e308'da5a1108'890d9f6a_u128},
509 {Sign::POS, -143, 0x80004000'2aaacaaa'c4445999'abe2ce2c_u128},
510 {Sign::POS, -143, 0x84004410'2ecb2431'1fdbbb4f'3bffc832_u128},
511 {Sign::POS, -143, 0x88004840'332d7e1d'97ff8f39'ec91b4ee_u128},
512 {Sign::POS, -143, 0x8c004c90'37d3d876'74bcfcf0'b3f0a95d_u128},
513 {Sign::POS, -143, 0x90005100'3cc03342'2e21f80c'a6813aff_u128},
514 {Sign::POS, -143, 0x94005590'41f48e87'6c3d4629'170ce87f_u128},
515 {Sign::POS, -143, 0x98005a40'4772ea4d'071e84e3'b80a8881_u128},
516 {Sign::POS, -143, 0x9c005f10'4d3d469a'06d62fdc'bdd6bec3_u128},
517 {Sign::POS, -143, 0xa0006400'5355a375'a375a6b7'01dc77c0_u128},
518 {Sign::POS, -143, 0xa4006910'59be00e7'450f3318'26ad6b05_u128},
519 {Sign::POS, -143, 0xa8006e40'60785ef6'83b60ea8'bd0aa459_u128},
520 {Sign::POS, -143, 0xac007390'6786bdab'277e6914'69dd13f5_u128},
521 {Sign::POS, -143, 0xb0007900'6eeb1d0d'287d6e0a'0d1e25eb_u128},
522 {Sign::POS, -143, 0xb4007e90'76a77d24'aec94b3b'e9b060f5_u128},
523 {Sign::POS, -143, 0xb8008440'7ebdddfa'1279365f'ce280cce_u128},
524 {Sign::POS, -143, 0xbc008a10'87303f95'dba5732f'3e83e04a_u128},
525 {Sign::POS, -143, 0xc0009000'9000a200'c2675967'9ed5b754_u128},
526 {Sign::POS, -143, 0xc4009610'99310543'aed95aca'5edb5109_u128},
527 {Sign::POS, -143, 0xc8009c40'a2c36967'b917091d'2687160f_u128},
528 {Sign::POS, -143, 0xcc00a290'acb9ce76'293d1c2a'0378e75d_u128},
529 {Sign::POS, -143, 0xd000a900'b7163478'776977bf'9766f5a7_u128},
530 {Sign::POS, -143, 0xd400af90'c1da9b78'4bbb31b1'4776a18b_u128},
531 {Sign::POS, -143, 0xd800b640'cd09037f'7e5297d7'6c8564ba_u128},
532 {Sign::POS, -143, 0xdc00bd10'd8a36c98'1751360f'8461c447_u128},
533 {Sign::POS, -143, 0xe000c400'e4abd6cc'4ed9dc3c'63f44c41_u128},
534 {Sign::POS, -143, 0xe400cb10'f1244226'8d10a446'6a5894d5_u128},
535 {Sign::POS, -143, 0xe800d240'fe0eaeb1'6a1af81b'b4e6510e_u128},
536 {Sign::POS, -143, 0xec00d991'0b6d1c77'ae1f97b0'542a677a_u128},
537 {Sign::POS, -143, 0xf000e101'19418b84'51469efe'81d014cc_u128},
538 {Sign::POS, -143, 0xf400e891'278dfbe2'7bb98c06'd77a18b4_u128},
539 {Sign::POS, -143, 0xf800f041'36546d9d'85a344d0'868bed17_u128},
540 {Sign::POS, -143, 0xfc00f811'4596e0c0'f7301d69'90e307cc_u128},
541 {Sign::POS, -142, 0x80008000'aaabaaac'4446eef3'8140138f_u128},
542 {Sign::POS, -142, 0x82008408'b2cbe5b8'10f5e432'96105497_u128},
543 {Sign::POS, -142, 0x84008820'bb2d2189'edbd4f83'ef63f730_u128},
544 {Sign::POS, -142, 0x86008c48'c3d05e27'feb654fd'541c638e_u128},
545 {Sign::POS, -142, 0x88009080'ccb69b98'7ffadeb8'882f7674_u128},
546 {Sign::POS, -142, 0x8a0094c8'd5e0d9e1'c5a59fd3'6bd44397_u128},
547 {Sign::POS, -142, 0x8c009920'df50190a'3bd21770'1b27dddb_u128},
548 {Sign::POS, -142, 0x8e009d88'e9055918'669c93b5'0e4a2595_u128},
549 {Sign::POS, -142, 0x9000a200'f3019a12'e22234cd'39f29cd4_u128},
550 {Sign::POS, -142, 0x9200a688'fd45dc00'6280efe8'307d41d9_u128},
551 {Sign::POS, -142, 0x9400ab21'07d31ee7'b3d7923a'436f6fc4_u128},
552 {Sign::POS, -142, 0x9600afc9'12aa62cf'ba45c3fc'a574c5a0_u128},
553 {Sign::POS, -142, 0x9800b481'1dcca7bf'71ec0b6d'8cd413d1_u128},
554 {Sign::POS, -142, 0x9a00b949'293aedbd'eeebcfd0'565c5006_u128},
555 {Sign::POS, -142, 0x9c00be21'34f634d2'5d675c6d'a8c98fc3_u128},
556 {Sign::POS, -142, 0x9e00c309'40ff7d04'0181e393'98a2099a_u128},
557 {Sign::POS, -142, 0xa000c801'4d57c65a'375f8195'cc8b1d29_u128},
558
559 },
560 // -log(r) for the fourth step, generated by SageMath with:
561 //
562 // for i in range(-65, 65):
563 // r = 2^-28 * round( 2^28 / (1 + i*2^(-28)) );
564 // s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
565 // print("{Sign::POS," if (s == -1) else "{Sign::NEG,", e, ",
566 // format_hex(m), "},");
567 /* .step_4 = */
568 {
569 {Sign::NEG, -149, 0x81fffef7'f002cb2b'4cd24d68'ff2f11ae_u128},
570 {Sign::NEG, -150, 0xfffffe00'00055555'45555588'8887ddde_u128},
571 {Sign::NEG, -150, 0xfbfffe0f'e0051653'f0fa101f'52b3971f_u128},
572 {Sign::NEG, -150, 0xf7fffe1f'8004d94a'9c9329d6'59ed3734_u128},
573 {Sign::NEG, -150, 0xf3fffe2e'e0049e31'4821006d'9b58462e_u128},
574 {Sign::NEG, -150, 0xeffffe3e'000464ff'f3a3f025'142f8c21_u128},
575 {Sign::NEG, -150, 0xebfffe4c'e0042dae'9f1c53bc'c1c4b11c_u128},
576 {Sign::NEG, -150, 0xe7fffe5b'8003f835'4a8a8474'a17fdd30_u128},
577 {Sign::NEG, -150, 0xe3fffe69'e003c48b'f5eeda0c'b0df586d_u128},
578 {Sign::NEG, -150, 0xdffffe78'000392aa'a149aac4'ed772adf_u128},
579 {Sign::NEG, -150, 0xdbfffe85'e0036289'4c9b4b5d'54f0bc96_u128},
580 {Sign::NEG, -150, 0xd7fffe93'8003341f'f7e40f15'e50a759f_u128},
581 {Sign::NEG, -150, 0xd3fffea0'e0030766'a32447ae'9b975e05_u128},
582 {Sign::NEG, -150, 0xcffffeae'0002dc55'4e5c4567'767ebdd5_u128},
583 {Sign::NEG, -150, 0xcbfffeba'e002b2e3'f98c5700'73bbbd19_u128},
584 {Sign::NEG, -150, 0xc7fffec7'80028b0a'a4b4c9b9'915d03dd_u128},
585 {Sign::NEG, -150, 0xc3fffed3'e00264c1'4fd5e952'cd845a28_u128},
586 {Sign::NEG, -150, 0xbffffee0'00023fff'faf0000c'26664806_u128},
587 {Sign::NEG, -150, 0xbbfffeeb'e0021cbe'a60356a5'9a49b57f_u128},
588 {Sign::NEG, -150, 0xb7fffef7'8001faf5'5110345f'27878a9b_u128},
589 {Sign::NEG, -150, 0xb3ffff02'e001da9b'fc16def8'cc8a4f61_u128},
590 {Sign::NEG, -150, 0xafffff0e'0001bbaa'a7179ab2'87cdcbd8_u128},
591 {Sign::NEG, -150, 0xabffff18'e0019e19'5212aa4c'57dea809_u128},
592 {Sign::NEG, -150, 0xa7ffff23'800181df'fd084f06'3b5a0bf8_u128},
593 {Sign::NEG, -150, 0xa3ffff2d'e00166f6'a7f8c8a0'30ed3fab_u128},
594 {Sign::NEG, -150, 0x9fffff38'00014d55'52e4555a'37554b29_u128},
595 {Sign::NEG, -150, 0x9bffff41'e00134f3'fdcb31f4'4d5e9676_u128},
596 {Sign::NEG, -150, 0x97ffff4b'80011dca'a8ad99ae'71e48997_u128},
597 {Sign::NEG, -150, 0x93ffff54'e00107d1'538bc648'a3d12c90_u128},
598 {Sign::NEG, -150, 0x8fffff5e'0000f2ff'fe65f002'e21cc765_u128},
599 {Sign::NEG, -150, 0x8bffff66'e000df4e'a93c4d9d'2bcd821a_u128},
600 {Sign::NEG, -150, 0x87ffff6f'8000ccb5'540f1457'7ff704b2_u128},
601 {Sign::NEG, -150, 0x83ffff77'e000bb2b'fede77f1'ddba1731_u128},
602 {Sign::NEG, -151, 0xffffff00'00015555'53555558'88888333_u128},
603 {Sign::NEG, -151, 0xf7ffff0f'c0013652'a8e7ba8d'659ed7dc_u128},
604 {Sign::NEG, -151, 0xefffff1f'0001193f'fe747e02'5142fc61_u128},
605 {Sign::NEG, -151, 0xe7ffff2d'c000fe0d'53fbfb37'4a1800c7_u128},
606 {Sign::NEG, -151, 0xdfffff3c'0000e4aa'a97e8aac'4ed77513_u128},
607 {Sign::NEG, -151, 0xd7ffff49'c000cd07'fefc81e1'5e50a947_u128},
608 {Sign::NEG, -151, 0xcfffff57'0000b715'54763356'7767ed66_u128},
609 {Sign::NEG, -151, 0xc7ffff63'c000a2c2'a9ebee8b'9915d174_u128},
610 {Sign::NEG, -151, 0xbfffff70'00008fff'ff5e0000'c2666573_u128},
611 {Sign::NEG, -151, 0xb7ffff7b'c0007ebd'54ccb135'f2787966_u128},
612 {Sign::NEG, -151, 0xafffff87'00006eea'aa3848ab'287cdd4e_u128},
613 {Sign::NEG, -151, 0xa7ffff91'c0006077'ffa109e0'63b5a12d_u128},
614 {Sign::NEG, -151, 0x9fffff9c'00005355'55073555'a3755504_u128},
615 {Sign::NEG, -151, 0x97ffffa5'c0004772'aa6b088a'e71e48d5_u128},
616 {Sign::NEG, -151, 0x8fffffaf'00003cbf'ffccbe00'2e21cca2_u128},
617 {Sign::NEG, -151, 0x87ffffb7'c000332d'552c8d35'77ff706a_u128},
618 {Sign::NEG, -152, 0xffffff80'00005555'55155555'8888885e_u128},
619 {Sign::NEG, -152, 0xefffff8f'8000464f'ffce8fc0'25142fe3_u128},
620 {Sign::NEG, -152, 0xdfffff9e'0000392a'aa8526aa'c4ed7764_u128},
621 {Sign::NEG, -152, 0xcfffffab'80002dc5'55397115'67767ee3_u128},
622 {Sign::NEG, -152, 0xbfffffb8'000023ff'ffebc000'0c26665f_u128},
623 {Sign::NEG, -152, 0xafffffc3'80001bba'aa9c5e6a'b287cdd9_u128},
624 {Sign::NEG, -152, 0x9fffffce'000014d5'554b9155'5a375553_u128},
625 {Sign::NEG, -152, 0x8fffffd7'80000f2f'fff997c0'02e21ccb_u128},
626 {Sign::NEG, -153, 0xffffffc0'00001555'554d5555'58888887_u128},
627 {Sign::NEG, -153, 0xdfffffcf'00000e4a'aaa5fa2a'ac4ed777_u128},
628 {Sign::NEG, -153, 0xbfffffdc'000008ff'fffd7800'00c26666_u128},
629 {Sign::NEG, -153, 0x9fffffe7'00000535'55541cd5'55a37555_u128},
630 {Sign::NEG, -154, 0xffffffe0'00000555'55545555'55888888_u128},
631 {Sign::NEG, -154, 0xbfffffee'0000023f'ffffaf00'000c2666_u128},
632 {Sign::NEG, -155, 0xfffffff0'00000155'55553555'55588889_u128},
633 {Sign::NEG, -156, 0xfffffff8'00000055'55555155'55558889_u128},
634 {Sign::POS, 0, 0_u128},
635 {Sign::POS, -155, 0x80000004'0000002a'aaaaacaa'aaaac444_u128},
636 {Sign::POS, -154, 0x80000008'000000aa'aaaabaaa'aaac4444_u128},
637 {Sign::POS, -154, 0xc0000012'00000240'00005100'000c2666_u128},
638 {Sign::POS, -153, 0x80000010'000002aa'aaab2aaa'aac44444_u128},
639 {Sign::POS, -153, 0xa0000019'00000535'55568dd5'55a37555_u128},
640 {Sign::POS, -153, 0xc0000024'00000900'00028800'00c26667_u128},
641 {Sign::POS, -153, 0xe0000031'00000e4a'aaaf5b2a'ac4ed778_u128},
642 {Sign::POS, -152, 0x80000020'00000aaa'aaaeaaaa'ac444445_u128},
643 {Sign::POS, -152, 0x90000028'80000f30'00066840'02e21cce_u128},
644 {Sign::POS, -152, 0xa0000032'000014d5'555f1955'5a375558_u128},
645 {Sign::POS, -152, 0xb000003c'80001bba'aab8f6ea'b287cde2_u128},
646 {Sign::POS, -152, 0xc0000048'00002400'00144000'0c26666e_u128},
647 {Sign::POS, -152, 0xd0000054'80002dc5'55713995'67767efb_u128},
648 {Sign::POS, -152, 0xe0000062'0000392a'aad02eaa'c4ed778b_u128},
649 {Sign::POS, -152, 0xf0000070'80004650'00317040'2514301d_u128},
650 {Sign::POS, -151, 0x80000040'00002aaa'aacaaaaa'c444445a_u128},
651 {Sign::POS, -151, 0x88000048'4000332d'557e1d75'77ff70a7_u128},
652 {Sign::POS, -151, 0x90000051'00003cc0'00334200'2e21ccf8_u128},
653 {Sign::POS, -151, 0x9800005a'40004772'aaea4cca'e71e494d_u128},
654 {Sign::POS, -151, 0xa0000064'00005355'55a37555'a37555a7_u128},
655 {Sign::POS, -151, 0xa800006e'40006078'005ef620'63b5a207_u128},
656 {Sign::POS, -151, 0xb0000079'00006eea'ab1d0cab'287cde6e_u128},
657 {Sign::POS, -151, 0xb8000084'40007ebd'55ddf975'f2787ade_u128},
658 {Sign::POS, -151, 0xc0000090'00009000'00a20000'c2666759_u128},
659 {Sign::POS, -151, 0xc800009c'4000a2c2'ab6966cb'9915d3e1_u128},
660 {Sign::POS, -151, 0xd00000a9'0000b715'56347756'7767f078_u128},
661 {Sign::POS, -151, 0xd80000b6'4000cd08'01037e21'5e50ad20_u128},
662 {Sign::POS, -151, 0xe00000c4'0000e4aa'abd6caac'4ed779dc_u128},
663 {Sign::POS, -151, 0xe80000d2'4000fe0d'56aeaf77'4a1806b0_u128},
664 {Sign::POS, -151, 0xf00000e1'00011940'018b8202'5143039f_u128},
665 {Sign::POS, -151, 0xf80000f0'40013652'ac6d9acd'659ee0ad_u128},
666 {Sign::POS, -150, 0x80000080'0000aaaa'abaaaaac'444446ef_u128},
667 {Sign::POS, -150, 0x84000088'2000bb2c'01218811'ddba1d9b_u128},
668 {Sign::POS, -150, 0x88000090'8000ccb5'569b9657'7ff70c5f_u128},
669 {Sign::POS, -150, 0x8c000099'2000df4e'ac1907bd'2bcd8b3b_u128},
670 {Sign::POS, -150, 0x900000a2'0000f300'019a1002'e21cd235_u128},
671 {Sign::POS, -150, 0x940000ab'200107d1'571ee468'a3d1394e_u128},
672 {Sign::POS, -150, 0x980000b4'80011dca'aca7bbae'71e4988b_u128},
673 {Sign::POS, -150, 0x9c0000be'200134f4'0234ce14'4d5ea7f0_u128},
674 {Sign::POS, -150, 0xa00000c8'00014d55'57c6555a'37555f82_u128},
675 {Sign::POS, -150, 0xa40000d2'200166f6'ad5c8cc0'30ed5744_u128},
676 {Sign::POS, -150, 0xa80000dc'800181e0'02f7b106'3b5a273b_u128},
677 {Sign::POS, -150, 0xac0000e7'20019e19'5898006c'57dec76f_u128},
678 {Sign::POS, -150, 0xb00000f2'0001bbaa'ae3dbab2'87cdefe3_u128},
679 {Sign::POS, -150, 0xb40000fd'2001da9c'03e92118'cc8a789f_u128},
680 {Sign::POS, -150, 0xb8000108'8001faf5'599a765f'2787b9aa_u128},
681 {Sign::POS, -150, 0xbc000114'20021cbe'af51fec5'9a49eb0a_u128},
682 {Sign::POS, -150, 0xc0000120'00024000'0510000c'266684c6_u128},
683 {Sign::POS, -150, 0xc400012c'200264c1'5ad4c172'cd849ee9_u128},
684 {Sign::POS, -150, 0xc8000138'80028b0a'b0a08bb9'915d5179_u128},
685 {Sign::POS, -150, 0xcc000145'2002b2e4'0673a920'73bc1480_u128},
686 {Sign::POS, -150, 0xd0000152'0002dc55'5c4e6567'767f2009_u128},
687 {Sign::POS, -150, 0xd400015f'20030766'b2310dce'9b97cc1d_u128},
688 {Sign::POS, -150, 0xd800016c'80033420'081bf115'e50af0c7_u128},
689 {Sign::POS, -150, 0xdc00017a'20036289'5e0f5f7d'54f14614_u128},
690 {Sign::POS, -150, 0xe0000188'000392aa'b40baac4'ed77c410_u128},
691 {Sign::POS, -150, 0xe4000196'2003c48c'0a11262c'b0e002c7_u128},
692 {Sign::POS, -150, 0xe80001a4'8003f835'60202674'a1809a47_u128},
693 {Sign::POS, -150, 0xec0001b3'20042dae'b63901dc'c1c582a0_u128},
694 {Sign::POS, -150, 0xf00001c2'00046500'0c5c1025'143073df_u128},
695 {Sign::POS, -150, 0xf40001d1'20049e31'6289aa8d'9b594616_u128},
696 {Sign::POS, -150, 0xf80001e0'8004d94a'b8c22bd6'59ee5155_u128},
697 {Sign::POS, -150, 0xfc0001f0'20051654'0f05f03f'52b4cdae_u128},
698 {Sign::POS, -149, 0x80000100'0002aaaa'b2aaaac4'4444999a_u128},
699
700 }};
701// > P = fpminimax((log(1 + x) - x)/x^2, 2, [|1, 128...|],
702// [-0x1.0002143p-29 , 0x1p-29]);
703// > P;
704// > dirtyinfnorm(log(1 + x)/x - x*P, [-0x1.0002143p-29 , 0x1p-29]);
705// 0x1.99a3...p-121
706constexpr Float128 BIG_COEFFS[3]{
707 {Sign::NEG, -129, 0x80000000'0006a710'b59c58e5'554d581c_u128},
708 {Sign::POS, -129, 0xaaaaaaaa'aaaaaabd'de05c7c9'4ae9cbae_u128},
709 {Sign::NEG, -128, 0x80000000'00000000'00000000'00000000_u128},
710};
711
712// Reuse the output of the fast pass range reduction.
713// -2^-8 <= m_x < 2^-7
714double log_accurate(int e_x, int index, double m_x) {
715
716 Float128 e_x_f128(static_cast<float>(e_x));
717 Float128 sum = fputil::quick_mul(a: LOG_2, b: e_x_f128);
718 sum = fputil::quick_add(a: sum, b: LOG_TABLE.step_1[index]);
719
720 Float128 v_f128 = log_range_reduction(m_x, log_table: LOG_TABLE, sum);
721 sum = fputil::quick_add(a: sum, b: v_f128);
722
723 // Polynomial approximation
724 Float128 p = fputil::quick_mul(a: v_f128, b: BIG_COEFFS[0]);
725 p = fputil::quick_mul(a: v_f128, b: fputil::quick_add(a: p, b: BIG_COEFFS[1]));
726 p = fputil::quick_mul(a: v_f128, b: fputil::quick_add(a: p, b: BIG_COEFFS[2]));
727 p = fputil::quick_mul(a: v_f128, b: p);
728
729 Float128 r = fputil::quick_add(a: sum, b: p);
730
731 return static_cast<double>(r);
732}
733
734} // namespace
735
736LLVM_LIBC_FUNCTION(double, log, (double x)) {
737 using FPBits_t = typename fputil::FPBits<double>;
738
739 FPBits_t xbits(x);
740 uint64_t x_u = xbits.uintval();
741
742 int x_e = -FPBits_t::EXP_BIAS;
743
744 if (LIBC_UNLIKELY(xbits == FPBits_t::one())) {
745 // log(1.0) = +0.0
746 return 0.0;
747 }
748
749 if (LIBC_UNLIKELY(xbits.uintval() < FPBits_t::min_normal().uintval() ||
750 xbits.uintval() > FPBits_t::max_normal().uintval())) {
751 if (xbits.is_zero()) {
752 // return -Inf and raise FE_DIVBYZERO.
753 fputil::set_errno_if_required(ERANGE);
754 fputil::raise_except_if_required(FE_DIVBYZERO);
755 return FPBits_t::inf(sign: Sign::NEG).get_val();
756 }
757 if (xbits.is_neg() && !xbits.is_nan()) {
758 fputil::set_errno_if_required(EDOM);
759 fputil::raise_except_if_required(FE_INVALID);
760 return FPBits_t::quiet_nan().get_val();
761 }
762 if (xbits.is_inf_or_nan()) {
763 return x;
764 }
765 // Normalize denormal inputs.
766 xbits = FPBits_t(x * 0x1.0p52);
767 x_e -= 52;
768 x_u = xbits.uintval();
769 }
770
771 // log(x) = log(2^x_e * x_m)
772 // = x_e * log(2) + log(x_m)
773
774 // Range reduction for log(x_m):
775 // For each x_m, we would like to find r such that:
776 // -2^-8 <= r * x_m - 1 < 2^-7
777 int shifted = static_cast<int>(x_u >> 45);
778 int index = shifted & 0x7F;
779 double r = RD[index];
780
781 // Add unbiased exponent. Add an extra 1 if the 8 leading fractional bits are
782 // all 1's.
783 x_e += static_cast<int>((x_u + (1ULL << 45)) >> 52);
784 double e_x = static_cast<double>(x_e);
785
786 // hi is exact
787 double hi = fputil::multiply_add(x: e_x, y: LOG_2_HI, z: LOG_R_DD[index].hi);
788 // lo errors ~ e_x * LSB(LOG_2_LO) + LSB(LOG_R[index].lo) + rounding err
789 // <= 2 * (e_x * LSB(LOG_2_LO) + LSB(LOG_R[index].lo))
790 double lo = fputil::multiply_add(x: e_x, y: LOG_2_LO, z: LOG_R_DD[index].lo);
791
792 // Set m = 1.mantissa.
793 uint64_t x_m = (x_u & 0x000F'FFFF'FFFF'FFFFULL) | 0x3FF0'0000'0000'0000ULL;
794 double m = FPBits_t(x_m).get_val();
795
796 double u, u_sq, err;
797 fputil::DoubleDouble r1;
798
799 // Perform exact range reduction
800#ifdef LIBC_TARGET_CPU_HAS_FMA
801 u = fputil::multiply_add(x: r, y: m, z: -1.0); // exact
802#else
803 uint64_t c_m = x_m & 0x3FFF'E000'0000'0000ULL;
804 double c = FPBits_t(c_m).get_val();
805 u = fputil::multiply_add(r, m - c, CD[index]); // exact
806#endif // LIBC_TARGET_CPU_HAS_FMA
807
808 // Exact sum:
809 // r1.hi + r1.lo = e_x * log(2)_hi - log(r)_hi + u
810 r1 = fputil::exact_add(a: hi, b: u);
811
812 // Error of u_sq = ulp(u^2);
813 u_sq = u * u;
814 // Total error is bounded by ~ C * ulp(u^2).
815 // Degree-7 minimax polynomial
816 double p0 = fputil::multiply_add(x: u, y: LOG_COEFFS[1], z: LOG_COEFFS[0]);
817 double p1 = fputil::multiply_add(x: u, y: LOG_COEFFS[3], z: LOG_COEFFS[2]);
818 double p2 = fputil::multiply_add(x: u, y: LOG_COEFFS[5], z: LOG_COEFFS[4]);
819 double p = fputil::polyeval(x: u_sq, a0: lo + r1.lo, a: p0, a: p1, a: p2);
820
821 // Technicallly error of r1.lo is bounded by:
822 // hi*ulp(log(2)_lo) + C*ulp(u^2)
823 // To simplify the error computation a bit, we replace |hi|*ulp(log(2)_lo)
824 // with the upper bound: 2^11 * ulp(log(2)_lo) = 2^-85.
825 // Total error is bounded by ~ C * ulp(u^2) + 2^-85.
826 err = fputil::multiply_add(x: u_sq, y: P_ERR, z: HI_ERR);
827
828 // Lower bound from the result
829 double left = r1.hi + (p - err);
830 // Upper bound from the result
831 double right = r1.hi + (p + err);
832
833 // Ziv's test if fast pass is accurate enough.
834 if (left == right)
835 return left;
836
837 return log_accurate(e_x: x_e, index, m_x: u);
838}
839
840} // namespace LIBC_NAMESPACE
841

source code of libc/src/math/generic/log.cpp