| ... | @@ -163,9 +163,241 @@ pub fn __log2x(a: f80) callconv(.c) f80 { | ... | @@ -163,9 +163,241 @@ pub fn __log2x(a: f80) callconv(.c) f80 { |
| 163 | return @floatCast(log2q(a)); | 163 | return @floatCast(log2q(a)); |
| 164 | } | 164 | } |
| 165 | | 165 | |
| 166 | pub fn log2q(a: f128) callconv(.c) f128 { | 166 | /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" |
| 167 | // TODO: more correct implementation | 167 | /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 |
| 168 | return log2(@floatCast(a)); | 168 | /// |
| | 169 | /// https://dl.acm.org/doi/pdf/10.1145/98267.98294 |
| | 170 | /// |
| | 171 | /// Adapted to work for f128 and base 2 by Christophe Delage. |
| | 172 | /// |
| | 173 | /// Accuracy on 100 million random numbers in [0, inf) (exponent uniformly random) |
| | 174 | /// <= 0.5 ulp: 99.99%, worst case <= 0.594 ulp |
| | 175 | /// |
| | 176 | /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): |
| | 177 | /// <= 0.5 ulp: 99.79%, worst case <= 0.605 ulp |
| | 178 | pub fn log2q(x: f128) callconv(.c) f128 { |
| | 179 | const bitsize = 7; |
| | 180 | const size = 1 << bitsize; |
| | 181 | if (!math.isFinite(x)) { |
| | 182 | if (math.isNan(x)) { |
| | 183 | if (math.isSignalNan(x)) math.raiseInvalid(); |
| | 184 | return math.nan(f128); |
| | 185 | } |
| | 186 | if (math.isPositiveInf(x)) return x; |
| | 187 | } |
| | 188 | if (x <= 0.0) { |
| | 189 | if (x >= 0.0) { |
| | 190 | math.raiseDivByZero(); |
| | 191 | return -math.inf(f128); |
| | 192 | } |
| | 193 | math.raiseInvalid(); |
| | 194 | return math.nan(f128); |
| | 195 | } |
| | 196 | |
| | 197 | // exp(-1 / 16) rounded down |
| | 198 | const proc2_lo: f128 = 0.939413062813475786119710824622305; |
| | 199 | // exp(1 / 16) rounded up |
| | 200 | const proc2_hi: f128 = 1.0644944589178594295633905946428897; |
| | 201 | if (proc2_lo < x and x < proc2_hi) { |
| | 202 | const f = x - 1.0; |
| | 203 | const g = 1 / (2 + f); |
| | 204 | const u = 2 * f * g; |
| | 205 | const v = u * u; |
| | 206 | const uv = u * v; |
| | 207 | |
| | 208 | const v64: f64 = @floatCast(v); |
| | 209 | // use f64 for the last few coefficients to improve performance |
| | 210 | const p19 = 2.909291439731657940692470637735429e-7; |
| | 211 | const p17 = 1.294917697032820750200161813672143e-6 + v64 * p19; |
| | 212 | const p15 = 5.870341197214724685339102193694838e-6 + v64 * p17; |
| | 213 | const p13 = 2.7093882228102330360125035037716968e-5 + v * p15; |
| | 214 | const p11 = 1.280801705334664325639770412440281e-4 + v * p13; |
| | 215 | const p9 = 6.261697226080570342191671010883619e-4 + v * p11; |
| | 216 | const p7 = 3.2203014305557218914285331735164364e-3 + v * p9; |
| | 217 | const p5 = 1.8033688011112042591999058475816515e-2 + v * p7; |
| | 218 | |
| | 219 | const q_hi = uv * 0.12022458674074695061332705675016125; |
| | 220 | const q_lo = uv * v * p5; |
| | 221 | |
| | 222 | const f_hi: f128 = @as(f64, @floatCast(f)); |
| | 223 | const f_lo: f128 = f - f_hi; |
| | 224 | |
| | 225 | const u_hi: f128 = @as(f64, @floatCast(u)); |
| | 226 | const u_lo: f128 = ((2 * (f - u_hi) - u_hi * f_hi) - u_hi * f_lo) * g; |
| | 227 | |
| | 228 | // t = u / ln(2) |
| | 229 | const log2e_hi: f128 = 0x1.71547652b82fep0; |
| | 230 | const log2e_lo: f128 = 0x1.777d0ffda0d23a7d11d6aef551bbp-56; |
| | 231 | const t_hi = u_hi * log2e_hi; |
| | 232 | const t_lo = u_lo * log2e_hi + u * log2e_lo; |
| | 233 | |
| | 234 | // y = t + q |
| | 235 | const y_hi = t_hi + q_hi; |
| | 236 | const y_lo = t_lo + (t_hi - y_hi + q_hi) + q_lo; |
| | 237 | |
| | 238 | return y_hi + y_lo; |
| | 239 | } |
| | 240 | |
| | 241 | const ym = @import("log.zig").frexp2(x); |
| | 242 | const y = ym.significand; |
| | 243 | const m = ym.exponent; |
| | 244 | |
| | 245 | const F0 = @round(math.ldexp(y, bitsize)); |
| | 246 | const j0: usize = @intFromFloat(F0); |
| | 247 | const j = j0 - size; |
| | 248 | const F = math.ldexp(F0, -bitsize); |
| | 249 | const f = y - F; |
| | 250 | |
| | 251 | const u = (f + f) / (y + F); |
| | 252 | const v = u * u; |
| | 253 | |
| | 254 | const v64: f64 = @floatCast(v); |
| | 255 | // use f64 for the last coefficient to improve performance |
| | 256 | const p11 = 1.280813940786848788109850061222256e-4; |
| | 257 | const p9 = 6.261697225875019234719395591078697e-4 + v64 * p11; |
| | 258 | const p7 = 3.22030143055572204818095463930704e-3 + v * p9; |
| | 259 | const p5 = 1.8033688011112042591998536830294507e-2 + v * p7; |
| | 260 | const p3 = 0.12022458674074695061332705675072149 + v * p5; |
| | 261 | const p1 = 1.442695040888963407359924681001892; |
| | 262 | |
| | 263 | const q = u * v * p3; |
| | 264 | |
| | 265 | const log1p_tab = [size + 1]struct { hi: f128, lo: f128 }{ |
| | 266 | .{ .hi = 0, .lo = 0 }, |
| | 267 | .{ .hi = 0x1.6fe50b6ef08517f8e37bp-7, .lo = 0x1.794f4441ccdf648f265a41e57d75p-99 }, |
| | 268 | .{ .hi = 0x1.6e79685c2d2298a6e27e212p-6, .lo = -0x1.fbd41ae7d5a2434912ad3fe21cfbp-100 }, |
| | 269 | .{ .hi = 0x1.11cd1d5133412ed814504fbp-5, .lo = -0x1.b2e2b43254008aeb4167a3359577p-99 }, |
| | 270 | .{ .hi = 0x1.6bad3758efd87313606f097p-5, .lo = -0x1.20fbdb7ce4c86d28e4be331fce17p-99 }, |
| | 271 | .{ .hi = 0x1.c4dfab90aab5ef4f8f869e6p-5, .lo = 0x1.dc4142bd2b182fdaac375356fc29p-100 }, |
| | 272 | .{ .hi = 0x1.0eb389fa29f9ab3cf74bab98p-4, .lo = 0x1.9217066b9150f3c7ddd223517be7p-100 }, |
| | 273 | .{ .hi = 0x1.3aa2fdd27f1c2d804d1121b8p-4, .lo = -0x1.acec4ac95b97a0e1d121d0222ba5p-99 }, |
| | 274 | .{ .hi = 0x1.663f6fac913167ccc5382618p-4, .lo = -0x1.dd4529e1ad7c182a716c033db6dep-99 }, |
| | 275 | .{ .hi = 0x1.918a16e46335aae7232494d8p-4, .lo = 0x1.9d1d19046b227370f7cb86bd9e3ep-99 }, |
| | 276 | .{ .hi = 0x1.bc84240adabba63b2c5a6e5p-4, .lo = 0x1.97ab879641c50810e3b820ca9aap-100 }, |
| | 277 | .{ .hi = 0x1.e72ec117fa5b21cbdb5d9dcp-4, .lo = 0x1.4f902752a1dc5b384b68c4f1e669p-99 }, |
| | 278 | .{ .hi = 0x1.08c588cda79e39627bc6fd0cp-3, .lo = -0x1.aad7542b0c4015f8fdff17d7ea79p-99 }, |
| | 279 | .{ .hi = 0x1.1dcd197552b7b5ea45430784p-3, .lo = -0x1.a7aa295e08add52f96d8aaf3b8edp-101 }, |
| | 280 | .{ .hi = 0x1.32ae9e278ae1a1f51f2c075cp-3, .lo = -0x1.8b459b26ac0ed3b39116e44d50c8p-99 }, |
| | 281 | .{ .hi = 0x1.476a9f983f74d3138e941644p-3, .lo = -0x1.27d822a49870762eeaffdcde52bdp-104 }, |
| | 282 | .{ .hi = 0x1.5c01a39fbd6879fa00b120ap-3, .lo = 0x1.a2eb74493cf9a8e8966c101ef964p-101 }, |
| | 283 | .{ .hi = 0x1.70742d4ef027f29c01cfad78p-3, .lo = -0x1.8495d6ca3b2dcc7941a5df4c8decp-103 }, |
| | 284 | .{ .hi = 0x1.84c2bd02f03b2fdd2248ee78p-3, .lo = -0x1.c56a8f0829344b50240232cdb09ep-99 }, |
| | 285 | .{ .hi = 0x1.98edd077e70df02face8ca9p-3, .lo = 0x1.72b7f2fcb409899d29e3feaf9c8fp-99 }, |
| | 286 | .{ .hi = 0x1.acf5e2db4ec93efe11ecbcp-3, .lo = 0x1.83634b52082beea143f1178aaf62p-99 }, |
| | 287 | .{ .hi = 0x1.c0db6cdd94dee40e26d9899cp-3, .lo = 0x1.fde86bd82482b9b4a45aa674cc1bp-100 }, |
| | 288 | .{ .hi = 0x1.d49ee4c32596fc8f4b565024p-3, .lo = -0x1.7eaef901f52d2d54011ca95ecca1p-101 }, |
| | 289 | .{ .hi = 0x1.e840be74e6a4cc7c9f3d51ep-3, .lo = -0x1.03c7c0d8554c2c17f944fa1f93cfp-99 }, |
| | 290 | .{ .hi = 0x1.fbc16b902680a23a8d998a78p-3, .lo = 0x1.3bcd7c933d5bb6b52a41ad567d8ep-101 }, |
| | 291 | .{ .hi = 0x1.0790adbb030096f031a699d6p-2, .lo = -0x1.748a4ccf5e3dadf04bd0ff35f885p-99 }, |
| | 292 | .{ .hi = 0x1.11307dad30b75cb09705a796p-2, .lo = -0x1.6c580f988c64f00bd800ed9b9d24p-100 }, |
| | 293 | .{ .hi = 0x1.1ac05b291f070528c7386df8p-2, .lo = 0x1.94340c3b639a4e5a59fded67fcb7p-99 }, |
| | 294 | .{ .hi = 0x1.24407ab0e07398245b94ba44p-2, .lo = 0x1.8077f77a0f4353b19301384099dap-99 }, |
| | 295 | .{ .hi = 0x1.2db10fc4d9aaf6f137a3d8c6p-2, .lo = 0x1.e79b8ee38b380b8be44e090558d7p-99 }, |
| | 296 | .{ .hi = 0x1.37124cea4cdecd991336c96p-2, .lo = 0x1.fb9186e41376f4612d4b0b9a507dp-100 }, |
| | 297 | .{ .hi = 0x1.406463b1b044975b2f344252p-2, .lo = 0x1.9a92f79c803c5151cb25af73b143p-101 }, |
| | 298 | .{ .hi = 0x1.49a784bcd1b8afe492bf6ff4p-2, .lo = 0x1.b5fb699b2d8abfc6f675a9d236d6p-99 }, |
| | 299 | .{ .hi = 0x1.52dbdfc4c96b37dcf60e61fcp-2, .lo = 0x1.36a5977bbf78792b6a99ccb74cd5p-99 }, |
| | 300 | .{ .hi = 0x1.5c01a39fbd6879fa00b120ap-2, .lo = 0x1.a2eb74493cf9a8e8966c101ef964p-100 }, |
| | 301 | .{ .hi = 0x1.6518fe4677ba6e52278edc8ap-2, .lo = -0x1.6778b4ba074a8ce60972502c7262p-102 }, |
| | 302 | .{ .hi = 0x1.6e221cd9d0cde578d520b45p-2, .lo = -0x1.1f87779b03b7d7e6bd0493f2e147p-99 }, |
| | 303 | .{ .hi = 0x1.771d2ba7efb3be46fecd5122p-2, .lo = 0x1.29ff1c3c9184a53c236eed64d17ep-100 }, |
| | 304 | .{ .hi = 0x1.800a563161c5432aeb609f4ep-2, .lo = -0x1.0a6ee4f4272036db2b8f6963d1c4p-103 }, |
| | 305 | .{ .hi = 0x1.88e9c72e0b225a4b664a4c8ep-2, .lo = -0x1.59153bc13892380cd03989062763p-100 }, |
| | 306 | .{ .hi = 0x1.91bba891f1708b4b2b5056b8p-2, .lo = 0x1.a7156185dba8beba3cb180b37bbbp-100 }, |
| | 307 | .{ .hi = 0x1.9a802391e232f34bb6d0e43ap-2, .lo = -0x1.67caee1e30b7c2d6ff9893868aa6p-99 }, |
| | 308 | .{ .hi = 0x1.a33760a7f60509d7c40d797ap-2, .lo = -0x1.3a4e0233ff8ac31bd7b2cb5c0041p-102 }, |
| | 309 | .{ .hi = 0x1.abe18797f1f48e1a4725558cp-2, .lo = 0x1.6f5c786e3d2aafcee056debabb79p-100 }, |
| | 310 | .{ .hi = 0x1.b47ebf73882a0a4146ef8fd8p-2, .lo = 0x1.44f1d5b8a5402f72138cbfe19e49p-99 }, |
| | 311 | .{ .hi = 0x1.bd0f2e9e79030ab442ce3202p-2, .lo = -0x1.d27aeb2ddd02924cf83def704a7bp-99 }, |
| | 312 | .{ .hi = 0x1.c592fad295b567e7ee54aefp-2, .lo = -0x1.99e7587ea99e677177c285c32088p-99 }, |
| | 313 | .{ .hi = 0x1.ce0a4923a587cc95d0a2ee7ap-2, .lo = 0x1.6482ae04295539bf0ed23f498b8ap-104 }, |
| | 314 | .{ .hi = 0x1.d6753e032ea0efe3ebe19906p-2, .lo = -0x1.55594a060c67a245f78bb523ad43p-99 }, |
| | 315 | .{ .hi = 0x1.ded3fd442364c4ebb196116p-2, .lo = -0x1.df9689b34ee848b0b7818878492cp-99 }, |
| | 316 | .{ .hi = 0x1.e726aa1e754d20c519e12f48p-2, .lo = -0x1.dd99950bae450ac5754344a16faep-99 }, |
| | 317 | .{ .hi = 0x1.ef6d67328e2207d1e01a839p-2, .lo = 0x1.04907f9ccddb53ed88c47c7d794cp-100 }, |
| | 318 | .{ .hi = 0x1.f7a8568cb06cece193180046p-2, .lo = -0x1.e149b9528336d5fee3ef52260ad1p-99 }, |
| | 319 | .{ .hi = 0x1.ffd799a83ff9ab9cc7f342f8p-2, .lo = 0x1.70c458bda55b08c8c8668867736bp-99 }, |
| | 320 | .{ .hi = 0x1.03fda8b97997f33943464056p-1, .lo = 0x1.eb47cb2aadd948d48bbef492995ep-99 }, |
| | 321 | .{ .hi = 0x1.0809cf27f703d525b3c1d158p-1, .lo = 0x1.f51e170ccb0f7761e5ff9b93854ep-100 }, |
| | 322 | .{ .hi = 0x1.0c10500d63aa6588257529b6p-1, .lo = 0x1.2ef0aa83f2869dd6be1d1cc2dc47p-100 }, |
| | 323 | .{ .hi = 0x1.10113b153c8ea7b1cddae6fbp-1, .lo = -0x1.8d4296259492a32f8b327d46339p-100 }, |
| | 324 | .{ .hi = 0x1.140c9faa1e5439e15a52a316p-1, .lo = 0x1.29611295daec3b07655c599a50e7p-103 }, |
| | 325 | .{ .hi = 0x1.18028cf72976a4eb8e97d145p-1, .lo = 0x1.9ac318308c388b1f2e108f3d37bep-100 }, |
| | 326 | .{ .hi = 0x1.1bf311e95d00de3b513a9dcdp-1, .lo = -0x1.3c8ff1c1539554d1f10759819adp-100 }, |
| | 327 | .{ .hi = 0x1.1fde3d30e812642415d47384p-1, .lo = 0x1.3c458dd53d12c99743f3c4617c37p-99 }, |
| | 328 | .{ .hi = 0x1.23c41d42727c8080ecc61a99p-1, .lo = -0x1.fb113740031e528bbef9ead829c7p-99 }, |
| | 329 | .{ .hi = 0x1.27a4c0585cbf805784ee0e3bp-1, .lo = -0x1.60c515c0f4b1772f673312a17eep-101 }, |
| | 330 | .{ .hi = 0x1.2b803473f7ad0f3f40162414p-1, .lo = 0x1.a2eb74493cf9a8e8966c101ef964p-102 }, |
| | 331 | .{ .hi = 0x1.2f56875eb3f2614278cd1699p-1, .lo = 0x1.88c5d320344f129c318704371e3dp-100 }, |
| | 332 | .{ .hi = 0x1.3327c6ab49ca6c86b9205fa4p-1, .lo = 0x1.1010939e6edc060bf80459dd880dp-100 }, |
| | 333 | .{ .hi = 0x1.36f3ffb6d9162404772a151dp-1, .lo = -0x1.93193dd58663d90eed123bda5ea2p-100 }, |
| | 334 | .{ .hi = 0x1.3abb3faa02166cccab240e9p-1, .lo = 0x1.3e5a84738c6a548017167cabbd62p-99 }, |
| | 335 | .{ .hi = 0x1.3e7d9379f70166ae2a7ada55p-1, .lo = 0x1.6369ad81817bfeddee4a96320fd3p-100 }, |
| | 336 | .{ .hi = 0x1.423b07e986aa9670761d14abp-1, .lo = -0x1.d93cd9e77a527017a3e16237ddd4p-100 }, |
| | 337 | .{ .hi = 0x1.45f3a98a20738a4d7ffe0267p-1, .lo = 0x1.75541c775be89f0841ae8379c6adp-100 }, |
| | 338 | .{ .hi = 0x1.49a784bcd1b8afe492bf6ff5p-1, .lo = -0x1.2812599349d500e4262958b724aap-100 }, |
| | 339 | .{ .hi = 0x1.4d56a5b33cec44a6deff9987p-1, .lo = 0x1.fad1e37de08f5e02036d27593a4p-100 }, |
| | 340 | .{ .hi = 0x1.510118708a8f8dde949378b2p-1, .lo = 0x1.348f1454e8c939a60252b34c6c66p-100 }, |
| | 341 | .{ .hi = 0x1.54a6e8ca5438db1b0ca63aacp-1, .lo = -0x1.2f1784ce0b08724e7f04c9712103p-99 }, |
| | 342 | .{ .hi = 0x1.5848226989d33c38d8bd28d7p-1, .lo = -0x1.a8e7bb5885dce30d5e9e8139d7b1p-99 }, |
| | 343 | .{ .hi = 0x1.5be4d0cb51434aaeb3f01222p-1, .lo = 0x1.2ce7e40053a5cfc072e22bbeab1dp-100 }, |
| | 344 | .{ .hi = 0x1.5f7cff41e09aeb8cb1ac05cdp-1, .lo = -0x1.4fb2c4a0dc9f7b2e29701f76805bp-100 }, |
| | 345 | .{ .hi = 0x1.6310b8f553048406a5a171dep-1, .lo = 0x1.003332544881b92584a992692c7dp-99 }, |
| | 346 | .{ .hi = 0x1.66a008e4788cbcd2edb4390ep-1, .lo = 0x1.4c1a88f0e7a41e948033b63cbaadp-99 }, |
| | 347 | .{ .hi = 0x1.6a2af9e5a0f0a08099572f21p-1, .lo = -0x1.0665eae13d10b498acfb49ce0dep-99 }, |
| | 348 | .{ .hi = 0x1.6db196a761949d97df07e357p-1, .lo = -0x1.7679e5a1e4a0e0dbeb3195d40b4dp-99 }, |
| | 349 | .{ .hi = 0x1.7133e9b156c7be5167fbdc81p-1, .lo = 0x1.b935e716c7cb214a0b718fc30587p-100 }, |
| | 350 | .{ .hi = 0x1.74b1fd64e0753c6e5783fd15p-1, .lo = 0x1.923a7aefc37ef9baffdf4ec86923p-102 }, |
| | 351 | .{ .hi = 0x1.782bdbfdda6577bc87e125ebp-1, .lo = -0x1.56e82c9d846f9e967e496249719bp-99 }, |
| | 352 | .{ .hi = 0x1.7ba18f93502e409eab77f21ap-1, .lo = -0x1.c097ea4900b7ca9ea124a56a0c75p-100 }, |
| | 353 | .{ .hi = 0x1.7f1322182cf15d12ecd77fe7p-1, .lo = -0x1.0512c0ac2d3510c6f5fd964c2ae2p-99 }, |
| | 354 | .{ .hi = 0x1.82809d5be7072dbdc0426c3cp-1, .lo = 0x1.3a309736edbb3eae70d10c173b0bp-100 }, |
| | 355 | .{ .hi = 0x1.85ea0b0b27b261086fce864ap-1, .lo = 0x1.f5979367f112e34dbc4e07ae924cp-101 }, |
| | 356 | .{ .hi = 0x1.894f74b06ef8b406ea2c7d92p-1, .lo = -0x1.54ede83a0018a21469a1f11911aep-99 }, |
| | 357 | .{ .hi = 0x1.8cb0e3b4b3bbdb3688a85fb2p-1, .lo = -0x1.910d207f019516331134b0c9d172p-99 }, |
| | 358 | .{ .hi = 0x1.900e6160002ccfe43f50847dp-1, .lo = 0x1.82887e54848c7603fba7d2ba264ap-101 }, |
| | 359 | .{ .hi = 0x1.9367f6da0ab2e9cc865b3dd1p-1, .lo = -0x1.225541e18baff32be2709a01f861p-100 }, |
| | 360 | .{ .hi = 0x1.96bdad2acb5f5efec4915314p-1, .lo = 0x1.b7c0b9db2fcb23be56be998e8e8fp-99 }, |
| | 361 | .{ .hi = 0x1.9a0f8d3b0e04fde95734abd3p-1, .lo = -0x1.9f19ce27d2dca3979bbb0ca9365fp-104 }, |
| | 362 | .{ .hi = 0x1.9d5d9fd5010b366655920748p-1, .lo = 0x1.3e5a84738c6a548017167cabbd62p-100 }, |
| | 363 | .{ .hi = 0x1.a0a7eda4c112ce6312ebb81dp-1, .lo = -0x1.5a727dbaad60b1bf6bcd429e9fdfp-102 }, |
| | 364 | .{ .hi = 0x1.a3ee7f38e181ed0798d1aa21p-1, .lo = 0x1.a51584c9dc5627ac1ab989c42834p-99 }, |
| | 365 | .{ .hi = 0x1.a7315d02f20c7bd560a3fee1p-1, .lo = -0x1.dacbac02cace034400340f2319ddp-99 }, |
| | 366 | .{ .hi = 0x1.aa708f58014d37cde37c86b2p-1, .lo = 0x1.06a19b5bedec4594babbdab2fd2p-100 }, |
| | 367 | .{ .hi = 0x1.adac1e711c832d1562d61af7p-1, .lo = 0x1.fbfa94970bb9fab077c80ac91e28p-100 }, |
| | 368 | .{ .hi = 0x1.b0e4126bcc86bd7a6ed4e1b1p-1, .lo = -0x1.b28c4122d931f14daa7bc7cc5b07p-99 }, |
| | 369 | .{ .hi = 0x1.b418734a9008bd978b98f7dfp-1, .lo = -0x1.039d32863d2685d1b265e993decbp-100 }, |
| | 370 | .{ .hi = 0x1.b74948f5532da4b4b7143364p-1, .lo = -0x1.ce44c707d13d9c8e8a9007c6ffb4p-99 }, |
| | 371 | .{ .hi = 0x1.ba769b39e49640ef87ede14bp-1, .lo = -0x1.735f3571b2e44add58e787eb935ep-101 }, |
| | 372 | .{ .hi = 0x1.bda071cc67e6db516de08136p-1, .lo = 0x1.b4d5660336e288cea5ceba447906p-99 }, |
| | 373 | .{ .hi = 0x1.c0c6d447c5dd362d9a9a55c7p-1, .lo = 0x1.17b370ba83c0155dfdf1fd11696ep-99 }, |
| | 374 | .{ .hi = 0x1.c3e9ca2e1a05533698b4e49bp-1, .lo = 0x1.ec0c07c38978823235b0f583d7a7p-99 }, |
| | 375 | .{ .hi = 0x1.c7095ae91e1c760bc9b188c4p-1, .lo = 0x1.322631fb315aaf4da97307d1076bp-99 }, |
| | 376 | .{ .hi = 0x1.ca258dca9331635fee390c0bp-1, .lo = -0x1.3e17e7a7e746edea65e0c4e7d82dp-99 }, |
| | 377 | .{ .hi = 0x1.cd3e6a0ca8906c243749114cp-1, .lo = 0x1.2bbae931e8daa670e214b298ab12p-99 }, |
| | 378 | .{ .hi = 0x1.d053f6d2608967318975dc0ep-1, .lo = 0x1.ea58d8245529f4e409432bd61602p-99 }, |
| | 379 | .{ .hi = 0x1.d3663b27f31d5297837adb4bp-1, .lo = -0x1.38daa2d672ec54842668a312854dp-100 }, |
| | 380 | .{ .hi = 0x1.d6753e032ea0efe3ebe19905p-1, .lo = 0x1.554d6bf3e730bb7410e895b8a57ap-99 }, |
| | 381 | .{ .hi = 0x1.d9810643d6614c3c406eb464p-1, .lo = 0x1.05d328adc61c09915e038a135bdfp-99 }, |
| | 382 | .{ .hi = 0x1.dc899ab3ff56c5e673abad44p-1, .lo = 0x1.8c6339fa7bd10d27c064978bc6f5p-100 }, |
| | 383 | .{ .hi = 0x1.df8f02086af2c4bef483c68bp-1, .lo = -0x1.0baa11f1460aebb8f273d9820bc8p-99 }, |
| | 384 | .{ .hi = 0x1.e29142e0e01401fbaaa67e3cp-1, .lo = -0x1.d6541223b8314593546e23de0435p-100 }, |
| | 385 | .{ .hi = 0x1.e59063c8822ce561911a9bacp-1, .lo = 0x1.9b0de815b6fb0c41cac421925a11p-99 }, |
| | 386 | .{ .hi = 0x1.e88c6b3626a72aa21a3c7f02p-1, .lo = -0x1.0e3aeafe4f838b64e3bde351d0f1p-102 }, |
| | 387 | .{ .hi = 0x1.eb855f8ca88fb0d4b5c673bbp-1, .lo = 0x1.1db401cf29698d7b00a45b6d1082p-102 }, |
| | 388 | .{ .hi = 0x1.ee7b471b3a9507d6dc1f27efp-1, .lo = 0x1.21f23cd188a03f54e360fd76a481p-99 }, |
| | 389 | .{ .hi = 0x1.f16e281db76303b21928c216p-1, .lo = -0x1.2854f795db443461c5e7233e545fp-102 }, |
| | 390 | .{ .hi = 0x1.f45e08bcf06554e4d5be4f7p-1, .lo = 0x1.07e81f4c1573947a3126425d9d0ap-99 }, |
| | 391 | .{ .hi = 0x1.f74aef0efafadd7a1b65f639p-1, .lo = -0x1.7bc1e9882648a6b530fa4d847e3fp-100 }, |
| | 392 | .{ .hi = 0x1.fa34e1177c23362928b9ed75p-1, .lo = -0x1.856dc2b529ad698bfda1e41b89bdp-101 }, |
| | 393 | .{ .hi = 0x1.fd1be4c7f2af942b221ce0d1p-1, .lo = 0x1.a275c854f5bb9732fae5130be48bp-104 }, |
| | 394 | .{ .hi = 0x1p0, .lo = 0 }, |
| | 395 | }; |
| | 396 | const xm: f128 = @floatFromInt(m); |
| | 397 | const l_hi = xm * log1p_tab[128].hi + log1p_tab[j].hi; |
| | 398 | const l_lo = xm * log1p_tab[128].lo + log1p_tab[j].lo; |
| | 399 | |
| | 400 | return l_hi + (u * p1 + (q + l_lo)); |
| 169 | } | 401 | } |
| 170 | | 402 | |
| 171 | pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble { | 403 | pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble { |
| ... | @@ -247,3 +479,34 @@ test "log2() boundary" { | ... | @@ -247,3 +479,34 @@ test "log2() boundary" { |
| 247 | try expectEqual(log2(0x1p-1022), -0x1.ffp+9); // First subnormal | 479 | try expectEqual(log2(0x1p-1022), -0x1.ffp+9); // First subnormal |
| 248 | try expect(math.isNan(log2(-0x1p-1022))); // First negative subnormal | 480 | try expect(math.isNan(log2(-0x1p-1022))); // First negative subnormal |
| 249 | } | 481 | } |
| | 482 | |
| | 483 | test "log2q() special" { |
| | 484 | try expectEqual(log2q(0.0), -math.inf(f128)); |
| | 485 | try expectEqual(log2q(-0.0), -math.inf(f128)); |
| | 486 | try expect(math.isPositiveZero(log2q(1.0))); |
| | 487 | try expectEqual(log2q(2.0), 1.0); |
| | 488 | try expectEqual(log2q(math.inf(f128)), math.inf(f128)); |
| | 489 | try expect(math.isNan(log2q(-1.0))); |
| | 490 | try expect(math.isNan(log2q(-math.inf(f128)))); |
| | 491 | try expect(math.isNan(log2q(math.nan(f128)))); |
| | 492 | try expect(math.isNan(log2q(math.snan(f128)))); |
| | 493 | } |
| | 494 | |
| | 495 | test "log2q() boundary" { |
| | 496 | try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value |
| | 497 | try expectEqual(log2q(0x1p-16494), -0x1.01b8p14); // Min positive input value |
| | 498 | try expect(math.isNan(log2q(-0x1p-16494))); // Min negative input value |
| | 499 | try expectEqual(log2q(0x1.0000000000000000000000000001p0), 0x1.71547652b82fe1777d0ffda0d23ap-112); // Last value before result reaches +0 |
| | 500 | try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp-1), -0x1.71547652b82fe1777d0ffda0d23bp-113); // Last value before result reaches -0 |
| | 501 | try expectEqual(log2q(0x1p-16382), -0x1.fffp13); // First subnormal |
| | 502 | try expect(math.isNan(log2q(-0x1p-16382))); // First negative subnormal |
| | 503 | } |
| | 504 | |
| | 505 | test "log2q() sanity" { |
| | 506 | try expectEqual(log2q(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1); |
| | 507 | try expectEqual(log2q(8.346531942223744e15), 5.28900982928636641107356163006646e1); |
| | 508 | try expectEqual(log2q(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1); |
| | 509 | try expectEqual(log2q(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1); |
| | 510 | try expectEqual(log2q(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1); |
| | 511 | try expectEqual(log2q(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1); |
| | 512 | } |