From 9a5eb691b789783528ccdb32520d7fd8bc79ab96 Mon Sep 17 00:00:00 2001 From: Leung Ming <165622843+leung-ming@users.noreply.github.com> Date: Fri, 20 Jun 2025 02:26:14 +0800 Subject: [PATCH 1/8] nit --- native/spark-expr/src/conversion_funcs/cast.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/native/spark-expr/src/conversion_funcs/cast.rs b/native/spark-expr/src/conversion_funcs/cast.rs index b8402a8e6c..478e98fe37 100644 --- a/native/spark-expr/src/conversion_funcs/cast.rs +++ b/native/spark-expr/src/conversion_funcs/cast.rs @@ -1298,6 +1298,7 @@ where }); } else { cast_array.append_null(); + continue; } } cast_array.append_value(v); From 955f739ca3a5a5175fae882d17eda0decaefb708 Mon Sep 17 00:00:00 2001 From: Leung Ming <165622843+leung-ming@users.noreply.github.com> Date: Wed, 18 Jun 2025 15:53:16 +0800 Subject: [PATCH 2/8] mark compactable --- docs/source/user-guide/compatibility.md | 4 ++-- .../apache/comet/expressions/CometCast.scala | 8 ++------ .../org/apache/comet/CometCastSuite.scala | 18 ++---------------- 3 files changed, 6 insertions(+), 24 deletions(-) diff --git a/docs/source/user-guide/compatibility.md b/docs/source/user-guide/compatibility.md index 9612090753..dd2b0e4926 100644 --- a/docs/source/user-guide/compatibility.md +++ b/docs/source/user-guide/compatibility.md @@ -174,6 +174,7 @@ The following cast operations are generally compatible with Spark except for the | float | integer | | | float | long | | | float | double | | +| float | decimal | | | float | string | There can be differences in precision. For example, the input "1.4E-45" will produce 1.0E-45 instead of 1.4E-45 | | double | boolean | | | double | byte | | @@ -181,6 +182,7 @@ The following cast operations are generally compatible with Spark except for the | double | integer | | | double | long | | | double | float | | +| double | decimal | | | double | string | There can be differences in precision. For example, the input "1.4E-45" will produce 1.0E-45 instead of 1.4E-45 | | decimal | byte | | | decimal | short | | @@ -210,8 +212,6 @@ The following cast operations are not compatible with Spark for all inputs and a |-|-|-| | integer | decimal | No overflow check | | long | decimal | No overflow check | -| float | decimal | There can be rounding differences | -| double | decimal | There can be rounding differences | | string | float | Does not support inputs ending with 'd' or 'f'. Does not support 'inf'. Does not support ANSI mode. | | string | double | Does not support inputs ending with 'd' or 'f'. Does not support 'inf'. Does not support ANSI mode. | | string | decimal | Does not support inputs ending with 'd' or 'f'. Does not support 'inf'. Does not support ANSI mode. Returns 0.0 instead of null if input contains no digits | diff --git a/spark/src/main/scala/org/apache/comet/expressions/CometCast.scala b/spark/src/main/scala/org/apache/comet/expressions/CometCast.scala index e0e89b35fc..7aa58286c7 100644 --- a/spark/src/main/scala/org/apache/comet/expressions/CometCast.scala +++ b/spark/src/main/scala/org/apache/comet/expressions/CometCast.scala @@ -262,9 +262,7 @@ object CometCast { case DataTypes.BooleanType | DataTypes.DoubleType | DataTypes.ByteType | DataTypes.ShortType | DataTypes.IntegerType | DataTypes.LongType => Compatible() - case _: DecimalType => - // https://github.com/apache/datafusion-comet/issues/1371 - Incompatible(Some("There can be rounding differences")) + case _: DecimalType => Compatible() case _ => Unsupported } @@ -272,9 +270,7 @@ object CometCast { case DataTypes.BooleanType | DataTypes.FloatType | DataTypes.ByteType | DataTypes.ShortType | DataTypes.IntegerType | DataTypes.LongType => Compatible() - case _: DecimalType => - // https://github.com/apache/datafusion-comet/issues/1371 - Incompatible(Some("There can be rounding differences")) + case _: DecimalType => Compatible() case _ => Unsupported } diff --git a/spark/src/test/scala/org/apache/comet/CometCastSuite.scala b/spark/src/test/scala/org/apache/comet/CometCastSuite.scala index cb12dde156..2b7475f02b 100644 --- a/spark/src/test/scala/org/apache/comet/CometCastSuite.scala +++ b/spark/src/test/scala/org/apache/comet/CometCastSuite.scala @@ -411,17 +411,10 @@ class CometCastSuite extends CometTestBase with AdaptiveSparkPlanHelper { castTest(generateFloats(), DataTypes.DoubleType) } - ignore("cast FloatType to DecimalType(10,2)") { - // // https://github.com/apache/datafusion-comet/issues/1371 + test("cast FloatType to DecimalType(10,2)") { castTest(generateFloats(), DataTypes.createDecimalType(10, 2)) } - test("cast FloatType to DecimalType(10,2) - allow incompat") { - withSQLConf(CometConf.COMET_CAST_ALLOW_INCOMPATIBLE.key -> "true") { - castTest(generateFloats(), DataTypes.createDecimalType(10, 2)) - } - } - test("cast FloatType to StringType") { // https://github.com/apache/datafusion-comet/issues/312 val r = new Random(0) @@ -471,17 +464,10 @@ class CometCastSuite extends CometTestBase with AdaptiveSparkPlanHelper { castTest(generateDoubles(), DataTypes.FloatType) } - ignore("cast DoubleType to DecimalType(10,2)") { - // https://github.com/apache/datafusion-comet/issues/1371 + test("cast DoubleType to DecimalType(10,2)") { castTest(generateDoubles(), DataTypes.createDecimalType(10, 2)) } - test("cast DoubleType to DecimalType(10,2) - allow incompat") { - withSQLConf(CometConf.COMET_CAST_ALLOW_INCOMPATIBLE.key -> "true") { - castTest(generateDoubles(), DataTypes.createDecimalType(10, 2)) - } - } - test("cast DoubleType to StringType") { // https://github.com/apache/datafusion-comet/issues/312 val r = new Random(0) From fbd493fa3d0fd38d48a70ed6a86df7ca4df58080 Mon Sep 17 00:00:00 2001 From: Leung Ming <165622843+leung-ming@users.noreply.github.com> Date: Fri, 20 Jun 2025 02:37:23 +0800 Subject: [PATCH 3/8] schubfach --- .../spark-expr/src/conversion_funcs/cast.rs | 22 +- native/spark-expr/src/conversion_funcs/mod.rs | 2 + .../src/conversion_funcs/schubfach.rs | 1517 +++++++++++++++++ 3 files changed, 1537 insertions(+), 4 deletions(-) create mode 100644 native/spark-expr/src/conversion_funcs/schubfach.rs diff --git a/native/spark-expr/src/conversion_funcs/cast.rs b/native/spark-expr/src/conversion_funcs/cast.rs index 478e98fe37..6a194159dc 100644 --- a/native/spark-expr/src/conversion_funcs/cast.rs +++ b/native/spark-expr/src/conversion_funcs/cast.rs @@ -15,6 +15,7 @@ // specific language governing permissions and limitations // under the License. +use crate::conversion_funcs::schubfach; use crate::timezone; use crate::utils::array_with_timezone; use crate::{EvalMode, SparkError, SparkResult}; @@ -49,6 +50,7 @@ use num::{ ToPrimitive, }; use regex::Regex; +use std::num::Saturating; use std::str::FromStr; use std::{ any::Any, @@ -1278,17 +1280,29 @@ where let input = array.as_any().downcast_ref::>().unwrap(); let mut cast_array = PrimitiveArray::::builder(input.len()); - let mul = 10_f64.powi(scale as i32); - for i in 0..input.len() { if input.is_null(i) { cast_array.append_null(); } else { let input_value = input.value(i).as_(); - let value = (input_value * mul).round().to_i128(); + let value = schubfach::to_decimal(input_value); match value { - Some(v) => { + Some((significand, exponent)) => { + let mut v = if input_value < 0. { + -significand + } else { + significand + } as i128; + + let k = exponent + scale as i32; + if k > 0 { + v = v.saturating_mul(Saturating(10_i128).pow(k as u32).0); + } else if k < 0 { + let dk = Saturating(10_i128).pow((-k) as u32).0; + let (div, rem) = if dk < v { v.div_rem(&dk) } else { (0, v) }; + v = if rem * 2 >= dk { div + 1 } else { div }; + } if Decimal128Type::validate_decimal_precision(v, precision).is_err() { if eval_mode == EvalMode::Ansi { return Err(SparkError::NumericValueOutOfRange { diff --git a/native/spark-expr/src/conversion_funcs/mod.rs b/native/spark-expr/src/conversion_funcs/mod.rs index f2c6f7ca36..1e440fba9c 100644 --- a/native/spark-expr/src/conversion_funcs/mod.rs +++ b/native/spark-expr/src/conversion_funcs/mod.rs @@ -16,3 +16,5 @@ // under the License. pub mod cast; + +mod schubfach; diff --git a/native/spark-expr/src/conversion_funcs/schubfach.rs b/native/spark-expr/src/conversion_funcs/schubfach.rs new file mode 100644 index 0000000000..e48daeb3bf --- /dev/null +++ b/native/spark-expr/src/conversion_funcs/schubfach.rs @@ -0,0 +1,1517 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +// https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/math/DoubleToDecimal.java +// +// For full details about this code see the following references: +// +// [1] Giulietti, "The Schubfach way to render doubles", +// https://drive.google.com/file/d/1gp5xv4CAa78SVgCeWfGqqI4FfYYYuNFb +// +// [2] IEEE Computer Society, "IEEE Standard for Floating-Point Arithmetic" +// +// Divisions are avoided altogether for the benefit of those architectures +// that do not provide specific machine instructions or where they are slow. +// This is discussed in section 10 of [1]. + +// The precision in bits +const P: i32 = 53; +// Exponent width in bits +const W: i32 = 64 - 1 - (P - 1); +// Minimum value of the exponent: -(2^(W-1)) - P + 3 +const Q_MIN: i32 = (-1 << (W - 1)) - P + 3; +// Threshold to detect tiny values, as in section 8.2.1 of [1] +const C_TINY: i64 = 3; +// The minimum k, as in section 8 of [1] +const K_MIN: i32 = -324; +// Minimum value of the significand of a normal value: 2^(P-1) +const C_MIN: i64 = 1 << (P - 1); +// Mask to extract the biased exponent +const BQ_MASK: i32 = (1 << W) - 1; +// Mask to extract the fraction bits +const T_MASK: u64 = (1 << (P - 1)) - 1; + +pub fn to_decimal(v: f64) -> Option<(i64, i32)> { + // For full details see references [2] and [1]. + // + // For finite v != 0, determine integers c and q such that + // |v| = c 2^q and + // Q_MIN <= q <= Q_MAX and + // either 2^(P-1) <= c < 2^P (normal) + // or 0 < c < 2^(P-1) and q = Q_MIN (subnormal) + + let bits = v.to_bits(); + let t = (bits & T_MASK) as i64; + let bq = (bits >> P - 1) as i32 & BQ_MASK; + if bq < BQ_MASK { + if bq != 0 { + // normal value. Here mq = -q + let mq = -Q_MIN + 1 - bq; + let c = C_MIN | t; + // The fast path discussed in section 8.3 of [1] + if 0 < mq && mq < P { + let f = c >> mq; + if f << mq == c { + return Some((f, 0)); + } + } + return Some(finite_positive_to_decimal(-mq, c, 0)); + } + if t != 0 { + // subnormal value + return Some(if t < C_TINY { + finite_positive_to_decimal(Q_MIN, 10 * t, -1) + } else { + finite_positive_to_decimal(Q_MIN, t, 0) + }); + } + return Some((0, 0)); + } + None +} + +fn finite_positive_to_decimal(q: i32, c: i64, dk: i32) -> (i64, i32) { + // The skeleton corresponds to figure 7 of [1]. + // The efficient computations are those summarized in figure 9. + // + // Here's a correspondence between variable names and names in [1], + // expressed as approximate LaTeX source code and informally. + // Other names are identical. + // cb: \bar{c} "c-bar" + // cbr: \bar{c}_r "c-bar-r" + // cbl: \bar{c}_l "c-bar-l" + // + // vb: \bar{v} "v-bar" + // vbr: \bar{v}_r "v-bar-r" + // vbl: \bar{v}_l "v-bar-l" + // + // rop: r_o' "r-o-prime" + + let out = c & 1; + let cb = c << 2; + let cbr = cb + 2; + // flog10pow2(e) = floor(log_10(2^e)) + // flog10threeQuartersPow2(e) = floor(log_10(3/4 2^e)) + // flog2pow10(e) = floor(log_2(10^e)) + let (cbl, k) = if c != C_MIN || q == Q_MIN { + // regular spacing + (cb - 2, f_log10_pow2(q)) + } else { + // irregular spacing + (cb - 1, f_log10_three_quarters_pow2(q)) + }; + let h = q + f_log2_pow10(-k) + 2; + + // g1 and g0 are as in section 9.8.3 of [1], so g = g1 2^63 + g0 + let g1 = g1(k); + let g0 = g0(k); + + let vb = rop(g1, g0, cb << h); + let vbl = rop(g1, g0, cbl << h); + let vbr = rop(g1, g0, cbr << h); + + let s = vb >> 2; + if s >= 100 { + // For n = 17, m = 1 the table in section 10 of [1] shows + // s' = floor(s / 10) = floor(s 115_292_150_460_684_698 / 2^60) + // = floor(s 115_292_150_460_684_698 2^4 / 2^64) + // + // sp10 = 10 s' + // tp10 = 10 t' + // upin iff u' = sp10 10^k in Rv + // wpin iff w' = tp10 10^k in Rv + // See section 9.3 of [1]. + + let sp10 = 10_i64.wrapping_mul( + ((s as i128 * (115_292_150_460_684_698_i64 << 4) as i128) as u128 >> 64) as i64, + ); + let tp10 = sp10 + 10; + let upin = vbl + out <= sp10 << 2; + let wpin = (tp10 << 2) + out <= vbr; + if upin != wpin { + return (if upin { sp10 } else { tp10 }, k); + } + } + + // 10 <= s < 100 or s >= 100 and u', w' not in Rv + // uin iff u = s 10^k in Rv + // win iff w = t 10^k in Rv + // See section 9.3 of [1]. + let t = s + 1; + let uin = vbl + out <= s << 2; + let win = (t << 2) + out <= vbr; + if uin != win { + return (if uin { s } else { t }, k + dk); + } + + // Both u and w lie in Rv: determine the one closest to v. + // See section 9.3 of [1]. + let cmp = vb - (s + t << 1); + ( + if cmp < 0 || cmp == 0 && (s & 1) == 0 { + s + } else { + t + }, + k + dk, + ) +} + +/// Computes rop(cp * g * 2^(-127)), where g = g1 2^63 + g0 +/// See section 9.9 and figure 8 of [1]. +fn rop(g1: i64, g0: i64, cp: i64) -> i64 { + const MASK_63: i64 = 0x7fff_ffff_ffff_ffff; + + let x1 = ((g0 as i128 * cp as i128) as u128 >> 64) as i64; + let y0 = g1.wrapping_mul(cp); + let y1 = ((g1 as i128 * cp as i128) as u128 >> 64) as i64; + let z = ((y0 as u64 >> 1) as i64).wrapping_add(x1); + let vbp = y1.wrapping_add((z as u64 >> 63) as i64); + vbp | (((z & MASK_63).wrapping_add(MASK_63)) as u64 >> 63) as i64 +} + +// math utils + +// C_10 = floor(log10(2) * 2^Q_10), A_10 = floor(log10(3/4) * 2^Q_10) +const Q_10: i32 = 41; +const C_10: i64 = 661_971_961_083; +const A_10: i64 = -274_743_187_321; + +// C_2 = floor(log2(10) * 2^Q_2) +const Q_2: i32 = 38; +const C_2: i64 = 913_124_641_741; + +/// Returns the unique integer k such that 10^k <= 2^e < 10^(k+1). +/// +/// The result is correct when |e| <= 6_432_162. +/// Otherwise the result is undefined. +/// +/// # Arguments +/// +/// * `e` - The exponent of 2, which should meet |e| <= 6_432_162 for safe results. +/// +/// # Returns +/// +/// * `i32` - floor(log10(2^e)). +fn f_log10_pow2(e: i32) -> i32 { + (e as i64 * C_10 >> Q_10) as i32 +} + +/// Returns the unique integer k such that 10^k <= 3/4 * 2^e < 10^(k+1). +/// +/// The result is correct when -3_606_689 < e <= 3_150_619. +/// Otherwise the result is undefined. +/// +/// # Arguments +/// +/// * `e` - The exponent of 2, which should meet -3_606_689 <= e < 3_150_619 for safe results. +/// +/// # Returns +/// +/// * `i32` - floor(log10(3/4 * 2^e)) +fn f_log10_three_quarters_pow2(e: i32) -> i32 { + (e as i64 * C_10 + A_10 >> Q_10) as i32 +} + +/// Returns the unique integer k such that 2^k <= 10^e < 2^(k+1). +/// +/// The result is correct when |e| <= 1_838_394. +/// Otherwise the result is undefined. +/// +/// # Arguments +/// +/// * `e` - The exponent of 10, which should meet |e| < 1_838_394 for safe results. +/// +/// # Returns +/// +/// * `i32` - floor(log2(10^e)) +fn f_log2_pow10(e: i32) -> i32 { + (e as i64 * C_2 >> Q_2) as i32 +} + +/// Let 10^-k = B * 2^r, for the unique pair of integer r and real B meeting 2^125 <= B < 2^126. +/// Further, let g = floor(B) + 1. Split g into the higher 63 bits g1 and the lower 63 bits g0. +/// Thus, g1 = floor(g * 2^-63) and g0 = g - g1 * 2^63. +/// +/// This method returns g1 while `g0(k)` returns g0. +/// +/// If needed, the exponent r can be computed as r = `flog2pow10(-k)` - 125. +/// +/// # Arguments +/// +/// * `k` - The exponent of 10, which must meet `K_MIN` <= k <= `K_MAX`. +/// +/// # Returns +/// +/// * `i64` - g1 as described above. +fn g1(k: i32) -> i64 { + return G[(k - K_MIN << 1) as usize]; +} + +/// Returns g0 as described in `g1(k)` +/// +/// # Arguments +/// +/// * `k` - The exponent of 10, which must meet `K_MIN` <= k <= `K_MAX`. +/// +/// # Returns +/// +/// * `i64` - g0 as described in `g1(k)` +fn g0(k: i32) -> i64 { + return G[(k - K_MIN << 1 | 1) as usize]; +} + +// The precomputed values for g1(int) and g0(int). +// The first entry must be for an exponent of K_MIN or less. +// The last entry must be for an exponent of K_MAX or more. +#[doc(hidden)] +const G: [i64; 1234] = [ + 0x4F0C_EDC9_5A71_8DD4_i64, + 0x5B01_E8B0_9AA0_D1B5_i64, // -324 + 0x7E7B_160E_F71C_1621_i64, + 0x119C_A780_F767_B5EE_i64, // -323 + 0x652F_44D8_C5B0_11B4_i64, + 0x0E16_EC67_2C52_F7F2_i64, // -322 + 0x50F2_9D7A_37C0_0E29_i64, + 0x5812_56B8_F042_5FF5_i64, // -321 + 0x40C2_1794_F966_71BA_i64, + 0x79A8_4560_C035_1991_i64, // -320 + 0x679C_F287_F570_B5F7_i64, + 0x75DA_089A_CD21_C281_i64, // -319 + 0x52E3_F539_9126_F7F9_i64, + 0x44AE_6D48_A41B_0201_i64, // -318 + 0x424F_F761_40EB_F994_i64, + 0x36F1_F106_E9AF_34CD_i64, // -317 + 0x6A19_8BCE_CE46_5C20_i64, + 0x57E9_81A4_A918_547B_i64, // -316 + 0x54E1_3CA5_71D1_E34D_i64, + 0x2CBA_CE1D_5413_76C9_i64, // -315 + 0x43E7_63B7_8E41_82A4_i64, + 0x23C8_A4E4_4342_C56E_i64, // -314 + 0x6CA5_6C58_E39C_043A_i64, + 0x060D_D4A0_6B9E_08B0_i64, // -313 + 0x56EA_BD13_E949_9CFB_i64, + 0x1E71_76E6_BC7E_6D59_i64, // -312 + 0x4588_9743_2107_B0C8_i64, + 0x7EC1_2BEB_C9FE_BDE1_i64, // -311 + 0x6F40_F205_01A5_E7A7_i64, + 0x7E01_DFDF_A997_9635_i64, // -310 + 0x5900_C19D_9AEB_1FB9_i64, + 0x4B34_B319_5479_44F7_i64, // -309 + 0x4733_CE17_AF22_7FC7_i64, + 0x55C3_C27A_A9FA_9D93_i64, // -308 + 0x71EC_7CF2_B1D0_CC72_i64, + 0x5606_03F7_765D_C8EA_i64, // -307 + 0x5B23_9728_8E40_A38E_i64, + 0x7804_CFF9_2B7E_3A55_i64, // -306 + 0x48E9_45BA_0B66_E93F_i64, + 0x1337_0CC7_55FE_9511_i64, // -305 + 0x74A8_6F90_123E_41FE_i64, + 0x51F1_AE0B_BCCA_881B_i64, // -304 + 0x5D53_8C73_41CB_67FE_i64, + 0x74C1_5809_63D5_39AF_i64, // -303 + 0x4AA9_3D29_016F_8665_i64, + 0x43CD_E007_8310_FAF3_i64, // -302 + 0x7775_2EA8_024C_0A3C_i64, + 0x0616_333F_381B_2B1E_i64, // -301 + 0x5F90_F220_01D6_6E96_i64, + 0x3811_C298_F9AF_55B1_i64, // -300 + 0x4C73_F4E6_67DE_BEDE_i64, + 0x600E_3547_2E25_DE28_i64, // -299 + 0x7A53_2170_A631_3164_i64, + 0x3349_EED8_49D6_303F_i64, // -298 + 0x61DC_1AC0_84F4_2783_i64, + 0x42A1_8BE0_3B11_C033_i64, // -297 + 0x4E49_AF00_6A5C_EC69_i64, + 0x1BB4_6FE6_95A7_CCF5_i64, // -296 + 0x7D42_B19A_43C7_E0A8_i64, + 0x2C53_E63D_BC3F_AE55_i64, // -295 + 0x6435_5AE1_CFD3_1A20_i64, + 0x2376_51CA_FCFF_BEAA_i64, // -294 + 0x502A_AF1B_0CA8_E1B3_i64, + 0x35F8_416F_30CC_9888_i64, // -293 + 0x4022_25AF_3D53_E7C2_i64, + 0x5E60_3458_F3D6_E06D_i64, // -292 + 0x669D_0918_621F_D937_i64, + 0x4A33_86F4_B957_CD7B_i64, // -291 + 0x5217_3A79_E819_7A92_i64, + 0x6E8F_9F2A_2DDF_D796_i64, // -290 + 0x41AC_2EC7_ECE1_2EDB_i64, + 0x720C_7F54_F17F_DFAB_i64, // -289 + 0x6913_7E0C_AE35_17C6_i64, + 0x1CE0_CBBB_1BFF_CC45_i64, // -288 + 0x540F_980A_24F7_4638_i64, + 0x171A_3C95_AFFF_D69E_i64, // -287 + 0x433F_ACD4_EA5F_6B60_i64, + 0x127B_63AA_F333_1218_i64, // -286 + 0x6B99_1487_DD65_7899_i64, + 0x6A5F_05DE_51EB_5026_i64, // -285 + 0x5614_106C_B11D_FA14_i64, + 0x5518_D17E_A7EF_7352_i64, // -284 + 0x44DC_D9F0_8DB1_94DD_i64, + 0x2A7A_4132_1FF2_C2A8_i64, // -283 + 0x6E2E_2980_E2B5_BAFB_i64, + 0x5D90_6850_331E_043F_i64, // -282 + 0x5824_EE00_B55E_2F2F_i64, + 0x6473_86A6_8F4B_3699_i64, // -281 + 0x4683_F19A_2AB1_BF59_i64, + 0x36C2_D21E_D908_F87B_i64, // -280 + 0x70D3_1C29_DDE9_3228_i64, + 0x579E_1CFE_280E_5A5D_i64, // -279 + 0x5A42_7CEE_4B20_F4ED_i64, + 0x2C7E_7D98_200B_7B7E_i64, // -278 + 0x4835_30BE_A280_C3F1_i64, + 0x09FE_CAE0_19A2_C932_i64, // -277 + 0x7388_4DFD_D0CE_064E_i64, + 0x4331_4499_C29E_0EB6_i64, // -276 + 0x5C6D_0B31_73D8_050B_i64, + 0x4F5A_9D47_CEE4_D891_i64, // -275 + 0x49F0_D5C1_2979_9DA2_i64, + 0x72AE_E439_7250_AD41_i64, // -274 + 0x764E_22CE_A8C2_95D1_i64, + 0x377E_39F5_83B4_4868_i64, // -273 + 0x5EA4_E8A5_53CE_DE41_i64, + 0x12CB_6191_3629_D387_i64, // -272 + 0x4BB7_2084_430B_E500_i64, + 0x756F_8140_F821_7605_i64, // -271 + 0x7925_00D3_9E79_6E67_i64, + 0x6F18_CECE_59CF_233C_i64, // -270 + 0x60EA_670F_B1FA_BEB9_i64, + 0x3F47_0BD8_47D8_E8FD_i64, // -269 + 0x4D88_5272_F4C8_9894_i64, + 0x329F_3CAD_0647_20CA_i64, // -268 + 0x7C0D_50B7_EE0D_C0ED_i64, + 0x3765_2DE1_A3A5_0143_i64, // -267 + 0x633D_DA2C_BE71_6724_i64, + 0x2C50_F181_4FB7_3436_i64, // -266 + 0x4F64_AE8A_31F4_5283_i64, + 0x3D0D_8E01_0C92_902B_i64, // -265 + 0x7F07_7DA9_E986_EA6B_i64, + 0x7B48_E334_E0EA_8045_i64, // -264 + 0x659F_97BB_2138_BB89_i64, + 0x4907_1C2A_4D88_669D_i64, // -263 + 0x514C_7962_80FA_2FA1_i64, + 0x20D2_7CEE_A46D_1EE4_i64, // -262 + 0x4109_FAB5_33FB_594D_i64, + 0x670E_CA58_838A_7F1D_i64, // -261 + 0x680F_F788_532B_C216_i64, + 0x0B4A_DD5A_6C10_CB62_i64, // -260 + 0x533F_F939_DC23_01AB_i64, + 0x22A2_4AAE_BCDA_3C4E_i64, // -259 + 0x4299_942E_49B5_9AEF_i64, + 0x354E_A225_63E1_C9D8_i64, // -258 + 0x6A8F_537D_42BC_2B18_i64, + 0x554A_9D08_9FCF_A95A_i64, // -257 + 0x553F_75FD_CEFC_EF46_i64, + 0x776E_E406_E63F_BAAE_i64, // -256 + 0x4432_C4CB_0BFD_8C38_i64, + 0x5F8B_E99F_1E99_6225_i64, // -255 + 0x6D1E_07AB_4662_79F4_i64, + 0x3279_75CB_6428_9D08_i64, // -254 + 0x574B_3955_D1E8_6190_i64, + 0x2861_2B09_1CED_4A6D_i64, // -253 + 0x45D5_C777_DB20_4E0D_i64, + 0x06B4_226D_B0BD_D524_i64, // -252 + 0x6FBC_7259_5E9A_167B_i64, + 0x2453_6A49_1AC9_5506_i64, // -251 + 0x5963_8EAD_E548_11FC_i64, + 0x1D0F_883A_7BD4_4405_i64, // -250 + 0x4782_D88B_1DD3_4196_i64, + 0x4A72_D361_FCA9_D004_i64, // -249 + 0x726A_F411_C952_028A_i64, + 0x43EA_EBCF_FAA9_4CD3_i64, // -248 + 0x5B88_C341_6DDB_353B_i64, + 0x4FEF_230C_C887_70A9_i64, // -247 + 0x493A_35CD_F17C_2A96_i64, + 0x0CBF_4F3D_6D39_26EE_i64, // -246 + 0x7529_EFAF_E8C6_AA89_i64, + 0x6132_1862_485B_717C_i64, // -245 + 0x5DBB_2626_53D2_2207_i64, + 0x675B_46B5_06AF_8DFD_i64, // -244 + 0x4AFC_1E85_0FDB_4E6C_i64, + 0x52AF_6BC4_0559_3E64_i64, // -243 + 0x77F9_CA6E_7FC5_4A47_i64, + 0x377F_12D3_3BC1_FD6D_i64, // -242 + 0x5FFB_0858_6637_6E9F_i64, + 0x45FF_4242_9634_CABD_i64, // -241 + 0x4CC8_D379_EB5F_8BB2_i64, + 0x6B32_9B68_782A_3BCB_i64, // -240 + 0x7ADA_EBF6_4565_AC51_i64, + 0x2B84_2BDA_59DD_2C77_i64, // -239 + 0x6248_BCC5_0451_56A7_i64, + 0x3C69_BCAE_AE4A_89F9_i64, // -238 + 0x4EA0_9704_0374_4552_i64, + 0x6387_CA25_583B_A194_i64, // -237 + 0x7DCD_BE6C_D253_A21E_i64, + 0x05A6_103B_C05F_68ED_i64, // -236 + 0x64A4_9857_0EA9_4E7E_i64, + 0x37B8_0CFC_99E5_ED8A_i64, // -235 + 0x5083_AD12_7221_0B98_i64, + 0x2C93_3D96_E184_BE08_i64, // -234 + 0x4069_5741_F4E7_3C79_i64, + 0x7075_CADF_1AD0_9807_i64, // -233 + 0x670E_F203_2171_FA5C_i64, + 0x4D89_4498_2AE7_59A4_i64, // -232 + 0x5272_5B35_B45B_2EB0_i64, + 0x3E07_6A13_5585_E150_i64, // -231 + 0x41F5_15C4_9048_F226_i64, + 0x64D2_BB42_AAD1_810D_i64, // -230 + 0x6988_22D4_1A0E_503E_i64, + 0x07B7_9204_4482_6815_i64, // -229 + 0x546C_E8A9_AE71_D9CB_i64, + 0x1FC6_0E69_D068_5344_i64, // -228 + 0x438A_53BA_F1F4_AE3C_i64, + 0x196B_3EBB_0D20_429D_i64, // -227 + 0x6C10_85F7_E987_7D2D_i64, + 0x0F11_FDF8_1500_6A94_i64, // -226 + 0x5673_9E5F_EE05_FDBD_i64, + 0x58DB_3193_4400_5543_i64, // -225 + 0x4529_4B7F_F19E_6497_i64, + 0x60AF_5ADC_3666_AA9C_i64, // -224 + 0x6EA8_78CC_B5CA_3A8C_i64, + 0x344B_C493_8A3D_DDC7_i64, // -223 + 0x5886_C70A_2B08_2ED6_i64, + 0x5D09_6A0F_A1CB_17D2_i64, // -222 + 0x46D2_38D4_EF39_BF12_i64, + 0x173A_BB3F_B4A2_7975_i64, // -221 + 0x7150_5AEE_4B8F_981D_i64, + 0x0B91_2B99_2103_F588_i64, // -220 + 0x5AA6_AF25_093F_ACE4_i64, + 0x0940_EFAD_B403_2AD3_i64, // -219 + 0x4885_58EA_6DCC_8A50_i64, + 0x0767_2624_9002_88A9_i64, // -218 + 0x7408_8E43_E2E0_DD4C_i64, + 0x723E_A36D_B337_410E_i64, // -217 + 0x5CD3_A503_1BE7_1770_i64, + 0x5B65_4F8A_F5C5_CDA5_i64, // -216 + 0x4A42_EA68_E31F_45F3_i64, + 0x62B7_72D5_916B_0AEB_i64, // -215 + 0x76D1_770E_3832_0986_i64, + 0x0458_B7BC_1BDE_77DD_i64, // -214 + 0x5F0D_F8D8_2CF4_D46B_i64, + 0x1D13_C630_164B_9318_i64, // -213 + 0x4C0B_2D79_BD90_A9EF_i64, + 0x30DC_9E8C_DEA2_DC13_i64, // -212 + 0x79AB_7BF5_FC1A_A97F_i64, + 0x0160_FDAE_3104_9351_i64, // -211 + 0x6155_FCC4_C9AE_EDFF_i64, + 0x1AB3_FE24_F403_A90E_i64, // -210 + 0x4DDE_63D0_A158_BE65_i64, + 0x6229_981D_9002_EDA5_i64, // -209 + 0x7C97_061A_9BC1_30A2_i64, + 0x69DC_2695_B337_E2A1_i64, // -208 + 0x63AC_04E2_1634_26E8_i64, + 0x54B0_1EDE_28F9_821B_i64, // -207 + 0x4FBC_D0B4_DE90_1F20_i64, + 0x43C0_18B1_BA61_34E2_i64, // -206 + 0x7F94_8121_6419_CB67_i64, + 0x1F99_C11C_5D68_549D_i64, // -205 + 0x6610_674D_E9AE_3C52_i64, + 0x4C7B_00E3_7DED_107E_i64, // -204 + 0x51A6_B90B_2158_3042_i64, + 0x09FC_00B5_FE57_4065_i64, // -203 + 0x4152_2DA2_8113_59CE_i64, + 0x3B30_0091_9845_CD1D_i64, // -202 + 0x6883_7C37_34EB_C2E3_i64, + 0x784C_CDB5_C06F_AE95_i64, // -201 + 0x539C_635F_5D89_68B6_i64, + 0x2D0A_3E2B_0059_5877_i64, // -200 + 0x42E3_82B2_B13A_BA2B_i64, + 0x3DA1_CB55_99E1_1393_i64, // -199 + 0x6B05_9DEA_B52A_C378_i64, + 0x629C_7888_F634_EC1E_i64, // -198 + 0x559E_17EE_F755_692D_i64, + 0x3549_FA07_2B5D_89B1_i64, // -197 + 0x447E_798B_F911_20F1_i64, + 0x1107_FB38_EF7E_07C1_i64, // -196 + 0x6D97_28DF_F4E8_34B5_i64, + 0x01A6_5EC1_7F30_0C68_i64, // -195 + 0x57AC_20B3_2A53_5D5D_i64, + 0x4E1E_B234_65C0_09ED_i64, // -194 + 0x4623_4D5C_21DC_4AB1_i64, + 0x24E5_5B5D_1E33_3B24_i64, // -193 + 0x7038_7BC6_9C93_AAB5_i64, + 0x216E_F894_FD1E_C506_i64, // -192 + 0x59C6_C96B_B076_222A_i64, + 0x4DF2_6077_30E5_6A6C_i64, // -191 + 0x47D2_3ABC_8D2B_4E88_i64, + 0x3E5B_805F_5A51_21F0_i64, // -190 + 0x72E9_F794_1512_1740_i64, + 0x63C5_9A32_2A1B_697F_i64, // -189 + 0x5BEE_5FA9_AA74_DF67_i64, + 0x0304_7B5B_54E2_BACC_i64, // -188 + 0x498B_7FBA_EEC3_E5EC_i64, + 0x0269_FC49_10B5_623D_i64, // -187 + 0x75AB_FF91_7E06_3CAC_i64, + 0x6A43_2D41_B455_69FB_i64, // -186 + 0x5E23_32DA_CB38_308A_i64, + 0x21CF_5767_C377_87FC_i64, // -185 + 0x4B4F_5BE2_3C2C_F3A1_i64, + 0x67D9_12B9_692C_6CCA_i64, // -184 + 0x787E_F969_F9E1_85CF_i64, + 0x595B_5128_A847_1476_i64, // -183 + 0x6065_9454_C7E7_9E3F_i64, + 0x6115_DA86_ED05_A9F8_i64, // -182 + 0x4D1E_1043_D31F_B1CC_i64, + 0x4DAB_1538_BD9E_2193_i64, // -181 + 0x7B63_4D39_51CC_4FAD_i64, + 0x62AB_5527_95C9_CF52_i64, // -180 + 0x62B5_D761_0E3D_0C8B_i64, + 0x0222_AA86_116E_3F75_i64, // -179 + 0x4EF7_DF80_D830_D6D5_i64, + 0x4E82_2204_DABE_992A_i64, // -178 + 0x7E59_659A_F381_57BC_i64, + 0x1736_9CD4_9130_F510_i64, // -177 + 0x6514_5148_C2CD_DFC9_i64, + 0x5F5E_E3DD_40F3_F740_i64, // -176 + 0x50DD_0DD3_CF0B_196E_i64, + 0x1918_B64A_9A5C_C5CD_i64, // -175 + 0x40B0_D7DC_A5A2_7ABE_i64, + 0x4746_F83B_AEB0_9E3E_i64, // -174 + 0x6781_5961_0903_F797_i64, + 0x253E_59F9_1780_FD2F_i64, // -173 + 0x52CD_E11A_6D9C_C612_i64, + 0x50FE_AE60_DF9A_6426_i64, // -172 + 0x423E_4DAE_BE17_04DB_i64, + 0x5A65_584D_7FAE_B685_i64, // -171 + 0x69FD_4917_968B_3AF9_i64, + 0x10A2_26E2_65E4_573B_i64, // -170 + 0x54CA_A0DF_ABA2_9594_i64, + 0x0D4E_8581_EB1D_1295_i64, // -169 + 0x43D5_4D7F_BC82_1143_i64, + 0x243E_D134_BC17_4211_i64, // -168 + 0x6C88_7BFF_9403_4ED2_i64, + 0x06CA_E854_6025_3682_i64, // -167 + 0x56D3_9666_1002_A574_i64, + 0x6BD5_86A9_E684_2B9B_i64, // -166 + 0x4576_11EB_4002_1DF7_i64, + 0x0977_9EEE_5203_5616_i64, // -165 + 0x6F23_4FDE_CCD0_2FF1_i64, + 0x5BF2_97E3_B66B_BCEF_i64, // -164 + 0x58E9_0CB2_3D73_598E_i64, + 0x165B_ACB6_2B89_63F3_i64, // -163 + 0x4720_D6F4_FDF5_E13E_i64, + 0x4516_23C4_EFA1_1CC2_i64, // -162 + 0x71CE_24BB_2FEF_CECA_i64, + 0x3B56_9FA1_7F68_2E03_i64, // -161 + 0x5B0B_5095_BFF3_0BD5_i64, + 0x15DE_E61A_CC53_5803_i64, // -160 + 0x48D5_DA11_665C_0977_i64, + 0x2B18_B815_7042_ACCF_i64, // -159 + 0x7489_5CE8_A3C6_758B_i64, + 0x5E8D_F355_806A_AE18_i64, // -158 + 0x5D3A_B0BA_1C9E_C46F_i64, + 0x653E_5C44_66BB_BE7A_i64, // -157 + 0x4A95_5A2E_7D4B_D059_i64, + 0x3765_169D_1EFC_9861_i64, // -156 + 0x7755_5D17_2EDF_B3C2_i64, + 0x256E_8A94_FE60_F3CF_i64, // -155 + 0x5F77_7DAC_257F_C301_i64, + 0x6ABE_D543_FEB3_F63F_i64, // -154 + 0x4C5F_97BC_EACC_9C01_i64, + 0x3BCB_DDCF_FEF6_5E99_i64, // -153 + 0x7A32_8C61_77AD_C668_i64, + 0x5FAC_9619_97F0_975B_i64, // -152 + 0x61C2_09E7_92F1_6B86_i64, + 0x7FBD_44E1_465A_12AF_i64, // -151 + 0x4E34_D4B9_425A_BC6B_i64, + 0x7FCA_9D81_0514_DBBF_i64, // -150 + 0x7D21_545B_9D5D_FA46_i64, + 0x32DD_C8CE_6E87_C5FF_i64, // -149 + 0x641A_A9E2_E44B_2E9E_i64, + 0x5BE4_A0A5_2539_6B32_i64, // -148 + 0x5015_54B5_836F_587E_i64, + 0x7CB6_E6EA_842D_EF5C_i64, // -147 + 0x4011_1091_35F2_AD32_i64, + 0x3092_5255_368B_25E3_i64, // -146 + 0x6681_B41B_8984_4850_i64, + 0x4DB6_EA21_F0DE_A304_i64, // -145 + 0x5201_5CE2_D469_D373_i64, + 0x57C5_881B_2718_826A_i64, // -144 + 0x419A_B0B5_76BB_0F8F_i64, + 0x5FD1_39AF_527A_01EF_i64, // -143 + 0x68F7_8122_5791_B27F_i64, + 0x4C81_F5E5_50C3_364A_i64, // -142 + 0x53F9_341B_7941_5B99_i64, + 0x239B_2B1D_DA35_C508_i64, // -141 + 0x432D_C349_2DCD_E2E1_i64, + 0x02E2_88E4_AE91_6A6D_i64, // -140 + 0x6B7C_6BA8_4949_6B01_i64, + 0x516A_74A1_174F_10AE_i64, // -139 + 0x55FD_22ED_076D_EF34_i64, + 0x4121_F6E7_45D8_DA25_i64, // -138 + 0x44CA_8257_3924_BF5D_i64, + 0x1A81_9252_9E47_14EB_i64, // -137 + 0x6E10_D08B_8EA1_322E_i64, + 0x5D9C_1D50_FD3E_87DD_i64, // -136 + 0x580D_73A2_D880_F4F2_i64, + 0x17B0_1773_FDCB_9FE4_i64, // -135 + 0x4671_294F_139A_5D8E_i64, + 0x4626_7929_97D6_1984_i64, // -134 + 0x70B5_0EE4_EC2A_2F4A_i64, + 0x3D0A_5B75_BFBC_F59F_i64, // -133 + 0x5A2A_7250_BCEE_8C3B_i64, + 0x4A6E_AF91_6630_C47F_i64, // -132 + 0x4821_F50D_63F2_09C9_i64, + 0x21F2_260D_EB5A_36CC_i64, // -131 + 0x7369_8815_6CB6_760E_i64, + 0x6983_7016_455D_247A_i64, // -130 + 0x5C54_6CDD_F091_F80B_i64, + 0x6E02_C011_D117_5062_i64, // -129 + 0x49DD_23E4_C074_C66F_i64, + 0x719B_CCDB_0DAC_404E_i64, // -128 + 0x762E_9FD4_6721_3D7F_i64, + 0x68F9_47C4_E2AD_33B0_i64, // -127 + 0x5E8B_B310_5280_FDFF_i64, + 0x6D94_396A_4EF0_F627_i64, // -126 + 0x4BA2_F5A6_A867_3199_i64, + 0x3E10_2DEE_A58D_91B9_i64, // -125 + 0x7904_BC3D_DA3E_B5C2_i64, + 0x3019_E317_6F48_E927_i64, // -124 + 0x60D0_9697_E1CB_C49B_i64, + 0x4014_B5AC_5907_20EC_i64, // -123 + 0x4D73_ABAC_B4A3_03AF_i64, + 0x4CDD_5E23_7A6C_1A57_i64, // -122 + 0x7BEC_45E1_2104_D2B2_i64, + 0x47C8_969F_2A46_908A_i64, // -121 + 0x6323_6B1A_80D0_A88E_i64, + 0x6CA0_787F_5505_406F_i64, // -120 + 0x4F4F_88E2_00A6_ED3F_i64, + 0x0A19_F9FF_7737_66BF_i64, // -119 + 0x7EE5_A7D0_010B_1531_i64, + 0x5CF6_5CCB_F1F2_3DFE_i64, // -118 + 0x6584_8640_00D5_AA8E_i64, + 0x172B_7D6F_F4C1_CB32_i64, // -117 + 0x5136_D1CC_CD77_BBA4_i64, + 0x78EF_978C_C3CE_3C28_i64, // -116 + 0x40F8_A7D7_0AC6_2FB7_i64, + 0x13F2_DFA3_CFD8_3020_i64, // -115 + 0x67F4_3FBE_77A3_7F8B_i64, + 0x3984_9906_1959_E699_i64, // -114 + 0x5329_CC98_5FB5_FFA2_i64, + 0x6136_E0D1_ADE1_8548_i64, // -113 + 0x4287_D6E0_4C91_994F_i64, + 0x00F8_B3DA_F181_376D_i64, // -112 + 0x6A72_F166_E0E8_F54B_i64, + 0x1B27_862B_1C01_F247_i64, // -111 + 0x5528_C11F_1A53_F76F_i64, + 0x2F52_D1BC_1667_F506_i64, // -110 + 0x4420_9A7F_4843_2C59_i64, + 0x0C42_4163_451F_F738_i64, // -109 + 0x6D00_F732_0D38_46F4_i64, + 0x7A03_9BD2_0833_2526_i64, // -108 + 0x5733_F8F4_D760_38C3_i64, + 0x7B36_1641_A028_EA85_i64, // -107 + 0x45C3_2D90_AC4C_FA36_i64, + 0x2F5E_7834_8020_BB9E_i64, // -106 + 0x6F9E_AF4D_E07B_29F0_i64, + 0x4BCA_59ED_99CD_F8FC_i64, // -105 + 0x594B_BF71_8062_87F3_i64, + 0x563B_7B24_7B0B_2D96_i64, // -104 + 0x476F_CC5A_CD1B_9FF6_i64, + 0x11C9_2F50_626F_57AC_i64, // -103 + 0x724C_7A2A_E1C5_CCBD_i64, + 0x02DB_7EE7_03E5_5912_i64, // -102 + 0x5B70_61BB_E7D1_7097_i64, + 0x1BE2_CBEC_031D_E0DC_i64, // -101 + 0x4926_B496_530D_F3AC_i64, + 0x164F_0989_9C17_E716_i64, // -100 + 0x750A_BA8A_1E7C_B913_i64, + 0x3D4B_4275_C68C_A4F0_i64, // -99 + 0x5DA2_2ED4_E530_940F_i64, + 0x4AA2_9B91_6BA3_B726_i64, // -98 + 0x4AE8_2577_1DC0_7672_i64, + 0x6EE8_7C74_561C_9285_i64, // -97 + 0x77D9_D58B_62CD_8A51_i64, + 0x3173_FA53_BCFA_8408_i64, // -96 + 0x5FE1_77A2_B571_3B74_i64, + 0x278F_FB76_30C8_69A0_i64, // -95 + 0x4CB4_5FB5_5DF4_2F90_i64, + 0x1FA6_62C4_F3D3_87B3_i64, // -94 + 0x7ABA_32BB_C986_B280_i64, + 0x32A3_D13B_1FB8_D91F_i64, // -93 + 0x622E_8EFC_A138_8ECD_i64, + 0x0EE9_742F_4C93_E0E6_i64, // -92 + 0x4E8B_A596_E760_723D_i64, + 0x58BA_C359_0A0F_E71E_i64, // -91 + 0x7DAC_3C24_A567_1D2F_i64, + 0x412A_D228_1019_71C9_i64, // -90 + 0x6489_C9B6_EAB8_E426_i64, + 0x00EF_0E86_7347_8E3B_i64, // -89 + 0x506E_3AF8_BBC7_1CEB_i64, + 0x1A58_D86B_8F6C_71C9_i64, // -88 + 0x4058_2F2D_6305_B0BC_i64, + 0x1513_E056_0C56_C16E_i64, // -87 + 0x66F3_7EAF_04D5_E793_i64, + 0x3B53_0089_AD57_9BE2_i64, // -86 + 0x525C_6558_D0AB_1FA9_i64, + 0x15DC_006E_2446_164F_i64, // -85 + 0x41E3_8447_0D55_B2ED_i64, + 0x5E49_99F1_B69E_783F_i64, // -84 + 0x696C_06D8_1555_EB15_i64, + 0x7D42_8FE9_2430_C065_i64, // -83 + 0x5456_6BE0_1111_88DE_i64, + 0x3102_0CBA_835A_3384_i64, // -82 + 0x4378_564C_DA74_6D7E_i64, + 0x5A68_0A2E_CF7B_5C69_i64, // -81 + 0x6BF3_BD47_C3ED_7BFD_i64, + 0x770C_DD17_B25E_FA42_i64, // -80 + 0x565C_976C_9CBD_FCCB_i64, + 0x1270_B0DF_C1E5_9502_i64, // -79 + 0x4516_DF8A_16FE_63D5_i64, + 0x5B8D_5A4C_9B1E_10CE_i64, // -78 + 0x6E8A_FF43_57FD_6C89_i64, + 0x127B_C3AD_C4FC_E7B0_i64, // -77 + 0x586F_329C_4664_56D4_i64, + 0x0EC9_6957_D0CA_52F3_i64, // -76 + 0x46BF_5BB0_3850_4576_i64, + 0x3F07_8779_73D5_0F29_i64, // -75 + 0x7132_2C4D_26E6_D58A_i64, + 0x31A5_A58F_1FBB_4B75_i64, // -74 + 0x5A8E_89D7_5252_446E_i64, + 0x5AEA_EAD8_E62F_6F91_i64, // -73 + 0x4872_07DF_750E_9D25_i64, + 0x2F22_557A_51BF_8C74_i64, // -72 + 0x73E9_A632_54E4_2EA2_i64, + 0x1836_EF2A_1C65_AD86_i64, // -71 + 0x5CBA_EB5B_771C_F21B_i64, + 0x2CF8_BF54_E384_8AD2_i64, // -70 + 0x4A2F_22AF_927D_8E7C_i64, + 0x23FA_32AA_4F9D_3BDB_i64, // -69 + 0x76B1_D118_EA62_7D93_i64, + 0x5329_EAAA_18FB_92F8_i64, // -68 + 0x5EF4_A747_21E8_6476_i64, + 0x0F54_BBBB_472F_A8C6_i64, // -67 + 0x4BF6_EC38_E7ED_1D2B_i64, + 0x25DD_62FC_38F2_ED6C_i64, // -66 + 0x798B_138E_3FE1_C845_i64, + 0x22FB_D193_8E51_7BDF_i64, // -65 + 0x613C_0FA4_FFE7_D36A_i64, + 0x4F2F_DADC_71DA_C97F_i64, // -64 + 0x4DC9_A61D_9986_42BB_i64, + 0x58F3_157D_27E2_3ACC_i64, // -63 + 0x7C75_D695_C270_6AC5_i64, + 0x74B8_2261_D969_F7AD_i64, // -62 + 0x6391_7877_CEC0_556B_i64, + 0x1093_4EB4_ADEE_5FBE_i64, // -61 + 0x4FA7_9393_0BCD_1122_i64, + 0x4075_D890_8B25_1965_i64, // -60 + 0x7F72_85B8_12E1_B504_i64, + 0x00BC_8DB4_11D4_F56E_i64, // -59 + 0x65F5_37C6_7581_5D9C_i64, + 0x66FD_3E29_A7DD_9125_i64, // -58 + 0x5190_F96B_9134_4AE3_i64, + 0x6BFD_CB54_864A_DA84_i64, // -57 + 0x4140_C789_40F6_A24F_i64, + 0x6FFE_3C43_9EA2_486A_i64, // -56 + 0x6867_A5A8_67F1_03B2_i64, + 0x7FFD_2D38_FDD0_73DC_i64, // -55 + 0x5386_1E20_5327_3628_i64, + 0x6664_242D_97D9_F64A_i64, // -54 + 0x42D1_B1B3_75B8_F820_i64, + 0x51E9_B68A_DFE1_91D5_i64, // -53 + 0x6AE9_1C52_55F4_C034_i64, + 0x1CA9_2411_6635_B621_i64, // -52 + 0x5587_49DB_77F7_0029_i64, + 0x63BA_8341_1E91_5E81_i64, // -51 + 0x446C_3B15_F992_6687_i64, + 0x6962_029A_7EDA_B201_i64, // -50 + 0x6D79_F823_28EA_3DA6_i64, + 0x0F03_375D_97C4_5001_i64, // -49 + 0x5794_C682_8721_CAEB_i64, + 0x259C_2C4A_DFD0_4001_i64, // -48 + 0x4610_9ECE_D281_6F22_i64, + 0x5149_BD08_B30D_0001_i64, // -47 + 0x701A_97B1_50CF_1837_i64, + 0x3542_C80D_EB48_0001_i64, // -46 + 0x59AE_DFC1_0D72_79C5_i64, + 0x7768_A00B_22A0_0001_i64, // -45 + 0x47BF_1967_3DF5_2E37_i64, + 0x7920_8008_E880_0001_i64, // -44 + 0x72CB_5BD8_6321_E38C_i64, + 0x5B67_3341_7400_0001_i64, // -43 + 0x5BD5_E313_8281_82D6_i64, + 0x7C52_8F67_9000_0001_i64, // -42 + 0x4977_E8DC_6867_9BDF_i64, + 0x16A8_72B9_4000_0001_i64, // -41 + 0x758C_A7C7_0D72_92FE_i64, + 0x5773_EAC2_0000_0001_i64, // -40 + 0x5E0A_1FD2_7128_7598_i64, + 0x45F6_5568_0000_0001_i64, // -39 + 0x4B3B_4CA8_5A86_C47A_i64, + 0x04C5_1120_0000_0001_i64, // -38 + 0x785E_E10D_5DA4_6D90_i64, + 0x07A1_B500_0000_0001_i64, // -37 + 0x604B_E73D_E483_8AD9_i64, + 0x52E7_C400_0000_0001_i64, // -36 + 0x4D09_85CB_1D36_08AE_i64, + 0x0F1F_D000_0000_0001_i64, // -35 + 0x7B42_6FAB_61F0_0DE3_i64, + 0x31CC_8000_0000_0001_i64, // -34 + 0x629B_8C89_1B26_7182_i64, + 0x5B0A_0000_0000_0001_i64, // -33 + 0x4EE2_D6D4_15B8_5ACE_i64, + 0x7C08_0000_0000_0001_i64, // -32 + 0x7E37_BE20_22C0_914B_i64, + 0x1340_0000_0000_0001_i64, // -31 + 0x64F9_64E6_8233_A76F_i64, + 0x2900_0000_0000_0001_i64, // -30 + 0x50C7_83EB_9B5C_85F2_i64, + 0x5400_0000_0000_0001_i64, // -29 + 0x409F_9CBC_7C4A_04C2_i64, + 0x1000_0000_0000_0001_i64, // -28 + 0x6765_C793_FA10_079D_i64, + 0x0000_0000_0000_0001_i64, // -27 + 0x52B7_D2DC_C80C_D2E4_i64, + 0x0000_0000_0000_0001_i64, // -26 + 0x422C_A8B0_A00A_4250_i64, + 0x0000_0000_0000_0001_i64, // -25 + 0x69E1_0DE7_6676_D080_i64, + 0x0000_0000_0000_0001_i64, // -24 + 0x54B4_0B1F_852B_DA00_i64, + 0x0000_0000_0000_0001_i64, // -23 + 0x43C3_3C19_3756_4800_i64, + 0x0000_0000_0000_0001_i64, // -22 + 0x6C6B_935B_8BBD_4000_i64, + 0x0000_0000_0000_0001_i64, // -21 + 0x56BC_75E2_D631_0000_i64, + 0x0000_0000_0000_0001_i64, // -20 + 0x4563_9182_44F4_0000_i64, + 0x0000_0000_0000_0001_i64, // -19 + 0x6F05_B59D_3B20_0000_i64, + 0x0000_0000_0000_0001_i64, // -18 + 0x58D1_5E17_6280_0000_i64, + 0x0000_0000_0000_0001_i64, // -17 + 0x470D_E4DF_8200_0000_i64, + 0x0000_0000_0000_0001_i64, // -16 + 0x71AF_D498_D000_0000_i64, + 0x0000_0000_0000_0001_i64, // -15 + 0x5AF3_107A_4000_0000_i64, + 0x0000_0000_0000_0001_i64, // -14 + 0x48C2_7395_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -13 + 0x746A_5288_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -12 + 0x5D21_DBA0_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -11 + 0x4A81_7C80_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -10 + 0x7735_9400_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -9 + 0x5F5E_1000_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -8 + 0x4C4B_4000_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -7 + 0x7A12_0000_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -6 + 0x61A8_0000_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -5 + 0x4E20_0000_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -4 + 0x7D00_0000_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -3 + 0x6400_0000_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -2 + 0x5000_0000_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // -1 + 0x4000_0000_0000_0000_i64, + 0x0000_0000_0000_0001_i64, // 0 + 0x6666_6666_6666_6666_i64, + 0x3333_3333_3333_3334_i64, // 1 + 0x51EB_851E_B851_EB85_i64, + 0x0F5C_28F5_C28F_5C29_i64, // 2 + 0x4189_374B_C6A7_EF9D_i64, + 0x5916_872B_020C_49BB_i64, // 3 + 0x68DB_8BAC_710C_B295_i64, + 0x74F0_D844_D013_A92B_i64, // 4 + 0x53E2_D623_8DA3_C211_i64, + 0x43F3_E037_0CDC_8755_i64, // 5 + 0x431B_DE82_D7B6_34DA_i64, + 0x698F_E692_70B0_6C44_i64, // 6 + 0x6B5F_CA6A_F2BD_215E_i64, + 0x0F4C_A41D_811A_46D4_i64, // 7 + 0x55E6_3B88_C230_E77E_i64, + 0x3F70_834A_CDAE_9F10_i64, // 8 + 0x44B8_2FA0_9B5A_52CB_i64, + 0x4C5A_02A2_3E25_4C0D_i64, // 9 + 0x6DF3_7F67_5EF6_EADF_i64, + 0x2D5C_D103_96A2_1347_i64, // 10 + 0x57F5_FF85_E592_557F_i64, + 0x3DE3_DA69_454E_75D3_i64, // 11 + 0x465E_6604_B7A8_4465_i64, + 0x7E4F_E1ED_D10B_9175_i64, // 12 + 0x7097_09A1_25DA_0709_i64, + 0x4A19_697C_81AC_1BEF_i64, // 13 + 0x5A12_6E1A_84AE_6C07_i64, + 0x54E1_2130_67BC_E326_i64, // 14 + 0x480E_BE7B_9D58_566C_i64, + 0x43E7_4DC0_52FD_8285_i64, // 15 + 0x734A_CA5F_6226_F0AD_i64, + 0x530B_AF9A_1E62_6A6D_i64, // 16 + 0x5C3B_D519_1B52_5A24_i64, + 0x426F_BFAE_7EB5_21F1_i64, // 17 + 0x49C9_7747_490E_AE83_i64, + 0x4EBF_CC8B_9890_E7F4_i64, // 18 + 0x760F_253E_DB4A_B0D2_i64, + 0x4ACC_7A78_F41B_0CBA_i64, // 19 + 0x5E72_8432_4908_8D75_i64, + 0x223D_2EC7_29AF_3D62_i64, // 20 + 0x4B8E_D028_3A6D_3DF7_i64, + 0x34FD_BF05_BAF2_9781_i64, // 21 + 0x78E4_8040_5D7B_9658_i64, + 0x54C9_31A2_C4B7_58CF_i64, // 22 + 0x60B6_CD00_4AC9_4513_i64, + 0x5D6D_C14F_03C5_E0A5_i64, // 23 + 0x4D5F_0A66_A23A_9DA9_i64, + 0x3124_9AA5_9C9E_4D51_i64, // 24 + 0x7BCB_43D7_69F7_62A8_i64, + 0x4EA0_F76F_60FD_4882_i64, // 25 + 0x6309_0312_BB2C_4EED_i64, + 0x254D_92BF_80CA_A068_i64, // 26 + 0x4F3A_68DB_C8F0_3F24_i64, + 0x1DD7_A899_33D5_4D20_i64, // 27 + 0x7EC3_DAF9_4180_6506_i64, + 0x62F2_A75B_8622_1500_i64, // 28 + 0x6569_7BFA_9ACD_1D9F_i64, + 0x025B_B916_04E8_10CD_i64, // 29 + 0x5121_2FFB_AF0A_7E18_i64, + 0x6849_60DE_6A53_40A4_i64, // 30 + 0x40E7_5996_25A1_FE7A_i64, + 0x203A_B3E5_21DC_33B6_i64, // 31 + 0x67D8_8F56_A29C_CA5D_i64, + 0x19F7_863B_6960_52BD_i64, // 32 + 0x5313_A5DE_E87D_6EB0_i64, + 0x7B2C_6B62_BAB3_7564_i64, // 33 + 0x4276_1E4B_ED31_255A_i64, + 0x2F56_BC4E_FBC2_C450_i64, // 34 + 0x6A56_96DF_E1E8_3BC3_i64, + 0x6557_93B1_92D1_3A1A_i64, // 35 + 0x5512_124C_B4B9_C969_i64, + 0x3779_42F4_7574_2E7B_i64, // 36 + 0x440E_750A_2A2E_3ABA_i64, + 0x5F94_3590_5DF6_8B96_i64, // 37 + 0x6CE3_EE76_A9E3_912A_i64, + 0x65B9_EF4D_6324_1289_i64, // 38 + 0x571C_BEC5_54B6_0DBB_i64, + 0x6AFB_25D7_8283_4207_i64, // 39 + 0x45B0_989D_DD5E_7163_i64, + 0x08C8_EB12_CECF_6806_i64, // 40 + 0x6F80_F42F_C897_1BD1_i64, + 0x5ADB_11B7_B14B_D9A3_i64, // 41 + 0x5933_F68C_A078_E30E_i64, + 0x157C_0E2C_8DD6_47B5_i64, // 42 + 0x475C_C53D_4D2D_8271_i64, + 0x5DFC_D823_A4AB_6C91_i64, // 43 + 0x722E_0862_1515_9D82_i64, + 0x632E_269F_6DDF_141B_i64, // 44 + 0x5B58_06B4_DDAA_E468_i64, + 0x4F58_1EE5_F17F_4349_i64, // 45 + 0x4913_3890_B155_8386_i64, + 0x72AC_E584_C132_9C3B_i64, // 46 + 0x74EB_8DB4_4EEF_38D7_i64, + 0x6AAE_3C07_9B84_2D2A_i64, // 47 + 0x5D89_3E29_D8BF_60AC_i64, + 0x5558_3006_1603_5755_i64, // 48 + 0x4AD4_31BB_13CC_4D56_i64, + 0x7779_C004_DE69_12AB_i64, // 49 + 0x77B9_E92B_52E0_7BBE_i64, + 0x258F_99A1_63DB_5111_i64, // 50 + 0x5FC7_EDBC_424D_2FCB_i64, + 0x37A6_1481_1CAF_740D_i64, // 51 + 0x4C9F_F163_683D_BFD5_i64, + 0x7951_AA00_E3BF_900B_i64, // 52 + 0x7A99_8238_A6C9_32EF_i64, + 0x754F_7667_D2CC_19AB_i64, // 53 + 0x6214_682D_523A_8F26_i64, + 0x2AA5_F853_0F09_AE22_i64, // 54 + 0x4E76_B9BD_DB62_0C1E_i64, + 0x5551_9375_A5A1_581B_i64, // 55 + 0x7D8A_C2C9_5F03_4697_i64, + 0x3BB5_B8BC_3C35_59C5_i64, // 56 + 0x646F_023A_B269_0545_i64, + 0x7C91_6096_9691_149E_i64, // 57 + 0x5058_CE95_5B87_376B_i64, + 0x16DA_B3AB_ABA7_43B2_i64, // 58 + 0x4047_0BAA_AF9F_5F88_i64, + 0x78AE_F622_EFB9_02F5_i64, // 59 + 0x66D8_12AA_B298_98DB_i64, + 0x0DE4_BD04_B2C1_9E54_i64, // 60 + 0x5246_7555_5BAD_4715_i64, + 0x57EA_30D0_8F01_4B76_i64, // 61 + 0x41D1_F777_7C8A_9F44_i64, + 0x4654_F3DA_0C01_092C_i64, // 62 + 0x694F_F258_C744_3207_i64, + 0x23BB_1FC3_4668_0EAC_i64, // 63 + 0x543F_F513_D29C_F4D2_i64, + 0x4FC8_E635_D1EC_D88A_i64, // 64 + 0x4366_5DA9_754A_5D75_i64, + 0x263A_51C4_A7F0_AD3B_i64, // 65 + 0x6BD6_FC42_5543_C8BB_i64, + 0x56C3_B607_731A_AEC4_i64, // 66 + 0x5645_969B_7769_6D62_i64, + 0x789C_919F_8F48_8BD0_i64, // 67 + 0x4504_787C_5F87_8AB5_i64, + 0x46E3_A7B2_D906_D640_i64, // 68 + 0x6E6D_8D93_CC0C_1122_i64, + 0x3E39_0C51_5B3E_239A_i64, // 69 + 0x5857_A476_3CD6_741B_i64, + 0x4B60_D6A7_7C31_B615_i64, // 70 + 0x46AC_8391_CA45_29AF_i64, + 0x55E7_121F_968E_2B44_i64, // 71 + 0x7114_05B6_106E_A919_i64, + 0x0971_B698_F0E3_786D_i64, // 72 + 0x5A76_6AF8_0D25_5414_i64, + 0x078E_2BAD_8D82_C6BD_i64, // 73 + 0x485E_BBF9_A41D_DCDC_i64, + 0x6C71_BC8A_D79B_D231_i64, // 74 + 0x73CA_C65C_39C9_6161_i64, + 0x2D82_C744_8C2C_8382_i64, // 75 + 0x5CA2_3849_C7D4_4DE7_i64, + 0x3E02_3903_A356_CF9B_i64, // 76 + 0x4A1B_603B_0643_7185_i64, + 0x7E68_2D9C_82AB_D949_i64, // 77 + 0x7692_3391_A39F_1C09_i64, + 0x4A40_48FA_6AAC_8EDB_i64, // 78 + 0x5EDB_5C74_82E5_B007_i64, + 0x5500_3A61_EEF0_7249_i64, // 79 + 0x4BE2_B05D_3584_8CD2_i64, + 0x7733_61E7_F259_F507_i64, // 80 + 0x796A_B3C8_55A0_E151_i64, + 0x3EB8_9CA6_508F_EE71_i64, // 81 + 0x6122_296D_114D_810D_i64, + 0x7EFA_16EB_73A6_585B_i64, // 82 + 0x4DB4_EDF0_DAA4_673E_i64, + 0x3261_ABEF_8FB8_46AF_i64, // 83 + 0x7C54_AFE7_C43A_3ECA_i64, + 0x1D69_1318_E5F3_A44B_i64, // 84 + 0x6376_F31F_D02E_98A1_i64, + 0x6454_0F47_1E5C_836F_i64, // 85 + 0x4F92_5C19_7358_7A1B_i64, + 0x0376_729F_4B7D_35F3_i64, // 86 + 0x7F50_935B_EBC0_C35E_i64, + 0x38BD_8432_1261_EFEB_i64, // 87 + 0x65DA_0F7C_BC9A_35E5_i64, + 0x13CA_D028_0EB4_BFEF_i64, // 88 + 0x517B_3F96_FD48_2B1D_i64, + 0x5CA2_4020_0BC3_CCBF_i64, // 89 + 0x412F_6612_6439_BC17_i64, + 0x63B5_0019_A303_0A33_i64, // 90 + 0x684B_D683_D38F_9359_i64, + 0x1F88_0029_04D1_A9EA_i64, // 91 + 0x536F_DECF_DC72_DC47_i64, + 0x32D3_3354_03DA_EE55_i64, // 92 + 0x42BF_E573_16C2_49D2_i64, + 0x5BDC_2910_0315_8B77_i64, // 93 + 0x6ACC_A251_BE03_A951_i64, + 0x12F9_DB4C_D1BC_1258_i64, // 94 + 0x5570_81DA_FE69_5440_i64, + 0x7594_AF70_A7C9_A847_i64, // 95 + 0x445A_017B_FEBA_A9CD_i64, + 0x4476_F2C0_863A_ED06_i64, // 96 + 0x6D5C_CF2C_CAC4_42E2_i64, + 0x3A57_EACD_A391_7B3C_i64, // 97 + 0x577D_728A_3BD0_3581_i64, + 0x7B79_88A4_82DA_C8FD_i64, // 98 + 0x45FD_F53B_630C_F79B_i64, + 0x15FA_D3B6_CF15_6D97_i64, // 99 + 0x6FFC_BB92_3814_BF5E_i64, + 0x565E_1F8A_E4EF_15BE_i64, // 100 + 0x5996_FC74_F9AA_32B2_i64, + 0x11E4_E608_B725_AAFF_i64, // 101 + 0x47AB_FD2A_6154_F55B_i64, + 0x27EA_51A0_9284_88CC_i64, // 102 + 0x72AC_C843_CEEE_555E_i64, + 0x7310_829A_8407_4146_i64, // 103 + 0x5BBD_6D03_0BF1_DDE5_i64, + 0x4273_9BAE_D005_CDD2_i64, // 104 + 0x4964_5735_A327_E4B7_i64, + 0x4EC2_E2F2_4004_A4A8_i64, // 105 + 0x756D_5855_D1D9_6DF2_i64, + 0x4AD1_6B1D_333A_A10C_i64, // 106 + 0x5DF1_1377_DB14_57F5_i64, + 0x2241_227D_C295_4DA3_i64, // 107 + 0x4B27_42C6_48DD_132A_i64, + 0x4E9A_81FE_3544_3E1C_i64, // 108 + 0x783E_D13D_4161_B844_i64, + 0x175D_9CC9_EED3_9694_i64, // 109 + 0x6032_40FD_CDE7_C69C_i64, + 0x7917_B0A1_8BDC_7876_i64, // 110 + 0x4CF5_00CB_0B1F_D217_i64, + 0x1412_F3B4_6FE3_9392_i64, // 111 + 0x7B21_9ADE_7832_E9BE_i64, + 0x5351_85ED_7FD2_85B6_i64, // 112 + 0x6281_48B1_F9C2_5498_i64, + 0x42A7_9E57_9975_37C5_i64, // 113 + 0x4ECD_D3C1_949B_76E0_i64, + 0x3552_E512_E12A_9304_i64, // 114 + 0x7E16_1F9C_20F8_BE33_i64, + 0x6EEB_081E_3510_EB39_i64, // 115 + 0x64DE_7FB0_1A60_9829_i64, + 0x3F22_6CE4_F740_BC2E_i64, // 116 + 0x50B1_FFC0_151A_1354_i64, + 0x3281_F0B7_2C33_C9BE_i64, // 117 + 0x408E_6633_4414_DC43_i64, + 0x4201_8D5F_568F_D498_i64, // 118 + 0x674A_3D1E_D354_939F_i64, + 0x1CCF_4898_8A7F_BA8D_i64, // 119 + 0x52A1_CA7F_0F76_DC7F_i64, + 0x30A5_D3AD_3B99_620B_i64, // 120 + 0x421B_0865_A5F8_B065_i64, + 0x73B7_DC8A_9614_4E6F_i64, // 121 + 0x69C4_DA3C_3CC1_1A3C_i64, + 0x52BF_C744_2353_B0B1_i64, // 122 + 0x549D_7B63_63CD_AE96_i64, + 0x7566_3903_4F76_26F4_i64, // 123 + 0x43B1_2F82_B63E_2545_i64, + 0x4451_C735_D92B_525D_i64, // 124 + 0x6C4E_B26A_BD30_3BA2_i64, + 0x3A1C_71EF_C1DE_EA2E_i64, // 125 + 0x56A5_5B88_9759_C94E_i64, + 0x61B0_5B26_34B2_54F2_i64, // 126 + 0x4551_1606_DF7B_0772_i64, + 0x1AF3_7C1E_908E_AA5B_i64, // 127 + 0x6EE8_233E_325E_7250_i64, + 0x2B1F_2CFD_B417_76F8_i64, // 128 + 0x58B9_B5CB_5B7E_C1D9_i64, + 0x6F4C_23FE_29AC_5F2D_i64, // 129 + 0x46FA_F7D5_E2CB_CE47_i64, + 0x72A3_4FFE_87BD_18F1_i64, // 130 + 0x7191_8C89_6ADF_B073_i64, + 0x0438_7FFD_A5FB_5B1B_i64, // 131 + 0x5ADA_D6D4_557F_C05C_i64, + 0x0360_6664_84C9_15AF_i64, // 132 + 0x48AF_1243_7799_66B0_i64, + 0x02B3_851D_3707_448C_i64, // 133 + 0x744B_506B_F28F_0AB3_i64, + 0x1DEC_082E_BE72_0746_i64, // 134 + 0x5D09_0D23_2872_6EF5_i64, + 0x64BC_D358_985B_3905_i64, // 135 + 0x4A6D_A41C_205B_8BF7_i64, + 0x6A30_A913_AD15_C738_i64, // 136 + 0x7715_D360_33C5_ACBF_i64, + 0x5D1A_A81F_7B56_0B8C_i64, // 137 + 0x5F44_A919_C304_8A32_i64, + 0x7DAE_ECE5_FC44_D609_i64, // 138 + 0x4C36_EDAE_359D_3B5B_i64, + 0x7E25_8A51_969D_7808_i64, // 139 + 0x79F1_7C49_EF61_F893_i64, + 0x16A2_76E8_F0FB_F33F_i64, // 140 + 0x618D_FD07_F2B4_C6DC_i64, + 0x121B_9253_F3FC_C299_i64, // 141 + 0x4E0B_30D3_2890_9F16_i64, + 0x41AF_A843_2997_0214_i64, // 142 + 0x7CDE_B485_0DB4_31BD_i64, + 0x4F7F_739E_A8F1_9CED_i64, // 143 + 0x63E5_5D37_3E29_C164_i64, + 0x3F99_294B_BA5A_E3F1_i64, // 144 + 0x4FEA_B0F8_FE87_CDE9_i64, + 0x7FAD_BAA2_FB7B_E98D_i64, // 145 + 0x7FDD_E7F4_CA72_E30F_i64, + 0x7F7C_5DD1_925F_DC15_i64, // 146 + 0x664B_1FF7_085B_E8D9_i64, + 0x4C63_7E41_41E6_49AB_i64, // 147 + 0x51D5_B32C_06AF_ED7A_i64, + 0x704F_9834_34B8_3AEF_i64, // 148 + 0x4177_C289_9EF3_2462_i64, + 0x26A6_135C_F6F9_C8BF_i64, // 149 + 0x68BF_9DA8_FE51_D3D0_i64, + 0x3DD6_8561_8B29_4132_i64, // 150 + 0x53CC_7E20_CB74_A973_i64, + 0x4B12_044E_08ED_CDC2_i64, // 151 + 0x4309_FE80_A2C3_BAC2_i64, + 0x6F41_9D0B_3A57_D7CE_i64, // 152 + 0x6B43_30CD_D139_2AD1_i64, + 0x3202_94DE_C3BF_BFB0_i64, // 153 + 0x55CF_5A3E_40FA_88A7_i64, + 0x419B_AA4B_CFCC_995A_i64, // 154 + 0x44A5_E1CB_672E_D3B9_i64, + 0x1AE2_EEA3_0CA3_ADE1_i64, // 155 + 0x6DD6_3612_3EB1_52C1_i64, + 0x77D1_7DD1_ADD2_AFCF_i64, // 156 + 0x57DE_91A8_3227_7567_i64, + 0x7974_64A7_BE42_263F_i64, // 157 + 0x464B_A7B9_C1B9_2AB9_i64, + 0x4790_5086_31CE_84FF_i64, // 158 + 0x7079_0C5C_6928_445C_i64, + 0x0C1A_1A70_4FB0_D4CC_i64, // 159 + 0x59FA_7049_EDB9_D049_i64, + 0x567B_4859_D95A_43D6_i64, // 160 + 0x47FB_8D07_F161_736E_i64, + 0x11FC_39E1_7AAE_9CAB_i64, // 161 + 0x732C_14D9_8235_857D_i64, + 0x032D_2968_C44A_9445_i64, // 162 + 0x5C23_43E1_34F7_9DFD_i64, + 0x4F57_5453_D03B_A9D1_i64, // 163 + 0x49B5_CFE7_5D92_E4CA_i64, + 0x72AC_4376_402F_BB0E_i64, // 164 + 0x75EF_B30B_C8EB_07AB_i64, + 0x0446_D256_CD19_2B49_i64, // 165 + 0x5E59_5C09_6D88_D2EF_i64, + 0x1D05_7512_3DAD_BC3A_i64, // 166 + 0x4B7A_B007_8AD3_DBF2_i64, + 0x4A6A_C40E_97BE_302F_i64, // 167 + 0x78C4_4CD8_DE1F_C650_i64, + 0x7711_39B0_F2C9_E6B1_i64, // 168 + 0x609D_0A47_1819_6B73_i64, + 0x78DA_948D_8F07_EBC1_i64, // 169 + 0x4D4A_6E9F_467A_BC5C_i64, + 0x60AE_DD3E_0C06_5634_i64, // 170 + 0x7BAA_4A98_70C4_6094_i64, + 0x344A_FB96_79A3_BD20_i64, // 171 + 0x62EE_A213_8D69_E6DD_i64, + 0x103B_FC78_614F_CA80_i64, // 172 + 0x4F25_4E76_0ABB_1F17_i64, + 0x2696_6393_810C_A200_i64, // 173 + 0x7EA2_1723_445E_9825_i64, + 0x2423_D285_9B47_6999_i64, // 174 + 0x654E_78E9_037E_E01D_i64, + 0x69B6_4204_7C39_2148_i64, // 175 + 0x510B_93ED_9C65_8017_i64, + 0x6E2B_6803_9694_1AA0_i64, // 176 + 0x40D6_0FF1_49EA_CCDF_i64, + 0x71BC_5336_1210_154D_i64, // 177 + 0x67BC_E64E_DCAA_E166_i64, + 0x1C60_8523_5019_BBAE_i64, // 178 + 0x52FD_850B_E3BB_E784_i64, + 0x7D1A_041C_4014_9625_i64, // 179 + 0x4264_6A6F_E963_1F9D_i64, + 0x4A7B_367D_0010_781D_i64, // 180 + 0x6A3A_43E6_4238_3295_i64, + 0x5D91_F0C8_001A_59C8_i64, // 181 + 0x54FB_6985_01C6_8EDE_i64, + 0x17A7_F3D3_3348_47D4_i64, // 182 + 0x43FC_546A_67D2_0BE4_i64, + 0x7953_2975_C2A0_3976_i64, // 183 + 0x6CC6_ED77_0C83_463B_i64, + 0x0EEB_7589_3766_C256_i64, // 184 + 0x5705_8AC5_A39C_382F_i64, + 0x2589_2AD4_2C52_3512_i64, // 185 + 0x459E_089E_1C7C_F9BF_i64, + 0x37A0_EF10_2374_F742_i64, // 186 + 0x6F63_40FC_FA61_8F98_i64, + 0x5901_7E80_38BB_2536_i64, // 187 + 0x591C_33FD_951A_D946_i64, + 0x7A67_9866_93C8_EA91_i64, // 188 + 0x4749_C331_4415_7A9F_i64, + 0x151F_AD1E_DCA0_BBA8_i64, // 189 + 0x720F_9EB5_39BB_F765_i64, + 0x0832_AE97_C767_92A5_i64, // 190 + 0x5B3F_B22A_9496_5F84_i64, + 0x068E_F213_05EC_7551_i64, // 191 + 0x48FF_C1BB_AA11_E603_i64, + 0x1ED8_C1A8_D189_F774_i64, // 192 + 0x74CC_692C_434F_D66B_i64, + 0x4AF4_690E_1C0F_F253_i64, // 193 + 0x5D70_5423_690C_AB89_i64, + 0x225D_20D8_1673_2843_i64, // 194 + 0x4AC0_434F_873D_5607_i64, + 0x3517_4D79_AB8F_5369_i64, // 195 + 0x779A_054C_0B95_5672_i64, + 0x21BE_E25C_45B2_1F0E_i64, // 196 + 0x5FAE_6AA3_3C77_785B_i64, + 0x3498_B516_9E28_18D8_i64, // 197 + 0x4C8B_8882_96C5_F9E2_i64, + 0x5D46_F745_4B53_4713_i64, // 198 + 0x7A78_DA6A_8AD6_5C9D_i64, + 0x7BA4_BED5_4552_0B52_i64, // 199 + 0x61FA_4855_3BDE_B07E_i64, + 0x2FB6_FF11_0441_A2A8_i64, // 200 + 0x4E61_D377_6318_8D31_i64, + 0x72F8_CC0D_9D01_4EED_i64, // 201 + 0x7D69_5258_9E8D_AEB6_i64, + 0x1E5A_E015_C802_17E1_i64, // 202 + 0x6454_41E0_7ED7_BEF8_i64, + 0x1848_B344_A001_ACB4_i64, // 203 + 0x5043_67E6_CBDF_CBF9_i64, + 0x603A_2903_B334_8A2A_i64, // 204 + 0x4035_ECB8_A319_6FFB_i64, + 0x002E_8736_28F6_D4EE_i64, // 205 + 0x66BC_ADF4_3828_B32B_i64, + 0x19E4_0B89_DB24_87E3_i64, // 206 + 0x5230_8B29_C686_F5BC_i64, + 0x14B6_6FA1_7C1D_3983_i64, // 207 + 0x41C0_6F54_9ED2_5E30_i64, + 0x1091_F2E7_967D_C79C_i64, // 208 + 0x6933_E554_3150_96B3_i64, + 0x341C_B7D8_F0C9_3F5F_i64, // 209 + 0x5429_8443_5AA6_DEF5_i64, + 0x767D_5FE0_C0A0_FF80_i64, // 210 + 0x4354_69CF_7BB8_B25E_i64, + 0x2B97_7FE7_0080_CC66_i64, // 211 + 0x6BBA_42E5_92C1_1D63_i64, + 0x5F58_CCA4_CD9A_E0A3_i64, // 212 + 0x562E_9BEA_DBCD_B11C_i64, + 0x4C47_0A1D_7148_B3B6_i64, // 213 + 0x44F2_1655_7CA4_8DB0_i64, + 0x3D05_A1B1_276D_5C92_i64, // 214 + 0x6E50_23BB_FAA0_E2B3_i64, + 0x7B3C_35E8_3F15_60E9_i64, // 215 + 0x5840_1C96_621A_4EF6_i64, + 0x2F63_5E53_65AA_B3ED_i64, // 216 + 0x4699_B078_4E7B_725E_i64, + 0x591C_4B75_EAEE_F658_i64, // 217 + 0x70F5_E726_E3F8_B6FD_i64, + 0x74FA_1256_44B1_8A26_i64, // 218 + 0x5A5E_5285_832D_5F31_i64, + 0x43FB_41DE_9D5A_D4EB_i64, // 219 + 0x484B_7537_9C24_4C27_i64, + 0x4FFC_34B2_177B_DD89_i64, // 220 + 0x73AB_EEBF_603A_1372_i64, + 0x4CC6_BAB6_8BF9_6274_i64, // 221 + 0x5C89_8BCC_4CFB_42C2_i64, + 0x0A38_955E_D661_1B90_i64, // 222 + 0x4A07_A309_D72F_689B_i64, + 0x21C6_DDE5_784D_AFA7_i64, // 223 + 0x7672_9E76_2518_A75E_i64, + 0x693E_2FD5_8D49_190B_i64, // 224 + 0x5EC2_185E_8413_B918_i64, + 0x5431_BFDE_0AA0_E0D5_i64, // 225 + 0x4BCE_79E5_3676_2DAD_i64, + 0x29C1_664B_3BB3_E711_i64, // 226 + 0x794A_5CA1_F0BD_15E2_i64, + 0x0F9B_D6DE_C5EC_A4E8_i64, // 227 + 0x6108_4A1B_26FD_AB1B_i64, + 0x2616_457F_04BD_50BA_i64, // 228 + 0x4DA0_3B48_EBFE_227C_i64, + 0x1E78_3798_D097_73C8_i64, // 229 + 0x7C33_920E_4663_6A60_i64, + 0x30C0_58F4_80F2_52D9_i64, // 230 + 0x635C_74D8_384F_884D_i64, + 0x0D66_AD90_6728_4247_i64, // 231 + 0x4F7D_2A46_9372_D370_i64, + 0x711E_F140_5286_9B6C_i64, // 232 + 0x7F2E_AA0A_8584_8581_i64, + 0x34FE_4ECD_50D7_5F14_i64, // 233 + 0x65BE_EE6E_D136_D134_i64, + 0x2A65_0BD7_73DF_7F43_i64, // 234 + 0x5165_8B8B_DA92_40F6_i64, + 0x551D_A312_C319_329C_i64, // 235 + 0x411E_093C_AEDB_672B_i64, + 0x5DB1_4F42_35AD_C217_i64, // 236 + 0x6830_0EC7_7E2B_D845_i64, + 0x7C4E_E536_BC49_368A_i64, // 237 + 0x5359_A56C_64EF_E037_i64, + 0x7D0B_EA92_303A_9208_i64, // 238 + 0x42AE_1DF0_50BF_E693_i64, + 0x173C_BBA8_2695_41A0_i64, // 239 + 0x6AB0_2FE6_E799_70EB_i64, + 0x3EC7_92A6_A422_029A_i64, // 240 + 0x5559_BFEB_EC7A_C0BC_i64, + 0x3239_421E_E9B4_CEE1_i64, // 241 + 0x4447_CCBC_BD2F_0096_i64, + 0x5B61_01B2_5490_A581_i64, // 242 + 0x6D3F_ADFA_C84B_3424_i64, + 0x2BCE_691D_541A_A268_i64, // 243 + 0x5766_24C8_A03C_29B6_i64, + 0x563E_BA7D_DCE2_1B87_i64, // 244 + 0x45EB_50A0_8030_215E_i64, + 0x7832_2ECB_171B_4939_i64, // 245 + 0x6FDE_E767_3380_3564_i64, + 0x59E9_E478_24F8_7527_i64, // 246 + 0x597F_1F85_C2CC_F783_i64, + 0x6187_E9F9_B72D_2A86_i64, // 247 + 0x4798_E604_9BD7_2C69_i64, + 0x346C_BB2E_2C24_2205_i64, // 248 + 0x728E_3CD4_2C8B_7A42_i64, + 0x20AD_F849_E039_D007_i64, // 249 + 0x5BA4_FD76_8A09_2E9B_i64, + 0x33BE_603B_19C7_D99F_i64, // 250 + 0x4950_CAC5_3B3A_8BAF_i64, + 0x42FE_B362_7B06_47B3_i64, // 251 + 0x754E_113B_91F7_45E5_i64, + 0x5197_856A_5E70_72B8_i64, // 252 + 0x5DD8_0DC9_4192_9E51_i64, + 0x27AC_6ABB_7EC0_5BC6_i64, // 253 + 0x4B13_3E3A_9ADB_B1DA_i64, + 0x52F0_5562_CBCD_1638_i64, // 254 + 0x781E_C9F7_5E2C_4FC4_i64, + 0x1E4D_556A_DFAE_89F3_i64, // 255 + 0x6018_A192_B1BD_0C9C_i64, + 0x7EA4_4455_7FBE_D4C3_i64, // 256 + 0x4CE0_8142_27CA_707D_i64, + 0x4BB6_9D11_32FF_109C_i64, // 257 + 0x7B00_CED0_3FAA_4D95_i64, + 0x5F8A_94E8_5198_1A93_i64, // 258 + 0x6267_0BD9_CC88_3E11_i64, + 0x32D5_43ED_0E13_4875_i64, // 259 + 0x4EB8_D647_D6D3_64DA_i64, + 0x5BDD_CFF0_D80F_6D2B_i64, // 260 + 0x7DF4_8A0C_8AEB_D491_i64, + 0x12FC_7FE7_C018_AEAB_i64, // 261 + 0x64C3_A1A3_A256_43A7_i64, + 0x28C9_FFEC_99AD_5889_i64, // 262 + 0x509C_814F_B511_CFB9_i64, + 0x0707_FFF0_7AF1_13A1_i64, // 263 + 0x407D_343F_C40E_3FC7_i64, + 0x1F39_998D_2F27_42E7_i64, // 264 + 0x672E_B9FF_A016_CC71_i64, + 0x7EC2_8F48_4B72_04A4_i64, // 265 + 0x528B_C7FF_B345_705B_i64, + 0x189B_A5D3_6F8E_6A1D_i64, // 266 + 0x4209_6CCC_8F6A_C048_i64, + 0x7A16_1E42_BFA5_21B1_i64, // 267 + 0x69A8_AE14_18AA_CD41_i64, + 0x4356_96D1_32A1_CF81_i64, // 268 + 0x5486_F1A9_AD55_7101_i64, + 0x1C45_4574_2881_72CE_i64, // 269 + 0x439F_27BA_F111_2734_i64, + 0x169D_D129_BA01_28A5_i64, // 270 + 0x6C31_D92B_1B4E_A520_i64, + 0x242F_B50F_9001_DAA1_i64, // 271 + 0x568E_4755_AF72_1DB3_i64, + 0x368C_90D9_4001_7BB4_i64, // 272 + 0x453E_9F77_BF8E_7E29_i64, + 0x120A_0D7A_999A_C95D_i64, // 273 + 0x6ECA_98BF_98E3_FD0E_i64, + 0x5010_1590_F5C4_7561_i64, // 274 + 0x58A2_13CC_7A4F_FDA5_i64, + 0x2673_4473_F7D0_5DE8_i64, // 275 + 0x46E8_0FD6_C83F_FE1D_i64, + 0x6B8F_69F6_5FD9_E4B9_i64, // 276 + 0x7173_4C8A_D9FF_FCFC_i64, + 0x45B2_4323_CC8F_D45C_i64, // 277 + 0x5AC2_A3A2_47FF_FD96_i64, + 0x6AF5_0283_0A0C_A9E3_i64, // 278 + 0x489B_B61B_6CCC_CADF_i64, + 0x08C4_0202_6E70_87E9_i64, // 279 + 0x742C_5692_47AE_1164_i64, + 0x746C_D003_E3E7_3FDB_i64, // 280 + 0x5CF0_4541_D2F1_A783_i64, + 0x76BD_7336_4FEC_3315_i64, // 281 + 0x4A59_D101_758E_1F9C_i64, + 0x5EFD_F5C5_0CBC_F5AB_i64, // 282 + 0x76F6_1B35_88E3_65C7_i64, + 0x4B2F_EFA1_ADFB_22AB_i64, // 283 + 0x5F2B_48F7_A0B5_EB06_i64, + 0x08F3_261A_F195_B555_i64, // 284 + 0x4C22_A0C6_1A2B_226B_i64, + 0x20C2_84E2_5ADE_2AAB_i64, // 285 + 0x79D1_013C_F6AB_6A45_i64, + 0x1AD0_D49D_5E30_4444_i64, // 286 + 0x6174_00FD_9222_BB6A_i64, + 0x48A7_107D_E4F3_69D0_i64, // 287 + 0x4DF6_6731_41B5_62BB_i64, + 0x53B8_D9FE_50C2_BB0D_i64, // 288 + 0x7CBD_71E8_6922_3792_i64, + 0x52C1_5CCA_1AD1_2B48_i64, // 289 + 0x63CA_C186_BA81_C60E_i64, + 0x7567_7D6E_7BDA_8906_i64, // 290 + 0x4FD5_679E_FB9B_04D8_i64, + 0x5DEC_6458_6315_3A6C_i64, // 291 + 0x7FBB_D8FE_5F5E_6E27_i64, + 0x497A_3A27_04EE_C3DF_i64, // 292 +]; From 7ff42e20313e99fe66955c560b4ba38d9ee4b698 Mon Sep 17 00:00:00 2001 From: Leung Ming <165622843+leung-ming@users.noreply.github.com> Date: Sat, 21 Jun 2025 03:20:23 +0800 Subject: [PATCH 4/8] nit --- .../src/conversion_funcs/schubfach.rs | 2536 ++++++++--------- 1 file changed, 1267 insertions(+), 1269 deletions(-) diff --git a/native/spark-expr/src/conversion_funcs/schubfach.rs b/native/spark-expr/src/conversion_funcs/schubfach.rs index e48daeb3bf..2fd2f6f12e 100644 --- a/native/spark-expr/src/conversion_funcs/schubfach.rs +++ b/native/spark-expr/src/conversion_funcs/schubfach.rs @@ -29,9 +29,9 @@ // This is discussed in section 10 of [1]. // The precision in bits -const P: i32 = 53; +const P: i32 = f64::MANTISSA_DIGITS as i32; // Exponent width in bits -const W: i32 = 64 - 1 - (P - 1); +const W: i32 = size_of::() as i32 * 8 - 1 - (P - 1); // Minimum value of the exponent: -(2^(W-1)) - P + 3 const Q_MIN: i32 = (-1 << (W - 1)) - P + 3; // Threshold to detect tiny values, as in section 8.2.1 of [1] @@ -44,6 +44,8 @@ const C_MIN: i64 = 1 << (P - 1); const BQ_MASK: i32 = (1 << W) - 1; // Mask to extract the fraction bits const T_MASK: u64 = (1 << (P - 1)) - 1; +// Used in rop() +const MASK_63: i64 = 0x7fff_ffff_ffff_ffff; pub fn to_decimal(v: f64) -> Option<(i64, i32)> { // For full details see references [2] and [1]. @@ -56,7 +58,7 @@ pub fn to_decimal(v: f64) -> Option<(i64, i32)> { let bits = v.to_bits(); let t = (bits & T_MASK) as i64; - let bq = (bits >> P - 1) as i32 & BQ_MASK; + let bq = (bits >> (P - 1)) as i32 & BQ_MASK; if bq < BQ_MASK { if bq != 0 { // normal value. Here mq = -q @@ -104,17 +106,17 @@ fn finite_positive_to_decimal(q: i32, c: i64, dk: i32) -> (i64, i32) { let out = c & 1; let cb = c << 2; let cbr = cb + 2; - // flog10pow2(e) = floor(log_10(2^e)) - // flog10threeQuartersPow2(e) = floor(log_10(3/4 2^e)) - // flog2pow10(e) = floor(log_2(10^e)) + // floor_log10_pow2(e) = floor(log_10(2^e)) + // floor_log10_three_quarters_pow2(e) = floor(log_10(3/4 2^e)) + // floor_log2_pow10(e) = floor(log_2(10^e)) let (cbl, k) = if c != C_MIN || q == Q_MIN { // regular spacing - (cb - 2, f_log10_pow2(q)) + (cb - 2, floor_log10_pow2(q)) } else { // irregular spacing - (cb - 1, f_log10_three_quarters_pow2(q)) + (cb - 1, floor_log10_three_quarters_pow2(q)) }; - let h = q + f_log2_pow10(-k) + 2; + let h = q + floor_log2_pow10(-k) + 2; // g1 and g0 are as in section 9.8.3 of [1], so g = g1 2^63 + g0 let g1 = g1(k); @@ -136,9 +138,8 @@ fn finite_positive_to_decimal(q: i32, c: i64, dk: i32) -> (i64, i32) { // wpin iff w' = tp10 10^k in Rv // See section 9.3 of [1]. - let sp10 = 10_i64.wrapping_mul( - ((s as i128 * (115_292_150_460_684_698_i64 << 4) as i128) as u128 >> 64) as i64, - ); + let sp10 = + 10 * ((s as i128 * (115_292_150_460_684_698_i64 << 4) as i128) as u128 >> 64) as i64; let tp10 = sp10 + 10; let upin = vbl + out <= sp10 << 2; let wpin = (tp10 << 2) + out <= vbr; @@ -160,7 +161,7 @@ fn finite_positive_to_decimal(q: i32, c: i64, dk: i32) -> (i64, i32) { // Both u and w lie in Rv: determine the one closest to v. // See section 9.3 of [1]. - let cmp = vb - (s + t << 1); + let cmp = vb - ((s + t) << 1); ( if cmp < 0 || cmp == 0 && (s & 1) == 0 { s @@ -171,11 +172,9 @@ fn finite_positive_to_decimal(q: i32, c: i64, dk: i32) -> (i64, i32) { ) } -/// Computes rop(cp * g * 2^(-127)), where g = g1 2^63 + g0 +/// Computes rop(cp g 2^-127), where g = g1 2^63 + g0 /// See section 9.9 and figure 8 of [1]. fn rop(g1: i64, g0: i64, cp: i64) -> i64 { - const MASK_63: i64 = 0x7fff_ffff_ffff_ffff; - let x1 = ((g0 as i128 * cp as i128) as u128 >> 64) as i64; let y0 = g1.wrapping_mul(cp); let y1 = ((g1 as i128 * cp as i128) as u128 >> 64) as i64; @@ -186,12 +185,12 @@ fn rop(g1: i64, g0: i64, cp: i64) -> i64 { // math utils -// C_10 = floor(log10(2) * 2^Q_10), A_10 = floor(log10(3/4) * 2^Q_10) +// C_10 = floor(log_10(2) * 2^Q_10), A_10 = floor(log_10(3/4) * 2^Q_10) const Q_10: i32 = 41; const C_10: i64 = 661_971_961_083; const A_10: i64 = -274_743_187_321; -// C_2 = floor(log2(10) * 2^Q_2) +// C_2 = floor(log_2(10) * 2^Q_2) const Q_2: i32 = 38; const C_2: i64 = 913_124_641_741; @@ -206,9 +205,9 @@ const C_2: i64 = 913_124_641_741; /// /// # Returns /// -/// * `i32` - floor(log10(2^e)). -fn f_log10_pow2(e: i32) -> i32 { - (e as i64 * C_10 >> Q_10) as i32 +/// * `i32` - floor(log_10(2^e)). +fn floor_log10_pow2(e: i32) -> i32 { + ((e as i64 * C_10) >> Q_10) as i32 } /// Returns the unique integer k such that 10^k <= 3/4 * 2^e < 10^(k+1). @@ -222,9 +221,9 @@ fn f_log10_pow2(e: i32) -> i32 { /// /// # Returns /// -/// * `i32` - floor(log10(3/4 * 2^e)) -fn f_log10_three_quarters_pow2(e: i32) -> i32 { - (e as i64 * C_10 + A_10 >> Q_10) as i32 +/// * `i32` - floor(log_10(3/4 2^e)) +fn floor_log10_three_quarters_pow2(e: i32) -> i32 { + ((e as i64 * C_10 + A_10) >> Q_10) as i32 } /// Returns the unique integer k such that 2^k <= 10^e < 2^(k+1). @@ -238,18 +237,18 @@ fn f_log10_three_quarters_pow2(e: i32) -> i32 { /// /// # Returns /// -/// * `i32` - floor(log2(10^e)) -fn f_log2_pow10(e: i32) -> i32 { - (e as i64 * C_2 >> Q_2) as i32 +/// * `i32` - floor(log_2(10^e)) +fn floor_log2_pow10(e: i32) -> i32 { + ((e as i64 * C_2) >> Q_2) as i32 } -/// Let 10^-k = B * 2^r, for the unique pair of integer r and real B meeting 2^125 <= B < 2^126. +/// Let 10^-k = B 2^r, for the unique pair of integer r and real B meeting 2^125 <= B < 2^126. /// Further, let g = floor(B) + 1. Split g into the higher 63 bits g1 and the lower 63 bits g0. /// Thus, g1 = floor(g * 2^-63) and g0 = g - g1 * 2^63. /// -/// This method returns g1 while `g0(k)` returns g0. +/// This method returns g1 while `g0(i32)` returns g0. /// -/// If needed, the exponent r can be computed as r = `flog2pow10(-k)` - 125. +/// If needed, the exponent r can be computed as r = `floor_log2_pow10(-k)` - 125. /// /// # Arguments /// @@ -259,10 +258,10 @@ fn f_log2_pow10(e: i32) -> i32 { /// /// * `i64` - g1 as described above. fn g1(k: i32) -> i64 { - return G[(k - K_MIN << 1) as usize]; + G[((k - K_MIN) << 1) as usize] } -/// Returns g0 as described in `g1(k)` +/// Returns g0 as described in `g1(i32)` /// /// # Arguments /// @@ -272,1246 +271,1245 @@ fn g1(k: i32) -> i64 { /// /// * `i64` - g0 as described in `g1(k)` fn g0(k: i32) -> i64 { - return G[(k - K_MIN << 1 | 1) as usize]; + G[((k - K_MIN) << 1 | 1) as usize] } -// The precomputed values for g1(int) and g0(int). +// The precomputed values for g1(i32) and g0(i32). // The first entry must be for an exponent of K_MIN or less. // The last entry must be for an exponent of K_MAX or more. -#[doc(hidden)] const G: [i64; 1234] = [ - 0x4F0C_EDC9_5A71_8DD4_i64, - 0x5B01_E8B0_9AA0_D1B5_i64, // -324 - 0x7E7B_160E_F71C_1621_i64, - 0x119C_A780_F767_B5EE_i64, // -323 - 0x652F_44D8_C5B0_11B4_i64, - 0x0E16_EC67_2C52_F7F2_i64, // -322 - 0x50F2_9D7A_37C0_0E29_i64, - 0x5812_56B8_F042_5FF5_i64, // -321 - 0x40C2_1794_F966_71BA_i64, - 0x79A8_4560_C035_1991_i64, // -320 - 0x679C_F287_F570_B5F7_i64, - 0x75DA_089A_CD21_C281_i64, // -319 - 0x52E3_F539_9126_F7F9_i64, - 0x44AE_6D48_A41B_0201_i64, // -318 - 0x424F_F761_40EB_F994_i64, - 0x36F1_F106_E9AF_34CD_i64, // -317 - 0x6A19_8BCE_CE46_5C20_i64, - 0x57E9_81A4_A918_547B_i64, // -316 - 0x54E1_3CA5_71D1_E34D_i64, - 0x2CBA_CE1D_5413_76C9_i64, // -315 - 0x43E7_63B7_8E41_82A4_i64, - 0x23C8_A4E4_4342_C56E_i64, // -314 - 0x6CA5_6C58_E39C_043A_i64, - 0x060D_D4A0_6B9E_08B0_i64, // -313 - 0x56EA_BD13_E949_9CFB_i64, - 0x1E71_76E6_BC7E_6D59_i64, // -312 - 0x4588_9743_2107_B0C8_i64, - 0x7EC1_2BEB_C9FE_BDE1_i64, // -311 - 0x6F40_F205_01A5_E7A7_i64, - 0x7E01_DFDF_A997_9635_i64, // -310 - 0x5900_C19D_9AEB_1FB9_i64, - 0x4B34_B319_5479_44F7_i64, // -309 - 0x4733_CE17_AF22_7FC7_i64, - 0x55C3_C27A_A9FA_9D93_i64, // -308 - 0x71EC_7CF2_B1D0_CC72_i64, - 0x5606_03F7_765D_C8EA_i64, // -307 - 0x5B23_9728_8E40_A38E_i64, - 0x7804_CFF9_2B7E_3A55_i64, // -306 - 0x48E9_45BA_0B66_E93F_i64, - 0x1337_0CC7_55FE_9511_i64, // -305 - 0x74A8_6F90_123E_41FE_i64, - 0x51F1_AE0B_BCCA_881B_i64, // -304 - 0x5D53_8C73_41CB_67FE_i64, - 0x74C1_5809_63D5_39AF_i64, // -303 - 0x4AA9_3D29_016F_8665_i64, - 0x43CD_E007_8310_FAF3_i64, // -302 - 0x7775_2EA8_024C_0A3C_i64, - 0x0616_333F_381B_2B1E_i64, // -301 - 0x5F90_F220_01D6_6E96_i64, - 0x3811_C298_F9AF_55B1_i64, // -300 - 0x4C73_F4E6_67DE_BEDE_i64, - 0x600E_3547_2E25_DE28_i64, // -299 - 0x7A53_2170_A631_3164_i64, - 0x3349_EED8_49D6_303F_i64, // -298 - 0x61DC_1AC0_84F4_2783_i64, - 0x42A1_8BE0_3B11_C033_i64, // -297 - 0x4E49_AF00_6A5C_EC69_i64, - 0x1BB4_6FE6_95A7_CCF5_i64, // -296 - 0x7D42_B19A_43C7_E0A8_i64, - 0x2C53_E63D_BC3F_AE55_i64, // -295 - 0x6435_5AE1_CFD3_1A20_i64, - 0x2376_51CA_FCFF_BEAA_i64, // -294 - 0x502A_AF1B_0CA8_E1B3_i64, - 0x35F8_416F_30CC_9888_i64, // -293 - 0x4022_25AF_3D53_E7C2_i64, - 0x5E60_3458_F3D6_E06D_i64, // -292 - 0x669D_0918_621F_D937_i64, - 0x4A33_86F4_B957_CD7B_i64, // -291 - 0x5217_3A79_E819_7A92_i64, - 0x6E8F_9F2A_2DDF_D796_i64, // -290 - 0x41AC_2EC7_ECE1_2EDB_i64, - 0x720C_7F54_F17F_DFAB_i64, // -289 - 0x6913_7E0C_AE35_17C6_i64, - 0x1CE0_CBBB_1BFF_CC45_i64, // -288 - 0x540F_980A_24F7_4638_i64, - 0x171A_3C95_AFFF_D69E_i64, // -287 - 0x433F_ACD4_EA5F_6B60_i64, - 0x127B_63AA_F333_1218_i64, // -286 - 0x6B99_1487_DD65_7899_i64, - 0x6A5F_05DE_51EB_5026_i64, // -285 - 0x5614_106C_B11D_FA14_i64, - 0x5518_D17E_A7EF_7352_i64, // -284 - 0x44DC_D9F0_8DB1_94DD_i64, - 0x2A7A_4132_1FF2_C2A8_i64, // -283 - 0x6E2E_2980_E2B5_BAFB_i64, - 0x5D90_6850_331E_043F_i64, // -282 - 0x5824_EE00_B55E_2F2F_i64, - 0x6473_86A6_8F4B_3699_i64, // -281 - 0x4683_F19A_2AB1_BF59_i64, - 0x36C2_D21E_D908_F87B_i64, // -280 - 0x70D3_1C29_DDE9_3228_i64, - 0x579E_1CFE_280E_5A5D_i64, // -279 - 0x5A42_7CEE_4B20_F4ED_i64, - 0x2C7E_7D98_200B_7B7E_i64, // -278 - 0x4835_30BE_A280_C3F1_i64, - 0x09FE_CAE0_19A2_C932_i64, // -277 - 0x7388_4DFD_D0CE_064E_i64, - 0x4331_4499_C29E_0EB6_i64, // -276 - 0x5C6D_0B31_73D8_050B_i64, - 0x4F5A_9D47_CEE4_D891_i64, // -275 - 0x49F0_D5C1_2979_9DA2_i64, - 0x72AE_E439_7250_AD41_i64, // -274 - 0x764E_22CE_A8C2_95D1_i64, - 0x377E_39F5_83B4_4868_i64, // -273 - 0x5EA4_E8A5_53CE_DE41_i64, - 0x12CB_6191_3629_D387_i64, // -272 - 0x4BB7_2084_430B_E500_i64, - 0x756F_8140_F821_7605_i64, // -271 - 0x7925_00D3_9E79_6E67_i64, - 0x6F18_CECE_59CF_233C_i64, // -270 - 0x60EA_670F_B1FA_BEB9_i64, - 0x3F47_0BD8_47D8_E8FD_i64, // -269 - 0x4D88_5272_F4C8_9894_i64, - 0x329F_3CAD_0647_20CA_i64, // -268 - 0x7C0D_50B7_EE0D_C0ED_i64, - 0x3765_2DE1_A3A5_0143_i64, // -267 - 0x633D_DA2C_BE71_6724_i64, - 0x2C50_F181_4FB7_3436_i64, // -266 - 0x4F64_AE8A_31F4_5283_i64, - 0x3D0D_8E01_0C92_902B_i64, // -265 - 0x7F07_7DA9_E986_EA6B_i64, - 0x7B48_E334_E0EA_8045_i64, // -264 - 0x659F_97BB_2138_BB89_i64, - 0x4907_1C2A_4D88_669D_i64, // -263 - 0x514C_7962_80FA_2FA1_i64, - 0x20D2_7CEE_A46D_1EE4_i64, // -262 - 0x4109_FAB5_33FB_594D_i64, - 0x670E_CA58_838A_7F1D_i64, // -261 - 0x680F_F788_532B_C216_i64, - 0x0B4A_DD5A_6C10_CB62_i64, // -260 - 0x533F_F939_DC23_01AB_i64, - 0x22A2_4AAE_BCDA_3C4E_i64, // -259 - 0x4299_942E_49B5_9AEF_i64, - 0x354E_A225_63E1_C9D8_i64, // -258 - 0x6A8F_537D_42BC_2B18_i64, - 0x554A_9D08_9FCF_A95A_i64, // -257 - 0x553F_75FD_CEFC_EF46_i64, - 0x776E_E406_E63F_BAAE_i64, // -256 - 0x4432_C4CB_0BFD_8C38_i64, - 0x5F8B_E99F_1E99_6225_i64, // -255 - 0x6D1E_07AB_4662_79F4_i64, - 0x3279_75CB_6428_9D08_i64, // -254 - 0x574B_3955_D1E8_6190_i64, - 0x2861_2B09_1CED_4A6D_i64, // -253 - 0x45D5_C777_DB20_4E0D_i64, - 0x06B4_226D_B0BD_D524_i64, // -252 - 0x6FBC_7259_5E9A_167B_i64, - 0x2453_6A49_1AC9_5506_i64, // -251 - 0x5963_8EAD_E548_11FC_i64, - 0x1D0F_883A_7BD4_4405_i64, // -250 - 0x4782_D88B_1DD3_4196_i64, - 0x4A72_D361_FCA9_D004_i64, // -249 - 0x726A_F411_C952_028A_i64, - 0x43EA_EBCF_FAA9_4CD3_i64, // -248 - 0x5B88_C341_6DDB_353B_i64, - 0x4FEF_230C_C887_70A9_i64, // -247 - 0x493A_35CD_F17C_2A96_i64, - 0x0CBF_4F3D_6D39_26EE_i64, // -246 - 0x7529_EFAF_E8C6_AA89_i64, - 0x6132_1862_485B_717C_i64, // -245 - 0x5DBB_2626_53D2_2207_i64, - 0x675B_46B5_06AF_8DFD_i64, // -244 - 0x4AFC_1E85_0FDB_4E6C_i64, - 0x52AF_6BC4_0559_3E64_i64, // -243 - 0x77F9_CA6E_7FC5_4A47_i64, - 0x377F_12D3_3BC1_FD6D_i64, // -242 - 0x5FFB_0858_6637_6E9F_i64, - 0x45FF_4242_9634_CABD_i64, // -241 - 0x4CC8_D379_EB5F_8BB2_i64, - 0x6B32_9B68_782A_3BCB_i64, // -240 - 0x7ADA_EBF6_4565_AC51_i64, - 0x2B84_2BDA_59DD_2C77_i64, // -239 - 0x6248_BCC5_0451_56A7_i64, - 0x3C69_BCAE_AE4A_89F9_i64, // -238 - 0x4EA0_9704_0374_4552_i64, - 0x6387_CA25_583B_A194_i64, // -237 - 0x7DCD_BE6C_D253_A21E_i64, - 0x05A6_103B_C05F_68ED_i64, // -236 - 0x64A4_9857_0EA9_4E7E_i64, - 0x37B8_0CFC_99E5_ED8A_i64, // -235 - 0x5083_AD12_7221_0B98_i64, - 0x2C93_3D96_E184_BE08_i64, // -234 - 0x4069_5741_F4E7_3C79_i64, - 0x7075_CADF_1AD0_9807_i64, // -233 - 0x670E_F203_2171_FA5C_i64, - 0x4D89_4498_2AE7_59A4_i64, // -232 - 0x5272_5B35_B45B_2EB0_i64, - 0x3E07_6A13_5585_E150_i64, // -231 - 0x41F5_15C4_9048_F226_i64, - 0x64D2_BB42_AAD1_810D_i64, // -230 - 0x6988_22D4_1A0E_503E_i64, - 0x07B7_9204_4482_6815_i64, // -229 - 0x546C_E8A9_AE71_D9CB_i64, - 0x1FC6_0E69_D068_5344_i64, // -228 - 0x438A_53BA_F1F4_AE3C_i64, - 0x196B_3EBB_0D20_429D_i64, // -227 - 0x6C10_85F7_E987_7D2D_i64, - 0x0F11_FDF8_1500_6A94_i64, // -226 - 0x5673_9E5F_EE05_FDBD_i64, - 0x58DB_3193_4400_5543_i64, // -225 - 0x4529_4B7F_F19E_6497_i64, - 0x60AF_5ADC_3666_AA9C_i64, // -224 - 0x6EA8_78CC_B5CA_3A8C_i64, - 0x344B_C493_8A3D_DDC7_i64, // -223 - 0x5886_C70A_2B08_2ED6_i64, - 0x5D09_6A0F_A1CB_17D2_i64, // -222 - 0x46D2_38D4_EF39_BF12_i64, - 0x173A_BB3F_B4A2_7975_i64, // -221 - 0x7150_5AEE_4B8F_981D_i64, - 0x0B91_2B99_2103_F588_i64, // -220 - 0x5AA6_AF25_093F_ACE4_i64, - 0x0940_EFAD_B403_2AD3_i64, // -219 - 0x4885_58EA_6DCC_8A50_i64, - 0x0767_2624_9002_88A9_i64, // -218 - 0x7408_8E43_E2E0_DD4C_i64, - 0x723E_A36D_B337_410E_i64, // -217 - 0x5CD3_A503_1BE7_1770_i64, - 0x5B65_4F8A_F5C5_CDA5_i64, // -216 - 0x4A42_EA68_E31F_45F3_i64, - 0x62B7_72D5_916B_0AEB_i64, // -215 - 0x76D1_770E_3832_0986_i64, - 0x0458_B7BC_1BDE_77DD_i64, // -214 - 0x5F0D_F8D8_2CF4_D46B_i64, - 0x1D13_C630_164B_9318_i64, // -213 - 0x4C0B_2D79_BD90_A9EF_i64, - 0x30DC_9E8C_DEA2_DC13_i64, // -212 - 0x79AB_7BF5_FC1A_A97F_i64, - 0x0160_FDAE_3104_9351_i64, // -211 - 0x6155_FCC4_C9AE_EDFF_i64, - 0x1AB3_FE24_F403_A90E_i64, // -210 - 0x4DDE_63D0_A158_BE65_i64, - 0x6229_981D_9002_EDA5_i64, // -209 - 0x7C97_061A_9BC1_30A2_i64, - 0x69DC_2695_B337_E2A1_i64, // -208 - 0x63AC_04E2_1634_26E8_i64, - 0x54B0_1EDE_28F9_821B_i64, // -207 - 0x4FBC_D0B4_DE90_1F20_i64, - 0x43C0_18B1_BA61_34E2_i64, // -206 - 0x7F94_8121_6419_CB67_i64, - 0x1F99_C11C_5D68_549D_i64, // -205 - 0x6610_674D_E9AE_3C52_i64, - 0x4C7B_00E3_7DED_107E_i64, // -204 - 0x51A6_B90B_2158_3042_i64, - 0x09FC_00B5_FE57_4065_i64, // -203 - 0x4152_2DA2_8113_59CE_i64, - 0x3B30_0091_9845_CD1D_i64, // -202 - 0x6883_7C37_34EB_C2E3_i64, - 0x784C_CDB5_C06F_AE95_i64, // -201 - 0x539C_635F_5D89_68B6_i64, - 0x2D0A_3E2B_0059_5877_i64, // -200 - 0x42E3_82B2_B13A_BA2B_i64, - 0x3DA1_CB55_99E1_1393_i64, // -199 - 0x6B05_9DEA_B52A_C378_i64, - 0x629C_7888_F634_EC1E_i64, // -198 - 0x559E_17EE_F755_692D_i64, - 0x3549_FA07_2B5D_89B1_i64, // -197 - 0x447E_798B_F911_20F1_i64, - 0x1107_FB38_EF7E_07C1_i64, // -196 - 0x6D97_28DF_F4E8_34B5_i64, - 0x01A6_5EC1_7F30_0C68_i64, // -195 - 0x57AC_20B3_2A53_5D5D_i64, - 0x4E1E_B234_65C0_09ED_i64, // -194 - 0x4623_4D5C_21DC_4AB1_i64, - 0x24E5_5B5D_1E33_3B24_i64, // -193 - 0x7038_7BC6_9C93_AAB5_i64, - 0x216E_F894_FD1E_C506_i64, // -192 - 0x59C6_C96B_B076_222A_i64, - 0x4DF2_6077_30E5_6A6C_i64, // -191 - 0x47D2_3ABC_8D2B_4E88_i64, - 0x3E5B_805F_5A51_21F0_i64, // -190 - 0x72E9_F794_1512_1740_i64, - 0x63C5_9A32_2A1B_697F_i64, // -189 - 0x5BEE_5FA9_AA74_DF67_i64, - 0x0304_7B5B_54E2_BACC_i64, // -188 - 0x498B_7FBA_EEC3_E5EC_i64, - 0x0269_FC49_10B5_623D_i64, // -187 - 0x75AB_FF91_7E06_3CAC_i64, - 0x6A43_2D41_B455_69FB_i64, // -186 - 0x5E23_32DA_CB38_308A_i64, - 0x21CF_5767_C377_87FC_i64, // -185 - 0x4B4F_5BE2_3C2C_F3A1_i64, - 0x67D9_12B9_692C_6CCA_i64, // -184 - 0x787E_F969_F9E1_85CF_i64, - 0x595B_5128_A847_1476_i64, // -183 - 0x6065_9454_C7E7_9E3F_i64, - 0x6115_DA86_ED05_A9F8_i64, // -182 - 0x4D1E_1043_D31F_B1CC_i64, - 0x4DAB_1538_BD9E_2193_i64, // -181 - 0x7B63_4D39_51CC_4FAD_i64, - 0x62AB_5527_95C9_CF52_i64, // -180 - 0x62B5_D761_0E3D_0C8B_i64, - 0x0222_AA86_116E_3F75_i64, // -179 - 0x4EF7_DF80_D830_D6D5_i64, - 0x4E82_2204_DABE_992A_i64, // -178 - 0x7E59_659A_F381_57BC_i64, - 0x1736_9CD4_9130_F510_i64, // -177 - 0x6514_5148_C2CD_DFC9_i64, - 0x5F5E_E3DD_40F3_F740_i64, // -176 - 0x50DD_0DD3_CF0B_196E_i64, - 0x1918_B64A_9A5C_C5CD_i64, // -175 - 0x40B0_D7DC_A5A2_7ABE_i64, - 0x4746_F83B_AEB0_9E3E_i64, // -174 - 0x6781_5961_0903_F797_i64, - 0x253E_59F9_1780_FD2F_i64, // -173 - 0x52CD_E11A_6D9C_C612_i64, - 0x50FE_AE60_DF9A_6426_i64, // -172 - 0x423E_4DAE_BE17_04DB_i64, - 0x5A65_584D_7FAE_B685_i64, // -171 - 0x69FD_4917_968B_3AF9_i64, - 0x10A2_26E2_65E4_573B_i64, // -170 - 0x54CA_A0DF_ABA2_9594_i64, - 0x0D4E_8581_EB1D_1295_i64, // -169 - 0x43D5_4D7F_BC82_1143_i64, - 0x243E_D134_BC17_4211_i64, // -168 - 0x6C88_7BFF_9403_4ED2_i64, - 0x06CA_E854_6025_3682_i64, // -167 - 0x56D3_9666_1002_A574_i64, - 0x6BD5_86A9_E684_2B9B_i64, // -166 - 0x4576_11EB_4002_1DF7_i64, - 0x0977_9EEE_5203_5616_i64, // -165 - 0x6F23_4FDE_CCD0_2FF1_i64, - 0x5BF2_97E3_B66B_BCEF_i64, // -164 - 0x58E9_0CB2_3D73_598E_i64, - 0x165B_ACB6_2B89_63F3_i64, // -163 - 0x4720_D6F4_FDF5_E13E_i64, - 0x4516_23C4_EFA1_1CC2_i64, // -162 - 0x71CE_24BB_2FEF_CECA_i64, - 0x3B56_9FA1_7F68_2E03_i64, // -161 - 0x5B0B_5095_BFF3_0BD5_i64, - 0x15DE_E61A_CC53_5803_i64, // -160 - 0x48D5_DA11_665C_0977_i64, - 0x2B18_B815_7042_ACCF_i64, // -159 - 0x7489_5CE8_A3C6_758B_i64, - 0x5E8D_F355_806A_AE18_i64, // -158 - 0x5D3A_B0BA_1C9E_C46F_i64, - 0x653E_5C44_66BB_BE7A_i64, // -157 - 0x4A95_5A2E_7D4B_D059_i64, - 0x3765_169D_1EFC_9861_i64, // -156 - 0x7755_5D17_2EDF_B3C2_i64, - 0x256E_8A94_FE60_F3CF_i64, // -155 - 0x5F77_7DAC_257F_C301_i64, - 0x6ABE_D543_FEB3_F63F_i64, // -154 - 0x4C5F_97BC_EACC_9C01_i64, - 0x3BCB_DDCF_FEF6_5E99_i64, // -153 - 0x7A32_8C61_77AD_C668_i64, - 0x5FAC_9619_97F0_975B_i64, // -152 - 0x61C2_09E7_92F1_6B86_i64, - 0x7FBD_44E1_465A_12AF_i64, // -151 - 0x4E34_D4B9_425A_BC6B_i64, - 0x7FCA_9D81_0514_DBBF_i64, // -150 - 0x7D21_545B_9D5D_FA46_i64, - 0x32DD_C8CE_6E87_C5FF_i64, // -149 - 0x641A_A9E2_E44B_2E9E_i64, - 0x5BE4_A0A5_2539_6B32_i64, // -148 - 0x5015_54B5_836F_587E_i64, - 0x7CB6_E6EA_842D_EF5C_i64, // -147 - 0x4011_1091_35F2_AD32_i64, - 0x3092_5255_368B_25E3_i64, // -146 - 0x6681_B41B_8984_4850_i64, - 0x4DB6_EA21_F0DE_A304_i64, // -145 - 0x5201_5CE2_D469_D373_i64, - 0x57C5_881B_2718_826A_i64, // -144 - 0x419A_B0B5_76BB_0F8F_i64, - 0x5FD1_39AF_527A_01EF_i64, // -143 - 0x68F7_8122_5791_B27F_i64, - 0x4C81_F5E5_50C3_364A_i64, // -142 - 0x53F9_341B_7941_5B99_i64, - 0x239B_2B1D_DA35_C508_i64, // -141 - 0x432D_C349_2DCD_E2E1_i64, - 0x02E2_88E4_AE91_6A6D_i64, // -140 - 0x6B7C_6BA8_4949_6B01_i64, - 0x516A_74A1_174F_10AE_i64, // -139 - 0x55FD_22ED_076D_EF34_i64, - 0x4121_F6E7_45D8_DA25_i64, // -138 - 0x44CA_8257_3924_BF5D_i64, - 0x1A81_9252_9E47_14EB_i64, // -137 - 0x6E10_D08B_8EA1_322E_i64, - 0x5D9C_1D50_FD3E_87DD_i64, // -136 - 0x580D_73A2_D880_F4F2_i64, - 0x17B0_1773_FDCB_9FE4_i64, // -135 - 0x4671_294F_139A_5D8E_i64, - 0x4626_7929_97D6_1984_i64, // -134 - 0x70B5_0EE4_EC2A_2F4A_i64, - 0x3D0A_5B75_BFBC_F59F_i64, // -133 - 0x5A2A_7250_BCEE_8C3B_i64, - 0x4A6E_AF91_6630_C47F_i64, // -132 - 0x4821_F50D_63F2_09C9_i64, - 0x21F2_260D_EB5A_36CC_i64, // -131 - 0x7369_8815_6CB6_760E_i64, - 0x6983_7016_455D_247A_i64, // -130 - 0x5C54_6CDD_F091_F80B_i64, - 0x6E02_C011_D117_5062_i64, // -129 - 0x49DD_23E4_C074_C66F_i64, - 0x719B_CCDB_0DAC_404E_i64, // -128 - 0x762E_9FD4_6721_3D7F_i64, - 0x68F9_47C4_E2AD_33B0_i64, // -127 - 0x5E8B_B310_5280_FDFF_i64, - 0x6D94_396A_4EF0_F627_i64, // -126 - 0x4BA2_F5A6_A867_3199_i64, - 0x3E10_2DEE_A58D_91B9_i64, // -125 - 0x7904_BC3D_DA3E_B5C2_i64, - 0x3019_E317_6F48_E927_i64, // -124 - 0x60D0_9697_E1CB_C49B_i64, - 0x4014_B5AC_5907_20EC_i64, // -123 - 0x4D73_ABAC_B4A3_03AF_i64, - 0x4CDD_5E23_7A6C_1A57_i64, // -122 - 0x7BEC_45E1_2104_D2B2_i64, - 0x47C8_969F_2A46_908A_i64, // -121 - 0x6323_6B1A_80D0_A88E_i64, - 0x6CA0_787F_5505_406F_i64, // -120 - 0x4F4F_88E2_00A6_ED3F_i64, - 0x0A19_F9FF_7737_66BF_i64, // -119 - 0x7EE5_A7D0_010B_1531_i64, - 0x5CF6_5CCB_F1F2_3DFE_i64, // -118 - 0x6584_8640_00D5_AA8E_i64, - 0x172B_7D6F_F4C1_CB32_i64, // -117 - 0x5136_D1CC_CD77_BBA4_i64, - 0x78EF_978C_C3CE_3C28_i64, // -116 - 0x40F8_A7D7_0AC6_2FB7_i64, - 0x13F2_DFA3_CFD8_3020_i64, // -115 - 0x67F4_3FBE_77A3_7F8B_i64, - 0x3984_9906_1959_E699_i64, // -114 - 0x5329_CC98_5FB5_FFA2_i64, - 0x6136_E0D1_ADE1_8548_i64, // -113 - 0x4287_D6E0_4C91_994F_i64, - 0x00F8_B3DA_F181_376D_i64, // -112 - 0x6A72_F166_E0E8_F54B_i64, - 0x1B27_862B_1C01_F247_i64, // -111 - 0x5528_C11F_1A53_F76F_i64, - 0x2F52_D1BC_1667_F506_i64, // -110 - 0x4420_9A7F_4843_2C59_i64, - 0x0C42_4163_451F_F738_i64, // -109 - 0x6D00_F732_0D38_46F4_i64, - 0x7A03_9BD2_0833_2526_i64, // -108 - 0x5733_F8F4_D760_38C3_i64, - 0x7B36_1641_A028_EA85_i64, // -107 - 0x45C3_2D90_AC4C_FA36_i64, - 0x2F5E_7834_8020_BB9E_i64, // -106 - 0x6F9E_AF4D_E07B_29F0_i64, - 0x4BCA_59ED_99CD_F8FC_i64, // -105 - 0x594B_BF71_8062_87F3_i64, - 0x563B_7B24_7B0B_2D96_i64, // -104 - 0x476F_CC5A_CD1B_9FF6_i64, - 0x11C9_2F50_626F_57AC_i64, // -103 - 0x724C_7A2A_E1C5_CCBD_i64, - 0x02DB_7EE7_03E5_5912_i64, // -102 - 0x5B70_61BB_E7D1_7097_i64, - 0x1BE2_CBEC_031D_E0DC_i64, // -101 - 0x4926_B496_530D_F3AC_i64, - 0x164F_0989_9C17_E716_i64, // -100 - 0x750A_BA8A_1E7C_B913_i64, - 0x3D4B_4275_C68C_A4F0_i64, // -99 - 0x5DA2_2ED4_E530_940F_i64, - 0x4AA2_9B91_6BA3_B726_i64, // -98 - 0x4AE8_2577_1DC0_7672_i64, - 0x6EE8_7C74_561C_9285_i64, // -97 - 0x77D9_D58B_62CD_8A51_i64, - 0x3173_FA53_BCFA_8408_i64, // -96 - 0x5FE1_77A2_B571_3B74_i64, - 0x278F_FB76_30C8_69A0_i64, // -95 - 0x4CB4_5FB5_5DF4_2F90_i64, - 0x1FA6_62C4_F3D3_87B3_i64, // -94 - 0x7ABA_32BB_C986_B280_i64, - 0x32A3_D13B_1FB8_D91F_i64, // -93 - 0x622E_8EFC_A138_8ECD_i64, - 0x0EE9_742F_4C93_E0E6_i64, // -92 - 0x4E8B_A596_E760_723D_i64, - 0x58BA_C359_0A0F_E71E_i64, // -91 - 0x7DAC_3C24_A567_1D2F_i64, - 0x412A_D228_1019_71C9_i64, // -90 - 0x6489_C9B6_EAB8_E426_i64, - 0x00EF_0E86_7347_8E3B_i64, // -89 - 0x506E_3AF8_BBC7_1CEB_i64, - 0x1A58_D86B_8F6C_71C9_i64, // -88 - 0x4058_2F2D_6305_B0BC_i64, - 0x1513_E056_0C56_C16E_i64, // -87 - 0x66F3_7EAF_04D5_E793_i64, - 0x3B53_0089_AD57_9BE2_i64, // -86 - 0x525C_6558_D0AB_1FA9_i64, - 0x15DC_006E_2446_164F_i64, // -85 - 0x41E3_8447_0D55_B2ED_i64, - 0x5E49_99F1_B69E_783F_i64, // -84 - 0x696C_06D8_1555_EB15_i64, - 0x7D42_8FE9_2430_C065_i64, // -83 - 0x5456_6BE0_1111_88DE_i64, - 0x3102_0CBA_835A_3384_i64, // -82 - 0x4378_564C_DA74_6D7E_i64, - 0x5A68_0A2E_CF7B_5C69_i64, // -81 - 0x6BF3_BD47_C3ED_7BFD_i64, - 0x770C_DD17_B25E_FA42_i64, // -80 - 0x565C_976C_9CBD_FCCB_i64, - 0x1270_B0DF_C1E5_9502_i64, // -79 - 0x4516_DF8A_16FE_63D5_i64, - 0x5B8D_5A4C_9B1E_10CE_i64, // -78 - 0x6E8A_FF43_57FD_6C89_i64, - 0x127B_C3AD_C4FC_E7B0_i64, // -77 - 0x586F_329C_4664_56D4_i64, - 0x0EC9_6957_D0CA_52F3_i64, // -76 - 0x46BF_5BB0_3850_4576_i64, - 0x3F07_8779_73D5_0F29_i64, // -75 - 0x7132_2C4D_26E6_D58A_i64, - 0x31A5_A58F_1FBB_4B75_i64, // -74 - 0x5A8E_89D7_5252_446E_i64, - 0x5AEA_EAD8_E62F_6F91_i64, // -73 - 0x4872_07DF_750E_9D25_i64, - 0x2F22_557A_51BF_8C74_i64, // -72 - 0x73E9_A632_54E4_2EA2_i64, - 0x1836_EF2A_1C65_AD86_i64, // -71 - 0x5CBA_EB5B_771C_F21B_i64, - 0x2CF8_BF54_E384_8AD2_i64, // -70 - 0x4A2F_22AF_927D_8E7C_i64, - 0x23FA_32AA_4F9D_3BDB_i64, // -69 - 0x76B1_D118_EA62_7D93_i64, - 0x5329_EAAA_18FB_92F8_i64, // -68 - 0x5EF4_A747_21E8_6476_i64, - 0x0F54_BBBB_472F_A8C6_i64, // -67 - 0x4BF6_EC38_E7ED_1D2B_i64, - 0x25DD_62FC_38F2_ED6C_i64, // -66 - 0x798B_138E_3FE1_C845_i64, - 0x22FB_D193_8E51_7BDF_i64, // -65 - 0x613C_0FA4_FFE7_D36A_i64, - 0x4F2F_DADC_71DA_C97F_i64, // -64 - 0x4DC9_A61D_9986_42BB_i64, - 0x58F3_157D_27E2_3ACC_i64, // -63 - 0x7C75_D695_C270_6AC5_i64, - 0x74B8_2261_D969_F7AD_i64, // -62 - 0x6391_7877_CEC0_556B_i64, - 0x1093_4EB4_ADEE_5FBE_i64, // -61 - 0x4FA7_9393_0BCD_1122_i64, - 0x4075_D890_8B25_1965_i64, // -60 - 0x7F72_85B8_12E1_B504_i64, - 0x00BC_8DB4_11D4_F56E_i64, // -59 - 0x65F5_37C6_7581_5D9C_i64, - 0x66FD_3E29_A7DD_9125_i64, // -58 - 0x5190_F96B_9134_4AE3_i64, - 0x6BFD_CB54_864A_DA84_i64, // -57 - 0x4140_C789_40F6_A24F_i64, - 0x6FFE_3C43_9EA2_486A_i64, // -56 - 0x6867_A5A8_67F1_03B2_i64, - 0x7FFD_2D38_FDD0_73DC_i64, // -55 - 0x5386_1E20_5327_3628_i64, - 0x6664_242D_97D9_F64A_i64, // -54 - 0x42D1_B1B3_75B8_F820_i64, - 0x51E9_B68A_DFE1_91D5_i64, // -53 - 0x6AE9_1C52_55F4_C034_i64, - 0x1CA9_2411_6635_B621_i64, // -52 - 0x5587_49DB_77F7_0029_i64, - 0x63BA_8341_1E91_5E81_i64, // -51 - 0x446C_3B15_F992_6687_i64, - 0x6962_029A_7EDA_B201_i64, // -50 - 0x6D79_F823_28EA_3DA6_i64, - 0x0F03_375D_97C4_5001_i64, // -49 - 0x5794_C682_8721_CAEB_i64, - 0x259C_2C4A_DFD0_4001_i64, // -48 - 0x4610_9ECE_D281_6F22_i64, - 0x5149_BD08_B30D_0001_i64, // -47 - 0x701A_97B1_50CF_1837_i64, - 0x3542_C80D_EB48_0001_i64, // -46 - 0x59AE_DFC1_0D72_79C5_i64, - 0x7768_A00B_22A0_0001_i64, // -45 - 0x47BF_1967_3DF5_2E37_i64, - 0x7920_8008_E880_0001_i64, // -44 - 0x72CB_5BD8_6321_E38C_i64, - 0x5B67_3341_7400_0001_i64, // -43 - 0x5BD5_E313_8281_82D6_i64, - 0x7C52_8F67_9000_0001_i64, // -42 - 0x4977_E8DC_6867_9BDF_i64, - 0x16A8_72B9_4000_0001_i64, // -41 - 0x758C_A7C7_0D72_92FE_i64, - 0x5773_EAC2_0000_0001_i64, // -40 - 0x5E0A_1FD2_7128_7598_i64, - 0x45F6_5568_0000_0001_i64, // -39 - 0x4B3B_4CA8_5A86_C47A_i64, - 0x04C5_1120_0000_0001_i64, // -38 - 0x785E_E10D_5DA4_6D90_i64, - 0x07A1_B500_0000_0001_i64, // -37 - 0x604B_E73D_E483_8AD9_i64, - 0x52E7_C400_0000_0001_i64, // -36 - 0x4D09_85CB_1D36_08AE_i64, - 0x0F1F_D000_0000_0001_i64, // -35 - 0x7B42_6FAB_61F0_0DE3_i64, - 0x31CC_8000_0000_0001_i64, // -34 - 0x629B_8C89_1B26_7182_i64, - 0x5B0A_0000_0000_0001_i64, // -33 - 0x4EE2_D6D4_15B8_5ACE_i64, - 0x7C08_0000_0000_0001_i64, // -32 - 0x7E37_BE20_22C0_914B_i64, - 0x1340_0000_0000_0001_i64, // -31 - 0x64F9_64E6_8233_A76F_i64, - 0x2900_0000_0000_0001_i64, // -30 - 0x50C7_83EB_9B5C_85F2_i64, - 0x5400_0000_0000_0001_i64, // -29 - 0x409F_9CBC_7C4A_04C2_i64, - 0x1000_0000_0000_0001_i64, // -28 - 0x6765_C793_FA10_079D_i64, - 0x0000_0000_0000_0001_i64, // -27 - 0x52B7_D2DC_C80C_D2E4_i64, - 0x0000_0000_0000_0001_i64, // -26 - 0x422C_A8B0_A00A_4250_i64, - 0x0000_0000_0000_0001_i64, // -25 - 0x69E1_0DE7_6676_D080_i64, - 0x0000_0000_0000_0001_i64, // -24 - 0x54B4_0B1F_852B_DA00_i64, - 0x0000_0000_0000_0001_i64, // -23 - 0x43C3_3C19_3756_4800_i64, - 0x0000_0000_0000_0001_i64, // -22 - 0x6C6B_935B_8BBD_4000_i64, - 0x0000_0000_0000_0001_i64, // -21 - 0x56BC_75E2_D631_0000_i64, - 0x0000_0000_0000_0001_i64, // -20 - 0x4563_9182_44F4_0000_i64, - 0x0000_0000_0000_0001_i64, // -19 - 0x6F05_B59D_3B20_0000_i64, - 0x0000_0000_0000_0001_i64, // -18 - 0x58D1_5E17_6280_0000_i64, - 0x0000_0000_0000_0001_i64, // -17 - 0x470D_E4DF_8200_0000_i64, - 0x0000_0000_0000_0001_i64, // -16 - 0x71AF_D498_D000_0000_i64, - 0x0000_0000_0000_0001_i64, // -15 - 0x5AF3_107A_4000_0000_i64, - 0x0000_0000_0000_0001_i64, // -14 - 0x48C2_7395_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -13 - 0x746A_5288_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -12 - 0x5D21_DBA0_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -11 - 0x4A81_7C80_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -10 - 0x7735_9400_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -9 - 0x5F5E_1000_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -8 - 0x4C4B_4000_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -7 - 0x7A12_0000_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -6 - 0x61A8_0000_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -5 - 0x4E20_0000_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -4 - 0x7D00_0000_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -3 - 0x6400_0000_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -2 - 0x5000_0000_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // -1 - 0x4000_0000_0000_0000_i64, - 0x0000_0000_0000_0001_i64, // 0 - 0x6666_6666_6666_6666_i64, - 0x3333_3333_3333_3334_i64, // 1 - 0x51EB_851E_B851_EB85_i64, - 0x0F5C_28F5_C28F_5C29_i64, // 2 - 0x4189_374B_C6A7_EF9D_i64, - 0x5916_872B_020C_49BB_i64, // 3 - 0x68DB_8BAC_710C_B295_i64, - 0x74F0_D844_D013_A92B_i64, // 4 - 0x53E2_D623_8DA3_C211_i64, - 0x43F3_E037_0CDC_8755_i64, // 5 - 0x431B_DE82_D7B6_34DA_i64, - 0x698F_E692_70B0_6C44_i64, // 6 - 0x6B5F_CA6A_F2BD_215E_i64, - 0x0F4C_A41D_811A_46D4_i64, // 7 - 0x55E6_3B88_C230_E77E_i64, - 0x3F70_834A_CDAE_9F10_i64, // 8 - 0x44B8_2FA0_9B5A_52CB_i64, - 0x4C5A_02A2_3E25_4C0D_i64, // 9 - 0x6DF3_7F67_5EF6_EADF_i64, - 0x2D5C_D103_96A2_1347_i64, // 10 - 0x57F5_FF85_E592_557F_i64, - 0x3DE3_DA69_454E_75D3_i64, // 11 - 0x465E_6604_B7A8_4465_i64, - 0x7E4F_E1ED_D10B_9175_i64, // 12 - 0x7097_09A1_25DA_0709_i64, - 0x4A19_697C_81AC_1BEF_i64, // 13 - 0x5A12_6E1A_84AE_6C07_i64, - 0x54E1_2130_67BC_E326_i64, // 14 - 0x480E_BE7B_9D58_566C_i64, - 0x43E7_4DC0_52FD_8285_i64, // 15 - 0x734A_CA5F_6226_F0AD_i64, - 0x530B_AF9A_1E62_6A6D_i64, // 16 - 0x5C3B_D519_1B52_5A24_i64, - 0x426F_BFAE_7EB5_21F1_i64, // 17 - 0x49C9_7747_490E_AE83_i64, - 0x4EBF_CC8B_9890_E7F4_i64, // 18 - 0x760F_253E_DB4A_B0D2_i64, - 0x4ACC_7A78_F41B_0CBA_i64, // 19 - 0x5E72_8432_4908_8D75_i64, - 0x223D_2EC7_29AF_3D62_i64, // 20 - 0x4B8E_D028_3A6D_3DF7_i64, - 0x34FD_BF05_BAF2_9781_i64, // 21 - 0x78E4_8040_5D7B_9658_i64, - 0x54C9_31A2_C4B7_58CF_i64, // 22 - 0x60B6_CD00_4AC9_4513_i64, - 0x5D6D_C14F_03C5_E0A5_i64, // 23 - 0x4D5F_0A66_A23A_9DA9_i64, - 0x3124_9AA5_9C9E_4D51_i64, // 24 - 0x7BCB_43D7_69F7_62A8_i64, - 0x4EA0_F76F_60FD_4882_i64, // 25 - 0x6309_0312_BB2C_4EED_i64, - 0x254D_92BF_80CA_A068_i64, // 26 - 0x4F3A_68DB_C8F0_3F24_i64, - 0x1DD7_A899_33D5_4D20_i64, // 27 - 0x7EC3_DAF9_4180_6506_i64, - 0x62F2_A75B_8622_1500_i64, // 28 - 0x6569_7BFA_9ACD_1D9F_i64, - 0x025B_B916_04E8_10CD_i64, // 29 - 0x5121_2FFB_AF0A_7E18_i64, - 0x6849_60DE_6A53_40A4_i64, // 30 - 0x40E7_5996_25A1_FE7A_i64, - 0x203A_B3E5_21DC_33B6_i64, // 31 - 0x67D8_8F56_A29C_CA5D_i64, - 0x19F7_863B_6960_52BD_i64, // 32 - 0x5313_A5DE_E87D_6EB0_i64, - 0x7B2C_6B62_BAB3_7564_i64, // 33 - 0x4276_1E4B_ED31_255A_i64, - 0x2F56_BC4E_FBC2_C450_i64, // 34 - 0x6A56_96DF_E1E8_3BC3_i64, - 0x6557_93B1_92D1_3A1A_i64, // 35 - 0x5512_124C_B4B9_C969_i64, - 0x3779_42F4_7574_2E7B_i64, // 36 - 0x440E_750A_2A2E_3ABA_i64, - 0x5F94_3590_5DF6_8B96_i64, // 37 - 0x6CE3_EE76_A9E3_912A_i64, - 0x65B9_EF4D_6324_1289_i64, // 38 - 0x571C_BEC5_54B6_0DBB_i64, - 0x6AFB_25D7_8283_4207_i64, // 39 - 0x45B0_989D_DD5E_7163_i64, - 0x08C8_EB12_CECF_6806_i64, // 40 - 0x6F80_F42F_C897_1BD1_i64, - 0x5ADB_11B7_B14B_D9A3_i64, // 41 - 0x5933_F68C_A078_E30E_i64, - 0x157C_0E2C_8DD6_47B5_i64, // 42 - 0x475C_C53D_4D2D_8271_i64, - 0x5DFC_D823_A4AB_6C91_i64, // 43 - 0x722E_0862_1515_9D82_i64, - 0x632E_269F_6DDF_141B_i64, // 44 - 0x5B58_06B4_DDAA_E468_i64, - 0x4F58_1EE5_F17F_4349_i64, // 45 - 0x4913_3890_B155_8386_i64, - 0x72AC_E584_C132_9C3B_i64, // 46 - 0x74EB_8DB4_4EEF_38D7_i64, - 0x6AAE_3C07_9B84_2D2A_i64, // 47 - 0x5D89_3E29_D8BF_60AC_i64, - 0x5558_3006_1603_5755_i64, // 48 - 0x4AD4_31BB_13CC_4D56_i64, - 0x7779_C004_DE69_12AB_i64, // 49 - 0x77B9_E92B_52E0_7BBE_i64, - 0x258F_99A1_63DB_5111_i64, // 50 - 0x5FC7_EDBC_424D_2FCB_i64, - 0x37A6_1481_1CAF_740D_i64, // 51 - 0x4C9F_F163_683D_BFD5_i64, - 0x7951_AA00_E3BF_900B_i64, // 52 - 0x7A99_8238_A6C9_32EF_i64, - 0x754F_7667_D2CC_19AB_i64, // 53 - 0x6214_682D_523A_8F26_i64, - 0x2AA5_F853_0F09_AE22_i64, // 54 - 0x4E76_B9BD_DB62_0C1E_i64, - 0x5551_9375_A5A1_581B_i64, // 55 - 0x7D8A_C2C9_5F03_4697_i64, - 0x3BB5_B8BC_3C35_59C5_i64, // 56 - 0x646F_023A_B269_0545_i64, - 0x7C91_6096_9691_149E_i64, // 57 - 0x5058_CE95_5B87_376B_i64, - 0x16DA_B3AB_ABA7_43B2_i64, // 58 - 0x4047_0BAA_AF9F_5F88_i64, - 0x78AE_F622_EFB9_02F5_i64, // 59 - 0x66D8_12AA_B298_98DB_i64, - 0x0DE4_BD04_B2C1_9E54_i64, // 60 - 0x5246_7555_5BAD_4715_i64, - 0x57EA_30D0_8F01_4B76_i64, // 61 - 0x41D1_F777_7C8A_9F44_i64, - 0x4654_F3DA_0C01_092C_i64, // 62 - 0x694F_F258_C744_3207_i64, - 0x23BB_1FC3_4668_0EAC_i64, // 63 - 0x543F_F513_D29C_F4D2_i64, - 0x4FC8_E635_D1EC_D88A_i64, // 64 - 0x4366_5DA9_754A_5D75_i64, - 0x263A_51C4_A7F0_AD3B_i64, // 65 - 0x6BD6_FC42_5543_C8BB_i64, - 0x56C3_B607_731A_AEC4_i64, // 66 - 0x5645_969B_7769_6D62_i64, - 0x789C_919F_8F48_8BD0_i64, // 67 - 0x4504_787C_5F87_8AB5_i64, - 0x46E3_A7B2_D906_D640_i64, // 68 - 0x6E6D_8D93_CC0C_1122_i64, - 0x3E39_0C51_5B3E_239A_i64, // 69 - 0x5857_A476_3CD6_741B_i64, - 0x4B60_D6A7_7C31_B615_i64, // 70 - 0x46AC_8391_CA45_29AF_i64, - 0x55E7_121F_968E_2B44_i64, // 71 - 0x7114_05B6_106E_A919_i64, - 0x0971_B698_F0E3_786D_i64, // 72 - 0x5A76_6AF8_0D25_5414_i64, - 0x078E_2BAD_8D82_C6BD_i64, // 73 - 0x485E_BBF9_A41D_DCDC_i64, - 0x6C71_BC8A_D79B_D231_i64, // 74 - 0x73CA_C65C_39C9_6161_i64, - 0x2D82_C744_8C2C_8382_i64, // 75 - 0x5CA2_3849_C7D4_4DE7_i64, - 0x3E02_3903_A356_CF9B_i64, // 76 - 0x4A1B_603B_0643_7185_i64, - 0x7E68_2D9C_82AB_D949_i64, // 77 - 0x7692_3391_A39F_1C09_i64, - 0x4A40_48FA_6AAC_8EDB_i64, // 78 - 0x5EDB_5C74_82E5_B007_i64, - 0x5500_3A61_EEF0_7249_i64, // 79 - 0x4BE2_B05D_3584_8CD2_i64, - 0x7733_61E7_F259_F507_i64, // 80 - 0x796A_B3C8_55A0_E151_i64, - 0x3EB8_9CA6_508F_EE71_i64, // 81 - 0x6122_296D_114D_810D_i64, - 0x7EFA_16EB_73A6_585B_i64, // 82 - 0x4DB4_EDF0_DAA4_673E_i64, - 0x3261_ABEF_8FB8_46AF_i64, // 83 - 0x7C54_AFE7_C43A_3ECA_i64, - 0x1D69_1318_E5F3_A44B_i64, // 84 - 0x6376_F31F_D02E_98A1_i64, - 0x6454_0F47_1E5C_836F_i64, // 85 - 0x4F92_5C19_7358_7A1B_i64, - 0x0376_729F_4B7D_35F3_i64, // 86 - 0x7F50_935B_EBC0_C35E_i64, - 0x38BD_8432_1261_EFEB_i64, // 87 - 0x65DA_0F7C_BC9A_35E5_i64, - 0x13CA_D028_0EB4_BFEF_i64, // 88 - 0x517B_3F96_FD48_2B1D_i64, - 0x5CA2_4020_0BC3_CCBF_i64, // 89 - 0x412F_6612_6439_BC17_i64, - 0x63B5_0019_A303_0A33_i64, // 90 - 0x684B_D683_D38F_9359_i64, - 0x1F88_0029_04D1_A9EA_i64, // 91 - 0x536F_DECF_DC72_DC47_i64, - 0x32D3_3354_03DA_EE55_i64, // 92 - 0x42BF_E573_16C2_49D2_i64, - 0x5BDC_2910_0315_8B77_i64, // 93 - 0x6ACC_A251_BE03_A951_i64, - 0x12F9_DB4C_D1BC_1258_i64, // 94 - 0x5570_81DA_FE69_5440_i64, - 0x7594_AF70_A7C9_A847_i64, // 95 - 0x445A_017B_FEBA_A9CD_i64, - 0x4476_F2C0_863A_ED06_i64, // 96 - 0x6D5C_CF2C_CAC4_42E2_i64, - 0x3A57_EACD_A391_7B3C_i64, // 97 - 0x577D_728A_3BD0_3581_i64, - 0x7B79_88A4_82DA_C8FD_i64, // 98 - 0x45FD_F53B_630C_F79B_i64, - 0x15FA_D3B6_CF15_6D97_i64, // 99 - 0x6FFC_BB92_3814_BF5E_i64, - 0x565E_1F8A_E4EF_15BE_i64, // 100 - 0x5996_FC74_F9AA_32B2_i64, - 0x11E4_E608_B725_AAFF_i64, // 101 - 0x47AB_FD2A_6154_F55B_i64, - 0x27EA_51A0_9284_88CC_i64, // 102 - 0x72AC_C843_CEEE_555E_i64, - 0x7310_829A_8407_4146_i64, // 103 - 0x5BBD_6D03_0BF1_DDE5_i64, - 0x4273_9BAE_D005_CDD2_i64, // 104 - 0x4964_5735_A327_E4B7_i64, - 0x4EC2_E2F2_4004_A4A8_i64, // 105 - 0x756D_5855_D1D9_6DF2_i64, - 0x4AD1_6B1D_333A_A10C_i64, // 106 - 0x5DF1_1377_DB14_57F5_i64, - 0x2241_227D_C295_4DA3_i64, // 107 - 0x4B27_42C6_48DD_132A_i64, - 0x4E9A_81FE_3544_3E1C_i64, // 108 - 0x783E_D13D_4161_B844_i64, - 0x175D_9CC9_EED3_9694_i64, // 109 - 0x6032_40FD_CDE7_C69C_i64, - 0x7917_B0A1_8BDC_7876_i64, // 110 - 0x4CF5_00CB_0B1F_D217_i64, - 0x1412_F3B4_6FE3_9392_i64, // 111 - 0x7B21_9ADE_7832_E9BE_i64, - 0x5351_85ED_7FD2_85B6_i64, // 112 - 0x6281_48B1_F9C2_5498_i64, - 0x42A7_9E57_9975_37C5_i64, // 113 - 0x4ECD_D3C1_949B_76E0_i64, - 0x3552_E512_E12A_9304_i64, // 114 - 0x7E16_1F9C_20F8_BE33_i64, - 0x6EEB_081E_3510_EB39_i64, // 115 - 0x64DE_7FB0_1A60_9829_i64, - 0x3F22_6CE4_F740_BC2E_i64, // 116 - 0x50B1_FFC0_151A_1354_i64, - 0x3281_F0B7_2C33_C9BE_i64, // 117 - 0x408E_6633_4414_DC43_i64, - 0x4201_8D5F_568F_D498_i64, // 118 - 0x674A_3D1E_D354_939F_i64, - 0x1CCF_4898_8A7F_BA8D_i64, // 119 - 0x52A1_CA7F_0F76_DC7F_i64, - 0x30A5_D3AD_3B99_620B_i64, // 120 - 0x421B_0865_A5F8_B065_i64, - 0x73B7_DC8A_9614_4E6F_i64, // 121 - 0x69C4_DA3C_3CC1_1A3C_i64, - 0x52BF_C744_2353_B0B1_i64, // 122 - 0x549D_7B63_63CD_AE96_i64, - 0x7566_3903_4F76_26F4_i64, // 123 - 0x43B1_2F82_B63E_2545_i64, - 0x4451_C735_D92B_525D_i64, // 124 - 0x6C4E_B26A_BD30_3BA2_i64, - 0x3A1C_71EF_C1DE_EA2E_i64, // 125 - 0x56A5_5B88_9759_C94E_i64, - 0x61B0_5B26_34B2_54F2_i64, // 126 - 0x4551_1606_DF7B_0772_i64, - 0x1AF3_7C1E_908E_AA5B_i64, // 127 - 0x6EE8_233E_325E_7250_i64, - 0x2B1F_2CFD_B417_76F8_i64, // 128 - 0x58B9_B5CB_5B7E_C1D9_i64, - 0x6F4C_23FE_29AC_5F2D_i64, // 129 - 0x46FA_F7D5_E2CB_CE47_i64, - 0x72A3_4FFE_87BD_18F1_i64, // 130 - 0x7191_8C89_6ADF_B073_i64, - 0x0438_7FFD_A5FB_5B1B_i64, // 131 - 0x5ADA_D6D4_557F_C05C_i64, - 0x0360_6664_84C9_15AF_i64, // 132 - 0x48AF_1243_7799_66B0_i64, - 0x02B3_851D_3707_448C_i64, // 133 - 0x744B_506B_F28F_0AB3_i64, - 0x1DEC_082E_BE72_0746_i64, // 134 - 0x5D09_0D23_2872_6EF5_i64, - 0x64BC_D358_985B_3905_i64, // 135 - 0x4A6D_A41C_205B_8BF7_i64, - 0x6A30_A913_AD15_C738_i64, // 136 - 0x7715_D360_33C5_ACBF_i64, - 0x5D1A_A81F_7B56_0B8C_i64, // 137 - 0x5F44_A919_C304_8A32_i64, - 0x7DAE_ECE5_FC44_D609_i64, // 138 - 0x4C36_EDAE_359D_3B5B_i64, - 0x7E25_8A51_969D_7808_i64, // 139 - 0x79F1_7C49_EF61_F893_i64, - 0x16A2_76E8_F0FB_F33F_i64, // 140 - 0x618D_FD07_F2B4_C6DC_i64, - 0x121B_9253_F3FC_C299_i64, // 141 - 0x4E0B_30D3_2890_9F16_i64, - 0x41AF_A843_2997_0214_i64, // 142 - 0x7CDE_B485_0DB4_31BD_i64, - 0x4F7F_739E_A8F1_9CED_i64, // 143 - 0x63E5_5D37_3E29_C164_i64, - 0x3F99_294B_BA5A_E3F1_i64, // 144 - 0x4FEA_B0F8_FE87_CDE9_i64, - 0x7FAD_BAA2_FB7B_E98D_i64, // 145 - 0x7FDD_E7F4_CA72_E30F_i64, - 0x7F7C_5DD1_925F_DC15_i64, // 146 - 0x664B_1FF7_085B_E8D9_i64, - 0x4C63_7E41_41E6_49AB_i64, // 147 - 0x51D5_B32C_06AF_ED7A_i64, - 0x704F_9834_34B8_3AEF_i64, // 148 - 0x4177_C289_9EF3_2462_i64, - 0x26A6_135C_F6F9_C8BF_i64, // 149 - 0x68BF_9DA8_FE51_D3D0_i64, - 0x3DD6_8561_8B29_4132_i64, // 150 - 0x53CC_7E20_CB74_A973_i64, - 0x4B12_044E_08ED_CDC2_i64, // 151 - 0x4309_FE80_A2C3_BAC2_i64, - 0x6F41_9D0B_3A57_D7CE_i64, // 152 - 0x6B43_30CD_D139_2AD1_i64, - 0x3202_94DE_C3BF_BFB0_i64, // 153 - 0x55CF_5A3E_40FA_88A7_i64, - 0x419B_AA4B_CFCC_995A_i64, // 154 - 0x44A5_E1CB_672E_D3B9_i64, - 0x1AE2_EEA3_0CA3_ADE1_i64, // 155 - 0x6DD6_3612_3EB1_52C1_i64, - 0x77D1_7DD1_ADD2_AFCF_i64, // 156 - 0x57DE_91A8_3227_7567_i64, - 0x7974_64A7_BE42_263F_i64, // 157 - 0x464B_A7B9_C1B9_2AB9_i64, - 0x4790_5086_31CE_84FF_i64, // 158 - 0x7079_0C5C_6928_445C_i64, - 0x0C1A_1A70_4FB0_D4CC_i64, // 159 - 0x59FA_7049_EDB9_D049_i64, - 0x567B_4859_D95A_43D6_i64, // 160 - 0x47FB_8D07_F161_736E_i64, - 0x11FC_39E1_7AAE_9CAB_i64, // 161 - 0x732C_14D9_8235_857D_i64, - 0x032D_2968_C44A_9445_i64, // 162 - 0x5C23_43E1_34F7_9DFD_i64, - 0x4F57_5453_D03B_A9D1_i64, // 163 - 0x49B5_CFE7_5D92_E4CA_i64, - 0x72AC_4376_402F_BB0E_i64, // 164 - 0x75EF_B30B_C8EB_07AB_i64, - 0x0446_D256_CD19_2B49_i64, // 165 - 0x5E59_5C09_6D88_D2EF_i64, - 0x1D05_7512_3DAD_BC3A_i64, // 166 - 0x4B7A_B007_8AD3_DBF2_i64, - 0x4A6A_C40E_97BE_302F_i64, // 167 - 0x78C4_4CD8_DE1F_C650_i64, - 0x7711_39B0_F2C9_E6B1_i64, // 168 - 0x609D_0A47_1819_6B73_i64, - 0x78DA_948D_8F07_EBC1_i64, // 169 - 0x4D4A_6E9F_467A_BC5C_i64, - 0x60AE_DD3E_0C06_5634_i64, // 170 - 0x7BAA_4A98_70C4_6094_i64, - 0x344A_FB96_79A3_BD20_i64, // 171 - 0x62EE_A213_8D69_E6DD_i64, - 0x103B_FC78_614F_CA80_i64, // 172 - 0x4F25_4E76_0ABB_1F17_i64, - 0x2696_6393_810C_A200_i64, // 173 - 0x7EA2_1723_445E_9825_i64, - 0x2423_D285_9B47_6999_i64, // 174 - 0x654E_78E9_037E_E01D_i64, - 0x69B6_4204_7C39_2148_i64, // 175 - 0x510B_93ED_9C65_8017_i64, - 0x6E2B_6803_9694_1AA0_i64, // 176 - 0x40D6_0FF1_49EA_CCDF_i64, - 0x71BC_5336_1210_154D_i64, // 177 - 0x67BC_E64E_DCAA_E166_i64, - 0x1C60_8523_5019_BBAE_i64, // 178 - 0x52FD_850B_E3BB_E784_i64, - 0x7D1A_041C_4014_9625_i64, // 179 - 0x4264_6A6F_E963_1F9D_i64, - 0x4A7B_367D_0010_781D_i64, // 180 - 0x6A3A_43E6_4238_3295_i64, - 0x5D91_F0C8_001A_59C8_i64, // 181 - 0x54FB_6985_01C6_8EDE_i64, - 0x17A7_F3D3_3348_47D4_i64, // 182 - 0x43FC_546A_67D2_0BE4_i64, - 0x7953_2975_C2A0_3976_i64, // 183 - 0x6CC6_ED77_0C83_463B_i64, - 0x0EEB_7589_3766_C256_i64, // 184 - 0x5705_8AC5_A39C_382F_i64, - 0x2589_2AD4_2C52_3512_i64, // 185 - 0x459E_089E_1C7C_F9BF_i64, - 0x37A0_EF10_2374_F742_i64, // 186 - 0x6F63_40FC_FA61_8F98_i64, - 0x5901_7E80_38BB_2536_i64, // 187 - 0x591C_33FD_951A_D946_i64, - 0x7A67_9866_93C8_EA91_i64, // 188 - 0x4749_C331_4415_7A9F_i64, - 0x151F_AD1E_DCA0_BBA8_i64, // 189 - 0x720F_9EB5_39BB_F765_i64, - 0x0832_AE97_C767_92A5_i64, // 190 - 0x5B3F_B22A_9496_5F84_i64, - 0x068E_F213_05EC_7551_i64, // 191 - 0x48FF_C1BB_AA11_E603_i64, - 0x1ED8_C1A8_D189_F774_i64, // 192 - 0x74CC_692C_434F_D66B_i64, - 0x4AF4_690E_1C0F_F253_i64, // 193 - 0x5D70_5423_690C_AB89_i64, - 0x225D_20D8_1673_2843_i64, // 194 - 0x4AC0_434F_873D_5607_i64, - 0x3517_4D79_AB8F_5369_i64, // 195 - 0x779A_054C_0B95_5672_i64, - 0x21BE_E25C_45B2_1F0E_i64, // 196 - 0x5FAE_6AA3_3C77_785B_i64, - 0x3498_B516_9E28_18D8_i64, // 197 - 0x4C8B_8882_96C5_F9E2_i64, - 0x5D46_F745_4B53_4713_i64, // 198 - 0x7A78_DA6A_8AD6_5C9D_i64, - 0x7BA4_BED5_4552_0B52_i64, // 199 - 0x61FA_4855_3BDE_B07E_i64, - 0x2FB6_FF11_0441_A2A8_i64, // 200 - 0x4E61_D377_6318_8D31_i64, - 0x72F8_CC0D_9D01_4EED_i64, // 201 - 0x7D69_5258_9E8D_AEB6_i64, - 0x1E5A_E015_C802_17E1_i64, // 202 - 0x6454_41E0_7ED7_BEF8_i64, - 0x1848_B344_A001_ACB4_i64, // 203 - 0x5043_67E6_CBDF_CBF9_i64, - 0x603A_2903_B334_8A2A_i64, // 204 - 0x4035_ECB8_A319_6FFB_i64, - 0x002E_8736_28F6_D4EE_i64, // 205 - 0x66BC_ADF4_3828_B32B_i64, - 0x19E4_0B89_DB24_87E3_i64, // 206 - 0x5230_8B29_C686_F5BC_i64, - 0x14B6_6FA1_7C1D_3983_i64, // 207 - 0x41C0_6F54_9ED2_5E30_i64, - 0x1091_F2E7_967D_C79C_i64, // 208 - 0x6933_E554_3150_96B3_i64, - 0x341C_B7D8_F0C9_3F5F_i64, // 209 - 0x5429_8443_5AA6_DEF5_i64, - 0x767D_5FE0_C0A0_FF80_i64, // 210 - 0x4354_69CF_7BB8_B25E_i64, - 0x2B97_7FE7_0080_CC66_i64, // 211 - 0x6BBA_42E5_92C1_1D63_i64, - 0x5F58_CCA4_CD9A_E0A3_i64, // 212 - 0x562E_9BEA_DBCD_B11C_i64, - 0x4C47_0A1D_7148_B3B6_i64, // 213 - 0x44F2_1655_7CA4_8DB0_i64, - 0x3D05_A1B1_276D_5C92_i64, // 214 - 0x6E50_23BB_FAA0_E2B3_i64, - 0x7B3C_35E8_3F15_60E9_i64, // 215 - 0x5840_1C96_621A_4EF6_i64, - 0x2F63_5E53_65AA_B3ED_i64, // 216 - 0x4699_B078_4E7B_725E_i64, - 0x591C_4B75_EAEE_F658_i64, // 217 - 0x70F5_E726_E3F8_B6FD_i64, - 0x74FA_1256_44B1_8A26_i64, // 218 - 0x5A5E_5285_832D_5F31_i64, - 0x43FB_41DE_9D5A_D4EB_i64, // 219 - 0x484B_7537_9C24_4C27_i64, - 0x4FFC_34B2_177B_DD89_i64, // 220 - 0x73AB_EEBF_603A_1372_i64, - 0x4CC6_BAB6_8BF9_6274_i64, // 221 - 0x5C89_8BCC_4CFB_42C2_i64, - 0x0A38_955E_D661_1B90_i64, // 222 - 0x4A07_A309_D72F_689B_i64, - 0x21C6_DDE5_784D_AFA7_i64, // 223 - 0x7672_9E76_2518_A75E_i64, - 0x693E_2FD5_8D49_190B_i64, // 224 - 0x5EC2_185E_8413_B918_i64, - 0x5431_BFDE_0AA0_E0D5_i64, // 225 - 0x4BCE_79E5_3676_2DAD_i64, - 0x29C1_664B_3BB3_E711_i64, // 226 - 0x794A_5CA1_F0BD_15E2_i64, - 0x0F9B_D6DE_C5EC_A4E8_i64, // 227 - 0x6108_4A1B_26FD_AB1B_i64, - 0x2616_457F_04BD_50BA_i64, // 228 - 0x4DA0_3B48_EBFE_227C_i64, - 0x1E78_3798_D097_73C8_i64, // 229 - 0x7C33_920E_4663_6A60_i64, - 0x30C0_58F4_80F2_52D9_i64, // 230 - 0x635C_74D8_384F_884D_i64, - 0x0D66_AD90_6728_4247_i64, // 231 - 0x4F7D_2A46_9372_D370_i64, - 0x711E_F140_5286_9B6C_i64, // 232 - 0x7F2E_AA0A_8584_8581_i64, - 0x34FE_4ECD_50D7_5F14_i64, // 233 - 0x65BE_EE6E_D136_D134_i64, - 0x2A65_0BD7_73DF_7F43_i64, // 234 - 0x5165_8B8B_DA92_40F6_i64, - 0x551D_A312_C319_329C_i64, // 235 - 0x411E_093C_AEDB_672B_i64, - 0x5DB1_4F42_35AD_C217_i64, // 236 - 0x6830_0EC7_7E2B_D845_i64, - 0x7C4E_E536_BC49_368A_i64, // 237 - 0x5359_A56C_64EF_E037_i64, - 0x7D0B_EA92_303A_9208_i64, // 238 - 0x42AE_1DF0_50BF_E693_i64, - 0x173C_BBA8_2695_41A0_i64, // 239 - 0x6AB0_2FE6_E799_70EB_i64, - 0x3EC7_92A6_A422_029A_i64, // 240 - 0x5559_BFEB_EC7A_C0BC_i64, - 0x3239_421E_E9B4_CEE1_i64, // 241 - 0x4447_CCBC_BD2F_0096_i64, - 0x5B61_01B2_5490_A581_i64, // 242 - 0x6D3F_ADFA_C84B_3424_i64, - 0x2BCE_691D_541A_A268_i64, // 243 - 0x5766_24C8_A03C_29B6_i64, - 0x563E_BA7D_DCE2_1B87_i64, // 244 - 0x45EB_50A0_8030_215E_i64, - 0x7832_2ECB_171B_4939_i64, // 245 - 0x6FDE_E767_3380_3564_i64, - 0x59E9_E478_24F8_7527_i64, // 246 - 0x597F_1F85_C2CC_F783_i64, - 0x6187_E9F9_B72D_2A86_i64, // 247 - 0x4798_E604_9BD7_2C69_i64, - 0x346C_BB2E_2C24_2205_i64, // 248 - 0x728E_3CD4_2C8B_7A42_i64, - 0x20AD_F849_E039_D007_i64, // 249 - 0x5BA4_FD76_8A09_2E9B_i64, - 0x33BE_603B_19C7_D99F_i64, // 250 - 0x4950_CAC5_3B3A_8BAF_i64, - 0x42FE_B362_7B06_47B3_i64, // 251 - 0x754E_113B_91F7_45E5_i64, - 0x5197_856A_5E70_72B8_i64, // 252 - 0x5DD8_0DC9_4192_9E51_i64, - 0x27AC_6ABB_7EC0_5BC6_i64, // 253 - 0x4B13_3E3A_9ADB_B1DA_i64, - 0x52F0_5562_CBCD_1638_i64, // 254 - 0x781E_C9F7_5E2C_4FC4_i64, - 0x1E4D_556A_DFAE_89F3_i64, // 255 - 0x6018_A192_B1BD_0C9C_i64, - 0x7EA4_4455_7FBE_D4C3_i64, // 256 - 0x4CE0_8142_27CA_707D_i64, - 0x4BB6_9D11_32FF_109C_i64, // 257 - 0x7B00_CED0_3FAA_4D95_i64, - 0x5F8A_94E8_5198_1A93_i64, // 258 - 0x6267_0BD9_CC88_3E11_i64, - 0x32D5_43ED_0E13_4875_i64, // 259 - 0x4EB8_D647_D6D3_64DA_i64, - 0x5BDD_CFF0_D80F_6D2B_i64, // 260 - 0x7DF4_8A0C_8AEB_D491_i64, - 0x12FC_7FE7_C018_AEAB_i64, // 261 - 0x64C3_A1A3_A256_43A7_i64, - 0x28C9_FFEC_99AD_5889_i64, // 262 - 0x509C_814F_B511_CFB9_i64, - 0x0707_FFF0_7AF1_13A1_i64, // 263 - 0x407D_343F_C40E_3FC7_i64, - 0x1F39_998D_2F27_42E7_i64, // 264 - 0x672E_B9FF_A016_CC71_i64, - 0x7EC2_8F48_4B72_04A4_i64, // 265 - 0x528B_C7FF_B345_705B_i64, - 0x189B_A5D3_6F8E_6A1D_i64, // 266 - 0x4209_6CCC_8F6A_C048_i64, - 0x7A16_1E42_BFA5_21B1_i64, // 267 - 0x69A8_AE14_18AA_CD41_i64, - 0x4356_96D1_32A1_CF81_i64, // 268 - 0x5486_F1A9_AD55_7101_i64, - 0x1C45_4574_2881_72CE_i64, // 269 - 0x439F_27BA_F111_2734_i64, - 0x169D_D129_BA01_28A5_i64, // 270 - 0x6C31_D92B_1B4E_A520_i64, - 0x242F_B50F_9001_DAA1_i64, // 271 - 0x568E_4755_AF72_1DB3_i64, - 0x368C_90D9_4001_7BB4_i64, // 272 - 0x453E_9F77_BF8E_7E29_i64, - 0x120A_0D7A_999A_C95D_i64, // 273 - 0x6ECA_98BF_98E3_FD0E_i64, - 0x5010_1590_F5C4_7561_i64, // 274 - 0x58A2_13CC_7A4F_FDA5_i64, - 0x2673_4473_F7D0_5DE8_i64, // 275 - 0x46E8_0FD6_C83F_FE1D_i64, - 0x6B8F_69F6_5FD9_E4B9_i64, // 276 - 0x7173_4C8A_D9FF_FCFC_i64, - 0x45B2_4323_CC8F_D45C_i64, // 277 - 0x5AC2_A3A2_47FF_FD96_i64, - 0x6AF5_0283_0A0C_A9E3_i64, // 278 - 0x489B_B61B_6CCC_CADF_i64, - 0x08C4_0202_6E70_87E9_i64, // 279 - 0x742C_5692_47AE_1164_i64, - 0x746C_D003_E3E7_3FDB_i64, // 280 - 0x5CF0_4541_D2F1_A783_i64, - 0x76BD_7336_4FEC_3315_i64, // 281 - 0x4A59_D101_758E_1F9C_i64, - 0x5EFD_F5C5_0CBC_F5AB_i64, // 282 - 0x76F6_1B35_88E3_65C7_i64, - 0x4B2F_EFA1_ADFB_22AB_i64, // 283 - 0x5F2B_48F7_A0B5_EB06_i64, - 0x08F3_261A_F195_B555_i64, // 284 - 0x4C22_A0C6_1A2B_226B_i64, - 0x20C2_84E2_5ADE_2AAB_i64, // 285 - 0x79D1_013C_F6AB_6A45_i64, - 0x1AD0_D49D_5E30_4444_i64, // 286 - 0x6174_00FD_9222_BB6A_i64, - 0x48A7_107D_E4F3_69D0_i64, // 287 - 0x4DF6_6731_41B5_62BB_i64, - 0x53B8_D9FE_50C2_BB0D_i64, // 288 - 0x7CBD_71E8_6922_3792_i64, - 0x52C1_5CCA_1AD1_2B48_i64, // 289 - 0x63CA_C186_BA81_C60E_i64, - 0x7567_7D6E_7BDA_8906_i64, // 290 - 0x4FD5_679E_FB9B_04D8_i64, - 0x5DEC_6458_6315_3A6C_i64, // 291 - 0x7FBB_D8FE_5F5E_6E27_i64, - 0x497A_3A27_04EE_C3DF_i64, // 292 + 0x4F0C_EDC9_5A71_8DD4, + 0x5B01_E8B0_9AA0_D1B5, // -324 + 0x7E7B_160E_F71C_1621, + 0x119C_A780_F767_B5EE, // -323 + 0x652F_44D8_C5B0_11B4, + 0x0E16_EC67_2C52_F7F2, // -322 + 0x50F2_9D7A_37C0_0E29, + 0x5812_56B8_F042_5FF5, // -321 + 0x40C2_1794_F966_71BA, + 0x79A8_4560_C035_1991, // -320 + 0x679C_F287_F570_B5F7, + 0x75DA_089A_CD21_C281, // -319 + 0x52E3_F539_9126_F7F9, + 0x44AE_6D48_A41B_0201, // -318 + 0x424F_F761_40EB_F994, + 0x36F1_F106_E9AF_34CD, // -317 + 0x6A19_8BCE_CE46_5C20, + 0x57E9_81A4_A918_547B, // -316 + 0x54E1_3CA5_71D1_E34D, + 0x2CBA_CE1D_5413_76C9, // -315 + 0x43E7_63B7_8E41_82A4, + 0x23C8_A4E4_4342_C56E, // -314 + 0x6CA5_6C58_E39C_043A, + 0x060D_D4A0_6B9E_08B0, // -313 + 0x56EA_BD13_E949_9CFB, + 0x1E71_76E6_BC7E_6D59, // -312 + 0x4588_9743_2107_B0C8, + 0x7EC1_2BEB_C9FE_BDE1, // -311 + 0x6F40_F205_01A5_E7A7, + 0x7E01_DFDF_A997_9635, // -310 + 0x5900_C19D_9AEB_1FB9, + 0x4B34_B319_5479_44F7, // -309 + 0x4733_CE17_AF22_7FC7, + 0x55C3_C27A_A9FA_9D93, // -308 + 0x71EC_7CF2_B1D0_CC72, + 0x5606_03F7_765D_C8EA, // -307 + 0x5B23_9728_8E40_A38E, + 0x7804_CFF9_2B7E_3A55, // -306 + 0x48E9_45BA_0B66_E93F, + 0x1337_0CC7_55FE_9511, // -305 + 0x74A8_6F90_123E_41FE, + 0x51F1_AE0B_BCCA_881B, // -304 + 0x5D53_8C73_41CB_67FE, + 0x74C1_5809_63D5_39AF, // -303 + 0x4AA9_3D29_016F_8665, + 0x43CD_E007_8310_FAF3, // -302 + 0x7775_2EA8_024C_0A3C, + 0x0616_333F_381B_2B1E, // -301 + 0x5F90_F220_01D6_6E96, + 0x3811_C298_F9AF_55B1, // -300 + 0x4C73_F4E6_67DE_BEDE, + 0x600E_3547_2E25_DE28, // -299 + 0x7A53_2170_A631_3164, + 0x3349_EED8_49D6_303F, // -298 + 0x61DC_1AC0_84F4_2783, + 0x42A1_8BE0_3B11_C033, // -297 + 0x4E49_AF00_6A5C_EC69, + 0x1BB4_6FE6_95A7_CCF5, // -296 + 0x7D42_B19A_43C7_E0A8, + 0x2C53_E63D_BC3F_AE55, // -295 + 0x6435_5AE1_CFD3_1A20, + 0x2376_51CA_FCFF_BEAA, // -294 + 0x502A_AF1B_0CA8_E1B3, + 0x35F8_416F_30CC_9888, // -293 + 0x4022_25AF_3D53_E7C2, + 0x5E60_3458_F3D6_E06D, // -292 + 0x669D_0918_621F_D937, + 0x4A33_86F4_B957_CD7B, // -291 + 0x5217_3A79_E819_7A92, + 0x6E8F_9F2A_2DDF_D796, // -290 + 0x41AC_2EC7_ECE1_2EDB, + 0x720C_7F54_F17F_DFAB, // -289 + 0x6913_7E0C_AE35_17C6, + 0x1CE0_CBBB_1BFF_CC45, // -288 + 0x540F_980A_24F7_4638, + 0x171A_3C95_AFFF_D69E, // -287 + 0x433F_ACD4_EA5F_6B60, + 0x127B_63AA_F333_1218, // -286 + 0x6B99_1487_DD65_7899, + 0x6A5F_05DE_51EB_5026, // -285 + 0x5614_106C_B11D_FA14, + 0x5518_D17E_A7EF_7352, // -284 + 0x44DC_D9F0_8DB1_94DD, + 0x2A7A_4132_1FF2_C2A8, // -283 + 0x6E2E_2980_E2B5_BAFB, + 0x5D90_6850_331E_043F, // -282 + 0x5824_EE00_B55E_2F2F, + 0x6473_86A6_8F4B_3699, // -281 + 0x4683_F19A_2AB1_BF59, + 0x36C2_D21E_D908_F87B, // -280 + 0x70D3_1C29_DDE9_3228, + 0x579E_1CFE_280E_5A5D, // -279 + 0x5A42_7CEE_4B20_F4ED, + 0x2C7E_7D98_200B_7B7E, // -278 + 0x4835_30BE_A280_C3F1, + 0x09FE_CAE0_19A2_C932, // -277 + 0x7388_4DFD_D0CE_064E, + 0x4331_4499_C29E_0EB6, // -276 + 0x5C6D_0B31_73D8_050B, + 0x4F5A_9D47_CEE4_D891, // -275 + 0x49F0_D5C1_2979_9DA2, + 0x72AE_E439_7250_AD41, // -274 + 0x764E_22CE_A8C2_95D1, + 0x377E_39F5_83B4_4868, // -273 + 0x5EA4_E8A5_53CE_DE41, + 0x12CB_6191_3629_D387, // -272 + 0x4BB7_2084_430B_E500, + 0x756F_8140_F821_7605, // -271 + 0x7925_00D3_9E79_6E67, + 0x6F18_CECE_59CF_233C, // -270 + 0x60EA_670F_B1FA_BEB9, + 0x3F47_0BD8_47D8_E8FD, // -269 + 0x4D88_5272_F4C8_9894, + 0x329F_3CAD_0647_20CA, // -268 + 0x7C0D_50B7_EE0D_C0ED, + 0x3765_2DE1_A3A5_0143, // -267 + 0x633D_DA2C_BE71_6724, + 0x2C50_F181_4FB7_3436, // -266 + 0x4F64_AE8A_31F4_5283, + 0x3D0D_8E01_0C92_902B, // -265 + 0x7F07_7DA9_E986_EA6B, + 0x7B48_E334_E0EA_8045, // -264 + 0x659F_97BB_2138_BB89, + 0x4907_1C2A_4D88_669D, // -263 + 0x514C_7962_80FA_2FA1, + 0x20D2_7CEE_A46D_1EE4, // -262 + 0x4109_FAB5_33FB_594D, + 0x670E_CA58_838A_7F1D, // -261 + 0x680F_F788_532B_C216, + 0x0B4A_DD5A_6C10_CB62, // -260 + 0x533F_F939_DC23_01AB, + 0x22A2_4AAE_BCDA_3C4E, // -259 + 0x4299_942E_49B5_9AEF, + 0x354E_A225_63E1_C9D8, // -258 + 0x6A8F_537D_42BC_2B18, + 0x554A_9D08_9FCF_A95A, // -257 + 0x553F_75FD_CEFC_EF46, + 0x776E_E406_E63F_BAAE, // -256 + 0x4432_C4CB_0BFD_8C38, + 0x5F8B_E99F_1E99_6225, // -255 + 0x6D1E_07AB_4662_79F4, + 0x3279_75CB_6428_9D08, // -254 + 0x574B_3955_D1E8_6190, + 0x2861_2B09_1CED_4A6D, // -253 + 0x45D5_C777_DB20_4E0D, + 0x06B4_226D_B0BD_D524, // -252 + 0x6FBC_7259_5E9A_167B, + 0x2453_6A49_1AC9_5506, // -251 + 0x5963_8EAD_E548_11FC, + 0x1D0F_883A_7BD4_4405, // -250 + 0x4782_D88B_1DD3_4196, + 0x4A72_D361_FCA9_D004, // -249 + 0x726A_F411_C952_028A, + 0x43EA_EBCF_FAA9_4CD3, // -248 + 0x5B88_C341_6DDB_353B, + 0x4FEF_230C_C887_70A9, // -247 + 0x493A_35CD_F17C_2A96, + 0x0CBF_4F3D_6D39_26EE, // -246 + 0x7529_EFAF_E8C6_AA89, + 0x6132_1862_485B_717C, // -245 + 0x5DBB_2626_53D2_2207, + 0x675B_46B5_06AF_8DFD, // -244 + 0x4AFC_1E85_0FDB_4E6C, + 0x52AF_6BC4_0559_3E64, // -243 + 0x77F9_CA6E_7FC5_4A47, + 0x377F_12D3_3BC1_FD6D, // -242 + 0x5FFB_0858_6637_6E9F, + 0x45FF_4242_9634_CABD, // -241 + 0x4CC8_D379_EB5F_8BB2, + 0x6B32_9B68_782A_3BCB, // -240 + 0x7ADA_EBF6_4565_AC51, + 0x2B84_2BDA_59DD_2C77, // -239 + 0x6248_BCC5_0451_56A7, + 0x3C69_BCAE_AE4A_89F9, // -238 + 0x4EA0_9704_0374_4552, + 0x6387_CA25_583B_A194, // -237 + 0x7DCD_BE6C_D253_A21E, + 0x05A6_103B_C05F_68ED, // -236 + 0x64A4_9857_0EA9_4E7E, + 0x37B8_0CFC_99E5_ED8A, // -235 + 0x5083_AD12_7221_0B98, + 0x2C93_3D96_E184_BE08, // -234 + 0x4069_5741_F4E7_3C79, + 0x7075_CADF_1AD0_9807, // -233 + 0x670E_F203_2171_FA5C, + 0x4D89_4498_2AE7_59A4, // -232 + 0x5272_5B35_B45B_2EB0, + 0x3E07_6A13_5585_E150, // -231 + 0x41F5_15C4_9048_F226, + 0x64D2_BB42_AAD1_810D, // -230 + 0x6988_22D4_1A0E_503E, + 0x07B7_9204_4482_6815, // -229 + 0x546C_E8A9_AE71_D9CB, + 0x1FC6_0E69_D068_5344, // -228 + 0x438A_53BA_F1F4_AE3C, + 0x196B_3EBB_0D20_429D, // -227 + 0x6C10_85F7_E987_7D2D, + 0x0F11_FDF8_1500_6A94, // -226 + 0x5673_9E5F_EE05_FDBD, + 0x58DB_3193_4400_5543, // -225 + 0x4529_4B7F_F19E_6497, + 0x60AF_5ADC_3666_AA9C, // -224 + 0x6EA8_78CC_B5CA_3A8C, + 0x344B_C493_8A3D_DDC7, // -223 + 0x5886_C70A_2B08_2ED6, + 0x5D09_6A0F_A1CB_17D2, // -222 + 0x46D2_38D4_EF39_BF12, + 0x173A_BB3F_B4A2_7975, // -221 + 0x7150_5AEE_4B8F_981D, + 0x0B91_2B99_2103_F588, // -220 + 0x5AA6_AF25_093F_ACE4, + 0x0940_EFAD_B403_2AD3, // -219 + 0x4885_58EA_6DCC_8A50, + 0x0767_2624_9002_88A9, // -218 + 0x7408_8E43_E2E0_DD4C, + 0x723E_A36D_B337_410E, // -217 + 0x5CD3_A503_1BE7_1770, + 0x5B65_4F8A_F5C5_CDA5, // -216 + 0x4A42_EA68_E31F_45F3, + 0x62B7_72D5_916B_0AEB, // -215 + 0x76D1_770E_3832_0986, + 0x0458_B7BC_1BDE_77DD, // -214 + 0x5F0D_F8D8_2CF4_D46B, + 0x1D13_C630_164B_9318, // -213 + 0x4C0B_2D79_BD90_A9EF, + 0x30DC_9E8C_DEA2_DC13, // -212 + 0x79AB_7BF5_FC1A_A97F, + 0x0160_FDAE_3104_9351, // -211 + 0x6155_FCC4_C9AE_EDFF, + 0x1AB3_FE24_F403_A90E, // -210 + 0x4DDE_63D0_A158_BE65, + 0x6229_981D_9002_EDA5, // -209 + 0x7C97_061A_9BC1_30A2, + 0x69DC_2695_B337_E2A1, // -208 + 0x63AC_04E2_1634_26E8, + 0x54B0_1EDE_28F9_821B, // -207 + 0x4FBC_D0B4_DE90_1F20, + 0x43C0_18B1_BA61_34E2, // -206 + 0x7F94_8121_6419_CB67, + 0x1F99_C11C_5D68_549D, // -205 + 0x6610_674D_E9AE_3C52, + 0x4C7B_00E3_7DED_107E, // -204 + 0x51A6_B90B_2158_3042, + 0x09FC_00B5_FE57_4065, // -203 + 0x4152_2DA2_8113_59CE, + 0x3B30_0091_9845_CD1D, // -202 + 0x6883_7C37_34EB_C2E3, + 0x784C_CDB5_C06F_AE95, // -201 + 0x539C_635F_5D89_68B6, + 0x2D0A_3E2B_0059_5877, // -200 + 0x42E3_82B2_B13A_BA2B, + 0x3DA1_CB55_99E1_1393, // -199 + 0x6B05_9DEA_B52A_C378, + 0x629C_7888_F634_EC1E, // -198 + 0x559E_17EE_F755_692D, + 0x3549_FA07_2B5D_89B1, // -197 + 0x447E_798B_F911_20F1, + 0x1107_FB38_EF7E_07C1, // -196 + 0x6D97_28DF_F4E8_34B5, + 0x01A6_5EC1_7F30_0C68, // -195 + 0x57AC_20B3_2A53_5D5D, + 0x4E1E_B234_65C0_09ED, // -194 + 0x4623_4D5C_21DC_4AB1, + 0x24E5_5B5D_1E33_3B24, // -193 + 0x7038_7BC6_9C93_AAB5, + 0x216E_F894_FD1E_C506, // -192 + 0x59C6_C96B_B076_222A, + 0x4DF2_6077_30E5_6A6C, // -191 + 0x47D2_3ABC_8D2B_4E88, + 0x3E5B_805F_5A51_21F0, // -190 + 0x72E9_F794_1512_1740, + 0x63C5_9A32_2A1B_697F, // -189 + 0x5BEE_5FA9_AA74_DF67, + 0x0304_7B5B_54E2_BACC, // -188 + 0x498B_7FBA_EEC3_E5EC, + 0x0269_FC49_10B5_623D, // -187 + 0x75AB_FF91_7E06_3CAC, + 0x6A43_2D41_B455_69FB, // -186 + 0x5E23_32DA_CB38_308A, + 0x21CF_5767_C377_87FC, // -185 + 0x4B4F_5BE2_3C2C_F3A1, + 0x67D9_12B9_692C_6CCA, // -184 + 0x787E_F969_F9E1_85CF, + 0x595B_5128_A847_1476, // -183 + 0x6065_9454_C7E7_9E3F, + 0x6115_DA86_ED05_A9F8, // -182 + 0x4D1E_1043_D31F_B1CC, + 0x4DAB_1538_BD9E_2193, // -181 + 0x7B63_4D39_51CC_4FAD, + 0x62AB_5527_95C9_CF52, // -180 + 0x62B5_D761_0E3D_0C8B, + 0x0222_AA86_116E_3F75, // -179 + 0x4EF7_DF80_D830_D6D5, + 0x4E82_2204_DABE_992A, // -178 + 0x7E59_659A_F381_57BC, + 0x1736_9CD4_9130_F510, // -177 + 0x6514_5148_C2CD_DFC9, + 0x5F5E_E3DD_40F3_F740, // -176 + 0x50DD_0DD3_CF0B_196E, + 0x1918_B64A_9A5C_C5CD, // -175 + 0x40B0_D7DC_A5A2_7ABE, + 0x4746_F83B_AEB0_9E3E, // -174 + 0x6781_5961_0903_F797, + 0x253E_59F9_1780_FD2F, // -173 + 0x52CD_E11A_6D9C_C612, + 0x50FE_AE60_DF9A_6426, // -172 + 0x423E_4DAE_BE17_04DB, + 0x5A65_584D_7FAE_B685, // -171 + 0x69FD_4917_968B_3AF9, + 0x10A2_26E2_65E4_573B, // -170 + 0x54CA_A0DF_ABA2_9594, + 0x0D4E_8581_EB1D_1295, // -169 + 0x43D5_4D7F_BC82_1143, + 0x243E_D134_BC17_4211, // -168 + 0x6C88_7BFF_9403_4ED2, + 0x06CA_E854_6025_3682, // -167 + 0x56D3_9666_1002_A574, + 0x6BD5_86A9_E684_2B9B, // -166 + 0x4576_11EB_4002_1DF7, + 0x0977_9EEE_5203_5616, // -165 + 0x6F23_4FDE_CCD0_2FF1, + 0x5BF2_97E3_B66B_BCEF, // -164 + 0x58E9_0CB2_3D73_598E, + 0x165B_ACB6_2B89_63F3, // -163 + 0x4720_D6F4_FDF5_E13E, + 0x4516_23C4_EFA1_1CC2, // -162 + 0x71CE_24BB_2FEF_CECA, + 0x3B56_9FA1_7F68_2E03, // -161 + 0x5B0B_5095_BFF3_0BD5, + 0x15DE_E61A_CC53_5803, // -160 + 0x48D5_DA11_665C_0977, + 0x2B18_B815_7042_ACCF, // -159 + 0x7489_5CE8_A3C6_758B, + 0x5E8D_F355_806A_AE18, // -158 + 0x5D3A_B0BA_1C9E_C46F, + 0x653E_5C44_66BB_BE7A, // -157 + 0x4A95_5A2E_7D4B_D059, + 0x3765_169D_1EFC_9861, // -156 + 0x7755_5D17_2EDF_B3C2, + 0x256E_8A94_FE60_F3CF, // -155 + 0x5F77_7DAC_257F_C301, + 0x6ABE_D543_FEB3_F63F, // -154 + 0x4C5F_97BC_EACC_9C01, + 0x3BCB_DDCF_FEF6_5E99, // -153 + 0x7A32_8C61_77AD_C668, + 0x5FAC_9619_97F0_975B, // -152 + 0x61C2_09E7_92F1_6B86, + 0x7FBD_44E1_465A_12AF, // -151 + 0x4E34_D4B9_425A_BC6B, + 0x7FCA_9D81_0514_DBBF, // -150 + 0x7D21_545B_9D5D_FA46, + 0x32DD_C8CE_6E87_C5FF, // -149 + 0x641A_A9E2_E44B_2E9E, + 0x5BE4_A0A5_2539_6B32, // -148 + 0x5015_54B5_836F_587E, + 0x7CB6_E6EA_842D_EF5C, // -147 + 0x4011_1091_35F2_AD32, + 0x3092_5255_368B_25E3, // -146 + 0x6681_B41B_8984_4850, + 0x4DB6_EA21_F0DE_A304, // -145 + 0x5201_5CE2_D469_D373, + 0x57C5_881B_2718_826A, // -144 + 0x419A_B0B5_76BB_0F8F, + 0x5FD1_39AF_527A_01EF, // -143 + 0x68F7_8122_5791_B27F, + 0x4C81_F5E5_50C3_364A, // -142 + 0x53F9_341B_7941_5B99, + 0x239B_2B1D_DA35_C508, // -141 + 0x432D_C349_2DCD_E2E1, + 0x02E2_88E4_AE91_6A6D, // -140 + 0x6B7C_6BA8_4949_6B01, + 0x516A_74A1_174F_10AE, // -139 + 0x55FD_22ED_076D_EF34, + 0x4121_F6E7_45D8_DA25, // -138 + 0x44CA_8257_3924_BF5D, + 0x1A81_9252_9E47_14EB, // -137 + 0x6E10_D08B_8EA1_322E, + 0x5D9C_1D50_FD3E_87DD, // -136 + 0x580D_73A2_D880_F4F2, + 0x17B0_1773_FDCB_9FE4, // -135 + 0x4671_294F_139A_5D8E, + 0x4626_7929_97D6_1984, // -134 + 0x70B5_0EE4_EC2A_2F4A, + 0x3D0A_5B75_BFBC_F59F, // -133 + 0x5A2A_7250_BCEE_8C3B, + 0x4A6E_AF91_6630_C47F, // -132 + 0x4821_F50D_63F2_09C9, + 0x21F2_260D_EB5A_36CC, // -131 + 0x7369_8815_6CB6_760E, + 0x6983_7016_455D_247A, // -130 + 0x5C54_6CDD_F091_F80B, + 0x6E02_C011_D117_5062, // -129 + 0x49DD_23E4_C074_C66F, + 0x719B_CCDB_0DAC_404E, // -128 + 0x762E_9FD4_6721_3D7F, + 0x68F9_47C4_E2AD_33B0, // -127 + 0x5E8B_B310_5280_FDFF, + 0x6D94_396A_4EF0_F627, // -126 + 0x4BA2_F5A6_A867_3199, + 0x3E10_2DEE_A58D_91B9, // -125 + 0x7904_BC3D_DA3E_B5C2, + 0x3019_E317_6F48_E927, // -124 + 0x60D0_9697_E1CB_C49B, + 0x4014_B5AC_5907_20EC, // -123 + 0x4D73_ABAC_B4A3_03AF, + 0x4CDD_5E23_7A6C_1A57, // -122 + 0x7BEC_45E1_2104_D2B2, + 0x47C8_969F_2A46_908A, // -121 + 0x6323_6B1A_80D0_A88E, + 0x6CA0_787F_5505_406F, // -120 + 0x4F4F_88E2_00A6_ED3F, + 0x0A19_F9FF_7737_66BF, // -119 + 0x7EE5_A7D0_010B_1531, + 0x5CF6_5CCB_F1F2_3DFE, // -118 + 0x6584_8640_00D5_AA8E, + 0x172B_7D6F_F4C1_CB32, // -117 + 0x5136_D1CC_CD77_BBA4, + 0x78EF_978C_C3CE_3C28, // -116 + 0x40F8_A7D7_0AC6_2FB7, + 0x13F2_DFA3_CFD8_3020, // -115 + 0x67F4_3FBE_77A3_7F8B, + 0x3984_9906_1959_E699, // -114 + 0x5329_CC98_5FB5_FFA2, + 0x6136_E0D1_ADE1_8548, // -113 + 0x4287_D6E0_4C91_994F, + 0x00F8_B3DA_F181_376D, // -112 + 0x6A72_F166_E0E8_F54B, + 0x1B27_862B_1C01_F247, // -111 + 0x5528_C11F_1A53_F76F, + 0x2F52_D1BC_1667_F506, // -110 + 0x4420_9A7F_4843_2C59, + 0x0C42_4163_451F_F738, // -109 + 0x6D00_F732_0D38_46F4, + 0x7A03_9BD2_0833_2526, // -108 + 0x5733_F8F4_D760_38C3, + 0x7B36_1641_A028_EA85, // -107 + 0x45C3_2D90_AC4C_FA36, + 0x2F5E_7834_8020_BB9E, // -106 + 0x6F9E_AF4D_E07B_29F0, + 0x4BCA_59ED_99CD_F8FC, // -105 + 0x594B_BF71_8062_87F3, + 0x563B_7B24_7B0B_2D96, // -104 + 0x476F_CC5A_CD1B_9FF6, + 0x11C9_2F50_626F_57AC, // -103 + 0x724C_7A2A_E1C5_CCBD, + 0x02DB_7EE7_03E5_5912, // -102 + 0x5B70_61BB_E7D1_7097, + 0x1BE2_CBEC_031D_E0DC, // -101 + 0x4926_B496_530D_F3AC, + 0x164F_0989_9C17_E716, // -100 + 0x750A_BA8A_1E7C_B913, + 0x3D4B_4275_C68C_A4F0, // -99 + 0x5DA2_2ED4_E530_940F, + 0x4AA2_9B91_6BA3_B726, // -98 + 0x4AE8_2577_1DC0_7672, + 0x6EE8_7C74_561C_9285, // -97 + 0x77D9_D58B_62CD_8A51, + 0x3173_FA53_BCFA_8408, // -96 + 0x5FE1_77A2_B571_3B74, + 0x278F_FB76_30C8_69A0, // -95 + 0x4CB4_5FB5_5DF4_2F90, + 0x1FA6_62C4_F3D3_87B3, // -94 + 0x7ABA_32BB_C986_B280, + 0x32A3_D13B_1FB8_D91F, // -93 + 0x622E_8EFC_A138_8ECD, + 0x0EE9_742F_4C93_E0E6, // -92 + 0x4E8B_A596_E760_723D, + 0x58BA_C359_0A0F_E71E, // -91 + 0x7DAC_3C24_A567_1D2F, + 0x412A_D228_1019_71C9, // -90 + 0x6489_C9B6_EAB8_E426, + 0x00EF_0E86_7347_8E3B, // -89 + 0x506E_3AF8_BBC7_1CEB, + 0x1A58_D86B_8F6C_71C9, // -88 + 0x4058_2F2D_6305_B0BC, + 0x1513_E056_0C56_C16E, // -87 + 0x66F3_7EAF_04D5_E793, + 0x3B53_0089_AD57_9BE2, // -86 + 0x525C_6558_D0AB_1FA9, + 0x15DC_006E_2446_164F, // -85 + 0x41E3_8447_0D55_B2ED, + 0x5E49_99F1_B69E_783F, // -84 + 0x696C_06D8_1555_EB15, + 0x7D42_8FE9_2430_C065, // -83 + 0x5456_6BE0_1111_88DE, + 0x3102_0CBA_835A_3384, // -82 + 0x4378_564C_DA74_6D7E, + 0x5A68_0A2E_CF7B_5C69, // -81 + 0x6BF3_BD47_C3ED_7BFD, + 0x770C_DD17_B25E_FA42, // -80 + 0x565C_976C_9CBD_FCCB, + 0x1270_B0DF_C1E5_9502, // -79 + 0x4516_DF8A_16FE_63D5, + 0x5B8D_5A4C_9B1E_10CE, // -78 + 0x6E8A_FF43_57FD_6C89, + 0x127B_C3AD_C4FC_E7B0, // -77 + 0x586F_329C_4664_56D4, + 0x0EC9_6957_D0CA_52F3, // -76 + 0x46BF_5BB0_3850_4576, + 0x3F07_8779_73D5_0F29, // -75 + 0x7132_2C4D_26E6_D58A, + 0x31A5_A58F_1FBB_4B75, // -74 + 0x5A8E_89D7_5252_446E, + 0x5AEA_EAD8_E62F_6F91, // -73 + 0x4872_07DF_750E_9D25, + 0x2F22_557A_51BF_8C74, // -72 + 0x73E9_A632_54E4_2EA2, + 0x1836_EF2A_1C65_AD86, // -71 + 0x5CBA_EB5B_771C_F21B, + 0x2CF8_BF54_E384_8AD2, // -70 + 0x4A2F_22AF_927D_8E7C, + 0x23FA_32AA_4F9D_3BDB, // -69 + 0x76B1_D118_EA62_7D93, + 0x5329_EAAA_18FB_92F8, // -68 + 0x5EF4_A747_21E8_6476, + 0x0F54_BBBB_472F_A8C6, // -67 + 0x4BF6_EC38_E7ED_1D2B, + 0x25DD_62FC_38F2_ED6C, // -66 + 0x798B_138E_3FE1_C845, + 0x22FB_D193_8E51_7BDF, // -65 + 0x613C_0FA4_FFE7_D36A, + 0x4F2F_DADC_71DA_C97F, // -64 + 0x4DC9_A61D_9986_42BB, + 0x58F3_157D_27E2_3ACC, // -63 + 0x7C75_D695_C270_6AC5, + 0x74B8_2261_D969_F7AD, // -62 + 0x6391_7877_CEC0_556B, + 0x1093_4EB4_ADEE_5FBE, // -61 + 0x4FA7_9393_0BCD_1122, + 0x4075_D890_8B25_1965, // -60 + 0x7F72_85B8_12E1_B504, + 0x00BC_8DB4_11D4_F56E, // -59 + 0x65F5_37C6_7581_5D9C, + 0x66FD_3E29_A7DD_9125, // -58 + 0x5190_F96B_9134_4AE3, + 0x6BFD_CB54_864A_DA84, // -57 + 0x4140_C789_40F6_A24F, + 0x6FFE_3C43_9EA2_486A, // -56 + 0x6867_A5A8_67F1_03B2, + 0x7FFD_2D38_FDD0_73DC, // -55 + 0x5386_1E20_5327_3628, + 0x6664_242D_97D9_F64A, // -54 + 0x42D1_B1B3_75B8_F820, + 0x51E9_B68A_DFE1_91D5, // -53 + 0x6AE9_1C52_55F4_C034, + 0x1CA9_2411_6635_B621, // -52 + 0x5587_49DB_77F7_0029, + 0x63BA_8341_1E91_5E81, // -51 + 0x446C_3B15_F992_6687, + 0x6962_029A_7EDA_B201, // -50 + 0x6D79_F823_28EA_3DA6, + 0x0F03_375D_97C4_5001, // -49 + 0x5794_C682_8721_CAEB, + 0x259C_2C4A_DFD0_4001, // -48 + 0x4610_9ECE_D281_6F22, + 0x5149_BD08_B30D_0001, // -47 + 0x701A_97B1_50CF_1837, + 0x3542_C80D_EB48_0001, // -46 + 0x59AE_DFC1_0D72_79C5, + 0x7768_A00B_22A0_0001, // -45 + 0x47BF_1967_3DF5_2E37, + 0x7920_8008_E880_0001, // -44 + 0x72CB_5BD8_6321_E38C, + 0x5B67_3341_7400_0001, // -43 + 0x5BD5_E313_8281_82D6, + 0x7C52_8F67_9000_0001, // -42 + 0x4977_E8DC_6867_9BDF, + 0x16A8_72B9_4000_0001, // -41 + 0x758C_A7C7_0D72_92FE, + 0x5773_EAC2_0000_0001, // -40 + 0x5E0A_1FD2_7128_7598, + 0x45F6_5568_0000_0001, // -39 + 0x4B3B_4CA8_5A86_C47A, + 0x04C5_1120_0000_0001, // -38 + 0x785E_E10D_5DA4_6D90, + 0x07A1_B500_0000_0001, // -37 + 0x604B_E73D_E483_8AD9, + 0x52E7_C400_0000_0001, // -36 + 0x4D09_85CB_1D36_08AE, + 0x0F1F_D000_0000_0001, // -35 + 0x7B42_6FAB_61F0_0DE3, + 0x31CC_8000_0000_0001, // -34 + 0x629B_8C89_1B26_7182, + 0x5B0A_0000_0000_0001, // -33 + 0x4EE2_D6D4_15B8_5ACE, + 0x7C08_0000_0000_0001, // -32 + 0x7E37_BE20_22C0_914B, + 0x1340_0000_0000_0001, // -31 + 0x64F9_64E6_8233_A76F, + 0x2900_0000_0000_0001, // -30 + 0x50C7_83EB_9B5C_85F2, + 0x5400_0000_0000_0001, // -29 + 0x409F_9CBC_7C4A_04C2, + 0x1000_0000_0000_0001, // -28 + 0x6765_C793_FA10_079D, + 0x0000_0000_0000_0001, // -27 + 0x52B7_D2DC_C80C_D2E4, + 0x0000_0000_0000_0001, // -26 + 0x422C_A8B0_A00A_4250, + 0x0000_0000_0000_0001, // -25 + 0x69E1_0DE7_6676_D080, + 0x0000_0000_0000_0001, // -24 + 0x54B4_0B1F_852B_DA00, + 0x0000_0000_0000_0001, // -23 + 0x43C3_3C19_3756_4800, + 0x0000_0000_0000_0001, // -22 + 0x6C6B_935B_8BBD_4000, + 0x0000_0000_0000_0001, // -21 + 0x56BC_75E2_D631_0000, + 0x0000_0000_0000_0001, // -20 + 0x4563_9182_44F4_0000, + 0x0000_0000_0000_0001, // -19 + 0x6F05_B59D_3B20_0000, + 0x0000_0000_0000_0001, // -18 + 0x58D1_5E17_6280_0000, + 0x0000_0000_0000_0001, // -17 + 0x470D_E4DF_8200_0000, + 0x0000_0000_0000_0001, // -16 + 0x71AF_D498_D000_0000, + 0x0000_0000_0000_0001, // -15 + 0x5AF3_107A_4000_0000, + 0x0000_0000_0000_0001, // -14 + 0x48C2_7395_0000_0000, + 0x0000_0000_0000_0001, // -13 + 0x746A_5288_0000_0000, + 0x0000_0000_0000_0001, // -12 + 0x5D21_DBA0_0000_0000, + 0x0000_0000_0000_0001, // -11 + 0x4A81_7C80_0000_0000, + 0x0000_0000_0000_0001, // -10 + 0x7735_9400_0000_0000, + 0x0000_0000_0000_0001, // -9 + 0x5F5E_1000_0000_0000, + 0x0000_0000_0000_0001, // -8 + 0x4C4B_4000_0000_0000, + 0x0000_0000_0000_0001, // -7 + 0x7A12_0000_0000_0000, + 0x0000_0000_0000_0001, // -6 + 0x61A8_0000_0000_0000, + 0x0000_0000_0000_0001, // -5 + 0x4E20_0000_0000_0000, + 0x0000_0000_0000_0001, // -4 + 0x7D00_0000_0000_0000, + 0x0000_0000_0000_0001, // -3 + 0x6400_0000_0000_0000, + 0x0000_0000_0000_0001, // -2 + 0x5000_0000_0000_0000, + 0x0000_0000_0000_0001, // -1 + 0x4000_0000_0000_0000, + 0x0000_0000_0000_0001, // 0 + 0x6666_6666_6666_6666, + 0x3333_3333_3333_3334, // 1 + 0x51EB_851E_B851_EB85, + 0x0F5C_28F5_C28F_5C29, // 2 + 0x4189_374B_C6A7_EF9D, + 0x5916_872B_020C_49BB, // 3 + 0x68DB_8BAC_710C_B295, + 0x74F0_D844_D013_A92B, // 4 + 0x53E2_D623_8DA3_C211, + 0x43F3_E037_0CDC_8755, // 5 + 0x431B_DE82_D7B6_34DA, + 0x698F_E692_70B0_6C44, // 6 + 0x6B5F_CA6A_F2BD_215E, + 0x0F4C_A41D_811A_46D4, // 7 + 0x55E6_3B88_C230_E77E, + 0x3F70_834A_CDAE_9F10, // 8 + 0x44B8_2FA0_9B5A_52CB, + 0x4C5A_02A2_3E25_4C0D, // 9 + 0x6DF3_7F67_5EF6_EADF, + 0x2D5C_D103_96A2_1347, // 10 + 0x57F5_FF85_E592_557F, + 0x3DE3_DA69_454E_75D3, // 11 + 0x465E_6604_B7A8_4465, + 0x7E4F_E1ED_D10B_9175, // 12 + 0x7097_09A1_25DA_0709, + 0x4A19_697C_81AC_1BEF, // 13 + 0x5A12_6E1A_84AE_6C07, + 0x54E1_2130_67BC_E326, // 14 + 0x480E_BE7B_9D58_566C, + 0x43E7_4DC0_52FD_8285, // 15 + 0x734A_CA5F_6226_F0AD, + 0x530B_AF9A_1E62_6A6D, // 16 + 0x5C3B_D519_1B52_5A24, + 0x426F_BFAE_7EB5_21F1, // 17 + 0x49C9_7747_490E_AE83, + 0x4EBF_CC8B_9890_E7F4, // 18 + 0x760F_253E_DB4A_B0D2, + 0x4ACC_7A78_F41B_0CBA, // 19 + 0x5E72_8432_4908_8D75, + 0x223D_2EC7_29AF_3D62, // 20 + 0x4B8E_D028_3A6D_3DF7, + 0x34FD_BF05_BAF2_9781, // 21 + 0x78E4_8040_5D7B_9658, + 0x54C9_31A2_C4B7_58CF, // 22 + 0x60B6_CD00_4AC9_4513, + 0x5D6D_C14F_03C5_E0A5, // 23 + 0x4D5F_0A66_A23A_9DA9, + 0x3124_9AA5_9C9E_4D51, // 24 + 0x7BCB_43D7_69F7_62A8, + 0x4EA0_F76F_60FD_4882, // 25 + 0x6309_0312_BB2C_4EED, + 0x254D_92BF_80CA_A068, // 26 + 0x4F3A_68DB_C8F0_3F24, + 0x1DD7_A899_33D5_4D20, // 27 + 0x7EC3_DAF9_4180_6506, + 0x62F2_A75B_8622_1500, // 28 + 0x6569_7BFA_9ACD_1D9F, + 0x025B_B916_04E8_10CD, // 29 + 0x5121_2FFB_AF0A_7E18, + 0x6849_60DE_6A53_40A4, // 30 + 0x40E7_5996_25A1_FE7A, + 0x203A_B3E5_21DC_33B6, // 31 + 0x67D8_8F56_A29C_CA5D, + 0x19F7_863B_6960_52BD, // 32 + 0x5313_A5DE_E87D_6EB0, + 0x7B2C_6B62_BAB3_7564, // 33 + 0x4276_1E4B_ED31_255A, + 0x2F56_BC4E_FBC2_C450, // 34 + 0x6A56_96DF_E1E8_3BC3, + 0x6557_93B1_92D1_3A1A, // 35 + 0x5512_124C_B4B9_C969, + 0x3779_42F4_7574_2E7B, // 36 + 0x440E_750A_2A2E_3ABA, + 0x5F94_3590_5DF6_8B96, // 37 + 0x6CE3_EE76_A9E3_912A, + 0x65B9_EF4D_6324_1289, // 38 + 0x571C_BEC5_54B6_0DBB, + 0x6AFB_25D7_8283_4207, // 39 + 0x45B0_989D_DD5E_7163, + 0x08C8_EB12_CECF_6806, // 40 + 0x6F80_F42F_C897_1BD1, + 0x5ADB_11B7_B14B_D9A3, // 41 + 0x5933_F68C_A078_E30E, + 0x157C_0E2C_8DD6_47B5, // 42 + 0x475C_C53D_4D2D_8271, + 0x5DFC_D823_A4AB_6C91, // 43 + 0x722E_0862_1515_9D82, + 0x632E_269F_6DDF_141B, // 44 + 0x5B58_06B4_DDAA_E468, + 0x4F58_1EE5_F17F_4349, // 45 + 0x4913_3890_B155_8386, + 0x72AC_E584_C132_9C3B, // 46 + 0x74EB_8DB4_4EEF_38D7, + 0x6AAE_3C07_9B84_2D2A, // 47 + 0x5D89_3E29_D8BF_60AC, + 0x5558_3006_1603_5755, // 48 + 0x4AD4_31BB_13CC_4D56, + 0x7779_C004_DE69_12AB, // 49 + 0x77B9_E92B_52E0_7BBE, + 0x258F_99A1_63DB_5111, // 50 + 0x5FC7_EDBC_424D_2FCB, + 0x37A6_1481_1CAF_740D, // 51 + 0x4C9F_F163_683D_BFD5, + 0x7951_AA00_E3BF_900B, // 52 + 0x7A99_8238_A6C9_32EF, + 0x754F_7667_D2CC_19AB, // 53 + 0x6214_682D_523A_8F26, + 0x2AA5_F853_0F09_AE22, // 54 + 0x4E76_B9BD_DB62_0C1E, + 0x5551_9375_A5A1_581B, // 55 + 0x7D8A_C2C9_5F03_4697, + 0x3BB5_B8BC_3C35_59C5, // 56 + 0x646F_023A_B269_0545, + 0x7C91_6096_9691_149E, // 57 + 0x5058_CE95_5B87_376B, + 0x16DA_B3AB_ABA7_43B2, // 58 + 0x4047_0BAA_AF9F_5F88, + 0x78AE_F622_EFB9_02F5, // 59 + 0x66D8_12AA_B298_98DB, + 0x0DE4_BD04_B2C1_9E54, // 60 + 0x5246_7555_5BAD_4715, + 0x57EA_30D0_8F01_4B76, // 61 + 0x41D1_F777_7C8A_9F44, + 0x4654_F3DA_0C01_092C, // 62 + 0x694F_F258_C744_3207, + 0x23BB_1FC3_4668_0EAC, // 63 + 0x543F_F513_D29C_F4D2, + 0x4FC8_E635_D1EC_D88A, // 64 + 0x4366_5DA9_754A_5D75, + 0x263A_51C4_A7F0_AD3B, // 65 + 0x6BD6_FC42_5543_C8BB, + 0x56C3_B607_731A_AEC4, // 66 + 0x5645_969B_7769_6D62, + 0x789C_919F_8F48_8BD0, // 67 + 0x4504_787C_5F87_8AB5, + 0x46E3_A7B2_D906_D640, // 68 + 0x6E6D_8D93_CC0C_1122, + 0x3E39_0C51_5B3E_239A, // 69 + 0x5857_A476_3CD6_741B, + 0x4B60_D6A7_7C31_B615, // 70 + 0x46AC_8391_CA45_29AF, + 0x55E7_121F_968E_2B44, // 71 + 0x7114_05B6_106E_A919, + 0x0971_B698_F0E3_786D, // 72 + 0x5A76_6AF8_0D25_5414, + 0x078E_2BAD_8D82_C6BD, // 73 + 0x485E_BBF9_A41D_DCDC, + 0x6C71_BC8A_D79B_D231, // 74 + 0x73CA_C65C_39C9_6161, + 0x2D82_C744_8C2C_8382, // 75 + 0x5CA2_3849_C7D4_4DE7, + 0x3E02_3903_A356_CF9B, // 76 + 0x4A1B_603B_0643_7185, + 0x7E68_2D9C_82AB_D949, // 77 + 0x7692_3391_A39F_1C09, + 0x4A40_48FA_6AAC_8EDB, // 78 + 0x5EDB_5C74_82E5_B007, + 0x5500_3A61_EEF0_7249, // 79 + 0x4BE2_B05D_3584_8CD2, + 0x7733_61E7_F259_F507, // 80 + 0x796A_B3C8_55A0_E151, + 0x3EB8_9CA6_508F_EE71, // 81 + 0x6122_296D_114D_810D, + 0x7EFA_16EB_73A6_585B, // 82 + 0x4DB4_EDF0_DAA4_673E, + 0x3261_ABEF_8FB8_46AF, // 83 + 0x7C54_AFE7_C43A_3ECA, + 0x1D69_1318_E5F3_A44B, // 84 + 0x6376_F31F_D02E_98A1, + 0x6454_0F47_1E5C_836F, // 85 + 0x4F92_5C19_7358_7A1B, + 0x0376_729F_4B7D_35F3, // 86 + 0x7F50_935B_EBC0_C35E, + 0x38BD_8432_1261_EFEB, // 87 + 0x65DA_0F7C_BC9A_35E5, + 0x13CA_D028_0EB4_BFEF, // 88 + 0x517B_3F96_FD48_2B1D, + 0x5CA2_4020_0BC3_CCBF, // 89 + 0x412F_6612_6439_BC17, + 0x63B5_0019_A303_0A33, // 90 + 0x684B_D683_D38F_9359, + 0x1F88_0029_04D1_A9EA, // 91 + 0x536F_DECF_DC72_DC47, + 0x32D3_3354_03DA_EE55, // 92 + 0x42BF_E573_16C2_49D2, + 0x5BDC_2910_0315_8B77, // 93 + 0x6ACC_A251_BE03_A951, + 0x12F9_DB4C_D1BC_1258, // 94 + 0x5570_81DA_FE69_5440, + 0x7594_AF70_A7C9_A847, // 95 + 0x445A_017B_FEBA_A9CD, + 0x4476_F2C0_863A_ED06, // 96 + 0x6D5C_CF2C_CAC4_42E2, + 0x3A57_EACD_A391_7B3C, // 97 + 0x577D_728A_3BD0_3581, + 0x7B79_88A4_82DA_C8FD, // 98 + 0x45FD_F53B_630C_F79B, + 0x15FA_D3B6_CF15_6D97, // 99 + 0x6FFC_BB92_3814_BF5E, + 0x565E_1F8A_E4EF_15BE, // 100 + 0x5996_FC74_F9AA_32B2, + 0x11E4_E608_B725_AAFF, // 101 + 0x47AB_FD2A_6154_F55B, + 0x27EA_51A0_9284_88CC, // 102 + 0x72AC_C843_CEEE_555E, + 0x7310_829A_8407_4146, // 103 + 0x5BBD_6D03_0BF1_DDE5, + 0x4273_9BAE_D005_CDD2, // 104 + 0x4964_5735_A327_E4B7, + 0x4EC2_E2F2_4004_A4A8, // 105 + 0x756D_5855_D1D9_6DF2, + 0x4AD1_6B1D_333A_A10C, // 106 + 0x5DF1_1377_DB14_57F5, + 0x2241_227D_C295_4DA3, // 107 + 0x4B27_42C6_48DD_132A, + 0x4E9A_81FE_3544_3E1C, // 108 + 0x783E_D13D_4161_B844, + 0x175D_9CC9_EED3_9694, // 109 + 0x6032_40FD_CDE7_C69C, + 0x7917_B0A1_8BDC_7876, // 110 + 0x4CF5_00CB_0B1F_D217, + 0x1412_F3B4_6FE3_9392, // 111 + 0x7B21_9ADE_7832_E9BE, + 0x5351_85ED_7FD2_85B6, // 112 + 0x6281_48B1_F9C2_5498, + 0x42A7_9E57_9975_37C5, // 113 + 0x4ECD_D3C1_949B_76E0, + 0x3552_E512_E12A_9304, // 114 + 0x7E16_1F9C_20F8_BE33, + 0x6EEB_081E_3510_EB39, // 115 + 0x64DE_7FB0_1A60_9829, + 0x3F22_6CE4_F740_BC2E, // 116 + 0x50B1_FFC0_151A_1354, + 0x3281_F0B7_2C33_C9BE, // 117 + 0x408E_6633_4414_DC43, + 0x4201_8D5F_568F_D498, // 118 + 0x674A_3D1E_D354_939F, + 0x1CCF_4898_8A7F_BA8D, // 119 + 0x52A1_CA7F_0F76_DC7F, + 0x30A5_D3AD_3B99_620B, // 120 + 0x421B_0865_A5F8_B065, + 0x73B7_DC8A_9614_4E6F, // 121 + 0x69C4_DA3C_3CC1_1A3C, + 0x52BF_C744_2353_B0B1, // 122 + 0x549D_7B63_63CD_AE96, + 0x7566_3903_4F76_26F4, // 123 + 0x43B1_2F82_B63E_2545, + 0x4451_C735_D92B_525D, // 124 + 0x6C4E_B26A_BD30_3BA2, + 0x3A1C_71EF_C1DE_EA2E, // 125 + 0x56A5_5B88_9759_C94E, + 0x61B0_5B26_34B2_54F2, // 126 + 0x4551_1606_DF7B_0772, + 0x1AF3_7C1E_908E_AA5B, // 127 + 0x6EE8_233E_325E_7250, + 0x2B1F_2CFD_B417_76F8, // 128 + 0x58B9_B5CB_5B7E_C1D9, + 0x6F4C_23FE_29AC_5F2D, // 129 + 0x46FA_F7D5_E2CB_CE47, + 0x72A3_4FFE_87BD_18F1, // 130 + 0x7191_8C89_6ADF_B073, + 0x0438_7FFD_A5FB_5B1B, // 131 + 0x5ADA_D6D4_557F_C05C, + 0x0360_6664_84C9_15AF, // 132 + 0x48AF_1243_7799_66B0, + 0x02B3_851D_3707_448C, // 133 + 0x744B_506B_F28F_0AB3, + 0x1DEC_082E_BE72_0746, // 134 + 0x5D09_0D23_2872_6EF5, + 0x64BC_D358_985B_3905, // 135 + 0x4A6D_A41C_205B_8BF7, + 0x6A30_A913_AD15_C738, // 136 + 0x7715_D360_33C5_ACBF, + 0x5D1A_A81F_7B56_0B8C, // 137 + 0x5F44_A919_C304_8A32, + 0x7DAE_ECE5_FC44_D609, // 138 + 0x4C36_EDAE_359D_3B5B, + 0x7E25_8A51_969D_7808, // 139 + 0x79F1_7C49_EF61_F893, + 0x16A2_76E8_F0FB_F33F, // 140 + 0x618D_FD07_F2B4_C6DC, + 0x121B_9253_F3FC_C299, // 141 + 0x4E0B_30D3_2890_9F16, + 0x41AF_A843_2997_0214, // 142 + 0x7CDE_B485_0DB4_31BD, + 0x4F7F_739E_A8F1_9CED, // 143 + 0x63E5_5D37_3E29_C164, + 0x3F99_294B_BA5A_E3F1, // 144 + 0x4FEA_B0F8_FE87_CDE9, + 0x7FAD_BAA2_FB7B_E98D, // 145 + 0x7FDD_E7F4_CA72_E30F, + 0x7F7C_5DD1_925F_DC15, // 146 + 0x664B_1FF7_085B_E8D9, + 0x4C63_7E41_41E6_49AB, // 147 + 0x51D5_B32C_06AF_ED7A, + 0x704F_9834_34B8_3AEF, // 148 + 0x4177_C289_9EF3_2462, + 0x26A6_135C_F6F9_C8BF, // 149 + 0x68BF_9DA8_FE51_D3D0, + 0x3DD6_8561_8B29_4132, // 150 + 0x53CC_7E20_CB74_A973, + 0x4B12_044E_08ED_CDC2, // 151 + 0x4309_FE80_A2C3_BAC2, + 0x6F41_9D0B_3A57_D7CE, // 152 + 0x6B43_30CD_D139_2AD1, + 0x3202_94DE_C3BF_BFB0, // 153 + 0x55CF_5A3E_40FA_88A7, + 0x419B_AA4B_CFCC_995A, // 154 + 0x44A5_E1CB_672E_D3B9, + 0x1AE2_EEA3_0CA3_ADE1, // 155 + 0x6DD6_3612_3EB1_52C1, + 0x77D1_7DD1_ADD2_AFCF, // 156 + 0x57DE_91A8_3227_7567, + 0x7974_64A7_BE42_263F, // 157 + 0x464B_A7B9_C1B9_2AB9, + 0x4790_5086_31CE_84FF, // 158 + 0x7079_0C5C_6928_445C, + 0x0C1A_1A70_4FB0_D4CC, // 159 + 0x59FA_7049_EDB9_D049, + 0x567B_4859_D95A_43D6, // 160 + 0x47FB_8D07_F161_736E, + 0x11FC_39E1_7AAE_9CAB, // 161 + 0x732C_14D9_8235_857D, + 0x032D_2968_C44A_9445, // 162 + 0x5C23_43E1_34F7_9DFD, + 0x4F57_5453_D03B_A9D1, // 163 + 0x49B5_CFE7_5D92_E4CA, + 0x72AC_4376_402F_BB0E, // 164 + 0x75EF_B30B_C8EB_07AB, + 0x0446_D256_CD19_2B49, // 165 + 0x5E59_5C09_6D88_D2EF, + 0x1D05_7512_3DAD_BC3A, // 166 + 0x4B7A_B007_8AD3_DBF2, + 0x4A6A_C40E_97BE_302F, // 167 + 0x78C4_4CD8_DE1F_C650, + 0x7711_39B0_F2C9_E6B1, // 168 + 0x609D_0A47_1819_6B73, + 0x78DA_948D_8F07_EBC1, // 169 + 0x4D4A_6E9F_467A_BC5C, + 0x60AE_DD3E_0C06_5634, // 170 + 0x7BAA_4A98_70C4_6094, + 0x344A_FB96_79A3_BD20, // 171 + 0x62EE_A213_8D69_E6DD, + 0x103B_FC78_614F_CA80, // 172 + 0x4F25_4E76_0ABB_1F17, + 0x2696_6393_810C_A200, // 173 + 0x7EA2_1723_445E_9825, + 0x2423_D285_9B47_6999, // 174 + 0x654E_78E9_037E_E01D, + 0x69B6_4204_7C39_2148, // 175 + 0x510B_93ED_9C65_8017, + 0x6E2B_6803_9694_1AA0, // 176 + 0x40D6_0FF1_49EA_CCDF, + 0x71BC_5336_1210_154D, // 177 + 0x67BC_E64E_DCAA_E166, + 0x1C60_8523_5019_BBAE, // 178 + 0x52FD_850B_E3BB_E784, + 0x7D1A_041C_4014_9625, // 179 + 0x4264_6A6F_E963_1F9D, + 0x4A7B_367D_0010_781D, // 180 + 0x6A3A_43E6_4238_3295, + 0x5D91_F0C8_001A_59C8, // 181 + 0x54FB_6985_01C6_8EDE, + 0x17A7_F3D3_3348_47D4, // 182 + 0x43FC_546A_67D2_0BE4, + 0x7953_2975_C2A0_3976, // 183 + 0x6CC6_ED77_0C83_463B, + 0x0EEB_7589_3766_C256, // 184 + 0x5705_8AC5_A39C_382F, + 0x2589_2AD4_2C52_3512, // 185 + 0x459E_089E_1C7C_F9BF, + 0x37A0_EF10_2374_F742, // 186 + 0x6F63_40FC_FA61_8F98, + 0x5901_7E80_38BB_2536, // 187 + 0x591C_33FD_951A_D946, + 0x7A67_9866_93C8_EA91, // 188 + 0x4749_C331_4415_7A9F, + 0x151F_AD1E_DCA0_BBA8, // 189 + 0x720F_9EB5_39BB_F765, + 0x0832_AE97_C767_92A5, // 190 + 0x5B3F_B22A_9496_5F84, + 0x068E_F213_05EC_7551, // 191 + 0x48FF_C1BB_AA11_E603, + 0x1ED8_C1A8_D189_F774, // 192 + 0x74CC_692C_434F_D66B, + 0x4AF4_690E_1C0F_F253, // 193 + 0x5D70_5423_690C_AB89, + 0x225D_20D8_1673_2843, // 194 + 0x4AC0_434F_873D_5607, + 0x3517_4D79_AB8F_5369, // 195 + 0x779A_054C_0B95_5672, + 0x21BE_E25C_45B2_1F0E, // 196 + 0x5FAE_6AA3_3C77_785B, + 0x3498_B516_9E28_18D8, // 197 + 0x4C8B_8882_96C5_F9E2, + 0x5D46_F745_4B53_4713, // 198 + 0x7A78_DA6A_8AD6_5C9D, + 0x7BA4_BED5_4552_0B52, // 199 + 0x61FA_4855_3BDE_B07E, + 0x2FB6_FF11_0441_A2A8, // 200 + 0x4E61_D377_6318_8D31, + 0x72F8_CC0D_9D01_4EED, // 201 + 0x7D69_5258_9E8D_AEB6, + 0x1E5A_E015_C802_17E1, // 202 + 0x6454_41E0_7ED7_BEF8, + 0x1848_B344_A001_ACB4, // 203 + 0x5043_67E6_CBDF_CBF9, + 0x603A_2903_B334_8A2A, // 204 + 0x4035_ECB8_A319_6FFB, + 0x002E_8736_28F6_D4EE, // 205 + 0x66BC_ADF4_3828_B32B, + 0x19E4_0B89_DB24_87E3, // 206 + 0x5230_8B29_C686_F5BC, + 0x14B6_6FA1_7C1D_3983, // 207 + 0x41C0_6F54_9ED2_5E30, + 0x1091_F2E7_967D_C79C, // 208 + 0x6933_E554_3150_96B3, + 0x341C_B7D8_F0C9_3F5F, // 209 + 0x5429_8443_5AA6_DEF5, + 0x767D_5FE0_C0A0_FF80, // 210 + 0x4354_69CF_7BB8_B25E, + 0x2B97_7FE7_0080_CC66, // 211 + 0x6BBA_42E5_92C1_1D63, + 0x5F58_CCA4_CD9A_E0A3, // 212 + 0x562E_9BEA_DBCD_B11C, + 0x4C47_0A1D_7148_B3B6, // 213 + 0x44F2_1655_7CA4_8DB0, + 0x3D05_A1B1_276D_5C92, // 214 + 0x6E50_23BB_FAA0_E2B3, + 0x7B3C_35E8_3F15_60E9, // 215 + 0x5840_1C96_621A_4EF6, + 0x2F63_5E53_65AA_B3ED, // 216 + 0x4699_B078_4E7B_725E, + 0x591C_4B75_EAEE_F658, // 217 + 0x70F5_E726_E3F8_B6FD, + 0x74FA_1256_44B1_8A26, // 218 + 0x5A5E_5285_832D_5F31, + 0x43FB_41DE_9D5A_D4EB, // 219 + 0x484B_7537_9C24_4C27, + 0x4FFC_34B2_177B_DD89, // 220 + 0x73AB_EEBF_603A_1372, + 0x4CC6_BAB6_8BF9_6274, // 221 + 0x5C89_8BCC_4CFB_42C2, + 0x0A38_955E_D661_1B90, // 222 + 0x4A07_A309_D72F_689B, + 0x21C6_DDE5_784D_AFA7, // 223 + 0x7672_9E76_2518_A75E, + 0x693E_2FD5_8D49_190B, // 224 + 0x5EC2_185E_8413_B918, + 0x5431_BFDE_0AA0_E0D5, // 225 + 0x4BCE_79E5_3676_2DAD, + 0x29C1_664B_3BB3_E711, // 226 + 0x794A_5CA1_F0BD_15E2, + 0x0F9B_D6DE_C5EC_A4E8, // 227 + 0x6108_4A1B_26FD_AB1B, + 0x2616_457F_04BD_50BA, // 228 + 0x4DA0_3B48_EBFE_227C, + 0x1E78_3798_D097_73C8, // 229 + 0x7C33_920E_4663_6A60, + 0x30C0_58F4_80F2_52D9, // 230 + 0x635C_74D8_384F_884D, + 0x0D66_AD90_6728_4247, // 231 + 0x4F7D_2A46_9372_D370, + 0x711E_F140_5286_9B6C, // 232 + 0x7F2E_AA0A_8584_8581, + 0x34FE_4ECD_50D7_5F14, // 233 + 0x65BE_EE6E_D136_D134, + 0x2A65_0BD7_73DF_7F43, // 234 + 0x5165_8B8B_DA92_40F6, + 0x551D_A312_C319_329C, // 235 + 0x411E_093C_AEDB_672B, + 0x5DB1_4F42_35AD_C217, // 236 + 0x6830_0EC7_7E2B_D845, + 0x7C4E_E536_BC49_368A, // 237 + 0x5359_A56C_64EF_E037, + 0x7D0B_EA92_303A_9208, // 238 + 0x42AE_1DF0_50BF_E693, + 0x173C_BBA8_2695_41A0, // 239 + 0x6AB0_2FE6_E799_70EB, + 0x3EC7_92A6_A422_029A, // 240 + 0x5559_BFEB_EC7A_C0BC, + 0x3239_421E_E9B4_CEE1, // 241 + 0x4447_CCBC_BD2F_0096, + 0x5B61_01B2_5490_A581, // 242 + 0x6D3F_ADFA_C84B_3424, + 0x2BCE_691D_541A_A268, // 243 + 0x5766_24C8_A03C_29B6, + 0x563E_BA7D_DCE2_1B87, // 244 + 0x45EB_50A0_8030_215E, + 0x7832_2ECB_171B_4939, // 245 + 0x6FDE_E767_3380_3564, + 0x59E9_E478_24F8_7527, // 246 + 0x597F_1F85_C2CC_F783, + 0x6187_E9F9_B72D_2A86, // 247 + 0x4798_E604_9BD7_2C69, + 0x346C_BB2E_2C24_2205, // 248 + 0x728E_3CD4_2C8B_7A42, + 0x20AD_F849_E039_D007, // 249 + 0x5BA4_FD76_8A09_2E9B, + 0x33BE_603B_19C7_D99F, // 250 + 0x4950_CAC5_3B3A_8BAF, + 0x42FE_B362_7B06_47B3, // 251 + 0x754E_113B_91F7_45E5, + 0x5197_856A_5E70_72B8, // 252 + 0x5DD8_0DC9_4192_9E51, + 0x27AC_6ABB_7EC0_5BC6, // 253 + 0x4B13_3E3A_9ADB_B1DA, + 0x52F0_5562_CBCD_1638, // 254 + 0x781E_C9F7_5E2C_4FC4, + 0x1E4D_556A_DFAE_89F3, // 255 + 0x6018_A192_B1BD_0C9C, + 0x7EA4_4455_7FBE_D4C3, // 256 + 0x4CE0_8142_27CA_707D, + 0x4BB6_9D11_32FF_109C, // 257 + 0x7B00_CED0_3FAA_4D95, + 0x5F8A_94E8_5198_1A93, // 258 + 0x6267_0BD9_CC88_3E11, + 0x32D5_43ED_0E13_4875, // 259 + 0x4EB8_D647_D6D3_64DA, + 0x5BDD_CFF0_D80F_6D2B, // 260 + 0x7DF4_8A0C_8AEB_D491, + 0x12FC_7FE7_C018_AEAB, // 261 + 0x64C3_A1A3_A256_43A7, + 0x28C9_FFEC_99AD_5889, // 262 + 0x509C_814F_B511_CFB9, + 0x0707_FFF0_7AF1_13A1, // 263 + 0x407D_343F_C40E_3FC7, + 0x1F39_998D_2F27_42E7, // 264 + 0x672E_B9FF_A016_CC71, + 0x7EC2_8F48_4B72_04A4, // 265 + 0x528B_C7FF_B345_705B, + 0x189B_A5D3_6F8E_6A1D, // 266 + 0x4209_6CCC_8F6A_C048, + 0x7A16_1E42_BFA5_21B1, // 267 + 0x69A8_AE14_18AA_CD41, + 0x4356_96D1_32A1_CF81, // 268 + 0x5486_F1A9_AD55_7101, + 0x1C45_4574_2881_72CE, // 269 + 0x439F_27BA_F111_2734, + 0x169D_D129_BA01_28A5, // 270 + 0x6C31_D92B_1B4E_A520, + 0x242F_B50F_9001_DAA1, // 271 + 0x568E_4755_AF72_1DB3, + 0x368C_90D9_4001_7BB4, // 272 + 0x453E_9F77_BF8E_7E29, + 0x120A_0D7A_999A_C95D, // 273 + 0x6ECA_98BF_98E3_FD0E, + 0x5010_1590_F5C4_7561, // 274 + 0x58A2_13CC_7A4F_FDA5, + 0x2673_4473_F7D0_5DE8, // 275 + 0x46E8_0FD6_C83F_FE1D, + 0x6B8F_69F6_5FD9_E4B9, // 276 + 0x7173_4C8A_D9FF_FCFC, + 0x45B2_4323_CC8F_D45C, // 277 + 0x5AC2_A3A2_47FF_FD96, + 0x6AF5_0283_0A0C_A9E3, // 278 + 0x489B_B61B_6CCC_CADF, + 0x08C4_0202_6E70_87E9, // 279 + 0x742C_5692_47AE_1164, + 0x746C_D003_E3E7_3FDB, // 280 + 0x5CF0_4541_D2F1_A783, + 0x76BD_7336_4FEC_3315, // 281 + 0x4A59_D101_758E_1F9C, + 0x5EFD_F5C5_0CBC_F5AB, // 282 + 0x76F6_1B35_88E3_65C7, + 0x4B2F_EFA1_ADFB_22AB, // 283 + 0x5F2B_48F7_A0B5_EB06, + 0x08F3_261A_F195_B555, // 284 + 0x4C22_A0C6_1A2B_226B, + 0x20C2_84E2_5ADE_2AAB, // 285 + 0x79D1_013C_F6AB_6A45, + 0x1AD0_D49D_5E30_4444, // 286 + 0x6174_00FD_9222_BB6A, + 0x48A7_107D_E4F3_69D0, // 287 + 0x4DF6_6731_41B5_62BB, + 0x53B8_D9FE_50C2_BB0D, // 288 + 0x7CBD_71E8_6922_3792, + 0x52C1_5CCA_1AD1_2B48, // 289 + 0x63CA_C186_BA81_C60E, + 0x7567_7D6E_7BDA_8906, // 290 + 0x4FD5_679E_FB9B_04D8, + 0x5DEC_6458_6315_3A6C, // 291 + 0x7FBB_D8FE_5F5E_6E27, + 0x497A_3A27_04EE_C3DF, // 292 ]; From 503c4b8b0eafb5c559506401368f86fbd9e033ae Mon Sep 17 00:00:00 2001 From: Leung Ming <165622843+leung-ming@users.noreply.github.com> Date: Sat, 21 Jun 2025 03:19:07 +0800 Subject: [PATCH 5/8] fix --- native/spark-expr/src/conversion_funcs/cast.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/native/spark-expr/src/conversion_funcs/cast.rs b/native/spark-expr/src/conversion_funcs/cast.rs index 6a194159dc..b91f6c0e99 100644 --- a/native/spark-expr/src/conversion_funcs/cast.rs +++ b/native/spark-expr/src/conversion_funcs/cast.rs @@ -1289,11 +1289,7 @@ where match value { Some((significand, exponent)) => { - let mut v = if input_value < 0. { - -significand - } else { - significand - } as i128; + let mut v = significand as i128; let k = exponent + scale as i32; if k > 0 { @@ -1303,6 +1299,8 @@ where let (div, rem) = if dk < v { v.div_rem(&dk) } else { (0, v) }; v = if rem * 2 >= dk { div + 1 } else { div }; } + v = if input_value < 0. { -v } else { v }; + if Decimal128Type::validate_decimal_precision(v, precision).is_err() { if eval_mode == EvalMode::Ansi { return Err(SparkError::NumericValueOutOfRange { From 487d775127b28d34b599c85d1cf5ac519a355d60 Mon Sep 17 00:00:00 2001 From: Leung Ming <165622843+leung-ming@users.noreply.github.com> Date: Mon, 23 Jun 2025 21:55:34 +0800 Subject: [PATCH 6/8] dragonbox 0.1.10 --- native/dragonbox/Cargo.toml | 25 + native/dragonbox/LICENSE-Apache2-LLVM | 193 +++++++ native/dragonbox/LICENSE-Boost | 23 + native/dragonbox/README.md | 48 ++ native/dragonbox/benches/bench.rs | 51 ++ native/dragonbox/src/buffer.rs | 116 +++++ native/dragonbox/src/cache.rs | 664 ++++++++++++++++++++++++ native/dragonbox/src/div.rs | 111 ++++ native/dragonbox/src/lib.rs | 558 ++++++++++++++++++++ native/dragonbox/src/log.rs | 123 +++++ native/dragonbox/src/to_chars.rs | 422 +++++++++++++++ native/dragonbox/src/wuint.rs | 38 ++ native/dragonbox/tests/binary64_test.rs | 330 ++++++++++++ native/dragonbox/tests/crate/.gitignore | 2 + native/dragonbox/tests/crate/Cargo.toml | 14 + native/dragonbox/tests/crate/test.rs | 3 + native/dragonbox/tests/macros/mod.rs | 8 + 17 files changed, 2729 insertions(+) create mode 100644 native/dragonbox/Cargo.toml create mode 100644 native/dragonbox/LICENSE-Apache2-LLVM create mode 100644 native/dragonbox/LICENSE-Boost create mode 100644 native/dragonbox/README.md create mode 100644 native/dragonbox/benches/bench.rs create mode 100644 native/dragonbox/src/buffer.rs create mode 100644 native/dragonbox/src/cache.rs create mode 100644 native/dragonbox/src/div.rs create mode 100644 native/dragonbox/src/lib.rs create mode 100644 native/dragonbox/src/log.rs create mode 100644 native/dragonbox/src/to_chars.rs create mode 100644 native/dragonbox/src/wuint.rs create mode 100644 native/dragonbox/tests/binary64_test.rs create mode 100644 native/dragonbox/tests/crate/.gitignore create mode 100644 native/dragonbox/tests/crate/Cargo.toml create mode 100644 native/dragonbox/tests/crate/test.rs create mode 100644 native/dragonbox/tests/macros/mod.rs diff --git a/native/dragonbox/Cargo.toml b/native/dragonbox/Cargo.toml new file mode 100644 index 0000000000..ec206b7b15 --- /dev/null +++ b/native/dragonbox/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "dragonbox" +version = "0.1.10" +authors = ["David Tolnay "] +categories = ["value-formatting", "no-std", "no-std::no-alloc"] +description = "Fast floating point to string conversion" +documentation = "https://docs.rs/dragonbox" +edition = "2018" +exclude = ["performance.png", "chart/**"] +keywords = ["float"] +license = "Apache-2.0 WITH LLVM-exception OR BSL-1.0" +repository = "https://github.com/dtolnay/dragonbox" +rust-version = "1.52" + +[dev-dependencies] +rand = "0.9" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = [ + "--generate-link-to-definition", + "--extern-html-root-url=core=https://doc.rust-lang.org", + "--extern-html-root-url=alloc=https://doc.rust-lang.org", + "--extern-html-root-url=std=https://doc.rust-lang.org", +] diff --git a/native/dragonbox/LICENSE-Apache2-LLVM b/native/dragonbox/LICENSE-Apache2-LLVM new file mode 100644 index 0000000000..c8d7ed2907 --- /dev/null +++ b/native/dragonbox/LICENSE-Apache2-LLVM @@ -0,0 +1,193 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + +--- LLVM Exceptions to the Apache 2.0 License ---- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. diff --git a/native/dragonbox/LICENSE-Boost b/native/dragonbox/LICENSE-Boost new file mode 100644 index 0000000000..36b7cd93cd --- /dev/null +++ b/native/dragonbox/LICENSE-Boost @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/native/dragonbox/README.md b/native/dragonbox/README.md new file mode 100644 index 0000000000..c0a8f88a02 --- /dev/null +++ b/native/dragonbox/README.md @@ -0,0 +1,48 @@ +# Dragonbox + +[github](https://github.com/dtolnay/dragonbox) +[crates.io](https://crates.io/crates/dragonbox) +[docs.rs](https://docs.rs/dragonbox) +[build status](https://github.com/dtolnay/dragonbox/actions?query=branch%3Amaster) + +This crate contains a basic port of to +Rust for benchmarking purposes. + +Please see the upstream repo for an explanation of the approach and comparison +to the Ryū algorithm. + +
+ +## Example + +```rust +fn main() { + let mut buffer = dragonbox::Buffer::new(); + let printed = buffer.format(1.234); + assert_eq!(printed, "1.234E0"); +} +``` + +
+ +## Performance (lower is better) + +![performance](https://raw.githubusercontent.com/dtolnay/dragonbox/master/performance.png) + +
+ +#### License + + +Licensed under either of Apache License, Version +2.0 with LLVM Exceptions or Boost Software License +Version 1.0 at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + diff --git a/native/dragonbox/benches/bench.rs b/native/dragonbox/benches/bench.rs new file mode 100644 index 0000000000..cf94cf019f --- /dev/null +++ b/native/dragonbox/benches/bench.rs @@ -0,0 +1,51 @@ +#![feature(test)] +#![allow(clippy::approx_constant, clippy::unreadable_literal)] + +extern crate test; + +use std::io::Write; +use test::{black_box, Bencher}; + +macro_rules! benches { + ($($name:ident($value:expr),)*) => { + mod bench_dragonbox { + use super::*; + $( + #[bench] + fn $name(b: &mut Bencher) { + let mut buf = dragonbox::Buffer::new(); + + b.iter(move || { + let value = black_box($value); + let formatted = buf.format_finite(value); + black_box(formatted); + }); + } + )* + } + + mod bench_std_fmt { + use super::*; + $( + #[bench] + fn $name(b: &mut Bencher) { + let mut buf = Vec::with_capacity(20); + + b.iter(|| { + buf.clear(); + let value = black_box($value); + write!(&mut buf, "{}", value).unwrap(); + black_box(buf.as_slice()); + }); + } + )* + } + }; +} + +benches! { + bench_0_f64(0f64), + bench_short_f64(0.1234f64), + bench_e_f64(2.718281828459045f64), + bench_max_f64(f64::MAX), +} diff --git a/native/dragonbox/src/buffer.rs b/native/dragonbox/src/buffer.rs new file mode 100644 index 0000000000..3b1dc2bdbe --- /dev/null +++ b/native/dragonbox/src/buffer.rs @@ -0,0 +1,116 @@ +use crate::{Buffer, Float}; +use core::mem::MaybeUninit; +use core::slice; +use core::str; + +impl Buffer { + /// This is a cheap operation; you don't need to worry about reusing buffers + /// for efficiency. + #[inline] + pub fn new() -> Self { + let bytes = [MaybeUninit::::uninit(); 24]; + Buffer { bytes } + } + + /// Print a floating point number into this buffer and return a reference to + /// its string representation within the buffer. + /// + /// # Special cases + /// + /// This function formats NaN as the string "NaN", positive infinity as + /// "inf", and negative infinity as "-inf" to match std::fmt. + /// + /// If your input is known to be finite, you may get better performance by + /// calling the `format_finite` method instead of `format` to avoid the + /// checks for special cases. + pub fn format(&mut self, f: F) -> &str { + if f.is_nonfinite() { + f.format_nonfinite() + } else { + self.format_finite(f) + } + } + + /// Print a floating point number into this buffer and return a reference to + /// its string representation within the buffer. + /// + /// # Special cases + /// + /// This function **does not** check for NaN or infinity. If the input + /// number is not a finite float, the printed representation will be some + /// correctly formatted but unspecified numerical value. + /// + /// Please check [`is_finite`] yourself before calling this function, or + /// check [`is_nan`] and [`is_infinite`] and handle those cases yourself. + /// + /// [`is_finite`]: f64::is_finite + /// [`is_nan`]: f64::is_nan + /// [`is_infinite`]: f64::is_infinite + #[inline] + pub fn format_finite(&mut self, f: F) -> &str { + unsafe { + let n = f.write_to_dragonbox_buffer(self.bytes.as_mut_ptr() as *mut u8); + debug_assert!(n <= self.bytes.len()); + let slice = slice::from_raw_parts(self.bytes.as_ptr() as *const u8, n); + str::from_utf8_unchecked(slice) + } + } +} + +impl Copy for Buffer {} + +impl Clone for Buffer { + #[inline] + #[allow(clippy::non_canonical_clone_impl)] // false positive https://github.com/rust-lang/rust-clippy/issues/11072 + fn clone(&self) -> Self { + Buffer::new() + } +} + +impl Default for Buffer { + #[inline] + fn default() -> Self { + Buffer::new() + } +} + +impl Float for f64 {} + +const NAN: &str = "NaN"; +const INFINITY: &str = "inf"; +const NEG_INFINITY: &str = "-inf"; + +pub trait Sealed: Copy { + fn is_nonfinite(self) -> bool; + fn format_nonfinite(self) -> &'static str; + unsafe fn write_to_dragonbox_buffer(self, result: *mut u8) -> usize; +} + +impl Sealed for f64 { + #[inline] + fn is_nonfinite(self) -> bool { + const EXP_MASK: u64 = 0x7ff0000000000000; + let bits = self.to_bits(); + bits & EXP_MASK == EXP_MASK + } + + #[cold] + fn format_nonfinite(self) -> &'static str { + const MANTISSA_MASK: u64 = 0x000fffffffffffff; + const SIGN_MASK: u64 = 0x8000000000000000; + let bits = self.to_bits(); + if bits & MANTISSA_MASK != 0 { + NAN + } else if bits & SIGN_MASK != 0 { + NEG_INFINITY + } else { + INFINITY + } + } + + #[inline] + unsafe fn write_to_dragonbox_buffer(self, buffer: *mut u8) -> usize { + let end = crate::to_chars::to_chars(self, buffer); + end.offset_from(buffer) as usize + } +} diff --git a/native/dragonbox/src/cache.rs b/native/dragonbox/src/cache.rs new file mode 100644 index 0000000000..90e31368ac --- /dev/null +++ b/native/dragonbox/src/cache.rs @@ -0,0 +1,664 @@ +// Translated from C++ to Rust. The original C++ code can be found at +// https://github.com/jk-jeon/dragonbox and carries the following license: +// +// Copyright 2020-2021 Junekey Jeon +// +// The contents of this file may be used under the terms of +// the Apache License v2.0 with LLVM Exceptions. +// +// (See accompanying file LICENSE-Apache or copy at +// https://llvm.org/foundation/relicensing/LICENSE.txt) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +pub(crate) type EntryType = u128; +const MIN_K: i32 = -292; +const MAX_K: i32 = 326; + +pub(crate) unsafe fn get(k: i32) -> EntryType { + debug_assert!(k >= MIN_K && k <= MAX_K); + *CACHE.get_unchecked((k - MIN_K) as usize) +} + +pub(crate) trait EntryTypeExt { + fn high(&self) -> u64; + fn low(&self) -> u64; +} + +impl EntryTypeExt for EntryType { + fn high(&self) -> u64 { + (self >> 64) as u64 + } + fn low(&self) -> u64 { + *self as u64 + } +} + +static CACHE: [EntryType; 619] = [ + 0xff77b1fcbebcdc4f_25e8e89c13bb0f7b, + 0x9faacf3df73609b1_77b191618c54e9ad, + 0xc795830d75038c1d_d59df5b9ef6a2418, + 0xf97ae3d0d2446f25_4b0573286b44ad1e, + 0x9becce62836ac577_4ee367f9430aec33, + 0xc2e801fb244576d5_229c41f793cda740, + 0xf3a20279ed56d48a_6b43527578c11110, + 0x9845418c345644d6_830a13896b78aaaa, + 0xbe5691ef416bd60c_23cc986bc656d554, + 0xedec366b11c6cb8f_2cbfbe86b7ec8aa9, + 0x94b3a202eb1c3f39_7bf7d71432f3d6aa, + 0xb9e08a83a5e34f07_daf5ccd93fb0cc54, + 0xe858ad248f5c22c9_d1b3400f8f9cff69, + 0x91376c36d99995be_23100809b9c21fa2, + 0xb58547448ffffb2d_abd40a0c2832a78b, + 0xe2e69915b3fff9f9_16c90c8f323f516d, + 0x8dd01fad907ffc3b_ae3da7d97f6792e4, + 0xb1442798f49ffb4a_99cd11cfdf41779d, + 0xdd95317f31c7fa1d_40405643d711d584, + 0x8a7d3eef7f1cfc52_482835ea666b2573, + 0xad1c8eab5ee43b66_da3243650005eed0, + 0xd863b256369d4a40_90bed43e40076a83, + 0x873e4f75e2224e68_5a7744a6e804a292, + 0xa90de3535aaae202_711515d0a205cb37, + 0xd3515c2831559a83_0d5a5b44ca873e04, + 0x8412d9991ed58091_e858790afe9486c3, + 0xa5178fff668ae0b6_626e974dbe39a873, + 0xce5d73ff402d98e3_fb0a3d212dc81290, + 0x80fa687f881c7f8e_7ce66634bc9d0b9a, + 0xa139029f6a239f72_1c1fffc1ebc44e81, + 0xc987434744ac874e_a327ffb266b56221, + 0xfbe9141915d7a922_4bf1ff9f0062baa9, + 0x9d71ac8fada6c9b5_6f773fc3603db4aa, + 0xc4ce17b399107c22_cb550fb4384d21d4, + 0xf6019da07f549b2b_7e2a53a146606a49, + 0x99c102844f94e0fb_2eda7444cbfc426e, + 0xc0314325637a1939_fa911155fefb5309, + 0xf03d93eebc589f88_793555ab7eba27cb, + 0x96267c7535b763b5_4bc1558b2f3458df, + 0xbbb01b9283253ca2_9eb1aaedfb016f17, + 0xea9c227723ee8bcb_465e15a979c1cadd, + 0x92a1958a7675175f_0bfacd89ec191eca, + 0xb749faed14125d36_cef980ec671f667c, + 0xe51c79a85916f484_82b7e12780e7401b, + 0x8f31cc0937ae58d2_d1b2ecb8b0908811, + 0xb2fe3f0b8599ef07_861fa7e6dcb4aa16, + 0xdfbdcece67006ac9_67a791e093e1d49b, + 0x8bd6a141006042bd_e0c8bb2c5c6d24e1, + 0xaecc49914078536d_58fae9f773886e19, + 0xda7f5bf590966848_af39a475506a899f, + 0x888f99797a5e012d_6d8406c952429604, + 0xaab37fd7d8f58178_c8e5087ba6d33b84, + 0xd5605fcdcf32e1d6_fb1e4a9a90880a65, + 0x855c3be0a17fcd26_5cf2eea09a550680, + 0xa6b34ad8c9dfc06f_f42faa48c0ea481f, + 0xd0601d8efc57b08b_f13b94daf124da27, + 0x823c12795db6ce57_76c53d08d6b70859, + 0xa2cb1717b52481ed_54768c4b0c64ca6f, + 0xcb7ddcdda26da268_a9942f5dcf7dfd0a, + 0xfe5d54150b090b02_d3f93b35435d7c4d, + 0x9efa548d26e5a6e1_c47bc5014a1a6db0, + 0xc6b8e9b0709f109a_359ab6419ca1091c, + 0xf867241c8cc6d4c0_c30163d203c94b63, + 0x9b407691d7fc44f8_79e0de63425dcf1e, + 0xc21094364dfb5636_985915fc12f542e5, + 0xf294b943e17a2bc4_3e6f5b7b17b2939e, + 0x979cf3ca6cec5b5a_a705992ceecf9c43, + 0xbd8430bd08277231_50c6ff782a838354, + 0xece53cec4a314ebd_a4f8bf5635246429, + 0x940f4613ae5ed136_871b7795e136be9a, + 0xb913179899f68584_28e2557b59846e40, + 0xe757dd7ec07426e5_331aeada2fe589d0, + 0x9096ea6f3848984f_3ff0d2c85def7622, + 0xb4bca50b065abe63_0fed077a756b53aa, + 0xe1ebce4dc7f16dfb_d3e8495912c62895, + 0x8d3360f09cf6e4bd_64712dd7abbbd95d, + 0xb080392cc4349dec_bd8d794d96aacfb4, + 0xdca04777f541c567_ecf0d7a0fc5583a1, + 0x89e42caaf9491b60_f41686c49db57245, + 0xac5d37d5b79b6239_311c2875c522ced6, + 0xd77485cb25823ac7_7d633293366b828c, + 0x86a8d39ef77164bc_ae5dff9c02033198, + 0xa8530886b54dbdeb_d9f57f830283fdfd, + 0xd267caa862a12d66_d072df63c324fd7c, + 0x8380dea93da4bc60_4247cb9e59f71e6e, + 0xa46116538d0deb78_52d9be85f074e609, + 0xcd795be870516656_67902e276c921f8c, + 0x806bd9714632dff6_00ba1cd8a3db53b7, + 0xa086cfcd97bf97f3_80e8a40eccd228a5, + 0xc8a883c0fdaf7df0_6122cd128006b2ce, + 0xfad2a4b13d1b5d6c_796b805720085f82, + 0x9cc3a6eec6311a63_cbe3303674053bb1, + 0xc3f490aa77bd60fc_bedbfc4411068a9d, + 0xf4f1b4d515acb93b_ee92fb5515482d45, + 0x991711052d8bf3c5_751bdd152d4d1c4b, + 0xbf5cd54678eef0b6_d262d45a78a0635e, + 0xef340a98172aace4_86fb897116c87c35, + 0x9580869f0e7aac0e_d45d35e6ae3d4da1, + 0xbae0a846d2195712_8974836059cca10a, + 0xe998d258869facd7_2bd1a438703fc94c, + 0x91ff83775423cc06_7b6306a34627ddd0, + 0xb67f6455292cbf08_1a3bc84c17b1d543, + 0xe41f3d6a7377eeca_20caba5f1d9e4a94, + 0x8e938662882af53e_547eb47b7282ee9d, + 0xb23867fb2a35b28d_e99e619a4f23aa44, + 0xdec681f9f4c31f31_6405fa00e2ec94d5, + 0x8b3c113c38f9f37e_de83bc408dd3dd05, + 0xae0b158b4738705e_9624ab50b148d446, + 0xd98ddaee19068c76_3badd624dd9b0958, + 0x87f8a8d4cfa417c9_e54ca5d70a80e5d7, + 0xa9f6d30a038d1dbc_5e9fcf4ccd211f4d, + 0xd47487cc8470652b_7647c32000696720, + 0x84c8d4dfd2c63f3b_29ecd9f40041e074, + 0xa5fb0a17c777cf09_f468107100525891, + 0xcf79cc9db955c2cc_7182148d4066eeb5, + 0x81ac1fe293d599bf_c6f14cd848405531, + 0xa21727db38cb002f_b8ada00e5a506a7d, + 0xca9cf1d206fdc03b_a6d90811f0e4851d, + 0xfd442e4688bd304a_908f4a166d1da664, + 0x9e4a9cec15763e2e_9a598e4e043287ff, + 0xc5dd44271ad3cdba_40eff1e1853f29fe, + 0xf7549530e188c128_d12bee59e68ef47d, + 0x9a94dd3e8cf578b9_82bb74f8301958cf, + 0xc13a148e3032d6e7_e36a52363c1faf02, + 0xf18899b1bc3f8ca1_dc44e6c3cb279ac2, + 0x96f5600f15a7b7e5_29ab103a5ef8c0ba, + 0xbcb2b812db11a5de_7415d448f6b6f0e8, + 0xebdf661791d60f56_111b495b3464ad22, + 0x936b9fcebb25c995_cab10dd900beec35, + 0xb84687c269ef3bfb_3d5d514f40eea743, + 0xe65829b3046b0afa_0cb4a5a3112a5113, + 0x8ff71a0fe2c2e6dc_47f0e785eaba72ac, + 0xb3f4e093db73a093_59ed216765690f57, + 0xe0f218b8d25088b8_306869c13ec3532d, + 0x8c974f7383725573_1e414218c73a13fc, + 0xafbd2350644eeacf_e5d1929ef90898fb, + 0xdbac6c247d62a583_df45f746b74abf3a, + 0x894bc396ce5da772_6b8bba8c328eb784, + 0xab9eb47c81f5114f_066ea92f3f326565, + 0xd686619ba27255a2_c80a537b0efefebe, + 0x8613fd0145877585_bd06742ce95f5f37, + 0xa798fc4196e952e7_2c48113823b73705, + 0xd17f3b51fca3a7a0_f75a15862ca504c6, + 0x82ef85133de648c4_9a984d73dbe722fc, + 0xa3ab66580d5fdaf5_c13e60d0d2e0ebbb, + 0xcc963fee10b7d1b3_318df905079926a9, + 0xffbbcfe994e5c61f_fdf17746497f7053, + 0x9fd561f1fd0f9bd3_feb6ea8bedefa634, + 0xc7caba6e7c5382c8_fe64a52ee96b8fc1, + 0xf9bd690a1b68637b_3dfdce7aa3c673b1, + 0x9c1661a651213e2d_06bea10ca65c084f, + 0xc31bfa0fe5698db8_486e494fcff30a63, + 0xf3e2f893dec3f126_5a89dba3c3efccfb, + 0x986ddb5c6b3a76b7_f89629465a75e01d, + 0xbe89523386091465_f6bbb397f1135824, + 0xee2ba6c0678b597f_746aa07ded582e2d, + 0x94db483840b717ef_a8c2a44eb4571cdd, + 0xba121a4650e4ddeb_92f34d62616ce414, + 0xe896a0d7e51e1566_77b020baf9c81d18, + 0x915e2486ef32cd60_0ace1474dc1d122f, + 0xb5b5ada8aaff80b8_0d819992132456bb, + 0xe3231912d5bf60e6_10e1fff697ed6c6a, + 0x8df5efabc5979c8f_ca8d3ffa1ef463c2, + 0xb1736b96b6fd83b3_bd308ff8a6b17cb3, + 0xddd0467c64bce4a0_ac7cb3f6d05ddbdf, + 0x8aa22c0dbef60ee4_6bcdf07a423aa96c, + 0xad4ab7112eb3929d_86c16c98d2c953c7, + 0xd89d64d57a607744_e871c7bf077ba8b8, + 0x87625f056c7c4a8b_11471cd764ad4973, + 0xa93af6c6c79b5d2d_d598e40d3dd89bd0, + 0xd389b47879823479_4aff1d108d4ec2c4, + 0x843610cb4bf160cb_cedf722a585139bb, + 0xa54394fe1eedb8fe_c2974eb4ee658829, + 0xce947a3da6a9273e_733d226229feea33, + 0x811ccc668829b887_0806357d5a3f5260, + 0xa163ff802a3426a8_ca07c2dcb0cf26f8, + 0xc9bcff6034c13052_fc89b393dd02f0b6, + 0xfc2c3f3841f17c67_bbac2078d443ace3, + 0x9d9ba7832936edc0_d54b944b84aa4c0e, + 0xc5029163f384a931_0a9e795e65d4df12, + 0xf64335bcf065d37d_4d4617b5ff4a16d6, + 0x99ea0196163fa42e_504bced1bf8e4e46, + 0xc06481fb9bcf8d39_e45ec2862f71e1d7, + 0xf07da27a82c37088_5d767327bb4e5a4d, + 0x964e858c91ba2655_3a6a07f8d510f870, + 0xbbe226efb628afea_890489f70a55368c, + 0xeadab0aba3b2dbe5_2b45ac74ccea842f, + 0x92c8ae6b464fc96f_3b0b8bc90012929e, + 0xb77ada0617e3bbcb_09ce6ebb40173745, + 0xe55990879ddcaabd_cc420a6a101d0516, + 0x8f57fa54c2a9eab6_9fa946824a12232e, + 0xb32df8e9f3546564_47939822dc96abfa, + 0xdff9772470297ebd_59787e2b93bc56f8, + 0x8bfbea76c619ef36_57eb4edb3c55b65b, + 0xaefae51477a06b03_ede622920b6b23f2, + 0xdab99e59958885c4_e95fab368e45ecee, + 0x88b402f7fd75539b_11dbcb0218ebb415, + 0xaae103b5fcd2a881_d652bdc29f26a11a, + 0xd59944a37c0752a2_4be76d3346f04960, + 0x857fcae62d8493a5_6f70a4400c562ddc, + 0xa6dfbd9fb8e5b88e_cb4ccd500f6bb953, + 0xd097ad07a71f26b2_7e2000a41346a7a8, + 0x825ecc24c873782f_8ed400668c0c28c9, + 0xa2f67f2dfa90563b_728900802f0f32fb, + 0xcbb41ef979346bca_4f2b40a03ad2ffba, + 0xfea126b7d78186bc_e2f610c84987bfa9, + 0x9f24b832e6b0f436_0dd9ca7d2df4d7ca, + 0xc6ede63fa05d3143_91503d1c79720dbc, + 0xf8a95fcf88747d94_75a44c6397ce912b, + 0x9b69dbe1b548ce7c_c986afbe3ee11abb, + 0xc24452da229b021b_fbe85badce996169, + 0xf2d56790ab41c2a2_fae27299423fb9c4, + 0x97c560ba6b0919a5_dccd879fc967d41b, + 0xbdb6b8e905cb600f_5400e987bbc1c921, + 0xed246723473e3813_290123e9aab23b69, + 0x9436c0760c86e30b_f9a0b6720aaf6522, + 0xb94470938fa89bce_f808e40e8d5b3e6a, + 0xe7958cb87392c2c2_b60b1d1230b20e05, + 0x90bd77f3483bb9b9_b1c6f22b5e6f48c3, + 0xb4ecd5f01a4aa828_1e38aeb6360b1af4, + 0xe2280b6c20dd5232_25c6da63c38de1b1, + 0x8d590723948a535f_579c487e5a38ad0f, + 0xb0af48ec79ace837_2d835a9df0c6d852, + 0xdcdb1b2798182244_f8e431456cf88e66, + 0x8a08f0f8bf0f156b_1b8e9ecb641b5900, + 0xac8b2d36eed2dac5_e272467e3d222f40, + 0xd7adf884aa879177_5b0ed81dcc6abb10, + 0x86ccbb52ea94baea_98e947129fc2b4ea, + 0xa87fea27a539e9a5_3f2398d747b36225, + 0xd29fe4b18e88640e_8eec7f0d19a03aae, + 0x83a3eeeef9153e89_1953cf68300424ad, + 0xa48ceaaab75a8e2b_5fa8c3423c052dd8, + 0xcdb02555653131b6_3792f412cb06794e, + 0x808e17555f3ebf11_e2bbd88bbee40bd1, + 0xa0b19d2ab70e6ed6_5b6aceaeae9d0ec5, + 0xc8de047564d20a8b_f245825a5a445276, + 0xfb158592be068d2e_eed6e2f0f0d56713, + 0x9ced737bb6c4183d_55464dd69685606c, + 0xc428d05aa4751e4c_aa97e14c3c26b887, + 0xf53304714d9265df_d53dd99f4b3066a9, + 0x993fe2c6d07b7fab_e546a8038efe402a, + 0xbf8fdb78849a5f96_de98520472bdd034, + 0xef73d256a5c0f77c_963e66858f6d4441, + 0x95a8637627989aad_dde7001379a44aa9, + 0xbb127c53b17ec159_5560c018580d5d53, + 0xe9d71b689dde71af_aab8f01e6e10b4a7, + 0x9226712162ab070d_cab3961304ca70e9, + 0xb6b00d69bb55c8d1_3d607b97c5fd0d23, + 0xe45c10c42a2b3b05_8cb89a7db77c506b, + 0x8eb98a7a9a5b04e3_77f3608e92adb243, + 0xb267ed1940f1c61c_55f038b237591ed4, + 0xdf01e85f912e37a3_6b6c46dec52f6689, + 0x8b61313bbabce2c6_2323ac4b3b3da016, + 0xae397d8aa96c1b77_abec975e0a0d081b, + 0xd9c7dced53c72255_96e7bd358c904a22, + 0x881cea14545c7575_7e50d64177da2e55, + 0xaa242499697392d2_dde50bd1d5d0b9ea, + 0xd4ad2dbfc3d07787_955e4ec64b44e865, + 0x84ec3c97da624ab4_bd5af13bef0b113f, + 0xa6274bbdd0fadd61_ecb1ad8aeacdd58f, + 0xcfb11ead453994ba_67de18eda5814af3, + 0x81ceb32c4b43fcf4_80eacf948770ced8, + 0xa2425ff75e14fc31_a1258379a94d028e, + 0xcad2f7f5359a3b3e_096ee45813a04331, + 0xfd87b5f28300ca0d_8bca9d6e188853fd, + 0x9e74d1b791e07e48_775ea264cf55347e, + 0xc612062576589dda_95364afe032a819e, + 0xf79687aed3eec551_3a83ddbd83f52205, + 0x9abe14cd44753b52_c4926a9672793543, + 0xc16d9a0095928a27_75b7053c0f178294, + 0xf1c90080baf72cb1_5324c68b12dd6339, + 0x971da05074da7bee_d3f6fc16ebca5e04, + 0xbce5086492111aea_88f4bb1ca6bcf585, + 0xec1e4a7db69561a5_2b31e9e3d06c32e6, + 0x9392ee8e921d5d07_3aff322e62439fd0, + 0xb877aa3236a4b449_09befeb9fad487c3, + 0xe69594bec44de15b_4c2ebe687989a9b4, + 0x901d7cf73ab0acd9_0f9d37014bf60a11, + 0xb424dc35095cd80f_538484c19ef38c95, + 0xe12e13424bb40e13_2865a5f206b06fba, + 0x8cbccc096f5088cb_f93f87b7442e45d4, + 0xafebff0bcb24aafe_f78f69a51539d749, + 0xdbe6fecebdedd5be_b573440e5a884d1c, + 0x89705f4136b4a597_31680a88f8953031, + 0xabcc77118461cefc_fdc20d2b36ba7c3e, + 0xd6bf94d5e57a42bc_3d32907604691b4d, + 0x8637bd05af6c69b5_a63f9a49c2c1b110, + 0xa7c5ac471b478423_0fcf80dc33721d54, + 0xd1b71758e219652b_d3c36113404ea4a9, + 0x83126e978d4fdf3b_645a1cac083126ea, + 0xa3d70a3d70a3d70a_3d70a3d70a3d70a4, + 0xcccccccccccccccc_cccccccccccccccd, + 0x8000000000000000_0000000000000000, + 0xa000000000000000_0000000000000000, + 0xc800000000000000_0000000000000000, + 0xfa00000000000000_0000000000000000, + 0x9c40000000000000_0000000000000000, + 0xc350000000000000_0000000000000000, + 0xf424000000000000_0000000000000000, + 0x9896800000000000_0000000000000000, + 0xbebc200000000000_0000000000000000, + 0xee6b280000000000_0000000000000000, + 0x9502f90000000000_0000000000000000, + 0xba43b74000000000_0000000000000000, + 0xe8d4a51000000000_0000000000000000, + 0x9184e72a00000000_0000000000000000, + 0xb5e620f480000000_0000000000000000, + 0xe35fa931a0000000_0000000000000000, + 0x8e1bc9bf04000000_0000000000000000, + 0xb1a2bc2ec5000000_0000000000000000, + 0xde0b6b3a76400000_0000000000000000, + 0x8ac7230489e80000_0000000000000000, + 0xad78ebc5ac620000_0000000000000000, + 0xd8d726b7177a8000_0000000000000000, + 0x878678326eac9000_0000000000000000, + 0xa968163f0a57b400_0000000000000000, + 0xd3c21bcecceda100_0000000000000000, + 0x84595161401484a0_0000000000000000, + 0xa56fa5b99019a5c8_0000000000000000, + 0xcecb8f27f4200f3a_0000000000000000, + 0x813f3978f8940984_4000000000000000, + 0xa18f07d736b90be5_5000000000000000, + 0xc9f2c9cd04674ede_a400000000000000, + 0xfc6f7c4045812296_4d00000000000000, + 0x9dc5ada82b70b59d_f020000000000000, + 0xc5371912364ce305_6c28000000000000, + 0xf684df56c3e01bc6_c732000000000000, + 0x9a130b963a6c115c_3c7f400000000000, + 0xc097ce7bc90715b3_4b9f100000000000, + 0xf0bdc21abb48db20_1e86d40000000000, + 0x96769950b50d88f4_1314448000000000, + 0xbc143fa4e250eb31_17d955a000000000, + 0xeb194f8e1ae525fd_5dcfab0800000000, + 0x92efd1b8d0cf37be_5aa1cae500000000, + 0xb7abc627050305ad_f14a3d9e40000000, + 0xe596b7b0c643c719_6d9ccd05d0000000, + 0x8f7e32ce7bea5c6f_e4820023a2000000, + 0xb35dbf821ae4f38b_dda2802c8a800000, + 0xe0352f62a19e306e_d50b2037ad200000, + 0x8c213d9da502de45_4526f422cc340000, + 0xaf298d050e4395d6_9670b12b7f410000, + 0xdaf3f04651d47b4c_3c0cdd765f114000, + 0x88d8762bf324cd0f_a5880a69fb6ac800, + 0xab0e93b6efee0053_8eea0d047a457a00, + 0xd5d238a4abe98068_72a4904598d6d880, + 0x85a36366eb71f041_47a6da2b7f864750, + 0xa70c3c40a64e6c51_999090b65f67d924, + 0xd0cf4b50cfe20765_fff4b4e3f741cf6d, + 0x82818f1281ed449f_bff8f10e7a8921a4, + 0xa321f2d7226895c7_aff72d52192b6a0d, + 0xcbea6f8ceb02bb39_9bf4f8a69f764490, + 0xfee50b7025c36a08_02f236d04753d5b4, + 0x9f4f2726179a2245_01d762422c946590, + 0xc722f0ef9d80aad6_424d3ad2b7b97ef5, + 0xf8ebad2b84e0d58b_d2e0898765a7deb2, + 0x9b934c3b330c8577_63cc55f49f88eb2f, + 0xc2781f49ffcfa6d5_3cbf6b71c76b25fb, + 0xf316271c7fc3908a_8bef464e3945ef7a, + 0x97edd871cfda3a56_97758bf0e3cbb5ac, + 0xbde94e8e43d0c8ec_3d52eeed1cbea317, + 0xed63a231d4c4fb27_4ca7aaa863ee4bdd, + 0x945e455f24fb1cf8_8fe8caa93e74ef6a, + 0xb975d6b6ee39e436_b3e2fd538e122b44, + 0xe7d34c64a9c85d44_60dbbca87196b616, + 0x90e40fbeea1d3a4a_bc8955e946fe31cd, + 0xb51d13aea4a488dd_6babab6398bdbe41, + 0xe264589a4dcdab14_c696963c7eed2dd1, + 0x8d7eb76070a08aec_fc1e1de5cf543ca2, + 0xb0de65388cc8ada8_3b25a55f43294bcb, + 0xdd15fe86affad912_49ef0eb713f39ebe, + 0x8a2dbf142dfcc7ab_6e3569326c784337, + 0xacb92ed9397bf996_49c2c37f07965404, + 0xd7e77a8f87daf7fb_dc33745ec97be906, + 0x86f0ac99b4e8dafd_69a028bb3ded71a3, + 0xa8acd7c0222311bc_c40832ea0d68ce0c, + 0xd2d80db02aabd62b_f50a3fa490c30190, + 0x83c7088e1aab65db_792667c6da79e0fa, + 0xa4b8cab1a1563f52_577001b891185938, + 0xcde6fd5e09abcf26_ed4c0226b55e6f86, + 0x80b05e5ac60b6178_544f8158315b05b4, + 0xa0dc75f1778e39d6_696361ae3db1c721, + 0xc913936dd571c84c_03bc3a19cd1e38e9, + 0xfb5878494ace3a5f_04ab48a04065c723, + 0x9d174b2dcec0e47b_62eb0d64283f9c76, + 0xc45d1df942711d9a_3ba5d0bd324f8394, + 0xf5746577930d6500_ca8f44ec7ee36479, + 0x9968bf6abbe85f20_7e998b13cf4e1ecb, + 0xbfc2ef456ae276e8_9e3fedd8c321a67e, + 0xefb3ab16c59b14a2_c5cfe94ef3ea101e, + 0x95d04aee3b80ece5_bba1f1d158724a12, + 0xbb445da9ca61281f_2a8a6e45ae8edc97, + 0xea1575143cf97226_f52d09d71a3293bd, + 0x924d692ca61be758_593c2626705f9c56, + 0xb6e0c377cfa2e12e_6f8b2fb00c77836c, + 0xe498f455c38b997a_0b6dfb9c0f956447, + 0x8edf98b59a373fec_4724bd4189bd5eac, + 0xb2977ee300c50fe7_58edec91ec2cb657, + 0xdf3d5e9bc0f653e1_2f2967b66737e3ed, + 0x8b865b215899f46c_bd79e0d20082ee74, + 0xae67f1e9aec07187_ecd8590680a3aa11, + 0xda01ee641a708de9_e80e6f4820cc9495, + 0x884134fe908658b2_3109058d147fdcdd, + 0xaa51823e34a7eede_bd4b46f0599fd415, + 0xd4e5e2cdc1d1ea96_6c9e18ac7007c91a, + 0x850fadc09923329e_03e2cf6bc604ddb0, + 0xa6539930bf6bff45_84db8346b786151c, + 0xcfe87f7cef46ff16_e612641865679a63, + 0x81f14fae158c5f6e_4fcb7e8f3f60c07e, + 0xa26da3999aef7749_e3be5e330f38f09d, + 0xcb090c8001ab551c_5cadf5bfd3072cc5, + 0xfdcb4fa002162a63_73d9732fc7c8f7f6, + 0x9e9f11c4014dda7e_2867e7fddcdd9afa, + 0xc646d63501a1511d_b281e1fd541501b8, + 0xf7d88bc24209a565_1f225a7ca91a4226, + 0x9ae757596946075f_3375788de9b06958, + 0xc1a12d2fc3978937_0052d6b1641c83ae, + 0xf209787bb47d6b84_c0678c5dbd23a49a, + 0x9745eb4d50ce6332_f840b7ba963646e0, + 0xbd176620a501fbff_b650e5a93bc3d898, + 0xec5d3fa8ce427aff_a3e51f138ab4cebe, + 0x93ba47c980e98cdf_c66f336c36b10137, + 0xb8a8d9bbe123f017_b80b0047445d4184, + 0xe6d3102ad96cec1d_a60dc059157491e5, + 0x9043ea1ac7e41392_87c89837ad68db2f, + 0xb454e4a179dd1877_29babe4598c311fb, + 0xe16a1dc9d8545e94_f4296dd6fef3d67a, + 0x8ce2529e2734bb1d_1899e4a65f58660c, + 0xb01ae745b101e9e4_5ec05dcff72e7f8f, + 0xdc21a1171d42645d_76707543f4fa1f73, + 0x899504ae72497eba_6a06494a791c53a8, + 0xabfa45da0edbde69_0487db9d17636892, + 0xd6f8d7509292d603_45a9d2845d3c42b6, + 0x865b86925b9bc5c2_0b8a2392ba45a9b2, + 0xa7f26836f282b732_8e6cac7768d7141e, + 0xd1ef0244af2364ff_3207d795430cd926, + 0x8335616aed761f1f_7f44e6bd49e807b8, + 0xa402b9c5a8d3a6e7_5f16206c9c6209a6, + 0xcd036837130890a1_36dba887c37a8c0f, + 0x802221226be55a64_c2494954da2c9789, + 0xa02aa96b06deb0fd_f2db9baa10b7bd6c, + 0xc83553c5c8965d3d_6f92829494e5acc7, + 0xfa42a8b73abbf48c_cb772339ba1f17f9, + 0x9c69a97284b578d7_ff2a760414536efb, + 0xc38413cf25e2d70d_fef5138519684aba, + 0xf46518c2ef5b8cd1_7eb258665fc25d69, + 0x98bf2f79d5993802_ef2f773ffbd97a61, + 0xbeeefb584aff8603_aafb550ffacfd8fa, + 0xeeaaba2e5dbf6784_95ba2a53f983cf38, + 0x952ab45cfa97a0b2_dd945a747bf26183, + 0xba756174393d88df_94f971119aeef9e4, + 0xe912b9d1478ceb17_7a37cd5601aab85d, + 0x91abb422ccb812ee_ac62e055c10ab33a, + 0xb616a12b7fe617aa_577b986b314d6009, + 0xe39c49765fdf9d94_ed5a7e85fda0b80b, + 0x8e41ade9fbebc27d_14588f13be847307, + 0xb1d219647ae6b31c_596eb2d8ae258fc8, + 0xde469fbd99a05fe3_6fca5f8ed9aef3bb, + 0x8aec23d680043bee_25de7bb9480d5854, + 0xada72ccc20054ae9_af561aa79a10ae6a, + 0xd910f7ff28069da4_1b2ba1518094da04, + 0x87aa9aff79042286_90fb44d2f05d0842, + 0xa99541bf57452b28_353a1607ac744a53, + 0xd3fa922f2d1675f2_42889b8997915ce8, + 0x847c9b5d7c2e09b7_69956135febada11, + 0xa59bc234db398c25_43fab9837e699095, + 0xcf02b2c21207ef2e_94f967e45e03f4bb, + 0x8161afb94b44f57d_1d1be0eebac278f5, + 0xa1ba1ba79e1632dc_6462d92a69731732, + 0xca28a291859bbf93_7d7b8f7503cfdcfe, + 0xfcb2cb35e702af78_5cda735244c3d43e, + 0x9defbf01b061adab_3a0888136afa64a7, + 0xc56baec21c7a1916_088aaa1845b8fdd0, + 0xf6c69a72a3989f5b_8aad549e57273d45, + 0x9a3c2087a63f6399_36ac54e2f678864b, + 0xc0cb28a98fcf3c7f_84576a1bb416a7dd, + 0xf0fdf2d3f3c30b9f_656d44a2a11c51d5, + 0x969eb7c47859e743_9f644ae5a4b1b325, + 0xbc4665b596706114_873d5d9f0dde1fee, + 0xeb57ff22fc0c7959_a90cb506d155a7ea, + 0x9316ff75dd87cbd8_09a7f12442d588f2, + 0xb7dcbf5354e9bece_0c11ed6d538aeb2f, + 0xe5d3ef282a242e81_8f1668c8a86da5fa, + 0x8fa475791a569d10_f96e017d694487bc, + 0xb38d92d760ec4455_37c981dcc395a9ac, + 0xe070f78d3927556a_85bbe253f47b1417, + 0x8c469ab843b89562_93956d7478ccec8e, + 0xaf58416654a6babb_387ac8d1970027b2, + 0xdb2e51bfe9d0696a_06997b05fcc0319e, + 0x88fcf317f22241e2_441fece3bdf81f03, + 0xab3c2fddeeaad25a_d527e81cad7626c3, + 0xd60b3bd56a5586f1_8a71e223d8d3b074, + 0x85c7056562757456_f6872d5667844e49, + 0xa738c6bebb12d16c_b428f8ac016561db, + 0xd106f86e69d785c7_e13336d701beba52, + 0x82a45b450226b39c_ecc0024661173473, + 0xa34d721642b06084_27f002d7f95d0190, + 0xcc20ce9bd35c78a5_31ec038df7b441f4, + 0xff290242c83396ce_7e67047175a15271, + 0x9f79a169bd203e41_0f0062c6e984d386, + 0xc75809c42c684dd1_52c07b78a3e60868, + 0xf92e0c3537826145_a7709a56ccdf8a82, + 0x9bbcc7a142b17ccb_88a66076400bb691, + 0xc2abf989935ddbfe_6acff893d00ea435, + 0xf356f7ebf83552fe_0583f6b8c4124d43, + 0x98165af37b2153de_c3727a337a8b704a, + 0xbe1bf1b059e9a8d6_744f18c0592e4c5c, + 0xeda2ee1c7064130c_1162def06f79df73, + 0x9485d4d1c63e8be7_8addcb5645ac2ba8, + 0xb9a74a0637ce2ee1_6d953e2bd7173692, + 0xe8111c87c5c1ba99_c8fa8db6ccdd0437, + 0x910ab1d4db9914a0_1d9c9892400a22a2, + 0xb54d5e4a127f59c8_2503beb6d00cab4b, + 0xe2a0b5dc971f303a_2e44ae64840fd61d, + 0x8da471a9de737e24_5ceaecfed289e5d2, + 0xb10d8e1456105dad_7425a83e872c5f47, + 0xdd50f1996b947518_d12f124e28f77719, + 0x8a5296ffe33cc92f_82bd6b70d99aaa6f, + 0xace73cbfdc0bfb7b_636cc64d1001550b, + 0xd8210befd30efa5a_3c47f7e05401aa4e, + 0x8714a775e3e95c78_65acfaec34810a71, + 0xa8d9d1535ce3b396_7f1839a741a14d0d, + 0xd31045a8341ca07c_1ede48111209a050, + 0x83ea2b892091e44d_934aed0aab460432, + 0xa4e4b66b68b65d60_f81da84d5617853f, + 0xce1de40642e3f4b9_36251260ab9d668e, + 0x80d2ae83e9ce78f3_c1d72b7c6b426019, + 0xa1075a24e4421730_b24cf65b8612f81f, + 0xc94930ae1d529cfc_dee033f26797b627, + 0xfb9b7cd9a4a7443c_169840ef017da3b1, + 0x9d412e0806e88aa5_8e1f289560ee864e, + 0xc491798a08a2ad4e_f1a6f2bab92a27e2, + 0xf5b5d7ec8acb58a2_ae10af696774b1db, + 0x9991a6f3d6bf1765_acca6da1e0a8ef29, + 0xbff610b0cc6edd3f_17fd090a58d32af3, + 0xeff394dcff8a948e_ddfc4b4cef07f5b0, + 0x95f83d0a1fb69cd9_4abdaf101564f98e, + 0xbb764c4ca7a4440f_9d6d1ad41abe37f1, + 0xea53df5fd18d5513_84c86189216dc5ed, + 0x92746b9be2f8552c_32fd3cf5b4e49bb4, + 0xb7118682dbb66a77_3fbc8c33221dc2a1, + 0xe4d5e82392a40515_0fabaf3feaa5334a, + 0x8f05b1163ba6832d_29cb4d87f2a7400e, + 0xb2c71d5bca9023f8_743e20e9ef511012, + 0xdf78e4b2bd342cf6_914da9246b255416, + 0x8bab8eefb6409c1a_1ad089b6c2f7548e, + 0xae9672aba3d0c320_a184ac2473b529b1, + 0xda3c0f568cc4f3e8_c9e5d72d90a2741e, + 0x8865899617fb1871_7e2fa67c7a658892, + 0xaa7eebfb9df9de8d_ddbb901b98feeab7, + 0xd51ea6fa85785631_552a74227f3ea565, + 0x8533285c936b35de_d53a88958f87275f, + 0xa67ff273b8460356_8a892abaf368f137, + 0xd01fef10a657842c_2d2b7569b0432d85, + 0x8213f56a67f6b29b_9c3b29620e29fc73, + 0xa298f2c501f45f42_8349f3ba91b47b8f, + 0xcb3f2f7642717713_241c70a936219a73, + 0xfe0efb53d30dd4d7_ed238cd383aa0110, + 0x9ec95d1463e8a506_f4363804324a40aa, + 0xc67bb4597ce2ce48_b143c6053edcd0d5, + 0xf81aa16fdc1b81da_dd94b7868e94050a, + 0x9b10a4e5e9913128_ca7cf2b4191c8326, + 0xc1d4ce1f63f57d72_fd1c2f611f63a3f0, + 0xf24a01a73cf2dccf_bc633b39673c8cec, + 0x976e41088617ca01_d5be0503e085d813, + 0xbd49d14aa79dbc82_4b2d8644d8a74e18, + 0xec9c459d51852ba2_ddf8e7d60ed1219e, + 0x93e1ab8252f33b45_cabb90e5c942b503, + 0xb8da1662e7b00a17_3d6a751f3b936243, + 0xe7109bfba19c0c9d_0cc512670a783ad4, + 0x906a617d450187e2_27fb2b80668b24c5, + 0xb484f9dc9641e9da_b1f9f660802dedf6, + 0xe1a63853bbd26451_5e7873f8a0396973, + 0x8d07e33455637eb2_db0b487b6423e1e8, + 0xb049dc016abc5e5f_91ce1a9a3d2cda62, + 0xdc5c5301c56b75f7_7641a140cc7810fb, + 0x89b9b3e11b6329ba_a9e904c87fcb0a9d, + 0xac2820d9623bf429_546345fa9fbdcd44, + 0xd732290fbacaf133_a97c177947ad4095, + 0x867f59a9d4bed6c0_49ed8eabcccc485d, + 0xa81f301449ee8c70_5c68f256bfff5a74, + 0xd226fc195c6a2f8c_73832eec6fff3111, + 0x83585d8fd9c25db7_c831fd53c5ff7eab, + 0xa42e74f3d032f525_ba3e7ca8b77f5e55, + 0xcd3a1230c43fb26f_28ce1bd2e55f35eb, + 0x80444b5e7aa7cf85_7980d163cf5b81b3, + 0xa0555e361951c366_d7e105bcc332621f, + 0xc86ab5c39fa63440_8dd9472bf3fefaa7, + 0xfa856334878fc150_b14f98f6f0feb951, + 0x9c935e00d4b9d8d2_6ed1bf9a569f33d3, + 0xc3b8358109e84f07_0a862f80ec4700c8, + 0xf4a642e14c6262c8_cd27bb612758c0fa, + 0x98e7e9cccfbd7dbd_8038d51cb897789c, + 0xbf21e44003acdd2c_e0470a63e6bd56c3, + 0xeeea5d5004981478_1858ccfce06cac74, + 0x95527a5202df0ccb_0f37801e0c43ebc8, + 0xbaa718e68396cffd_d30560258f54e6ba, + 0xe950df20247c83fd_47c6b82ef32a2069, + 0x91d28b7416cdd27e_4cdc331d57fa5441, + 0xb6472e511c81471d_e0133fe4adf8e952, + 0xe3d8f9e563a198e5_58180fddd97723a6, + 0x8e679c2f5e44ff8f_570f09eaa7ea7648, + 0xb201833b35d63f73_2cd2cc6551e513da, + 0xde81e40a034bcf4f_f8077f7ea65e58d1, + 0x8b112e86420f6191_fb04afaf27faf782, + 0xadd57a27d29339f6_79c5db9af1f9b563, + 0xd94ad8b1c7380874_18375281ae7822bc, + 0x87cec76f1c830548_8f2293910d0b15b5, + 0xa9c2794ae3a3c69a_b2eb3875504ddb22, + 0xd433179d9c8cb841_5fa60692a46151eb, + 0x849feec281d7f328_dbc7c41ba6bcd333, + 0xa5c7ea73224deff3_12b9b522906c0800, + 0xcf39e50feae16bef_d768226b34870a00, + 0x81842f29f2cce375_e6a1158300d46640, + 0xa1e53af46f801c53_60495ae3c1097fd0, + 0xca5e89b18b602368_385bb19cb14bdfc4, + 0xfcf62c1dee382c42_46729e03dd9ed7b5, + 0x9e19db92b4e31ba9_6c07a2c26a8346d1, + 0xc5a05277621be293_c7098b7305241885, + 0xf70867153aa2db38_b8cbee4fc66d1ea7, +]; diff --git a/native/dragonbox/src/div.rs b/native/dragonbox/src/div.rs new file mode 100644 index 0000000000..986e6b481b --- /dev/null +++ b/native/dragonbox/src/div.rs @@ -0,0 +1,111 @@ +// Translated from C++ to Rust. The original C++ code can be found at +// https://github.com/jk-jeon/dragonbox and carries the following license: +// +// Copyright 2020-2021 Junekey Jeon +// +// The contents of this file may be used under the terms of +// the Apache License v2.0 with LLVM Exceptions. +// +// (See accompanying file LICENSE-Apache or copy at +// https://llvm.org/foundation/relicensing/LICENSE.txt) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +use crate::{CarrierUint, CARRIER_BITS}; + +const fn modular_inverse() -> CarrierUint { + // By Euler's theorem, a^phi(2^n) == 1 (mod 2^n), + // where phi(2^n) = 2^(n-1), so the modular inverse of a is + // a^(2^(n-1) - 1) = a^(1 + 2 + 2^2 + ... + 2^(n-2)). + let mut mod_inverse: CarrierUint = 1; + let mut i = 1; + while i < CARRIER_BITS { + mod_inverse = mod_inverse.wrapping_mul(mod_inverse).wrapping_mul(A); + i += 1; + } + mod_inverse +} + +struct Table { + //assert(a % 2 != 0); + //assert(N > 0); + mod_inv: [CarrierUint; N], + max_quotients: [CarrierUint; N], +} + +impl Table { + const TABLE: Self = { + let mod_inverse = modular_inverse::(); + let mut mod_inv = [0; N]; + let mut max_quotients = [0; N]; + let mut pow_of_mod_inverse: CarrierUint = 1; + let mut pow_of_a = 1; + let mut i = 0; + while i < N { + mod_inv[i] = pow_of_mod_inverse; + max_quotients[i] = CarrierUint::MAX / pow_of_a; + + pow_of_mod_inverse = pow_of_mod_inverse.wrapping_mul(mod_inverse); + pow_of_a *= A; + i += 1; + } + Table { + mod_inv, + max_quotients, + } + }; +} + +pub(crate) unsafe fn divisible_by_power_of_5( + x: CarrierUint, + exp: u32, +) -> bool { + let table = &Table::<5, TABLE_SIZE>::TABLE; + debug_assert!((exp as usize) < TABLE_SIZE); + (x * *table.mod_inv.get_unchecked(exp as usize)) + <= *table.max_quotients.get_unchecked(exp as usize) +} + +pub(crate) fn divisible_by_power_of_2(x: CarrierUint, exp: u32) -> bool { + debug_assert!(exp >= 1); + debug_assert!(x != 0); + x.trailing_zeros() >= exp +} + +// Replace n by floor(n / 10^N). +// Returns true if and only if n is divisible by 10^N. +// Precondition: n <= 10^(N+1) +pub(crate) fn check_divisibility_and_divide_by_pow10(n: &mut u32) -> bool { + const N: u32 = 2; + debug_assert!(*n <= crate::compute_power32::<{ N + 1 }>(10)); + + struct Info; + impl Info { + const MAGIC_NUMBER: u32 = 0x147c29; + const BITS_FOR_COMPARISON: i32 = 12; + const THRESHOLD: u32 = 0xa3; + const SHIFT_AMOUNT: i32 = 27; + } + + *n *= Info::MAGIC_NUMBER; + + const COMPARISON_MASK: u32 = if Info::BITS_FOR_COMPARISON >= 32 { + u32::MAX + } else { + ((1 << Info::BITS_FOR_COMPARISON) - 1) as u32 + }; + + // The lowest N bits of (n & comparison_mask) must be zero, and + // (n >> N) & comparison_mask must be at most threshold. + let c = ((*n >> N) | (*n << (Info::BITS_FOR_COMPARISON as u32 - N))) & COMPARISON_MASK; + + *n >>= Info::SHIFT_AMOUNT; + c <= Info::THRESHOLD +} diff --git a/native/dragonbox/src/lib.rs b/native/dragonbox/src/lib.rs new file mode 100644 index 0000000000..728153ee88 --- /dev/null +++ b/native/dragonbox/src/lib.rs @@ -0,0 +1,558 @@ +// Translated from C++ to Rust. The original C++ code can be found at +// https://github.com/jk-jeon/dragonbox and carries the following license: +// +// Copyright 2020-2021 Junekey Jeon +// +// The contents of this file may be used under the terms of +// the Apache License v2.0 with LLVM Exceptions. +// +// (See accompanying file LICENSE-Apache or copy at +// https://llvm.org/foundation/relicensing/LICENSE.txt) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +//! [![github]](https://github.com/dtolnay/dragonbox) [![crates-io]](https://crates.io/crates/dragonbox) [![docs-rs]](https://docs.rs/dragonbox) +//! +//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github +//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust +//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs +//! +//!
+//! +//! This crate contains a basic port of +//! to Rust for benchmarking purposes. +//! +//! Please see the upstream repo for an explanation of the approach and +//! comparison to the Ryū algorithm. +//! +//! # Example +//! +//! ``` +//! fn main() { +//! let mut buffer = dragonbox::Buffer::new(); +//! let printed = buffer.format(1.234); +//! assert_eq!(printed, "1.234E0"); +//! } +//! ``` +//! +//! ## Performance (lower is better) +//! +//! ![performance](https://raw.githubusercontent.com/dtolnay/dragonbox/master/performance.png) + +#![no_std] +#![doc(html_root_url = "https://docs.rs/dragonbox/0.1.10")] +#![allow(unsafe_op_in_unsafe_fn)] +#![allow( + clippy::bool_to_int_with_if, + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::cast_possible_wrap, + clippy::cast_sign_loss, + clippy::comparison_chain, + clippy::doc_markdown, + clippy::expl_impl_clone_on_copy, + clippy::if_not_else, + clippy::items_after_statements, + clippy::manual_range_contains, + clippy::must_use_candidate, + clippy::needless_doctest_main, + clippy::never_loop, + clippy::ptr_as_ptr, + clippy::shadow_unrelated, + clippy::similar_names, + clippy::too_many_lines, + clippy::toplevel_ref_arg, + clippy::unreadable_literal, + clippy::unusual_byte_groupings +)] + +mod buffer; +mod cache; +mod div; +mod log; +mod to_chars; +mod wuint; + +use crate::buffer::Sealed; +use crate::cache::EntryTypeExt as _; +use core::mem::MaybeUninit; + +/// Buffer correctly sized to hold the text representation of any floating point +/// value. +/// +/// ## Example +/// +/// ``` +/// let mut buffer = dragonbox::Buffer::new(); +/// let printed = buffer.format_finite(1.234); +/// assert_eq!(printed, "1.234E0"); +/// ``` +pub struct Buffer { + bytes: [MaybeUninit; to_chars::MAX_OUTPUT_STRING_LENGTH], +} + +/// A floating point number that can be written into a +/// [`dragonbox::Buffer`][Buffer]. +/// +/// This trait is sealed and cannot be implemented for types outside of the +/// `dragonbox` crate. +pub trait Float: Sealed {} + +// IEEE754-binary64 +const SIGNIFICAND_BITS: usize = 52; +const EXPONENT_BITS: usize = 11; +const MIN_EXPONENT: i32 = -1022; +const EXPONENT_BIAS: i32 = -1023; + +// Defines an unsigned integer type that is large enough +// to carry a variable of type f64. +// Most of the operations will be done on this integer type. +type CarrierUint = u64; + +// Defines a signed integer type for holding significand bits together with the +// sign bit. +type SignedSignificand = i64; + +// Number of bits in the above unsigned integer type. +const CARRIER_BITS: usize = 64; + +// Extract exponent bits from a bit pattern. The result must be aligned to the +// LSB so that there is no additional zero paddings on the right. This function +// does not do bias adjustment. +const fn extract_exponent_bits(u: CarrierUint) -> u32 { + const EXPONENT_BITS_MASK: u32 = (1 << EXPONENT_BITS) - 1; + (u >> SIGNIFICAND_BITS) as u32 & EXPONENT_BITS_MASK +} + +// Remove the exponent bits and extract significand bits together with the sign +// bit. +const fn remove_exponent_bits(u: CarrierUint, exponent_bits: u32) -> SignedSignificand { + (u ^ ((exponent_bits as CarrierUint) << SIGNIFICAND_BITS)) as SignedSignificand +} + +// Shift the obtained signed significand bits to the left by 1 to remove the +// sign bit. +const fn remove_sign_bit_and_shift(s: SignedSignificand) -> CarrierUint { + (s as CarrierUint) << 1 +} + +const fn is_nonzero(u: CarrierUint) -> bool { + (u << 1) != 0 +} + +const fn is_negative(s: SignedSignificand) -> bool { + s < 0 +} + +const fn has_even_significand_bits(s: SignedSignificand) -> bool { + s % 2 == 0 +} + +const fn compute_power32(a: u32) -> u32 { + // assert!(k >= 0); + let mut p = 1; + let mut i = 0; + while i < K { + p *= a; + i += 1; + } + p +} + +const fn compute_power64(a: u64) -> u64 { + // assert!(k >= 0); + let mut p = 1; + let mut i = 0; + while i < K { + p *= a; + i += 1; + } + p +} + +const fn count_factors(mut n: usize) -> u32 { + // assert!(a > 1); + let mut c = 0; + while n % A == 0 { + n /= A; + c += 1; + } + c +} + +fn break_rounding_tie(significand: &mut u64) { + *significand = if *significand % 2 == 0 { + *significand + } else { + *significand - 1 + }; +} + +// Compute floor(n / 10^N) for small N. +// Precondition: n <= 2^a * 5^b (a = max_pow2, b = max_pow5) +fn divide_by_pow10(n: u64) -> u64 { + // Ensure no overflow. + assert!(MAX_POW2 + (log::floor_log2_pow10(MAX_POW5) - MAX_POW5) < 64); + + // Specialize for 64-bit division by 1000. + // Ensure that the correctness condition is met. + if N == 3 + && MAX_POW2 + (log::floor_log2_pow10(N as i32 + MAX_POW5) - (N as i32 + MAX_POW5)) < 70 + { + wuint::umul128_upper64(n, 0x8312_6e97_8d4f_df3c) >> 9 + } else { + struct Divisor; + impl Divisor { + const VALUE: u64 = compute_power64::(10); + } + n / Divisor::::VALUE + } +} + +struct Decimal { + significand: u64, + exponent: i32, +} + +const KAPPA: u32 = 2; + +// The main algorithm assumes the input is a normal/subnormal finite number +fn compute_nearest_normal( + two_fc: CarrierUint, + exponent: i32, + has_even_significand_bits: bool, +) -> Decimal { + ////////////////////////////////////////////////////////////////////// + // Step 1: Schubfach multiplier calculation + ////////////////////////////////////////////////////////////////////// + + // Compute k and beta. + let minus_k = log::floor_log10_pow2(exponent) - KAPPA as i32; + let ref cache = unsafe { cache::get(-minus_k) }; + let beta_minus_1 = exponent + log::floor_log2_pow10(-minus_k); + + // Compute zi and deltai. + // 10^kappa <= deltai < 10^(kappa + 1) + let deltai = compute_delta(cache, beta_minus_1); + let two_fr = two_fc | 1; + let zi = compute_mul(two_fr << beta_minus_1, cache); + + ////////////////////////////////////////////////////////////////////// + // Step 2: Try larger divisor; remove trailing zeros if necessary + ////////////////////////////////////////////////////////////////////// + + const BIG_DIVISOR: u32 = compute_power32::<{ KAPPA + 1 }>(10); + const SMALL_DIVISOR: u32 = compute_power32::(10); + + // Using an upper bound on zi, we might be able to optimize the division + // better than the compiler; we are computing zi / big_divisor here. + let mut significand = divide_by_pow10::< + { KAPPA + 1 }, + { SIGNIFICAND_BITS as i32 + KAPPA as i32 + 2 }, + { KAPPA as i32 + 1 }, + >(zi); + let mut r = (zi - BIG_DIVISOR as u64 * significand) as u32; + + 'small_divisor_case_label: loop { + if r > deltai { + break 'small_divisor_case_label; + } else if r < deltai { + // Exclude the right endpoint if necessary. + if r == 0 + && !has_even_significand_bits + && is_product_integer_fc_pm_half(two_fr, exponent, minus_k) + { + significand -= 1; + r = BIG_DIVISOR; + break 'small_divisor_case_label; + } + } else { + // r == deltai; compare fractional parts. + // Check conditions in the order different from the paper to take + // advantage of short-circuiting. + let two_fl = two_fc - 1; + if (!has_even_significand_bits + || !is_product_integer_fc_pm_half(two_fl, exponent, minus_k)) + && !compute_mul_parity(two_fl, cache, beta_minus_1) + { + break 'small_divisor_case_label; + } + } + let exponent = minus_k + KAPPA as i32 + 1; + + return Decimal { + significand, + exponent, + }; + } + + ////////////////////////////////////////////////////////////////////// + // Step 3: Find the significand with the smaller divisor + ////////////////////////////////////////////////////////////////////// + + significand *= 10; + let exponent = minus_k + KAPPA as i32; + + let mut dist = r - (deltai / 2) + (SMALL_DIVISOR / 2); + let approx_y_parity = ((dist ^ (SMALL_DIVISOR / 2)) & 1) != 0; + + // Is dist divisible by 10^kappa? + let divisible_by_10_to_the_kappa = div::check_divisibility_and_divide_by_pow10(&mut dist); + + // Add dist / 10^kappa to the significand. + significand += dist as CarrierUint; + + if divisible_by_10_to_the_kappa { + // Check z^(f) >= epsilon^(f) + // We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1, + // where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f) + // Since there are only 2 possibilities, we only need to care about the parity. + // Also, zi and r should have the same parity since the divisor + // is an even number. + if compute_mul_parity(two_fc, cache, beta_minus_1) != approx_y_parity { + significand -= 1; + } else { + // If z^(f) >= epsilon^(f), we might have a tie + // when z^(f) == epsilon^(f), or equivalently, when y is an integer. + // For tie-to-up case, we can just choose the upper one. + if is_product_integer_fc(two_fc, exponent, minus_k) { + break_rounding_tie(&mut significand); + } + } + } + + Decimal { + significand, + exponent, + } +} + +fn compute_nearest_shorter(exponent: i32) -> Decimal { + // Compute k and beta. + let minus_k = log::floor_log10_pow2_minus_log10_4_over_3(exponent); + let beta_minus_1 = exponent + log::floor_log2_pow10(-minus_k); + + // Compute xi and zi. + let ref cache = unsafe { cache::get(-minus_k) }; + + let mut xi = compute_left_endpoint_for_shorter_interval_case(cache, beta_minus_1); + let zi = compute_right_endpoint_for_shorter_interval_case(cache, beta_minus_1); + + // If the left endpoint is not an integer, increase it. + if !is_left_endpoint_integer_shorter_interval(exponent) { + xi += 1; + } + + // Try bigger divisor. + let significand = zi / 10; + + // If succeed, remove trailing zeros if necessary and return. + if significand * 10 >= xi { + return Decimal { + significand, + exponent: minus_k + 1, + }; + } + + // Otherwise, compute the round-up of y. + let mut significand = compute_round_up_for_shorter_interval_case(cache, beta_minus_1); + let exponent = minus_k; + + // When tie occurs, choose one of them according to the rule. + const SHORTER_INTERVAL_TIE_LOWER_THRESHOLD: i32 = + -log::floor_log5_pow2_minus_log5_3(SIGNIFICAND_BITS as i32 + 4) + - 2 + - SIGNIFICAND_BITS as i32; + const SHORTER_INTERVAL_TIE_UPPER_THRESHOLD: i32 = + -log::floor_log5_pow2(SIGNIFICAND_BITS as i32 + 2) - 2 - SIGNIFICAND_BITS as i32; + if exponent >= SHORTER_INTERVAL_TIE_LOWER_THRESHOLD + && exponent <= SHORTER_INTERVAL_TIE_UPPER_THRESHOLD + { + break_rounding_tie(&mut significand); + } else if significand < xi { + significand += 1; + } + + Decimal { + significand, + exponent, + } +} + +fn compute_mul(u: CarrierUint, cache: &cache::EntryType) -> CarrierUint { + wuint::umul192_upper64(u, *cache) +} + +fn compute_delta(cache: &cache::EntryType, beta_minus_1: i32) -> u32 { + (cache.high() >> ((CARRIER_BITS - 1) as i32 - beta_minus_1)) as u32 +} + +fn compute_mul_parity(two_f: CarrierUint, cache: &cache::EntryType, beta_minus_1: i32) -> bool { + debug_assert!(beta_minus_1 >= 1); + debug_assert!(beta_minus_1 < 64); + + ((wuint::umul192_middle64(two_f, *cache) >> (64 - beta_minus_1)) & 1) != 0 +} + +fn compute_left_endpoint_for_shorter_interval_case( + cache: &cache::EntryType, + beta_minus_1: i32, +) -> CarrierUint { + (cache.high() - (cache.high() >> (SIGNIFICAND_BITS + 2))) + >> ((CARRIER_BITS - SIGNIFICAND_BITS - 1) as i32 - beta_minus_1) +} + +fn compute_right_endpoint_for_shorter_interval_case( + cache: &cache::EntryType, + beta_minus_1: i32, +) -> CarrierUint { + (cache.high() + (cache.high() >> (SIGNIFICAND_BITS + 2))) + >> ((CARRIER_BITS - SIGNIFICAND_BITS - 1) as i32 - beta_minus_1) +} + +fn compute_round_up_for_shorter_interval_case( + cache: &cache::EntryType, + beta_minus_1: i32, +) -> CarrierUint { + ((cache.high() >> ((CARRIER_BITS - SIGNIFICAND_BITS - 2) as i32 - beta_minus_1)) + 1) / 2 +} + +const MAX_POWER_OF_FACTOR_OF_5: i32 = log::floor_log5_pow2(SIGNIFICAND_BITS as i32 + 2); +const DIVISIBILITY_CHECK_BY_5_THRESHOLD: i32 = + log::floor_log2_pow10(MAX_POWER_OF_FACTOR_OF_5 + KAPPA as i32 + 1); + +fn is_product_integer_fc_pm_half(two_f: CarrierUint, exponent: i32, minus_k: i32) -> bool { + const CASE_FC_PM_HALF_LOWER_THRESHOLD: i32 = + -(KAPPA as i32) - log::floor_log5_pow2(KAPPA as i32); + const CASE_FC_PM_HALF_UPPER_THRESHOLD: i32 = log::floor_log2_pow10(KAPPA as i32 + 1); + + // Case I: f = fc +- 1/2 + if exponent < CASE_FC_PM_HALF_LOWER_THRESHOLD { + false + } + // For k >= 0 + else if exponent <= CASE_FC_PM_HALF_UPPER_THRESHOLD { + true + } + // For k < 0 + else if exponent > DIVISIBILITY_CHECK_BY_5_THRESHOLD { + false + } else { + unsafe { + div::divisible_by_power_of_5::<{ MAX_POWER_OF_FACTOR_OF_5 as usize + 1 }>( + two_f, + minus_k as u32, + ) + } + } +} + +fn is_product_integer_fc(two_f: CarrierUint, exponent: i32, minus_k: i32) -> bool { + const CASE_FC_LOWER_THRESHOLD: i32 = + -(KAPPA as i32) - 1 - log::floor_log5_pow2(KAPPA as i32 + 1); + const CASE_FC_UPPER_THRESHOLD: i32 = log::floor_log2_pow10(KAPPA as i32 + 1); + + // Case II: f = fc + 1 + // Case III: f = fc + // Exponent for 5 is negative + if exponent > DIVISIBILITY_CHECK_BY_5_THRESHOLD { + false + } else if exponent > CASE_FC_UPPER_THRESHOLD { + unsafe { + div::divisible_by_power_of_5::<{ MAX_POWER_OF_FACTOR_OF_5 as usize + 1 }>( + two_f, + minus_k as u32, + ) + } + } + // Both exponents are nonnegative + else if exponent >= CASE_FC_LOWER_THRESHOLD { + true + } + // Exponent for 2 is negative + else { + div::divisible_by_power_of_2(two_f, (minus_k - exponent + 1) as u32) + } +} + +const fn floor_log2(mut n: u64) -> i32 { + let mut count = -1; + while n != 0 { + count += 1; + n >>= 1; + } + count +} + +fn is_left_endpoint_integer_shorter_interval(exponent: i32) -> bool { + const CASE_SHORTER_INTERVAL_LEFT_ENDPOINT_LOWER_THRESHOLD: i32 = 2; + const CASE_SHORTER_INTERVAL_LEFT_ENDPOINT_UPPER_THRESHOLD: i32 = 2 + floor_log2( + compute_power64::<{ count_factors::<5>((1 << (SIGNIFICAND_BITS + 2)) - 1) + 1 }>(10) / 3, + ); + exponent >= CASE_SHORTER_INTERVAL_LEFT_ENDPOINT_LOWER_THRESHOLD + && exponent <= CASE_SHORTER_INTERVAL_LEFT_ENDPOINT_UPPER_THRESHOLD +} + +fn to_decimal(x: f64) -> Decimal { + let br = x.to_bits(); + let exponent_bits = extract_exponent_bits(br); + let signed_significand_bits = remove_exponent_bits(br, exponent_bits); + + let mut two_fc = remove_sign_bit_and_shift(signed_significand_bits); + let mut exponent = exponent_bits as i32; + + // Is the input a normal number? + if exponent != 0 { + exponent += EXPONENT_BIAS - SIGNIFICAND_BITS as i32; + + // Shorter interval case; proceed like Schubfach. One might think this + // condition is wrong, since when exponent_bits == 1 and two_fc == 0, + // the interval is actually regular. However, it turns out that this + // seemingly wrong condition is actually fine, because the end result is + // anyway the same. + // + // [binary32] + // floor( (fc-1/2) * 2^e ) = 1.175'494'28... * 10^-38 + // floor( (fc-1/4) * 2^e ) = 1.175'494'31... * 10^-38 + // floor( fc * 2^e ) = 1.175'494'35... * 10^-38 + // floor( (fc+1/2) * 2^e ) = 1.175'494'42... * 10^-38 + // + // Hence, shorter_interval_case will return 1.175'494'4 * 10^-38. + // 1.175'494'3 * 10^-38 is also a correct shortest representation that + // will be rejected if we assume shorter interval, but 1.175'494'4 * + // 10^-38 is closer to the true value so it doesn't matter. + // + // [binary64] + // floor( (fc-1/2) * 2^e ) = 2.225'073'858'507'201'13... * 10^-308 + // floor( (fc-1/4) * 2^e ) = 2.225'073'858'507'201'25... * 10^-308 + // floor( fc * 2^e ) = 2.225'073'858'507'201'38... * 10^-308 + // floor( (fc+1/2) * 2^e ) = 2.225'073'858'507'201'63... * 10^-308 + // + // Hence, shorter_interval_case will return 2.225'073'858'507'201'4 * 10^-308. + // This is indeed of the shortest length, and it is the unique one + // closest to the true value among valid representations of the same + // length. + if two_fc == 0 { + return compute_nearest_shorter(exponent); + } + + two_fc |= 1 << (SIGNIFICAND_BITS + 1); + } + // Is the input a subnormal number? + else { + exponent = MIN_EXPONENT - SIGNIFICAND_BITS as i32; + } + + compute_nearest_normal( + two_fc, + exponent, + has_even_significand_bits(signed_significand_bits), + ) +} diff --git a/native/dragonbox/src/log.rs b/native/dragonbox/src/log.rs new file mode 100644 index 0000000000..2cc7ff83f0 --- /dev/null +++ b/native/dragonbox/src/log.rs @@ -0,0 +1,123 @@ +// Translated from C++ to Rust. The original C++ code can be found at +// https://github.com/jk-jeon/dragonbox and carries the following license: +// +// Copyright 2020-2021 Junekey Jeon +// +// The contents of this file may be used under the terms of +// the Apache License v2.0 with LLVM Exceptions. +// +// (See accompanying file LICENSE-Apache or copy at +// https://llvm.org/foundation/relicensing/LICENSE.txt) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +//////////////////////////////////////////////////////////////////////////////////////// +// Utilities for fast/constexpr log computation. +//////////////////////////////////////////////////////////////////////////////////////// + +const fn floor_shift(integer_part: u32, fractional_digits: u64, shift_amount: usize) -> i32 { + //debug_assert!(shift_amount < 32); + // Ensure no overflow + //debug_assert!(shift_amount == 0 || integer_part < (1 << (32 - shift_amount))); + + if shift_amount == 0 { + integer_part as i32 + } else { + ((integer_part << shift_amount) | (fractional_digits >> (64 - shift_amount)) as u32) as i32 + } +} + +// Compute floor(e * c - s). +const fn compute< + const C_INTEGER_PART: u32, + const C_FRACTIONAL_DIGITS: u64, + const SHIFT_AMOUNT: usize, + const MAX_EXPONENT: i32, + const S_INTEGER_PART: u32, + const S_FRACTIONAL_DIGITS: u64, +>( + e: i32, +) -> i32 { + //debug_assert!(e <= MAX_EXPONENT && e >= -MAX_EXPONENT); + let c = floor_shift(C_INTEGER_PART, C_FRACTIONAL_DIGITS, SHIFT_AMOUNT); + let s = floor_shift(S_INTEGER_PART, S_FRACTIONAL_DIGITS, SHIFT_AMOUNT); + (e * c - s) >> SHIFT_AMOUNT +} + +const LOG10_2_FRACTIONAL_DIGITS: u64 = 0x4d10_4d42_7de7_fbcc; +const LOG10_4_OVER_3_FRACTIONAL_DIGITS: u64 = 0x1ffb_fc2b_bc78_0375; +const FLOOR_LOG10_POW2_SHIFT_AMOUNT: usize = 22; +const FLOOR_LOG10_POW2_INPUT_LIMIT: i32 = 1700; +const FLOOR_LOG10_POW2_MINUS_LOG10_4_OVER_3_INPUT_LIMIT: i32 = 1700; + +const LOG2_10_FRACTIONAL_DIGITS: u64 = 0x5269_e12f_346e_2bf9; +const FLOOR_LOG2_POW10_SHIFT_AMOUNT: usize = 19; +const FLOOR_LOG2_POW10_INPUT_LIMIT: i32 = 1233; + +const LOG5_2_FRACTIONAL_DIGITS: u64 = 0x6e40_d1a4_143d_cb94; +const LOG5_3_FRACTIONAL_DIGITS: u64 = 0xaebf_4791_5d44_3b24; +const FLOOR_LOG5_POW2_SHIFT_AMOUNT: usize = 20; +const FLOOR_LOG5_POW2_INPUT_LIMIT: i32 = 1492; +const FLOOR_LOG5_POW2_MINUS_LOG5_3_INPUT_LIMIT: i32 = 2427; + +pub(crate) const fn floor_log10_pow2(e: i32) -> i32 { + compute::< + 0, + LOG10_2_FRACTIONAL_DIGITS, + FLOOR_LOG10_POW2_SHIFT_AMOUNT, + FLOOR_LOG10_POW2_INPUT_LIMIT, + 0, + 0, + >(e) +} + +pub(crate) const fn floor_log2_pow10(e: i32) -> i32 { + compute::< + 3, + LOG2_10_FRACTIONAL_DIGITS, + FLOOR_LOG2_POW10_SHIFT_AMOUNT, + FLOOR_LOG2_POW10_INPUT_LIMIT, + 0, + 0, + >(e) +} + +pub(crate) const fn floor_log5_pow2(e: i32) -> i32 { + compute::< + 0, + LOG5_2_FRACTIONAL_DIGITS, + FLOOR_LOG5_POW2_SHIFT_AMOUNT, + FLOOR_LOG5_POW2_INPUT_LIMIT, + 0, + 0, + >(e) +} + +pub(crate) const fn floor_log5_pow2_minus_log5_3(e: i32) -> i32 { + compute::< + 0, + LOG5_2_FRACTIONAL_DIGITS, + FLOOR_LOG5_POW2_SHIFT_AMOUNT, + FLOOR_LOG5_POW2_MINUS_LOG5_3_INPUT_LIMIT, + 0, + LOG5_3_FRACTIONAL_DIGITS, + >(e) +} + +pub(crate) const fn floor_log10_pow2_minus_log10_4_over_3(e: i32) -> i32 { + compute::< + 0, + LOG10_2_FRACTIONAL_DIGITS, + FLOOR_LOG10_POW2_SHIFT_AMOUNT, + FLOOR_LOG10_POW2_MINUS_LOG10_4_OVER_3_INPUT_LIMIT, + 0, + LOG10_4_OVER_3_FRACTIONAL_DIGITS, + >(e) +} diff --git a/native/dragonbox/src/to_chars.rs b/native/dragonbox/src/to_chars.rs new file mode 100644 index 0000000000..4a95af71fd --- /dev/null +++ b/native/dragonbox/src/to_chars.rs @@ -0,0 +1,422 @@ +// Translated from C++ to Rust. The original C++ code can be found at +// https://github.com/jk-jeon/dragonbox and carries the following license: +// +// Copyright 2020-2021 Junekey Jeon +// +// The contents of this file may be used under the terms of +// the Apache License v2.0 with LLVM Exceptions. +// +// (See accompanying file LICENSE-Apache or copy at +// https://llvm.org/foundation/relicensing/LICENSE.txt) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +use core::ptr; + +// sign(1) + significand(17) + decimal_point(1) + exp_marker(1) + exp_sign(1) + exp(3) +pub(crate) const MAX_OUTPUT_STRING_LENGTH: usize = 1 + 17 + 1 + 1 + 1 + 3; + +pub(crate) unsafe fn to_chars(x: f64, mut buffer: *mut u8) -> *mut u8 { + let br = x.to_bits(); + let exponent_bits = crate::extract_exponent_bits(br); + let s = crate::remove_exponent_bits(br, exponent_bits); + + if crate::is_negative(s) { + *buffer = b'-'; + buffer = buffer.add(1); + } + + if crate::is_nonzero(br) { + let result = crate::to_decimal(x); + to_chars_detail(result.significand, result.exponent, buffer) + } else { + ptr::copy_nonoverlapping(b"0E0".as_ptr(), buffer, 3); + buffer.add(3) + } +} + +#[rustfmt::skip] +static RADIX_100_TABLE: [u8; 200] = [ + b'0', b'0', b'0', b'1', b'0', b'2', b'0', b'3', b'0', b'4', + b'0', b'5', b'0', b'6', b'0', b'7', b'0', b'8', b'0', b'9', + b'1', b'0', b'1', b'1', b'1', b'2', b'1', b'3', b'1', b'4', + b'1', b'5', b'1', b'6', b'1', b'7', b'1', b'8', b'1', b'9', + b'2', b'0', b'2', b'1', b'2', b'2', b'2', b'3', b'2', b'4', + b'2', b'5', b'2', b'6', b'2', b'7', b'2', b'8', b'2', b'9', + b'3', b'0', b'3', b'1', b'3', b'2', b'3', b'3', b'3', b'4', + b'3', b'5', b'3', b'6', b'3', b'7', b'3', b'8', b'3', b'9', + b'4', b'0', b'4', b'1', b'4', b'2', b'4', b'3', b'4', b'4', + b'4', b'5', b'4', b'6', b'4', b'7', b'4', b'8', b'4', b'9', + b'5', b'0', b'5', b'1', b'5', b'2', b'5', b'3', b'5', b'4', + b'5', b'5', b'5', b'6', b'5', b'7', b'5', b'8', b'5', b'9', + b'6', b'0', b'6', b'1', b'6', b'2', b'6', b'3', b'6', b'4', + b'6', b'5', b'6', b'6', b'6', b'7', b'6', b'8', b'6', b'9', + b'7', b'0', b'7', b'1', b'7', b'2', b'7', b'3', b'7', b'4', + b'7', b'5', b'7', b'6', b'7', b'7', b'7', b'8', b'7', b'9', + b'8', b'0', b'8', b'1', b'8', b'2', b'8', b'3', b'8', b'4', + b'8', b'5', b'8', b'6', b'8', b'7', b'8', b'8', b'8', b'9', + b'9', b'0', b'9', b'1', b'9', b'2', b'9', b'3', b'9', b'4', + b'9', b'5', b'9', b'6', b'9', b'7', b'9', b'8', b'9', b'9', +]; + +#[rustfmt::skip] +static TRAILING_ZERO_COUNT_TABLE: [i8; 100] = [ + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +]; + +fn decimal_length_minus_1(v: u32) -> i32 { + debug_assert!(v < 1000000000); + if v >= 100000000 { + 8 + } else if v >= 10000000 { + 7 + } else if v >= 1000000 { + 6 + } else if v >= 100000 { + 5 + } else if v >= 10000 { + 4 + } else if v >= 1000 { + 3 + } else if v >= 100 { + 2 + } else if v >= 10 { + 1 + } else { + 0 + } +} + +// Granlund-Montgomery style fast division +struct QuotientRemainderPair { + quotient: u32, + remainder: u32, +} + +fn fast_div( + n: u32, +) -> QuotientRemainderPair { + debug_assert!(MAX_PRECISION > 0 && MAX_PRECISION <= 32); + debug_assert!(n < (1 << MAX_PRECISION)); + + let left_end = ((1u32 << (MAX_PRECISION + ADDITIONAL_PRECISION)) + DIVISOR - 1) / DIVISOR; + let right_end = ((1u32 << ADDITIONAL_PRECISION) * ((1 << MAX_PRECISION) + 1)) / DIVISOR; + + // Ensures sufficient precision. + debug_assert!(left_end <= right_end); + // Ensures no overflow. + debug_assert!(left_end <= (1 << (32 - MAX_PRECISION)) as u32); + + let quotient = (n * left_end) >> (MAX_PRECISION + ADDITIONAL_PRECISION); + let remainder = n - DIVISOR * quotient; + QuotientRemainderPair { + quotient, + remainder, + } +} + +unsafe fn to_chars_detail(significand: u64, mut exponent: i32, mut buffer: *mut u8) -> *mut u8 { + let mut s32: u32; + let mut remaining_digits_minus_1: i32; + let mut exponent_position: i32; + let mut may_have_more_trailing_zeros = false; + + if significand >> 32 != 0 { + // Since significand is at most 10^17, the quotient is at most 10^9, so + // it fits inside 32-bit integer + s32 = (significand / 1_0000_0000) as u32; + let mut r = (significand as u32).wrapping_sub(s32.wrapping_mul(1_0000_0000)); + + remaining_digits_minus_1 = decimal_length_minus_1(s32) + 8; + exponent += remaining_digits_minus_1; + exponent_position = remaining_digits_minus_1 + 2; + + if r != 0 { + // Print 8 digits + // `c = r % 1_0000` https://bugs.llvm.org/show_bug.cgi?id=38217 + let c = r - 1_0000 * (r / 1_0000); + r /= 1_0000; + + // c1 = r / 100; c2 = r % 100; + let QuotientRemainderPair { + quotient: c1, + remainder: c2, + } = fast_div::<100, 14, 5>(r); + // c3 = c / 100; c4 = c % 100; + let QuotientRemainderPair { + quotient: c3, + remainder: c4, + } = fast_div::<100, 14, 5>(c); + + 'after_print_label: loop { + 'print_c1_label: loop { + 'print_c2_label: loop { + 'print_c3_label: loop { + 'print_c4_label: loop { + let mut tz = *TRAILING_ZERO_COUNT_TABLE.get_unchecked(c4 as usize); + if tz == 0 { + break 'print_c4_label; + } else if tz == 1 { + *buffer.offset(remaining_digits_minus_1 as isize) = + *RADIX_100_TABLE.get_unchecked(c4 as usize * 2); + exponent_position -= 1; + break 'print_c3_label; + } + + tz = *TRAILING_ZERO_COUNT_TABLE.get_unchecked(c3 as usize); + if tz == 0 { + exponent_position -= 2; + break 'print_c3_label; + } else if tz == 1 { + *buffer.offset(remaining_digits_minus_1 as isize - 2) = + *RADIX_100_TABLE.get_unchecked(c3 as usize * 2); + exponent_position -= 3; + break 'print_c2_label; + } + + tz = *TRAILING_ZERO_COUNT_TABLE.get_unchecked(c2 as usize); + if tz == 0 { + exponent_position -= 4; + break 'print_c2_label; + } else if tz == 1 { + *buffer.offset(remaining_digits_minus_1 as isize - 4) = + *RADIX_100_TABLE.get_unchecked(c2 as usize * 2); + exponent_position -= 5; + break 'print_c1_label; + } + + tz = *TRAILING_ZERO_COUNT_TABLE.get_unchecked(c1 as usize); + if tz == 0 { + exponent_position -= 6; + break 'print_c1_label; + } + // We assumed r != 0, so c1 cannot be zero in this case. + debug_assert!(tz == 1); + *buffer.offset(remaining_digits_minus_1 as isize - 6) = + *RADIX_100_TABLE.get_unchecked(c1 as usize * 2); + exponent_position -= 7; + break 'after_print_label; + } + + ptr::copy_nonoverlapping( + RADIX_100_TABLE.as_ptr().add(c4 as usize * 2), + buffer.offset(remaining_digits_minus_1 as isize), + 2, + ); + break; + } + + ptr::copy_nonoverlapping( + RADIX_100_TABLE.as_ptr().add(c3 as usize * 2), + buffer.offset(remaining_digits_minus_1 as isize - 2), + 2, + ); + break; + } + + ptr::copy_nonoverlapping( + RADIX_100_TABLE.as_ptr().add(c2 as usize * 2), + buffer.offset(remaining_digits_minus_1 as isize - 4), + 2, + ); + break; + } + + ptr::copy_nonoverlapping( + RADIX_100_TABLE.as_ptr().add(c1 as usize * 2), + buffer.offset(remaining_digits_minus_1 as isize - 6), + 2, + ); + break; + } + } + // r != 0 + else { + // r == 0 + exponent_position -= 8; + may_have_more_trailing_zeros = true; + } + remaining_digits_minus_1 -= 8; + } else { + s32 = significand as u32; + if s32 >= 10_0000_0000 { + remaining_digits_minus_1 = 9; + } else { + remaining_digits_minus_1 = decimal_length_minus_1(s32); + } + exponent += remaining_digits_minus_1; + exponent_position = remaining_digits_minus_1 + 2; + may_have_more_trailing_zeros = true; + } + + while remaining_digits_minus_1 >= 4 { + // c = s32 % 1_0000` https://bugs.llvm.org/show_bug.cgi?id=38217 + let c = s32 - 1_0000 * (s32 / 1_0000); + s32 /= 1_0000; + + // c1 = c / 100; c2 = c % 100; + let QuotientRemainderPair { + quotient: c1, + remainder: c2, + } = fast_div::<100, 14, 5>(c); + + 'inside_loop_after_print_label: loop { + 'inside_loop_print_c1_label: loop { + 'inside_loop_print_c2_label: loop { + if may_have_more_trailing_zeros { + let mut tz = *TRAILING_ZERO_COUNT_TABLE.get_unchecked(c2 as usize); + if tz == 0 { + may_have_more_trailing_zeros = false; + break 'inside_loop_print_c2_label; + } else if tz == 1 { + may_have_more_trailing_zeros = false; + exponent_position -= 1; + *buffer.offset(remaining_digits_minus_1 as isize) = + *RADIX_100_TABLE.get_unchecked(c2 as usize * 2); + break 'inside_loop_print_c1_label; + } + + tz = *TRAILING_ZERO_COUNT_TABLE.get_unchecked(c1 as usize); + if tz == 0 { + may_have_more_trailing_zeros = false; + exponent_position -= 2; + break 'inside_loop_print_c1_label; + } else if tz == 1 { + may_have_more_trailing_zeros = false; + exponent_position -= 3; + *buffer.offset(remaining_digits_minus_1 as isize - 2) = + *RADIX_100_TABLE.get_unchecked(c1 as usize * 2); + break 'inside_loop_after_print_label; + } + exponent_position -= 4; + break 'inside_loop_after_print_label; + } + break; + } + + ptr::copy_nonoverlapping( + RADIX_100_TABLE.as_ptr().add(c2 as usize * 2), + buffer.offset(remaining_digits_minus_1 as isize), + 2, + ); + break; + } + + ptr::copy_nonoverlapping( + RADIX_100_TABLE.as_ptr().add(c1 as usize * 2), + buffer.offset(remaining_digits_minus_1 as isize - 2), + 2, + ); + break; + } + remaining_digits_minus_1 -= 4; + } + if remaining_digits_minus_1 >= 2 { + // c1 = s32 / 100; c2 = s32 % 100; + let QuotientRemainderPair { + quotient: c1, + remainder: c2, + } = fast_div::<100, 14, 5>(s32); + s32 = c1; + + if may_have_more_trailing_zeros { + let tz = *TRAILING_ZERO_COUNT_TABLE.get_unchecked(c2 as usize); + exponent_position -= tz as i32; + if tz == 0 { + ptr::copy_nonoverlapping( + RADIX_100_TABLE.as_ptr().add(c2 as usize * 2), + buffer.offset(remaining_digits_minus_1 as isize), + 2, + ); + may_have_more_trailing_zeros = false; + } else if tz == 1 { + *buffer.offset(remaining_digits_minus_1 as isize) = + *RADIX_100_TABLE.get_unchecked(c2 as usize * 2); + may_have_more_trailing_zeros = false; + } + } else { + ptr::copy_nonoverlapping( + RADIX_100_TABLE.as_ptr().add(c2 as usize * 2), + buffer.offset(remaining_digits_minus_1 as isize), + 2, + ); + } + + remaining_digits_minus_1 -= 2; + } + if remaining_digits_minus_1 > 0 { + debug_assert!(remaining_digits_minus_1 == 1); + // d1 = s32 / 10; d2 = s32 % 10; + let QuotientRemainderPair { + quotient: d1, + remainder: d2, + } = fast_div::<10, 7, 3>(s32); + + *buffer = b'0' + d1 as u8; + if may_have_more_trailing_zeros && d2 == 0 { + buffer = buffer.add(1); + } else { + *buffer.add(1) = b'.'; + *buffer.add(2) = b'0' + d2 as u8; + buffer = buffer.offset(exponent_position as isize); + } + } else { + *buffer = b'0' + s32 as u8; + + if may_have_more_trailing_zeros { + buffer = buffer.add(1); + } else { + *buffer.add(1) = b'.'; + buffer = buffer.offset(exponent_position as isize); + } + } + + // Print exponent and return + if exponent < 0 { + ptr::copy_nonoverlapping(b"E-".as_ptr(), buffer, 2); + buffer = buffer.add(2); + exponent = -exponent; + } else { + *buffer = b'E'; + buffer = buffer.add(1); + } + + if exponent >= 100 { + // d1 = exponent / 10; d2 = exponent % 10; + let QuotientRemainderPair { + quotient: d1, + remainder: d2, + } = fast_div::<10, 10, 3>(exponent as u32); + ptr::copy_nonoverlapping(RADIX_100_TABLE.as_ptr().add(d1 as usize * 2), buffer, 2); + *buffer.add(2) = b'0' + d2 as u8; + buffer = buffer.add(3); + } else if exponent >= 10 { + ptr::copy_nonoverlapping( + RADIX_100_TABLE.as_ptr().add(exponent as usize * 2), + buffer, + 2, + ); + buffer = buffer.add(2); + } else { + *buffer = b'0' + exponent as u8; + buffer = buffer.add(1); + } + + buffer +} diff --git a/native/dragonbox/src/wuint.rs b/native/dragonbox/src/wuint.rs new file mode 100644 index 0000000000..06df591ac2 --- /dev/null +++ b/native/dragonbox/src/wuint.rs @@ -0,0 +1,38 @@ +// Translated from C++ to Rust. The original C++ code can be found at +// https://github.com/jk-jeon/dragonbox and carries the following license: +// +// Copyright 2020-2021 Junekey Jeon +// +// The contents of this file may be used under the terms of +// the Apache License v2.0 with LLVM Exceptions. +// +// (See accompanying file LICENSE-Apache or copy at +// https://llvm.org/foundation/relicensing/LICENSE.txt) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +use crate::cache::EntryTypeExt as _; + +pub(crate) fn umul128_upper64(x: u64, y: u64) -> u64 { + let p = x as u128 * y as u128; + (p >> 64) as u64 +} + +pub(crate) fn umul192_upper64(x: u64, y: u128) -> u64 { + let mut g0 = x as u128 * y.high() as u128; + g0 += umul128_upper64(x, y.low()) as u128; + g0.high() +} + +pub(crate) fn umul192_middle64(x: u64, y: u128) -> u64 { + let g01 = x.wrapping_mul(y.high()); + let g10 = umul128_upper64(x, y.low()); + g01.wrapping_add(g10) +} diff --git a/native/dragonbox/tests/binary64_test.rs b/native/dragonbox/tests/binary64_test.rs new file mode 100644 index 0000000000..765135d1bc --- /dev/null +++ b/native/dragonbox/tests/binary64_test.rs @@ -0,0 +1,330 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +#![allow( + clippy::cast_lossless, + clippy::excessive_precision, + clippy::float_cmp, + clippy::int_plus_one, + clippy::non_ascii_literal, + clippy::unreadable_literal, + clippy::unseparated_literal_suffix +)] + +#[macro_use] +mod macros; + +use std::f64; + +fn to_chars(f: f64) -> String { + dragonbox::Buffer::new().format(f).to_owned() +} + +fn ieee_parts_to_double(sign: bool, ieee_exponent: u32, ieee_mantissa: u64) -> f64 { + assert!(ieee_exponent <= 2047); + assert!(ieee_mantissa <= (1u64 << 53) - 1); + f64::from_bits(((sign as u64) << 63) | ((ieee_exponent as u64) << 52) | ieee_mantissa) +} + +#[test] +fn test_dragonbox() { + check!(3E-1); + check!(1.234E15); + check!(2.71828E0); + check!(1.1E128); + check!(1.1E-64); + check!(2.718281828459045E0); + check!(5E-324); + check!(1.7976931348623157E308); +} + +#[test] +fn test_random() { + let n = if cfg!(miri) { 100 } else { 1000000 }; + let mut buffer = dragonbox::Buffer::new(); + for _ in 0..n { + let f: f64 = rand::random(); + assert_eq!(f, buffer.format_finite(f).parse().unwrap()); + } +} + +#[test] +#[cfg_attr(miri, ignore = "too slow for miri")] +fn test_non_finite() { + for i in 0u64..1 << 23 { + let f = f64::from_bits((((1 << 11) - 1) << 52) + (i << 29)); + assert!(!f.is_finite(), "f={}", f); + dragonbox::Buffer::new().format_finite(f); + } +} + +#[test] +fn test_basic() { + check!(0E0); + check!(-0E0); + check!(1E0); + check!(-1E0); + assert_eq!(to_chars(f64::NAN.copysign(1.0)), "NaN"); + assert_eq!(to_chars(f64::NAN.copysign(-1.0)), "NaN"); + assert_eq!(to_chars(f64::INFINITY), "inf"); + assert_eq!(to_chars(f64::NEG_INFINITY), "-inf"); +} + +#[test] +fn test_switch_to_subnormal() { + check!(2.2250738585072014E-308); +} + +#[test] +fn test_min_and_max() { + assert_eq!(f64::from_bits(0x7fefffffffffffff), 1.7976931348623157E308); + check!(1.7976931348623157E308); + assert_eq!(f64::from_bits(1), 5E-324); + check!(5E-324); +} + +#[test] +fn test_lots_of_trailing_zeros() { + check!(2.9802322387695313E-8); +} + +#[test] +fn test_regression() { + check!(-2.109808898695963E16); + check!(4.940656E-318); + check!(1.18575755E-316); + check!(2.989102097996E-312); + check!(9.0608011534336E15); + check!(4.708356024711512E18); + check!(9.409340012568248E18); + check!(1.2345678E0); +} + +#[test] +fn test_looks_like_pow5() { + // These numbers have a mantissa that is a multiple of the largest power of + // 5 that fits, and an exponent that causes the computation for q to result + // in 22, which is a corner case for Ryū. + assert_eq!(f64::from_bits(0x4830F0CF064DD592), 5.764607523034235E39); + check!(5.764607523034235E39); + assert_eq!(f64::from_bits(0x4840F0CF064DD592), 1.152921504606847E40); + check!(1.152921504606847E40); + assert_eq!(f64::from_bits(0x4850F0CF064DD592), 2.305843009213694E40); + check!(2.305843009213694E40); +} + +#[test] +fn test_output_length() { + check!(1E0); // already tested in Basic + check!(1.2E0); + check!(1.23E0); + check!(1.234E0); + check!(1.2345E0); + check!(1.23456E0); + check!(1.234567E0); + check!(1.2345678E0); // already tested in Regression + check!(1.23456789E0); + check!(1.234567895E0); // 1.234567890 would be trimmed + check!(1.2345678901E0); + check!(1.23456789012E0); + check!(1.234567890123E0); + check!(1.2345678901234E0); + check!(1.23456789012345E0); + check!(1.234567890123456E0); + check!(1.2345678901234567E0); + + // Test 32-bit chunking + check!(4.294967294E0); // 2^32 - 2 + check!(4.294967295E0); // 2^32 - 1 + check!(4.294967296E0); // 2^32 + check!(4.294967297E0); // 2^32 + 1 + check!(4.294967298E0); // 2^32 + 2 +} + +// Test min, max shift values in shiftright128 +#[test] +fn test_min_max_shift() { + let max_mantissa = (1u64 << 53) - 1; + + // 32-bit opt-size=0: 49 <= dist <= 50 + // 32-bit opt-size=1: 30 <= dist <= 50 + // 64-bit opt-size=0: 50 <= dist <= 50 + // 64-bit opt-size=1: 30 <= dist <= 50 + assert_eq!(1.7800590868057611E-307, ieee_parts_to_double(false, 4, 0)); + check!(1.7800590868057611E-307); + // 32-bit opt-size=0: 49 <= dist <= 49 + // 32-bit opt-size=1: 28 <= dist <= 49 + // 64-bit opt-size=0: 50 <= dist <= 50 + // 64-bit opt-size=1: 28 <= dist <= 50 + assert_eq!( + 2.8480945388892175E-306, + ieee_parts_to_double(false, 6, max_mantissa) + ); + check!(2.8480945388892175E-306); + // 32-bit opt-size=0: 52 <= dist <= 53 + // 32-bit opt-size=1: 2 <= dist <= 53 + // 64-bit opt-size=0: 53 <= dist <= 53 + // 64-bit opt-size=1: 2 <= dist <= 53 + assert_eq!(2.446494580089078E-296, ieee_parts_to_double(false, 41, 0)); + check!(2.446494580089078E-296); + // 32-bit opt-size=0: 52 <= dist <= 52 + // 32-bit opt-size=1: 2 <= dist <= 52 + // 64-bit opt-size=0: 53 <= dist <= 53 + // 64-bit opt-size=1: 2 <= dist <= 53 + assert_eq!( + 4.8929891601781557E-296, + ieee_parts_to_double(false, 40, max_mantissa) + ); + check!(4.8929891601781557E-296); + + // 32-bit opt-size=0: 57 <= dist <= 58 + // 32-bit opt-size=1: 57 <= dist <= 58 + // 64-bit opt-size=0: 58 <= dist <= 58 + // 64-bit opt-size=1: 58 <= dist <= 58 + assert_eq!(1.8014398509481984E16, ieee_parts_to_double(false, 1077, 0)); + check!(1.8014398509481984E16); + // 32-bit opt-size=0: 57 <= dist <= 57 + // 32-bit opt-size=1: 57 <= dist <= 57 + // 64-bit opt-size=0: 58 <= dist <= 58 + // 64-bit opt-size=1: 58 <= dist <= 58 + assert_eq!( + 3.6028797018963964E16, + ieee_parts_to_double(false, 1076, max_mantissa) + ); + check!(3.6028797018963964E16); + // 32-bit opt-size=0: 51 <= dist <= 52 + // 32-bit opt-size=1: 51 <= dist <= 59 + // 64-bit opt-size=0: 52 <= dist <= 52 + // 64-bit opt-size=1: 52 <= dist <= 59 + assert_eq!(2.9008355198595578E-216, ieee_parts_to_double(false, 307, 0)); + check!(2.9008355198595578E-216); + // 32-bit opt-size=0: 51 <= dist <= 51 + // 32-bit opt-size=1: 51 <= dist <= 59 + // 64-bit opt-size=0: 52 <= dist <= 52 + // 64-bit opt-size=1: 52 <= dist <= 59 + assert_eq!( + 5.801671039719115E-216, + ieee_parts_to_double(false, 306, max_mantissa) + ); + check!(5.801671039719115E-216); + + // https://github.com/ulfjack/ryu/commit/19e44d16d80236f5de25800f56d82606d1be00b9#commitcomment-30146483 + // 32-bit opt-size=0: 49 <= dist <= 49 + // 32-bit opt-size=1: 44 <= dist <= 49 + // 64-bit opt-size=0: 50 <= dist <= 50 + // 64-bit opt-size=1: 44 <= dist <= 50 + assert_eq!( + 3.196104012172126E-27, + ieee_parts_to_double(false, 934, 0x000FA7161A4D6E0C) + ); + check!(3.196104012172126E-27); +} + +#[test] +fn test_small_integers() { + check!(9.007199254740991E15); // 2^53-1 + check!(9.007199254740992E15); // 2^53 + + check!(1E0); + check!(1.2E1); + check!(1.23E2); + check!(1.234E3); + check!(1.2345E4); + check!(1.23456E5); + check!(1.234567E6); + check!(1.2345678E7); + check!(1.23456789E8); + check!(1.23456789E9); + check!(1.234567895E10); + check!(1.2345678901E11); + check!(1.23456789012E12); + check!(1.234567890123E13); + check!(1.2345678901234E14); + check!(1.23456789012345E15); + check!(1.234567890123456E16); + + // 10^i + check!(1E0); + check!(1E1); + check!(1E2); + check!(1E3); + check!(1E4); + check!(1E5); + check!(1E6); + check!(1E7); + check!(1E8); + check!(1E9); + check!(1E10); + check!(1E11); + check!(1E12); + check!(1E13); + check!(1E14); + check!(1E15); + + // 10^15 + 10^i + check!(1.000000000000001E15); + check!(1.00000000000001E15); + check!(1.0000000000001E15); + check!(1.000000000001E15); + check!(1.00000000001E15); + check!(1.0000000001E15); + check!(1.000000001E15); + check!(1.00000001E15); + check!(1.0000001E15); + check!(1.000001E15); + check!(1.00001E15); + check!(1.0001E15); + check!(1.001E15); + check!(1.01E15); + check!(1.1E15); + + // Largest power of 2 <= 10^(i+1) + check!(8E0); + check!(6.4E1); + check!(5.12E2); + check!(8.192E3); + check!(6.5536E4); + check!(5.24288E5); + check!(8.388608E6); + check!(6.7108864E7); + check!(5.36870912E8); + check!(8.589934592E9); + check!(6.8719476736E10); + check!(5.49755813888E11); + check!(8.796093022208E12); + check!(7.0368744177664E13); + check!(5.62949953421312E14); + check!(9.007199254740992E15); + + // 1000 * (Largest power of 2 <= 10^(i+1)) + check!(8E3); + check!(6.4E4); + check!(5.12E5); + check!(8.192E6); + check!(6.5536E7); + check!(5.24288E8); + check!(8.388608E9); + check!(6.7108864E10); + check!(5.36870912E11); + check!(8.589934592E12); + check!(6.8719476736E13); + check!(5.49755813888E14); + check!(8.796093022208E15); +} diff --git a/native/dragonbox/tests/crate/.gitignore b/native/dragonbox/tests/crate/.gitignore new file mode 100644 index 0000000000..e9e21997b1 --- /dev/null +++ b/native/dragonbox/tests/crate/.gitignore @@ -0,0 +1,2 @@ +/target/ +/Cargo.lock diff --git a/native/dragonbox/tests/crate/Cargo.toml b/native/dragonbox/tests/crate/Cargo.toml new file mode 100644 index 0000000000..f2d8106807 --- /dev/null +++ b/native/dragonbox/tests/crate/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "dragonbox-test" +version = "0.0.0" +authors = ["David Tolnay "] +edition = "2018" +publish = false + +[lib] +path = "test.rs" + +[dependencies] +dragonbox = { path = "../.." } + +[workspace] diff --git a/native/dragonbox/tests/crate/test.rs b/native/dragonbox/tests/crate/test.rs new file mode 100644 index 0000000000..6faeb03bcb --- /dev/null +++ b/native/dragonbox/tests/crate/test.rs @@ -0,0 +1,3 @@ +#![no_std] + +pub use dragonbox::*; diff --git a/native/dragonbox/tests/macros/mod.rs b/native/dragonbox/tests/macros/mod.rs new file mode 100644 index 0000000000..602cad51aa --- /dev/null +++ b/native/dragonbox/tests/macros/mod.rs @@ -0,0 +1,8 @@ +macro_rules! check { + ($f:tt) => { + assert_eq!(to_chars($f), stringify!($f)); + }; + (-$f:tt) => { + assert_eq!(to_chars(-$f), concat!("-", stringify!($f))); + }; +} From fef60961c659a0906cda245b0da941104f498c1f Mon Sep 17 00:00:00 2001 From: Leung Ming <165622843+leung-ming@users.noreply.github.com> Date: Mon, 23 Jun 2025 23:02:22 +0800 Subject: [PATCH 7/8] integrate dragonbox --- NOTICE.txt | 5 +- native/Cargo.lock | 5 + native/Cargo.toml | 4 +- native/dragonbox/Cargo.toml | 42 +- native/dragonbox/LICENSE-Apache2-LLVM | 193 --- native/dragonbox/LICENSE-Boost | 23 - native/dragonbox/README.md | 73 +- native/dragonbox/benches/bench.rs | 51 - native/dragonbox/src/lib.rs | 10 +- native/dragonbox/src/to_chars.rs | 2 +- native/dragonbox/tests/binary64_test.rs | 330 ---- native/dragonbox/tests/crate/.gitignore | 2 - native/dragonbox/tests/crate/Cargo.toml | 14 - native/dragonbox/tests/crate/test.rs | 3 - native/dragonbox/tests/macros/mod.rs | 8 - native/spark-expr/Cargo.toml | 1 + .../spark-expr/src/conversion_funcs/cast.rs | 14 +- native/spark-expr/src/conversion_funcs/mod.rs | 2 - .../src/conversion_funcs/schubfach.rs | 1515 ----------------- 19 files changed, 78 insertions(+), 2219 deletions(-) delete mode 100644 native/dragonbox/LICENSE-Apache2-LLVM delete mode 100644 native/dragonbox/LICENSE-Boost delete mode 100644 native/dragonbox/benches/bench.rs delete mode 100644 native/dragonbox/tests/binary64_test.rs delete mode 100644 native/dragonbox/tests/crate/.gitignore delete mode 100644 native/dragonbox/tests/crate/Cargo.toml delete mode 100644 native/dragonbox/tests/crate/test.rs delete mode 100644 native/dragonbox/tests/macros/mod.rs delete mode 100644 native/spark-expr/src/conversion_funcs/schubfach.rs diff --git a/NOTICE.txt b/NOTICE.txt index 8a77627012..83910b403f 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -10,4 +10,7 @@ Specifically: - Optimizer rule to replace SortMergeJoin with ShuffleHashJoin This product includes software developed at -DataFusion HDFS ObjectStore Contrib Package(https://github.com/datafusion-contrib/datafusion-objectstore-hdfs) \ No newline at end of file +DataFusion HDFS ObjectStore Contrib Package(https://github.com/datafusion-contrib/datafusion-objectstore-hdfs) + +This product includes software developed at +dragonbox (https://github.com/dtolnay/dragonbox) diff --git a/native/Cargo.lock b/native/Cargo.lock index 87b42e427f..d251b837c1 100644 --- a/native/Cargo.lock +++ b/native/Cargo.lock @@ -1410,6 +1410,10 @@ dependencies = [ "zstd", ] +[[package]] +name = "datafusion-comet-dragonbox" +version = "0.9.0" + [[package]] name = "datafusion-comet-objectstore-hdfs" version = "0.9.0" @@ -1441,6 +1445,7 @@ dependencies = [ "chrono-tz", "criterion", "datafusion", + "datafusion-comet-dragonbox", "futures", "num", "rand 0.9.1", diff --git a/native/Cargo.toml b/native/Cargo.toml index 86138ef09c..239bf39a36 100644 --- a/native/Cargo.toml +++ b/native/Cargo.toml @@ -16,8 +16,8 @@ # under the License. [workspace] -default-members = ["core", "spark-expr", "proto"] -members = ["core", "spark-expr", "proto", "hdfs"] +default-members = ["core", "spark-expr", "proto", "dragonbox"] +members = ["core", "spark-expr", "proto", "hdfs", "dragonbox"] resolver = "2" [workspace.package] diff --git a/native/dragonbox/Cargo.toml b/native/dragonbox/Cargo.toml index ec206b7b15..9df6a29aca 100644 --- a/native/dragonbox/Cargo.toml +++ b/native/dragonbox/Cargo.toml @@ -1,22 +1,32 @@ -[package] -name = "dragonbox" -version = "0.1.10" -authors = ["David Tolnay "] -categories = ["value-formatting", "no-std", "no-std::no-alloc"] -description = "Fast floating point to string conversion" -documentation = "https://docs.rs/dragonbox" -edition = "2018" -exclude = ["performance.png", "chart/**"] -keywords = ["float"] -license = "Apache-2.0 WITH LLVM-exception OR BSL-1.0" -repository = "https://github.com/dtolnay/dragonbox" -rust-version = "1.52" +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. -[dev-dependencies] -rand = "0.9" +[package] +name = "datafusion-comet-dragonbox" +description = "Comet dragonbox integration" +version = { workspace = true } +homepage = { workspace = true } +repository = { workspace = true } +authors = { workspace = true } +readme = { workspace = true } +license = { workspace = true } +edition = { workspace = true } [package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] rustdoc-args = [ "--generate-link-to-definition", "--extern-html-root-url=core=https://doc.rust-lang.org", diff --git a/native/dragonbox/LICENSE-Apache2-LLVM b/native/dragonbox/LICENSE-Apache2-LLVM deleted file mode 100644 index c8d7ed2907..0000000000 --- a/native/dragonbox/LICENSE-Apache2-LLVM +++ /dev/null @@ -1,193 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - ---- LLVM Exceptions to the Apache 2.0 License ---- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into an Object form of such source code, you -may redistribute such embedded portions in such Object form without complying -with the conditions of Sections 4(a), 4(b) and 4(d) of the License. - -In addition, if you combine or link compiled forms of this Software with -software that is licensed under the GPLv2 ("Combined Software") and if a -court of competent jurisdiction determines that the patent provision (Section -3), the indemnity provision (Section 9) or other Section of the License -conflicts with the conditions of the GPLv2, you may retroactively and -prospectively choose to deem waived or otherwise exclude such Section(s) of -the License, but only in their entirety and only with respect to the Combined -Software. diff --git a/native/dragonbox/LICENSE-Boost b/native/dragonbox/LICENSE-Boost deleted file mode 100644 index 36b7cd93cd..0000000000 --- a/native/dragonbox/LICENSE-Boost +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/native/dragonbox/README.md b/native/dragonbox/README.md index c0a8f88a02..f36913aa6e 100644 --- a/native/dragonbox/README.md +++ b/native/dragonbox/README.md @@ -1,48 +1,25 @@ -# Dragonbox - -[github](https://github.com/dtolnay/dragonbox) -[crates.io](https://crates.io/crates/dragonbox) -[docs.rs](https://docs.rs/dragonbox) -[build status](https://github.com/dtolnay/dragonbox/actions?query=branch%3Amaster) - -This crate contains a basic port of to -Rust for benchmarking purposes. - -Please see the upstream repo for an explanation of the approach and comparison -to the Ryū algorithm. - -
- -## Example - -```rust -fn main() { - let mut buffer = dragonbox::Buffer::new(); - let printed = buffer.format(1.234); - assert_eq!(printed, "1.234E0"); -} -``` - -
- -## Performance (lower is better) - -![performance](https://raw.githubusercontent.com/dtolnay/dragonbox/master/performance.png) - -
- -#### License - - -Licensed under either of
Apache License, Version -2.0 with LLVM Exceptions or Boost Software License -Version 1.0 at your option. - - -
- - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in this crate by you, as defined in the Apache-2.0 license, shall -be dual licensed as above, without any additional terms or conditions. - + + +# Apache DataFusion Comet: dragonbox integration + +This crate contains the dragonbox integration +and is intended to be used as part of the Apache DataFusion Comet project + +The binary floating-point to decimal floating-point conversion powered by [dragonbox](https://github.com/dtolnay/dragonbox). diff --git a/native/dragonbox/benches/bench.rs b/native/dragonbox/benches/bench.rs deleted file mode 100644 index cf94cf019f..0000000000 --- a/native/dragonbox/benches/bench.rs +++ /dev/null @@ -1,51 +0,0 @@ -#![feature(test)] -#![allow(clippy::approx_constant, clippy::unreadable_literal)] - -extern crate test; - -use std::io::Write; -use test::{black_box, Bencher}; - -macro_rules! benches { - ($($name:ident($value:expr),)*) => { - mod bench_dragonbox { - use super::*; - $( - #[bench] - fn $name(b: &mut Bencher) { - let mut buf = dragonbox::Buffer::new(); - - b.iter(move || { - let value = black_box($value); - let formatted = buf.format_finite(value); - black_box(formatted); - }); - } - )* - } - - mod bench_std_fmt { - use super::*; - $( - #[bench] - fn $name(b: &mut Bencher) { - let mut buf = Vec::with_capacity(20); - - b.iter(|| { - buf.clear(); - let value = black_box($value); - write!(&mut buf, "{}", value).unwrap(); - black_box(buf.as_slice()); - }); - } - )* - } - }; -} - -benches! { - bench_0_f64(0f64), - bench_short_f64(0.1234f64), - bench_e_f64(2.718281828459045f64), - bench_max_f64(f64::MAX), -} diff --git a/native/dragonbox/src/lib.rs b/native/dragonbox/src/lib.rs index 728153ee88..36dbbef3a9 100644 --- a/native/dragonbox/src/lib.rs +++ b/native/dragonbox/src/lib.rs @@ -216,9 +216,9 @@ fn divide_by_pow10(n: u6 } } -struct Decimal { - significand: u64, - exponent: i32, +pub struct Decimal { + pub significand: u64, + pub exponent: i32, } const KAPPA: u32 = 2; @@ -421,7 +421,7 @@ fn compute_round_up_for_shorter_interval_case( cache: &cache::EntryType, beta_minus_1: i32, ) -> CarrierUint { - ((cache.high() >> ((CARRIER_BITS - SIGNIFICAND_BITS - 2) as i32 - beta_minus_1)) + 1) / 2 + (cache.high() >> ((CARRIER_BITS - SIGNIFICAND_BITS - 2) as i32 - beta_minus_1)).div_ceil(2) } const MAX_POWER_OF_FACTOR_OF_5: i32 = log::floor_log5_pow2(SIGNIFICAND_BITS as i32 + 2); @@ -500,7 +500,7 @@ fn is_left_endpoint_integer_shorter_interval(exponent: i32) -> bool { && exponent <= CASE_SHORTER_INTERVAL_LEFT_ENDPOINT_UPPER_THRESHOLD } -fn to_decimal(x: f64) -> Decimal { +pub fn to_decimal(x: f64) -> Decimal { let br = x.to_bits(); let exponent_bits = extract_exponent_bits(br); let signed_significand_bits = remove_exponent_bits(br, exponent_bits); diff --git a/native/dragonbox/src/to_chars.rs b/native/dragonbox/src/to_chars.rs index 4a95af71fd..6fec24b318 100644 --- a/native/dragonbox/src/to_chars.rs +++ b/native/dragonbox/src/to_chars.rs @@ -115,7 +115,7 @@ fn fast_div 0 && MAX_PRECISION <= 32); debug_assert!(n < (1 << MAX_PRECISION)); - let left_end = ((1u32 << (MAX_PRECISION + ADDITIONAL_PRECISION)) + DIVISOR - 1) / DIVISOR; + let left_end = (1u32 << (MAX_PRECISION + ADDITIONAL_PRECISION)).div_ceil(DIVISOR); let right_end = ((1u32 << ADDITIONAL_PRECISION) * ((1 << MAX_PRECISION) + 1)) / DIVISOR; // Ensures sufficient precision. diff --git a/native/dragonbox/tests/binary64_test.rs b/native/dragonbox/tests/binary64_test.rs deleted file mode 100644 index 765135d1bc..0000000000 --- a/native/dragonbox/tests/binary64_test.rs +++ /dev/null @@ -1,330 +0,0 @@ -// Translated from C to Rust. The original C code can be found at -// https://github.com/ulfjack/ryu and carries the following license: -// -// Copyright 2018 Ulf Adams -// -// The contents of this file may be used under the terms of the Apache License, -// Version 2.0. -// -// (See accompanying file LICENSE-Apache or copy at -// http://www.apache.org/licenses/LICENSE-2.0) -// -// Alternatively, the contents of this file may be used under the terms of -// the Boost Software License, Version 1.0. -// (See accompanying file LICENSE-Boost or copy at -// https://www.boost.org/LICENSE_1_0.txt) -// -// Unless required by applicable law or agreed to in writing, this software -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. - -#![allow( - clippy::cast_lossless, - clippy::excessive_precision, - clippy::float_cmp, - clippy::int_plus_one, - clippy::non_ascii_literal, - clippy::unreadable_literal, - clippy::unseparated_literal_suffix -)] - -#[macro_use] -mod macros; - -use std::f64; - -fn to_chars(f: f64) -> String { - dragonbox::Buffer::new().format(f).to_owned() -} - -fn ieee_parts_to_double(sign: bool, ieee_exponent: u32, ieee_mantissa: u64) -> f64 { - assert!(ieee_exponent <= 2047); - assert!(ieee_mantissa <= (1u64 << 53) - 1); - f64::from_bits(((sign as u64) << 63) | ((ieee_exponent as u64) << 52) | ieee_mantissa) -} - -#[test] -fn test_dragonbox() { - check!(3E-1); - check!(1.234E15); - check!(2.71828E0); - check!(1.1E128); - check!(1.1E-64); - check!(2.718281828459045E0); - check!(5E-324); - check!(1.7976931348623157E308); -} - -#[test] -fn test_random() { - let n = if cfg!(miri) { 100 } else { 1000000 }; - let mut buffer = dragonbox::Buffer::new(); - for _ in 0..n { - let f: f64 = rand::random(); - assert_eq!(f, buffer.format_finite(f).parse().unwrap()); - } -} - -#[test] -#[cfg_attr(miri, ignore = "too slow for miri")] -fn test_non_finite() { - for i in 0u64..1 << 23 { - let f = f64::from_bits((((1 << 11) - 1) << 52) + (i << 29)); - assert!(!f.is_finite(), "f={}", f); - dragonbox::Buffer::new().format_finite(f); - } -} - -#[test] -fn test_basic() { - check!(0E0); - check!(-0E0); - check!(1E0); - check!(-1E0); - assert_eq!(to_chars(f64::NAN.copysign(1.0)), "NaN"); - assert_eq!(to_chars(f64::NAN.copysign(-1.0)), "NaN"); - assert_eq!(to_chars(f64::INFINITY), "inf"); - assert_eq!(to_chars(f64::NEG_INFINITY), "-inf"); -} - -#[test] -fn test_switch_to_subnormal() { - check!(2.2250738585072014E-308); -} - -#[test] -fn test_min_and_max() { - assert_eq!(f64::from_bits(0x7fefffffffffffff), 1.7976931348623157E308); - check!(1.7976931348623157E308); - assert_eq!(f64::from_bits(1), 5E-324); - check!(5E-324); -} - -#[test] -fn test_lots_of_trailing_zeros() { - check!(2.9802322387695313E-8); -} - -#[test] -fn test_regression() { - check!(-2.109808898695963E16); - check!(4.940656E-318); - check!(1.18575755E-316); - check!(2.989102097996E-312); - check!(9.0608011534336E15); - check!(4.708356024711512E18); - check!(9.409340012568248E18); - check!(1.2345678E0); -} - -#[test] -fn test_looks_like_pow5() { - // These numbers have a mantissa that is a multiple of the largest power of - // 5 that fits, and an exponent that causes the computation for q to result - // in 22, which is a corner case for Ryū. - assert_eq!(f64::from_bits(0x4830F0CF064DD592), 5.764607523034235E39); - check!(5.764607523034235E39); - assert_eq!(f64::from_bits(0x4840F0CF064DD592), 1.152921504606847E40); - check!(1.152921504606847E40); - assert_eq!(f64::from_bits(0x4850F0CF064DD592), 2.305843009213694E40); - check!(2.305843009213694E40); -} - -#[test] -fn test_output_length() { - check!(1E0); // already tested in Basic - check!(1.2E0); - check!(1.23E0); - check!(1.234E0); - check!(1.2345E0); - check!(1.23456E0); - check!(1.234567E0); - check!(1.2345678E0); // already tested in Regression - check!(1.23456789E0); - check!(1.234567895E0); // 1.234567890 would be trimmed - check!(1.2345678901E0); - check!(1.23456789012E0); - check!(1.234567890123E0); - check!(1.2345678901234E0); - check!(1.23456789012345E0); - check!(1.234567890123456E0); - check!(1.2345678901234567E0); - - // Test 32-bit chunking - check!(4.294967294E0); // 2^32 - 2 - check!(4.294967295E0); // 2^32 - 1 - check!(4.294967296E0); // 2^32 - check!(4.294967297E0); // 2^32 + 1 - check!(4.294967298E0); // 2^32 + 2 -} - -// Test min, max shift values in shiftright128 -#[test] -fn test_min_max_shift() { - let max_mantissa = (1u64 << 53) - 1; - - // 32-bit opt-size=0: 49 <= dist <= 50 - // 32-bit opt-size=1: 30 <= dist <= 50 - // 64-bit opt-size=0: 50 <= dist <= 50 - // 64-bit opt-size=1: 30 <= dist <= 50 - assert_eq!(1.7800590868057611E-307, ieee_parts_to_double(false, 4, 0)); - check!(1.7800590868057611E-307); - // 32-bit opt-size=0: 49 <= dist <= 49 - // 32-bit opt-size=1: 28 <= dist <= 49 - // 64-bit opt-size=0: 50 <= dist <= 50 - // 64-bit opt-size=1: 28 <= dist <= 50 - assert_eq!( - 2.8480945388892175E-306, - ieee_parts_to_double(false, 6, max_mantissa) - ); - check!(2.8480945388892175E-306); - // 32-bit opt-size=0: 52 <= dist <= 53 - // 32-bit opt-size=1: 2 <= dist <= 53 - // 64-bit opt-size=0: 53 <= dist <= 53 - // 64-bit opt-size=1: 2 <= dist <= 53 - assert_eq!(2.446494580089078E-296, ieee_parts_to_double(false, 41, 0)); - check!(2.446494580089078E-296); - // 32-bit opt-size=0: 52 <= dist <= 52 - // 32-bit opt-size=1: 2 <= dist <= 52 - // 64-bit opt-size=0: 53 <= dist <= 53 - // 64-bit opt-size=1: 2 <= dist <= 53 - assert_eq!( - 4.8929891601781557E-296, - ieee_parts_to_double(false, 40, max_mantissa) - ); - check!(4.8929891601781557E-296); - - // 32-bit opt-size=0: 57 <= dist <= 58 - // 32-bit opt-size=1: 57 <= dist <= 58 - // 64-bit opt-size=0: 58 <= dist <= 58 - // 64-bit opt-size=1: 58 <= dist <= 58 - assert_eq!(1.8014398509481984E16, ieee_parts_to_double(false, 1077, 0)); - check!(1.8014398509481984E16); - // 32-bit opt-size=0: 57 <= dist <= 57 - // 32-bit opt-size=1: 57 <= dist <= 57 - // 64-bit opt-size=0: 58 <= dist <= 58 - // 64-bit opt-size=1: 58 <= dist <= 58 - assert_eq!( - 3.6028797018963964E16, - ieee_parts_to_double(false, 1076, max_mantissa) - ); - check!(3.6028797018963964E16); - // 32-bit opt-size=0: 51 <= dist <= 52 - // 32-bit opt-size=1: 51 <= dist <= 59 - // 64-bit opt-size=0: 52 <= dist <= 52 - // 64-bit opt-size=1: 52 <= dist <= 59 - assert_eq!(2.9008355198595578E-216, ieee_parts_to_double(false, 307, 0)); - check!(2.9008355198595578E-216); - // 32-bit opt-size=0: 51 <= dist <= 51 - // 32-bit opt-size=1: 51 <= dist <= 59 - // 64-bit opt-size=0: 52 <= dist <= 52 - // 64-bit opt-size=1: 52 <= dist <= 59 - assert_eq!( - 5.801671039719115E-216, - ieee_parts_to_double(false, 306, max_mantissa) - ); - check!(5.801671039719115E-216); - - // https://github.com/ulfjack/ryu/commit/19e44d16d80236f5de25800f56d82606d1be00b9#commitcomment-30146483 - // 32-bit opt-size=0: 49 <= dist <= 49 - // 32-bit opt-size=1: 44 <= dist <= 49 - // 64-bit opt-size=0: 50 <= dist <= 50 - // 64-bit opt-size=1: 44 <= dist <= 50 - assert_eq!( - 3.196104012172126E-27, - ieee_parts_to_double(false, 934, 0x000FA7161A4D6E0C) - ); - check!(3.196104012172126E-27); -} - -#[test] -fn test_small_integers() { - check!(9.007199254740991E15); // 2^53-1 - check!(9.007199254740992E15); // 2^53 - - check!(1E0); - check!(1.2E1); - check!(1.23E2); - check!(1.234E3); - check!(1.2345E4); - check!(1.23456E5); - check!(1.234567E6); - check!(1.2345678E7); - check!(1.23456789E8); - check!(1.23456789E9); - check!(1.234567895E10); - check!(1.2345678901E11); - check!(1.23456789012E12); - check!(1.234567890123E13); - check!(1.2345678901234E14); - check!(1.23456789012345E15); - check!(1.234567890123456E16); - - // 10^i - check!(1E0); - check!(1E1); - check!(1E2); - check!(1E3); - check!(1E4); - check!(1E5); - check!(1E6); - check!(1E7); - check!(1E8); - check!(1E9); - check!(1E10); - check!(1E11); - check!(1E12); - check!(1E13); - check!(1E14); - check!(1E15); - - // 10^15 + 10^i - check!(1.000000000000001E15); - check!(1.00000000000001E15); - check!(1.0000000000001E15); - check!(1.000000000001E15); - check!(1.00000000001E15); - check!(1.0000000001E15); - check!(1.000000001E15); - check!(1.00000001E15); - check!(1.0000001E15); - check!(1.000001E15); - check!(1.00001E15); - check!(1.0001E15); - check!(1.001E15); - check!(1.01E15); - check!(1.1E15); - - // Largest power of 2 <= 10^(i+1) - check!(8E0); - check!(6.4E1); - check!(5.12E2); - check!(8.192E3); - check!(6.5536E4); - check!(5.24288E5); - check!(8.388608E6); - check!(6.7108864E7); - check!(5.36870912E8); - check!(8.589934592E9); - check!(6.8719476736E10); - check!(5.49755813888E11); - check!(8.796093022208E12); - check!(7.0368744177664E13); - check!(5.62949953421312E14); - check!(9.007199254740992E15); - - // 1000 * (Largest power of 2 <= 10^(i+1)) - check!(8E3); - check!(6.4E4); - check!(5.12E5); - check!(8.192E6); - check!(6.5536E7); - check!(5.24288E8); - check!(8.388608E9); - check!(6.7108864E10); - check!(5.36870912E11); - check!(8.589934592E12); - check!(6.8719476736E13); - check!(5.49755813888E14); - check!(8.796093022208E15); -} diff --git a/native/dragonbox/tests/crate/.gitignore b/native/dragonbox/tests/crate/.gitignore deleted file mode 100644 index e9e21997b1..0000000000 --- a/native/dragonbox/tests/crate/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target/ -/Cargo.lock diff --git a/native/dragonbox/tests/crate/Cargo.toml b/native/dragonbox/tests/crate/Cargo.toml deleted file mode 100644 index f2d8106807..0000000000 --- a/native/dragonbox/tests/crate/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "dragonbox-test" -version = "0.0.0" -authors = ["David Tolnay "] -edition = "2018" -publish = false - -[lib] -path = "test.rs" - -[dependencies] -dragonbox = { path = "../.." } - -[workspace] diff --git a/native/dragonbox/tests/crate/test.rs b/native/dragonbox/tests/crate/test.rs deleted file mode 100644 index 6faeb03bcb..0000000000 --- a/native/dragonbox/tests/crate/test.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![no_std] - -pub use dragonbox::*; diff --git a/native/dragonbox/tests/macros/mod.rs b/native/dragonbox/tests/macros/mod.rs deleted file mode 100644 index 602cad51aa..0000000000 --- a/native/dragonbox/tests/macros/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -macro_rules! check { - ($f:tt) => { - assert_eq!(to_chars($f), stringify!($f)); - }; - (-$f:tt) => { - assert_eq!(to_chars(-$f), concat!("-", stringify!($f))); - }; -} diff --git a/native/spark-expr/Cargo.toml b/native/spark-expr/Cargo.toml index f12b6d07d1..c1abdcfcc6 100644 --- a/native/spark-expr/Cargo.toml +++ b/native/spark-expr/Cargo.toml @@ -37,6 +37,7 @@ thiserror = { workspace = true } futures = { workspace = true } twox-hash = "2.0.0" rand = { workspace = true } +datafusion-comet-dragonbox = { path = "../dragonbox" } [dev-dependencies] arrow = {workspace = true} diff --git a/native/spark-expr/src/conversion_funcs/cast.rs b/native/spark-expr/src/conversion_funcs/cast.rs index b91f6c0e99..634d9a5e65 100644 --- a/native/spark-expr/src/conversion_funcs/cast.rs +++ b/native/spark-expr/src/conversion_funcs/cast.rs @@ -15,7 +15,6 @@ // specific language governing permissions and limitations // under the License. -use crate::conversion_funcs::schubfach; use crate::timezone; use crate::utils::array_with_timezone; use crate::{EvalMode, SparkError, SparkResult}; @@ -45,6 +44,7 @@ use datafusion::common::{ }; use datafusion::physical_expr::PhysicalExpr; use datafusion::physical_plan::ColumnarValue; +use datafusion_comet_dragonbox::to_decimal; use num::{ cast::AsPrimitive, integer::div_floor, traits::CheckedNeg, CheckedSub, Integer, Num, ToPrimitive, @@ -1285,13 +1285,17 @@ where cast_array.append_null(); } else { let input_value = input.value(i).as_(); - let value = schubfach::to_decimal(input_value); + let value = if input_value.is_finite() { + Some(to_decimal(input_value)) + } else { + None + }; match value { - Some((significand, exponent)) => { - let mut v = significand as i128; + Some(decimal) => { + let mut v = decimal.significand as i128; - let k = exponent + scale as i32; + let k = decimal.exponent + scale as i32; if k > 0 { v = v.saturating_mul(Saturating(10_i128).pow(k as u32).0); } else if k < 0 { diff --git a/native/spark-expr/src/conversion_funcs/mod.rs b/native/spark-expr/src/conversion_funcs/mod.rs index 1e440fba9c..f2c6f7ca36 100644 --- a/native/spark-expr/src/conversion_funcs/mod.rs +++ b/native/spark-expr/src/conversion_funcs/mod.rs @@ -16,5 +16,3 @@ // under the License. pub mod cast; - -mod schubfach; diff --git a/native/spark-expr/src/conversion_funcs/schubfach.rs b/native/spark-expr/src/conversion_funcs/schubfach.rs deleted file mode 100644 index 2fd2f6f12e..0000000000 --- a/native/spark-expr/src/conversion_funcs/schubfach.rs +++ /dev/null @@ -1,1515 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -// https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/math/DoubleToDecimal.java -// -// For full details about this code see the following references: -// -// [1] Giulietti, "The Schubfach way to render doubles", -// https://drive.google.com/file/d/1gp5xv4CAa78SVgCeWfGqqI4FfYYYuNFb -// -// [2] IEEE Computer Society, "IEEE Standard for Floating-Point Arithmetic" -// -// Divisions are avoided altogether for the benefit of those architectures -// that do not provide specific machine instructions or where they are slow. -// This is discussed in section 10 of [1]. - -// The precision in bits -const P: i32 = f64::MANTISSA_DIGITS as i32; -// Exponent width in bits -const W: i32 = size_of::() as i32 * 8 - 1 - (P - 1); -// Minimum value of the exponent: -(2^(W-1)) - P + 3 -const Q_MIN: i32 = (-1 << (W - 1)) - P + 3; -// Threshold to detect tiny values, as in section 8.2.1 of [1] -const C_TINY: i64 = 3; -// The minimum k, as in section 8 of [1] -const K_MIN: i32 = -324; -// Minimum value of the significand of a normal value: 2^(P-1) -const C_MIN: i64 = 1 << (P - 1); -// Mask to extract the biased exponent -const BQ_MASK: i32 = (1 << W) - 1; -// Mask to extract the fraction bits -const T_MASK: u64 = (1 << (P - 1)) - 1; -// Used in rop() -const MASK_63: i64 = 0x7fff_ffff_ffff_ffff; - -pub fn to_decimal(v: f64) -> Option<(i64, i32)> { - // For full details see references [2] and [1]. - // - // For finite v != 0, determine integers c and q such that - // |v| = c 2^q and - // Q_MIN <= q <= Q_MAX and - // either 2^(P-1) <= c < 2^P (normal) - // or 0 < c < 2^(P-1) and q = Q_MIN (subnormal) - - let bits = v.to_bits(); - let t = (bits & T_MASK) as i64; - let bq = (bits >> (P - 1)) as i32 & BQ_MASK; - if bq < BQ_MASK { - if bq != 0 { - // normal value. Here mq = -q - let mq = -Q_MIN + 1 - bq; - let c = C_MIN | t; - // The fast path discussed in section 8.3 of [1] - if 0 < mq && mq < P { - let f = c >> mq; - if f << mq == c { - return Some((f, 0)); - } - } - return Some(finite_positive_to_decimal(-mq, c, 0)); - } - if t != 0 { - // subnormal value - return Some(if t < C_TINY { - finite_positive_to_decimal(Q_MIN, 10 * t, -1) - } else { - finite_positive_to_decimal(Q_MIN, t, 0) - }); - } - return Some((0, 0)); - } - None -} - -fn finite_positive_to_decimal(q: i32, c: i64, dk: i32) -> (i64, i32) { - // The skeleton corresponds to figure 7 of [1]. - // The efficient computations are those summarized in figure 9. - // - // Here's a correspondence between variable names and names in [1], - // expressed as approximate LaTeX source code and informally. - // Other names are identical. - // cb: \bar{c} "c-bar" - // cbr: \bar{c}_r "c-bar-r" - // cbl: \bar{c}_l "c-bar-l" - // - // vb: \bar{v} "v-bar" - // vbr: \bar{v}_r "v-bar-r" - // vbl: \bar{v}_l "v-bar-l" - // - // rop: r_o' "r-o-prime" - - let out = c & 1; - let cb = c << 2; - let cbr = cb + 2; - // floor_log10_pow2(e) = floor(log_10(2^e)) - // floor_log10_three_quarters_pow2(e) = floor(log_10(3/4 2^e)) - // floor_log2_pow10(e) = floor(log_2(10^e)) - let (cbl, k) = if c != C_MIN || q == Q_MIN { - // regular spacing - (cb - 2, floor_log10_pow2(q)) - } else { - // irregular spacing - (cb - 1, floor_log10_three_quarters_pow2(q)) - }; - let h = q + floor_log2_pow10(-k) + 2; - - // g1 and g0 are as in section 9.8.3 of [1], so g = g1 2^63 + g0 - let g1 = g1(k); - let g0 = g0(k); - - let vb = rop(g1, g0, cb << h); - let vbl = rop(g1, g0, cbl << h); - let vbr = rop(g1, g0, cbr << h); - - let s = vb >> 2; - if s >= 100 { - // For n = 17, m = 1 the table in section 10 of [1] shows - // s' = floor(s / 10) = floor(s 115_292_150_460_684_698 / 2^60) - // = floor(s 115_292_150_460_684_698 2^4 / 2^64) - // - // sp10 = 10 s' - // tp10 = 10 t' - // upin iff u' = sp10 10^k in Rv - // wpin iff w' = tp10 10^k in Rv - // See section 9.3 of [1]. - - let sp10 = - 10 * ((s as i128 * (115_292_150_460_684_698_i64 << 4) as i128) as u128 >> 64) as i64; - let tp10 = sp10 + 10; - let upin = vbl + out <= sp10 << 2; - let wpin = (tp10 << 2) + out <= vbr; - if upin != wpin { - return (if upin { sp10 } else { tp10 }, k); - } - } - - // 10 <= s < 100 or s >= 100 and u', w' not in Rv - // uin iff u = s 10^k in Rv - // win iff w = t 10^k in Rv - // See section 9.3 of [1]. - let t = s + 1; - let uin = vbl + out <= s << 2; - let win = (t << 2) + out <= vbr; - if uin != win { - return (if uin { s } else { t }, k + dk); - } - - // Both u and w lie in Rv: determine the one closest to v. - // See section 9.3 of [1]. - let cmp = vb - ((s + t) << 1); - ( - if cmp < 0 || cmp == 0 && (s & 1) == 0 { - s - } else { - t - }, - k + dk, - ) -} - -/// Computes rop(cp g 2^-127), where g = g1 2^63 + g0 -/// See section 9.9 and figure 8 of [1]. -fn rop(g1: i64, g0: i64, cp: i64) -> i64 { - let x1 = ((g0 as i128 * cp as i128) as u128 >> 64) as i64; - let y0 = g1.wrapping_mul(cp); - let y1 = ((g1 as i128 * cp as i128) as u128 >> 64) as i64; - let z = ((y0 as u64 >> 1) as i64).wrapping_add(x1); - let vbp = y1.wrapping_add((z as u64 >> 63) as i64); - vbp | (((z & MASK_63).wrapping_add(MASK_63)) as u64 >> 63) as i64 -} - -// math utils - -// C_10 = floor(log_10(2) * 2^Q_10), A_10 = floor(log_10(3/4) * 2^Q_10) -const Q_10: i32 = 41; -const C_10: i64 = 661_971_961_083; -const A_10: i64 = -274_743_187_321; - -// C_2 = floor(log_2(10) * 2^Q_2) -const Q_2: i32 = 38; -const C_2: i64 = 913_124_641_741; - -/// Returns the unique integer k such that 10^k <= 2^e < 10^(k+1). -/// -/// The result is correct when |e| <= 6_432_162. -/// Otherwise the result is undefined. -/// -/// # Arguments -/// -/// * `e` - The exponent of 2, which should meet |e| <= 6_432_162 for safe results. -/// -/// # Returns -/// -/// * `i32` - floor(log_10(2^e)). -fn floor_log10_pow2(e: i32) -> i32 { - ((e as i64 * C_10) >> Q_10) as i32 -} - -/// Returns the unique integer k such that 10^k <= 3/4 * 2^e < 10^(k+1). -/// -/// The result is correct when -3_606_689 < e <= 3_150_619. -/// Otherwise the result is undefined. -/// -/// # Arguments -/// -/// * `e` - The exponent of 2, which should meet -3_606_689 <= e < 3_150_619 for safe results. -/// -/// # Returns -/// -/// * `i32` - floor(log_10(3/4 2^e)) -fn floor_log10_three_quarters_pow2(e: i32) -> i32 { - ((e as i64 * C_10 + A_10) >> Q_10) as i32 -} - -/// Returns the unique integer k such that 2^k <= 10^e < 2^(k+1). -/// -/// The result is correct when |e| <= 1_838_394. -/// Otherwise the result is undefined. -/// -/// # Arguments -/// -/// * `e` - The exponent of 10, which should meet |e| < 1_838_394 for safe results. -/// -/// # Returns -/// -/// * `i32` - floor(log_2(10^e)) -fn floor_log2_pow10(e: i32) -> i32 { - ((e as i64 * C_2) >> Q_2) as i32 -} - -/// Let 10^-k = B 2^r, for the unique pair of integer r and real B meeting 2^125 <= B < 2^126. -/// Further, let g = floor(B) + 1. Split g into the higher 63 bits g1 and the lower 63 bits g0. -/// Thus, g1 = floor(g * 2^-63) and g0 = g - g1 * 2^63. -/// -/// This method returns g1 while `g0(i32)` returns g0. -/// -/// If needed, the exponent r can be computed as r = `floor_log2_pow10(-k)` - 125. -/// -/// # Arguments -/// -/// * `k` - The exponent of 10, which must meet `K_MIN` <= k <= `K_MAX`. -/// -/// # Returns -/// -/// * `i64` - g1 as described above. -fn g1(k: i32) -> i64 { - G[((k - K_MIN) << 1) as usize] -} - -/// Returns g0 as described in `g1(i32)` -/// -/// # Arguments -/// -/// * `k` - The exponent of 10, which must meet `K_MIN` <= k <= `K_MAX`. -/// -/// # Returns -/// -/// * `i64` - g0 as described in `g1(k)` -fn g0(k: i32) -> i64 { - G[((k - K_MIN) << 1 | 1) as usize] -} - -// The precomputed values for g1(i32) and g0(i32). -// The first entry must be for an exponent of K_MIN or less. -// The last entry must be for an exponent of K_MAX or more. -const G: [i64; 1234] = [ - 0x4F0C_EDC9_5A71_8DD4, - 0x5B01_E8B0_9AA0_D1B5, // -324 - 0x7E7B_160E_F71C_1621, - 0x119C_A780_F767_B5EE, // -323 - 0x652F_44D8_C5B0_11B4, - 0x0E16_EC67_2C52_F7F2, // -322 - 0x50F2_9D7A_37C0_0E29, - 0x5812_56B8_F042_5FF5, // -321 - 0x40C2_1794_F966_71BA, - 0x79A8_4560_C035_1991, // -320 - 0x679C_F287_F570_B5F7, - 0x75DA_089A_CD21_C281, // -319 - 0x52E3_F539_9126_F7F9, - 0x44AE_6D48_A41B_0201, // -318 - 0x424F_F761_40EB_F994, - 0x36F1_F106_E9AF_34CD, // -317 - 0x6A19_8BCE_CE46_5C20, - 0x57E9_81A4_A918_547B, // -316 - 0x54E1_3CA5_71D1_E34D, - 0x2CBA_CE1D_5413_76C9, // -315 - 0x43E7_63B7_8E41_82A4, - 0x23C8_A4E4_4342_C56E, // -314 - 0x6CA5_6C58_E39C_043A, - 0x060D_D4A0_6B9E_08B0, // -313 - 0x56EA_BD13_E949_9CFB, - 0x1E71_76E6_BC7E_6D59, // -312 - 0x4588_9743_2107_B0C8, - 0x7EC1_2BEB_C9FE_BDE1, // -311 - 0x6F40_F205_01A5_E7A7, - 0x7E01_DFDF_A997_9635, // -310 - 0x5900_C19D_9AEB_1FB9, - 0x4B34_B319_5479_44F7, // -309 - 0x4733_CE17_AF22_7FC7, - 0x55C3_C27A_A9FA_9D93, // -308 - 0x71EC_7CF2_B1D0_CC72, - 0x5606_03F7_765D_C8EA, // -307 - 0x5B23_9728_8E40_A38E, - 0x7804_CFF9_2B7E_3A55, // -306 - 0x48E9_45BA_0B66_E93F, - 0x1337_0CC7_55FE_9511, // -305 - 0x74A8_6F90_123E_41FE, - 0x51F1_AE0B_BCCA_881B, // -304 - 0x5D53_8C73_41CB_67FE, - 0x74C1_5809_63D5_39AF, // -303 - 0x4AA9_3D29_016F_8665, - 0x43CD_E007_8310_FAF3, // -302 - 0x7775_2EA8_024C_0A3C, - 0x0616_333F_381B_2B1E, // -301 - 0x5F90_F220_01D6_6E96, - 0x3811_C298_F9AF_55B1, // -300 - 0x4C73_F4E6_67DE_BEDE, - 0x600E_3547_2E25_DE28, // -299 - 0x7A53_2170_A631_3164, - 0x3349_EED8_49D6_303F, // -298 - 0x61DC_1AC0_84F4_2783, - 0x42A1_8BE0_3B11_C033, // -297 - 0x4E49_AF00_6A5C_EC69, - 0x1BB4_6FE6_95A7_CCF5, // -296 - 0x7D42_B19A_43C7_E0A8, - 0x2C53_E63D_BC3F_AE55, // -295 - 0x6435_5AE1_CFD3_1A20, - 0x2376_51CA_FCFF_BEAA, // -294 - 0x502A_AF1B_0CA8_E1B3, - 0x35F8_416F_30CC_9888, // -293 - 0x4022_25AF_3D53_E7C2, - 0x5E60_3458_F3D6_E06D, // -292 - 0x669D_0918_621F_D937, - 0x4A33_86F4_B957_CD7B, // -291 - 0x5217_3A79_E819_7A92, - 0x6E8F_9F2A_2DDF_D796, // -290 - 0x41AC_2EC7_ECE1_2EDB, - 0x720C_7F54_F17F_DFAB, // -289 - 0x6913_7E0C_AE35_17C6, - 0x1CE0_CBBB_1BFF_CC45, // -288 - 0x540F_980A_24F7_4638, - 0x171A_3C95_AFFF_D69E, // -287 - 0x433F_ACD4_EA5F_6B60, - 0x127B_63AA_F333_1218, // -286 - 0x6B99_1487_DD65_7899, - 0x6A5F_05DE_51EB_5026, // -285 - 0x5614_106C_B11D_FA14, - 0x5518_D17E_A7EF_7352, // -284 - 0x44DC_D9F0_8DB1_94DD, - 0x2A7A_4132_1FF2_C2A8, // -283 - 0x6E2E_2980_E2B5_BAFB, - 0x5D90_6850_331E_043F, // -282 - 0x5824_EE00_B55E_2F2F, - 0x6473_86A6_8F4B_3699, // -281 - 0x4683_F19A_2AB1_BF59, - 0x36C2_D21E_D908_F87B, // -280 - 0x70D3_1C29_DDE9_3228, - 0x579E_1CFE_280E_5A5D, // -279 - 0x5A42_7CEE_4B20_F4ED, - 0x2C7E_7D98_200B_7B7E, // -278 - 0x4835_30BE_A280_C3F1, - 0x09FE_CAE0_19A2_C932, // -277 - 0x7388_4DFD_D0CE_064E, - 0x4331_4499_C29E_0EB6, // -276 - 0x5C6D_0B31_73D8_050B, - 0x4F5A_9D47_CEE4_D891, // -275 - 0x49F0_D5C1_2979_9DA2, - 0x72AE_E439_7250_AD41, // -274 - 0x764E_22CE_A8C2_95D1, - 0x377E_39F5_83B4_4868, // -273 - 0x5EA4_E8A5_53CE_DE41, - 0x12CB_6191_3629_D387, // -272 - 0x4BB7_2084_430B_E500, - 0x756F_8140_F821_7605, // -271 - 0x7925_00D3_9E79_6E67, - 0x6F18_CECE_59CF_233C, // -270 - 0x60EA_670F_B1FA_BEB9, - 0x3F47_0BD8_47D8_E8FD, // -269 - 0x4D88_5272_F4C8_9894, - 0x329F_3CAD_0647_20CA, // -268 - 0x7C0D_50B7_EE0D_C0ED, - 0x3765_2DE1_A3A5_0143, // -267 - 0x633D_DA2C_BE71_6724, - 0x2C50_F181_4FB7_3436, // -266 - 0x4F64_AE8A_31F4_5283, - 0x3D0D_8E01_0C92_902B, // -265 - 0x7F07_7DA9_E986_EA6B, - 0x7B48_E334_E0EA_8045, // -264 - 0x659F_97BB_2138_BB89, - 0x4907_1C2A_4D88_669D, // -263 - 0x514C_7962_80FA_2FA1, - 0x20D2_7CEE_A46D_1EE4, // -262 - 0x4109_FAB5_33FB_594D, - 0x670E_CA58_838A_7F1D, // -261 - 0x680F_F788_532B_C216, - 0x0B4A_DD5A_6C10_CB62, // -260 - 0x533F_F939_DC23_01AB, - 0x22A2_4AAE_BCDA_3C4E, // -259 - 0x4299_942E_49B5_9AEF, - 0x354E_A225_63E1_C9D8, // -258 - 0x6A8F_537D_42BC_2B18, - 0x554A_9D08_9FCF_A95A, // -257 - 0x553F_75FD_CEFC_EF46, - 0x776E_E406_E63F_BAAE, // -256 - 0x4432_C4CB_0BFD_8C38, - 0x5F8B_E99F_1E99_6225, // -255 - 0x6D1E_07AB_4662_79F4, - 0x3279_75CB_6428_9D08, // -254 - 0x574B_3955_D1E8_6190, - 0x2861_2B09_1CED_4A6D, // -253 - 0x45D5_C777_DB20_4E0D, - 0x06B4_226D_B0BD_D524, // -252 - 0x6FBC_7259_5E9A_167B, - 0x2453_6A49_1AC9_5506, // -251 - 0x5963_8EAD_E548_11FC, - 0x1D0F_883A_7BD4_4405, // -250 - 0x4782_D88B_1DD3_4196, - 0x4A72_D361_FCA9_D004, // -249 - 0x726A_F411_C952_028A, - 0x43EA_EBCF_FAA9_4CD3, // -248 - 0x5B88_C341_6DDB_353B, - 0x4FEF_230C_C887_70A9, // -247 - 0x493A_35CD_F17C_2A96, - 0x0CBF_4F3D_6D39_26EE, // -246 - 0x7529_EFAF_E8C6_AA89, - 0x6132_1862_485B_717C, // -245 - 0x5DBB_2626_53D2_2207, - 0x675B_46B5_06AF_8DFD, // -244 - 0x4AFC_1E85_0FDB_4E6C, - 0x52AF_6BC4_0559_3E64, // -243 - 0x77F9_CA6E_7FC5_4A47, - 0x377F_12D3_3BC1_FD6D, // -242 - 0x5FFB_0858_6637_6E9F, - 0x45FF_4242_9634_CABD, // -241 - 0x4CC8_D379_EB5F_8BB2, - 0x6B32_9B68_782A_3BCB, // -240 - 0x7ADA_EBF6_4565_AC51, - 0x2B84_2BDA_59DD_2C77, // -239 - 0x6248_BCC5_0451_56A7, - 0x3C69_BCAE_AE4A_89F9, // -238 - 0x4EA0_9704_0374_4552, - 0x6387_CA25_583B_A194, // -237 - 0x7DCD_BE6C_D253_A21E, - 0x05A6_103B_C05F_68ED, // -236 - 0x64A4_9857_0EA9_4E7E, - 0x37B8_0CFC_99E5_ED8A, // -235 - 0x5083_AD12_7221_0B98, - 0x2C93_3D96_E184_BE08, // -234 - 0x4069_5741_F4E7_3C79, - 0x7075_CADF_1AD0_9807, // -233 - 0x670E_F203_2171_FA5C, - 0x4D89_4498_2AE7_59A4, // -232 - 0x5272_5B35_B45B_2EB0, - 0x3E07_6A13_5585_E150, // -231 - 0x41F5_15C4_9048_F226, - 0x64D2_BB42_AAD1_810D, // -230 - 0x6988_22D4_1A0E_503E, - 0x07B7_9204_4482_6815, // -229 - 0x546C_E8A9_AE71_D9CB, - 0x1FC6_0E69_D068_5344, // -228 - 0x438A_53BA_F1F4_AE3C, - 0x196B_3EBB_0D20_429D, // -227 - 0x6C10_85F7_E987_7D2D, - 0x0F11_FDF8_1500_6A94, // -226 - 0x5673_9E5F_EE05_FDBD, - 0x58DB_3193_4400_5543, // -225 - 0x4529_4B7F_F19E_6497, - 0x60AF_5ADC_3666_AA9C, // -224 - 0x6EA8_78CC_B5CA_3A8C, - 0x344B_C493_8A3D_DDC7, // -223 - 0x5886_C70A_2B08_2ED6, - 0x5D09_6A0F_A1CB_17D2, // -222 - 0x46D2_38D4_EF39_BF12, - 0x173A_BB3F_B4A2_7975, // -221 - 0x7150_5AEE_4B8F_981D, - 0x0B91_2B99_2103_F588, // -220 - 0x5AA6_AF25_093F_ACE4, - 0x0940_EFAD_B403_2AD3, // -219 - 0x4885_58EA_6DCC_8A50, - 0x0767_2624_9002_88A9, // -218 - 0x7408_8E43_E2E0_DD4C, - 0x723E_A36D_B337_410E, // -217 - 0x5CD3_A503_1BE7_1770, - 0x5B65_4F8A_F5C5_CDA5, // -216 - 0x4A42_EA68_E31F_45F3, - 0x62B7_72D5_916B_0AEB, // -215 - 0x76D1_770E_3832_0986, - 0x0458_B7BC_1BDE_77DD, // -214 - 0x5F0D_F8D8_2CF4_D46B, - 0x1D13_C630_164B_9318, // -213 - 0x4C0B_2D79_BD90_A9EF, - 0x30DC_9E8C_DEA2_DC13, // -212 - 0x79AB_7BF5_FC1A_A97F, - 0x0160_FDAE_3104_9351, // -211 - 0x6155_FCC4_C9AE_EDFF, - 0x1AB3_FE24_F403_A90E, // -210 - 0x4DDE_63D0_A158_BE65, - 0x6229_981D_9002_EDA5, // -209 - 0x7C97_061A_9BC1_30A2, - 0x69DC_2695_B337_E2A1, // -208 - 0x63AC_04E2_1634_26E8, - 0x54B0_1EDE_28F9_821B, // -207 - 0x4FBC_D0B4_DE90_1F20, - 0x43C0_18B1_BA61_34E2, // -206 - 0x7F94_8121_6419_CB67, - 0x1F99_C11C_5D68_549D, // -205 - 0x6610_674D_E9AE_3C52, - 0x4C7B_00E3_7DED_107E, // -204 - 0x51A6_B90B_2158_3042, - 0x09FC_00B5_FE57_4065, // -203 - 0x4152_2DA2_8113_59CE, - 0x3B30_0091_9845_CD1D, // -202 - 0x6883_7C37_34EB_C2E3, - 0x784C_CDB5_C06F_AE95, // -201 - 0x539C_635F_5D89_68B6, - 0x2D0A_3E2B_0059_5877, // -200 - 0x42E3_82B2_B13A_BA2B, - 0x3DA1_CB55_99E1_1393, // -199 - 0x6B05_9DEA_B52A_C378, - 0x629C_7888_F634_EC1E, // -198 - 0x559E_17EE_F755_692D, - 0x3549_FA07_2B5D_89B1, // -197 - 0x447E_798B_F911_20F1, - 0x1107_FB38_EF7E_07C1, // -196 - 0x6D97_28DF_F4E8_34B5, - 0x01A6_5EC1_7F30_0C68, // -195 - 0x57AC_20B3_2A53_5D5D, - 0x4E1E_B234_65C0_09ED, // -194 - 0x4623_4D5C_21DC_4AB1, - 0x24E5_5B5D_1E33_3B24, // -193 - 0x7038_7BC6_9C93_AAB5, - 0x216E_F894_FD1E_C506, // -192 - 0x59C6_C96B_B076_222A, - 0x4DF2_6077_30E5_6A6C, // -191 - 0x47D2_3ABC_8D2B_4E88, - 0x3E5B_805F_5A51_21F0, // -190 - 0x72E9_F794_1512_1740, - 0x63C5_9A32_2A1B_697F, // -189 - 0x5BEE_5FA9_AA74_DF67, - 0x0304_7B5B_54E2_BACC, // -188 - 0x498B_7FBA_EEC3_E5EC, - 0x0269_FC49_10B5_623D, // -187 - 0x75AB_FF91_7E06_3CAC, - 0x6A43_2D41_B455_69FB, // -186 - 0x5E23_32DA_CB38_308A, - 0x21CF_5767_C377_87FC, // -185 - 0x4B4F_5BE2_3C2C_F3A1, - 0x67D9_12B9_692C_6CCA, // -184 - 0x787E_F969_F9E1_85CF, - 0x595B_5128_A847_1476, // -183 - 0x6065_9454_C7E7_9E3F, - 0x6115_DA86_ED05_A9F8, // -182 - 0x4D1E_1043_D31F_B1CC, - 0x4DAB_1538_BD9E_2193, // -181 - 0x7B63_4D39_51CC_4FAD, - 0x62AB_5527_95C9_CF52, // -180 - 0x62B5_D761_0E3D_0C8B, - 0x0222_AA86_116E_3F75, // -179 - 0x4EF7_DF80_D830_D6D5, - 0x4E82_2204_DABE_992A, // -178 - 0x7E59_659A_F381_57BC, - 0x1736_9CD4_9130_F510, // -177 - 0x6514_5148_C2CD_DFC9, - 0x5F5E_E3DD_40F3_F740, // -176 - 0x50DD_0DD3_CF0B_196E, - 0x1918_B64A_9A5C_C5CD, // -175 - 0x40B0_D7DC_A5A2_7ABE, - 0x4746_F83B_AEB0_9E3E, // -174 - 0x6781_5961_0903_F797, - 0x253E_59F9_1780_FD2F, // -173 - 0x52CD_E11A_6D9C_C612, - 0x50FE_AE60_DF9A_6426, // -172 - 0x423E_4DAE_BE17_04DB, - 0x5A65_584D_7FAE_B685, // -171 - 0x69FD_4917_968B_3AF9, - 0x10A2_26E2_65E4_573B, // -170 - 0x54CA_A0DF_ABA2_9594, - 0x0D4E_8581_EB1D_1295, // -169 - 0x43D5_4D7F_BC82_1143, - 0x243E_D134_BC17_4211, // -168 - 0x6C88_7BFF_9403_4ED2, - 0x06CA_E854_6025_3682, // -167 - 0x56D3_9666_1002_A574, - 0x6BD5_86A9_E684_2B9B, // -166 - 0x4576_11EB_4002_1DF7, - 0x0977_9EEE_5203_5616, // -165 - 0x6F23_4FDE_CCD0_2FF1, - 0x5BF2_97E3_B66B_BCEF, // -164 - 0x58E9_0CB2_3D73_598E, - 0x165B_ACB6_2B89_63F3, // -163 - 0x4720_D6F4_FDF5_E13E, - 0x4516_23C4_EFA1_1CC2, // -162 - 0x71CE_24BB_2FEF_CECA, - 0x3B56_9FA1_7F68_2E03, // -161 - 0x5B0B_5095_BFF3_0BD5, - 0x15DE_E61A_CC53_5803, // -160 - 0x48D5_DA11_665C_0977, - 0x2B18_B815_7042_ACCF, // -159 - 0x7489_5CE8_A3C6_758B, - 0x5E8D_F355_806A_AE18, // -158 - 0x5D3A_B0BA_1C9E_C46F, - 0x653E_5C44_66BB_BE7A, // -157 - 0x4A95_5A2E_7D4B_D059, - 0x3765_169D_1EFC_9861, // -156 - 0x7755_5D17_2EDF_B3C2, - 0x256E_8A94_FE60_F3CF, // -155 - 0x5F77_7DAC_257F_C301, - 0x6ABE_D543_FEB3_F63F, // -154 - 0x4C5F_97BC_EACC_9C01, - 0x3BCB_DDCF_FEF6_5E99, // -153 - 0x7A32_8C61_77AD_C668, - 0x5FAC_9619_97F0_975B, // -152 - 0x61C2_09E7_92F1_6B86, - 0x7FBD_44E1_465A_12AF, // -151 - 0x4E34_D4B9_425A_BC6B, - 0x7FCA_9D81_0514_DBBF, // -150 - 0x7D21_545B_9D5D_FA46, - 0x32DD_C8CE_6E87_C5FF, // -149 - 0x641A_A9E2_E44B_2E9E, - 0x5BE4_A0A5_2539_6B32, // -148 - 0x5015_54B5_836F_587E, - 0x7CB6_E6EA_842D_EF5C, // -147 - 0x4011_1091_35F2_AD32, - 0x3092_5255_368B_25E3, // -146 - 0x6681_B41B_8984_4850, - 0x4DB6_EA21_F0DE_A304, // -145 - 0x5201_5CE2_D469_D373, - 0x57C5_881B_2718_826A, // -144 - 0x419A_B0B5_76BB_0F8F, - 0x5FD1_39AF_527A_01EF, // -143 - 0x68F7_8122_5791_B27F, - 0x4C81_F5E5_50C3_364A, // -142 - 0x53F9_341B_7941_5B99, - 0x239B_2B1D_DA35_C508, // -141 - 0x432D_C349_2DCD_E2E1, - 0x02E2_88E4_AE91_6A6D, // -140 - 0x6B7C_6BA8_4949_6B01, - 0x516A_74A1_174F_10AE, // -139 - 0x55FD_22ED_076D_EF34, - 0x4121_F6E7_45D8_DA25, // -138 - 0x44CA_8257_3924_BF5D, - 0x1A81_9252_9E47_14EB, // -137 - 0x6E10_D08B_8EA1_322E, - 0x5D9C_1D50_FD3E_87DD, // -136 - 0x580D_73A2_D880_F4F2, - 0x17B0_1773_FDCB_9FE4, // -135 - 0x4671_294F_139A_5D8E, - 0x4626_7929_97D6_1984, // -134 - 0x70B5_0EE4_EC2A_2F4A, - 0x3D0A_5B75_BFBC_F59F, // -133 - 0x5A2A_7250_BCEE_8C3B, - 0x4A6E_AF91_6630_C47F, // -132 - 0x4821_F50D_63F2_09C9, - 0x21F2_260D_EB5A_36CC, // -131 - 0x7369_8815_6CB6_760E, - 0x6983_7016_455D_247A, // -130 - 0x5C54_6CDD_F091_F80B, - 0x6E02_C011_D117_5062, // -129 - 0x49DD_23E4_C074_C66F, - 0x719B_CCDB_0DAC_404E, // -128 - 0x762E_9FD4_6721_3D7F, - 0x68F9_47C4_E2AD_33B0, // -127 - 0x5E8B_B310_5280_FDFF, - 0x6D94_396A_4EF0_F627, // -126 - 0x4BA2_F5A6_A867_3199, - 0x3E10_2DEE_A58D_91B9, // -125 - 0x7904_BC3D_DA3E_B5C2, - 0x3019_E317_6F48_E927, // -124 - 0x60D0_9697_E1CB_C49B, - 0x4014_B5AC_5907_20EC, // -123 - 0x4D73_ABAC_B4A3_03AF, - 0x4CDD_5E23_7A6C_1A57, // -122 - 0x7BEC_45E1_2104_D2B2, - 0x47C8_969F_2A46_908A, // -121 - 0x6323_6B1A_80D0_A88E, - 0x6CA0_787F_5505_406F, // -120 - 0x4F4F_88E2_00A6_ED3F, - 0x0A19_F9FF_7737_66BF, // -119 - 0x7EE5_A7D0_010B_1531, - 0x5CF6_5CCB_F1F2_3DFE, // -118 - 0x6584_8640_00D5_AA8E, - 0x172B_7D6F_F4C1_CB32, // -117 - 0x5136_D1CC_CD77_BBA4, - 0x78EF_978C_C3CE_3C28, // -116 - 0x40F8_A7D7_0AC6_2FB7, - 0x13F2_DFA3_CFD8_3020, // -115 - 0x67F4_3FBE_77A3_7F8B, - 0x3984_9906_1959_E699, // -114 - 0x5329_CC98_5FB5_FFA2, - 0x6136_E0D1_ADE1_8548, // -113 - 0x4287_D6E0_4C91_994F, - 0x00F8_B3DA_F181_376D, // -112 - 0x6A72_F166_E0E8_F54B, - 0x1B27_862B_1C01_F247, // -111 - 0x5528_C11F_1A53_F76F, - 0x2F52_D1BC_1667_F506, // -110 - 0x4420_9A7F_4843_2C59, - 0x0C42_4163_451F_F738, // -109 - 0x6D00_F732_0D38_46F4, - 0x7A03_9BD2_0833_2526, // -108 - 0x5733_F8F4_D760_38C3, - 0x7B36_1641_A028_EA85, // -107 - 0x45C3_2D90_AC4C_FA36, - 0x2F5E_7834_8020_BB9E, // -106 - 0x6F9E_AF4D_E07B_29F0, - 0x4BCA_59ED_99CD_F8FC, // -105 - 0x594B_BF71_8062_87F3, - 0x563B_7B24_7B0B_2D96, // -104 - 0x476F_CC5A_CD1B_9FF6, - 0x11C9_2F50_626F_57AC, // -103 - 0x724C_7A2A_E1C5_CCBD, - 0x02DB_7EE7_03E5_5912, // -102 - 0x5B70_61BB_E7D1_7097, - 0x1BE2_CBEC_031D_E0DC, // -101 - 0x4926_B496_530D_F3AC, - 0x164F_0989_9C17_E716, // -100 - 0x750A_BA8A_1E7C_B913, - 0x3D4B_4275_C68C_A4F0, // -99 - 0x5DA2_2ED4_E530_940F, - 0x4AA2_9B91_6BA3_B726, // -98 - 0x4AE8_2577_1DC0_7672, - 0x6EE8_7C74_561C_9285, // -97 - 0x77D9_D58B_62CD_8A51, - 0x3173_FA53_BCFA_8408, // -96 - 0x5FE1_77A2_B571_3B74, - 0x278F_FB76_30C8_69A0, // -95 - 0x4CB4_5FB5_5DF4_2F90, - 0x1FA6_62C4_F3D3_87B3, // -94 - 0x7ABA_32BB_C986_B280, - 0x32A3_D13B_1FB8_D91F, // -93 - 0x622E_8EFC_A138_8ECD, - 0x0EE9_742F_4C93_E0E6, // -92 - 0x4E8B_A596_E760_723D, - 0x58BA_C359_0A0F_E71E, // -91 - 0x7DAC_3C24_A567_1D2F, - 0x412A_D228_1019_71C9, // -90 - 0x6489_C9B6_EAB8_E426, - 0x00EF_0E86_7347_8E3B, // -89 - 0x506E_3AF8_BBC7_1CEB, - 0x1A58_D86B_8F6C_71C9, // -88 - 0x4058_2F2D_6305_B0BC, - 0x1513_E056_0C56_C16E, // -87 - 0x66F3_7EAF_04D5_E793, - 0x3B53_0089_AD57_9BE2, // -86 - 0x525C_6558_D0AB_1FA9, - 0x15DC_006E_2446_164F, // -85 - 0x41E3_8447_0D55_B2ED, - 0x5E49_99F1_B69E_783F, // -84 - 0x696C_06D8_1555_EB15, - 0x7D42_8FE9_2430_C065, // -83 - 0x5456_6BE0_1111_88DE, - 0x3102_0CBA_835A_3384, // -82 - 0x4378_564C_DA74_6D7E, - 0x5A68_0A2E_CF7B_5C69, // -81 - 0x6BF3_BD47_C3ED_7BFD, - 0x770C_DD17_B25E_FA42, // -80 - 0x565C_976C_9CBD_FCCB, - 0x1270_B0DF_C1E5_9502, // -79 - 0x4516_DF8A_16FE_63D5, - 0x5B8D_5A4C_9B1E_10CE, // -78 - 0x6E8A_FF43_57FD_6C89, - 0x127B_C3AD_C4FC_E7B0, // -77 - 0x586F_329C_4664_56D4, - 0x0EC9_6957_D0CA_52F3, // -76 - 0x46BF_5BB0_3850_4576, - 0x3F07_8779_73D5_0F29, // -75 - 0x7132_2C4D_26E6_D58A, - 0x31A5_A58F_1FBB_4B75, // -74 - 0x5A8E_89D7_5252_446E, - 0x5AEA_EAD8_E62F_6F91, // -73 - 0x4872_07DF_750E_9D25, - 0x2F22_557A_51BF_8C74, // -72 - 0x73E9_A632_54E4_2EA2, - 0x1836_EF2A_1C65_AD86, // -71 - 0x5CBA_EB5B_771C_F21B, - 0x2CF8_BF54_E384_8AD2, // -70 - 0x4A2F_22AF_927D_8E7C, - 0x23FA_32AA_4F9D_3BDB, // -69 - 0x76B1_D118_EA62_7D93, - 0x5329_EAAA_18FB_92F8, // -68 - 0x5EF4_A747_21E8_6476, - 0x0F54_BBBB_472F_A8C6, // -67 - 0x4BF6_EC38_E7ED_1D2B, - 0x25DD_62FC_38F2_ED6C, // -66 - 0x798B_138E_3FE1_C845, - 0x22FB_D193_8E51_7BDF, // -65 - 0x613C_0FA4_FFE7_D36A, - 0x4F2F_DADC_71DA_C97F, // -64 - 0x4DC9_A61D_9986_42BB, - 0x58F3_157D_27E2_3ACC, // -63 - 0x7C75_D695_C270_6AC5, - 0x74B8_2261_D969_F7AD, // -62 - 0x6391_7877_CEC0_556B, - 0x1093_4EB4_ADEE_5FBE, // -61 - 0x4FA7_9393_0BCD_1122, - 0x4075_D890_8B25_1965, // -60 - 0x7F72_85B8_12E1_B504, - 0x00BC_8DB4_11D4_F56E, // -59 - 0x65F5_37C6_7581_5D9C, - 0x66FD_3E29_A7DD_9125, // -58 - 0x5190_F96B_9134_4AE3, - 0x6BFD_CB54_864A_DA84, // -57 - 0x4140_C789_40F6_A24F, - 0x6FFE_3C43_9EA2_486A, // -56 - 0x6867_A5A8_67F1_03B2, - 0x7FFD_2D38_FDD0_73DC, // -55 - 0x5386_1E20_5327_3628, - 0x6664_242D_97D9_F64A, // -54 - 0x42D1_B1B3_75B8_F820, - 0x51E9_B68A_DFE1_91D5, // -53 - 0x6AE9_1C52_55F4_C034, - 0x1CA9_2411_6635_B621, // -52 - 0x5587_49DB_77F7_0029, - 0x63BA_8341_1E91_5E81, // -51 - 0x446C_3B15_F992_6687, - 0x6962_029A_7EDA_B201, // -50 - 0x6D79_F823_28EA_3DA6, - 0x0F03_375D_97C4_5001, // -49 - 0x5794_C682_8721_CAEB, - 0x259C_2C4A_DFD0_4001, // -48 - 0x4610_9ECE_D281_6F22, - 0x5149_BD08_B30D_0001, // -47 - 0x701A_97B1_50CF_1837, - 0x3542_C80D_EB48_0001, // -46 - 0x59AE_DFC1_0D72_79C5, - 0x7768_A00B_22A0_0001, // -45 - 0x47BF_1967_3DF5_2E37, - 0x7920_8008_E880_0001, // -44 - 0x72CB_5BD8_6321_E38C, - 0x5B67_3341_7400_0001, // -43 - 0x5BD5_E313_8281_82D6, - 0x7C52_8F67_9000_0001, // -42 - 0x4977_E8DC_6867_9BDF, - 0x16A8_72B9_4000_0001, // -41 - 0x758C_A7C7_0D72_92FE, - 0x5773_EAC2_0000_0001, // -40 - 0x5E0A_1FD2_7128_7598, - 0x45F6_5568_0000_0001, // -39 - 0x4B3B_4CA8_5A86_C47A, - 0x04C5_1120_0000_0001, // -38 - 0x785E_E10D_5DA4_6D90, - 0x07A1_B500_0000_0001, // -37 - 0x604B_E73D_E483_8AD9, - 0x52E7_C400_0000_0001, // -36 - 0x4D09_85CB_1D36_08AE, - 0x0F1F_D000_0000_0001, // -35 - 0x7B42_6FAB_61F0_0DE3, - 0x31CC_8000_0000_0001, // -34 - 0x629B_8C89_1B26_7182, - 0x5B0A_0000_0000_0001, // -33 - 0x4EE2_D6D4_15B8_5ACE, - 0x7C08_0000_0000_0001, // -32 - 0x7E37_BE20_22C0_914B, - 0x1340_0000_0000_0001, // -31 - 0x64F9_64E6_8233_A76F, - 0x2900_0000_0000_0001, // -30 - 0x50C7_83EB_9B5C_85F2, - 0x5400_0000_0000_0001, // -29 - 0x409F_9CBC_7C4A_04C2, - 0x1000_0000_0000_0001, // -28 - 0x6765_C793_FA10_079D, - 0x0000_0000_0000_0001, // -27 - 0x52B7_D2DC_C80C_D2E4, - 0x0000_0000_0000_0001, // -26 - 0x422C_A8B0_A00A_4250, - 0x0000_0000_0000_0001, // -25 - 0x69E1_0DE7_6676_D080, - 0x0000_0000_0000_0001, // -24 - 0x54B4_0B1F_852B_DA00, - 0x0000_0000_0000_0001, // -23 - 0x43C3_3C19_3756_4800, - 0x0000_0000_0000_0001, // -22 - 0x6C6B_935B_8BBD_4000, - 0x0000_0000_0000_0001, // -21 - 0x56BC_75E2_D631_0000, - 0x0000_0000_0000_0001, // -20 - 0x4563_9182_44F4_0000, - 0x0000_0000_0000_0001, // -19 - 0x6F05_B59D_3B20_0000, - 0x0000_0000_0000_0001, // -18 - 0x58D1_5E17_6280_0000, - 0x0000_0000_0000_0001, // -17 - 0x470D_E4DF_8200_0000, - 0x0000_0000_0000_0001, // -16 - 0x71AF_D498_D000_0000, - 0x0000_0000_0000_0001, // -15 - 0x5AF3_107A_4000_0000, - 0x0000_0000_0000_0001, // -14 - 0x48C2_7395_0000_0000, - 0x0000_0000_0000_0001, // -13 - 0x746A_5288_0000_0000, - 0x0000_0000_0000_0001, // -12 - 0x5D21_DBA0_0000_0000, - 0x0000_0000_0000_0001, // -11 - 0x4A81_7C80_0000_0000, - 0x0000_0000_0000_0001, // -10 - 0x7735_9400_0000_0000, - 0x0000_0000_0000_0001, // -9 - 0x5F5E_1000_0000_0000, - 0x0000_0000_0000_0001, // -8 - 0x4C4B_4000_0000_0000, - 0x0000_0000_0000_0001, // -7 - 0x7A12_0000_0000_0000, - 0x0000_0000_0000_0001, // -6 - 0x61A8_0000_0000_0000, - 0x0000_0000_0000_0001, // -5 - 0x4E20_0000_0000_0000, - 0x0000_0000_0000_0001, // -4 - 0x7D00_0000_0000_0000, - 0x0000_0000_0000_0001, // -3 - 0x6400_0000_0000_0000, - 0x0000_0000_0000_0001, // -2 - 0x5000_0000_0000_0000, - 0x0000_0000_0000_0001, // -1 - 0x4000_0000_0000_0000, - 0x0000_0000_0000_0001, // 0 - 0x6666_6666_6666_6666, - 0x3333_3333_3333_3334, // 1 - 0x51EB_851E_B851_EB85, - 0x0F5C_28F5_C28F_5C29, // 2 - 0x4189_374B_C6A7_EF9D, - 0x5916_872B_020C_49BB, // 3 - 0x68DB_8BAC_710C_B295, - 0x74F0_D844_D013_A92B, // 4 - 0x53E2_D623_8DA3_C211, - 0x43F3_E037_0CDC_8755, // 5 - 0x431B_DE82_D7B6_34DA, - 0x698F_E692_70B0_6C44, // 6 - 0x6B5F_CA6A_F2BD_215E, - 0x0F4C_A41D_811A_46D4, // 7 - 0x55E6_3B88_C230_E77E, - 0x3F70_834A_CDAE_9F10, // 8 - 0x44B8_2FA0_9B5A_52CB, - 0x4C5A_02A2_3E25_4C0D, // 9 - 0x6DF3_7F67_5EF6_EADF, - 0x2D5C_D103_96A2_1347, // 10 - 0x57F5_FF85_E592_557F, - 0x3DE3_DA69_454E_75D3, // 11 - 0x465E_6604_B7A8_4465, - 0x7E4F_E1ED_D10B_9175, // 12 - 0x7097_09A1_25DA_0709, - 0x4A19_697C_81AC_1BEF, // 13 - 0x5A12_6E1A_84AE_6C07, - 0x54E1_2130_67BC_E326, // 14 - 0x480E_BE7B_9D58_566C, - 0x43E7_4DC0_52FD_8285, // 15 - 0x734A_CA5F_6226_F0AD, - 0x530B_AF9A_1E62_6A6D, // 16 - 0x5C3B_D519_1B52_5A24, - 0x426F_BFAE_7EB5_21F1, // 17 - 0x49C9_7747_490E_AE83, - 0x4EBF_CC8B_9890_E7F4, // 18 - 0x760F_253E_DB4A_B0D2, - 0x4ACC_7A78_F41B_0CBA, // 19 - 0x5E72_8432_4908_8D75, - 0x223D_2EC7_29AF_3D62, // 20 - 0x4B8E_D028_3A6D_3DF7, - 0x34FD_BF05_BAF2_9781, // 21 - 0x78E4_8040_5D7B_9658, - 0x54C9_31A2_C4B7_58CF, // 22 - 0x60B6_CD00_4AC9_4513, - 0x5D6D_C14F_03C5_E0A5, // 23 - 0x4D5F_0A66_A23A_9DA9, - 0x3124_9AA5_9C9E_4D51, // 24 - 0x7BCB_43D7_69F7_62A8, - 0x4EA0_F76F_60FD_4882, // 25 - 0x6309_0312_BB2C_4EED, - 0x254D_92BF_80CA_A068, // 26 - 0x4F3A_68DB_C8F0_3F24, - 0x1DD7_A899_33D5_4D20, // 27 - 0x7EC3_DAF9_4180_6506, - 0x62F2_A75B_8622_1500, // 28 - 0x6569_7BFA_9ACD_1D9F, - 0x025B_B916_04E8_10CD, // 29 - 0x5121_2FFB_AF0A_7E18, - 0x6849_60DE_6A53_40A4, // 30 - 0x40E7_5996_25A1_FE7A, - 0x203A_B3E5_21DC_33B6, // 31 - 0x67D8_8F56_A29C_CA5D, - 0x19F7_863B_6960_52BD, // 32 - 0x5313_A5DE_E87D_6EB0, - 0x7B2C_6B62_BAB3_7564, // 33 - 0x4276_1E4B_ED31_255A, - 0x2F56_BC4E_FBC2_C450, // 34 - 0x6A56_96DF_E1E8_3BC3, - 0x6557_93B1_92D1_3A1A, // 35 - 0x5512_124C_B4B9_C969, - 0x3779_42F4_7574_2E7B, // 36 - 0x440E_750A_2A2E_3ABA, - 0x5F94_3590_5DF6_8B96, // 37 - 0x6CE3_EE76_A9E3_912A, - 0x65B9_EF4D_6324_1289, // 38 - 0x571C_BEC5_54B6_0DBB, - 0x6AFB_25D7_8283_4207, // 39 - 0x45B0_989D_DD5E_7163, - 0x08C8_EB12_CECF_6806, // 40 - 0x6F80_F42F_C897_1BD1, - 0x5ADB_11B7_B14B_D9A3, // 41 - 0x5933_F68C_A078_E30E, - 0x157C_0E2C_8DD6_47B5, // 42 - 0x475C_C53D_4D2D_8271, - 0x5DFC_D823_A4AB_6C91, // 43 - 0x722E_0862_1515_9D82, - 0x632E_269F_6DDF_141B, // 44 - 0x5B58_06B4_DDAA_E468, - 0x4F58_1EE5_F17F_4349, // 45 - 0x4913_3890_B155_8386, - 0x72AC_E584_C132_9C3B, // 46 - 0x74EB_8DB4_4EEF_38D7, - 0x6AAE_3C07_9B84_2D2A, // 47 - 0x5D89_3E29_D8BF_60AC, - 0x5558_3006_1603_5755, // 48 - 0x4AD4_31BB_13CC_4D56, - 0x7779_C004_DE69_12AB, // 49 - 0x77B9_E92B_52E0_7BBE, - 0x258F_99A1_63DB_5111, // 50 - 0x5FC7_EDBC_424D_2FCB, - 0x37A6_1481_1CAF_740D, // 51 - 0x4C9F_F163_683D_BFD5, - 0x7951_AA00_E3BF_900B, // 52 - 0x7A99_8238_A6C9_32EF, - 0x754F_7667_D2CC_19AB, // 53 - 0x6214_682D_523A_8F26, - 0x2AA5_F853_0F09_AE22, // 54 - 0x4E76_B9BD_DB62_0C1E, - 0x5551_9375_A5A1_581B, // 55 - 0x7D8A_C2C9_5F03_4697, - 0x3BB5_B8BC_3C35_59C5, // 56 - 0x646F_023A_B269_0545, - 0x7C91_6096_9691_149E, // 57 - 0x5058_CE95_5B87_376B, - 0x16DA_B3AB_ABA7_43B2, // 58 - 0x4047_0BAA_AF9F_5F88, - 0x78AE_F622_EFB9_02F5, // 59 - 0x66D8_12AA_B298_98DB, - 0x0DE4_BD04_B2C1_9E54, // 60 - 0x5246_7555_5BAD_4715, - 0x57EA_30D0_8F01_4B76, // 61 - 0x41D1_F777_7C8A_9F44, - 0x4654_F3DA_0C01_092C, // 62 - 0x694F_F258_C744_3207, - 0x23BB_1FC3_4668_0EAC, // 63 - 0x543F_F513_D29C_F4D2, - 0x4FC8_E635_D1EC_D88A, // 64 - 0x4366_5DA9_754A_5D75, - 0x263A_51C4_A7F0_AD3B, // 65 - 0x6BD6_FC42_5543_C8BB, - 0x56C3_B607_731A_AEC4, // 66 - 0x5645_969B_7769_6D62, - 0x789C_919F_8F48_8BD0, // 67 - 0x4504_787C_5F87_8AB5, - 0x46E3_A7B2_D906_D640, // 68 - 0x6E6D_8D93_CC0C_1122, - 0x3E39_0C51_5B3E_239A, // 69 - 0x5857_A476_3CD6_741B, - 0x4B60_D6A7_7C31_B615, // 70 - 0x46AC_8391_CA45_29AF, - 0x55E7_121F_968E_2B44, // 71 - 0x7114_05B6_106E_A919, - 0x0971_B698_F0E3_786D, // 72 - 0x5A76_6AF8_0D25_5414, - 0x078E_2BAD_8D82_C6BD, // 73 - 0x485E_BBF9_A41D_DCDC, - 0x6C71_BC8A_D79B_D231, // 74 - 0x73CA_C65C_39C9_6161, - 0x2D82_C744_8C2C_8382, // 75 - 0x5CA2_3849_C7D4_4DE7, - 0x3E02_3903_A356_CF9B, // 76 - 0x4A1B_603B_0643_7185, - 0x7E68_2D9C_82AB_D949, // 77 - 0x7692_3391_A39F_1C09, - 0x4A40_48FA_6AAC_8EDB, // 78 - 0x5EDB_5C74_82E5_B007, - 0x5500_3A61_EEF0_7249, // 79 - 0x4BE2_B05D_3584_8CD2, - 0x7733_61E7_F259_F507, // 80 - 0x796A_B3C8_55A0_E151, - 0x3EB8_9CA6_508F_EE71, // 81 - 0x6122_296D_114D_810D, - 0x7EFA_16EB_73A6_585B, // 82 - 0x4DB4_EDF0_DAA4_673E, - 0x3261_ABEF_8FB8_46AF, // 83 - 0x7C54_AFE7_C43A_3ECA, - 0x1D69_1318_E5F3_A44B, // 84 - 0x6376_F31F_D02E_98A1, - 0x6454_0F47_1E5C_836F, // 85 - 0x4F92_5C19_7358_7A1B, - 0x0376_729F_4B7D_35F3, // 86 - 0x7F50_935B_EBC0_C35E, - 0x38BD_8432_1261_EFEB, // 87 - 0x65DA_0F7C_BC9A_35E5, - 0x13CA_D028_0EB4_BFEF, // 88 - 0x517B_3F96_FD48_2B1D, - 0x5CA2_4020_0BC3_CCBF, // 89 - 0x412F_6612_6439_BC17, - 0x63B5_0019_A303_0A33, // 90 - 0x684B_D683_D38F_9359, - 0x1F88_0029_04D1_A9EA, // 91 - 0x536F_DECF_DC72_DC47, - 0x32D3_3354_03DA_EE55, // 92 - 0x42BF_E573_16C2_49D2, - 0x5BDC_2910_0315_8B77, // 93 - 0x6ACC_A251_BE03_A951, - 0x12F9_DB4C_D1BC_1258, // 94 - 0x5570_81DA_FE69_5440, - 0x7594_AF70_A7C9_A847, // 95 - 0x445A_017B_FEBA_A9CD, - 0x4476_F2C0_863A_ED06, // 96 - 0x6D5C_CF2C_CAC4_42E2, - 0x3A57_EACD_A391_7B3C, // 97 - 0x577D_728A_3BD0_3581, - 0x7B79_88A4_82DA_C8FD, // 98 - 0x45FD_F53B_630C_F79B, - 0x15FA_D3B6_CF15_6D97, // 99 - 0x6FFC_BB92_3814_BF5E, - 0x565E_1F8A_E4EF_15BE, // 100 - 0x5996_FC74_F9AA_32B2, - 0x11E4_E608_B725_AAFF, // 101 - 0x47AB_FD2A_6154_F55B, - 0x27EA_51A0_9284_88CC, // 102 - 0x72AC_C843_CEEE_555E, - 0x7310_829A_8407_4146, // 103 - 0x5BBD_6D03_0BF1_DDE5, - 0x4273_9BAE_D005_CDD2, // 104 - 0x4964_5735_A327_E4B7, - 0x4EC2_E2F2_4004_A4A8, // 105 - 0x756D_5855_D1D9_6DF2, - 0x4AD1_6B1D_333A_A10C, // 106 - 0x5DF1_1377_DB14_57F5, - 0x2241_227D_C295_4DA3, // 107 - 0x4B27_42C6_48DD_132A, - 0x4E9A_81FE_3544_3E1C, // 108 - 0x783E_D13D_4161_B844, - 0x175D_9CC9_EED3_9694, // 109 - 0x6032_40FD_CDE7_C69C, - 0x7917_B0A1_8BDC_7876, // 110 - 0x4CF5_00CB_0B1F_D217, - 0x1412_F3B4_6FE3_9392, // 111 - 0x7B21_9ADE_7832_E9BE, - 0x5351_85ED_7FD2_85B6, // 112 - 0x6281_48B1_F9C2_5498, - 0x42A7_9E57_9975_37C5, // 113 - 0x4ECD_D3C1_949B_76E0, - 0x3552_E512_E12A_9304, // 114 - 0x7E16_1F9C_20F8_BE33, - 0x6EEB_081E_3510_EB39, // 115 - 0x64DE_7FB0_1A60_9829, - 0x3F22_6CE4_F740_BC2E, // 116 - 0x50B1_FFC0_151A_1354, - 0x3281_F0B7_2C33_C9BE, // 117 - 0x408E_6633_4414_DC43, - 0x4201_8D5F_568F_D498, // 118 - 0x674A_3D1E_D354_939F, - 0x1CCF_4898_8A7F_BA8D, // 119 - 0x52A1_CA7F_0F76_DC7F, - 0x30A5_D3AD_3B99_620B, // 120 - 0x421B_0865_A5F8_B065, - 0x73B7_DC8A_9614_4E6F, // 121 - 0x69C4_DA3C_3CC1_1A3C, - 0x52BF_C744_2353_B0B1, // 122 - 0x549D_7B63_63CD_AE96, - 0x7566_3903_4F76_26F4, // 123 - 0x43B1_2F82_B63E_2545, - 0x4451_C735_D92B_525D, // 124 - 0x6C4E_B26A_BD30_3BA2, - 0x3A1C_71EF_C1DE_EA2E, // 125 - 0x56A5_5B88_9759_C94E, - 0x61B0_5B26_34B2_54F2, // 126 - 0x4551_1606_DF7B_0772, - 0x1AF3_7C1E_908E_AA5B, // 127 - 0x6EE8_233E_325E_7250, - 0x2B1F_2CFD_B417_76F8, // 128 - 0x58B9_B5CB_5B7E_C1D9, - 0x6F4C_23FE_29AC_5F2D, // 129 - 0x46FA_F7D5_E2CB_CE47, - 0x72A3_4FFE_87BD_18F1, // 130 - 0x7191_8C89_6ADF_B073, - 0x0438_7FFD_A5FB_5B1B, // 131 - 0x5ADA_D6D4_557F_C05C, - 0x0360_6664_84C9_15AF, // 132 - 0x48AF_1243_7799_66B0, - 0x02B3_851D_3707_448C, // 133 - 0x744B_506B_F28F_0AB3, - 0x1DEC_082E_BE72_0746, // 134 - 0x5D09_0D23_2872_6EF5, - 0x64BC_D358_985B_3905, // 135 - 0x4A6D_A41C_205B_8BF7, - 0x6A30_A913_AD15_C738, // 136 - 0x7715_D360_33C5_ACBF, - 0x5D1A_A81F_7B56_0B8C, // 137 - 0x5F44_A919_C304_8A32, - 0x7DAE_ECE5_FC44_D609, // 138 - 0x4C36_EDAE_359D_3B5B, - 0x7E25_8A51_969D_7808, // 139 - 0x79F1_7C49_EF61_F893, - 0x16A2_76E8_F0FB_F33F, // 140 - 0x618D_FD07_F2B4_C6DC, - 0x121B_9253_F3FC_C299, // 141 - 0x4E0B_30D3_2890_9F16, - 0x41AF_A843_2997_0214, // 142 - 0x7CDE_B485_0DB4_31BD, - 0x4F7F_739E_A8F1_9CED, // 143 - 0x63E5_5D37_3E29_C164, - 0x3F99_294B_BA5A_E3F1, // 144 - 0x4FEA_B0F8_FE87_CDE9, - 0x7FAD_BAA2_FB7B_E98D, // 145 - 0x7FDD_E7F4_CA72_E30F, - 0x7F7C_5DD1_925F_DC15, // 146 - 0x664B_1FF7_085B_E8D9, - 0x4C63_7E41_41E6_49AB, // 147 - 0x51D5_B32C_06AF_ED7A, - 0x704F_9834_34B8_3AEF, // 148 - 0x4177_C289_9EF3_2462, - 0x26A6_135C_F6F9_C8BF, // 149 - 0x68BF_9DA8_FE51_D3D0, - 0x3DD6_8561_8B29_4132, // 150 - 0x53CC_7E20_CB74_A973, - 0x4B12_044E_08ED_CDC2, // 151 - 0x4309_FE80_A2C3_BAC2, - 0x6F41_9D0B_3A57_D7CE, // 152 - 0x6B43_30CD_D139_2AD1, - 0x3202_94DE_C3BF_BFB0, // 153 - 0x55CF_5A3E_40FA_88A7, - 0x419B_AA4B_CFCC_995A, // 154 - 0x44A5_E1CB_672E_D3B9, - 0x1AE2_EEA3_0CA3_ADE1, // 155 - 0x6DD6_3612_3EB1_52C1, - 0x77D1_7DD1_ADD2_AFCF, // 156 - 0x57DE_91A8_3227_7567, - 0x7974_64A7_BE42_263F, // 157 - 0x464B_A7B9_C1B9_2AB9, - 0x4790_5086_31CE_84FF, // 158 - 0x7079_0C5C_6928_445C, - 0x0C1A_1A70_4FB0_D4CC, // 159 - 0x59FA_7049_EDB9_D049, - 0x567B_4859_D95A_43D6, // 160 - 0x47FB_8D07_F161_736E, - 0x11FC_39E1_7AAE_9CAB, // 161 - 0x732C_14D9_8235_857D, - 0x032D_2968_C44A_9445, // 162 - 0x5C23_43E1_34F7_9DFD, - 0x4F57_5453_D03B_A9D1, // 163 - 0x49B5_CFE7_5D92_E4CA, - 0x72AC_4376_402F_BB0E, // 164 - 0x75EF_B30B_C8EB_07AB, - 0x0446_D256_CD19_2B49, // 165 - 0x5E59_5C09_6D88_D2EF, - 0x1D05_7512_3DAD_BC3A, // 166 - 0x4B7A_B007_8AD3_DBF2, - 0x4A6A_C40E_97BE_302F, // 167 - 0x78C4_4CD8_DE1F_C650, - 0x7711_39B0_F2C9_E6B1, // 168 - 0x609D_0A47_1819_6B73, - 0x78DA_948D_8F07_EBC1, // 169 - 0x4D4A_6E9F_467A_BC5C, - 0x60AE_DD3E_0C06_5634, // 170 - 0x7BAA_4A98_70C4_6094, - 0x344A_FB96_79A3_BD20, // 171 - 0x62EE_A213_8D69_E6DD, - 0x103B_FC78_614F_CA80, // 172 - 0x4F25_4E76_0ABB_1F17, - 0x2696_6393_810C_A200, // 173 - 0x7EA2_1723_445E_9825, - 0x2423_D285_9B47_6999, // 174 - 0x654E_78E9_037E_E01D, - 0x69B6_4204_7C39_2148, // 175 - 0x510B_93ED_9C65_8017, - 0x6E2B_6803_9694_1AA0, // 176 - 0x40D6_0FF1_49EA_CCDF, - 0x71BC_5336_1210_154D, // 177 - 0x67BC_E64E_DCAA_E166, - 0x1C60_8523_5019_BBAE, // 178 - 0x52FD_850B_E3BB_E784, - 0x7D1A_041C_4014_9625, // 179 - 0x4264_6A6F_E963_1F9D, - 0x4A7B_367D_0010_781D, // 180 - 0x6A3A_43E6_4238_3295, - 0x5D91_F0C8_001A_59C8, // 181 - 0x54FB_6985_01C6_8EDE, - 0x17A7_F3D3_3348_47D4, // 182 - 0x43FC_546A_67D2_0BE4, - 0x7953_2975_C2A0_3976, // 183 - 0x6CC6_ED77_0C83_463B, - 0x0EEB_7589_3766_C256, // 184 - 0x5705_8AC5_A39C_382F, - 0x2589_2AD4_2C52_3512, // 185 - 0x459E_089E_1C7C_F9BF, - 0x37A0_EF10_2374_F742, // 186 - 0x6F63_40FC_FA61_8F98, - 0x5901_7E80_38BB_2536, // 187 - 0x591C_33FD_951A_D946, - 0x7A67_9866_93C8_EA91, // 188 - 0x4749_C331_4415_7A9F, - 0x151F_AD1E_DCA0_BBA8, // 189 - 0x720F_9EB5_39BB_F765, - 0x0832_AE97_C767_92A5, // 190 - 0x5B3F_B22A_9496_5F84, - 0x068E_F213_05EC_7551, // 191 - 0x48FF_C1BB_AA11_E603, - 0x1ED8_C1A8_D189_F774, // 192 - 0x74CC_692C_434F_D66B, - 0x4AF4_690E_1C0F_F253, // 193 - 0x5D70_5423_690C_AB89, - 0x225D_20D8_1673_2843, // 194 - 0x4AC0_434F_873D_5607, - 0x3517_4D79_AB8F_5369, // 195 - 0x779A_054C_0B95_5672, - 0x21BE_E25C_45B2_1F0E, // 196 - 0x5FAE_6AA3_3C77_785B, - 0x3498_B516_9E28_18D8, // 197 - 0x4C8B_8882_96C5_F9E2, - 0x5D46_F745_4B53_4713, // 198 - 0x7A78_DA6A_8AD6_5C9D, - 0x7BA4_BED5_4552_0B52, // 199 - 0x61FA_4855_3BDE_B07E, - 0x2FB6_FF11_0441_A2A8, // 200 - 0x4E61_D377_6318_8D31, - 0x72F8_CC0D_9D01_4EED, // 201 - 0x7D69_5258_9E8D_AEB6, - 0x1E5A_E015_C802_17E1, // 202 - 0x6454_41E0_7ED7_BEF8, - 0x1848_B344_A001_ACB4, // 203 - 0x5043_67E6_CBDF_CBF9, - 0x603A_2903_B334_8A2A, // 204 - 0x4035_ECB8_A319_6FFB, - 0x002E_8736_28F6_D4EE, // 205 - 0x66BC_ADF4_3828_B32B, - 0x19E4_0B89_DB24_87E3, // 206 - 0x5230_8B29_C686_F5BC, - 0x14B6_6FA1_7C1D_3983, // 207 - 0x41C0_6F54_9ED2_5E30, - 0x1091_F2E7_967D_C79C, // 208 - 0x6933_E554_3150_96B3, - 0x341C_B7D8_F0C9_3F5F, // 209 - 0x5429_8443_5AA6_DEF5, - 0x767D_5FE0_C0A0_FF80, // 210 - 0x4354_69CF_7BB8_B25E, - 0x2B97_7FE7_0080_CC66, // 211 - 0x6BBA_42E5_92C1_1D63, - 0x5F58_CCA4_CD9A_E0A3, // 212 - 0x562E_9BEA_DBCD_B11C, - 0x4C47_0A1D_7148_B3B6, // 213 - 0x44F2_1655_7CA4_8DB0, - 0x3D05_A1B1_276D_5C92, // 214 - 0x6E50_23BB_FAA0_E2B3, - 0x7B3C_35E8_3F15_60E9, // 215 - 0x5840_1C96_621A_4EF6, - 0x2F63_5E53_65AA_B3ED, // 216 - 0x4699_B078_4E7B_725E, - 0x591C_4B75_EAEE_F658, // 217 - 0x70F5_E726_E3F8_B6FD, - 0x74FA_1256_44B1_8A26, // 218 - 0x5A5E_5285_832D_5F31, - 0x43FB_41DE_9D5A_D4EB, // 219 - 0x484B_7537_9C24_4C27, - 0x4FFC_34B2_177B_DD89, // 220 - 0x73AB_EEBF_603A_1372, - 0x4CC6_BAB6_8BF9_6274, // 221 - 0x5C89_8BCC_4CFB_42C2, - 0x0A38_955E_D661_1B90, // 222 - 0x4A07_A309_D72F_689B, - 0x21C6_DDE5_784D_AFA7, // 223 - 0x7672_9E76_2518_A75E, - 0x693E_2FD5_8D49_190B, // 224 - 0x5EC2_185E_8413_B918, - 0x5431_BFDE_0AA0_E0D5, // 225 - 0x4BCE_79E5_3676_2DAD, - 0x29C1_664B_3BB3_E711, // 226 - 0x794A_5CA1_F0BD_15E2, - 0x0F9B_D6DE_C5EC_A4E8, // 227 - 0x6108_4A1B_26FD_AB1B, - 0x2616_457F_04BD_50BA, // 228 - 0x4DA0_3B48_EBFE_227C, - 0x1E78_3798_D097_73C8, // 229 - 0x7C33_920E_4663_6A60, - 0x30C0_58F4_80F2_52D9, // 230 - 0x635C_74D8_384F_884D, - 0x0D66_AD90_6728_4247, // 231 - 0x4F7D_2A46_9372_D370, - 0x711E_F140_5286_9B6C, // 232 - 0x7F2E_AA0A_8584_8581, - 0x34FE_4ECD_50D7_5F14, // 233 - 0x65BE_EE6E_D136_D134, - 0x2A65_0BD7_73DF_7F43, // 234 - 0x5165_8B8B_DA92_40F6, - 0x551D_A312_C319_329C, // 235 - 0x411E_093C_AEDB_672B, - 0x5DB1_4F42_35AD_C217, // 236 - 0x6830_0EC7_7E2B_D845, - 0x7C4E_E536_BC49_368A, // 237 - 0x5359_A56C_64EF_E037, - 0x7D0B_EA92_303A_9208, // 238 - 0x42AE_1DF0_50BF_E693, - 0x173C_BBA8_2695_41A0, // 239 - 0x6AB0_2FE6_E799_70EB, - 0x3EC7_92A6_A422_029A, // 240 - 0x5559_BFEB_EC7A_C0BC, - 0x3239_421E_E9B4_CEE1, // 241 - 0x4447_CCBC_BD2F_0096, - 0x5B61_01B2_5490_A581, // 242 - 0x6D3F_ADFA_C84B_3424, - 0x2BCE_691D_541A_A268, // 243 - 0x5766_24C8_A03C_29B6, - 0x563E_BA7D_DCE2_1B87, // 244 - 0x45EB_50A0_8030_215E, - 0x7832_2ECB_171B_4939, // 245 - 0x6FDE_E767_3380_3564, - 0x59E9_E478_24F8_7527, // 246 - 0x597F_1F85_C2CC_F783, - 0x6187_E9F9_B72D_2A86, // 247 - 0x4798_E604_9BD7_2C69, - 0x346C_BB2E_2C24_2205, // 248 - 0x728E_3CD4_2C8B_7A42, - 0x20AD_F849_E039_D007, // 249 - 0x5BA4_FD76_8A09_2E9B, - 0x33BE_603B_19C7_D99F, // 250 - 0x4950_CAC5_3B3A_8BAF, - 0x42FE_B362_7B06_47B3, // 251 - 0x754E_113B_91F7_45E5, - 0x5197_856A_5E70_72B8, // 252 - 0x5DD8_0DC9_4192_9E51, - 0x27AC_6ABB_7EC0_5BC6, // 253 - 0x4B13_3E3A_9ADB_B1DA, - 0x52F0_5562_CBCD_1638, // 254 - 0x781E_C9F7_5E2C_4FC4, - 0x1E4D_556A_DFAE_89F3, // 255 - 0x6018_A192_B1BD_0C9C, - 0x7EA4_4455_7FBE_D4C3, // 256 - 0x4CE0_8142_27CA_707D, - 0x4BB6_9D11_32FF_109C, // 257 - 0x7B00_CED0_3FAA_4D95, - 0x5F8A_94E8_5198_1A93, // 258 - 0x6267_0BD9_CC88_3E11, - 0x32D5_43ED_0E13_4875, // 259 - 0x4EB8_D647_D6D3_64DA, - 0x5BDD_CFF0_D80F_6D2B, // 260 - 0x7DF4_8A0C_8AEB_D491, - 0x12FC_7FE7_C018_AEAB, // 261 - 0x64C3_A1A3_A256_43A7, - 0x28C9_FFEC_99AD_5889, // 262 - 0x509C_814F_B511_CFB9, - 0x0707_FFF0_7AF1_13A1, // 263 - 0x407D_343F_C40E_3FC7, - 0x1F39_998D_2F27_42E7, // 264 - 0x672E_B9FF_A016_CC71, - 0x7EC2_8F48_4B72_04A4, // 265 - 0x528B_C7FF_B345_705B, - 0x189B_A5D3_6F8E_6A1D, // 266 - 0x4209_6CCC_8F6A_C048, - 0x7A16_1E42_BFA5_21B1, // 267 - 0x69A8_AE14_18AA_CD41, - 0x4356_96D1_32A1_CF81, // 268 - 0x5486_F1A9_AD55_7101, - 0x1C45_4574_2881_72CE, // 269 - 0x439F_27BA_F111_2734, - 0x169D_D129_BA01_28A5, // 270 - 0x6C31_D92B_1B4E_A520, - 0x242F_B50F_9001_DAA1, // 271 - 0x568E_4755_AF72_1DB3, - 0x368C_90D9_4001_7BB4, // 272 - 0x453E_9F77_BF8E_7E29, - 0x120A_0D7A_999A_C95D, // 273 - 0x6ECA_98BF_98E3_FD0E, - 0x5010_1590_F5C4_7561, // 274 - 0x58A2_13CC_7A4F_FDA5, - 0x2673_4473_F7D0_5DE8, // 275 - 0x46E8_0FD6_C83F_FE1D, - 0x6B8F_69F6_5FD9_E4B9, // 276 - 0x7173_4C8A_D9FF_FCFC, - 0x45B2_4323_CC8F_D45C, // 277 - 0x5AC2_A3A2_47FF_FD96, - 0x6AF5_0283_0A0C_A9E3, // 278 - 0x489B_B61B_6CCC_CADF, - 0x08C4_0202_6E70_87E9, // 279 - 0x742C_5692_47AE_1164, - 0x746C_D003_E3E7_3FDB, // 280 - 0x5CF0_4541_D2F1_A783, - 0x76BD_7336_4FEC_3315, // 281 - 0x4A59_D101_758E_1F9C, - 0x5EFD_F5C5_0CBC_F5AB, // 282 - 0x76F6_1B35_88E3_65C7, - 0x4B2F_EFA1_ADFB_22AB, // 283 - 0x5F2B_48F7_A0B5_EB06, - 0x08F3_261A_F195_B555, // 284 - 0x4C22_A0C6_1A2B_226B, - 0x20C2_84E2_5ADE_2AAB, // 285 - 0x79D1_013C_F6AB_6A45, - 0x1AD0_D49D_5E30_4444, // 286 - 0x6174_00FD_9222_BB6A, - 0x48A7_107D_E4F3_69D0, // 287 - 0x4DF6_6731_41B5_62BB, - 0x53B8_D9FE_50C2_BB0D, // 288 - 0x7CBD_71E8_6922_3792, - 0x52C1_5CCA_1AD1_2B48, // 289 - 0x63CA_C186_BA81_C60E, - 0x7567_7D6E_7BDA_8906, // 290 - 0x4FD5_679E_FB9B_04D8, - 0x5DEC_6458_6315_3A6C, // 291 - 0x7FBB_D8FE_5F5E_6E27, - 0x497A_3A27_04EE_C3DF, // 292 -]; From 906662e606f0ab000895c3df33f4347dd9bcea95 Mon Sep 17 00:00:00 2001 From: Leung Ming <165622843+leung-ming@users.noreply.github.com> Date: Wed, 25 Jun 2025 02:24:18 +0800 Subject: [PATCH 8/8] fix --- native/dragonbox/src/buffer.rs | 17 +++++++++++++++++ native/dragonbox/src/cache.rs | 17 +++++++++++++++++ native/dragonbox/src/div.rs | 17 +++++++++++++++++ native/dragonbox/src/lib.rs | 21 +++++++++++++++++++-- native/dragonbox/src/log.rs | 17 +++++++++++++++++ native/dragonbox/src/to_chars.rs | 17 +++++++++++++++++ native/dragonbox/src/wuint.rs | 17 +++++++++++++++++ 7 files changed, 121 insertions(+), 2 deletions(-) diff --git a/native/dragonbox/src/buffer.rs b/native/dragonbox/src/buffer.rs index 3b1dc2bdbe..80ce4a6660 100644 --- a/native/dragonbox/src/buffer.rs +++ b/native/dragonbox/src/buffer.rs @@ -1,3 +1,20 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + use crate::{Buffer, Float}; use core::mem::MaybeUninit; use core::slice; diff --git a/native/dragonbox/src/cache.rs b/native/dragonbox/src/cache.rs index 90e31368ac..de566ed746 100644 --- a/native/dragonbox/src/cache.rs +++ b/native/dragonbox/src/cache.rs @@ -1,3 +1,20 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + // Translated from C++ to Rust. The original C++ code can be found at // https://github.com/jk-jeon/dragonbox and carries the following license: // diff --git a/native/dragonbox/src/div.rs b/native/dragonbox/src/div.rs index 986e6b481b..50ee9edf85 100644 --- a/native/dragonbox/src/div.rs +++ b/native/dragonbox/src/div.rs @@ -1,3 +1,20 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + // Translated from C++ to Rust. The original C++ code can be found at // https://github.com/jk-jeon/dragonbox and carries the following license: // diff --git a/native/dragonbox/src/lib.rs b/native/dragonbox/src/lib.rs index 36dbbef3a9..4ee7eb6ca5 100644 --- a/native/dragonbox/src/lib.rs +++ b/native/dragonbox/src/lib.rs @@ -1,3 +1,20 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + // Translated from C++ to Rust. The original C++ code can be found at // https://github.com/jk-jeon/dragonbox and carries the following license: // @@ -36,7 +53,7 @@ //! //! ``` //! fn main() { -//! let mut buffer = dragonbox::Buffer::new(); +//! let mut buffer = datafusion_comet_dragonbox::Buffer::new(); //! let printed = buffer.format(1.234); //! assert_eq!(printed, "1.234E0"); //! } @@ -90,7 +107,7 @@ use core::mem::MaybeUninit; /// ## Example /// /// ``` -/// let mut buffer = dragonbox::Buffer::new(); +/// let mut buffer = datafusion_comet_dragonbox::Buffer::new(); /// let printed = buffer.format_finite(1.234); /// assert_eq!(printed, "1.234E0"); /// ``` diff --git a/native/dragonbox/src/log.rs b/native/dragonbox/src/log.rs index 2cc7ff83f0..6395eedeb9 100644 --- a/native/dragonbox/src/log.rs +++ b/native/dragonbox/src/log.rs @@ -1,3 +1,20 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + // Translated from C++ to Rust. The original C++ code can be found at // https://github.com/jk-jeon/dragonbox and carries the following license: // diff --git a/native/dragonbox/src/to_chars.rs b/native/dragonbox/src/to_chars.rs index 6fec24b318..f348857435 100644 --- a/native/dragonbox/src/to_chars.rs +++ b/native/dragonbox/src/to_chars.rs @@ -1,3 +1,20 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + // Translated from C++ to Rust. The original C++ code can be found at // https://github.com/jk-jeon/dragonbox and carries the following license: // diff --git a/native/dragonbox/src/wuint.rs b/native/dragonbox/src/wuint.rs index 06df591ac2..c069299071 100644 --- a/native/dragonbox/src/wuint.rs +++ b/native/dragonbox/src/wuint.rs @@ -1,3 +1,20 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + // Translated from C++ to Rust. The original C++ code can be found at // https://github.com/jk-jeon/dragonbox and carries the following license: //