lexical-core-0.7.6/.cargo_vcs_info.json0000644000000001120000000000000134060ustar { "git": { "sha1": "1a5687db70268ab72f19b67cda83c1197a7f5a25" } } lexical-core-0.7.6/CHANGELOG000075500000000000000000000155320000000000000134050ustar 00000000000000# Changelog Notes significant changes to lexical-core. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] - Updated cfg_if version. - Downgraded rand to fix proptests. - Fixed a bug on newer Rustc versions where `slice::sort` is not present in `no_std`. - Added a feature `libm` which enables stable `no_std` use. - Patched an implementation of insert_many due to a security advisory which does not affect lexical. ## [0.7.5] 2021-02-21 ### Changed - Fixed issue with `integer::BITS` conflicting with new compilers. ## [0.7.4] 2020-01-27 ### Changed - Changed NumberFormat to use 64-bit flags. - Added `NO_INTEGER_LEADING_ZEROS` and `NO_FLOAT_LEADING_ZEROS` NumberFormat flags. - Added `InvalidLeadingZeros` to ErrorCode enum. - Added `validate_no_leading_zeros` to reject invalid inputs. - Added new leading zero checks to all pre-defined NumberFormat constants. ## [0.7.3] 2020-01-26 ### Changed - Updated the format bitflags to make matches more efficient, allowing jumptables to be used for most situations. ## [0.7.2] 2020-01-25 ### Changed - Fixed a regression in parsing special values. ## [0.7.1] 2020-01-23 ### Added - Added `format` feature to control parsing integers and floats from number specifications. - Added the `NumberFormat` bitflags to control Number format specifications. These flags control how a number is parsed, including enabling the use of digit separators, requiring integer or fraction digits, and more. - Added pre-defined constants for `NumberFormat` (`RUST_STRING`, `PYTHON_LITERAL`) to avoid compiling formats when not needed. - Added the `FromLexicalFormat` and `FromLexicalLossyFormat` traits with the `format` feature, which enable you to specify the number format during parsing. - Implemented algorithms in terms of generic iterators, to allow skipping digit separators. - Implemented data interfaces to simplify parsing and validating number format. - Added more values to `ErrorCode` to signify more parse failures. ### Changed - Changed `ErrorCode::MissingFraction` to be `ErrorCode::MissingMantissa`, to differentiate between missing integers, missing fractions, and missing significant digits (mantissa). - Remove `RawFloatState` and `FloatState` and replaced it logically with `FastDataInterface` and `SlowDataInterface`, allowing format-defined parsing. ## [0.7.0] - 2020-01-07 ### Changed - Updated `arrayvec` and `static-assertions` versions. - Removed support for Rustc versions below 1.37.0. ## [0.6.3] - 2019-10-08 ### Changed - Forced version `0.1.9` for cfg-if to support older Rustc versions. - Documented dependency versioning and upgrade procedure. ## [0.6.2] - 2019-09-22 ### Changed - Fixed a bug causing compilation issues on MSVC. ## [0.6.1] - 2019-09-16 ### Changed - Removed panic handler, allowing use in `no_std` environments. ## [0.6.0] - 2019-09-08 ### Added - Added `get/set_exponent_default_char`, `get/set_exponent_backup_char`, and `get/set_float_rounding`, to allow validation logic for config variables. - Added the `write*` functions, which replace the `*toa` methods. - Added `parse*` functions, which replace the `ato*` methods. - Added tests to ensure lexical-core works with proc-macros. - Substituted rust-stackvector with arrayvec, which has better support. ### Removed - Removed `EXPONENT_DEFAULT_CHAR`, `EXPONENT_BACKUP_CHAR`, and `FLOAT_ROUNDING`. - Removed all expanded API signatures for `ato*` to `*toa`, since these were for compatibility with the C-API and were therefore redundant. - Removed the FFI submodule, and moved all functionality to the `lexical-capi` crate. ## [0.5.0] - 2019-08-20 ### Added - Added ffi::Result, an FFI-compatible tagged union, to store results for FFI-compatible functions. - Added `MAX_*_SIZE_BASE10` constants, to determine the maximum size in bytes a formatted type will take in base 10. - Added `ato*_partial` functions, which parse until an invalid digit is found, returning the value and number of processed digits. ### Changed - Improved code generation and reduced binary bloat. There are a few algorithmic differences that make this possible, but the parsers now generally extract the float subcomponents first, then parsed known-good data after for enhanced performance. - Updated the benchmarks and benchmark results. - Add variants for lexical_core::ErrorCode. Added `Underflow`, to detect numerical underflow, `EmptyFraction`, to detect floats with an empty integer and fraction components, and `EmptyExponent`, to detect floats with no value following the exponent character. - Changed Result to use `std::result::Result`. - Fixed proptests and added more comprehensive proptests thanks to @dangrabcad. - Moved FFI-compatible code to the public `ffi` module. - Removed `*_slice` from functions in the public API, since there is no naming conflict with FFI code. - Removed `*_ffi` and `*_FFI` from public functions and constants. - Optimized the itoa exporters using specialized optimizations for the type size and number of digits. The resulting performance excels for all values, providing 2-3x performance improvements, with exceptional performance for values with a small number of digits. - Optimized integer division algorithm based off the compiler-builtins crate to avoid redundant calls to an expensive compiler intrinsic (`__udivmodti4`). - Optimized the atoi algorithm for 128-bit integers by using intermediary 64-bit integers, leading to performance boosts of up to 30x. ### Removed - Removed the unchecked parsers from the public API. `try_parse*` has been replaced with `parse*`. - Removed ErrorCode::Success, since with the new result types it was redundant. ## [0.4.3] - 2019-06-26 - Fixed a bug (issue #20) leading to incorrect float parsing (1 ULP error) for slow-path algorithms containing floats with a trailing 0-digit in the fraction component (discovery by @dangrabcad). Added in comprehensive unittests to avoid future regressions. - Fixed CI for older Rustc versions due to issues with the `edition` keyword. - Updated dependencies (credit to @junhoo). - Updated the benchmarks for float and integer formatting to use `Write::write_fmt` rather than `to_string` to avoid heap allocation leading to misleading results (credit to @RazrFalcon). ## [0.4.2] - 2019-06-24 ### Added - Comprehensive continuous integration unittests for numerous platforms, based off the [trust](https://github.com/japaric/trust) templates. - Added known issue for a non-default, lossy setting on armv6 architectures. ### Changed - Bug fix for 32-bit targets. ## [0.4.1] - 2019-06-20 ### Added - Backwards compatible support for Rustc 1.24.0. ### Changed - Worked around a bug in the internal float formatter where `&arr[idx]` creates a local copy in Rust versions before 1.28.0, creating a dangling reference after the scope ends. For more details, see `cached_grisu_power` in `/lexical-core/src/ftoa/grisu2.rs` . lexical-core-0.7.6/Cargo.toml0000644000000041600000000000000114130ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "lexical-core" version = "0.7.6" authors = ["Alex Huszagh "] build = "build.rs" exclude = ["fuzz/*", "scripts/*", "ffi/*"] autobenches = false description = "Lexical, to- and from-string conversion routines." documentation = "https://docs.rs/lexical-core" readme = "README.md" keywords = ["parsing", "lexical", "encoding", "no_std"] categories = ["parsing", "encoding", "no-std", "value-formatting"] license = "MIT/Apache-2.0" repository = "https://github.com/Alexhuszagh/rust-lexical/tree/master/lexical-core" [profile.dev] opt-level = 0 lto = false debug = true [profile.release] opt-level = 3 lto = true debug = false debug-assertions = false [dependencies.arrayvec] version = "0.5" features = ["array-sizes-33-128"] optional = true default-features = false [dependencies.bitflags] version = "1.2" [dependencies.cfg-if] version = "1.0" [dependencies.dtoa] version = "0.4" optional = true [dependencies.libm] version = "0.2.1" optional = true [dependencies.proptest] version = "0.10.1" optional = true [dependencies.quickcheck] version = "1.0.3" optional = true [dependencies.ryu] version = "1.0" optional = true [dependencies.static_assertions] version = "1" optional = true [dev-dependencies.approx] version = "0.4.0" [features] correct = ["arrayvec", "static_assertions", "table"] default = ["correct", "ryu", "std"] format = ["static_assertions"] grisu3 = ["dtoa"] noinline = [] property_tests = ["quickcheck", "proptest"] radix = [] rounding = [] std = [] table = [] trim_floats = [] unchecked_index = [] [badges.travis-ci] repository = "Alexhuszagh/rust-lexical" lexical-core-0.7.6/Cargo.toml.orig000075500000000000000000000053170000000000000150620ustar 00000000000000[package] authors = ["Alex Huszagh "] autobenches = false categories = ["parsing", "encoding", "no-std", "value-formatting"] description = "Lexical, to- and from-string conversion routines." documentation = "https://docs.rs/lexical-core" edition = "2018" keywords = ["parsing", "lexical", "encoding", "no_std"] license = "MIT/Apache-2.0" name = "lexical-core" readme = "README.md" repository = "https://github.com/Alexhuszagh/rust-lexical/tree/master/lexical-core" version = "0.7.6" build = "build.rs" exclude = [ "fuzz/*", "scripts/*", "ffi/*", ] [badges] travis-ci = { repository = "Alexhuszagh/rust-lexical" } [dependencies] bitflags = "1.2" cfg-if = "1.0" # Use static_assertions for correct or format features. static_assertions = { version = "1", optional = true } # Use arrayvec for the correct parser. arrayvec = { version = "0.5", default-features = false, optional = true, features = ["array-sizes-33-128"] } # Optimized Grisu3 implementation, a well-tested, correct algorithm. dtoa = { version = "0.4", optional = true } # Optimized Ryu implementation, the fastest correct algorithm. ryu = { version = "1.0", optional = true } # Enable quickcheck for newer Rustc versions. quickcheck = { version = "1.0.3", optional = true } # Enable proptest for newer Rustc versions. proptest = { version = "0.10.1", optional = true } # Use libm in a stable, no_std environment. libm = { version = "0.2.1", optional = true } [dev-dependencies] approx = "0.4.0" [features] default = ["correct", "ryu", "std"] # Use the correct atof parser. correct = ["arrayvec", "static_assertions", "table"] # Add support for different float string formats. format = ["static_assertions"] # Use the optimized Grisu3 implementation from dtoa (not recommended). grisu3 = ["dtoa"] # Add support for parsing non-decimal float and integer strings. radix = [] # Allow custom rounding schemes, at the cost of slower performance. rounding = [] # Use the `std` library. std = [] # Use precompiled tables for faster performance and accuracy, at the cost of larger binaries. table = [] # Trim a trailing ".0" from an exported float string, and represent -0.0 as "0". trim_floats = [] # Don't force bounds checking with indexing not-known to be valid at compile time. # This may lead to memory safety issues. unchecked_index = [] # Don't inline when using perftools # Testing only. noinline = [] # Undocumented. Disable quickcheck for older Rustc versions. property_tests = ["quickcheck", "proptest"] # Use heavy optimizations for release builds, and make our panics to detect # internal logic errors safe for FFI, via abort. [profile.dev] opt-level = 0 debug = true lto = false [profile.release] opt-level = 3 debug = false debug-assertions = false lto = true lexical-core-0.7.6/LICENSE-APACHE000075500000000000000000000251420000000000000141150ustar 00000000000000 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 APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed 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. lexical-core-0.7.6/LICENSE-MIT000075500000000000000000000017770000000000000136350ustar 00000000000000Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. lexical-core-0.7.6/README.md000075500000000000000000000712200000000000000134460ustar 00000000000000lexical-core ============ [![Build Status](https://api.travis-ci.org/Alexhuszagh/rust-lexical.svg?branch=master)](https://travis-ci.org/Alexhuszagh/rust-lexical) [![Latest Version](https://img.shields.io/crates/v/lexical-core.svg)](https://crates.io/crates/lexical-core) [![Rustc Version 1.37+](https://img.shields.io/badge/rustc-1.37+-lightgray.svg)](https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html) Low-level, lexical conversion routines for use in a `no_std` context. This crate by default does not use the Rust standard library. - [Getting Started](#getting-started) - [Features](#features) - [Format](#format) - [Configuration](#configuration) - [Constants](#constants) - [Documentation](#documentation) - [Validation](#validation) - [Implementation Details](#implementation-details) - [Float to String](#float-to-string) - [String to Float](#string-to-float) - [Arbitrary-Precision Arithmetic](#arbitrary-precision-arithmetic) - [Algorithm Background and Comparison](#algorithm-background-and-comparison) - [Known Issues](#known-issues) - [Versioning and Version Support](#versioning-and-version-support) - [Changelog](#changelog) - [License](#license) - [Contributing](#contributing) # Getting Started lexical-core is a low-level API for number-to-string and string-to-number conversions, without requiring a system allocator. If you would like to use a convenient, high-level API, please look at [lexical](../lexical) instead. Add lexical-core to your `Cargo.toml`: ```toml [dependencies] lexical-core = "^0.7.1" ``` And an introduction through use: ```rust extern crate lexical_core; // String to number using Rust slices. // The argument is the byte string parsed. let f: f32 = lexical_core::parse(b"3.5").unwrap(); // 3.5 let i: i32 = lexical_core::parse(b"15").unwrap(); // 15 // All lexical_core parsers are checked, they validate the // input data is entirely correct, and stop parsing when invalid data // is found, or upon numerical overflow. let r = lexical_core::parse::(b"256"); // Err(ErrorCode::Overflow.into()) let r = lexical_core::parse::(b"1a5"); // Err(ErrorCode::InvalidDigit.into()) // In order to extract and parse a number from a substring of the input // data, use `parse_partial`. These functions return the parsed value and // the number of processed digits, allowing you to extract and parse the // number in a single pass. let r = lexical_core::parse_partial::(b"3a5"); // Ok((3, 1)) // If an insufficiently long buffer is passed, the serializer will panic. // PANICS let mut buf = [b'0'; 1]; //let slc = lexical_core::write::(15, &mut buf); // In order to guarantee the buffer is long enough, always ensure there // are at least `T::FORMATTED_SIZE` bytes, which requires the // `lexical_core::Number` trait to be in scope. use lexical_core::Number; let mut buf = [b'0'; f64::FORMATTED_SIZE]; let slc = lexical_core::write::(15.1, &mut buf); assert_eq!(slc, b"15.1"); // When the `radix` feature is enabled, for decimal floats, using // `T::FORMATTED_SIZE` may significantly overestimate the space // required to format the number. Therefore, the // `T::FORMATTED_SIZE_DECIMAL` constants allow you to get a much // tighter bound on the space required. let mut buf = [b'0'; f64::FORMATTED_SIZE_DECIMAL]; let slc = lexical_core::write::(15.1, &mut buf); assert_eq!(slc, b"15.1"); ``` # Features - **correct** Use a correct string-to-float parser.
Enabled by default, and may be turned off by setting default-features = false. If neither algorithm_m nor bhcomp is enabled while correct is enabled, lexical uses the bigcomp algorithm.
- **trim_floats** Export floats without a fraction as an integer.
For example, 0.0f64 will be serialized to "0" and not "0.0", and -0.0 as "0" and not "-0.0".
- **radix** Allow conversions to and from non-decimal strings.
With radix enabled, any radix from 2 to 36 (inclusive) is valid, otherwise, only 10 is valid.
- **format** Customize accepted inputs for number parsing.
With format enabled, the number format is dictated through the NumberFormat bitflags, which allow you to toggle how to parse a string into a number. Various flags including enabling digit separators, requiring integer or fraction digits, and toggling special values.
- **rounding** Enable custom rounding for IEEE754 floats.
By default, lexical uses round-nearest, tie-even for float rounding (recommended by IEE754).
- **ryu** Use dtolnay's [ryu](https://github.com/dtolnay/ryu/) library for float-to-string conversions.
Enabled by default, and may be turned off by setting default-features = false. Ryu is ~2x as fast as other float formatters.
- **libm** Enable use of the [libm](https://github.com/rust-lang/libm) library for stable `no_std` support. ## Format Every language has competing specifications for valid numerical input, meaning a number parser for Rust will incorrectly accept or reject input for different programming or data languages. For example: ```rust extern crate lexical_core; use lexical_core::*; // Valid in Rust strings. // Not valid in JSON. let f: f64 = parse(b"3.e7").unwrap(); // 3e7 // Let's only accept JSON floats. let format = NumberFormat::JSON; let f: f64 = parse_format(b"3.0e7", format).unwrap(); // 3e7 let f: f64 = parse_format(b"3.e7", format).unwrap(); // Panics! // We can also allow digit separators, for example. // OCaml, a programming language that inspired Rust, // accepts digit separators pretty much anywhere. let format = NumberFormat::OCAML_STRING; let f: f64 = parse(b"3_4.__0_1").unwrap(); // Panics! let f: f64 = parse_format(b"3_4.__0_1", format).unwrap(); // 34.01 ``` The parsing specification is defined by `NumberFormat`, which provides pre-defined constants for over 40 programming and data languages. However, it also allows you to create your own specification, to dictate parsing. ```rust extern crate lexical_core; use lexical_core::*; // Let's use the standard, Rust grammar. let format = NumberFormat::standard().unwrap(); // Let's use a permissive grammar, one that allows anything besides // digit separators. let format = NumberFormat::permissive().unwrap(); // Let's ignore digit separators and have an otherwise permissive grammar. let format = NumberFormat::ignore(b'_').unwrap(); // Create our own grammar. // A NumberFormat is compiled from options into binary flags, each // taking 1-bit, allowing high-performance, customizable parsing // once they're compiled. Each flag will be explained while defining it. // The '_' character will be used as a digit separator. let digit_separator = b'_'; // Require digits in the integer component of a float. // `0.1` is valid, but `.1` is not. let required_integer_digits = false; // Require digits in the fraction component of a float. // `1.0` is valid, but `1.` and `1` are not. let required_fraction_digits = false; // Require digits in the exponent component of a float. // `1.0` and `1.0e7` is valid, but `1.0e` is not. let required_exponent_digits = false; // Do not allow a positive sign before the mantissa. // `1.0` and `-1.0` are valid, but `+1.0` is not. let no_positive_mantissa_sign = false; // Require a sign before the mantissa. // `+1.0` and `-1.0` are valid, but `1.0` is not. let required_mantissa_sign = false; // Do not allow the use of exponents. // `300.0` is valid, but `3.0e2` is not. let no_exponent_notation = false; // Do not allow a positive sign before the exponent. // `3.0e2` and 3.0e-2` are valid, but `3.0e+2` is not. let no_positive_exponent_sign = false; // Require a sign before the exponent. // `3.0e+2` and `3.0e-2` are valid, but `3.0e2` is not. let required_exponent_sign = false; // Do not allow an exponent without fraction digits. // `3.0e7` is valid, but `3e7` and `3.e7` are not. let no_exponent_without_fraction = false; // Do not allow special values. // `1.0` is valid, but `NaN` and `inf` are not. let no_special = false; // Use case-sensitive matching when parsing special values. // `NaN` is valid, but `nan` and `NAN` are not. let case_sensitive_special = false; // Allow digit separators between digits in the integer component. // `3_4.01` is valid, but `_34.01`, `34_.01` and `34.0_1` are not. let integer_internal_digit_separator = false; // Allow digit separators between digits in the fraction component. // `34.0_1` is valid, but `34._01`, `34.01_` and `3_4.01` are not. let fraction_internal_digit_separator = false; // Allow digit separators between digits in the exponent component. // `1.0e6_7` is valid, but `1.0e_67`, `1.0e67_` and `1_2.0e67` are not. let exponent_internal_digit_separator = false; // Allow digit separators before any digits in the integer component. // These digit separators may occur before or after the sign, as long // as they occur before any digits. // `_34.01` is valid, but `3_4.01`, `34_.01` and `34._01` are not. let integer_leading_digit_separator = false; // Allow digit separators before any digits in the fraction component. // `34._01` is valid, but `34.0_1`, `34.01_` and `_34.01` are not. let fraction_leading_digit_separator = false; // Allow digit separators before any digits in the exponent component. // These digit separators may occur before or after the sign, as long // as they occur before any digits. // `1.0e_67` is valid, but `1.0e6_7`, `1.0e67_` and `_1.0e67` are not. let exponent_leading_digit_separator = false; // Allow digit separators after any digits in the integer component. // If `required_integer_digits` is not set, `_.01` is valid. // `34_.01` is valid, but `3_4.01`, `_34.01` and `34.01_` are not. let integer_trailing_digit_separator = false; // Allow digit separators after any digits in the fraction component. // If `required_fraction_digits` is not set, `1._` is valid. // `34.01_` is valid, but `34.0_1`, `34._01` and `34_.01` are not. let fraction_trailing_digit_separator = false; // Allow digit separators after any digits in the exponent component. // If `required_exponent_digits` is not set, `1.0e_` is valid. // `1.0e67_` is valid, but `1.0e6_7`, `1.0e_67` and `1.0_e67` are not. let exponent_trailing_digit_separator = false; // Allow consecutive separators in the integer component. // This requires another integer digit separator flag to be set. // For example, if `integer_internal_digit_separator` and this flag are set, // `3__4.01` is valid, but `__34.01`, `34__.01` and `34.0__1` are not. let integer_consecutive_digit_separator = false; // Allow consecutive separators in the fraction component. // This requires another fraction digit separator flag to be set. // For example, if `fraction_internal_digit_separator` and this flag are set, // `34.0__1` is valid, but `34.__01`, `34.01__` and `3__4.01` are not. let fraction_consecutive_digit_separator = false; // Allow consecutive separators in the exponent component. // This requires another exponent digit separator flag to be set. // For example, if `exponent_internal_digit_separator` and this flag are set, // `1.0e6__7` is valid, but `1.0e__67`, `1.0e67__` and `1__2.0e67` are not. let exponent_consecutive_digit_separator = false; // Allow digit separators in special values. // If set, allow digit separators in special values will be ignored. // `N_a_N__` is valid, but `i_n_f_e` is not. let special_digit_separator = false; // Compile the grammar. let format = NumberFormat::compile( digit_separator, required_integer_digits, required_fraction_digits, required_exponent_digits, no_positive_mantissa_sign, required_mantissa_sign, no_exponent_notation, no_positive_exponent_sign, required_exponent_sign, no_exponent_without_fraction, no_special, case_sensitive_special, integer_internal_digit_separator, fraction_internal_digit_separator, exponent_internal_digit_separator, integer_leading_digit_separator, fraction_leading_digit_separator, exponent_leading_digit_separator, integer_trailing_digit_separator, fraction_trailing_digit_separator, exponent_trailing_digit_separator, integer_consecutive_digit_separator, fraction_consecutive_digit_separator, exponent_consecutive_digit_separator, special_digit_separator ).unwrap(); ``` # Configuration Lexical-core also includes configuration options that allow you to configure float processing and formatting. These are provided as getters and setters, so lexical-core can validate the input. - **NaN** - `get_nan_string` - `set_nan_string`
The representation of Not a Number (NaN) as a string (default b"NaN"). For float parsing, lexical-core uses case-insensitive comparisons. This string must start with an 'N' or 'n'.
- **Short Infinity** - `get_inf_string` - `set_inf_string`
The short, default representation of infinity as a string (default b"inf"). For float parsing, lexical-core uses case-insensitive comparisons. This string **must** start with an 'I' or 'i'.
- **Long Infinity** - `get_infinity_string` - `set_infinity_string`
The long, backup representation of infinity as a string (default b"infinity"). The long infinity must be at least as long as the short infinity, and will only be used during float parsing (and is case-insensitive). This string **must** start with an 'I' or 'i'.
- **Exponent Default Character** - `get_exponent_default_char` - `set_exponent_default_char`
The default character designating the exponent component of a float (default b'e') for strings with a radix less than 15 (including decimal strings). For float parsing, lexical-core uses case-insensitive comparisons. This value should be not be in character set [0-9a-eA-E.+\-].
- **Exponent Backup Character** (radix only) - `get_exponent_backup_char` - `set_exponent_backup_char`
The backup character designating the exponent component of a float (default b'^') for strings with a radix greater than or equal to 15. This value should be not be in character set [0-9a-zA-Z.+\-].
- **Float Rounding** (rounding only) - `get_float_rounding` - `set_float_rounding`
The IEEE754 float-rounding scheme to be used during float parsing. In almost every case, this should be set to RoundingKind::NearestTieEven.
# Constants Lexical-core also includes a few constants to simplify interfacing with number-to-string code, and are implemented for the `lexical_core::Number` trait, which is required by `ToLexical`. - **FORMATTED_SIZE** The maximum number of bytes a formatter may write.
For example, lexical_core::write_radix::<i32> may write up to i32::FORMATTED_SIZE characters. This constant may significantly overestimate the number of characters required for decimal strings when the radix feature is enabled.
- **FORMATTED_SIZE_DECIMAL** The maximum number of bytes a formatter may write in decimal (base 10).
For example, lexical_core::write::<i32> may write up to i32::FORMATTED_SIZE_DECIMAL characters.
These are provided as Rust constants so they may be used as the size element in arrays. # Documentation Lexical-core's documentation can be found on [docs.rs](https://docs.rs/lexical-core). # Validation Float parsing is difficult to do correctly, and major bugs have been found in implementations from [libstdc++'s strtod](https://www.exploringbinary.com/glibc-strtod-incorrectly-converts-2-to-the-negative-1075/) to [Python](https://bugs.python.org/issue7632). In order to validate the accuracy of the lexical, we employ the following external tests: 1. Hrvoje Abraham's [strtod](https://github.com/ahrvoje/numerics/tree/master/strtod) test cases. 2. Rust's [test-float-parse](https://github.com/rust-lang/rust/tree/64185f205dcbd8db255ad6674e43c63423f2369a/src/etc/test-float-parse) unittests. 3. Testbase's [stress tests](https://www.icir.org/vern/papers/testbase-report.pdf) for converting from decimal to binary. 4. [Various](https://www.exploringbinary.com/glibc-strtod-incorrectly-converts-2-to-the-negative-1075/) [difficult](https://www.exploringbinary.com/how-glibc-strtod-works/) [cases](https://www.exploringbinary.com/how-strtod-works-and-sometimes-doesnt/) reported on blogs. Although lexical may contain bugs leading to rounding error, it is tested against a comprehensive suite of random-data and near-halfway representations, and should be fast and correct for the vast majority of use-cases. # Implementation Details ## Float to String For more information on the Grisu2 and Grisu3 algorithms, see [Printing Floating-Point Numbers Quickly and Accurately with Integers](https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf). For more information on the Ryu algorithm, see [RyĆ«: fast float-to-string conversion](https://dl.acm.org/citation.cfm?id=3192369). ## String to Float In order to implement an efficient parser in Rust, lexical uses the following steps: 1. We ignore the sign until the end, and merely toggle the sign bit after creating a correct representation of the positive float. 2. We handle special floats, such as "NaN", "inf", "Infinity". If we do not have a special float, we continue to the next step. 3. We parse up to 64-bits from the string for the mantissa, ignoring any trailing digits, and parse the exponent (if present) as a signed 32-bit integer. If the exponent overflows or underflows, we set the value to i32::max_value() or i32::min_value(), respectively. 4. **Fast Path** We then try to create an exact representation of a native binary float from parsed mantissa and exponent. If both can be exactly represented, we multiply the two to create an exact representation, since IEEE754 floats mandate the use of guard digits to minimizing rounding error. If either component cannot be exactly represented as the native float, we continue to the next step. 5. **Moderate Path** We create an approximate, extended, 80-bit float type (64-bits for the mantissa, 16-bits for the exponent) from both components, and multiplies them together. This minimizes the rounding error, through guard digits. We then estimate the error from the parsing and multiplication steps, and if the float +/- the error differs significantly from b+h, we return the correct representation (b or b+u). If we cannot unambiguously determine the correct floating-point representation, we continue to the next step. 6. **Fallback Moderate Path** Next, we create a 128-bit representation of the numerator and denominator for b+h, to disambiguate b from b+u by comparing the actual digits in the input to theoretical digits generated from b+h. This is accurate for ~36 significant digits from a 128-bit approximation with decimal float strings. If the input is less than or equal to 36 digits, we return the value from this step. Otherwise, we continue to the next step. 7. **Slow Path** We use arbitrary-precision arithmetic to disambiguate the correct representation without any rounding error. We create an exact representation of the input digits as a big integer, to determine how to round the top 53 bits for the mantissa. If there is a fraction or a negative exponent, we create a representation of the significant digits for `b+h` and scale the input digits by the binary exponent in `b+h`, and scale the significant digits in `b+h` by the decimal exponent, and compare the two to determine if we need to round up or down. Since arbitrary-precision arithmetic is slow and scales poorly for decimal strings with many digits or exponents of high magnitude, lexical also supports a lossy algorithm, which returns the result from the moderate path. The result from the lossy parser should be accurate to within 1 ULP. ## Arbitrary-Precision Arithmetic Lexical uses arbitrary-precision arithmetic to exactly represent strings between two floating-point representations, and is highly optimized for performance. The following section is a comparison of different algorithms to determine the correct float representation. The arbitrary-precision arithmetic logic is not dependent on memory allocation: it only uses the heap when the `radix` feature is enabled. ## Algorithm Background and Comparison For close-to-halfway representations of a decimal string `s`, where `s` is close between two representations, `b` and the next float `b+u`, arbitrary-precision arithmetic is used to determine the correct representation. This means `s` is close to `b+h`, where `h` is the halfway point between `b` and `b+u`. For the following example, we will use the following values for our test case: * `s = 2.4703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125001e-324` * `b = 0.0` * `b+h = 2.4703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125e-324` * `b+u = 5e-324` **Algorithm M** Algorithm M represents the significant digits of a float as a fraction of arbitrary-precision integers (a more in-depth description can be found [here](https://www.exploringbinary.com/correct-decimal-to-floating-point-using-big-integers/)). For example, 1.23 would be 123/100, while 314.159 would be 314159/1000. We then scale the numerator and denominator by powers of 2 until the quotient is in the range `[2^52, 2^53)`, generating the correct significant digits of the mantissa. A naive implementation, in Python, is as follows: ```python def algorithm_m(num, b): # Ensure numerator >= 2**52 bits = int(math.ceil(math.log2(num))) if bits <= 53: num <<= 53 b -= 53 # Track number of steps required (optional). steps = 0 while True: steps += 1 c = num//b if c < 2**52: b //= 2 elif c >= 2**53: b *= 2 else: break return (num, b, steps-1) ``` **bigcomp** Bigcomp is the canonical string-to-float parser, which creates an exact representation of `b+h` as a big integer, and compares the theoretical digits from `b+h` scaled into the range `[1, 10)` by a power of 10 to the actual digits in the input string (a more in-depth description can be found [here](https://www.exploringbinary.com/bigcomp-deciding-truncated-near-halfway-conversions/)). A maximum of 768 digits need to be compared to determine the correct representation, and the size of the big integers in the ratio does not depend on the number of digits in the input string. Bigcomp is used as a fallback algorithm for lexical-core when the radix feature is enabled, since the radix-representation of a binary float may never terminate if the radix is not divisible by 2. Since bigcomp uses constant memory, it is used as the default algorithm if more than `2^15` digits are passed and the representation is potentially non-terminating. **bhcomp** Bhcomp is a simple, performant algorithm that compared the significant digits to the theoretical significant digits for `b+h`. Simply, the significant digits from the string are parsed, creating a ratio. A ratio is generated for `b+h`, and these two ratios are scaled using the binary and radix exponents. For example, "2.470328e-324" produces a ratio of `2470328/10^329`, while `b+h` produces a binary ratio of `1/2^1075`. We're looking to compare these ratios, so we need to scale them using common factors. Here, we convert this to `(2470328*5^329*2^1075)/10^329` and `(1*5^329*2^1075)/2^1075`, which converts to `2470328*2^746` and `1*5^329`. Our significant digits (real_digits) and `b+h` (bh_digits) therefore start like: ``` real_digits = 91438982... bh_digits = 91438991... ``` Since our real digits are below the theoretical halfway point, we know we need to round-down, meaning our literal value is `b`, or `0.0`. This approach allows us to calculate whether we need to round-up or down with a single comparison step, without any native divisions required. This is the default algorithm lexical-core uses. **Other Optimizations** 1. We remove powers of 2 during exponentiation in bhcomp. 2. We limit the number of parsed digits to the theoretical max number of digits produced by `b+h` (768 for decimal strings), and merely compare any trailing digits to '0'. This provides an upper-bound on the computation cost. 3. We use fast exponentiation and multiplication algorithms to scale the significant digits for comparison. 4. For the fallback bigcomp algorithm, we use a division algorithm optimized for the generation of a single digit from a given radix, by setting the leading bit in the denominator 4 below the most-significant bit (in decimal strings). This requires only 1 native division per digit generated. 4. The individual "limbs" of the big integers are optimized to the architecture we compile on, for example, u32 on x86 and u64 on x86-64, minimizing the number of native operations required. Currently, 64-bit limbs are used on target architectures `aarch64`, `powerpc64`, `mips64`, and `x86_64`. # Known Issues On the ARMVv6 architecture, the stable exponentiation for the fast, incorrect float parser is not fully stable. For example, `1e-300` is correct, while `5e-324` rounds to `0`, leading to "5e-324" being incorrectly parsed as `0`. This does not affect the default, correct float parser, nor ARMVv7 or ARMVv8 (aarch64) architectures. This bug can compound errors in the incorrect parser (feature-gated by disabling the `correct` feature`). It is not known if this bug is an artifact of Qemu emulation of ARMv6, or is actually representative the hardware. Versions of lexical-core prior to 0.4.3 could round parsed floating-point numbers with an error of up to 1 ULP. This occurred for strings with 16 or more digits and a trailing 0 in the fraction, the `b+h` comparison in the slow-path algorithm incorrectly scales the the theoretical digits due to an over-calculated real exponent. This affects a very small percentage of inputs, however, it is recommended to update immediately. # Versioning and Version Support **Version Support** The currently supported versions are: - v0.7.x - v0.6.x (Maintenace) **Rustc Compatibility** v0.7.x supports 1.37+, including stable, beta, and nightly. v0.6.x supports Rustc 1.24+, including stable, beta, and nightly. Please report any errors compiling a supported lexical-core version on a compatible Rustc version. **Versioning** Lexical-core uses [semantic versioning](https://semver.org/). Removing support for Rustc versions newer than the latest stable Debian or Ubuntu version is considered an incompatible API change, requiring a major version change. # Changelog All changes since 0.4.1 are documented in [CHANGELOG](CHANGELOG). # License Lexical-core is dual licensed under the Apache 2.0 license as well as the MIT license. See the LICENCE-MIT and the LICENCE-APACHE files for the licenses. Lexical-core also ports some code from [rust](https://github.com/rust-lang/rust) (for backwards compatibility), [V8](https://github.com/v8/v8), [libgo](https://golang.org/src) and [fpconv](https://github.com/night-shift/fpconv), and therefore might be subject to the terms of a 3-clause BSD license or BSD-like license. # Contributing Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in lexical by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. lexical-core-0.7.6/build.rs000075500000000000000000000014120000000000000136300ustar 00000000000000fn main() { // TARGET // ------ // We need to optimize limb size for performance. // Only have optimized 64-bit instructions on certain architectures. // See `lexical-core/src/atof/algorithm/math.rs` for detailed // instructions of architecture instruction support for 64-bit // mathematical operations. // https://github.com/rust-lang/cargo/issues/4302#issuecomment-316482399 let limb_64_archs = ["aarch64", "mips64", "powerpc64", "x86_64"]; let limb_width_64 = match std::env::var("CARGO_CFG_TARGET_ARCH") { Ok(arch) => limb_64_archs.contains(&&*arch), _ => false, }; if limb_width_64 { println!("cargo:rustc-cfg=limb_width_64"); } else { println!("cargo:rustc-cfg=limb_width_32"); } } lexical-core-0.7.6/src/atof/algorithm/alias.rs000075500000000000000000000040030000000000000173270ustar 00000000000000//! Aliases and traits to simplify float-parsing. use crate::float::*; use crate::util::*; use super::bignum::ToBigfloat; use super::errors::FloatErrors; // TRAITS /// Trait to simplify type signatures for atof. pub(super) trait FloatType: FloatRounding + FloatRounding + StablePower { type Mantissa: Mantissa; type ExtendedFloat: ExtendedFloatType; } impl FloatType for f32 { type Mantissa = Self::Unsigned; type ExtendedFloat = ExtendedFloat; } impl FloatType for f64 { type Mantissa = Self::Unsigned; type ExtendedFloat = ExtendedFloat; } /// Trait for a useable mantissa. pub(super) trait MantissaType: Mantissa + FloatErrors {} impl MantissaType for u64 { } impl MantissaType for u128 { } /// Trait for extended-float types. pub(super) trait ExtendedFloatType: ToBigfloat + From { // I really wish I had any other choice **other** than getters and setters, // but since we can't specify fields in traits, and we can't use properties... // C'est la vie. fn mant(&self) -> F::Mantissa; fn exp(&self) -> i32; fn set_mant(&mut self, mant: F::Mantissa); fn set_exp(&mut self, exp: i32); } impl ExtendedFloatType for ExtendedFloat { perftools_inline!{ fn mant(&self) -> u32 { self.mant }} perftools_inline!{ fn exp(&self) -> i32 { self.exp }} perftools_inline!{ fn set_mant(&mut self, mant: u32) { self.mant = mant; }} perftools_inline!{ fn set_exp(&mut self, exp: i32) { self.exp = exp; }} } impl ExtendedFloatType for ExtendedFloat { perftools_inline!{ fn mant(&self) -> u64 { self.mant }} perftools_inline!{ fn exp(&self) -> i32 { self.exp }} perftools_inline!{ fn set_mant(&mut self, mant: u64) { self.mant = mant; }} perftools_inline!{ fn set_exp(&mut self, exp: i32) { self.exp = exp; }} } lexical-core-0.7.6/src/atof/algorithm/bhcomp.rs000075500000000000000000000321040000000000000175110ustar 00000000000000//! Compare the mantissa to the halfway representation of the float. //! //! Compares the actual significant digits of the mantissa to the //! theoretical digits from `b+h`, scaled into the proper range. use crate::float::*; use crate::float::convert::*; use crate::float::rounding::*; use crate::util::*; use super::alias::*; use super::bigcomp; use super::bignum::*; use super::format::*; use super::math::*; // Export a character to digit. macro_rules! to_digit { ($c:expr, $radix:ident) => (($c as char).to_digit($radix)); } // PARSE MANTISSA /// Iteratively add small digits to the mantissa and increment the counter. macro_rules! add_digits { ( $iter:expr, $result:ident, $value:ident, $i:ident, $counter:ident, $step:ident, $small_powers:ident, $base:ident, $radix:ident, $max_digits:ident ) => { while let Some(&digit) = $iter.next() { // We've parsed the max digits using small values, add to bignum if $counter == $step { $result.imul_small($small_powers[$counter]); $result.iadd_small($value); $counter = 0; $value = 0; } $value *= $base; $value += as_limb(to_digit!(digit, $radix).unwrap()); // Check if we've parsed all our possible digits. $i += 1; $counter += 1; if $i == $max_digits { break; } } }; } /// Parse the full mantissa into a big integer. /// /// Max digits is the maximum number of digits plus one. pub(super) fn parse_mantissa<'a, Data>(data: Data, radix: u32, max_digits: usize) -> Bigint where Data: SlowDataInterface<'a> { let small_powers = Bigint::small_powers(radix); let count = data.mantissa_digits(); let bits = count / integral_binary_factor(radix).as_usize(); let bytes = bits / ::BITS; // Main loop let step = small_powers.len() - 2; let base = as_limb(radix); let max_digits = max_digits - 1; let mut counter = 0; let mut value: Limb = 0; let mut i: usize = 0; let mut result = Bigint::default(); result.data.reserve(bytes); // Iteratively process all the data in the mantissa. let mut integer_iter = data.integer_iter(); let mut fraction_iter = data.significant_fraction_iter(); add_digits!(integer_iter, result, value, i, counter, step, small_powers, base, radix, max_digits); if integer_iter.consumed() { // Continue if we haven't already processed the max digits. add_digits!(fraction_iter, result, value, i, counter, step, small_powers, base, radix, max_digits); } // We will always have a remainder, as long as we entered the loop // once, or counter % step is 0. if counter != 0 { result.imul_small(small_powers[counter]); result.iadd_small(value); } // If we have any remaining digits after the last value, we need // to add a 1 after the rest of the array, it doesn't matter where, // just move it up. This is good for the worst-possible float // representation. We also need to return an index. // Since we already trimmed trailing zeros, we know there has // to be a non-zero digit if there are any left. let is_consumed = integer_iter.consumed() && fraction_iter.consumed(); if !is_consumed { result.imul_small(base); result.iadd_small(1); } result } perftools_inline!{ /// Implied method to calculate the number of digits from a 32-bit float. fn max_digits_f32(radix: u32) -> Option { match radix { 6 => Some(103), 10 => Some(114), 12 => Some(117), 14 => Some(119), 18 => Some(122), 20 => Some(123), 22 => Some(123), 24 => Some(124), 26 => Some(125), 28 => Some(125), 30 => Some(126), 34 => Some(127), 36 => Some(127), // Powers of two and odd numbers should be unreachable _ => None, } }} perftools_inline!{ /// Implied method to calculate the number of digits from a 64-bit float. fn max_digits_f64(radix: u32) -> Option { match radix { 6 => Some(682), 10 => Some(769), 12 => Some(792), 14 => Some(808), 18 => Some(832), 20 => Some(840), 22 => Some(848), 24 => Some(854), 26 => Some(859), 28 => Some(864), 30 => Some(868), 34 => Some(876), 36 => Some(879), // Powers of two and odd numbers should be unreachable _ => None, } }} perftools_inline!{ /// Calculate the maximum number of digits possible in the mantissa. /// /// Returns the maximum number of digits plus one. /// /// We can exactly represent a float in radix `b` from radix 2 if /// `b` is divisible by 2. This function calculates the exact number of /// digits required to exactly represent that float. /// /// According to the "Handbook of Floating Point Arithmetic", /// for IEEE754, with emin being the min exponent, p2 being the /// precision, and b being the radix, the number of digits follows as: /// /// `−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋` /// /// For f32, this follows as: /// emin = -126 /// p2 = 24 /// /// For f64, this follows as: /// emin = -1022 /// p2 = 53 /// /// In Python: /// `-emin + p2 + math.floor((emin+1)*math.log(2, b) - math.log(1-2**(-p2), b))` /// /// This was used to calculate the maximum number of digits for [2, 36]. pub(super) fn max_digits(radix: u32) -> Option where F: Float { match F::BITS { 32 => max_digits_f32(radix), 64 => max_digits_f64(radix), _ => unreachable!(), } }} // ROUNDING /// Custom rounding for round-nearest algorithms. macro_rules! nearest_cb { ($m:tt, $is_truncated:ident, $cb:ident) => { // Create our wrapper for round_nearest_tie_*. // If there are truncated bits, and we are exactly halfway, // then we need to set above to true and halfway to false. move | f: &mut ExtendedFloat<$m>, shift: i32 | { let (mut is_above, mut is_halfway) = round_nearest(f, shift); if is_halfway && $is_truncated { is_above = true; is_halfway = false; } $cb::<$m>(f, is_above, is_halfway); } }; } /// Custom rounding for round-toward algorithms. #[cfg(feature = "rounding")] macro_rules! toward_cb { ($m:tt, $is_truncated:ident, $cb:ident) => { // Create our wrapper for round_towards_tie_*. // If there are truncated bits, and truncated is not set, set it. move | f: &mut ExtendedFloat<$m>, shift: i32 | { let truncated = round_toward(f, shift); $cb::<$m>(f, $is_truncated | truncated); } }; } perftools_inline!{ /// Custom rounding for truncated mantissa. /// /// Respect rounding rules in the config file. #[allow(unused_variables)] pub(super) fn round_to_native(fp: &mut ExtendedFloat80, is_truncated: bool, kind: RoundingKind) where F: FloatType { type M = u64; // Define a simplified function, since we can't store the callback to // a variable without `impl Trait`, which requires 1.26.0. #[inline(always)] fn round(fp: &mut ExtendedFloat80, cb: Cb) where F: FloatRounding, Cb: FnOnce(&mut ExtendedFloat, i32) { fp.round_to_native::(cb); } #[cfg(feature = "rounding")] match kind { RoundingKind::NearestTieEven => round::(fp, nearest_cb!(M, is_truncated, tie_even)), RoundingKind::NearestTieAwayZero => round::(fp, nearest_cb!(M, is_truncated, tie_away_zero)), RoundingKind::Upward => round::(fp, toward_cb!(M, is_truncated, upward)), RoundingKind::Downward => round::(fp, toward_cb!(M, is_truncated, downard)), _ => unreachable!(), }; #[cfg(not(feature = "rounding"))] round::(fp, nearest_cb!(M, is_truncated, tie_even)); }} /// BIGCOMP PATH /// Maximum number of digits before reverting to bigcomp. const LARGE_POWER_MAX: usize = 1 << 15; perftools_inline!{ /// Check if we need to use bigcomp. pub(super) fn use_bigcomp(radix: u32, count: usize) -> bool { // When we have extremely large values, it makes a lot more sense to // use am algorithm that scales linearly with input size. We // only precompute exponent up to 2^15 anyway for a given radix, so // use it. If the radix is not odd, we know the finite number of digits // for the worst-case representation, so we can create a valid ratio // and ignore the remaining digits. radix.is_odd() && count > LARGE_POWER_MAX }} /// Calculate the mantissa for a big integer with a positive exponent. pub(super) fn large_atof<'a, F, Data>(data: Data, radix: u32, max_digits: usize, exponent: i32, kind: RoundingKind) -> F where F: FloatType, Data: SlowDataInterface<'a> { // Simple, we just need to multiply by the power of the radix. // Now, we can calculate the mantissa and the exponent from this. // The binary exponent is the binary exponent for the mantissa // shifted to the hidden bit. let mut bigmant = parse_mantissa(data, radix, max_digits); bigmant.imul_power(radix, exponent.as_u32()); // Get the exact representation of the float from the big integer. let (mant, is_truncated) = bigmant.hi64(); let exp = bigmant.bit_length().as_i32() - ::BITS.as_i32(); let mut fp = ExtendedFloat { mant: mant, exp: exp }; round_to_native::(&mut fp, is_truncated, kind); into_float(fp) } // BHCOMP /// Calculate the mantissa for a big integer with a negative exponent. /// /// This invokes the comparison with `b+h`. pub(super) fn small_atof<'a, F, Data>(data: Data, radix: u32, max_digits: usize, exponent: i32, f: F, kind: RoundingKind) -> F where F: FloatType, Data: SlowDataInterface<'a> { // Get the significant digits and radix exponent for the real digits. let mut real_digits = parse_mantissa(data, radix, max_digits); let real_exp = exponent; debug_assert!(real_exp < 0); // Get the significant digits and the binary exponent for `b+h`. let theor = bigcomp::theoretical_float(f, kind); let mut theor_digits = Bigint::from_u64(theor.mant().as_u64()); let theor_exp = theor.exp(); // We need to scale the real digits and `b+h` digits to be the same // order. We currently have `real_exp`, in `radix`, that needs to be // shifted to `theor_digits` (since it is negative), and `theor_exp` // to either `theor_digits` or `real_digits` as a power of 2 (since it // may be positive or negative). Try to remove as many powers of 2 // as possible. All values are relative to `theor_digits`, that is, // reflect the power you need to multiply `theor_digits` by. let (binary_exp, halfradix_exp, radix_exp) = match radix.is_even() { // Can remove a power-of-two. // Both are on opposite-sides of equation, can factor out a // power of two. // // Example: 10^-10, 2^-10 -> ( 0, 10, 0) // Example: 10^-10, 2^-15 -> (-5, 10, 0) // Example: 10^-10, 2^-5 -> ( 5, 10, 0) // Example: 10^-10, 2^5 -> (15, 10, 0) true => (theor_exp - real_exp, -real_exp, 0), // Cannot remove a power-of-two. false => (theor_exp, 0, -real_exp), }; // Carry out our multiplication. if halfradix_exp != 0 { theor_digits.imul_power(radix / 2, halfradix_exp.as_u32()); } if radix_exp != 0 { theor_digits.imul_power(radix, radix_exp.as_u32()); } if binary_exp > 0 { theor_digits.imul_power(2, binary_exp.as_u32()); } else if binary_exp < 0 { real_digits.imul_power(2, (-binary_exp).as_u32()); } bigcomp::round_to_native(f, real_digits.compare(&theor_digits), kind) } /// Calculate the exact value of the float. /// /// Notes: /// The digits iterator must not have any trailing zeros (true for /// `FloatState2`). /// sci_exponent and digits.size_hint() must not overflow i32. pub(super) fn atof<'a, F, Data>(data: Data, radix: u32, f: F, kind: RoundingKind) -> F where F: FloatType, Data: SlowDataInterface<'a> { // We have a finite conversions number of digits for base10. // In order for a float in radix `b` with a finite number of digits // to have a finite representation in radix `y`, `b` should divide // an integer power of `y`. This means for binary, all even radixes // have finite representations, and all odd ones do not. let max_digits = unwrap_or_max(max_digits::(radix)); let count = max_digits.min(data.mantissa_digits()); let exponent = data.scientific_exponent() + 1 - count.as_i32(); if cfg!(feature = "radix") && use_bigcomp(radix, count) { // Use the slower algorithm for giant data, since we use a lot less memory. bigcomp::atof(data, radix, f, kind) } else if exponent >= 0 { large_atof(data, radix, max_digits, exponent, kind) } else { small_atof(data, radix, max_digits, exponent, f, kind) } } lexical-core-0.7.6/src/atof/algorithm/bigcomp.rs000075500000000000000000000556100000000000000176700ustar 00000000000000//! An implementation of bigcomp for Rust. //! //! Compares the known string to theoretical digits generated on the //! fly for `b+h`, where a string representation of a float is between //! `b` and `b+u`, where `b+u` is 1 unit in the least-precision. Therefore, //! the string must be close to `b+h`. //! //! Adapted from: //! https://www.exploringbinary.com/bigcomp-deciding-truncated-near-halfway-conversions/ use crate::lib::cmp; use crate::util::*; use super::alias::*; use super::bignum::*; use super::format::*; use super::math::*; // ROUNDING /// Custom rounding for the ratio. #[allow(unused_variables)] pub(super) fn round_to_native(f: F, order: cmp::Ordering, kind: RoundingKind) -> F where F: FloatType { #[cfg(not(feature = "rounding"))] { match order { cmp::Ordering::Greater => f.next_positive(), cmp::Ordering::Less => f, cmp::Ordering::Equal => f.round_positive_even(), } } // Compare the actual digits to the round-down or halfway point. #[cfg(feature = "rounding")] { match order { cmp::Ordering::Greater => match kind { // Comparison with `b+h`, above. Round-up. RoundingKind::NearestTieEven => f.next_positive(), RoundingKind::NearestTieAwayZero => f.next_positive(), // Comparison with `b`, above. Truncated digits. RoundingKind::Upward => f.next_positive(), RoundingKind::Downward => f, _ => unimplemented!(), }, // This cannot happen for RoundingKind Upward or Downward. // For round-nearest algorithms, we are below `b+h` so round-down. cmp::Ordering::Less => match kind { // Comparison with `b+h`, below. Stay put. RoundingKind::NearestTieEven => f, RoundingKind::NearestTieAwayZero => f, // Comparison with `b`, below. Truncated digits, but below our // estimate `b`. RoundingKind::Upward => f, RoundingKind::Downward => f.prev_positive(), _ => unimplemented!(), }, cmp::Ordering::Equal => match kind { // Only round-up if the mantissa is odd. RoundingKind::NearestTieEven => f.round_positive_even(), // Always round-up, we want to go away from 0. RoundingKind::NearestTieAwayZero => f.next_positive(), // Comparison with `b`, equal. No truncated digits. RoundingKind::Upward => f, RoundingKind::Downward => f, _ => unimplemented!(), }, } } } // SHARED perftools_inline!{ /// Calculate `b` from a a representation of `b` as a float. pub(super) fn b(f: F) -> F::ExtendedFloat { f.into() }} perftools_inline!{ /// Calculate `b+h` from a a representation of `b` as a float. pub(super) fn bh(f: F) -> F::ExtendedFloat { // None of these can overflow. let mut b = b(f); let mant = (b.mant() << 1) + as_cast(1); let exp = b.exp() - 1; b.set_mant(mant); b.set_exp(exp); b }} perftools_inline!{ /// Generate the theoretical float type for the rounding kind. #[allow(unused_variables)] pub(super) fn theoretical_float(f: F, kind: RoundingKind) -> F::ExtendedFloat where F: FloatType { #[cfg(not(feature = "rounding"))] { bh(f) } #[cfg(feature = "rounding")] { match is_nearest(kind) { // We need to check if we're close to halfway, so use `b+h`. true => bh(f), // Just care if there are any truncated digits, use `b`. false => b(f), } } }} // BIGCOMP perftools_inline!{ /// Get the appropriate scaling factor from the digit count. /// /// * `radix` - Radix for the number parsing. /// * `sci_exponent` - Exponent of basen string in scientific notation. pub fn scaling_factor(radix: u32, sci_exponent: u32) -> Bigfloat { let mut factor = Bigfloat { data: arrvec![1], exp: 0 }; factor.imul_power(radix, sci_exponent); factor }} /// Make a ratio for the numerator and denominator. /// /// * `radix` - Radix for the number parsing. /// * `sci_exponent` - Exponent of basen string in scientific notation. /// * `f` - Sub-halfway (`b`) float. pub(super) fn make_ratio(radix: u32, sci_exponent: i32, f: F, kind: RoundingKind) -> (Bigfloat, Bigfloat) where F: FloatType { let theor = theoretical_float(f, kind).to_bigfloat(); let factor = scaling_factor(radix, sci_exponent.abs().as_u32()); let mut num: Bigfloat; let mut den: Bigfloat; if sci_exponent < 0 { // Need to have the basen factor be the numerator, and the fp // be the denominator. Since we assumed that theor was the numerator, // if it's the denominator, we need to multiply it into the numerator. num = factor; num.imul_large(&theor); den = Bigfloat { data: arrvec![1], exp: -theor.exp }; } else { num = theor; den = factor; } // Scale the denominator so it has the number of bits // in the radix as the number of leading zeros. let wlz = integral_binary_factor(radix).as_usize(); let nlz = den.leading_zeros().wrapping_sub(wlz) & (::BITS - 1); small::ishl_bits(den.data_mut(), nlz); den.exp -= nlz.as_i32(); // Need to scale the numerator or denominator to the same value. // We don't want to shift the denominator, so... let diff = den.exp - num.exp; let shift = diff.abs().as_usize(); if diff < 0 { // Need to shift the numerator left. small::ishl(num.data_mut(), shift); num.exp -= shift.as_i32() } else if diff > 0 { // Need to shift denominator left, go by a power of ::BITS. // After this, the numerator will be non-normalized, and the // denominator will be normalized. // We need to add one to the quotient,since we're calculating the // ceiling of the divmod. let (q, r) = shift.ceil_divmod(::BITS); // Since we're using a power from the denominator to the // numerator, we to invert r, not add u32::BITS. let r = -r; small::ishl_bits(num.data_mut(), r.as_usize()); num.exp -= r; if !q.is_zero() { den.pad_zero_digits(q); den.exp -= ::BITS.as_i32() * q.as_i32(); } } (num, den) } // Compare digits in BigFloat with a given iterator. macro_rules! compare_digits { ($iter:ident, $radix:ident, $num:ident, $den:ident) => { while !$num.data.is_empty() { let actual = match $iter.next() { Some(&v) => v, None => return cmp::Ordering::Less, }; let expected = digit_to_char($num.quorem(&$den)); $num.imul_small($radix); if actual < expected { return cmp::Ordering::Less; } else if actual > expected { return cmp::Ordering::Greater; } } }; } /// Compare digits between the generated values the ratio and the actual view. /// /// * `integer` - Digits from the integer component of the mantissa. /// * `fraction` - Digits from the fraction component of the mantissa. /// * `radix` - Radix for the number parsing. /// * `num` - Numerator for the fraction. /// * `denm` - Denominator for the fraction. pub(super) fn compare_digits<'a, Iter1, Iter2>( integer: Iter1, fraction: Iter2, radix: u32, mut num: Bigfloat, den: Bigfloat ) -> cmp::Ordering where Iter1: Iterator, Iter2: Iterator { // Iterate until we get a difference in the generated digits. // If we run out,return Equal. let radix = as_limb(radix); let mut iter = integer.chain(fraction); compare_digits!(iter, radix, num, den); // We cannot have any trailing zeros, so if there any remaining digits, // we're >= to the value. We've already exhausted num.data here, // so need to check if integer and fraction don't have data. let is_none = iter.next().is_none(); match is_none { true => cmp::Ordering::Equal, false => cmp::Ordering::Greater, } } /// Generate the correct representation from a halfway representation. /// /// The digits iterator must not have any trailing zeros (true for /// `SlowDataInterface`). /// /// * `digits` - Actual digits from the mantissa. /// * `radix` - Radix for the number parsing. /// * `sci_exponent` - Exponent of basen string in scientific notation. /// * `f` - Sub-halfway (`b`) float. pub(super) fn atof<'a, F, Data>(data: Data, radix: u32, f: F, kind: RoundingKind) -> F where F: FloatType, Data: SlowDataInterface<'a> { // This works when we're doing, like, round-even. let (num, den) = make_ratio(radix, data.scientific_exponent(), f, kind); let integer_iter = data.integer_iter(); let fraction_iter = data.significant_fraction_iter(); let order = compare_digits(integer_iter, fraction_iter, radix, num, den); round_to_native(f, order, kind) } // TESTS // ----- #[cfg(test)] mod tests { use crate::util::test::*; use super::*; #[test] fn b_test() { assert_eq!(b(1e-45_f32), (1, -149).into()); assert_eq!(b(5e-324_f64), (1, -1074).into()); assert_eq!(b(1e-323_f64), (2, -1074).into()); assert_eq!(b(2e-323_f64), (4, -1074).into()); assert_eq!(b(3e-323_f64), (6, -1074).into()); assert_eq!(b(4e-323_f64), (8, -1074).into()); assert_eq!(b(5e-323_f64), (10, -1074).into()); assert_eq!(b(6e-323_f64), (12, -1074).into()); assert_eq!(b(7e-323_f64), (14, -1074).into()); assert_eq!(b(8e-323_f64), (16, -1074).into()); assert_eq!(b(9e-323_f64), (18, -1074).into()); assert_eq!(b(1_f32), (8388608, -23).into()); assert_eq!(b(1_f64), (4503599627370496, -52).into()); assert_eq!(b(1e38_f32), (9860761, 103).into()); assert_eq!(b(1e308_f64), (5010420900022432, 971).into()); } #[test] fn bh_test() { assert_eq!(bh(1e-45_f32), (3, -150).into()); assert_eq!(bh(5e-324_f64), (3, -1075).into()); assert_eq!(bh(1_f32), (16777217, -24).into()); assert_eq!(bh(1_f64), (9007199254740993, -53).into()); assert_eq!(bh(1e38_f32), (19721523, 102).into()); assert_eq!(bh(1e308_f64), (10020841800044865, 970).into()); } // SLOW PATH #[test] fn scaling_factor_test() { assert_eq!(scaling_factor(10, 0), Bigfloat { data: deduce_from_u32(&[1]), exp: 0 }); assert_eq!(scaling_factor(10, 20), Bigfloat { data: deduce_from_u32(&[1977800241, 22204]), exp: 20 }); assert_eq!(scaling_factor(10, 300), Bigfloat { data: deduce_from_u32(&[2502905297, 773182544, 1122691908, 922368819, 2799959258, 2138784391, 2365897751, 2382789932, 3061508751, 1799019667, 3501640837, 269048281, 2748691596, 1866771432, 2228563347, 475471294, 278892994, 2258936920, 3352132269, 1505791508, 2147965370, 25052104]), exp: 300 }); } #[test] fn make_ratio_test() { let (num1, den1) = make_ratio(10, -324, 0f64, RoundingKind::NearestTieEven); let (num2, den2) = make_ratio(10, -324, 5e-324f64, RoundingKind::NearestTieEven); let (num3, den3) = make_ratio(10, 307, 8.98846567431158e+307f64, RoundingKind::NearestTieEven); #[cfg(limb_width_32)] { assert_eq!(num1, Bigfloat { data: arrvec![1725370368, 1252154597, 1017462556, 675087593, 2805901938, 1401824593, 1124332496, 2380663002, 1612846757, 4128923878, 1492915356, 437569744, 2975325085, 3331531962, 3367627909, 730662168, 2699172281, 1440714968, 2778340312, 690527038, 1297115354, 763425880, 1453089653, 331561842], exp: 312 }); assert_eq!(den1, Bigfloat { data: arrvec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134217728], exp: 312 }); assert_eq!(num2, Bigfloat { data: arrvec![881143808, 3756463792, 3052387668, 2025262779, 4122738518, 4205473780, 3372997488, 2847021710, 543572976, 3796837043, 183778774, 1312709233, 336040663, 1404661296, 1512949137, 2191986506, 3802549547, 27177609, 4040053641, 2071581115, 3891346062, 2290277640, 64301663, 994685527], exp: 312 }); assert_eq!(den2, Bigfloat { data: arrvec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134217728], exp: 312 }); assert_eq!(num3, Bigfloat { data: arrvec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1024, 2147483648], exp: 288 }); assert_eq!(den3, Bigfloat { data: arrvec![1978138624, 2671552565, 2938166866, 3588566204, 1860064291, 2104472219, 2014975858, 2797301608, 462262832, 318515330, 1101517094, 1738264167, 3721375114, 414401884, 1406861075, 3053102637, 387329537, 2051556775, 1867945454, 3717689914, 1434550525, 1446648206, 238915486], exp: 288 }); } #[cfg(limb_width_64)] { assert_eq!(num1, Bigfloat { data: arrvec![7410409304047484928, 4369968404176723173, 12051257060168107241, 4828971301551875409, 6927124077155322074, 6412022633845121254, 12778923935480989904, 14463851737583396026, 11592856673895384344, 11932880778639151320, 5571068025259989822, 6240972538554414168, 331561842], exp: 280 }); assert_eq!(den1, Bigfloat { data: arrvec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134217728], exp: 280 }); assert_eq!(num2, Bigfloat { data: arrvec![3784483838432903168, 13109905212530169520, 17707027106794770107, 14486913904655626228, 2334628157756414606, 789323827825812147, 1443283659023866481, 6498067065331084848, 16331825947976601418, 17351898262207902345, 16713204075779969467, 276173541953690888, 994685527], exp: 280 }); assert_eq!(den2, Bigfloat { data: arrvec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134217728], exp: 280 }); assert_eq!(num3, Bigfloat { data: arrvec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4398046511104, 2147483648], exp: 288 }); assert_eq!(den3, Bigfloat { data: arrvec![11474230898198052864, 15412774488649031250, 9038639357805614115, 12014318925423187826, 1368012926086910512, 7465787750175199526, 1779842542902160778, 13112975978653220627, 8811369254899559937, 15967356599166997998, 6213306735021621501, 238915486], exp: 288 }); } } #[test] fn compare_digits_test() { // 2^-1074 let num = Bigfloat { data: deduce_from_u32(&[1725370368, 1252154597, 1017462556, 675087593, 2805901938, 1401824593, 1124332496, 2380663002, 1612846757, 4128923878, 1492915356, 437569744, 2975325085, 3331531962, 3367627909, 730662168, 2699172281, 1440714968, 2778340312, 690527038, 1297115354, 763425880, 1453089653, 331561842]), exp: 312 }; let den = Bigfloat { data: deduce_from_u32(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134217728]), exp: 312 }; // Below halfway let digits = b"24703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328124999"; let empty = b""; assert_eq!(compare_digits(digits.iter(), empty.iter(), 10, num.clone(), den.clone()), cmp::Ordering::Less); // Exactly halfway. let digits = b"24703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125"; assert_eq!(compare_digits(digits.iter(), empty.iter(), 10, num.clone(), den.clone()), cmp::Ordering::Equal); // Above halfway. let digits = b"24703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125001"; assert_eq!(compare_digits(digits.iter(), empty.iter(), 10, num.clone(), den.clone()), cmp::Ordering::Greater); // 2*2^-1074 let num = Bigfloat { data: deduce_from_u32(&[881143808, 3756463792, 3052387668, 2025262779, 4122738518, 4205473780, 3372997488, 2847021710, 543572976, 3796837043, 183778774, 1312709233, 336040663, 1404661296, 1512949137, 2191986506, 3802549547, 27177609, 4040053641, 2071581115, 3891346062, 2290277640, 64301663, 994685527]), exp: 312 }; let den = Bigfloat { data: deduce_from_u32(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134217728]), exp: 312 }; // Below halfway let digits = b"74109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984374999"; assert_eq!(compare_digits(digits.iter(), empty.iter(), 10, num.clone(), den.clone()), cmp::Ordering::Less); // Exactly halfway. let digits = b"74109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375"; assert_eq!(compare_digits(digits.iter(), empty.iter(), 10, num.clone(), den.clone()), cmp::Ordering::Equal); // Above halfway. let digits = b"74109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375001"; assert_eq!(compare_digits(digits.iter(), empty.iter(), 10, num.clone(), den.clone()), cmp::Ordering::Greater); // 4503599627370496*2^971 let num = Bigfloat { data: deduce_from_u32(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1024, 2147483648]), exp: 288 }; let den = Bigfloat { data: deduce_from_u32(&[1978138624, 2671552565, 2938166866, 3588566204, 1860064291, 2104472219, 2014975858, 2797301608, 462262832, 318515330, 1101517094, 1738264167, 3721375114, 414401884, 1406861075, 3053102637, 387329537, 2051556775, 1867945454, 3717689914, 1434550525, 1446648206, 238915486]), exp: 288 }; // Below halfway let digits = b"89884656743115805365666807213050294962762414131308158973971342756154045415486693752413698006024096935349884403114202125541629105369684531108613657287705365884742938136589844238179474556051429647415148697857438797685859063890851407391008830874765563025951597582513936655578157348020066364210154316532161708031999"; assert_eq!(compare_digits(digits.iter(), empty.iter(), 10, num.clone(), den.clone()), cmp::Ordering::Less); // Exactly halfway. let digits = b"89884656743115805365666807213050294962762414131308158973971342756154045415486693752413698006024096935349884403114202125541629105369684531108613657287705365884742938136589844238179474556051429647415148697857438797685859063890851407391008830874765563025951597582513936655578157348020066364210154316532161708032"; assert_eq!(compare_digits(digits.iter(), empty.iter(), 10, num.clone(), den.clone()), cmp::Ordering::Equal); // Above halfway. let digits = b"89884656743115805365666807213050294962762414131308158973971342756154045415486693752413698006024096935349884403114202125541629105369684531108613657287705365884742938136589844238179474556051429648741514697857438797685859063890851407391008830874765563025951597582513936655578157348020066364210154316532161708032001"; assert_eq!(compare_digits(digits.iter(), empty.iter(), 10, num.clone(), den.clone()), cmp::Ordering::Greater); } } lexical-core-0.7.6/src/atof/algorithm/bignum.rs000075500000000000000000000123000000000000000175160ustar 00000000000000//! Big integer type definition. use crate::float::*; use crate::util::*; use super::math::*; // DATA TYPE cfg_if! { if #[cfg(feature = "radix")] { use crate::lib::Vec; type IntStorageType = Vec; } else { // Maximum denominator is 767 mantissa digits + 324 exponent, // or 1091 digits, or approximately 3600 bits (round up to 4k). #[cfg(limb_width_32)] type IntStorageType = arrayvec::ArrayVec<[Limb; 128]>; #[cfg(limb_width_64)] type IntStorageType = arrayvec::ArrayVec<[Limb; 64]>; }} // cfg_if perftools_inline!{ /// Calculate the integral ceiling of the binary factor from a basen number. pub(super) fn integral_binary_factor(radix: u32) -> u32 { debug_assert_radix!(radix); #[cfg(not(feature = "radix"))] { 4 } #[cfg(feature = "radix")] { match radix.as_i32() { 2 => 1, 3 => 2, 4 => 2, 5 => 3, 6 => 3, 7 => 3, 8 => 3, 9 => 4, 10 => 4, 11 => 4, 12 => 4, 13 => 4, 14 => 4, 15 => 4, 16 => 4, 17 => 5, 18 => 5, 19 => 5, 20 => 5, 21 => 5, 22 => 5, 23 => 5, 24 => 5, 25 => 5, 26 => 5, 27 => 5, 28 => 5, 29 => 5, 30 => 5, 31 => 5, 32 => 5, 33 => 6, 34 => 6, 35 => 6, 36 => 6, // Invalid radix _ => unreachable!(), } } }} // BIGINT /// Storage for a big integer type. #[derive(Clone, PartialEq, Eq)] #[cfg_attr(test, derive(Debug))] pub(crate) struct Bigint { /// Internal storage for the Bigint, in little-endian order. pub(crate) data: IntStorageType, } impl Default for Bigint { fn default() -> Self { // We want to avoid lower-order let mut bigint = Bigint { data: IntStorageType::default() }; bigint.data.reserve(20); bigint } } impl SharedOps for Bigint { type StorageType = IntStorageType; perftools_inline_always!{ fn data<'a>(&'a self) -> &'a Self::StorageType { &self.data }} perftools_inline_always!{ fn data_mut<'a>(&'a mut self) -> &'a mut Self::StorageType { &mut self.data }} } impl SmallOps for Bigint { } impl LargeOps for Bigint { } // BIGFLOAT // Adjust the storage capacity for the underlying array. cfg_if! { if #[cfg(limb_width_64)] { type FloatStorageType = arrayvec::ArrayVec<[Limb; 20]>; } else { type FloatStorageType = arrayvec::ArrayVec<[Limb; 36]>; }} // cfg_if /// Storage for a big floating-point type. #[derive(Clone, PartialEq, Eq)] #[cfg_attr(test, derive(Debug))] pub struct Bigfloat { /// Internal storage for the Bigint, in little-endian order. /// /// Enough storage for up to 10^345, which is 2^1146, or more than /// the max for f64. pub(crate) data: FloatStorageType, /// It also makes sense to store an exponent, since this simplifies /// normalizing and powers of 2. pub(crate) exp: i32, } impl Default for Bigfloat { perftools_inline!{ fn default() -> Self { // We want to avoid lower-order let mut bigfloat = Bigfloat { data: FloatStorageType::default(), exp: 0 }; bigfloat.data.reserve(10); bigfloat }} } impl SharedOps for Bigfloat { type StorageType = FloatStorageType; perftools_inline_always!{ fn data<'a>(&'a self) -> &'a Self::StorageType { &self.data }} perftools_inline_always!{ fn data_mut<'a>(&'a mut self) -> &'a mut Self::StorageType { &mut self.data }} } impl SmallOps for Bigfloat { perftools_inline!{ fn imul_pow2(&mut self, n: u32) { // Increment exponent to simulate actual multiplication. self.exp += n.as_i32(); }} } impl LargeOps for Bigfloat { } // TO BIGFLOAT /// Simple overloads to allow conversions of extended floats to big integers. pub trait ToBigfloat { fn to_bigfloat(&self) -> Bigfloat; } impl ToBigfloat for ExtendedFloat { perftools_inline!{ fn to_bigfloat(&self) -> Bigfloat { let mut bigfloat = Bigfloat::from_u32(self.mant); bigfloat.exp = self.exp; bigfloat }} } impl ToBigfloat for ExtendedFloat { perftools_inline!{ fn to_bigfloat(&self) -> Bigfloat { let mut bigfloat = Bigfloat::from_u64(self.mant); bigfloat.exp = self.exp; bigfloat }} } impl ToBigfloat for ExtendedFloat { perftools_inline!{ fn to_bigfloat(&self) -> Bigfloat { let mut bigfloat = Bigfloat::from_u128(self.mant); bigfloat.exp = self.exp; bigfloat }} } // TESTS // ----- #[cfg(all(test, feature = "correct", feature = "radix"))] mod test { use super::*; #[test] fn integral_binary_factor_test() { const TABLE: [u32; 35] = [1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6]; for (idx, base) in (2..37).enumerate() { assert_eq!(integral_binary_factor(base), TABLE[idx]); } } } lexical-core-0.7.6/src/atof/algorithm/cached.rs000075500000000000000000000047600000000000000174570ustar 00000000000000//! Cached powers trait for extended-precision floats. use crate::float::{ExtendedFloat, Mantissa}; use super::cached_float80; use super::cached_float160; // POWERS /// Precalculated powers that uses two-separate arrays for memory-efficiency. #[doc(hidden)] pub(crate) struct ExtendedFloatArray { // Pre-calculated mantissa for the powers. pub mant: &'static [M], // Pre-calculated binary exponents for the powers. pub exp: &'static [i32], } /// Allow indexing of values without bounds checking impl ExtendedFloatArray { perftools_inline!{ pub fn get_extended_float(&self, index: usize) -> ExtendedFloat { let mant = self.mant[index]; let exp = self.exp[index]; ExtendedFloat { mant: mant, exp: exp } }} perftools_inline!{ pub fn len(&self) -> usize { self.mant.len() }} } // MODERATE PATH POWERS /// Precalculated powers of base N for the moderate path. #[doc(hidden)] pub(crate) struct ModeratePathPowers { // Pre-calculated small powers. pub small: ExtendedFloatArray, // Pre-calculated large powers. pub large: ExtendedFloatArray, /// Pre-calculated small powers as 64-bit integers pub small_int: &'static [M], // Step between large powers and number of small powers. pub step: i32, // Exponent bias for the large powers. pub bias: i32, } /// Allow indexing of values without bounds checking impl ModeratePathPowers { perftools_inline!{ pub fn get_small(&self, index: usize) -> ExtendedFloat { self.small.get_extended_float(index) }} perftools_inline!{ pub fn get_large(&self, index: usize) -> ExtendedFloat { self.large.get_extended_float(index) }} perftools_inline!{ pub fn get_small_int(&self, index: usize) -> M { self.small_int[index] }} } // CACHED EXTENDED POWERS /// Cached powers as a trait for a floating-point type. pub(super) trait ModeratePathCache { /// Get powers from radix. fn get_powers(radix: u32) -> &'static ModeratePathPowers; } impl ModeratePathCache for ExtendedFloat { perftools_inline!{ fn get_powers(radix: u32) -> &'static ModeratePathPowers { cached_float80::get_powers(radix) }} } impl ModeratePathCache for ExtendedFloat { perftools_inline!{ fn get_powers(radix: u32) -> &'static ModeratePathPowers { cached_float160::get_powers(radix) }} } lexical-core-0.7.6/src/atof/algorithm/cached_float160.rs000075500000000000000000012327540000000000000211020ustar 00000000000000//! Cached exponents for basen values with 160-bit extended floats. //! //! Exact versions of base**n as an extended-precision float, with both //! large and small powers. Use the large powers to minimize the amount //! of compounded error. //! //! These values were calculated using Python, using the arbitrary-precision //! integer to calculate exact extended-representation of each value. //! These values are all normalized. //! //! This files takes ~ 44KB of storage. //! //! This file is mostly automatically generated, do not change values //! manually, unless you know what you are doing. The script to generate //! the values is as follows: //! //! ```text //! import math //! from collections import deque //! //! STEP_STR = "const BASE{0}_STEP: i32 = {1};" //! SMALL_MANTISSA_STR = "const BASE{0}_SMALL_MANTISSA: [u128; {1}] = [" //! SMALL_EXPONENT_STR = "const BASE{0}_SMALL_EXPONENT: [i32; {1}] = [" //! LARGE_MANTISSA_STR = "const BASE{0}_LARGE_MANTISSA: [u128; {1}] = [" //! LARGE_EXPONENT_STR = "const BASE{0}_LARGE_EXPONENT: [i32; {1}] = [" //! SMALL_INT_STR = "const BASE{0}_SMALL_INT_POWERS: [u128; {1}] = {2};" //! BIAS_STR = "const BASE{0}_BIAS: i32 = {1};" //! EXP_STR = "// {}^{}" //! POWER_STR = """pub(crate) const BASE{0}_POWERS: ModeratePathPowers = ModeratePathPowers {{ //! small: ExtendedFloatArray {{ mant: &BASE{0}_SMALL_MANTISSA, exp: &BASE{0}_SMALL_EXPONENT }}, //! large: ExtendedFloatArray {{ mant: &BASE{0}_LARGE_MANTISSA, exp: &BASE{0}_LARGE_EXPONENT }}, //! small_int: &BASE{0}_SMALL_INT_POWERS, //! step: BASE{0}_STEP, //! bias: BASE{0}_BIAS, //! }};\n""" //! //! def calculate_bitshift(base, exponent): //! ''' //! Calculate the bitshift required for a given base. The exponent //! is the absolute value of the max exponent (log distance from 1.) //! ''' //! //! return 127 + math.ceil(math.log2(base**exponent)) //! //! //! def next_fp(fp, base, step = 1): //! '''Generate the next extended-floating point value.''' //! //! return (fp[0] * (base**step), fp[1]) //! //! //! def prev_fp(fp, base, step = 1): //! '''Generate the previous extended-floating point value.''' //! //! return (fp[0] // (base**step), fp[1]) //! //! //! def normalize_fp(fp): //! '''Normalize a extended-float so the MSB is the 128th bit''' //! //! while fp[0] >> 128 != 0: //! fp = (fp[0] >> 1, fp[1] + 1) //! return fp //! //! //! def generate_small(base, count): //! '''Generate the small powers for a given base''' //! //! bitshift = calculate_bitshift(base, count) //! fps = [] //! fp = (1 << bitshift, -bitshift) //! for exp in range(count): //! fps.append((normalize_fp(fp), exp)) //! fp = next_fp(fp, base) //! //! # Print the small powers as integers. //! ints = [base**i for _, i in fps] //! //! return fps, ints //! //! //! def generate_large(base, step): //! '''Generate the large powers for a given base.''' //! //! # Get our starting parameters //! min_exp = math.floor(math.log(5e-324, base) - math.log(0xFFFFFFFFFFFFFFFF, base)) //! max_exp = math.ceil(math.log(1.7976931348623157e+308, base)) //! bitshift = calculate_bitshift(base, abs(min_exp - step)) //! fps = deque() //! //! # Add negative exponents //! # We need to go below the minimum exponent, since we need //! # all resulting exponents to be positive. //! fp = (1 << bitshift, -bitshift) //! for exp in range(-step, min_exp-step, -step): //! fp = prev_fp(fp, base, step) //! fps.appendleft((normalize_fp(fp), exp)) //! //! # Add positive exponents //! fp = (1 << bitshift, -bitshift) //! fps.append((normalize_fp(fp), 0)) //! for exp in range(step, max_exp, step): //! fp = next_fp(fp, base, step) //! fps.append((normalize_fp(fp), exp)) //! //! # Return the smallest exp, AKA, the bias //! return fps, -fps[0][1] //! //! //! def print_array(base, string, fps, index): //! '''Print an entire array''' //! //! print(string.format(base, len(fps))) //! for fp, exp in fps: //! value = " {},".format(fp[index]) //! exp = EXP_STR.format(base, exp) //! print(value.ljust(56, " ") + exp) //! print("];") //! //! //! def generate_base(base): //! '''Generate all powers and variables.''' //! //! step = math.floor(math.log(1e10, base)) //! small, ints = generate_small(base, step) //! large, bias = generate_large(base, step) //! //! print_array(base, SMALL_MANTISSA_STR, small, 0) //! print_array(base, SMALL_EXPONENT_STR, small, 1) //! print_array(base, LARGE_MANTISSA_STR, large, 0) //! print_array(base, LARGE_EXPONENT_STR, large, 1) //! print(SMALL_INT_STR.format(base, len(ints), ints)) //! print(STEP_STR.format(base, step)) //! print(BIAS_STR.format(base, bias)) //! //! //! def generate(): //! '''Generate all bases.''' //! //! bases = [ //! 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, //! 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36 //! ] //! //! for base in bases: //! print("// BASE{}\n".format(base)) //! generate_base(base) //! print("") //! //! print("// HIGH LEVEL\n// ----------\n") //! //! for base in bases: //! print(POWER_STR.format(base)) //! //! //! if __name__ == '__main__': //! generate() //! ``` use crate::util::*; use super::cached::{ExtendedFloatArray, ModeratePathPowers}; // LOW-LEVEL // --------- // BASE10 const BASE10_SMALL_MANTISSA: [u128; 10] = [ 170141183460469231731687303715884105728, // 10^0 212676479325586539664609129644855132160, // 10^1 265845599156983174580761412056068915200, // 10^2 332306998946228968225951765070086144000, // 10^3 207691874341393105141219853168803840000, // 10^4 259614842926741381426524816461004800000, // 10^5 324518553658426726783156020576256000000, // 10^6 202824096036516704239472512860160000000, // 10^7 253530120045645880299340641075200000000, // 10^8 316912650057057350374175801344000000000, // 10^9 ]; const BASE10_SMALL_EXPONENT: [i32; 10] = [ -127, // 10^0 -124, // 10^1 -121, // 10^2 -118, // 10^3 -114, // 10^4 -111, // 10^5 -108, // 10^6 -104, // 10^7 -101, // 10^8 -98, // 10^9 ]; const BASE10_LARGE_MANTISSA: [u128; 66] = [ 213154451346726893197828921904416471830, // 10^-350 248144440523729302452212341484167231049, // 10^-340 288878149031346317441449898160257412877, // 10^-330 336298426882534191759128470626028036788, // 10^-320 195751447977110622310503659901458325789, // 10^-310 227884678143438210606695688214919443462, // 10^-300 265292681454958173686982700851419292695, // 10^-290 308841328899094571460716776609676066664, // 10^-280 179769313486231590772930519078902473361, // 10^-270 209279024841067836122739267394531603625, // 10^-260 243632850284999977008834559696879707771, // 10^-250 283625966735416996535885333662014114404, // 10^-240 330184081959790778970212365572822879074, // 10^-230 192192430817400325887261637005036975649, // 10^-220 223741436863085634409521749481834675708, // 10^-210 260469313784369307581244210575049132700, // 10^-200 303226189902482213896285056340332530323, // 10^-190 176500872419263593559319302637789241459, // 10^-180 205474058654233340126601167300005025998, // 10^-170 239203286653190548679094257880939433814, // 10^-160 278469275977917188637766821636980671685, // 10^-150 324180903818827574883781864350871964922, // 10^-140 188698121241077067612077729049413444545, // 10^-130 219673525124179510879420825570604582952, // 10^-120 255733641241886083594780445064656183766, // 10^-110 297713141471480582369003031710926657271, // 10^-100 173291855882550928723650886508942731464, // 10^-90 201738271725539733566868685312735302682, // 10^-80 234854258277383322788948059678933702737, // 10^-70 273406340597876490546562778389702670669, // 10^-60 318286871302263450979444638813965337664, // 10^-50 185267342779705912677713576013900652565, // 10^-40 215679573337205118357336120696157045389, // 10^-30 251084069415467230553431576928306656644, // 10^-20 292300327466180583640736966543256603931, // 10^-10 170141183460469231731687303715884105728, // 10^0 198070406285660843983859875840000000000, // 10^10 230584300921369395200000000000000000000, // 10^20 268435456000000000000000000000000000000, // 10^30 312500000000000000000000000000000000000, // 10^40 181898940354585647583007812500000000000, // 10^50 211758236813575084767080625169910490512, // 10^60 246519032881566189191165176650870696772, // 10^70 286985925493722536125179818657774823686, // 10^80 334095588761524455767567058393935234851, // 10^90 194469227433160678348252001680628882518, // 10^100 226391976970667809187727982272194794517, // 10^110 263554948580763080608714351281750475192, // 10^120 306818341581107909568485747186642227685, // 10^130 178591779887855465971216179422709524914, // 10^140 207908195312897984370608091613638127355, // 10^150 242036994678082392051126914580396990473, // 10^160 281768146294730706199918541335962934504, // 10^170 328021294314799255458543241647960309061, // 10^180 190933522718725292628248712075851106236, // 10^190 222275874948507748344271341427056009691, // 10^200 258763175164940474024358370140027266101, // 10^210 301239983137860514717593754339063617053, // 10^220 175344747920672243180215448571289666610, // 10^230 204128152598478183127259193653345185577, // 10^240 237636445786894977939384050729387888658, // 10^250 276645233140903266541874095249674153349, // 10^260 322057438479856665411351825168442625260, // 10^270 187462101736953869352205554703508169192, // 10^280 218234609040610805796698614376955862613, // 10^290 254058522452380049271391022923583936195, // 10^300 ]; const BASE10_LARGE_EXPONENT: [i32; 66] = [ -1290, // 10^-350 -1257, // 10^-340 -1224, // 10^-330 -1191, // 10^-320 -1157, // 10^-310 -1124, // 10^-300 -1091, // 10^-290 -1058, // 10^-280 -1024, // 10^-270 -991, // 10^-260 -958, // 10^-250 -925, // 10^-240 -892, // 10^-230 -858, // 10^-220 -825, // 10^-210 -792, // 10^-200 -759, // 10^-190 -725, // 10^-180 -692, // 10^-170 -659, // 10^-160 -626, // 10^-150 -593, // 10^-140 -559, // 10^-130 -526, // 10^-120 -493, // 10^-110 -460, // 10^-100 -426, // 10^-90 -393, // 10^-80 -360, // 10^-70 -327, // 10^-60 -294, // 10^-50 -260, // 10^-40 -227, // 10^-30 -194, // 10^-20 -161, // 10^-10 -127, // 10^0 -94, // 10^10 -61, // 10^20 -28, // 10^30 5, // 10^40 39, // 10^50 72, // 10^60 105, // 10^70 138, // 10^80 171, // 10^90 205, // 10^100 238, // 10^110 271, // 10^120 304, // 10^130 338, // 10^140 371, // 10^150 404, // 10^160 437, // 10^170 470, // 10^180 504, // 10^190 537, // 10^200 570, // 10^210 603, // 10^220 637, // 10^230 670, // 10^240 703, // 10^250 736, // 10^260 769, // 10^270 803, // 10^280 836, // 10^290 869, // 10^300 ]; const BASE10_SMALL_INT_POWERS: [u128; 10] = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000]; const BASE10_STEP: i32 = 10; const BASE10_BIAS: i32 = 350; cfg_if! { if #[cfg(feature = "radix")] { // BASE3 const BASE3_SMALL_MANTISSA: [u128; 20] = [ 170141183460469231731687303715884105728, // 3^0 255211775190703847597530955573826158592, // 3^1 191408831393027885698148216680369618944, // 3^2 287113247089541828547222325020554428416, // 3^3 215334935317156371410416743765415821312, // 3^4 323002402975734557115625115648123731968, // 3^5 242251802231800917836718836736092798976, // 3^6 181688851673850688377539127552069599232, // 3^7 272533277510776032566308691328104398848, // 3^8 204399958133082024424731518496078299136, // 3^9 306599937199623036637097277744117448704, // 3^10 229949952899717277477822958308088086528, // 3^11 172462464674787958108367218731066064896, // 3^12 258693697012181937162550828096599097344, // 3^13 194020272759136452871913121072449323008, // 3^14 291030409138704679307869681608673984512, // 3^15 218272806854028509480902261206505488384, // 3^16 327409210281042764221353391809758232576, // 3^17 245556907710782073166015043857318674432, // 3^18 184167680783086554874511282892989005824, // 3^19 ]; const BASE3_SMALL_EXPONENT: [i32; 20] = [ -127, // 3^0 -126, // 3^1 -124, // 3^2 -123, // 3^3 -121, // 3^4 -120, // 3^5 -118, // 3^6 -116, // 3^7 -115, // 3^8 -113, // 3^9 -112, // 3^10 -110, // 3^11 -108, // 3^12 -107, // 3^13 -105, // 3^14 -104, // 3^15 -102, // 3^16 -101, // 3^17 -99, // 3^18 -97, // 3^19 ]; const BASE3_LARGE_MANTISSA: [u128; 69] = [ 301829093537629265639465570217176944359, // 3^-720 245033990385703656345786023933864839340, // 3^-700 198926007233479871031630637668169238011, // 3^-680 322988302900880006728964617948539328448, // 3^-660 262211676747596696167096696967233799204, // 3^-640 212871372756449173771443137071089544143, // 3^-620 172815421118085121562612771428651141606, // 3^-600 280593575260967566098415738074481154338, // 3^-580 227794354139073103116567345878808448350, // 3^-560 184930348919702200346046943747485274024, // 3^-540 300264105147079021545114594266031000970, // 3^-520 243763485459391712918376663011554847091, // 3^-500 197894572893436379626501802082900685163, // 3^-480 321313603691473325606249593990411338331, // 3^-460 260852105259086286749566195634740776863, // 3^-440 211767631486382365261996259087726574961, // 3^-420 171919370559843833352674924374427532806, // 3^-400 279138693352137745884317186629683060895, // 3^-380 226613236986043931067161987739751269180, // 3^-360 183971482278558945643179980616811190964, // 3^-340 298707231244876640116631457791747347925, // 3^-320 242499568120235502703106353919523432682, // 3^-300 196868486555962367745019627988939060464, // 3^-280 319647587822660709450189016904055940251, // 3^-260 259499583169196479959998361450291137700, // 3^-240 210669613131404954481085620515615417585, // 3^-220 171027966037226738058674240289082148799, // 3^-200 277691355027891684120101092281051616669, // 3^-180 225438243943221318560556485110109738278, // 3^-160 183017587375374702561553597022155160742, // 3^-140 297158429757277967604640789526650060843, // 3^-120 241242204211496523037749538228345943134, // 3^-100 195847720491584060106836777189641681162, // 3^-80 317990210271190550439415903835536554761, // 3^-60 258154073926689380540223575440483383976, // 3^-40 209577288018116110386327960504760073299, // 3^-20 170141183460469231731687303715884105728, // 3^0 276251521174629832311766924339483508736, // 3^20 224269343257001716702690972139746492416, // 3^40 182068638431613361423174859113151594496, // 3^60 295617658828691846632166420412766595202, // 3^80 239991359753539474232337032335634004651, // 3^100 194832247114605420104007752175098574688, // 3^120 316341426247257477645159711999449660471, // 3^140 256815541169845811576524073480007610450, // 3^160 208490626626972031635281014538153149532, // 3^180 338517997729425004575949331160209430911, // 3^200 274819152881557244028610584245948464515, // 3^220 223106503338424488684979682521025988628, // 3^240 181124609802400910077427551154104473922, // 3^260 294084876820548989626661915132664622178, // 3^280 238747000942913976797497733353022683918, // 3^300 193822038982362660063056049982127016523, // 3^320 314701191193291934781116205950433765545, // 3^340 255483948725482657093998355855298189652, // 3^360 207409599591488195571905341445445255582, // 3^380 336762776818711782198286065086981891498, // 3^400 273394211439632029990640781047045990695, // 3^420 221949692762318233808346663450192754968, // 3^440 180185475975832393914650652957737664335, // 3^460 292560042310176717160312096633717510967, // 3^480 237509094151441049982785534773499431992, // 3^500 192817068794482616882547252154136283242, // 3^520 313069460782756034010893203297842312622, // 3^540 254159260607975299744356396919078736707, // 3^560 206334177697445743564032291193028958152, // 3^580 335016656754825225194410391893304442626, // 3^600 271976658340519265432186039827268288213, // 3^620 220798880266451537830039115389735391778, // 3^640 ]; const BASE3_LARGE_EXPONENT: [i32; 69] = [ -1269, // 3^-720 -1237, // 3^-700 -1205, // 3^-680 -1174, // 3^-660 -1142, // 3^-640 -1110, // 3^-620 -1078, // 3^-600 -1047, // 3^-580 -1015, // 3^-560 -983, // 3^-540 -952, // 3^-520 -920, // 3^-500 -888, // 3^-480 -857, // 3^-460 -825, // 3^-440 -793, // 3^-420 -761, // 3^-400 -730, // 3^-380 -698, // 3^-360 -666, // 3^-340 -635, // 3^-320 -603, // 3^-300 -571, // 3^-280 -540, // 3^-260 -508, // 3^-240 -476, // 3^-220 -444, // 3^-200 -413, // 3^-180 -381, // 3^-160 -349, // 3^-140 -318, // 3^-120 -286, // 3^-100 -254, // 3^-80 -223, // 3^-60 -191, // 3^-40 -159, // 3^-20 -127, // 3^0 -96, // 3^20 -64, // 3^40 -32, // 3^60 -1, // 3^80 31, // 3^100 63, // 3^120 94, // 3^140 126, // 3^160 158, // 3^180 189, // 3^200 221, // 3^220 253, // 3^240 285, // 3^260 316, // 3^280 348, // 3^300 380, // 3^320 411, // 3^340 443, // 3^360 475, // 3^380 506, // 3^400 538, // 3^420 570, // 3^440 602, // 3^460 633, // 3^480 665, // 3^500 697, // 3^520 728, // 3^540 760, // 3^560 792, // 3^580 823, // 3^600 855, // 3^620 887, // 3^640 ]; const BASE3_SMALL_INT_POWERS: [u128; 20] = [1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721, 129140163, 387420489, 1162261467]; const BASE3_STEP: i32 = 20; const BASE3_BIAS: i32 = 720; // BASE5 const BASE5_SMALL_MANTISSA: [u128; 14] = [ 170141183460469231731687303715884105728, // 5^0 212676479325586539664609129644855132160, // 5^1 265845599156983174580761412056068915200, // 5^2 332306998946228968225951765070086144000, // 5^3 207691874341393105141219853168803840000, // 5^4 259614842926741381426524816461004800000, // 5^5 324518553658426726783156020576256000000, // 5^6 202824096036516704239472512860160000000, // 5^7 253530120045645880299340641075200000000, // 5^8 316912650057057350374175801344000000000, // 5^9 198070406285660843983859875840000000000, // 5^10 247588007857076054979824844800000000000, // 5^11 309485009821345068724781056000000000000, // 5^12 193428131138340667952988160000000000000, // 5^13 ]; const BASE5_SMALL_EXPONENT: [i32; 14] = [ -127, // 5^0 -125, // 5^1 -123, // 5^2 -121, // 5^3 -118, // 5^4 -116, // 5^5 -114, // 5^6 -111, // 5^7 -109, // 5^8 -107, // 5^9 -104, // 5^10 -102, // 5^11 -100, // 5^12 -97, // 5^13 ]; const BASE5_LARGE_MANTISSA: [u128; 68] = [ 285793394306920833441610418092098634655, // 5^-504 203068420253004570555511362849258201390, // 5^-490 288577581746103207017755725657449092679, // 5^-476 205046704412910121830119952091883627559, // 5^-462 291388892624283530821742192659774598780, // 5^-448 207044260935364498850036477975162511299, // 5^-434 294227591176883860910658765384315687611, // 5^-420 209061277570927374050781655074839937648, // 5^-406 297093944213496817569054052050375869453, // 5^-392 211097943899216614887176072592734406508, // 5^-378 299988221142963048588365030287739055137, // 5^-364 213154451346726893197828921904416471830, // 5^-350 302910693998692996157485768413290076965, // 5^-336 215230993204821882725842221200657943544, // 5^-322 305861637464235347360161968596028634045, // 5^-308 217327764647901735884376228537482684576, // 5^-294 308841328899094571460716776609676066664, // 5^-280 219444962751747547330237450047488370802, // 5^-266 311850048364799970571308236412006025948, // 5^-252 221582786512044528543660416923448526878, // 5^-238 314888078651228693933689466069052580904, // 5^-224 223741436863085634409521749481834675708, // 5^-210 317955705303185189918510999237120523316, // 5^-196 225921116696657399755928707376370229068, // 5^-182 321053216647239593947814323906257853121, // 5^-168 228122030881109760932058580285014566244, // 5^-154 324180903818827574883781864350871964922, // 5^-140 230344386280611654799899571593522271174, // 5^-126 327339060789614187001318969682759915221, // 5^-112 232588391774594204975783618524161450993, // 5^-98 330527984395124299475957654016385519914, // 5^-84 234854258277383322788948059678933702737, // 5^-70 333747974362642200374222141588992517906, // 5^-56 237142198758023568227473377297792835283, // 5^-42 336999333339382997433337688587745383420, // 5^-28 239452428260295134118491722992235809940, // 5^-14 170141183460469231731687303715884105728, // 5^0 241785163922925834941235200000000000000, // 5^14 171798691840000000000000000000000000000, // 5^28 244140625000000000000000000000000000000, // 5^42 173472347597680709441192448139190673828, // 5^56 246519032881566189191165176650870696772, // 5^70 175162308040602133865466197911239516410, // 5^84 248920611114445668285762562151204969623, // 5^98 176868732008334225927912486150152183216, // 5^112 251345585423243599518503524095297312920, // 5^126 178591779887855465971216179422709524914, // 5^140 253794183731564922327402455583054354682, // 5^154 180331613628627651967947866455016278082, // 5^168 256266636183436918326986907537468991453, // 5^182 182088396757817547443627082897044283139, // 5^196 258763175164940474024358370140027266101, // 5^210 183862294395666818064937594201088633455, // 5^224 261284035326052074402891767876281837538, // 5^238 185653473271011701515143789632334288014, // 5^252 263829453602698580304979415177988198613, // 5^266 187462101736953869352205554703508169192, // 5^280 266399669239026862544798113253119949479, // 5^294 189288349786683953755640255602884245064, // 5^308 268994923809890385876486015494726082500, // 5^322 191132389069459226417170338759437756337, // 5^336 271615461243554856334256923502490730495, // 5^350 192994392906736931318972184714148973580, // 5^364 274261527844625066050770363850331497104, // 5^378 194874536308464787773268059716493991903, // 5^392 276933372317195090450451374005771742621, // 5^406 196772995989530194869453349330805553038, // 5^420 279631245788224013707368483964622716141, // 5^434 ]; const BASE5_LARGE_EXPONENT: [i32; 68] = [ -1298, // 5^-504 -1265, // 5^-490 -1233, // 5^-476 -1200, // 5^-462 -1168, // 5^-448 -1135, // 5^-434 -1103, // 5^-420 -1070, // 5^-406 -1038, // 5^-392 -1005, // 5^-378 -973, // 5^-364 -940, // 5^-350 -908, // 5^-336 -875, // 5^-322 -843, // 5^-308 -810, // 5^-294 -778, // 5^-280 -745, // 5^-266 -713, // 5^-252 -680, // 5^-238 -648, // 5^-224 -615, // 5^-210 -583, // 5^-196 -550, // 5^-182 -518, // 5^-168 -485, // 5^-154 -453, // 5^-140 -420, // 5^-126 -388, // 5^-112 -355, // 5^-98 -323, // 5^-84 -290, // 5^-70 -258, // 5^-56 -225, // 5^-42 -193, // 5^-28 -160, // 5^-14 -127, // 5^0 -95, // 5^14 -62, // 5^28 -30, // 5^42 3, // 5^56 35, // 5^70 68, // 5^84 100, // 5^98 133, // 5^112 165, // 5^126 198, // 5^140 230, // 5^154 263, // 5^168 295, // 5^182 328, // 5^196 360, // 5^210 393, // 5^224 425, // 5^238 458, // 5^252 490, // 5^266 523, // 5^280 555, // 5^294 588, // 5^308 620, // 5^322 653, // 5^336 685, // 5^350 718, // 5^364 750, // 5^378 783, // 5^392 815, // 5^406 848, // 5^420 880, // 5^434 ]; const BASE5_SMALL_INT_POWERS: [u128; 14] = [1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125]; const BASE5_STEP: i32 = 14; const BASE5_BIAS: i32 = 504; // BASE6 const BASE6_SMALL_MANTISSA: [u128; 12] = [ 170141183460469231731687303715884105728, // 6^0 255211775190703847597530955573826158592, // 6^1 191408831393027885698148216680369618944, // 6^2 287113247089541828547222325020554428416, // 6^3 215334935317156371410416743765415821312, // 6^4 323002402975734557115625115648123731968, // 6^5 242251802231800917836718836736092798976, // 6^6 181688851673850688377539127552069599232, // 6^7 272533277510776032566308691328104398848, // 6^8 204399958133082024424731518496078299136, // 6^9 306599937199623036637097277744117448704, // 6^10 229949952899717277477822958308088086528, // 6^11 ]; const BASE6_SMALL_EXPONENT: [i32; 12] = [ -127, // 6^0 -125, // 6^1 -122, // 6^2 -120, // 6^3 -117, // 6^4 -115, // 6^5 -112, // 6^6 -109, // 6^7 -107, // 6^8 -104, // 6^9 -102, // 6^10 -99, // 6^11 ]; const BASE6_LARGE_MANTISSA: [u128; 71] = [ 206105367118290399407064648402758144682, // 6^-444 208917317212507950117664039252872831665, // 6^-432 211767631486382365261996259087726574961, // 6^-420 214656833352574406771088703014069554755, // 6^-408 217585453364802351586979201161384846208, // 6^-396 220554029315269330081435801781477974040, // 6^-384 223563106333419891448609016293621894840, // 6^-372 226613236986043931067161987739751269180, // 6^-360 229704981378746362247969882824709232796, // 6^-348 232838907258801165579649662968151663564, // 6^-336 236015590119408703302029793810763336632, // 6^-324 239235613305375443823879271798297650114, // 6^-312 242499568120235502703106353919523432682, // 6^-300 245808053934833671173174941698733239342, // 6^-288 249161678297389871677290466673500998400, // 6^-276 252561057045065251911260457800735557729, // 6^-264 256006814417050404626793229969178591795, // 6^-252 259499583169196479959998361450291137700, // 6^-240 263040004690210240376322725691803307553, // 6^-228 266628729119434395515123988465075762881, // 6^-216 270266415466234845327287688358055741312, // 6^-204 273953731731016754981191818978678705632, // 6^-192 277691355027891684120101092281051616669, // 6^-180 281479971709018296242657937208050445965, // 6^-168 285320277490639481303204301467482637509, // 6^-156 289212977580839036146652597763405686112, // 6^-144 293158786809041363160730749526943361727, // 6^-132 297158429757277967604640789526650060843, // 6^-120 301212640893244858516269504216828222245, // 6^-108 305322164705175286969651759320250334279, // 6^-96 309487755838552588810803796052767101096, // 6^-84 313710179234688236904530296665341569850, // 6^-72 317990210271190550439415903835536554761, // 6^-60 322328634904349856025836233807108654402, // 6^-48 326726249813466247246220462666861782844, // 6^-36 331183862547146446042592332649497399781, // 6^-24 335702291671596630919115661345637412333, // 6^-12 170141183460469231731687303715884105728, // 6^0 172462464674787958108367218731066064896, // 6^12 174815415743320440759790006808579407872, // 6^24 177200468746272961345336076752392290304, // 6^36 179618061658836457920697688990341398528, // 6^48 182068638431613361423174859113151594496, // 6^60 184552649072141716781794491390137475072, // 6^72 187070549727531559196917812917453861026, // 6^84 189622802768228720381105803326920695033, // 6^96 192209876872921446586714266254161951235, // 6^108 194832247114605420104007752175098574688, // 6^120 197490395047822988635051696441052554380, // 6^132 200184808797092622572327630249651738267, // 6^144 202915983146544838776512848181734408257, // 6^156 205684419630781050995309380627725821797, // 6^168 208490626626972031635281014538153149532, // 6^180 211335119448212897232599978727666183358, // 6^192 214218420438151760708217936124820030498, // 6^204 217141059066909427380630585083218539864, // 6^216 220103572028307748788051030668660629356, // 6^228 223106503338424488684979682521025988628, // 6^240 226150404435492799169987273137391228527, // 6^252 229235834281163651816744244429413474808, // 6^264 232363359463149818964276081092475750857, // 6^276 235533554299270254021060647605641184828, // 6^288 238747000942913976797497733353022683918, // 6^300 242004289489942830549695955106475311593, // 6^312 245306018087052741642305313258629505287, // 6^324 248652793041613380567795520750960012282, // 6^336 252045228933006394543323172270604972624, // 6^348 255483948725482657093998355855298189652, // 6^360 258969583882559258973487053363982248701, // 6^372 262502774482977247520692697766891651596, // 6^384 266084169338241408156670471179837543899, // 6^396 ]; const BASE6_LARGE_EXPONENT: [i32; 71] = [ -1275, // 6^-444 -1244, // 6^-432 -1213, // 6^-420 -1182, // 6^-408 -1151, // 6^-396 -1120, // 6^-384 -1089, // 6^-372 -1058, // 6^-360 -1027, // 6^-348 -996, // 6^-336 -965, // 6^-324 -934, // 6^-312 -903, // 6^-300 -872, // 6^-288 -841, // 6^-276 -810, // 6^-264 -779, // 6^-252 -748, // 6^-240 -717, // 6^-228 -686, // 6^-216 -655, // 6^-204 -624, // 6^-192 -593, // 6^-180 -562, // 6^-168 -531, // 6^-156 -500, // 6^-144 -469, // 6^-132 -438, // 6^-120 -407, // 6^-108 -376, // 6^-96 -345, // 6^-84 -314, // 6^-72 -283, // 6^-60 -252, // 6^-48 -221, // 6^-36 -190, // 6^-24 -159, // 6^-12 -127, // 6^0 -96, // 6^12 -65, // 6^24 -34, // 6^36 -3, // 6^48 28, // 6^60 59, // 6^72 90, // 6^84 121, // 6^96 152, // 6^108 183, // 6^120 214, // 6^132 245, // 6^144 276, // 6^156 307, // 6^168 338, // 6^180 369, // 6^192 400, // 6^204 431, // 6^216 462, // 6^228 493, // 6^240 524, // 6^252 555, // 6^264 586, // 6^276 617, // 6^288 648, // 6^300 679, // 6^312 710, // 6^324 741, // 6^336 772, // 6^348 803, // 6^360 834, // 6^372 865, // 6^384 896, // 6^396 ]; const BASE6_SMALL_INT_POWERS: [u128; 12] = [1, 6, 36, 216, 1296, 7776, 46656, 279936, 1679616, 10077696, 60466176, 362797056]; const BASE6_STEP: i32 = 12; const BASE6_BIAS: i32 = 444; // BASE7 const BASE7_SMALL_MANTISSA: [u128; 11] = [ 170141183460469231731687303715884105728, // 7^0 297747071055821155530452781502797185024, // 7^1 260528687173843511089146183814947536896, // 7^2 227962601277113072203002910838079094784, // 7^3 199467276117473938177627546983319207936, // 7^4 174533866602789695905424103610404306944, // 7^5 305434266554881967834492181318207537152, // 7^6 267254983235521721855180658653431595008, // 7^7 233848110331081506623283076321752645632, // 7^8 204617096539696318295372691781533564928, // 7^9 179039959472234278508451105308841869312, // 7^10 ]; const BASE7_SMALL_EXPONENT: [i32; 11] = [ -127, // 7^0 -125, // 7^1 -122, // 7^2 -119, // 7^3 -116, // 7^4 -113, // 7^5 -111, // 7^6 -108, // 7^7 -105, // 7^8 -102, // 7^9 -99, // 7^10 ]; const BASE7_LARGE_MANTISSA: [u128; 71] = [ 225523710066019267908218449093892378358, // 7^-407 207654229874777697952558290622819921790, // 7^-396 191200646585071218824745087565327043379, // 7^-385 176050770921424471559828841966017113260, // 7^-374 324202605959679334675793064499391555083, // 7^-363 298514255748300407155832676761118149894, // 7^-352 274861334384351909098688755274300249465, // 7^-341 253082563679127241756740166823033329043, // 7^-330 233029444399168140266755890269514708731, // 7^-319 214565243719567885018434177936373702812, // 7^-308 197564062906901525077828647577582055243, // 7^-297 181909978874749832229630901118123515094, // 7^-286 334992507516972618831705765612473924060, // 7^-275 308449214239576126269380201889590576494, // 7^-264 284009091636748185128341566413187692045, // 7^-253 261505493963360706349361998265286260917, // 7^-242 240784979730461811097321743219099069136, // 7^-231 221706265459654420066135217688280855198, // 7^-220 204139262337252438224351496710052887294, // 7^-209 187964189199610581269006081054389519147, // 7^-198 173070755801490399767170008783447571912, // 7^-187 318714821597104302344272129046782646031, // 7^-176 293461298632634947256039303556899737616, // 7^-165 270208750768480083796084384984407980627, // 7^-154 248798629775241702400557051000361115726, // 7^-143 229084950069124576377435007616984162844, // 7^-132 210933293304638808346189699277966975327, // 7^-121 194219891838880796776419735762035423417, // 7^-110 178830784817964977889863278397948540205, // 7^-99 329322082262710237520775170056072850605, // 7^-88 303228087871569629902816732340606701122, // 7^-77 279201663740542055384000770694089408486, // 7^-66 257078984940548995242906668328695771951, // 7^-55 236709207289964795762477040448859922676, // 7^-44 217953438818817001855782665313698094789, // 7^-33 200683792729517998822275406364627986706, // 7^-22 184782515396710906443711214287193178833, // 7^-11 170141183460469231731687303715884105728, // 7^0 313319929076409987389789434290473271296, // 7^11 288493873028852398739253829029106548736, // 7^22 265634921533798919351224824788236107776, // 7^33 244587210111081219100242972308429222416, // 7^44 225207224277966141315155116349116687572, // 7^55 207362820991138609531788808643065835705, // 7^66 190932327625202079604864455739987836428, // 7^77 175803712344053086257499345217280929659, // 7^88 323747640416561983962207324433251030705, // 7^99 298095339619934405668456872884344580325, // 7^110 274475611277932187651307585787198545738, // 7^121 252727403529513497084111370284014563793, // 7^132 232702425535702904483240997815950541938, // 7^143 214264136353838934720254978302625752306, // 7^154 197286813928859418414994791325492154413, // 7^165 181654697853512422889189735564216996803, // 7^176 334522400104752565046325502667785120787, // 7^187 308016356015425756696586706818979868623, // 7^198 283610531143243549972387138852602501496, // 7^209 261138513603233655506120063924465915820, // 7^220 240447077236577495145565086308268824286, // 7^231 221395136833224081873557773886454798418, // 7^242 203852786137945162132478938839041683065, // 7^253 187700412080445632409314398956810353518, // 7^264 172827879189879361689316520165778889316, // 7^275 318267557265350256871483486812089934265, // 7^286 293049473506426909088112326597996634777, // 7^297 269829556805234360375792834335085449819, // 7^308 248449481428986202531286841797890645972, // 7^319 228763466660872229208763580066607974130, // 7^330 210637282789652967136592584117374228567, // 7^341 193947335860149215724544902551342320202, // 7^352 178579824943969003959847035500732297209, // 7^363 ]; const BASE7_LARGE_EXPONENT: [i32; 71] = [ -1270, // 7^-407 -1239, // 7^-396 -1208, // 7^-385 -1177, // 7^-374 -1147, // 7^-363 -1116, // 7^-352 -1085, // 7^-341 -1054, // 7^-330 -1023, // 7^-319 -992, // 7^-308 -961, // 7^-297 -930, // 7^-286 -900, // 7^-275 -869, // 7^-264 -838, // 7^-253 -807, // 7^-242 -776, // 7^-231 -745, // 7^-220 -714, // 7^-209 -683, // 7^-198 -652, // 7^-187 -622, // 7^-176 -591, // 7^-165 -560, // 7^-154 -529, // 7^-143 -498, // 7^-132 -467, // 7^-121 -436, // 7^-110 -405, // 7^-99 -375, // 7^-88 -344, // 7^-77 -313, // 7^-66 -282, // 7^-55 -251, // 7^-44 -220, // 7^-33 -189, // 7^-22 -158, // 7^-11 -127, // 7^0 -97, // 7^11 -66, // 7^22 -35, // 7^33 -4, // 7^44 27, // 7^55 58, // 7^66 89, // 7^77 120, // 7^88 150, // 7^99 181, // 7^110 212, // 7^121 243, // 7^132 274, // 7^143 305, // 7^154 336, // 7^165 367, // 7^176 397, // 7^187 428, // 7^198 459, // 7^209 490, // 7^220 521, // 7^231 552, // 7^242 583, // 7^253 614, // 7^264 645, // 7^275 675, // 7^286 706, // 7^297 737, // 7^308 768, // 7^319 799, // 7^330 830, // 7^341 861, // 7^352 892, // 7^363 ]; const BASE7_SMALL_INT_POWERS: [u128; 11] = [1, 7, 49, 343, 2401, 16807, 117649, 823543, 5764801, 40353607, 282475249]; const BASE7_STEP: i32 = 11; const BASE7_BIAS: i32 = 407; // BASE9 const BASE9_SMALL_MANTISSA: [u128; 10] = [ 170141183460469231731687303715884105728, // 9^0 191408831393027885698148216680369618944, // 9^1 215334935317156371410416743765415821312, // 9^2 242251802231800917836718836736092798976, // 9^3 272533277510776032566308691328104398848, // 9^4 306599937199623036637097277744117448704, // 9^5 172462464674787958108367218731066064896, // 9^6 194020272759136452871913121072449323008, // 9^7 218272806854028509480902261206505488384, // 9^8 245556907710782073166015043857318674432, // 9^9 ]; const BASE9_SMALL_EXPONENT: [i32; 10] = [ -127, // 9^0 -124, // 9^1 -121, // 9^2 -118, // 9^3 -115, // 9^4 -112, // 9^5 -108, // 9^6 -105, // 9^7 -102, // 9^8 -99, // 9^9 ]; const BASE9_LARGE_MANTISSA: [u128; 69] = [ 301829093537629265639465570217176944359, // 9^-360 245033990385703656345786023933864839340, // 9^-350 198926007233479871031630637668169238011, // 9^-340 322988302900880006728964617948539328448, // 9^-330 262211676747596696167096696967233799204, // 9^-320 212871372756449173771443137071089544143, // 9^-310 172815421118085121562612771428651141606, // 9^-300 280593575260967566098415738074481154338, // 9^-290 227794354139073103116567345878808448350, // 9^-280 184930348919702200346046943747485274024, // 9^-270 300264105147079021545114594266031000970, // 9^-260 243763485459391712918376663011554847091, // 9^-250 197894572893436379626501802082900685163, // 9^-240 321313603691473325606249593990411338331, // 9^-230 260852105259086286749566195634740776863, // 9^-220 211767631486382365261996259087726574961, // 9^-210 171919370559843833352674924374427532806, // 9^-200 279138693352137745884317186629683060895, // 9^-190 226613236986043931067161987739751269180, // 9^-180 183971482278558945643179980616811190964, // 9^-170 298707231244876640116631457791747347925, // 9^-160 242499568120235502703106353919523432682, // 9^-150 196868486555962367745019627988939060464, // 9^-140 319647587822660709450189016904055940251, // 9^-130 259499583169196479959998361450291137700, // 9^-120 210669613131404954481085620515615417585, // 9^-110 171027966037226738058674240289082148799, // 9^-100 277691355027891684120101092281051616669, // 9^-90 225438243943221318560556485110109738278, // 9^-80 183017587375374702561553597022155160742, // 9^-70 297158429757277967604640789526650060843, // 9^-60 241242204211496523037749538228345943134, // 9^-50 195847720491584060106836777189641681162, // 9^-40 317990210271190550439415903835536554761, // 9^-30 258154073926689380540223575440483383976, // 9^-20 209577288018116110386327960504760073299, // 9^-10 170141183460469231731687303715884105728, // 9^0 276251521174629832311766924339483508736, // 9^10 224269343257001716702690972139746492416, // 9^20 182068638431613361423174859113151594496, // 9^30 295617658828691846632166420412766595202, // 9^40 239991359753539474232337032335634004651, // 9^50 194832247114605420104007752175098574688, // 9^60 316341426247257477645159711999449660471, // 9^70 256815541169845811576524073480007610450, // 9^80 208490626626972031635281014538153149532, // 9^90 338517997729425004575949331160209430911, // 9^100 274819152881557244028610584245948464515, // 9^110 223106503338424488684979682521025988628, // 9^120 181124609802400910077427551154104473922, // 9^130 294084876820548989626661915132664622178, // 9^140 238747000942913976797497733353022683918, // 9^150 193822038982362660063056049982127016523, // 9^160 314701191193291934781116205950433765545, // 9^170 255483948725482657093998355855298189652, // 9^180 207409599591488195571905341445445255582, // 9^190 336762776818711782198286065086981891498, // 9^200 273394211439632029990640781047045990695, // 9^210 221949692762318233808346663450192754968, // 9^220 180185475975832393914650652957737664335, // 9^230 292560042310176717160312096633717510967, // 9^240 237509094151441049982785534773499431992, // 9^250 192817068794482616882547252154136283242, // 9^260 313069460782756034010893203297842312622, // 9^270 254159260607975299744356396919078736707, // 9^280 206334177697445743564032291193028958152, // 9^290 335016656754825225194410391893304442626, // 9^300 271976658340519265432186039827268288213, // 9^310 220798880266451537830039115389735391778, // 9^320 ]; const BASE9_LARGE_EXPONENT: [i32; 69] = [ -1269, // 9^-360 -1237, // 9^-350 -1205, // 9^-340 -1174, // 9^-330 -1142, // 9^-320 -1110, // 9^-310 -1078, // 9^-300 -1047, // 9^-290 -1015, // 9^-280 -983, // 9^-270 -952, // 9^-260 -920, // 9^-250 -888, // 9^-240 -857, // 9^-230 -825, // 9^-220 -793, // 9^-210 -761, // 9^-200 -730, // 9^-190 -698, // 9^-180 -666, // 9^-170 -635, // 9^-160 -603, // 9^-150 -571, // 9^-140 -540, // 9^-130 -508, // 9^-120 -476, // 9^-110 -444, // 9^-100 -413, // 9^-90 -381, // 9^-80 -349, // 9^-70 -318, // 9^-60 -286, // 9^-50 -254, // 9^-40 -223, // 9^-30 -191, // 9^-20 -159, // 9^-10 -127, // 9^0 -96, // 9^10 -64, // 9^20 -32, // 9^30 -1, // 9^40 31, // 9^50 63, // 9^60 94, // 9^70 126, // 9^80 158, // 9^90 189, // 9^100 221, // 9^110 253, // 9^120 285, // 9^130 316, // 9^140 348, // 9^150 380, // 9^160 411, // 9^170 443, // 9^180 475, // 9^190 506, // 9^200 538, // 9^210 570, // 9^220 602, // 9^230 633, // 9^240 665, // 9^250 697, // 9^260 728, // 9^270 760, // 9^280 792, // 9^290 823, // 9^300 855, // 9^310 887, // 9^320 ]; const BASE9_SMALL_INT_POWERS: [u128; 10] = [1, 9, 81, 729, 6561, 59049, 531441, 4782969, 43046721, 387420489]; const BASE9_STEP: i32 = 10; const BASE9_BIAS: i32 = 360; // BASE11 const BASE11_SMALL_MANTISSA: [u128; 9] = [ 170141183460469231731687303715884105728, // 11^0 233944127258145193631070042609340645376, // 11^1 321673174979949641242721308587843387392, // 11^2 221150307798715378354370899654142328832, // 11^3 304081673223233645237259987024445702144, // 11^4 209056150340973131100616241079306420224, // 11^5 287452206718838055263347331484046327808, // 11^6 197623392119201162993551290395281850368, // 11^7 271732164163901599116133024293512544256, // 11^8 ]; const BASE11_SMALL_EXPONENT: [i32; 9] = [ -127, // 11^0 -124, // 11^1 -121, // 11^2 -117, // 11^3 -114, // 11^4 -110, // 11^5 -107, // 11^6 -103, // 11^7 -100, // 11^8 ]; const BASE11_LARGE_MANTISSA: [u128; 70] = [ 171238059048456285069153007806767780751, // 11^-333 188020237695718721716314139814895141308, // 11^-324 206447153042951189194086232691622882083, // 11^-315 226679997440031906769564274339983654138, // 11^-306 248895760886189129917706060109685643694, // 11^-297 273288779277949488106534827711219187027, // 11^-288 300072434393060227248554937081761703289, // 11^-279 329481020481262984343182946079685486146, // 11^-270 180885896895108223589085363619768036079, // 11^-261 198613611477559667549559644399735817047, // 11^-252 218078729968836026458633966547967004969, // 11^-243 239451526564652757041971603611460905574, // 11^-234 262918963175987885652063848834117643272, // 11^-225 288686324907902004950333378158035100892, // 11^-216 316979015823390018300576675081611005238, // 11^-207 174022265350496153683469750680295263035, // 11^-198 191077310017213090920037889613280023761, // 11^-189 209803833606456768694276179860414245615, // 11^-180 230365649338482385703357683130616542302, // 11^-171 252942624941184287338239913752743474826, // 11^-162 277732256071429933018369293137137136134, // 11^-153 304951393939484349279174830456271141999, // 11^-144 334838142249192351062534286575243350001, // 11^-135 183826970023851061892407973678416422311, // 11^-126 201842924352393404728314593418040675821, // 11^-117 221624531513738305774870271734740961947, // 11^-108 243344834238186465986122993315325591576, // 11^-99 267193834301414676708834595107417746247, // 11^-90 293380154594991977782504639045547494542, // 11^-81 322132864088045607402818330486415493575, // 11^-72 176851740822108453297561032060281913714, // 11^-63 194184088111306107232610402385759498575, // 11^-54 213215091354676888577329040601887973466, // 11^-45 234111227256299197427917870802090967668, // 11^-36 257055288062508663991611489278928709768, // 11^-27 282247980565918687696808555402942563478, // 11^-18 309909681819761564465444461107912469729, // 11^-9 170141183460469231731687303715884105728, // 11^0 186815862862682349392341454201789874176, // 11^9 205124743505955904636591107127579246592, // 11^18 225227985212968648451224991661780107264, // 11^27 247301444262965381085386823495099626888, // 11^36 271538211722310826714720080747313199115, // 11^45 298150302539063592923933328180322755271, // 11^54 327370510177191550022527822209865447333, // 11^63 179727221507067050840782578187764330990, // 11^72 197341380157710189331417385894277071911, // 11^81 216681813672942089280666997109850212851, // 11^90 237917705546974217796728292841033536358, // 11^99 261234820095126400184969690376374338338, // 11^108 286837127456489808703442688252756740915, // 11^117 314948587854906379895896832699151980516, // 11^126 172907555363184572545974225978641470455, // 11^135 189853352925309785288573204303090400331, // 11^144 208459922652152508348644224820166488004, // 11^153 228890028448627145607277691781146666326, // 11^162 251322385889182188596856419989450117198, // 11^171 275953225560490099471194727985491113834, // 11^180 302998009619470597652934458975103615488, // 11^189 332693316582509542060143699364121908613, // 11^198 182649455416682266091504883729813020363, // 11^207 200550007476552106538373760555841065584, // 11^216 220204902374823007850602460837751774656, // 11^225 241786074406278472344858080843135119733, // 11^234 265482308278902675848717553283442644763, // 11^243 291500890537904924029114199837605959154, // 11^252 320069422837484936971208194402230692262, // 11^261 175718906461109937023963056381563419957, // 11^270 192940230367248485471498733602562118815, // 11^279 211849329385655768374338506351963365331, // 11^288 ]; const BASE11_LARGE_EXPONENT: [i32; 70] = [ -1279, // 11^-333 -1248, // 11^-324 -1217, // 11^-315 -1186, // 11^-306 -1155, // 11^-297 -1124, // 11^-288 -1093, // 11^-279 -1062, // 11^-270 -1030, // 11^-261 -999, // 11^-252 -968, // 11^-243 -937, // 11^-234 -906, // 11^-225 -875, // 11^-216 -844, // 11^-207 -812, // 11^-198 -781, // 11^-189 -750, // 11^-180 -719, // 11^-171 -688, // 11^-162 -657, // 11^-153 -626, // 11^-144 -595, // 11^-135 -563, // 11^-126 -532, // 11^-117 -501, // 11^-108 -470, // 11^-99 -439, // 11^-90 -408, // 11^-81 -377, // 11^-72 -345, // 11^-63 -314, // 11^-54 -283, // 11^-45 -252, // 11^-36 -221, // 11^-27 -190, // 11^-18 -159, // 11^-9 -127, // 11^0 -96, // 11^9 -65, // 11^18 -34, // 11^27 -3, // 11^36 28, // 11^45 59, // 11^54 90, // 11^63 122, // 11^72 153, // 11^81 184, // 11^90 215, // 11^99 246, // 11^108 277, // 11^117 308, // 11^126 340, // 11^135 371, // 11^144 402, // 11^153 433, // 11^162 464, // 11^171 495, // 11^180 526, // 11^189 557, // 11^198 589, // 11^207 620, // 11^216 651, // 11^225 682, // 11^234 713, // 11^243 744, // 11^252 775, // 11^261 807, // 11^270 838, // 11^279 869, // 11^288 ]; const BASE11_SMALL_INT_POWERS: [u128; 9] = [1, 11, 121, 1331, 14641, 161051, 1771561, 19487171, 214358881]; const BASE11_STEP: i32 = 9; const BASE11_BIAS: i32 = 333; // BASE12 const BASE12_SMALL_MANTISSA: [u128; 9] = [ 170141183460469231731687303715884105728, // 12^0 255211775190703847597530955573826158592, // 12^1 191408831393027885698148216680369618944, // 12^2 287113247089541828547222325020554428416, // 12^3 215334935317156371410416743765415821312, // 12^4 323002402975734557115625115648123731968, // 12^5 242251802231800917836718836736092798976, // 12^6 181688851673850688377539127552069599232, // 12^7 272533277510776032566308691328104398848, // 12^8 ]; const BASE12_SMALL_EXPONENT: [i32; 9] = [ -127, // 12^0 -124, // 12^1 -120, // 12^2 -117, // 12^3 -113, // 12^4 -110, // 12^5 -106, // 12^6 -102, // 12^7 -99, // 12^8 ]; const BASE12_LARGE_MANTISSA: [u128; 68] = [ 236015590119408703302029793810763336632, // 12^-324 283538504658222748235708766575760177913, // 12^-315 170315197362908885300398426895467760677, // 12^-306 204609010601448705405745986119597896326, // 12^-297 245808053934833671173174941698733239342, // 12^-288 295302729833943551617529441983408590696, // 12^-279 177381702616012906692133545122052956869, // 12^-270 213098391881773806300126011269370626834, // 12^-261 256006814417050404626793229969178591795, // 12^-252 307555061533862494767405465422567274311, // 12^-243 184741402471039290909022270993420155647, // 12^-234 221940003957364890317522299802459040748, // 12^-225 266628729119434395515123988465075762881, // 12^-216 320315751663685742610118741757695693407, // 12^-207 192406461791880080316008520325217417399, // 12^-198 231148461148045387015380597263260157877, // 12^-189 277691355027891684120101092281051616669, // 12^-180 333605892395873536287594592246578306329, // 12^-171 200389550171752283164939097875653100692, // 12^-162 240738984132727062349578629363188475398, // 12^-153 289212977580839036146652597763405686112, // 12^-144 173723725516468955947099703423373843986, // 12^-135 208703862874796048578293668364396201854, // 12^-126 250727425107703285166415666163110988836, // 12^-117 301212640893244858516269504216828222245, // 12^-108 180931653158622392278312153671259457350, // 12^-99 217363142646555453321168098187951653993, // 12^-90 261130293988778746809115702919522241550, // 12^-81 313710179234688236904530296665341569850, // 12^-72 188438643123668474334468683754392032451, // 12^-63 226381702429392491474935736226666160567, // 12^-54 271964785700545191021799322274747927151, // 12^-45 326726249813466247246220462666861782844, // 12^-36 196257103731642338395610271199702162833, // 12^-27 235774449020380624184618955567855082461, // 12^-18 283248808597909657338003839260381566656, // 12^-9 170141183460469231731687303715884105728, // 12^0 204399958133082024424731518496078299136, // 12^9 245556907710782073166015043857318674432, // 12^18 295001014066853243782145636489477750784, // 12^27 177200468746272961345336076752392290304, // 12^36 212880665669732098276382446210774990848, // 12^45 255745247947835503562868389206950936576, // 12^54 307240827353347547401607574753443315712, // 12^63 184552649072141716781794491390137475072, // 12^72 221713244121518884974124815309574946401, // 12^81 266356310061270520809673995345359110719, // 12^90 319988479671385965643116043114178672868, // 12^99 192209876872921446586714266254161951235, // 12^108 230912292876569386789935113689005718149, // 12^117 277407633098725295421526662764935275289, // 12^126 333265041643201293321649737744276185517, // 12^135 200184808797092622572327630249651738267, // 12^144 240493017062571660772163375622796335712, // 12^153 288917483816076538023589582665008561757, // 12^162 173546229063471511777292289904643662141, // 12^171 208490626626972031635281014538153149532, // 12^180 250471252679363433757155530343900661758, // 12^189 300904886870600004067510516586852827477, // 12^198 180746792244690548097558883605316900733, // 12^207 217141059066909427380630585083218539864, // 12^216 260863492774290665230282703014708894052, // 12^225 313389656266867868879861721401276560157, // 12^234 188246112191795662327951607127115677904, // 12^243 226150404435492799169987273137391228527, // 12^252 271686914703601365116141326731156710883, // 12^261 326392428107359965184387801150473482685, // 12^270 196056584547032659751107943421776414785, // 12^279 ]; const BASE12_LARGE_EXPONENT: [i32; 68] = [ -1289, // 12^-324 -1257, // 12^-315 -1224, // 12^-306 -1192, // 12^-297 -1160, // 12^-288 -1128, // 12^-279 -1095, // 12^-270 -1063, // 12^-261 -1031, // 12^-252 -999, // 12^-243 -966, // 12^-234 -934, // 12^-225 -902, // 12^-216 -870, // 12^-207 -837, // 12^-198 -805, // 12^-189 -773, // 12^-180 -741, // 12^-171 -708, // 12^-162 -676, // 12^-153 -644, // 12^-144 -611, // 12^-135 -579, // 12^-126 -547, // 12^-117 -515, // 12^-108 -482, // 12^-99 -450, // 12^-90 -418, // 12^-81 -386, // 12^-72 -353, // 12^-63 -321, // 12^-54 -289, // 12^-45 -257, // 12^-36 -224, // 12^-27 -192, // 12^-18 -160, // 12^-9 -127, // 12^0 -95, // 12^9 -63, // 12^18 -31, // 12^27 2, // 12^36 34, // 12^45 66, // 12^54 98, // 12^63 131, // 12^72 163, // 12^81 195, // 12^90 227, // 12^99 260, // 12^108 292, // 12^117 324, // 12^126 356, // 12^135 389, // 12^144 421, // 12^153 453, // 12^162 486, // 12^171 518, // 12^180 550, // 12^189 582, // 12^198 615, // 12^207 647, // 12^216 679, // 12^225 711, // 12^234 744, // 12^243 776, // 12^252 808, // 12^261 840, // 12^270 873, // 12^279 ]; const BASE12_SMALL_INT_POWERS: [u128; 9] = [1, 12, 144, 1728, 20736, 248832, 2985984, 35831808, 429981696]; const BASE12_STEP: i32 = 9; const BASE12_BIAS: i32 = 324; // BASE13 const BASE13_SMALL_MANTISSA: [u128; 8] = [ 170141183460469231731687303715884105728, // 13^0 276479423123262501563991868538311671808, // 13^1 224639531287650782520743393187378233344, // 13^2 182519619171216260798104006964744814592, // 13^3 296594381153226423796919011317710323712, // 13^4 240982934686996469334996696695639638016, // 13^5 195798634433184631334684816065207205888, // 13^6 318172780953925025918862826105961709568, // 13^7 ]; const BASE13_SMALL_EXPONENT: [i32; 8] = [ -127, // 13^0 -124, // 13^1 -120, // 13^2 -116, // 13^3 -113, // 13^4 -109, // 13^5 -105, // 13^6 -102, // 13^7 ]; const BASE13_LARGE_MANTISSA: [u128; 74] = [ 234492264952419818661296823055466035238, // 13^-312 178145751691013993109826848158654507171, // 13^-304 270677660536016922109887166011364690074, // 13^-296 205636101949623162244352604410701629545, // 13^-288 312446962496257587924386799659895562352, // 13^-280 237368592984352411701605597109952160960, // 13^-272 180330922359490147340520816471555077038, // 13^-264 273997845714729128559081401928980460360, // 13^-256 208158474636564731932432542641850208607, // 13^-248 316279498110609430339960234785638219567, // 13^-240 240280202619066059925234911435300433349, // 13^-232 182542896759209079117924981191278218615, // 13^-224 277358756934885281135534847026826478882, // 13^-216 210711787240726612911538723377341283448, // 13^-208 320159044357159213189440578296814412270, // 13^-200 243227526627608078053980201967728671175, // 13^-192 184782003669985976085437039910686134984, // 13^-184 280760893750083272032555777889582843511, // 13^-176 213296419277190995686832685182416132955, // 13^-168 324086177877525444638594829459150002632, // 13^-160 246211003089480177174216643591955743445, // 13^-152 187048575904513609075482455349961378053, // 13^-144 284204761841543230201034707437221523825, // 13^-136 215912754916246372204794564138901211197, // 13^-128 328061482386525623150638173263346085618, // 13^-120 249231075457753005677502945704601914895, // 13^-112 189342950357830398121128390896356453239, // 13^-104 287690873093270135400938070638952191684, // 13^-96 218561183040489207765436578950529361150, // 13^-88 332085548758937481126223466223271077691, // 13^-80 252288192624979397908801362020362227394, // 13^-72 191665468057395263450492571375008762286, // 13^-64 291219745668138391592456499213129019442, // 13^-56 221242097302626033221832363181059870585, // 13^-48 336158975117324458944453423021025623710, // 13^-40 255382808989916127627430380985009698372, // 13^-32 194016474213776704407345321083633835842, // 13^-24 294791904084909668600573533146696407742, // 13^-16 223955896183984548959338021657683010637, // 13^-8 170141183460469231731687303715884105728, // 13^0 258515384525064083559076046211093889024, // 13^8 196396318271963640537903969427202768896, // 13^16 298407879296195459704416306334760173568, // 13^24 226702983053742437531808354380178063872, // 13^32 172228168527856562581024588413877561828, // 13^40 261686384845036905964465455013477410965, // 13^48 198805353963305641500281734389939339052, // 13^56 302068208767375943221882620634577632307, // 13^64 229483766228882688509711411881831930515, // 13^72 174340752962680465097022527378326959423, // 13^80 264896281275768246289732905498826672107, // 13^88 201243939358090266003114541899396801267, // 13^96 305773436556486878301580275426022079145, // 13^104 232298659034884347081172590621418853088, // 13^112 176479250771793883849064971202097683281, // 13^120 268145550924567936613388404500729180677, // 13^128 203712436918765324677453955129179600235, // 13^136 309524113395086409019191949184662333574, // 13^144 235148079867157707257686510259099274415, // 13^152 178643979813719299400243488890704650366, // 13^160 271434676751037481783657313824389119896, // 13^168 206211213553813977645157972930830162165, // 13^176 313320796770113796525378889251061848013, // 13^184 238032452253233081187768481790039531230, // 13^192 180835261845894060934288352757379708280, // 13^200 274764147638855414866553566635921015415, // 13^208 208740640672290674581982064710037218783, // 13^216 317164051006752246428908041221997358677, // 13^224 240952204915712388090624317255539471706, // 13^232 183053422572495239382420468754129441919, // 13^240 278134458468443185818361944895170594350, // 13^248 211301094239026043298793364640604498188, // 13^256 321054447352308147843744474962905446408, // 13^264 243907771835992919704646129069158162971, // 13^272 ]; const BASE13_LARGE_EXPONENT: [i32; 74] = [ -1282, // 13^-312 -1252, // 13^-304 -1223, // 13^-296 -1193, // 13^-288 -1164, // 13^-280 -1134, // 13^-272 -1104, // 13^-264 -1075, // 13^-256 -1045, // 13^-248 -1016, // 13^-240 -986, // 13^-232 -956, // 13^-224 -927, // 13^-216 -897, // 13^-208 -868, // 13^-200 -838, // 13^-192 -808, // 13^-184 -779, // 13^-176 -749, // 13^-168 -720, // 13^-160 -690, // 13^-152 -660, // 13^-144 -631, // 13^-136 -601, // 13^-128 -572, // 13^-120 -542, // 13^-112 -512, // 13^-104 -483, // 13^-96 -453, // 13^-88 -424, // 13^-80 -394, // 13^-72 -364, // 13^-64 -335, // 13^-56 -305, // 13^-48 -276, // 13^-40 -246, // 13^-32 -216, // 13^-24 -187, // 13^-16 -157, // 13^-8 -127, // 13^0 -98, // 13^8 -68, // 13^16 -39, // 13^24 -9, // 13^32 21, // 13^40 50, // 13^48 80, // 13^56 109, // 13^64 139, // 13^72 169, // 13^80 198, // 13^88 228, // 13^96 257, // 13^104 287, // 13^112 317, // 13^120 346, // 13^128 376, // 13^136 405, // 13^144 435, // 13^152 465, // 13^160 494, // 13^168 524, // 13^176 553, // 13^184 583, // 13^192 613, // 13^200 642, // 13^208 672, // 13^216 701, // 13^224 731, // 13^232 761, // 13^240 790, // 13^248 820, // 13^256 849, // 13^264 879, // 13^272 ]; const BASE13_SMALL_INT_POWERS: [u128; 8] = [1, 13, 169, 2197, 28561, 371293, 4826809, 62748517]; const BASE13_STEP: i32 = 8; const BASE13_BIAS: i32 = 312; // BASE14 const BASE14_SMALL_MANTISSA: [u128; 8] = [ 170141183460469231731687303715884105728, // 14^0 297747071055821155530452781502797185024, // 14^1 260528687173843511089146183814947536896, // 14^2 227962601277113072203002910838079094784, // 14^3 199467276117473938177627546983319207936, // 14^4 174533866602789695905424103610404306944, // 14^5 305434266554881967834492181318207537152, // 14^6 267254983235521721855180658653431595008, // 14^7 ]; const BASE14_SMALL_EXPONENT: [i32; 8] = [ -127, // 14^0 -124, // 14^1 -120, // 14^2 -116, // 14^3 -112, // 14^4 -108, // 14^5 -105, // 14^6 -101, // 14^7 ]; const BASE14_LARGE_MANTISSA: [u128; 72] = [ 251548413169278560512334209582633427955, // 14^-304 172868555043538834443100066630384298338, // 14^-296 237596707101714066585640360644079693184, // 14^-288 326561387705008590881101164026582541311, // 14^-280 224418808746721891131396635947419054595, // 14^-272 308449214239576126269380201889590576494, // 14^-264 211971800172033630882960469392933087940, // 14^-256 291341601754078780972414349774563326428, // 14^-248 200215143815698040798730279921859793515, // 14^-240 275182833977670641254081992250398936156, // 14^-232 189110550462878905579110756278883461660, // 14^-224 259920284847963995399800125815215983072, // 14^-216 178621854545095883446307559621296276382, // 14^-208 245504247117858718392171207907774065824, // 14^-200 337429792711562885676838629607664070711, // 14^-192 231887770468403152813044191455947332680, // 14^-184 318714821597104302344272129046782646031, // 14^-176 219026508600450572879143037057044702127, // 14^-168 301037844611736789461197056572315300910, // 14^-160 206878574807117564156377107253687360168, // 14^-152 284341291171704802743493772571841275116, // 14^-144 195404405556671025581418948604574579552, // 14^-136 268570783748031302676865943988466296381, // 14^-128 184566631641558957302915986868221103411, // 14^-120 253674960769150428442670675281025859157, // 14^-112 174329956473941702727882427159635204541, // 14^-104 239605309345945263344621501916001364416, // 14^-96 329322082262710237520775170056072850605, // 14^-88 226316007274407653805017736090948441653, // 14^-80 311056791556242112413125050076207081650, // 14^-72 213763773801352511153375590062662203372, // 14^-64 293804554217770280277607620947080882230, // 14^-56 201907728667158642949418150287074186439, // 14^-48 277509182960549548157083678768414391770, // 14^-40 190709258966464876623809832149485832940, // 14^-32 262117606830390855604604612394616145902, // 14^-24 180131893393211845729384454981934494079, // 14^-16 247579698363561878555441197267606485702, // 14^-8 170141183460469231731687303715884105728, // 14^0 233848110331081506623283076321752645632, // 14^8 321409182616407632938244080939940446208, // 14^16 220878121537715117784741212850409701376, // 14^24 303582767467198764972828371186555551744, // 14^32 208627491173467029036775346642092064768, // 14^40 286745064197610355009611023687762970225, // 14^48 197056321243220373650760726805477101625, // 14^56 270841235580262673674173137819514560921, // 14^64 186126926626483659918254253754028720893, // 14^72 255819485841579348845580110620374327715, // 14^80 175803712344053086257499345217280929659, // 14^88 241630891972710985114650364591580944199, // 14^96 332106115263742508816700348007180790592, // 14^104 228229244396512279339912293302076319311, // 14^112 313686412889065357315780098042512623701, // 14^120 215570896471654994597359469530054904893, // 14^128 296288328063653274657691113306601058431, // 14^136 203614622343740041422835873088956724196, // 14^144 279855198502973302491761604313633635665, // 14^152 192321482680456518790460799730877816261, // 14^160 264333504599995236391965677440014878764, // 14^168 181654697853512422889189735564216996803, // 14^176 249672695121914450880056351845343996855, // 14^184 171579528154314464133715598246382584383, // 14^192 235825022574310344970824197408281461914, // 14^200 324126321306564057111299587260117144567, // 14^208 222745387696552489161405202381218740358, // 14^216 306149204668634768979587047598946613225, // 14^224 210391192582005308252369450519735221250, // 14^232 289169158312782474283830561810879736710, // 14^240 198722201944671478335130298919429936059, // 14^248 273130881427012463325938578210122255044, // 14^256 187700412080445632409314398956810353518, // 14^264 ]; const BASE14_LARGE_EXPONENT: [i32; 72] = [ -1285, // 14^-304 -1254, // 14^-296 -1224, // 14^-288 -1194, // 14^-280 -1163, // 14^-272 -1133, // 14^-264 -1102, // 14^-256 -1072, // 14^-248 -1041, // 14^-240 -1011, // 14^-232 -980, // 14^-224 -950, // 14^-216 -919, // 14^-208 -889, // 14^-200 -859, // 14^-192 -828, // 14^-184 -798, // 14^-176 -767, // 14^-168 -737, // 14^-160 -706, // 14^-152 -676, // 14^-144 -645, // 14^-136 -615, // 14^-128 -584, // 14^-120 -554, // 14^-112 -523, // 14^-104 -493, // 14^-96 -463, // 14^-88 -432, // 14^-80 -402, // 14^-72 -371, // 14^-64 -341, // 14^-56 -310, // 14^-48 -280, // 14^-40 -249, // 14^-32 -219, // 14^-24 -188, // 14^-16 -158, // 14^-8 -127, // 14^0 -97, // 14^8 -67, // 14^16 -36, // 14^24 -6, // 14^32 25, // 14^40 55, // 14^48 86, // 14^56 116, // 14^64 147, // 14^72 177, // 14^80 208, // 14^88 238, // 14^96 268, // 14^104 299, // 14^112 329, // 14^120 360, // 14^128 390, // 14^136 421, // 14^144 451, // 14^152 482, // 14^160 512, // 14^168 543, // 14^176 573, // 14^184 604, // 14^192 634, // 14^200 664, // 14^208 695, // 14^216 725, // 14^224 756, // 14^232 786, // 14^240 817, // 14^248 847, // 14^256 878, // 14^264 ]; const BASE14_SMALL_INT_POWERS: [u128; 8] = [1, 14, 196, 2744, 38416, 537824, 7529536, 105413504]; const BASE14_STEP: i32 = 8; const BASE14_BIAS: i32 = 304; // BASE15 const BASE15_SMALL_MANTISSA: [u128; 8] = [ 170141183460469231731687303715884105728, // 15^0 319014718988379809496913694467282698240, // 15^1 299076299051606071403356588563077529600, // 15^2 280384030360880691940646801777885184000, // 15^3 262860028463325648694356376666767360000, // 15^4 246431276684367795650959103125094400000, // 15^5 231029321891594808422774159179776000000, // 15^6 216589989273370132896350774231040000000, // 15^7 ]; const BASE15_SMALL_EXPONENT: [i32; 8] = [ -127, // 15^0 -124, // 15^1 -120, // 15^2 -116, // 15^3 -112, // 15^4 -108, // 15^5 -104, // 15^6 -100, // 15^7 ]; const BASE15_LARGE_MANTISSA: [u128; 70] = [ 250900630150587280377850342682701393565, // 15^-296 299434584015762656519487081521438784545, // 15^-288 178678447421354466262014715708770369510, // 15^-280 213241818261213966824485132704511196490, // 15^-272 254491091184140684406056053498886823977, // 15^-264 303719580053283976738045342609656736770, // 15^-256 181235388002241613446887230826356048960, // 15^-248 216293370737313530448778168911616746705, // 15^-240 258132932759965856034693127408739651425, // 15^-232 308065895631104646134849028190499821539, // 15^-224 183828919146951883093674448351327494412, // 15^-216 219388591817396682923135459647357436704, // 15^-208 261826890148575264294539329193196343516, // 15^-200 312474408249691315911417866816293319027, // 15^-192 186459564477102023710796186076704586060, // 15^-184 222528106411894691985532295229724475420, // 15^-176 265573709142416387133758214804806317848, // 15^-168 316946007966797681726272939583274683428, // 15^-160 189127855107486501747742000280219617523, // 15^-152 225712548373888955751123878842649157480, // 15^-144 269374146206443663446975509775551676690, // 15^-136 321481597577162915672598741300570427622, // 15^-128 191834329753307055373436045708607941890, // 15^-120 228942560627082928532238637834630336646, // 15^-112 273228968630845173556739192069109710925, // 15^-104 326082092794781635112624979076905003855, // 15^-96 194579534838936734374686465136944546456, // 15^-88 232218795295605362158733969001967701715, // 15^-80 277138954685954882938577351637270128950, // 15^-72 330748422437782207809506145002547658085, // 15^-64 197364024608240385117657735223630441823, // 15^-56 235541913835671069456466721167496749113, // 15^-48 281104893779381725235703590002221275596, // 15^-40 335481528615950719408183659471355674975, // 15^-32 200188361236473853754168248068850933442, // 15^-24 238912587169125791566529710613345919103, // 15^-16 285127586615387248178740525206042107172, // 15^-8 170141183460469231731687303715884105728, // 15^0 203053114943784499590328850841600000000, // 15^8 242331495818902131179520000000000000000, // 15^16 289207845356544000000000000000000000000, // 15^24 172575953309595678001642227172851562500, // 15^32 205958864110335933831952325359648803271, // 15^40 245799330046413899594233809090775284541, // 15^48 293346493787707294402529081970820087350, // 15^56 175045565423820113080636775231191731391, // 15^64 208906195393080226844550976655564036201, // 15^72 249316789990916616866725045444974174010, // 15^80 297544367482333459204270734183314844936, // 15^88 177550518406095745907734479894927853604, // 15^96 211895703844201159681805788312089434384, // 15^104 252884585810862301272632571838697691236, // 15^112 301802313971178147521594347169174498450, // 15^120 180091317994529147280371081412973024665, // 15^128 214927993031252433012289596290523334542, // 15^136 256503437827277086943219190518379691262, // 15^144 306121192913408770879770801728425641044, // 15^152 182668477164486370906358954938714362551, // 15^160 218003675159015088778073023304915283497, // 15^168 260174076669190616934963528529542450091, // 15^176 310501876270165601037714752361776484586, // 15^184 185282516232160242762660936045505469826, // 15^192 221123371193098747019724833334214306438, // 15^200 263897243421146573236258451562349376134, // 15^208 314945248480606581688897076801472259251, // 15^216 187933962959619728504626775329093970226, // 15^224 224287710985311612370215929865332425589, // 15^232 267673689772824125386430153566188172461, // 15^240 319452206640471392649554807130291119305, // 15^248 190623352661362587893902772482928415571, // 15^256 ]; const BASE15_LARGE_EXPONENT: [i32; 70] = [ -1284, // 15^-296 -1253, // 15^-288 -1221, // 15^-280 -1190, // 15^-272 -1159, // 15^-264 -1128, // 15^-256 -1096, // 15^-248 -1065, // 15^-240 -1034, // 15^-232 -1003, // 15^-224 -971, // 15^-216 -940, // 15^-208 -909, // 15^-200 -878, // 15^-192 -846, // 15^-184 -815, // 15^-176 -784, // 15^-168 -753, // 15^-160 -721, // 15^-152 -690, // 15^-144 -659, // 15^-136 -628, // 15^-128 -596, // 15^-120 -565, // 15^-112 -534, // 15^-104 -503, // 15^-96 -471, // 15^-88 -440, // 15^-80 -409, // 15^-72 -378, // 15^-64 -346, // 15^-56 -315, // 15^-48 -284, // 15^-40 -253, // 15^-32 -221, // 15^-24 -190, // 15^-16 -159, // 15^-8 -127, // 15^0 -96, // 15^8 -65, // 15^16 -34, // 15^24 -2, // 15^32 29, // 15^40 60, // 15^48 91, // 15^56 123, // 15^64 154, // 15^72 185, // 15^80 216, // 15^88 248, // 15^96 279, // 15^104 310, // 15^112 341, // 15^120 373, // 15^128 404, // 15^136 435, // 15^144 466, // 15^152 498, // 15^160 529, // 15^168 560, // 15^176 591, // 15^184 623, // 15^192 654, // 15^200 685, // 15^208 716, // 15^216 748, // 15^224 779, // 15^232 810, // 15^240 841, // 15^248 873, // 15^256 ]; const BASE15_SMALL_INT_POWERS: [u128; 8] = [1, 15, 225, 3375, 50625, 759375, 11390625, 170859375]; const BASE15_STEP: i32 = 8; const BASE15_BIAS: i32 = 296; // BASE17 const BASE17_SMALL_MANTISSA: [u128; 8] = [ 170141183460469231731687303715884105728, // 17^0 180775007426748558714917760198126862336, // 17^1 192073445390920343634600120210509791232, // 17^2 204078035727852865111762627723666653184, // 17^3 216832912960843669181247791956395819008, // 17^4 230384970020896398505075778953670557696, // 17^5 244784030647202423411643015138274967552, // 17^6 260083032562652574874870703584417153024, // 17^7 ]; const BASE17_SMALL_EXPONENT: [i32; 8] = [ -127, // 17^0 -123, // 17^1 -119, // 17^2 -115, // 17^3 -111, // 17^4 -107, // 17^5 -103, // 17^6 -99, // 17^7 ]; const BASE17_LARGE_MANTISSA: [u128; 67] = [ 242357519372662728375060373498171096966, // 17^-280 196814917627041423628769027913700117445, // 17^-272 319660903452112403161269325795427500295, // 17^-264 259591839957616255097162958982226744872, // 17^-256 210810651677570156300974624360660789801, // 17^-248 171196178077006380843936555487576333355, // 17^-240 278051712804343163076920967240438328697, // 17^-232 225801638394791143591435147984466155468, // 17^-224 183370134237042583472660416437030762483, // 17^-216 297824288336843871393537735572731133862, // 17^-208 241858651334916724628852435647948831754, // 17^-200 196409794352921881357331916371145369426, // 17^-192 319002914345514633220184430371226516661, // 17^-184 259057496842743054458415989246502258570, // 17^-176 210376719623757394611528557965027181599, // 17^-168 170843788344482468189688357828247614648, // 17^-160 277479371939006412580670873073737346072, // 17^-152 225336848935989032116058614991615739830, // 17^-144 182992685667322765043701960137104341962, // 17^-136 297211247657519026846228781764556419486, // 17^-128 241360810165739638162969982622013142483, // 17^-120 196005504983412884662857445298594989473, // 17^-112 318346279641847361755138868550752397781, // 17^-104 258524253618237975606418771469177669493, // 17^-96 209943680774466452613153056292584472116, // 17^-88 170492123969995067410761994182235561833, // 17^-80 276908209178500704519431941303594138118, // 17^-72 224873016198504574919954139464723650485, // 17^-64 182616014036679619640392724861134514431, // 17^-56 296599468859408121472112670217716316867, // 17^-48 240863993751428088431121063565557553364, // 17^-40 195602047802007523394399179976814437447, // 17^-32 317690996553211397504541477525504659745, // 17^-24 257992108020089771434235624403421929746, // 17^-16 209511533291127649202286079418781645629, // 17^-8 170141183460469231731687303715884105728, // 17^0 276338222097818360804550122558443225088, // 17^8 224410138213025296601555690180338253824, // 17^16 182240117745863932172015090234506084352, // 17^24 295988949345058405730513287165118905920, // 17^32 240368199982629535993820184805831872348, // 17^40 195199421095732140407812372336079928061, // 17^48 317037062297446153078380490386689107619, // 17^56 257461057788947429232455063849242347039, // 17^64 209080275338955809947349984471742343690, // 17^72 339581930651806711314806824645491109283, // 17^80 275769408276943332346622203534744539377, // 17^88 223948213014292349032159641795245781843, // 17^96 181864995198918377644202761532864575404, // 17^104 295379686522363719531147616048257012833, // 17^112 239873426754333326759263874720553852658, // 17^120 194797623155139058727680168785666503632, // 17^128 316384474098117832632118586933880356805, // 17^136 256931100670110578075784008065054807112, // 17^144 208649905086942477070838417411852870460, // 17^152 338882936158725697632383782036927673666, // 17^160 275201765300840924300371814765015192837, // 17^168 223487238641092167380922055560365365575, // 17^176 181490644803170745141604509031893001355, // 17^184 294771677804553486829405243638525556429, // 17^192 239379671965861754658715697694088165244, // 17^200 194396652274299323679629299288271234884, // 17^208 315733229184507643855046849844924656388, // 17^216 256402234413519915955050497805856036474, // 17^224 208220420707848135466354215936729966175, // 17^232 338185380473947645648707735110624890484, // 17^240 274635290759447542459052551448368297186, // 17^248 ]; const BASE17_LARGE_EXPONENT: [i32; 67] = [ -1272, // 17^-280 -1239, // 17^-272 -1207, // 17^-264 -1174, // 17^-256 -1141, // 17^-248 -1108, // 17^-240 -1076, // 17^-232 -1043, // 17^-224 -1010, // 17^-216 -978, // 17^-208 -945, // 17^-200 -912, // 17^-192 -880, // 17^-184 -847, // 17^-176 -814, // 17^-168 -781, // 17^-160 -749, // 17^-152 -716, // 17^-144 -683, // 17^-136 -651, // 17^-128 -618, // 17^-120 -585, // 17^-112 -553, // 17^-104 -520, // 17^-96 -487, // 17^-88 -454, // 17^-80 -422, // 17^-72 -389, // 17^-64 -356, // 17^-56 -324, // 17^-48 -291, // 17^-40 -258, // 17^-32 -226, // 17^-24 -193, // 17^-16 -160, // 17^-8 -127, // 17^0 -95, // 17^8 -62, // 17^16 -29, // 17^24 3, // 17^32 36, // 17^40 69, // 17^48 101, // 17^56 134, // 17^64 167, // 17^72 199, // 17^80 232, // 17^88 265, // 17^96 298, // 17^104 330, // 17^112 363, // 17^120 396, // 17^128 428, // 17^136 461, // 17^144 494, // 17^152 526, // 17^160 559, // 17^168 592, // 17^176 625, // 17^184 657, // 17^192 690, // 17^200 723, // 17^208 755, // 17^216 788, // 17^224 821, // 17^232 853, // 17^240 886, // 17^248 ]; const BASE17_SMALL_INT_POWERS: [u128; 8] = [1, 17, 289, 4913, 83521, 1419857, 24137569, 410338673]; const BASE17_STEP: i32 = 8; const BASE17_BIAS: i32 = 280; // BASE18 const BASE18_SMALL_MANTISSA: [u128; 7] = [ 170141183460469231731687303715884105728, // 18^0 191408831393027885698148216680369618944, // 18^1 215334935317156371410416743765415821312, // 18^2 242251802231800917836718836736092798976, // 18^3 272533277510776032566308691328104398848, // 18^4 306599937199623036637097277744117448704, // 18^5 172462464674787958108367218731066064896, // 18^6 ]; const BASE18_SMALL_EXPONENT: [i32; 7] = [ -127, // 18^0 -123, // 18^1 -119, // 18^2 -115, // 18^3 -111, // 18^4 -107, // 18^5 -102, // 18^6 ]; const BASE18_LARGE_MANTISSA: [u128; 75] = [ 259764989429046712145887613713888779974, // 18^-273 296222660952677279411722167462707735076, // 18^-266 337797118290463899238253918549284876092, // 18^-259 192603247770383575639211190527648274245, // 18^-252 219634857984796466920734002291401705412, // 18^-245 250460318818255417964791343261171179660, // 18^-238 285612092170198511649999639102587856294, // 18^-231 325697370261002112643262654266086944683, // 18^-224 185704281966673733437923590446998072591, // 18^-217 211767631486382365261996259087726574961, // 18^-210 241488937521646207617474790890828249100, // 18^-203 275381589414827976227270551469877695982, // 18^-196 314031030021154964119856834958393443507, // 18^-189 179052434161812488744424286609186187994, // 18^-182 204182205669996766442639895844185984708, // 18^-175 232838907258801165579649662968151663564, // 18^-168 265517538884334791214783518037108753711, // 18^-161 302782573089615796089597203369720463425, // 18^-154 172638852694972345186098175788410725025, // 18^-147 196868486555962367745019627988939060464, // 18^-140 224498717373391335032231518045098273537, // 18^-133 256006814417050404626793229969178591795, // 18^-126 291937031065346039954998156631577529912, // 18^-119 332910005936047335476283449703688561122, // 18^-112 189816741726628588213403698819375225722, // 18^-105 216457269515865090355509585365869594574, // 18^-98 246836760024792608106756526472045881483, // 18^-91 281479971709018296242657937208050445965, // 18^-84 320985312176969416466104839150917967197, // 18^-77 183017587375374702561553597022155160742, // 18^-70 208703862874796048578293668364396201854, // 18^-63 237995173051452727716558620615765508935, // 18^-56 271397479737933588417468230506889186025, // 18^-49 309487755838552588810803796052767101096, // 18^-42 176461975819512133258798291874254633040, // 18^-35 201228179937237770199942876645925476060, // 18^-28 229470287934835004924643178169318563534, // 18^-21 261676138308856451194147028266269550444, // 18^-14 298402037041419227483658365640566588740, // 18^-7 170141183460469231731687303715884105728, // 18^0 194020272759136452871913121072449323008, // 18^7 221250760550139932836609227367108313088, // 18^14 252303011164126931290527343657214803968, // 18^21 287713403941314941508226937857819803648, // 18^28 328093598350474163167634651360244400128, // 18^35 187070549727531559196917812917453861026, // 18^42 213325653114257310428744028742785781912, // 18^49 243265625417291205836310243227923719532, // 18^56 277407633098725295421526662764935275289, // 18^63 316341426247257477645159711999449660471, // 18^70 180369762796928745579122531717097251784, // 18^77 205684419630781050995309380627725821797, // 18^84 234551954955343535589691141355422293223, // 18^91 267471010551644448060009348077202513313, // 18^98 305010211912915299914630616083972269987, // 18^105 173908995182860443486855135343139262701, // 18^112 198316891856377323275537495574245323224, // 18^119 226150404435492799169987273137391228527, // 18^126 257890313566309108293837274983090159159, // 18^133 294084876820548989626661915132664622178, // 18^140 335359298992515654651080492391625827617, // 18^147 191213265769831372286179520084128641258, // 18^154 218049793855157992570938056229892893589, // 18^161 248652793041613380567795520750960012282, // 18^168 283550882549632193861238568804430594202, // 18^175 323346872605688987884591669129361771279, // 18^182 184364088525767284952804747951506893851, // 18^189 210239343674659878049714940191476577896, // 18^196 239746156543789930881397013133212694240, // 18^203 273394211439632029990640781047045990695, // 18^210 311764726184655516350818907233192566650, // 18^217 177760245875679923341865534533290364422, // 18^224 202708660472811443153981984577454872377, // 18^231 231158551948781603682221903513060749406, // 18^238 263601347936609267755115798860540547258, // 18^245 ]; const BASE18_LARGE_EXPONENT: [i32; 75] = [ -1266, // 18^-273 -1237, // 18^-266 -1208, // 18^-259 -1178, // 18^-252 -1149, // 18^-245 -1120, // 18^-238 -1091, // 18^-231 -1062, // 18^-224 -1032, // 18^-217 -1003, // 18^-210 -974, // 18^-203 -945, // 18^-196 -916, // 18^-189 -886, // 18^-182 -857, // 18^-175 -828, // 18^-168 -799, // 18^-161 -770, // 18^-154 -740, // 18^-147 -711, // 18^-140 -682, // 18^-133 -653, // 18^-126 -624, // 18^-119 -595, // 18^-112 -565, // 18^-105 -536, // 18^-98 -507, // 18^-91 -478, // 18^-84 -449, // 18^-77 -419, // 18^-70 -390, // 18^-63 -361, // 18^-56 -332, // 18^-49 -303, // 18^-42 -273, // 18^-35 -244, // 18^-28 -215, // 18^-21 -186, // 18^-14 -157, // 18^-7 -127, // 18^0 -98, // 18^7 -69, // 18^14 -40, // 18^21 -11, // 18^28 18, // 18^35 48, // 18^42 77, // 18^49 106, // 18^56 135, // 18^63 164, // 18^70 194, // 18^77 223, // 18^84 252, // 18^91 281, // 18^98 310, // 18^105 340, // 18^112 369, // 18^119 398, // 18^126 427, // 18^133 456, // 18^140 485, // 18^147 515, // 18^154 544, // 18^161 573, // 18^168 602, // 18^175 631, // 18^182 661, // 18^189 690, // 18^196 719, // 18^203 748, // 18^210 777, // 18^217 807, // 18^224 836, // 18^231 865, // 18^238 894, // 18^245 ]; const BASE18_SMALL_INT_POWERS: [u128; 7] = [1, 18, 324, 5832, 104976, 1889568, 34012224]; const BASE18_STEP: i32 = 7; const BASE18_BIAS: i32 = 273; // BASE19 const BASE19_SMALL_MANTISSA: [u128; 7] = [ 170141183460469231731687303715884105728, // 19^0 202042655359307212681378673162612375552, // 19^1 239925653239177315059137174380602195968, // 19^2 284911713221523061632725394576965107712, // 19^3 338332659450558635688861406060146065408, // 19^4 200885016548769189940261459848211726336, // 19^5 238550957151663413054060483569751425024, // 19^6 ]; const BASE19_SMALL_EXPONENT: [i32; 7] = [ -127, // 19^0 -123, // 19^1 -119, // 19^2 -115, // 19^3 -111, // 19^4 -106, // 19^5 -102, // 19^6 ]; const BASE19_LARGE_MANTISSA: [u128; 74] = [ 211773375714873706954526795446522416463, // 19^-273 176297720171655089222657736919708805072, // 19^-266 293529685049453215881543661471874663538, // 19^-259 244358452058655253685245151337508023797, // 19^-252 203424239979142604035433607238695466107, // 19^-245 338694414393807804581041366088196084612, // 19^-238 281957318246159342222500231430112814088, // 19^-231 234724654242834897063227749239967575385, // 19^-224 195404267752744776874588226122954622761, // 19^-217 325341434449269614607198466720898964379, // 19^-210 270841190386491955899443752473167688523, // 19^-203 225470667559284387835624717321131334248, // 19^-196 187700481810335462307725392489901825033, // 19^-189 312514893872556142260088491662230499613, // 19^-182 260163314313871975296322899252180920269, // 19^-175 216581518007204247993872678149555585108, // 19^-168 180300416551865148993646942230063074210, // 19^-161 300194037865176954165930472692882676095, // 19^-154 249906412012854191998973084780461202007, // 19^-147 208042821933683442841807340743863291908, // 19^-140 173192097831823827445985218112992713522, // 19^-133 288358929883670982310136287441393538062, // 19^-126 240053886651337192078493312543483732688, // 19^-119 199840762759316398351061941853830886312, // 19^-112 332728047167428932050765437002481330484, // 19^-105 276990419380016367557580152018464109110, // 19^-98 230589795725005243268941857960660823918, // 19^-91 191962068621409314298003076822671000161, // 19^-84 319610290416807823632571053703933063036, // 19^-77 266070110813870135824430347248350305665, // 19^-70 221498825260546806854707890357129976717, // 19^-63 184393990898599943457278294759382590034, // 19^-56 307009699392470911375170613720126268120, // 19^-49 255580333886495993526502175170654921405, // 19^-42 212766265035907553834903279232863277537, // 19^-35 177124283582141234157272719875613305569, // 19^-28 294905884907949220984741236292709278206, // 19^-21 245504114948215358970059027289947453449, // 19^-14 204377984777481442195434041001194890061, // 19^-7 170141183460469231731687303715884105728, // 19^0 283279261617600303001696824239079817216, // 19^7 235825149533115640143913831779140632576, // 19^14 196320411295724208786653789764804673536, // 19^21 326866782169983241283381922259938632192, // 19^28 272111016325296008481488740678554545334, // 19^35 226527775976573799542251126784141726274, // 19^42 188580506522192103284103254483314456872, // 19^49 313980104972594785419533005246072709649, // 19^56 261383077542535819285819131850454151532, // 19^63 217596950072905364683647533344696965413, // 19^70 181145746412467300065049161663171614429, // 19^77 301601483222404786925353682146130769038, // 19^84 251078086246727305139312855014591629283, // 19^91 209018220732132084019166621358085321302, // 19^98 174004100680832526758226172220060851297, // 19^105 289710886904423785696066284771374024143, // 19^112 241179367792317286239104434314982328918, // 19^119 200777706596478115292553836948931709029, // 19^126 334288026667806625723834320874258952107, // 19^133 278289075684203471850125042859239363909, // 19^140 231670904929322723497179168675130067798, // 19^147 192862073578757583112120353708241916963, // 19^154 321108767943438131876044073228689471164, // 19^161 267317567774791732969648063348207624890, // 19^168 222537311885602256946640972609673172416, // 19^175 185258513286308067365753274779077551187, // 19^182 308449099652072036761706748552096805527, // 19^189 256778610031103646805005837172547824357, // 19^196 213763809470930565948441961387708938512, // 19^203 177954722295557497937779873950595261616, // 19^210 296288537013515928119667265056482304979, // 19^217 246655149223317717362685108852956230915, // 19^224 205336201162591117777390249036062770913, // 19^231 170938882243688352586356584716130516258, // 19^238 ]; const BASE19_LARGE_EXPONENT: [i32; 74] = [ -1287, // 19^-273 -1257, // 19^-266 -1228, // 19^-259 -1198, // 19^-252 -1168, // 19^-245 -1139, // 19^-238 -1109, // 19^-231 -1079, // 19^-224 -1049, // 19^-217 -1020, // 19^-210 -990, // 19^-203 -960, // 19^-196 -930, // 19^-189 -901, // 19^-182 -871, // 19^-175 -841, // 19^-168 -811, // 19^-161 -782, // 19^-154 -752, // 19^-147 -722, // 19^-140 -692, // 19^-133 -663, // 19^-126 -633, // 19^-119 -603, // 19^-112 -574, // 19^-105 -544, // 19^-98 -514, // 19^-91 -484, // 19^-84 -455, // 19^-77 -425, // 19^-70 -395, // 19^-63 -365, // 19^-56 -336, // 19^-49 -306, // 19^-42 -276, // 19^-35 -246, // 19^-28 -217, // 19^-21 -187, // 19^-14 -157, // 19^-7 -127, // 19^0 -98, // 19^7 -68, // 19^14 -38, // 19^21 -9, // 19^28 21, // 19^35 51, // 19^42 81, // 19^49 110, // 19^56 140, // 19^63 170, // 19^70 200, // 19^77 229, // 19^84 259, // 19^91 289, // 19^98 319, // 19^105 348, // 19^112 378, // 19^119 408, // 19^126 437, // 19^133 467, // 19^140 497, // 19^147 527, // 19^154 556, // 19^161 586, // 19^168 616, // 19^175 646, // 19^182 675, // 19^189 705, // 19^196 735, // 19^203 765, // 19^210 794, // 19^217 824, // 19^224 854, // 19^231 884, // 19^238 ]; const BASE19_SMALL_INT_POWERS: [u128; 7] = [1, 19, 361, 6859, 130321, 2476099, 47045881]; const BASE19_STEP: i32 = 7; const BASE19_BIAS: i32 = 273; // BASE20 const BASE20_SMALL_MANTISSA: [u128; 7] = [ 170141183460469231731687303715884105728, // 20^0 212676479325586539664609129644855132160, // 20^1 265845599156983174580761412056068915200, // 20^2 332306998946228968225951765070086144000, // 20^3 207691874341393105141219853168803840000, // 20^4 259614842926741381426524816461004800000, // 20^5 324518553658426726783156020576256000000, // 20^6 ]; const BASE20_SMALL_EXPONENT: [i32; 7] = [ -127, // 20^0 -123, // 20^1 -119, // 20^2 -115, // 20^3 -110, // 20^4 -106, // 20^5 -102, // 20^6 ]; const BASE20_LARGE_MANTISSA: [u128; 72] = [ 219444962751747547330237450047488370802, // 20^-266 261598781051334795153424084243164504531, // 20^-259 311850048364799970571308236412006025948, // 20^-252 185877113559722882849757812268737570016, // 20^-245 221582786512044528543660416923448526878, // 20^-238 264147265567832623176169892458258303259, // 20^-231 314888078651228693933689466069052580904, // 20^-224 187687920720117505749278942387731421532, // 20^-217 223741436863085634409521749481834675708, // 20^-210 266720577315194170963194071628850311885, // 20^-203 317955705303185189918510999237120523316, // 20^-196 189516368689051383685178160212707831452, // 20^-189 225921116696657399755928707376370229068, // 20^-182 269318958159276723570738682003462587676, // 20^-175 321053216647239593947814323906257853121, // 20^-168 191362629322552438943275406304751547051, // 20^-161 228122030881109760932058580285014566244, // 20^-154 271942652322184754529069161754863937192, // 20^-147 324180903818827574883781864350871964922, // 20^-140 193226876150862917234767594546599367214, // 20^-133 230344386280611654799899571593522271174, // 20^-126 274591906405224388599276031963255728690, // 20^-119 327339060789614187001318969682759915221, // 20^-112 195109284394749514461349826862072894109, // 20^-105 232588391774594204975783618524161450993, // 20^-98 277266969412081485957841418414308370343, // 20^-91 330527984395124299475957654016385519914, // 20^-84 197010030981972396061395200500718069025, // 20^-77 234854258277383322788948059678933702737, // 20^-70 279968092772225526319680285071055534765, // 20^-63 333747974362642200374222141588992517906, // 20^-56 198929294563914656862152899258728336040, // 20^-49 237142198758023568227473377297792835283, // 20^-42 282695530364541492733327600118866962532, // 20^-35 336999333339382997433337688587745383420, // 20^-28 200867255532373784442745261542645325315, // 20^-21 239452428260295134118491722992235809940, // 20^-14 285449538541191976211657193889899027276, // 20^-7 170141183460469231731687303715884105728, // 20^0 202824096036516704239472512860160000000, // 20^7 241785163922925834941235200000000000000, // 20^14 288230376151711744000000000000000000000, // 20^21 171798691840000000000000000000000000000, // 20^28 204800000000000000000000000000000000000, // 20^35 244140625000000000000000000000000000000, // 20^42 291038304567337036132812500000000000000, // 20^49 173472347597680709441192448139190673828, // 20^56 206795153138256918717852173017490713391, // 20^63 246519032881566189191165176650870696772, // 20^70 293873587705571876992184134305561419454, // 20^77 175162308040602133865466197911239516410, // 20^84 208809742975952784854729411496209521782, // 20^91 248920611114445668285762562151204969623, // 20^98 296736492054993710858538820923811161069, // 20^105 176868732008334225927912486150152183216, // 20^112 210843958864610464486971481025400380154, // 20^119 251345585423243599518503524095297312920, // 20^126 299627286700300692937974362486955300474, // 20^133 178591779887855465971216179422709524914, // 20^140 212897992000407535995502685812365442412, // 20^147 253794183731564922327402455583054354682, // 20^154 302546243347602990063908643225496238091, // 20^161 180331613628627651967947866455016278082, // 20^168 214972035442146840057310898846407268146, // 20^175 256266636183436918326986907537468991453, // 20^182 305493636349960468205197939321361769978, // 20^189 182088396757817547443627082897044283139, // 20^196 217066284129402097992452481862359384464, // 20^203 258763175164940474024358370140027266101, // 20^210 308469742733169167070816004443201143863, // 20^217 183862294395666818064937594201088633455, // 20^224 219180934900840303975269310714112083263, // 20^231 ]; const BASE20_LARGE_EXPONENT: [i32; 72] = [ -1277, // 20^-266 -1247, // 20^-259 -1217, // 20^-252 -1186, // 20^-245 -1156, // 20^-238 -1126, // 20^-231 -1096, // 20^-224 -1065, // 20^-217 -1035, // 20^-210 -1005, // 20^-203 -975, // 20^-196 -944, // 20^-189 -914, // 20^-182 -884, // 20^-175 -854, // 20^-168 -823, // 20^-161 -793, // 20^-154 -763, // 20^-147 -733, // 20^-140 -702, // 20^-133 -672, // 20^-126 -642, // 20^-119 -612, // 20^-112 -581, // 20^-105 -551, // 20^-98 -521, // 20^-91 -491, // 20^-84 -460, // 20^-77 -430, // 20^-70 -400, // 20^-63 -370, // 20^-56 -339, // 20^-49 -309, // 20^-42 -279, // 20^-35 -249, // 20^-28 -218, // 20^-21 -188, // 20^-14 -158, // 20^-7 -127, // 20^0 -97, // 20^7 -67, // 20^14 -37, // 20^21 -6, // 20^28 24, // 20^35 54, // 20^42 84, // 20^49 115, // 20^56 145, // 20^63 175, // 20^70 205, // 20^77 236, // 20^84 266, // 20^91 296, // 20^98 326, // 20^105 357, // 20^112 387, // 20^119 417, // 20^126 447, // 20^133 478, // 20^140 508, // 20^147 538, // 20^154 568, // 20^161 599, // 20^168 629, // 20^175 659, // 20^182 689, // 20^189 720, // 20^196 750, // 20^203 780, // 20^210 810, // 20^217 841, // 20^224 871, // 20^231 ]; const BASE20_SMALL_INT_POWERS: [u128; 7] = [1, 20, 400, 8000, 160000, 3200000, 64000000]; const BASE20_STEP: i32 = 7; const BASE20_BIAS: i32 = 266; // BASE21 const BASE21_SMALL_MANTISSA: [u128; 7] = [ 170141183460469231731687303715884105728, // 21^0 223310303291865866647839586127097888768, // 21^1 293094773070573949975289456791815979008, // 21^2 192343444827564154671283706019629236224, // 21^3 252450771336177953006059864150763372544, // 21^4 331341637378733563320453571697876926464, // 21^5 217442949529793900929047656426731732992, // 21^6 ]; const BASE21_SMALL_EXPONENT: [i32; 7] = [ -127, // 21^0 -123, // 21^1 -119, // 21^2 -114, // 21^3 -110, // 21^4 -106, // 21^5 -101, // 21^6 ]; const BASE21_LARGE_MANTISSA: [u128; 72] = [ 265792046637109917415346664544311644566, // 21^-266 222919047571269915259553685343512655124, // 21^-259 186961582932271121624867982904669033286, // 21^-252 313608315425491608924946770674906010971, // 21^-245 263022418727710133477288744271513099136, // 21^-238 220596168374913987040298637494305910349, // 21^-231 185013390634471631571140317809259206000, // 21^-224 310340428541697166126551714455108139315, // 21^-217 260281651120390792657949798157903984485, // 21^-210 218297494233351046265168261721480533031, // 21^-203 183085499048559996047315841365348324923, // 21^-196 307106593958686861611740529249331599561, // 21^-189 257569443082684061423017949935163592863, // 21^-182 216022772923099798407562907443165238977, // 21^-175 181177696635406520735133253192775193924, // 21^-168 303906456841905544859103298218510174905, // 21^-161 254885497015839035366704878377106222377, // 21^-154 213771754848918589809660748287013123679, // 21^-147 179289774060178761532557823153782969422, // 21^-140 300739666054273966520895709937608788747, // 21^-133 252229518422167527105381200194678741672, // 21^-126 211544193016418411141172507362190098875, // 21^-119 177421524169372127003871154186445625381, // 21^-112 297605874117660039208334869188863219128, // 21^-105 249601215872730120248972738434931034589, // 21^-98 209339843004961281067680970866486691183, // 21^-91 175572741968079828414917198043029764862, // 21^-84 294504737174751578579986057113044461622, // 21^-77 247000300975358943781849899984000214119, // 21^-70 207158462940841036386486635842909509778, // 21^-63 173743224597499683284324187350601048284, // 21^-56 291435914951326341195521446658582144907, // 21^-49 244426488343013658131803347774089798564, // 21^-42 204999813470743585875109991683322467328, // 21^-35 171932771312675304370424739613867083896, // 21^-28 288399070718915219190771894363169343679, // 21^-21 241879495562467180767563428674995339169, // 21^-14 202863657735483715761934442388454879916, // 21^-7 170141183460469231731687303715884105728, // 21^0 285393871257854494969375049060085399552, // 21^7 239359043163317715346200180609446313984, // 21^14 200749761344015565073276401119215484928, // 21^21 336736528915531181897146582027467512352, // 21^28 282419986820723101796180638245767114566, // 21^35 236864854587323684235605162154192799609, // 21^42 198657892347713919139770232958888414539, // 21^49 333227639539799771559276379603105082665, // 21^56 279477091096160878422591085338554667498, // 21^63 234396656158058199668034426556911280906, // 21^70 196587821214923499260650393397155679946, // 21^77 329755313778627116894330266634709348105, // 21^84 276564861173063847678827937275753188756, // 21^91 231954177050879743842271364358265802922, // 21^98 194539320805773455930561882331086488568, // 21^105 326319170628861950820780822968026849107, // 21^112 273682977505152590337309001442167333935, // 21^119 229537149263215762988196018745023784859, // 21^126 192512166347254302133159603748230049238, // 21^133 322918833057513041780316846850363342758, // 21^140 270831123875909826489436864951365328546, // 21^147 227145307585155914742230901032159391581, // 21^154 190506135408554552002160365053046193282, // 21^161 319553927960379009120613001977483142041, // 21^168 268008987363883357189628558586004761583, // 21^175 224778389570351742159039695242233732277, // 21^182 188521007876654358646847770858984158583, // 21^189 316224086121109227441755855330741121363, // 21^196 265216258308350559209803685525363124313, // 21^203 222436135507219581307712678266362793773, // 21^210 186556565932173473138426942632517671964, // 21^217 312928942170691327838033505846831903751, // 21^224 262452630275340665419193194878653363790, // 21^231 ]; const BASE21_LARGE_EXPONENT: [i32; 72] = [ -1296, // 21^-266 -1265, // 21^-259 -1234, // 21^-252 -1204, // 21^-245 -1173, // 21^-238 -1142, // 21^-231 -1111, // 21^-224 -1081, // 21^-217 -1050, // 21^-210 -1019, // 21^-203 -988, // 21^-196 -958, // 21^-189 -927, // 21^-182 -896, // 21^-175 -865, // 21^-168 -835, // 21^-161 -804, // 21^-154 -773, // 21^-147 -742, // 21^-140 -712, // 21^-133 -681, // 21^-126 -650, // 21^-119 -619, // 21^-112 -589, // 21^-105 -558, // 21^-98 -527, // 21^-91 -496, // 21^-84 -466, // 21^-77 -435, // 21^-70 -404, // 21^-63 -373, // 21^-56 -343, // 21^-49 -312, // 21^-42 -281, // 21^-35 -250, // 21^-28 -220, // 21^-21 -189, // 21^-14 -158, // 21^-7 -127, // 21^0 -97, // 21^7 -66, // 21^14 -35, // 21^21 -5, // 21^28 26, // 21^35 57, // 21^42 88, // 21^49 118, // 21^56 149, // 21^63 180, // 21^70 211, // 21^77 241, // 21^84 272, // 21^91 303, // 21^98 334, // 21^105 364, // 21^112 395, // 21^119 426, // 21^126 457, // 21^133 487, // 21^140 518, // 21^147 549, // 21^154 580, // 21^161 610, // 21^168 641, // 21^175 672, // 21^182 703, // 21^189 733, // 21^196 764, // 21^203 795, // 21^210 826, // 21^217 856, // 21^224 887, // 21^231 ]; const BASE21_SMALL_INT_POWERS: [u128; 7] = [1, 21, 441, 9261, 194481, 4084101, 85766121]; const BASE21_STEP: i32 = 7; const BASE21_BIAS: i32 = 266; // BASE22 const BASE22_SMALL_MANTISSA: [u128; 7] = [ 170141183460469231731687303715884105728, // 22^0 233944127258145193631070042609340645376, // 22^1 321673174979949641242721308587843387392, // 22^2 221150307798715378354370899654142328832, // 22^3 304081673223233645237259987024445702144, // 22^4 209056150340973131100616241079306420224, // 22^5 287452206718838055263347331484046327808, // 22^6 ]; const BASE22_SMALL_EXPONENT: [i32; 7] = [ -127, // 22^0 -123, // 22^1 -119, // 22^2 -114, // 22^3 -110, // 22^4 -105, // 22^5 -101, // 22^6 ]; const BASE22_LARGE_MANTISSA: [u128; 70] = [ 170993699408656992611557257796811971606, // 22^-259 198613611477559667549559644399735817047, // 22^-252 230694854843066209807480559654047740794, // 22^-245 267958050080955588510051414081700394572, // 22^-238 311240216657766425412953324616068813788, // 22^-231 180756787183491671385793896073455879749, // 22^-224 209953690842110549054787911387661891558, // 22^-217 243866650791248218437107825156701479612, // 22^-210 283257432291885574825362738029166670391, // 22^-203 329010845428281790557809997379933231677, // 22^-196 191077310017213090920037889613280023761, // 22^-189 221941245467987325560887198530024987097, // 22^-182 257790506028392555656294807759853932728, // 22^-175 299430350849140679073407301022315056449, // 22^-168 173898054647064197545039940705011138943, // 22^-161 201987095324676314922450395008827008097, // 22^-154 234613243722037545951821958217296505941, // 22^-147 272509360270263083361596599896866808472, // 22^-140 316526681344939644363801942778159729297, // 22^-133 183826970023851061892407973678416422311, // 22^-126 213519787744680626489456759979414929795, // 22^-119 248008764723795396613310192753363562635, // 22^-112 288068604926548520494484698905215058937, // 22^-105 334599147077506390730919115808572688418, // 22^-98 194322788582847037606425160078121997271, // 22^-91 225710952896522753756036626884027523975, // 22^-84 262169118861406100263284327408804984594, // 22^-77 304516223083230613247976703037939646270, // 22^-70 176851740822108453297561032060281913714, // 22^-63 205417878332621336576645714920472857997, // 22^-56 238598187060653380400994399373084663429, // 22^-49 277137975188549744820727493204211809261, // 22^-42 321902937477411396463387072352875080544, // 22^-35 186949300409097210175717446748311788922, // 22^-28 217146455371525722164937611369356262209, // 22^-21 252221233121680633945860233133208134270, // 22^-14 292961496095243353908740467141073506540, // 22^-7 170141183460469231731687303715884105728, // 22^0 197623392119201162993551290395281850368, // 22^7 229544689406569328704727047276706398208, // 22^14 266622103131276669014944105065242165248, // 22^21 309688479667831891620434363534947647488, // 22^28 179855595827611186243917689814617910464, // 22^35 208906933736774069538597567757512183241, // 22^42 242650815297018604365857953016443636978, // 22^49 281845207868958552685905724295461354592, // 22^56 327370510177191550022527822209865447333, // 22^63 190124664073591590972067520727552350138, // 22^70 220834722526051754798575401303998056567, // 22^77 256505250966711193359488809204377717494, // 22^84 297937493800295372760917121026044042670, // 22^91 173031058579617612943075122066206208260, // 22^98 200980056932689281584830175015332323410, // 22^105 233443542542281837469979323535186565406, // 22^112 271150722048713022289973166238934106646, // 22^119 314948587854906379895896832699151980516, // 22^126 182910471789153927982518189465009158829, // 22^133 212455251303071888680280266327561854998, // 22^140 246772278069909496307705991140052073087, // 22^147 286632393646709698979385809127728921005, // 22^154 332930950470730393610585733499849696474, // 22^161 193353961796034982060992467369794830962, // 22^168 224585635486054469192295827945894724481, // 22^175 260862033537650797156363766298784568546, // 22^182 302998009619470597652934458975103615488, // 22^189 175970018688269509849993361647138860754, // 22^196 204393735233038880379975139336743154541, // 22^203 237408618319925875163860351801153447367, // 22^210 275756260280259146490263920764281465178, // 22^217 320298039817924375055421761218548035863, // 22^224 ]; const BASE22_LARGE_EXPONENT: [i32; 70] = [ -1282, // 22^-259 -1251, // 22^-252 -1220, // 22^-245 -1189, // 22^-238 -1158, // 22^-231 -1126, // 22^-224 -1095, // 22^-217 -1064, // 22^-210 -1033, // 22^-203 -1002, // 22^-196 -970, // 22^-189 -939, // 22^-182 -908, // 22^-175 -877, // 22^-168 -845, // 22^-161 -814, // 22^-154 -783, // 22^-147 -752, // 22^-140 -721, // 22^-133 -689, // 22^-126 -658, // 22^-119 -627, // 22^-112 -596, // 22^-105 -565, // 22^-98 -533, // 22^-91 -502, // 22^-84 -471, // 22^-77 -440, // 22^-70 -408, // 22^-63 -377, // 22^-56 -346, // 22^-49 -315, // 22^-42 -284, // 22^-35 -252, // 22^-28 -221, // 22^-21 -190, // 22^-14 -159, // 22^-7 -127, // 22^0 -96, // 22^7 -65, // 22^14 -34, // 22^21 -3, // 22^28 29, // 22^35 60, // 22^42 91, // 22^49 122, // 22^56 153, // 22^63 185, // 22^70 216, // 22^77 247, // 22^84 278, // 22^91 310, // 22^98 341, // 22^105 372, // 22^112 403, // 22^119 434, // 22^126 466, // 22^133 497, // 22^140 528, // 22^147 559, // 22^154 590, // 22^161 622, // 22^168 653, // 22^175 684, // 22^182 715, // 22^189 747, // 22^196 778, // 22^203 809, // 22^210 840, // 22^217 871, // 22^224 ]; const BASE22_SMALL_INT_POWERS: [u128; 7] = [1, 22, 484, 10648, 234256, 5153632, 113379904]; const BASE22_STEP: i32 = 7; const BASE22_BIAS: i32 = 259; // BASE23 const BASE23_SMALL_MANTISSA: [u128; 7] = [ 170141183460469231731687303715884105728, // 23^0 244577951224424520614300499091583401984, // 23^1 175790402442555124191528483722075570176, // 23^2 252698703511172991025322195350483632128, // 23^3 181627193148655587299450327908160110592, // 23^4 261089090151192406742959846367980158976, // 23^5 187657783546169542346502389576985739264, // 23^6 ]; const BASE23_SMALL_EXPONENT: [i32; 7] = [ -127, // 23^0 -123, // 23^1 -118, // 23^2 -114, // 23^3 -109, // 23^4 -105, // 23^5 -100, // 23^6 ]; const BASE23_LARGE_MANTISSA: [u128; 69] = [ 177660070384959299518117426820409879479, // 23^-252 281679224484842507661590842703493245235, // 23^-245 223300557447880794264720046366338636067, // 23^-238 177021003404592607294928857171705382014, // 23^-231 280665986726726659567026238400885338462, // 23^-224 222497315545222527698408099502330410230, // 23^-217 176384235233432227183413281705333529169, // 23^-210 279656393720034524921314175179274359595, // 23^-203 221696963010873772243653930801015609536, // 23^-196 175749757602354687973874432000535316950, // 23^-189 278650432354108872233513992865613552171, // 23^-182 220899489451391157505367921930602163472, // 23^-175 175117562271981659025201047697761937562, // 23^-168 277648089565453253577594524944387660343, // 23^-161 220104884510717915806439152820624263438, // 23^-154 174487641032572953025011241897191693675, // 23^-147 276649352337562360960754521131809259049, // 23^-140 219313137870049397588841701361789229875, // 23^-133 173859985703919913633146478806481352851, // 23^-126 275654207700752992922523689325318624601, // 23^-119 218524239247699070573788964393354746146, // 23^-112 173234588135239186624038395745277208596, // 23^-105 274662642731995629169562809047557585825, // 23^-98 217738178398965000940790150805824878955, // 23^-91 172611440205066873148451849294509762826, // 23^-84 273674644554746611058977369746265857416, // 23^-77 216954945115996814791722634413562231827, // 23^-70 171990533821153063740069798803230423676, // 23^-63 272690200338780925750826785583705218666, // 23^-56 216174529227663138172270874689475697712, // 23^-49 171371860920356751697330024074687407971, // 23^-42 271709297300025591858350535820526217684, // 23^-35 215396920599419513929297198496715326537, // 23^-28 170755413468541124475850272054650469150, // 23^-21 270731922700393644432243678371210997948, // 23^-14 214622109133176793688901966303396671549, // 23^-7 170141183460469231731687303715884105728, // 23^0 269758063847618717123097185016917000192, // 23^7 213850084767170003246100602438595641344, // 23^14 339058325839400057321133061640411938816, // 23^21 268787708095090219373873551177395072962, // 23^28 213080837475827679663192730864754774513, // 23^35 337838687796969586566185112723027994705, // 23^42 267820842841689106502015241773782572538, // 23^49 212314357269641678380024305538561269739, // 23^56 336623436955327832661614051077606366471, // 23^63 266857455531624240538482847903341038248, // 23^70 211550634195037448645447237257455979321, // 23^77 335412557533128124785597638278283462337, // 23^84 265897533654269339698691446779528819034, // 23^91 210789658334244775585362676204225495858, // 23^98 334206033805791401974785682123232789907, // 23^105 264941064744000514367957679290425962065, // 23^112 210031419805168987228793890184514974036, // 23^119 333003850105302012456495057986285588216, // 23^126 263988036380034387491686584861354377998, // 23^133 209275908761262624819472661494385533289, // 23^140 331805990820004247517955628678622148639, // 23^147 263038436186266797268116360982380732098, // 23^154 208523115391397574746439388866966551936, // 23^161 330612440394399607270379273154482344971, // 23^168 262092251831112080049001043331284413642, // 23^175 207773029919737660433151703156509162570, // 23^182 329423183328944795675128680336602321085, // 23^189 261149471027342931361145730086041639640, // 23^196 207025642605611692530569464171386341133, // 23^203 328238204179850442208732821518504518810, // 23^210 260210081531930842969216498623209392426, // 23^217 206280943743386975765635578931435897048, // 23^224 ]; const BASE23_LARGE_EXPONENT: [i32; 69] = [ -1267, // 23^-252 -1236, // 23^-245 -1204, // 23^-238 -1172, // 23^-231 -1141, // 23^-224 -1109, // 23^-217 -1077, // 23^-210 -1046, // 23^-203 -1014, // 23^-196 -982, // 23^-189 -951, // 23^-182 -919, // 23^-175 -887, // 23^-168 -856, // 23^-161 -824, // 23^-154 -792, // 23^-147 -761, // 23^-140 -729, // 23^-133 -697, // 23^-126 -666, // 23^-119 -634, // 23^-112 -602, // 23^-105 -571, // 23^-98 -539, // 23^-91 -507, // 23^-84 -476, // 23^-77 -444, // 23^-70 -412, // 23^-63 -381, // 23^-56 -349, // 23^-49 -317, // 23^-42 -286, // 23^-35 -254, // 23^-28 -222, // 23^-21 -191, // 23^-14 -159, // 23^-7 -127, // 23^0 -96, // 23^7 -64, // 23^14 -33, // 23^21 -1, // 23^28 31, // 23^35 62, // 23^42 94, // 23^49 126, // 23^56 157, // 23^63 189, // 23^70 221, // 23^77 252, // 23^84 284, // 23^91 316, // 23^98 347, // 23^105 379, // 23^112 411, // 23^119 442, // 23^126 474, // 23^133 506, // 23^140 537, // 23^147 569, // 23^154 601, // 23^161 632, // 23^168 664, // 23^175 696, // 23^182 727, // 23^189 759, // 23^196 791, // 23^203 822, // 23^210 854, // 23^217 886, // 23^224 ]; const BASE23_SMALL_INT_POWERS: [u128; 7] = [1, 23, 529, 12167, 279841, 6436343, 148035889]; const BASE23_STEP: i32 = 7; const BASE23_BIAS: i32 = 252; // BASE24 const BASE24_SMALL_MANTISSA: [u128; 7] = [ 170141183460469231731687303715884105728, // 24^0 255211775190703847597530955573826158592, // 24^1 191408831393027885698148216680369618944, // 24^2 287113247089541828547222325020554428416, // 24^3 215334935317156371410416743765415821312, // 24^4 323002402975734557115625115648123731968, // 24^5 242251802231800917836718836736092798976, // 24^6 ]; const BASE24_SMALL_EXPONENT: [i32; 7] = [ -127, // 24^0 -123, // 24^1 -118, // 24^2 -114, // 24^3 -109, // 24^4 -105, // 24^5 -100, // 24^6 ]; const BASE24_LARGE_MANTISSA: [u128; 68] = [ 256006814417050404626793229969178591795, // 24^-252 273382276918988884237693747042282021609, // 24^-245 291937031065346039954998156631577529912, // 24^-238 311751116669878803408975082301396512655, // 24^-231 332910005936047335476283449703688561122, // 24^-224 177752486079622930343415992310050508587, // 24^-217 189816741726628588213403698819375225722, // 24^-210 202699811599676133995465766268541805984, // 24^-203 216457269515865090355509585365869594574, // 24^-196 231148461148045387015380597263260157877, // 24^-189 246836760024792608106756526472045881483, // 24^-182 263589840905381559535877208688654464260, // 24^-175 281479971709018296242657937208050445965, // 24^-168 300584325257628424747408646813479651038, // 24^-161 320985312176969416466104839150917967197, // 24^-154 171385468196052762160979317193129295473, // 24^-147 183017587375374702561553597022155160742, // 24^-140 195439191206027575440487166351295574484, // 24^-133 208703862874796048578293668364396201854, // 24^-126 222868822317958475703480592144987545632, // 24^-119 237995173051452727716558620615765508935, // 24^-112 254148165753675349373102394182948812519, // 24^-105 271397479737933588417468230506889186025, // 24^-98 289817523528740604428224130917268871991, // 24^-91 309487755838552588810803796052767101096, // 24^-84 330493028329548101430287061507520336961, // 24^-77 176461975819512133258798291874254633040, // 24^-70 188438643123668474334468683754392032451, // 24^-63 201228179937237770199942876645925476060, // 24^-56 214885756602899904017224155871405769601, // 24^-49 229470287934835004924643178169318563534, // 24^-42 245044687360099685434665347000146337133, // 24^-35 261676138308856451194147028266269550444, // 24^-28 279436384024154813848437280673013431065, // 24^-21 298402037041419227483658365640566588740, // 24^-14 318654909672648364505254319167929262488, // 24^-7 170141183460469231731687303715884105728, // 24^0 181688851673850688377539127552069599232, // 24^7 194020272759136452871913121072449323008, // 24^14 207188640880972374233825193254612631552, // 24^21 221250760550139932836609227367108313088, // 24^28 236267291661697281793781435669856387072, // 24^35 252303011164126931290527343657214803968, // 24^42 269427092488254686881046533485512097792, // 24^49 287713403941314941508226937857819803648, // 24^56 307240827353347547401607574753443315712, // 24^63 328093598350474163167634651360244400128, // 24^70 175180834861447020226468989874232056416, // 24^77 187070549727531559196917812917453861026, // 24^84 199767232545952890607255496509019333039, // 24^91 213325653114257310428744028742785781912, // 24^98 227804298516055047806476167412340090352, // 24^105 243265625417291205836310243227923719532, // 24^112 259776329486140560138677002900131432918, // 24^119 277407633098725295421526662764935275289, // 24^126 296235592571734482952577544661578831571, // 24^133 316341426247257477645159711999449660471, // 24^140 337811864845093800590802876046287308325, // 24^147 180369762796928745579122531717097251784, // 24^154 192611655877384358682393055110005707838, // 24^161 205684419630781050995309380627725821797, // 24^168 219644446158456132093135554410564634898, // 24^175 234551954955343535589691141355422293223, // 24^182 250471252679363433757155530343900661758, // 24^189 267471010551644448060009348077202513313, // 24^196 285624560584202347610957248166426707331, // 24^203 305010211912915299914630616083972269987, // 24^210 325711588600364141070945877624827809796, // 24^217 ]; const BASE24_LARGE_EXPONENT: [i32; 68] = [ -1283, // 24^-252 -1251, // 24^-245 -1219, // 24^-238 -1187, // 24^-231 -1155, // 24^-224 -1122, // 24^-217 -1090, // 24^-210 -1058, // 24^-203 -1026, // 24^-196 -994, // 24^-189 -962, // 24^-182 -930, // 24^-175 -898, // 24^-168 -866, // 24^-161 -834, // 24^-154 -801, // 24^-147 -769, // 24^-140 -737, // 24^-133 -705, // 24^-126 -673, // 24^-119 -641, // 24^-112 -609, // 24^-105 -577, // 24^-98 -545, // 24^-91 -513, // 24^-84 -481, // 24^-77 -448, // 24^-70 -416, // 24^-63 -384, // 24^-56 -352, // 24^-49 -320, // 24^-42 -288, // 24^-35 -256, // 24^-28 -224, // 24^-21 -192, // 24^-14 -160, // 24^-7 -127, // 24^0 -95, // 24^7 -63, // 24^14 -31, // 24^21 1, // 24^28 33, // 24^35 65, // 24^42 97, // 24^49 129, // 24^56 161, // 24^63 193, // 24^70 226, // 24^77 258, // 24^84 290, // 24^91 322, // 24^98 354, // 24^105 386, // 24^112 418, // 24^119 450, // 24^126 482, // 24^133 514, // 24^140 546, // 24^147 579, // 24^154 611, // 24^161 643, // 24^168 675, // 24^175 707, // 24^182 739, // 24^189 771, // 24^196 803, // 24^203 835, // 24^210 867, // 24^217 ]; const BASE24_SMALL_INT_POWERS: [u128; 7] = [1, 24, 576, 13824, 331776, 7962624, 191102976]; const BASE24_STEP: i32 = 7; const BASE24_BIAS: i32 = 252; // BASE25 const BASE25_SMALL_MANTISSA: [u128; 7] = [ 170141183460469231731687303715884105728, // 25^0 265845599156983174580761412056068915200, // 25^1 207691874341393105141219853168803840000, // 25^2 324518553658426726783156020576256000000, // 25^3 253530120045645880299340641075200000000, // 25^4 198070406285660843983859875840000000000, // 25^5 309485009821345068724781056000000000000, // 25^6 ]; const BASE25_SMALL_EXPONENT: [i32; 7] = [ -127, // 25^0 -123, // 25^1 -118, // 25^2 -114, // 25^3 -109, // 25^4 -104, // 25^5 -100, // 25^6 ]; const BASE25_LARGE_MANTISSA: [u128; 68] = [ 285793394306920833441610418092098634655, // 25^-252 203068420253004570555511362849258201390, // 25^-245 288577581746103207017755725657449092679, // 25^-238 205046704412910121830119952091883627559, // 25^-231 291388892624283530821742192659774598780, // 25^-224 207044260935364498850036477975162511299, // 25^-217 294227591176883860910658765384315687611, // 25^-210 209061277570927374050781655074839937648, // 25^-203 297093944213496817569054052050375869453, // 25^-196 211097943899216614887176072592734406508, // 25^-189 299988221142963048588365030287739055137, // 25^-182 213154451346726893197828921904416471830, // 25^-175 302910693998692996157485768413290076965, // 25^-168 215230993204821882725842221200657943544, // 25^-161 305861637464235347360161968596028634045, // 25^-154 217327764647901735884376228537482684576, // 25^-147 308841328899094571460716776609676066664, // 25^-140 219444962751747547330237450047488370802, // 25^-133 311850048364799970571308236412006025948, // 25^-126 221582786512044528543660416923448526878, // 25^-119 314888078651228693933689466069052580904, // 25^-112 223741436863085634409521749481834675708, // 25^-105 317955705303185189918510999237120523316, // 25^-98 225921116696657399755928707376370229068, // 25^-91 321053216647239593947814323906257853121, // 25^-84 228122030881109760932058580285014566244, // 25^-77 324180903818827574883781864350871964922, // 25^-70 230344386280611654799899571593522271174, // 25^-63 327339060789614187001318969682759915221, // 25^-56 232588391774594204975783618524161450993, // 25^-49 330527984395124299475957654016385519914, // 25^-42 234854258277383322788948059678933702737, // 25^-35 333747974362642200374222141588992517906, // 25^-28 237142198758023568227473377297792835283, // 25^-21 336999333339382997433337688587745383420, // 25^-14 239452428260295134118491722992235809940, // 25^-7 170141183460469231731687303715884105728, // 25^0 241785163922925834941235200000000000000, // 25^7 171798691840000000000000000000000000000, // 25^14 244140625000000000000000000000000000000, // 25^21 173472347597680709441192448139190673828, // 25^28 246519032881566189191165176650870696772, // 25^35 175162308040602133865466197911239516410, // 25^42 248920611114445668285762562151204969623, // 25^49 176868732008334225927912486150152183216, // 25^56 251345585423243599518503524095297312920, // 25^63 178591779887855465971216179422709524914, // 25^70 253794183731564922327402455583054354682, // 25^77 180331613628627651967947866455016278082, // 25^84 256266636183436918326986907537468991453, // 25^91 182088396757817547443627082897044283139, // 25^98 258763175164940474024358370140027266101, // 25^105 183862294395666818064937594201088633455, // 25^112 261284035326052074402891767876281837538, // 25^119 185653473271011701515143789632334288014, // 25^126 263829453602698580304979415177988198613, // 25^133 187462101736953869352205554703508169192, // 25^140 266399669239026862544798113253119949479, // 25^147 189288349786683953755640255602884245064, // 25^154 268994923809890385876486015494726082500, // 25^161 191132389069459226417170338759437756337, // 25^168 271615461243554856334256923502490730495, // 25^175 192994392906736931318972184714148973580, // 25^182 274261527844625066050770363850331497104, // 25^189 194874536308464787773268059716493991903, // 25^196 276933372317195090450451374005771742621, // 25^203 196772995989530194869453349330805553038, // 25^210 279631245788224013707368483964622716141, // 25^217 ]; const BASE25_LARGE_EXPONENT: [i32; 68] = [ -1298, // 25^-252 -1265, // 25^-245 -1233, // 25^-238 -1200, // 25^-231 -1168, // 25^-224 -1135, // 25^-217 -1103, // 25^-210 -1070, // 25^-203 -1038, // 25^-196 -1005, // 25^-189 -973, // 25^-182 -940, // 25^-175 -908, // 25^-168 -875, // 25^-161 -843, // 25^-154 -810, // 25^-147 -778, // 25^-140 -745, // 25^-133 -713, // 25^-126 -680, // 25^-119 -648, // 25^-112 -615, // 25^-105 -583, // 25^-98 -550, // 25^-91 -518, // 25^-84 -485, // 25^-77 -453, // 25^-70 -420, // 25^-63 -388, // 25^-56 -355, // 25^-49 -323, // 25^-42 -290, // 25^-35 -258, // 25^-28 -225, // 25^-21 -193, // 25^-14 -160, // 25^-7 -127, // 25^0 -95, // 25^7 -62, // 25^14 -30, // 25^21 3, // 25^28 35, // 25^35 68, // 25^42 100, // 25^49 133, // 25^56 165, // 25^63 198, // 25^70 230, // 25^77 263, // 25^84 295, // 25^91 328, // 25^98 360, // 25^105 393, // 25^112 425, // 25^119 458, // 25^126 490, // 25^133 523, // 25^140 555, // 25^147 588, // 25^154 620, // 25^161 653, // 25^168 685, // 25^175 718, // 25^182 750, // 25^189 783, // 25^196 815, // 25^203 848, // 25^210 880, // 25^217 ]; const BASE25_SMALL_INT_POWERS: [u128; 7] = [1, 25, 625, 15625, 390625, 9765625, 244140625]; const BASE25_STEP: i32 = 7; const BASE25_BIAS: i32 = 252; // BASE26 const BASE26_SMALL_MANTISSA: [u128; 7] = [ 170141183460469231731687303715884105728, // 26^0 276479423123262501563991868538311671808, // 26^1 224639531287650782520743393187378233344, // 26^2 182519619171216260798104006964744814592, // 26^3 296594381153226423796919011317710323712, // 26^4 240982934686996469334996696695639638016, // 26^5 195798634433184631334684816065207205888, // 26^6 ]; const BASE26_SMALL_EXPONENT: [i32; 7] = [ -127, // 26^0 -123, // 26^1 -118, // 26^2 -113, // 26^3 -109, // 26^4 -104, // 26^5 -99, // 26^6 ]; const BASE26_LARGE_MANTISSA: [u128; 67] = [ 223302816785416365261501121183664506010, // 26^-245 208793887424582006747864373745206480886, // 26^-238 195227664627991173689253365541181602096, // 26^-231 182542896759209079117924981191278218615, // 26^-224 170682311959929403775713752016508602388, // 26^-217 319184719133881733167774634228398630548, // 26^-210 298445936660656380797439373851559361096, // 26^-203 279054640682520272457995982566385389064, // 26^-196 260923279297292454826462160021044868443, // 26^-189 243969989220528359050303591757077787596, // 26^-182 228118226171942658526451569535286060353, // 26^-175 213296419277190995686832685182416132955, // 26^-168 199437647924631042854519895051784617004, // 26^-161 186479339618067826498814972661362929947, // 26^-154 174362987461285330626576271532417342855, // 26^-147 326067771997608226855765039505019953527, // 26^-140 304881768440366443726402955195105316329, // 26^-133 285072309225356538301642822964643005408, // 26^-126 266549954439052068809893515776468694564, // 26^-119 249231075457753005677502945704601914895, // 26^-112 233037477363483566918311865718592557833, // 26^-105 217896045893127676516686822732460831572, // 26^-98 203738417326773735777703283427712394918, // 26^-91 190500669824811165252338688092226229364, // 26^-84 178123034820162511238845936350714491622, // 26^-77 333099254325168111301464298292509503356, // 26^-70 311456385593267303107050428484389238716, // 26^-63 291219745668138391592456499213129019442, // 26^-56 272297965910924348580716754684381379181, // 26^-49 254605614290044560620651113294031241626, // 26^-42 238062809654687405271268739306918462570, // 26^-35 222594861070586991002412082254420837256, // 26^-28 208131930589681357218231284385128680344, // 26^-21 194608717931053648412097371491373800423, // 26^-14 181964165649487446029462142596867446143, // 26^-7 170141183460469231731687303715884105728, // 26^0 318172780953925025918862826105961709568, // 26^7 297499748388299952530789444812804194304, // 26^14 278169930267914565987548746187341299712, // 26^21 260096052263752396381159488684908609536, // 26^28 243196510629429753543644020787720315589, // 26^35 227395003759435617782759026890197718352, // 26^42 212620187686592486096128182198450396409, // 26^49 198805353963305641500281734389939339052, // 26^56 185888128472231349675004689621278542958, // 26^63 173810189806491030350550655153103473999, // 26^70 325034011895830307254166714675296871096, // 26^77 303915176108832810280521264920190203131, // 26^84 284168520489679119677023043643028417295, // 26^91 265704888683728554332237168601547339173, // 26^98 248440917202145588620033973783642939305, // 26^105 232298659034884347081172590621418853088, // 26^112 217205231719130933968079964556427917884, // 26^119 203092488274228969742684708734280089507, // 26^126 189896709517356115129460946793154219973, // 26^133 177558316370753675479515454481338457101, // 26^140 332043201723146894831623394706398020929, // 26^147 310468949199606660363664220576467010752, // 26^154 290296467197293861525395669447395056845, // 26^161 271434676751037481783657313824389119896, // 26^168 253798416681617203255579043607175584203, // 26^175 237308059092157195001470401326248026898, // 26^182 221889149847346996027560241559399617642, // 26^189 207472072412249451654170398205728730819, // 26^196 193991733532924439390933354984357040572, // 26^203 181387269339713144970498252974494732833, // 26^210 339203541092472346195720855153810480522, // 26^217 ]; const BASE26_LARGE_EXPONENT: [i32; 67] = [ -1279, // 26^-245 -1246, // 26^-238 -1213, // 26^-231 -1180, // 26^-224 -1147, // 26^-217 -1115, // 26^-210 -1082, // 26^-203 -1049, // 26^-196 -1016, // 26^-189 -983, // 26^-182 -950, // 26^-175 -917, // 26^-168 -884, // 26^-161 -851, // 26^-154 -818, // 26^-147 -786, // 26^-140 -753, // 26^-133 -720, // 26^-126 -687, // 26^-119 -654, // 26^-112 -621, // 26^-105 -588, // 26^-98 -555, // 26^-91 -522, // 26^-84 -489, // 26^-77 -457, // 26^-70 -424, // 26^-63 -391, // 26^-56 -358, // 26^-49 -325, // 26^-42 -292, // 26^-35 -259, // 26^-28 -226, // 26^-21 -193, // 26^-14 -160, // 26^-7 -127, // 26^0 -95, // 26^7 -62, // 26^14 -29, // 26^21 4, // 26^28 37, // 26^35 70, // 26^42 103, // 26^49 136, // 26^56 169, // 26^63 202, // 26^70 234, // 26^77 267, // 26^84 300, // 26^91 333, // 26^98 366, // 26^105 399, // 26^112 432, // 26^119 465, // 26^126 498, // 26^133 531, // 26^140 563, // 26^147 596, // 26^154 629, // 26^161 662, // 26^168 695, // 26^175 728, // 26^182 761, // 26^189 794, // 26^196 827, // 26^203 860, // 26^210 892, // 26^217 ]; const BASE26_SMALL_INT_POWERS: [u128; 7] = [1, 26, 676, 17576, 456976, 11881376, 308915776]; const BASE26_STEP: i32 = 7; const BASE26_BIAS: i32 = 245; // BASE27 const BASE27_SMALL_MANTISSA: [u128; 6] = [ 170141183460469231731687303715884105728, // 27^0 287113247089541828547222325020554428416, // 27^1 242251802231800917836718836736092798976, // 27^2 204399958133082024424731518496078299136, // 27^3 172462464674787958108367218731066064896, // 27^4 291030409138704679307869681608673984512, // 27^5 ]; const BASE27_SMALL_EXPONENT: [i32; 6] = [ -127, // 27^0 -123, // 27^1 -118, // 27^2 -113, // 27^3 -108, // 27^4 -104, // 27^5 ]; const BASE27_LARGE_MANTISSA: [u128; 76] = [ 301829093537629265639465570217176944359, // 27^-240 217807991453958805640698687941213190524, // 27^-234 314352208961548438173441007673156326734, // 27^-228 226845008347394462887832488874694288292, // 27^-222 327394917835133689224334116987590197085, // 27^-216 236256977848340413085493360278597848651, // 27^-210 170489389240119998671196096475026672256, // 27^-204 246059457021648542224892012444309926233, // 27^-198 177563121844831037921653709250257605479, // 27^-192 256268648406457241006138264113659504394, // 27^-186 184930348919702200346046943747485274024, // 27^-180 266901426797403574706768528236472000862, // 27^-174 192603247770383575639211190527648274245, // 27^-168 277975367137008028446553971650055283412, // 27^-162 200594500948068090486693848039128919647, // 27^-156 289508773565335211238455692680966173052, // 27^-150 208917317212507950117664039252872831665, // 27^-144 301520709674946766164053267333891939739, // 27^-138 217585453364802351586979201161384846208, // 27^-132 314031030021154964119856834958393443507, // 27^-126 226613236986043931067161987739751269180, // 27^-120 327060412939660347810097743318775450603, // 27^-114 236015590119408703302029793810763336632, // 27^-108 170315197362908885300398426895467760677, // 27^-102 245808053934833671173174941698733239342, // 27^-96 177381702616012906692133545122052956869, // 27^-90 256006814417050404626793229969178591795, // 27^-84 184741402471039290909022270993420155647, // 27^-78 266628729119434395515123988465075762881, // 27^-72 192406461791880080316008520325217417399, // 27^-66 277691355027891684120101092281051616669, // 27^-60 200389550171752283164939097875653100692, // 27^-54 289212977580839036146652597763405686112, // 27^-48 208703862874796048578293668364396201854, // 27^-42 301212640893244858516269504216828222245, // 27^-36 217363142646555453321168098187951653993, // 27^-30 313710179234688236904530296665341569850, // 27^-24 226381702429392491474935736226666160567, // 27^-18 326726249813466247246220462666861782844, // 27^-12 235774449020380624184618955567855082461, // 27^-6 170141183460469231731687303715884105728, // 27^0 245556907710782073166015043857318674432, // 27^6 177200468746272961345336076752392290304, // 27^12 255745247947835503562868389206950936576, // 27^18 184552649072141716781794491390137475072, // 27^24 266356310061270520809673995345359110719, // 27^30 192209876872921446586714266254161951235, // 27^36 277407633098725295421526662764935275289, // 27^42 200184808797092622572327630249651738267, // 27^48 288917483816076538023589582665008561757, // 27^54 208490626626972031635281014538153149532, // 27^60 300904886870600004067510516586852827477, // 27^66 217141059066909427380630585083218539864, // 27^72 313389656266867868879861721401276560157, // 27^78 226150404435492799169987273137391228527, // 27^84 326392428107359965184387801150473482685, // 27^90 235533554299270254021060647605641184828, // 27^96 339934694701922439619874702371784251126, // 27^102 245306018087052741642305313258629505287, // 27^108 177019420046226713314377865847118993119, // 27^114 255483948725482657093998355855298189652, // 27^120 184364088525767284952804747951506893851, // 27^126 266084169338241408156670471179837543899, // 27^132 192013492808081754945415747456910215687, // 27^138 277124201053027125645172361985060059244, // 27^144 199980276610139913759598726349951659975, // 27^150 288622291962264730584478255384696488209, // 27^156 208277608246209791806511248482402407710, // 27^162 300597447285417578884462942447710218615, // 27^168 216919202393792943992865658673403318648, // 27^174 313069460782756034010893203297842312622, // 27^180 225919342762644710883872352816958877073, // 27^186 326058947472506854027112756453181563499, // 27^192 235292905704349129354647627776916151748, // 27^198 339587377705461640362820917278613293254, // 27^204 245055384801472810432512717678228228007, // 27^210 ]; const BASE27_LARGE_EXPONENT: [i32; 76] = [ -1269, // 27^-240 -1240, // 27^-234 -1212, // 27^-228 -1183, // 27^-222 -1155, // 27^-216 -1126, // 27^-210 -1097, // 27^-204 -1069, // 27^-198 -1040, // 27^-192 -1012, // 27^-186 -983, // 27^-180 -955, // 27^-174 -926, // 27^-168 -898, // 27^-162 -869, // 27^-156 -841, // 27^-150 -812, // 27^-144 -784, // 27^-138 -755, // 27^-132 -727, // 27^-126 -698, // 27^-120 -670, // 27^-114 -641, // 27^-108 -612, // 27^-102 -584, // 27^-96 -555, // 27^-90 -527, // 27^-84 -498, // 27^-78 -470, // 27^-72 -441, // 27^-66 -413, // 27^-60 -384, // 27^-54 -356, // 27^-48 -327, // 27^-42 -299, // 27^-36 -270, // 27^-30 -242, // 27^-24 -213, // 27^-18 -185, // 27^-12 -156, // 27^-6 -127, // 27^0 -99, // 27^6 -70, // 27^12 -42, // 27^18 -13, // 27^24 15, // 27^30 44, // 27^36 72, // 27^42 101, // 27^48 129, // 27^54 158, // 27^60 186, // 27^66 215, // 27^72 243, // 27^78 272, // 27^84 300, // 27^90 329, // 27^96 357, // 27^102 386, // 27^108 415, // 27^114 443, // 27^120 472, // 27^126 500, // 27^132 529, // 27^138 557, // 27^144 586, // 27^150 614, // 27^156 643, // 27^162 671, // 27^168 700, // 27^174 728, // 27^180 757, // 27^186 785, // 27^192 814, // 27^198 842, // 27^204 871, // 27^210 ]; const BASE27_SMALL_INT_POWERS: [u128; 6] = [1, 27, 729, 19683, 531441, 14348907]; const BASE27_STEP: i32 = 6; const BASE27_BIAS: i32 = 240; // BASE28 const BASE28_SMALL_MANTISSA: [u128; 6] = [ 170141183460469231731687303715884105728, // 28^0 297747071055821155530452781502797185024, // 28^1 260528687173843511089146183814947536896, // 28^2 227962601277113072203002910838079094784, // 28^3 199467276117473938177627546983319207936, // 28^4 174533866602789695905424103610404306944, // 28^5 ]; const BASE28_SMALL_EXPONENT: [i32; 6] = [ -127, // 28^0 -123, // 28^1 -118, // 28^2 -113, // 28^3 -108, // 28^4 -103, // 28^5 ]; const BASE28_LARGE_MANTISSA: [u128; 76] = [ 200215143815698040798730279921859793515, // 28^-240 179711238516029806533278035755362570551, // 28^-234 322614250185735942212427179391214768413, // 28^-228 289575530396283324168013345552040300667, // 28^-222 259920284847963995399800125815215983072, // 28^-216 233302014099717072256401710525774728336, // 28^-210 209409703497448836012980688794302909957, // 28^-204 187964189199610581269006081054389519147, // 28^-198 337429792711562885676838629607664070711, // 28^-192 302873822652608199592547515371033250847, // 28^-186 271856707468083969679745656096547629768, // 28^-180 244016035285282981482333348801442963368, // 28^-174 219026508600450572879143037057044702127, // 28^-168 196596143419909740056291955312532441411, // 28^-162 176462857644721687377034700397980722042, // 28^-156 316782817673398770114452445482208770257, // 28^-150 284341291171704802743493772571841275116, // 28^-144 255222080727080523208383932871281083497, // 28^-138 229084950069124576377435007616984162844, // 28^-132 205624506307086466111975488366169508167, // 28^-126 184566631641558957302915986868221103411, // 28^-120 331330561004604641231243330979299081348, // 28^-114 297399209378286220063892720385616742108, // 28^-108 266942745850723232302069966588191406954, // 28^-102 239605309345945263344621501916001364416, // 28^-96 215067482294014848993159294730496555497, // 28^-90 193042558474796699288911421705232156812, // 28^-84 173273193069468359944466704194632400641, // 28^-78 311056791556242112413125050076207081650, // 28^-72 279201663740542055384000770694089408486, // 28^-66 250608799266136415663698628779517553855, // 28^-60 224944111822980370837543334787608800457, // 28^-54 201907728667158642949418150287074186439, // 28^-48 181230486831379296755646484093658378299, // 28^-42 325341576312636457580643512071759255196, // 28^-36 292023552792399342330208805478900181690, // 28^-30 262117606830390855604604612394616145902, // 28^-24 235274309738072614830216430996812400431, // 28^-18 211180017596241035935669959185363632952, // 28^-12 189553206559602063269009666658011215615, // 28^-6 170141183460469231731687303715884105728, // 28^0 305434266554881967834492181318207537152, // 28^6 274154937941858738966065755004164112384, // 28^12 246078905440687093968343124469641904128, // 28^18 220878121537715117784741212850409701376, // 28^24 198258133856129805696540977101424033792, // 28^30 177954644699400447924746318168681611264, // 28^36 319460845859371388212562249545703474176, // 28^42 286745064197610355009611023687762970225, // 28^48 257379684889104161503034418684704785797, // 28^54 231021595363755916570056887236303965333, // 28^60 207362820991138609531788808643065835705, // 28^66 186126926626483659918254253754028720893, // 28^72 334131573344103639308512797544978713750, // 28^78 299913371828921883094842698046640019943, // 28^84 269199434526831288331795872363961423540, // 28^90 241630891972710985114650364591580944199, // 28^96 216885626294688985349681859923056842835, // 28^102 194674507506895938395726937393857685110, // 28^108 174738015241079713869620349559402181972, // 28^114 313686412889065357315780098042512623701, // 28^120 281561987228284074576142980610683957411, // 28^126 252727403529513497084111370284014563793, // 28^132 226845751173734538409794758625366435361, // 28^138 203614622343740041422835873088956724196, // 28^144 182762578614186646525232068123189313087, // 28^150 328091958791815868790390435525895683218, // 28^156 294492270354449044397893099587906656150, // 28^162 264333504599995236391965677440014878764, // 28^168 237263278829077450304247817879793628477, // 28^174 212965297630021155936008083539885258459, // 28^180 191155657202715751455043144381591497592, // 28^186 171579528154314464133715598246382584383, // 28^192 308016356015425756696586706818979868623, // 28^198 276472597266073797985814891590470600613, // 28^204 248159214750338106225838746496027188809, // 28^210 ]; const BASE28_LARGE_EXPONENT: [i32; 76] = [ -1281, // 28^-240 -1252, // 28^-234 -1224, // 28^-228 -1195, // 28^-222 -1166, // 28^-216 -1137, // 28^-210 -1108, // 28^-204 -1079, // 28^-198 -1051, // 28^-192 -1022, // 28^-186 -993, // 28^-180 -964, // 28^-174 -935, // 28^-168 -906, // 28^-162 -877, // 28^-156 -849, // 28^-150 -820, // 28^-144 -791, // 28^-138 -762, // 28^-132 -733, // 28^-126 -704, // 28^-120 -676, // 28^-114 -647, // 28^-108 -618, // 28^-102 -589, // 28^-96 -560, // 28^-90 -531, // 28^-84 -502, // 28^-78 -474, // 28^-72 -445, // 28^-66 -416, // 28^-60 -387, // 28^-54 -358, // 28^-48 -329, // 28^-42 -301, // 28^-36 -272, // 28^-30 -243, // 28^-24 -214, // 28^-18 -185, // 28^-12 -156, // 28^-6 -127, // 28^0 -99, // 28^6 -70, // 28^12 -41, // 28^18 -12, // 28^24 17, // 28^30 46, // 28^36 74, // 28^42 103, // 28^48 132, // 28^54 161, // 28^60 190, // 28^66 219, // 28^72 247, // 28^78 276, // 28^84 305, // 28^90 334, // 28^96 363, // 28^102 392, // 28^108 421, // 28^114 449, // 28^120 478, // 28^126 507, // 28^132 536, // 28^138 565, // 28^144 594, // 28^150 622, // 28^156 651, // 28^162 680, // 28^168 709, // 28^174 738, // 28^180 767, // 28^186 796, // 28^192 824, // 28^198 853, // 28^204 882, // 28^210 ]; const BASE28_SMALL_INT_POWERS: [u128; 6] = [1, 28, 784, 21952, 614656, 17210368]; const BASE28_STEP: i32 = 6; const BASE28_BIAS: i32 = 240; // BASE29 const BASE29_SMALL_MANTISSA: [u128; 6] = [ 170141183460469231731687303715884105728, // 29^0 308380895022100482513683237985039941632, // 29^1 279470186113778562278025434423942447104, // 29^2 253269856165611822064460549946697842688, // 29^3 229525807150085713745917373389194919936, // 29^4 208007762729765178082237619633957896192, // 29^5 ]; const BASE29_SMALL_EXPONENT: [i32; 6] = [ -127, // 29^0 -123, // 29^1 -118, // 29^2 -113, // 29^3 -108, // 29^4 -103, // 29^5 ]; const BASE29_LARGE_MANTISSA: [u128; 76] = [ 180411782640948456163108621039484300353, // 29^-240 199886291656678749778798199538954577713, // 29^-234 221462972137332420374365077239613292335, // 29^-228 245368742505570013761609603669658845854, // 29^-222 271855015841791437163383377269432435982, // 29^-216 301200343954417841961395964144914808415, // 29^-210 333713346863741229059418106803065448261, // 29^-204 184867979254122350694373980738345610830, // 29^-198 204823511403978168182734748793342650457, // 29^-192 226933138952023660037574950865203175761, // 29^-186 251429385238135556008900174982942596722, // 29^-180 278569873281449391084528542386060643447, // 29^-174 308640035159552273337407148073177516540, // 29^-168 170978056925499484035797671737173759761, // 29^-162 189434244555519246827735852425496159000, // 29^-156 209882681179121373738148351480252166035, // 29^-150 232538419662693834656863635067192575556, // 29^-144 257639726705579546348788818074016917383, // 29^-138 285450588652016995453946272087193218261, // 29^-132 316263487792383250937533050996202736450, // 29^-126 175201239175822924661859658491633525197, // 29^-120 194113297257345719179697640426306620561, // 29^-114 215066813165088318898530949380694999931, // 29^-108 238282151601732438626757341123945812037, // 29^-102 264003464487880391063907148518553600721, // 29^-96 292501258667905961095191488633763572010, // 29^-90 324075240786231793266420435905585066661, // 29^-84 179528734626566103050967344518404222838, // 29^-78 198907923224385351394870557131224024014, // 29^-72 220378993946205681004466278772642662300, // 29^-66 244167754534112212293116837315364018708, // 29^-60 270524387495766270724774864712621178351, // 29^-54 299726081232954872012689080099923610541, // 29^-48 332079945186715557451765374774991672241, // 29^-42 183963119828570739334286542177638201257, // 29^-36 203820977132676910337518249049241331980, // 29^-30 225822386345870676314424417535913775896, // 29^-24 250198732693485636863600410972168425001, // 29^-18 277206378226597610088077970727216566225, // 29^-12 307129357939822377568583266911848900855, // 29^-6 170141183460469231731687303715884105728, // 29^0 188507034973849692637027842793274343424, // 29^6 208855384169162106382075974754544648192, // 29^12 231400231309666912826787170353923751936, // 29^18 256378676868573301455838684793773426688, // 29^24 284053415075970164879962990673826094314, // 29^30 314715496631115750914098978917481871688, // 29^36 174343694817539847357322592625772163155, // 29^42 193163185467532912371523116182520814756, // 29^48 214014141773314894388674508400179209532, // 29^54 237115849834993471687725998227739696222, // 29^60 262711266541086358656385267533109039869, // 29^66 291069574706415032602452081981147446763, // 29^72 322489014023779685975823216414806216349, // 29^78 178650008801035774670984867305268298071, // 29^84 197934343538640677425270715935647505996, // 29^90 219300321421789265371466533424126863110, // 29^96 242972644948356100526463281459541324974, // 29^102 269200272076455967884065094333741996545, // 29^108 298259034474605889482552078350958780837, // 29^114 330454538398307869859357548505383554011, // 29^120 183062689350548673356118481539553806163, // 29^126 202823349890643162760568057855283073783, // 29^132 224717070457148091679782830215989826885, // 29^138 248974103731497779640892318688061490897, // 29^144 275849556968674066644388728598920812956, // 29^150 305626074918518590345961283073160340970, // 29^156 338616812354378462414859289927404969896, // 29^162 187584363735341677353233362159059264795, // 29^168 207833115392789061354400140358968381064, // 29^174 230267613961761833964469003400183663813, // 29^180 255123799397575000468261630468177681638, // 29^186 282663080140582027146793786682106989268, // 29^192 313175082306023963280707662359655742783, // 29^198 173490347817277081445057491729890113081, // 29^204 192217724118601260264099717636971309833, // 29^210 ]; const BASE29_LARGE_EXPONENT: [i32; 76] = [ -1293, // 29^-240 -1264, // 29^-234 -1235, // 29^-228 -1206, // 29^-222 -1177, // 29^-216 -1148, // 29^-210 -1119, // 29^-204 -1089, // 29^-198 -1060, // 29^-192 -1031, // 29^-186 -1002, // 29^-180 -973, // 29^-174 -944, // 29^-168 -914, // 29^-162 -885, // 29^-156 -856, // 29^-150 -827, // 29^-144 -798, // 29^-138 -769, // 29^-132 -740, // 29^-126 -710, // 29^-120 -681, // 29^-114 -652, // 29^-108 -623, // 29^-102 -594, // 29^-96 -565, // 29^-90 -536, // 29^-84 -506, // 29^-78 -477, // 29^-72 -448, // 29^-66 -419, // 29^-60 -390, // 29^-54 -361, // 29^-48 -332, // 29^-42 -302, // 29^-36 -273, // 29^-30 -244, // 29^-24 -215, // 29^-18 -186, // 29^-12 -157, // 29^-6 -127, // 29^0 -98, // 29^6 -69, // 29^12 -40, // 29^18 -11, // 29^24 18, // 29^30 47, // 29^36 77, // 29^42 106, // 29^48 135, // 29^54 164, // 29^60 193, // 29^66 222, // 29^72 251, // 29^78 281, // 29^84 310, // 29^90 339, // 29^96 368, // 29^102 397, // 29^108 426, // 29^114 455, // 29^120 485, // 29^126 514, // 29^132 543, // 29^138 572, // 29^144 601, // 29^150 630, // 29^156 659, // 29^162 689, // 29^168 718, // 29^174 747, // 29^180 776, // 29^186 805, // 29^192 834, // 29^198 864, // 29^204 893, // 29^210 ]; const BASE29_SMALL_INT_POWERS: [u128; 6] = [1, 29, 841, 24389, 707281, 20511149]; const BASE29_STEP: i32 = 6; const BASE29_BIAS: i32 = 240; // BASE30 const BASE30_SMALL_MANTISSA: [u128; 6] = [ 170141183460469231731687303715884105728, // 30^0 319014718988379809496913694467282698240, // 30^1 299076299051606071403356588563077529600, // 30^2 280384030360880691940646801777885184000, // 30^3 262860028463325648694356376666767360000, // 30^4 246431276684367795650959103125094400000, // 30^5 ]; const BASE30_SMALL_EXPONENT: [i32; 6] = [ -127, // 30^0 -123, // 30^1 -118, // 30^2 -113, // 30^3 -108, // 30^4 -103, // 30^5 ]; const BASE30_LARGE_MANTISSA: [u128; 74] = [ 293697914606894485088361958296166003399, // 30^-234 199401546035358756435491021348075025228, // 30^-228 270761041082025567891957153683056483774, // 30^-222 183828919146951883093674448351327494412, // 30^-216 249615464467793559236989678532104461317, // 30^-210 338944929832632662139396137837142035924, // 30^-204 230121290169646228383872457298707723793, // 30^-198 312474408249691315911417866816293319027, // 30^-192 212149548916169413644283660602828329029, // 30^-186 288071150257973936473359891361485890787, // 30^-180 195581343526079319127909243854250027224, // 30^-174 265573709142416387133758214804806317848, // 30^-168 180307062310000458937613050074040708794, // 30^-162 244833246663194772909432488501026624276, // 30^-156 332451307806128616353452734867573546427, // 30^-150 225712548373888955751123878842649157480, // 30^-144 306487917461553679299669913344627685478, // 30^-138 208085115840167395965624010961720331305, // 30^-132 282552185370553343852869987471204477403, // 30^-126 191834329753307055373436045708607941890, // 30^-120 260485757869036576463347072380734960806, // 30^-114 176852678401887104140389725347567150767, // 30^-108 240142648210703765821352805529490956868, // 30^-102 326082092794781635112624979076905003855, // 30^-96 221388270750079128888532155889145795079, // 30^-90 300616117896153936087600778123712697276, // 30^-84 204098550552778150334824777443135675335, // 30^-78 277138954685954882938577351637270128950, // 30^-72 188159102542382767109407940268116001044, // 30^-66 255495283293346012426090218975127795266, // 30^-60 173464474753336275982316368848893943009, // 30^-54 235541913835671069456466721167496749113, // 30^-48 319834901366763207379289417958082873567, // 30^-42 217146839104937741700096042539405091508, // 30^-36 294856812260112936979848919457246198708, // 30^-30 200188361236473853754168248068850933442, // 30^-24 271829432512427567293473804075629134624, // 30^-18 184554286581985369843377175900278276895, // 30^-12 250600417923680198594596164731872945757, // 30^-6 170141183460469231731687303715884105728, // 30^0 231029321891594808422774159179776000000, // 30^6 313707395752840890251476992000000000000, // 30^12 212986666247081951232000000000000000000, // 30^18 289207845356544000000000000000000000000, // 30^24 196353084654473304748535156250000000000, // 30^30 266621631967110632288608940143603831529, // 30^36 181018532909474941844489348460628831000, // 30^42 245799330046413899594233809090775284541, // 30^48 333763121820680299409099755486799743829, // 30^54 226603183715861233202026897808422346833, // 30^60 307697282971558792524556831461079215336, // 30^66 208906195393080226844550976655564036201, // 30^72 283667103278554017412807162817392837984, // 30^78 192591285603182277357146536646298485706, // 30^84 261513604232519641878753574965804062932, // 30^90 177550518406095745907734479894927853604, // 30^96 241090223040513319460187919146199534233, // 30^102 327368774631124380764508606973252185538, // 30^108 222261842997828194477899721342605392688, // 30^114 301802313971178147521594347169174498450, // 30^120 204903899584886496461222208185427085841, // 30^126 278232512618195742220116760148063945729, // 30^132 188901556375124208702207652989717774500, // 30^138 256503437827277086943219190518379691262, // 30^144 174148945301850322989380722761059920238, // 30^150 236471334705220322048773145103478211637, // 30^156 321096932515698698858834100478208840422, // 30^162 218003675159015088778073023304915283497, // 30^168 296020282788056879712669614682501632104, // 30^174 200978281118435287206001718625001320433, // 30^180 272902039690575235287053981567967613406, // 30^186 185282516232160242762660936045505469826, // 30^192 251589257890814574386886921482483833102, // 30^198 170812540689859376035668482781137073721, // 30^204 ]; const BASE30_LARGE_EXPONENT: [i32; 74] = [ -1276, // 30^-234 -1246, // 30^-228 -1217, // 30^-222 -1187, // 30^-216 -1158, // 30^-210 -1129, // 30^-204 -1099, // 30^-198 -1070, // 30^-192 -1040, // 30^-186 -1011, // 30^-180 -981, // 30^-174 -952, // 30^-168 -922, // 30^-162 -893, // 30^-156 -864, // 30^-150 -834, // 30^-144 -805, // 30^-138 -775, // 30^-132 -746, // 30^-126 -716, // 30^-120 -687, // 30^-114 -657, // 30^-108 -628, // 30^-102 -599, // 30^-96 -569, // 30^-90 -540, // 30^-84 -510, // 30^-78 -481, // 30^-72 -451, // 30^-66 -422, // 30^-60 -392, // 30^-54 -363, // 30^-48 -334, // 30^-42 -304, // 30^-36 -275, // 30^-30 -245, // 30^-24 -216, // 30^-18 -186, // 30^-12 -157, // 30^-6 -127, // 30^0 -98, // 30^6 -69, // 30^12 -39, // 30^18 -10, // 30^24 20, // 30^30 49, // 30^36 79, // 30^42 108, // 30^48 137, // 30^54 167, // 30^60 196, // 30^66 226, // 30^72 255, // 30^78 285, // 30^84 314, // 30^90 344, // 30^96 373, // 30^102 402, // 30^108 432, // 30^114 461, // 30^120 491, // 30^126 520, // 30^132 550, // 30^138 579, // 30^144 609, // 30^150 638, // 30^156 667, // 30^162 697, // 30^168 726, // 30^174 756, // 30^180 785, // 30^186 815, // 30^192 844, // 30^198 874, // 30^204 ]; const BASE30_SMALL_INT_POWERS: [u128; 6] = [1, 30, 900, 27000, 810000, 24300000]; const BASE30_STEP: i32 = 6; const BASE30_BIAS: i32 = 234; // BASE31 const BASE31_SMALL_MANTISSA: [u128; 6] = [ 170141183460469231731687303715884105728, // 31^0 329648542954659136480144150949525454848, // 31^1 319347025987326038465139646232352784384, // 31^2 309367431425222099763104032287591759872, // 31^3 299699699193183909145507031278604517376, // 31^4 290334083593396911984709936551148126208, // 31^5 ]; const BASE31_SMALL_EXPONENT: [i32; 6] = [ -127, // 31^0 -123, // 31^1 -118, // 31^2 -113, // 31^3 -108, // 31^4 -103, // 31^5 ]; const BASE31_LARGE_MANTISSA: [u128; 74] = [ 279877549230888994466722529922465951128, // 31^-234 231333407733284590292354000091386191754, // 31^-228 191209140142019782313183919746595976478, // 31^-222 316088675925298444140273004034743674741, // 31^-216 261263794643914746305034655542823358647, // 31^-210 215948167684024592485185159022754788335, // 31^-204 178492435929157837038046463019461592108, // 31^-198 295066635902569136770934561228011804883, // 31^-192 243887980937787207068127465341221873783, // 31^-186 201586150409601608540557644579125879351, // 31^-180 333242957530806000015262416296943861408, // 31^-174 275442704070282164877682412643443854572, // 31^-168 227667776650720372831068985136241988697, // 31^-162 188179304658062925738530341045324738580, // 31^-156 311080041475689584245114254221154550706, // 31^-150 257123896754632869764136622554477725012, // 31^-144 212526325921342359594316086083656739425, // 31^-138 175664105047096554749814041961690625344, // 31^-132 290391109602281582919653498207198252857, // 31^-126 240023414326551697067636257878891518439, // 31^-120 198391884324143423870507706735824676989, // 31^-114 327962502126029666246881442269148110223, // 31^-108 271078131968920728852328597367236335349, // 31^-102 224060229920801636254083864004341099802, // 31^-96 185197478924335716894196793983277050828, // 31^-90 306150772156692797734166574102932652557, // 31^-84 253049598289706899575201136976026000492, // 31^-78 209158705508044155113481306826330986049, // 31^-72 172880590941369685133685946960988620150, // 31^-66 285789670113326703641484035227164931190, // 31^-60 236220084333189890382264913587684321799, // 31^-54 195248233500715771863466694882341429463, // 31^-48 322765719034956327944217102842371688313, // 31^-42 266782719403631527651786656524762917448, // 31^-36 220509847158485190531810693342620280466, // 31^-30 182262902194543738831736462131829646508, // 31^-24 301299610375241462753468658335350302125, // 31^-18 249039859782804352657429715423616325073, // 31^-12 205844447270932349829274233837837318735, // 31^-6 170141183460469231731687303715884105728, // 31^0 281261143481103258485187751033924747264, // 31^6 232477020622927971041480650211423420416, // 31^12 192154395906963839472434931204572053504, // 31^18 317651282414350176352409831205456445952, // 31^24 262555370495753687560337482407159416999, // 31^30 217015722562838525119352550468059930336, // 31^36 179374825776921533841673613411506136043, // 31^42 296525318465664137401900073705767585881, // 31^48 245093658238625334625948305994309525378, // 31^54 202582705650977753904076181059390370572, // 31^60 334890367411416504232175148268475073388, // 31^66 276804374353098300220638069068074602530, // 31^72 228793268236589371413606590094648720070, // 31^78 189109582219266748069833984779993889354, // 31^84 312617887429839722873414506299686714932, // 31^90 258395006731549634868442333657079980382, // 31^96 213576964685944914612871149421565862652, // 31^102 176532512843220607081571440296564925357, // 31^108 291826678373921783044839874892818001863, // 31^114 241209986871908117885122799335937441435, // 31^120 199372648487594099824157002892036768477, // 31^126 329583807705824908665978895106558273752, // 31^132 272418225684124763666228455375305707749, // 31^138 225167887346958248891898253497228074938, // 31^144 186113015621359245893427982047443315204, // 31^150 307664249923018427479642383336104189758, // 31^156 254300566687046383525258086411660098107, // 31^162 210192696205470376085866529648531617961, // 31^168 173735238240724141814430167095519087450, // 31^174 287202491346848457988114640516635531033, // 31^180 237387854850570349221700427782261535085, // 31^186 196213456806330839063706448987155946803, // 31^192 324361333953874416226256763524449662322, // 31^198 268101578446229760174200876130811505774, // 31^204 ]; const BASE31_LARGE_EXPONENT: [i32; 74] = [ -1287, // 31^-234 -1257, // 31^-228 -1227, // 31^-222 -1198, // 31^-216 -1168, // 31^-210 -1138, // 31^-204 -1108, // 31^-198 -1079, // 31^-192 -1049, // 31^-186 -1019, // 31^-180 -990, // 31^-174 -960, // 31^-168 -930, // 31^-162 -900, // 31^-156 -871, // 31^-150 -841, // 31^-144 -811, // 31^-138 -781, // 31^-132 -752, // 31^-126 -722, // 31^-120 -692, // 31^-114 -663, // 31^-108 -633, // 31^-102 -603, // 31^-96 -573, // 31^-90 -544, // 31^-84 -514, // 31^-78 -484, // 31^-72 -454, // 31^-66 -425, // 31^-60 -395, // 31^-54 -365, // 31^-48 -336, // 31^-42 -306, // 31^-36 -276, // 31^-30 -246, // 31^-24 -217, // 31^-18 -187, // 31^-12 -157, // 31^-6 -127, // 31^0 -98, // 31^6 -68, // 31^12 -38, // 31^18 -9, // 31^24 21, // 31^30 51, // 31^36 81, // 31^42 110, // 31^48 140, // 31^54 170, // 31^60 199, // 31^66 229, // 31^72 259, // 31^78 289, // 31^84 318, // 31^90 348, // 31^96 378, // 31^102 408, // 31^108 437, // 31^114 467, // 31^120 497, // 31^126 526, // 31^132 556, // 31^138 586, // 31^144 616, // 31^150 645, // 31^156 675, // 31^162 705, // 31^168 735, // 31^174 764, // 31^180 794, // 31^186 824, // 31^192 853, // 31^198 883, // 31^204 ]; const BASE31_SMALL_INT_POWERS: [u128; 6] = [1, 31, 961, 29791, 923521, 28629151]; const BASE31_STEP: i32 = 6; const BASE31_BIAS: i32 = 234; // BASE33 const BASE33_SMALL_MANTISSA: [u128; 6] = [ 170141183460469231731687303715884105728, // 33^0 175458095443608895223302531957005484032, // 33^1 180941160926221673199030736080661905408, // 33^2 186595572205166100486500446583182589952, // 33^3 192426683836577541126703585538907045888, // 33^4 198440017706470589286913072586997891072, // 33^5 ]; const BASE33_SMALL_EXPONENT: [i32; 6] = [ -127, // 33^0 -122, // 33^1 -117, // 33^2 -112, // 33^3 -107, // 33^4 -102, // 33^5 ]; const BASE33_LARGE_MANTISSA: [u128; 72] = [ 312720366502509540124188550868577470271, // 33^-228 188065849520234218420139418711557486770, // 33^-222 226200577540468899968415353242546081790, // 33^-216 272068009211510778916881923005514361559, // 33^-210 327236130168906522048072439540872358087, // 33^-204 196795435814493025178219114364462772750, // 33^-198 236700290627603575579431376108202583063, // 33^-192 284696783496570703658001718555889571262, // 33^-186 171212841180688182412693440011648609110, // 33^-180 205930229524469868245369490973155168397, // 33^-174 247687376364759110421449812279701734754, // 33^-168 297911756579516503503766398038992340964, // 33^-162 179160149400574418614614090847719005026, // 33^-156 215489039450973655880961058312920063458, // 33^-150 259184457474862991304220337185522020620, // 33^-144 311740138466868713435648102307209093287, // 33^-138 187476353478425047886734580102095167043, // 33^-132 225491547456297727220699982909970598320, // 33^-126 271215206775862669602998925081523543654, // 33^-120 326210402191372960931717472229356291097, // 33^-114 196178576715647050727159488732861667611, // 33^-108 235958348989735718000162987087766864735, // 33^-102 283804395923732956473182174007605293342, // 33^-96 170676171219393275768862099029406252664, // 33^-90 205284737238107330416766226733647440005, // 33^-84 246910995494199118965634147066154669324, // 33^-78 296977946418022259559609845940558313794, // 33^-72 178598568447993152099773363289076713958, // 33^-66 214813584890064968045989415466080479007, // 33^-60 258372038781252962127704032685119793391, // 33^-54 310762982974959535779710715380461212334, // 33^-48 186888705223357570139042022172334279947, // 33^-42 224784739840635370899218738060963824868, // 33^-36 270365077465939099085308357449561310080, // 33^-30 325187889378018709806160016110270251585, // 33^-24 195563651173574149793648095659417101115, // 33^-18 235218732982278125085778976978720276897, // 33^-12 282914805556997697053159518336509943216, // 33^-6 170141183460469231731687303715884105728, // 33^0 204641268259797795202129106105341575168, // 33^6 246137048204490191229033862368809975808, // 33^12 296047063302535604636168085099824283648, // 33^18 178038747781766620403928207609098977344, // 33^24 214140247554538205717741625292909706188, // 33^30 257562166629747183314707096744136073023, // 33^36 309788890395834268833431845588643035745, // 33^42 186302898963108514077454910111746951397, // 33^48 224080147727111315915564635257325506176, // 33^54 269517612902775795573733407057825442248, // 33^60 324168581650849479410768181980047458277, // 33^66 194950653127503229444535496044715069916, // 33^72 234481435315497306894208542281087212757, // 33^78 282028003628468309677795696968404883305, // 33^84 339215745262040382698593524434347927396, // 33^90 203999816247443047277506123370388146319, // 33^96 245365526867526093228395853689144006062, // 33^102 295119098058174229856749108333084701428, // 33^108 177480681884243207276442522127875068624, // 33^114 213469020807909470054649976638820369879, // 33^120 256754833038160188521579955085771893751, // 33^126 308817851128733566186038756059234075639, // 33^132 185718928923909504089695656878457160369, // 33^138 223377764171191270264346565880758640128, // 33^144 268672804733672512805858396506074869210, // 33^150 323152468963460648455199258995519212913, // 33^156 194339576535660800930047023345366203227, // 33^162 233746448722509584063702393615930970798, // 33^168 281143981397731320107155010945727058593, // 33^174 338152466949356579395454697640846384307, // 33^180 203360374878824300807265157901557614739, // 33^186 244596423879111037469845073222731160599, // 33^192 294194041538814672349638971928150296782, // 33^198 ]; const BASE33_LARGE_EXPONENT: [i32; 72] = [ -1278, // 33^-228 -1247, // 33^-222 -1217, // 33^-216 -1187, // 33^-210 -1157, // 33^-204 -1126, // 33^-198 -1096, // 33^-192 -1066, // 33^-186 -1035, // 33^-180 -1005, // 33^-174 -975, // 33^-168 -945, // 33^-162 -914, // 33^-156 -884, // 33^-150 -854, // 33^-144 -824, // 33^-138 -793, // 33^-132 -763, // 33^-126 -733, // 33^-120 -703, // 33^-114 -672, // 33^-108 -642, // 33^-102 -612, // 33^-96 -581, // 33^-90 -551, // 33^-84 -521, // 33^-78 -491, // 33^-72 -460, // 33^-66 -430, // 33^-60 -400, // 33^-54 -370, // 33^-48 -339, // 33^-42 -309, // 33^-36 -279, // 33^-30 -249, // 33^-24 -218, // 33^-18 -188, // 33^-12 -158, // 33^-6 -127, // 33^0 -97, // 33^6 -67, // 33^12 -37, // 33^18 -6, // 33^24 24, // 33^30 54, // 33^36 84, // 33^42 115, // 33^48 145, // 33^54 175, // 33^60 205, // 33^66 236, // 33^72 266, // 33^78 296, // 33^84 326, // 33^90 357, // 33^96 387, // 33^102 417, // 33^108 448, // 33^114 478, // 33^120 508, // 33^126 538, // 33^132 569, // 33^138 599, // 33^144 629, // 33^150 659, // 33^156 690, // 33^162 720, // 33^168 750, // 33^174 780, // 33^180 811, // 33^186 841, // 33^192 871, // 33^198 ]; const BASE33_SMALL_INT_POWERS: [u128; 6] = [1, 33, 1089, 35937, 1185921, 39135393]; const BASE33_STEP: i32 = 6; const BASE33_BIAS: i32 = 228; // BASE34 const BASE34_SMALL_MANTISSA: [u128; 6] = [ 170141183460469231731687303715884105728, // 34^0 180775007426748558714917760198126862336, // 34^1 192073445390920343634600120210509791232, // 34^2 204078035727852865111762627723666653184, // 34^3 216832912960843669181247791956395819008, // 34^4 230384970020896398505075778953670557696, // 34^5 ]; const BASE34_SMALL_EXPONENT: [i32; 6] = [ -127, // 34^0 -122, // 34^1 -117, // 34^2 -112, // 34^3 -107, // 34^4 -102, // 34^5 ]; const BASE34_LARGE_MANTISSA: [u128; 72] = [ 177178627816250193201809052313908765038, // 34^-228 254908880844119689445018585029338745822, // 34^-222 183370134237042583472660416437030762483, // 34^-216 263816670637481076390123392064426194701, // 34^-210 189778002824260993825223275854263893366, // 34^-204 273035743108558333663040444930692235847, // 34^-198 196409794352921881357331916371145369426, // 34^-192 282576976029244796208883094031259474966, // 34^-186 203273333809293576669182005378991774735, // 34^-180 292451627295127901322196175360309190338, // 34^-174 210376719623757394611528557965027181599, // 34^-168 302671348208910116654395983418902348443, // 34^-162 217728333226311038599715596529740433091, // 34^-156 313248197228018957952397977805898800839, // 34^-150 225336848935989032116058614991615739830, // 34^-144 324194654192627182361160566056046446660, // 34^-138 233211244195868906543198111154344051285, // 34^-132 335523635050871088900625460663893770435, // 34^-126 241360810165739638162969982622013142483, // 34^-120 173624253549320755964330470575918052959, // 34^-114 249795162684930840147804514904540284970, // 34^-108 179691552375964624115693619162436412029, // 34^-102 258524253618237975606418771469177669493, // 34^-96 185970872935167515117533503151908736546, // 34^-90 267558382598330880564928534158522761469, // 34^-84 192469624325502244069180532494789364726, // 34^-78 276908209178500704519431941303594138118, // 34^-72 199195474556460799929094324231727524305, // 34^-66 286584765410084542875511011996966308779, // 34^-60 206156359596095351859662099550265135432, // 34^-54 296599468859408121472112670217716316867, // 34^-48 213360492734829033350750838314127106094, // 34^-42 306964136079605489713373754120772284157, // 34^-36 220816374276485055706958449270700673524, // 34^-30 317690996553211397504541477525504659745, // 34^-24 228532801567968794073232940648013889325, // 34^-18 328792707121977505492535302517672775182, // 34^-12 236518879379437072732268269343858967136, // 34^-6 170141183460469231731687303715884105728, // 34^0 244784030647202423411643015138274967552, // 34^6 176086766417174433233313223161344425984, // 34^12 253338007592048088741599978367647481856, // 34^18 182240117745863932172015090234506084352, // 34^24 262190903226072497809728032921351003168, // 34^30 188608497911442742195268251474898499613, // 34^36 271353163261640374618023568003458637143, // 34^42 195199421095732140407812372336079928061, // 34^48 280835598436492094076350884217966821974, // 34^54 202020664063606263361049018383687293681, // 34^60 290649397269553933781951224423558743337, // 34^66 209080275338955809947349984471742343690, // 34^72 300806139262500062617960370620227418603, // 34^78 216386584701305758176605078134277823932, // 34^84 311317808562643058781928971959145202656, // 34^90 223948213014292349032159641795245781843, // 34^96 322196808103274080809106622508050735664, // 34^102 231774082397596158130210248504430880773, // 34^108 333455974238137167751959613429477643393, // 34^114 239873426754333326759263874720553852658, // 34^120 172554295943652591814138834633669982456, // 34^126 248255802666326436218178945574152405546, // 34^132 178584205106164167247426311765412935775, // 34^138 256931100670110578075784008065054807112, // 34^144 184824829419575343010846487395966556532, // 34^150 265909556926979410208640982981191461086, // 34^156 191283532323968216046404126970062690800, // 34^162 275201765300840924300371814765015192837, // 34^168 197967934574808286676526111499839216564, // 34^174 284818689858133833493377548255268489047, // 34^180 204885923234829474007514465274285458561, // 34^186 294771677804553486829405243638525556429, // 34^192 212045660980140516237478265085420658486, // 34^198 ]; const BASE34_LARGE_EXPONENT: [i32; 72] = [ -1287, // 34^-228 -1257, // 34^-222 -1226, // 34^-216 -1196, // 34^-210 -1165, // 34^-204 -1135, // 34^-198 -1104, // 34^-192 -1074, // 34^-186 -1043, // 34^-180 -1013, // 34^-174 -982, // 34^-168 -952, // 34^-162 -921, // 34^-156 -891, // 34^-150 -860, // 34^-144 -830, // 34^-138 -799, // 34^-132 -769, // 34^-126 -738, // 34^-120 -707, // 34^-114 -677, // 34^-108 -646, // 34^-102 -616, // 34^-96 -585, // 34^-90 -555, // 34^-84 -524, // 34^-78 -494, // 34^-72 -463, // 34^-66 -433, // 34^-60 -402, // 34^-54 -372, // 34^-48 -341, // 34^-42 -311, // 34^-36 -280, // 34^-30 -250, // 34^-24 -219, // 34^-18 -189, // 34^-12 -158, // 34^-6 -127, // 34^0 -97, // 34^6 -66, // 34^12 -36, // 34^18 -5, // 34^24 25, // 34^30 56, // 34^36 86, // 34^42 117, // 34^48 147, // 34^54 178, // 34^60 208, // 34^66 239, // 34^72 269, // 34^78 300, // 34^84 330, // 34^90 361, // 34^96 391, // 34^102 422, // 34^108 452, // 34^114 483, // 34^120 514, // 34^126 544, // 34^132 575, // 34^138 605, // 34^144 636, // 34^150 666, // 34^156 697, // 34^162 727, // 34^168 758, // 34^174 788, // 34^180 819, // 34^186 849, // 34^192 880, // 34^198 ]; const BASE34_SMALL_INT_POWERS: [u128; 6] = [1, 34, 1156, 39304, 1336336, 45435424]; const BASE34_STEP: i32 = 6; const BASE34_BIAS: i32 = 228; // BASE35 const BASE35_SMALL_MANTISSA: [u128; 6] = [ 170141183460469231731687303715884105728, // 35^0 186091919409888222206532988439248240640, // 35^1 203538036854565243038395456105427763200, // 35^2 222619727809680734573245030115311616000, // 35^3 243490327291838303439486751688622080000, // 35^4 266317545475448144386938634659430400000, // 35^5 ]; const BASE35_SMALL_EXPONENT: [i32; 6] = [ -127, // 35^0 -122, // 35^1 -117, // 35^2 -112, // 35^3 -107, // 35^4 -102, // 35^5 ]; const BASE35_LARGE_MANTISSA: [u128; 71] = [ 209347927024496598038547144935237941328, // 35^-222 179203738418473223738234323205585013488, // 35^-216 306800075067366652359189609572260396844, // 35^-210 262623667597658781475957209306702595701, // 35^-204 224808259148244964176155115402974869951, // 35^-198 192437923982884034851744022831878031683, // 35^-192 329457242604437106875016361913696434196, // 35^-186 282018410035885035080273518999343445370, // 35^-180 241410335891937127541744115564170038883, // 35^-174 206649453374488156391879990784284316065, // 35^-168 176893820317164915550880607303262990177, // 35^-162 302845453064861578599747045789577351117, // 35^-156 259238475028744868618971960605253012775, // 35^-150 221910503377561727015952290044860359194, // 35^-144 189957418565367403947310019950147953923, // 35^-138 325210571999150993462493010696415973233, // 35^-132 278383221194439940371876875109029372360, // 35^-126 238298581027663491439386725539968731964, // 35^-120 203985762777473298078638682440591083627, // 35^-114 174613676827044081042213382537397413381, // 35^-108 298941805740831610317914779329181594758, // 35^-102 255896917250379178747915691007066092001, // 35^-96 219050099386294168656703063834650082992, // 35^-90 187508886612326915552639247886565481996, // 35^-84 321018640549353575448221161417409055741, // 35^-78 274794889570264049674062490664049677426, // 35^-72 235226936369523138128743288428339150410, // 35^-66 201356406883409564599485887013038683702, // 35^-60 172362924156377643998457025163202983813, // 35^-54 295088476036816041433113722500648405442, // 35^-48 252598431814515573631538400793788490787, // 35^-42 216226565713775509518577464877951003673, // 35^-36 185091915989032531210622402180350455682, // 35^-30 316880742672855387564028424008808371736, // 35^-24 271252811178556028546302550648486766486, // 35^-18 232194884901007304160476988045002650981, // 35^-12 198760943121441293094365080225590768425, // 35^-6 170141183460469231731687303715884105728, // 35^0 291284815363771407923214131658752000000, // 35^6 249342463523006462279286784000000000000, // 35^12 213439427105318371328000000000000000000, // 35^18 182706099873129286194801330566406250000, // 35^24 312796181882350172840701732490664710439, // 35^30 267756389819817671992755772413469185401, // 35^36 229201916269897841937750664282591869365, // 35^42 196198934625406481835921498002300001382, // 35^48 335896161555784742544555459149306885413, // 35^54 287530183492901554386658282699185698307, // 35^60 246128464334152340394473578644658105769, // 35^66 210688214432220328999897334535237907298, // 35^72 180351036686161310983217274120661055754, // 35^78 308764270668182755993104788402294107778, // 35^84 264305036979502132888830858069861274896, // 35^90 226247526702365186299998179464172492810, // 35^96 193669950160303864708173829536684422103, // 35^102 331566493935091266452974274160244175815, // 35^108 283823948447894890028153679891537227671, // 35^114 242955893270455896832007072848205740580, // 35^120 207972464612800582882401068589523181243, // 35^126 178026330025978501184229413909552478799, // 35^132 304784330382628027085206214062708598478, // 35^138 260898171728955674614898641290082042559, // 35^144 223331218918173589647399860035052277272, // 35^150 191173564049707817673529979461919468076, // 35^156 327292635293038256953486831534470016773, // 35^162 280165486398550695538293601153410149006, // 35^168 239824216327565160313568077123618791086, // 35^174 205291720534454460326603808102056989101, // 35^180 175731588600014458664842906141703880790, // 35^186 300855691125661557416025651977765954086, // 35^192 257535220627636274500677259708261311842, // 35^198 ]; const BASE35_LARGE_EXPONENT: [i32; 71] = [ -1266, // 35^-222 -1235, // 35^-216 -1205, // 35^-210 -1174, // 35^-204 -1143, // 35^-198 -1112, // 35^-192 -1082, // 35^-186 -1051, // 35^-180 -1020, // 35^-174 -989, // 35^-168 -958, // 35^-162 -928, // 35^-156 -897, // 35^-150 -866, // 35^-144 -835, // 35^-138 -805, // 35^-132 -774, // 35^-126 -743, // 35^-120 -712, // 35^-114 -681, // 35^-108 -651, // 35^-102 -620, // 35^-96 -589, // 35^-90 -558, // 35^-84 -528, // 35^-78 -497, // 35^-72 -466, // 35^-66 -435, // 35^-60 -404, // 35^-54 -374, // 35^-48 -343, // 35^-42 -312, // 35^-36 -281, // 35^-30 -251, // 35^-24 -220, // 35^-18 -189, // 35^-12 -158, // 35^-6 -127, // 35^0 -97, // 35^6 -66, // 35^12 -35, // 35^18 -4, // 35^24 26, // 35^30 57, // 35^36 88, // 35^42 119, // 35^48 149, // 35^54 180, // 35^60 211, // 35^66 242, // 35^72 273, // 35^78 303, // 35^84 334, // 35^90 365, // 35^96 396, // 35^102 426, // 35^108 457, // 35^114 488, // 35^120 519, // 35^126 550, // 35^132 580, // 35^138 611, // 35^144 642, // 35^150 673, // 35^156 703, // 35^162 734, // 35^168 765, // 35^174 796, // 35^180 827, // 35^186 857, // 35^192 888, // 35^198 ]; const BASE35_SMALL_INT_POWERS: [u128; 6] = [1, 35, 1225, 42875, 1500625, 52521875]; const BASE35_STEP: i32 = 6; const BASE35_BIAS: i32 = 222; // BASE36 const BASE36_SMALL_MANTISSA: [u128; 6] = [ 170141183460469231731687303715884105728, // 36^0 191408831393027885698148216680369618944, // 36^1 215334935317156371410416743765415821312, // 36^2 242251802231800917836718836736092798976, // 36^3 272533277510776032566308691328104398848, // 36^4 306599937199623036637097277744117448704, // 36^5 ]; const BASE36_SMALL_EXPONENT: [i32; 6] = [ -127, // 36^0 -122, // 36^1 -117, // 36^2 -112, // 36^3 -107, // 36^4 -102, // 36^5 ]; const BASE36_LARGE_MANTISSA: [u128; 71] = [ 206105367118290399407064648402758144682, // 36^-222 208917317212507950117664039252872831665, // 36^-216 211767631486382365261996259087726574961, // 36^-210 214656833352574406771088703014069554755, // 36^-204 217585453364802351586979201161384846208, // 36^-198 220554029315269330081435801781477974040, // 36^-192 223563106333419891448609016293621894840, // 36^-186 226613236986043931067161987739751269180, // 36^-180 229704981378746362247969882824709232796, // 36^-174 232838907258801165579649662968151663564, // 36^-168 236015590119408703302029793810763336632, // 36^-162 239235613305375443823879271798297650114, // 36^-156 242499568120235502703106353919523432682, // 36^-150 245808053934833671173174941698733239342, // 36^-144 249161678297389871677290466673500998400, // 36^-138 252561057045065251911260457800735557729, // 36^-132 256006814417050404626793229969178591795, // 36^-126 259499583169196479959998361450291137700, // 36^-120 263040004690210240376322725691803307553, // 36^-114 266628729119434395515123988465075762881, // 36^-108 270266415466234845327287688358055741312, // 36^-102 273953731731016754981191818978678705632, // 36^-96 277691355027891684120101092281051616669, // 36^-90 281479971709018296242657937208050445965, // 36^-84 285320277490639481303204301467482637509, // 36^-78 289212977580839036146652597763405686112, // 36^-72 293158786809041363160730749526943361727, // 36^-66 297158429757277967604640789526650060843, // 36^-60 301212640893244858516269504216828222245, // 36^-54 305322164705175286969651759320250334279, // 36^-48 309487755838552588810803796052767101096, // 36^-42 313710179234688236904530296665341569850, // 36^-36 317990210271190550439415903835536554761, // 36^-30 322328634904349856025836233807108654402, // 36^-24 326726249813466247246220462666861782844, // 36^-18 331183862547146446042592332649497399781, // 36^-12 335702291671596630919115661345637412333, // 36^-6 170141183460469231731687303715884105728, // 36^0 172462464674787958108367218731066064896, // 36^6 174815415743320440759790006808579407872, // 36^12 177200468746272961345336076752392290304, // 36^18 179618061658836457920697688990341398528, // 36^24 182068638431613361423174859113151594496, // 36^30 184552649072141716781794491390137475072, // 36^36 187070549727531559196917812917453861026, // 36^42 189622802768228720381105803326920695033, // 36^48 192209876872921446586714266254161951235, // 36^54 194832247114605420104007752175098574688, // 36^60 197490395047822988635051696441052554380, // 36^66 200184808797092622572327630249651738267, // 36^72 202915983146544838776512848181734408257, // 36^78 205684419630781050995309380627725821797, // 36^84 208490626626972031635281014538153149532, // 36^90 211335119448212897232599978727666183358, // 36^96 214218420438151760708217936124820030498, // 36^102 217141059066909427380630585083218539864, // 36^108 220103572028307748788051030668660629356, // 36^114 223106503338424488684979682521025988628, // 36^120 226150404435492799169987273137391228527, // 36^126 229235834281163651816744244429413474808, // 36^132 232363359463149818964276081092475750857, // 36^138 235533554299270254021060647605641184828, // 36^144 238747000942913976797497733353022683918, // 36^150 242004289489942830549695955106475311593, // 36^156 245306018087052741642305313258629505287, // 36^162 248652793041613380567795520750960012282, // 36^168 252045228933006394543323172270604972624, // 36^174 255483948725482657093998355855298189652, // 36^180 258969583882559258973487053363982248701, // 36^186 262502774482977247520692697766891651596, // 36^192 266084169338241408156670471179837543899, // 36^198 ]; const BASE36_LARGE_EXPONENT: [i32; 71] = [ -1275, // 36^-222 -1244, // 36^-216 -1213, // 36^-210 -1182, // 36^-204 -1151, // 36^-198 -1120, // 36^-192 -1089, // 36^-186 -1058, // 36^-180 -1027, // 36^-174 -996, // 36^-168 -965, // 36^-162 -934, // 36^-156 -903, // 36^-150 -872, // 36^-144 -841, // 36^-138 -810, // 36^-132 -779, // 36^-126 -748, // 36^-120 -717, // 36^-114 -686, // 36^-108 -655, // 36^-102 -624, // 36^-96 -593, // 36^-90 -562, // 36^-84 -531, // 36^-78 -500, // 36^-72 -469, // 36^-66 -438, // 36^-60 -407, // 36^-54 -376, // 36^-48 -345, // 36^-42 -314, // 36^-36 -283, // 36^-30 -252, // 36^-24 -221, // 36^-18 -190, // 36^-12 -159, // 36^-6 -127, // 36^0 -96, // 36^6 -65, // 36^12 -34, // 36^18 -3, // 36^24 28, // 36^30 59, // 36^36 90, // 36^42 121, // 36^48 152, // 36^54 183, // 36^60 214, // 36^66 245, // 36^72 276, // 36^78 307, // 36^84 338, // 36^90 369, // 36^96 400, // 36^102 431, // 36^108 462, // 36^114 493, // 36^120 524, // 36^126 555, // 36^132 586, // 36^138 617, // 36^144 648, // 36^150 679, // 36^156 710, // 36^162 741, // 36^168 772, // 36^174 803, // 36^180 834, // 36^186 865, // 36^192 896, // 36^198 ]; const BASE36_SMALL_INT_POWERS: [u128; 6] = [1, 36, 1296, 46656, 1679616, 60466176]; const BASE36_STEP: i32 = 6; const BASE36_BIAS: i32 = 222; }} // cfg_if // HIGH LEVEL // ---------- pub(crate) const BASE10_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE10_SMALL_MANTISSA, exp: &BASE10_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE10_LARGE_MANTISSA, exp: &BASE10_LARGE_EXPONENT }, small_int: &BASE10_SMALL_INT_POWERS, step: BASE10_STEP, bias: BASE10_BIAS, }; cfg_if! { if #[cfg(feature = "radix")] { pub(crate) const BASE3_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE3_SMALL_MANTISSA, exp: &BASE3_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE3_LARGE_MANTISSA, exp: &BASE3_LARGE_EXPONENT }, small_int: &BASE3_SMALL_INT_POWERS, step: BASE3_STEP, bias: BASE3_BIAS, }; pub(crate) const BASE5_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE5_SMALL_MANTISSA, exp: &BASE5_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE5_LARGE_MANTISSA, exp: &BASE5_LARGE_EXPONENT }, small_int: &BASE5_SMALL_INT_POWERS, step: BASE5_STEP, bias: BASE5_BIAS, }; pub(crate) const BASE6_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE6_SMALL_MANTISSA, exp: &BASE6_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE6_LARGE_MANTISSA, exp: &BASE6_LARGE_EXPONENT }, small_int: &BASE6_SMALL_INT_POWERS, step: BASE6_STEP, bias: BASE6_BIAS, }; pub(crate) const BASE7_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE7_SMALL_MANTISSA, exp: &BASE7_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE7_LARGE_MANTISSA, exp: &BASE7_LARGE_EXPONENT }, small_int: &BASE7_SMALL_INT_POWERS, step: BASE7_STEP, bias: BASE7_BIAS, }; pub(crate) const BASE9_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE9_SMALL_MANTISSA, exp: &BASE9_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE9_LARGE_MANTISSA, exp: &BASE9_LARGE_EXPONENT }, small_int: &BASE9_SMALL_INT_POWERS, step: BASE9_STEP, bias: BASE9_BIAS, }; pub(crate) const BASE11_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE11_SMALL_MANTISSA, exp: &BASE11_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE11_LARGE_MANTISSA, exp: &BASE11_LARGE_EXPONENT }, small_int: &BASE11_SMALL_INT_POWERS, step: BASE11_STEP, bias: BASE11_BIAS, }; pub(crate) const BASE12_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE12_SMALL_MANTISSA, exp: &BASE12_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE12_LARGE_MANTISSA, exp: &BASE12_LARGE_EXPONENT }, small_int: &BASE12_SMALL_INT_POWERS, step: BASE12_STEP, bias: BASE12_BIAS, }; pub(crate) const BASE13_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE13_SMALL_MANTISSA, exp: &BASE13_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE13_LARGE_MANTISSA, exp: &BASE13_LARGE_EXPONENT }, small_int: &BASE13_SMALL_INT_POWERS, step: BASE13_STEP, bias: BASE13_BIAS, }; pub(crate) const BASE14_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE14_SMALL_MANTISSA, exp: &BASE14_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE14_LARGE_MANTISSA, exp: &BASE14_LARGE_EXPONENT }, small_int: &BASE14_SMALL_INT_POWERS, step: BASE14_STEP, bias: BASE14_BIAS, }; pub(crate) const BASE15_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE15_SMALL_MANTISSA, exp: &BASE15_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE15_LARGE_MANTISSA, exp: &BASE15_LARGE_EXPONENT }, small_int: &BASE15_SMALL_INT_POWERS, step: BASE15_STEP, bias: BASE15_BIAS, }; pub(crate) const BASE17_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE17_SMALL_MANTISSA, exp: &BASE17_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE17_LARGE_MANTISSA, exp: &BASE17_LARGE_EXPONENT }, small_int: &BASE17_SMALL_INT_POWERS, step: BASE17_STEP, bias: BASE17_BIAS, }; pub(crate) const BASE18_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE18_SMALL_MANTISSA, exp: &BASE18_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE18_LARGE_MANTISSA, exp: &BASE18_LARGE_EXPONENT }, small_int: &BASE18_SMALL_INT_POWERS, step: BASE18_STEP, bias: BASE18_BIAS, }; pub(crate) const BASE19_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE19_SMALL_MANTISSA, exp: &BASE19_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE19_LARGE_MANTISSA, exp: &BASE19_LARGE_EXPONENT }, small_int: &BASE19_SMALL_INT_POWERS, step: BASE19_STEP, bias: BASE19_BIAS, }; pub(crate) const BASE20_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE20_SMALL_MANTISSA, exp: &BASE20_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE20_LARGE_MANTISSA, exp: &BASE20_LARGE_EXPONENT }, small_int: &BASE20_SMALL_INT_POWERS, step: BASE20_STEP, bias: BASE20_BIAS, }; pub(crate) const BASE21_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE21_SMALL_MANTISSA, exp: &BASE21_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE21_LARGE_MANTISSA, exp: &BASE21_LARGE_EXPONENT }, small_int: &BASE21_SMALL_INT_POWERS, step: BASE21_STEP, bias: BASE21_BIAS, }; pub(crate) const BASE22_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE22_SMALL_MANTISSA, exp: &BASE22_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE22_LARGE_MANTISSA, exp: &BASE22_LARGE_EXPONENT }, small_int: &BASE22_SMALL_INT_POWERS, step: BASE22_STEP, bias: BASE22_BIAS, }; pub(crate) const BASE23_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE23_SMALL_MANTISSA, exp: &BASE23_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE23_LARGE_MANTISSA, exp: &BASE23_LARGE_EXPONENT }, small_int: &BASE23_SMALL_INT_POWERS, step: BASE23_STEP, bias: BASE23_BIAS, }; pub(crate) const BASE24_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE24_SMALL_MANTISSA, exp: &BASE24_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE24_LARGE_MANTISSA, exp: &BASE24_LARGE_EXPONENT }, small_int: &BASE24_SMALL_INT_POWERS, step: BASE24_STEP, bias: BASE24_BIAS, }; pub(crate) const BASE25_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE25_SMALL_MANTISSA, exp: &BASE25_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE25_LARGE_MANTISSA, exp: &BASE25_LARGE_EXPONENT }, small_int: &BASE25_SMALL_INT_POWERS, step: BASE25_STEP, bias: BASE25_BIAS, }; pub(crate) const BASE26_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE26_SMALL_MANTISSA, exp: &BASE26_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE26_LARGE_MANTISSA, exp: &BASE26_LARGE_EXPONENT }, small_int: &BASE26_SMALL_INT_POWERS, step: BASE26_STEP, bias: BASE26_BIAS, }; pub(crate) const BASE27_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE27_SMALL_MANTISSA, exp: &BASE27_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE27_LARGE_MANTISSA, exp: &BASE27_LARGE_EXPONENT }, small_int: &BASE27_SMALL_INT_POWERS, step: BASE27_STEP, bias: BASE27_BIAS, }; pub(crate) const BASE28_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE28_SMALL_MANTISSA, exp: &BASE28_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE28_LARGE_MANTISSA, exp: &BASE28_LARGE_EXPONENT }, small_int: &BASE28_SMALL_INT_POWERS, step: BASE28_STEP, bias: BASE28_BIAS, }; pub(crate) const BASE29_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE29_SMALL_MANTISSA, exp: &BASE29_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE29_LARGE_MANTISSA, exp: &BASE29_LARGE_EXPONENT }, small_int: &BASE29_SMALL_INT_POWERS, step: BASE29_STEP, bias: BASE29_BIAS, }; pub(crate) const BASE30_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE30_SMALL_MANTISSA, exp: &BASE30_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE30_LARGE_MANTISSA, exp: &BASE30_LARGE_EXPONENT }, small_int: &BASE30_SMALL_INT_POWERS, step: BASE30_STEP, bias: BASE30_BIAS, }; pub(crate) const BASE31_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE31_SMALL_MANTISSA, exp: &BASE31_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE31_LARGE_MANTISSA, exp: &BASE31_LARGE_EXPONENT }, small_int: &BASE31_SMALL_INT_POWERS, step: BASE31_STEP, bias: BASE31_BIAS, }; pub(crate) const BASE33_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE33_SMALL_MANTISSA, exp: &BASE33_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE33_LARGE_MANTISSA, exp: &BASE33_LARGE_EXPONENT }, small_int: &BASE33_SMALL_INT_POWERS, step: BASE33_STEP, bias: BASE33_BIAS, }; pub(crate) const BASE34_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE34_SMALL_MANTISSA, exp: &BASE34_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE34_LARGE_MANTISSA, exp: &BASE34_LARGE_EXPONENT }, small_int: &BASE34_SMALL_INT_POWERS, step: BASE34_STEP, bias: BASE34_BIAS, }; pub(crate) const BASE35_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE35_SMALL_MANTISSA, exp: &BASE35_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE35_LARGE_MANTISSA, exp: &BASE35_LARGE_EXPONENT }, small_int: &BASE35_SMALL_INT_POWERS, step: BASE35_STEP, bias: BASE35_BIAS, }; pub(crate) const BASE36_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE36_SMALL_MANTISSA, exp: &BASE36_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE36_LARGE_MANTISSA, exp: &BASE36_LARGE_EXPONENT }, small_int: &BASE36_SMALL_INT_POWERS, step: BASE36_STEP, bias: BASE36_BIAS, }; }} // cfg_if /// Get powers from radix. pub(crate) fn get_powers(radix: u32) -> &'static ModeratePathPowers { debug_assert_radix!(radix); #[cfg(not(feature = "radix"))] { &BASE10_POWERS } #[cfg(feature = "radix")] { match radix { 3 => &BASE3_POWERS, 5 => &BASE5_POWERS, 6 => &BASE6_POWERS, 7 => &BASE7_POWERS, 9 => &BASE9_POWERS, 10 => &BASE10_POWERS, 11 => &BASE11_POWERS, 12 => &BASE12_POWERS, 13 => &BASE13_POWERS, 14 => &BASE14_POWERS, 15 => &BASE15_POWERS, 17 => &BASE17_POWERS, 18 => &BASE18_POWERS, 19 => &BASE19_POWERS, 20 => &BASE20_POWERS, 21 => &BASE21_POWERS, 22 => &BASE22_POWERS, 23 => &BASE23_POWERS, 24 => &BASE24_POWERS, 25 => &BASE25_POWERS, 26 => &BASE26_POWERS, 27 => &BASE27_POWERS, 28 => &BASE28_POWERS, 29 => &BASE29_POWERS, 30 => &BASE30_POWERS, 31 => &BASE31_POWERS, 33 => &BASE33_POWERS, 34 => &BASE34_POWERS, 35 => &BASE35_POWERS, 36 => &BASE36_POWERS, // Powers of 2, and others, should already be handled by now. _ => unreachable!(), } } } // TESTS // ----- #[cfg(test)] mod tests { use crate::util::test::*; use super::*; #[test] fn normalization_test() { // Ensure each valid is normalized. for base in BASE_POWN.iter().cloned() { let powers = get_powers(base); for idx in 0..powers.small.len() { let fp = powers.get_small(idx); assert_eq!(fp.mant.leading_zeros(), 0); } for idx in 0..powers.large.len() { let fp = powers.get_large(idx); assert_eq!(fp.mant.leading_zeros(), 0); } } } #[cfg(feature = "radix")] #[test] #[should_panic] fn pow2_test() { for base in BASE_POW2.iter().cloned() { let _ = get_powers(base); } } } lexical-core-0.7.6/src/atof/algorithm/cached_float80.rs000075500000000000000000006513120000000000000210150ustar 00000000000000//! Cached exponents for basen values with 80-bit extended floats. //! //! Exact versions of base**n as an extended-precision float, with both //! large and small powers. Use the large powers to minimize the amount //! of compounded error. //! //! These values were calculated using Python, using the arbitrary-precision //! integer to calculate exact extended-representation of each value. //! These values are all normalized. //! //! This files takes ~ 26KB of storage. //! //! This file is mostly automatically generated, do not change values //! manually, unless you know what you are doing. The script to generate //! the values is as follows: //! //! ```text //! import math //! from collections import deque //! //! STEP_STR = "const BASE{0}_STEP: i32 = {1};" //! SMALL_MANTISSA_STR = "const BASE{0}_SMALL_MANTISSA: [u64; {1}] = [" //! SMALL_EXPONENT_STR = "const BASE{0}_SMALL_EXPONENT: [i32; {1}] = [" //! LARGE_MANTISSA_STR = "const BASE{0}_LARGE_MANTISSA: [u64; {1}] = [" //! LARGE_EXPONENT_STR = "const BASE{0}_LARGE_EXPONENT: [i32; {1}] = [" //! SMALL_INT_STR = "const BASE{0}_SMALL_INT_POWERS: [u64; {1}] = {2};" //! BIAS_STR = "const BASE{0}_BIAS: i32 = {1};" //! EXP_STR = "// {}^{}" //! POWER_STR = """pub(crate) const BASE{0}_POWERS: ModeratePathPowers = ModeratePathPowers {{ //! small: ExtendedFloatArray {{ mant: &BASE{0}_SMALL_MANTISSA, exp: &BASE{0}_SMALL_EXPONENT }}, //! large: ExtendedFloatArray {{ mant: &BASE{0}_LARGE_MANTISSA, exp: &BASE{0}_LARGE_EXPONENT }}, //! small_int: &BASE{0}_SMALL_INT_POWERS, //! step: BASE{0}_STEP, //! bias: BASE{0}_BIAS, //! }};\n""" //! //! def calculate_bitshift(base, exponent): //! ''' //! Calculate the bitshift required for a given base. The exponent //! is the absolute value of the max exponent (log distance from 1.) //! ''' //! //! return 63 + math.ceil(math.log2(base**exponent)) //! //! //! def next_fp(fp, base, step = 1): //! '''Generate the next extended-floating point value.''' //! //! return (fp[0] * (base**step), fp[1]) //! //! //! def prev_fp(fp, base, step = 1): //! '''Generate the previous extended-floating point value.''' //! //! return (fp[0] // (base**step), fp[1]) //! //! //! def normalize_fp(fp): //! '''Normalize a extended-float so the MSB is the 64th bit''' //! //! while fp[0] >> 64 != 0: //! fp = (fp[0] >> 1, fp[1] + 1) //! return fp //! //! //! def generate_small(base, count): //! '''Generate the small powers for a given base''' //! //! bitshift = calculate_bitshift(base, count) //! fps = [] //! fp = (1 << bitshift, -bitshift) //! for exp in range(count): //! fps.append((normalize_fp(fp), exp)) //! fp = next_fp(fp, base) //! //! # Print the small powers as integers. //! ints = [base**i for _, i in fps] //! //! return fps, ints //! //! //! def generate_large(base, step): //! '''Generate the large powers for a given base.''' //! //! # Get our starting parameters //! min_exp = math.floor(math.log(5e-324, base) - math.log(0xFFFFFFFFFFFFFFFF, base)) //! max_exp = math.ceil(math.log(1.7976931348623157e+308, base)) //! bitshift = calculate_bitshift(base, abs(min_exp - step)) //! fps = deque() //! //! # Add negative exponents //! # We need to go below the minimum exponent, since we need //! # all resulting exponents to be positive. //! fp = (1 << bitshift, -bitshift) //! for exp in range(-step, min_exp-step, -step): //! fp = prev_fp(fp, base, step) //! fps.appendleft((normalize_fp(fp), exp)) //! //! # Add positive exponents //! fp = (1 << bitshift, -bitshift) //! fps.append((normalize_fp(fp), 0)) //! for exp in range(step, max_exp, step): //! fp = next_fp(fp, base, step) //! fps.append((normalize_fp(fp), exp)) //! //! # Return the smallest exp, AKA, the bias //! return fps, -fps[0][1] //! //! //! def print_array(base, string, fps, index): //! '''Print an entire array''' //! //! print(string.format(base, len(fps))) //! for fp, exp in fps: //! value = " {},".format(fp[index]) //! exp = EXP_STR.format(base, exp) //! print(value.ljust(30, " ") + exp) //! print("];") //! //! //! def generate_base(base): //! '''Generate all powers and variables.''' //! //! step = math.floor(math.log(1e10, base)) //! small, ints = generate_small(base, step) //! large, bias = generate_large(base, step) //! //! print_array(base, SMALL_MANTISSA_STR, small, 0) //! print_array(base, SMALL_EXPONENT_STR, small, 1) //! print_array(base, LARGE_MANTISSA_STR, large, 0) //! print_array(base, LARGE_EXPONENT_STR, large, 1) //! print(SMALL_INT_STR.format(base, len(ints), ints)) //! print(STEP_STR.format(base, step)) //! print(BIAS_STR.format(base, bias)) //! //! //! def generate(): //! '''Generate all bases.''' //! //! bases = [ //! 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, //! 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36 //! ] //! //! for base in bases: //! print("// BASE{}\n".format(base)) //! generate_base(base) //! print("") //! //! print("// HIGH LEVEL\n// ----------\n") //! //! for base in bases: //! print(POWER_STR.format(base)) //! //! //! if __name__ == '__main__': //! generate() //! ``` use crate::util::*; use super::cached::{ExtendedFloatArray, ModeratePathPowers}; // LOW-LEVEL // --------- // BASE10 const BASE10_SMALL_MANTISSA: [u64; 10] = [ 9223372036854775808, // 10^0 11529215046068469760, // 10^1 14411518807585587200, // 10^2 18014398509481984000, // 10^3 11258999068426240000, // 10^4 14073748835532800000, // 10^5 17592186044416000000, // 10^6 10995116277760000000, // 10^7 13743895347200000000, // 10^8 17179869184000000000, // 10^9 ]; const BASE10_SMALL_EXPONENT: [i32; 10] = [ -63, // 10^0 -60, // 10^1 -57, // 10^2 -54, // 10^3 -50, // 10^4 -47, // 10^5 -44, // 10^6 -40, // 10^7 -37, // 10^8 -34, // 10^9 ]; const BASE10_LARGE_MANTISSA: [u64; 66] = [ 11555125961253852697, // 10^-350 13451937075301367670, // 10^-340 15660115838168849784, // 10^-330 18230774251475056848, // 10^-320 10611707258198326947, // 10^-310 12353653155963782858, // 10^-300 14381545078898527261, // 10^-290 16742321987285426889, // 10^-280 9745314011399999080, // 10^-270 11345038669416679861, // 10^-260 13207363278391631158, // 10^-250 15375394465392026070, // 10^-240 17899314949046850752, // 10^-230 10418772551374772303, // 10^-220 12129047596099288555, // 10^-210 14120069793541087484, // 10^-200 16437924692338667210, // 10^-190 9568131466127621947, // 10^-180 11138771039116687545, // 10^-170 12967236152753102995, // 10^-160 15095849699286165408, // 10^-150 17573882009934360870, // 10^-140 10229345649675443343, // 10^-130 11908525658859223294, // 10^-120 13863348470604074297, // 10^-110 16139061738043178685, // 10^-100 9394170331095332911, // 10^-90 10936253623915059621, // 10^-80 12731474852090538039, // 10^-70 14821387422376473014, // 10^-60 17254365866976409468, // 10^-50 10043362776618689222, // 10^-40 11692013098647223345, // 10^-30 13611294676837538538, // 10^-20 15845632502852867518, // 10^-10 9223372036854775808, // 10^0 10737418240000000000, // 10^10 12500000000000000000, // 10^20 14551915228366851806, // 10^30 16940658945086006781, // 10^40 9860761315262647567, // 10^50 11479437019748901445, // 10^60 13363823550460978230, // 10^70 15557538194652854267, // 10^80 18111358157653424735, // 10^90 10542197943230523224, // 10^100 12272733663244316382, // 10^110 14287342391028437277, // 10^120 16632655625031838749, // 10^130 9681479787123295682, // 10^140 11270725851789228247, // 10^150 13120851772591970218, // 10^160 15274681817498023410, // 10^170 17782069995880619867, // 10^180 10350527006597618960, // 10^190 12049599325514420588, // 10^200 14027579833653779454, // 10^210 16330252207878254650, // 10^220 9505457831475799117, // 10^230 11065809325636130661, // 10^240 12882297539194266616, // 10^250 14996968138956309548, // 10^260 17458768723248864463, // 10^270 10162340898095201970, // 10^280 11830521861667747109, // 10^290 13772540099066387756, // 10^300 ]; const BASE10_LARGE_EXPONENT: [i32; 66] = [ -1226, // 10^-350 -1193, // 10^-340 -1160, // 10^-330 -1127, // 10^-320 -1093, // 10^-310 -1060, // 10^-300 -1027, // 10^-290 -994, // 10^-280 -960, // 10^-270 -927, // 10^-260 -894, // 10^-250 -861, // 10^-240 -828, // 10^-230 -794, // 10^-220 -761, // 10^-210 -728, // 10^-200 -695, // 10^-190 -661, // 10^-180 -628, // 10^-170 -595, // 10^-160 -562, // 10^-150 -529, // 10^-140 -495, // 10^-130 -462, // 10^-120 -429, // 10^-110 -396, // 10^-100 -362, // 10^-90 -329, // 10^-80 -296, // 10^-70 -263, // 10^-60 -230, // 10^-50 -196, // 10^-40 -163, // 10^-30 -130, // 10^-20 -97, // 10^-10 -63, // 10^0 -30, // 10^10 3, // 10^20 36, // 10^30 69, // 10^40 103, // 10^50 136, // 10^60 169, // 10^70 202, // 10^80 235, // 10^90 269, // 10^100 302, // 10^110 335, // 10^120 368, // 10^130 402, // 10^140 435, // 10^150 468, // 10^160 501, // 10^170 534, // 10^180 568, // 10^190 601, // 10^200 634, // 10^210 667, // 10^220 701, // 10^230 734, // 10^240 767, // 10^250 800, // 10^260 833, // 10^270 867, // 10^280 900, // 10^290 933, // 10^300 ]; const BASE10_SMALL_INT_POWERS: [u64; 10] = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000]; const BASE10_STEP: i32 = 10; const BASE10_BIAS: i32 = 350; cfg_if! { if #[cfg(feature = "radix")] { // BASE3 const BASE3_SMALL_MANTISSA: [u64; 20] = [ 9223372036854775808, // 3^0 13835058055282163712, // 3^1 10376293541461622784, // 3^2 15564440312192434176, // 3^3 11673330234144325632, // 3^4 17509995351216488448, // 3^5 13132496513412366336, // 3^6 9849372385059274752, // 3^7 14774058577588912128, // 3^8 11080543933191684096, // 3^9 16620815899787526144, // 3^10 12465611924840644608, // 3^11 9349208943630483456, // 3^12 14023813415445725184, // 3^13 10517860061584293888, // 3^14 15776790092376440832, // 3^15 11832592569282330624, // 3^16 17748888853923495936, // 3^17 13311666640442621952, // 3^18 9983749980331966464, // 3^19 ]; const BASE3_SMALL_EXPONENT: [i32; 20] = [ -63, // 3^0 -62, // 3^1 -60, // 3^2 -59, // 3^3 -57, // 3^4 -56, // 3^5 -54, // 3^6 -52, // 3^7 -51, // 3^8 -49, // 3^9 -48, // 3^10 -46, // 3^11 -44, // 3^12 -43, // 3^13 -41, // 3^14 -40, // 3^15 -38, // 3^16 -37, // 3^17 -35, // 3^18 -33, // 3^19 ]; const BASE3_LARGE_MANTISSA: [u64; 69] = [ 16362187946641408838, // 3^-720 13283319235448605538, // 3^-700 10783800460320302292, // 3^-680 17509230984627012859, // 3^-660 14214523479040558273, // 3^-640 11539780240125690827, // 3^-620 9368342750761260524, // 3^-600 15211008194170796346, // 3^-580 12348756681875770872, // 3^-560 10025094302862174179, // 3^-540 16277349755993950451, // 3^-520 13214445025385558299, // 3^-500 10727886292707736997, // 3^-480 17418445358572088840, // 3^-460 14140820960965941427, // 3^-440 11479946305982273645, // 3^-420 9319767752666157840, // 3^-400 15132138887857638912, // 3^-380 12284728192712064755, // 3^-360 9973114038089604413, // 3^-340 16192951452641260116, // 3^-320 13145927929137795237, // 3^-300 10672262040895386089, // 3^-280 17328130457353990660, // 3^-260 14067500591556283265, // 3^-240 11420422611687500217, // 3^-220 9271444616666914905, // 3^-200 15053678520084183432, // 3^-180 12221031692227883264, // 3^-160 9921403291771844100, // 3^-140 16108990755761097026, // 3^-120 13077766095064811873, // 3^-100 10616926201665464118, // 3^-80 17238283840257358043, // 3^-60 13994560389365007134, // 3^-40 11361207548643088241, // 3^-20 9223372036854775808, // 3^0 14975624970497949696, // 3^20 12157665459056928801, // 3^40 9869960666451650558, // 3^60 16025465396357318008, // 3^80 13009957681126887596, // 3^100 10561877279594392463, // 3^120 17148903079221976570, // 3^140 13921998383219366688, // 3^160 11302299516591361707, // 3^180 18351097428184282358, // 3^200 14897976129740516999, // 3^220 12094627780758213915, // 3^240 9818784771917617934, // 3^260 15942373117198559022, // 3^280 12942500854835305460, // 3^300 10507113787012386253, // 3^320 17059985758777160561, // 3^340 13849812612167175924, // 3^360 11243696923572004730, // 3^380 18255946711954919292, // 3^400 14820729899390519784, // 3^420 12031916953769783440, // 3^440 9767874225166607426, // 3^460 15859711672757234610, // 3^480 12875393793202830082, // 3^500 10452634243963250834, // 3^520 16971529475976476179, // 3^540 13778001125423815423, // 3^560 11185398185879039609, // 3^580 18161289353620602647, // 3^600 14743884191906938838, // 3^620 11969531283362676572, // 3^640 ]; const BASE3_LARGE_EXPONENT: [i32; 69] = [ -1205, // 3^-720 -1173, // 3^-700 -1141, // 3^-680 -1110, // 3^-660 -1078, // 3^-640 -1046, // 3^-620 -1014, // 3^-600 -983, // 3^-580 -951, // 3^-560 -919, // 3^-540 -888, // 3^-520 -856, // 3^-500 -824, // 3^-480 -793, // 3^-460 -761, // 3^-440 -729, // 3^-420 -697, // 3^-400 -666, // 3^-380 -634, // 3^-360 -602, // 3^-340 -571, // 3^-320 -539, // 3^-300 -507, // 3^-280 -476, // 3^-260 -444, // 3^-240 -412, // 3^-220 -380, // 3^-200 -349, // 3^-180 -317, // 3^-160 -285, // 3^-140 -254, // 3^-120 -222, // 3^-100 -190, // 3^-80 -159, // 3^-60 -127, // 3^-40 -95, // 3^-20 -63, // 3^0 -32, // 3^20 0, // 3^40 32, // 3^60 63, // 3^80 95, // 3^100 127, // 3^120 158, // 3^140 190, // 3^160 222, // 3^180 253, // 3^200 285, // 3^220 317, // 3^240 349, // 3^260 380, // 3^280 412, // 3^300 444, // 3^320 475, // 3^340 507, // 3^360 539, // 3^380 570, // 3^400 602, // 3^420 634, // 3^440 666, // 3^460 697, // 3^480 729, // 3^500 761, // 3^520 792, // 3^540 824, // 3^560 856, // 3^580 887, // 3^600 919, // 3^620 951, // 3^640 ]; const BASE3_SMALL_INT_POWERS: [u64; 20] = [1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721, 129140163, 387420489, 1162261467]; const BASE3_STEP: i32 = 20; const BASE3_BIAS: i32 = 720; // BASE5 const BASE5_SMALL_MANTISSA: [u64; 14] = [ 9223372036854775808, // 5^0 11529215046068469760, // 5^1 14411518807585587200, // 5^2 18014398509481984000, // 5^3 11258999068426240000, // 5^4 14073748835532800000, // 5^5 17592186044416000000, // 5^6 10995116277760000000, // 5^7 13743895347200000000, // 5^8 17179869184000000000, // 5^9 10737418240000000000, // 5^10 13421772800000000000, // 5^11 16777216000000000000, // 5^12 10485760000000000000, // 5^13 ]; const BASE5_SMALL_EXPONENT: [i32; 14] = [ -63, // 5^0 -61, // 5^1 -59, // 5^2 -57, // 5^3 -54, // 5^4 -52, // 5^5 -50, // 5^6 -47, // 5^7 -45, // 5^8 -43, // 5^9 -40, // 5^10 -38, // 5^11 -36, // 5^12 -33, // 5^13 ]; const BASE5_LARGE_MANTISSA: [u64; 68] = [ 15492890949478498119, // 5^-504 11008361120075348168, // 5^-490 15643822052986917253, // 5^-476 11115604119273511155, // 5^-462 15796223521069679172, // 5^-448 11223891875338892399, // 5^-434 15950109677957715915, // 5^-420 11333234566249726012, // 5^-406 16105494987428025427, // 5^-392 11443642469137689536, // 5^-378 16262394054163123565, // 5^-364 11555125961253852697, // 5^-350 16420821625123739831, // 5^-336 11667695520944036383, // 5^-322 16580792590934885855, // 5^-308 11781361728633673532, // 5^-294 16742321987285426889, // 5^-280 11896135267822264502, // 5^-266 16905424996341287883, // 5^-252 12012026926087520367, // 5^-238 17070116948172426941, // 5^-224 12129047596099288555, // 5^-210 17236413322193710308, // 5^-196 12247208276643356092, // 5^-182 17404329748619824289, // 5^-168 12366520073655226703, // 5^-154 17573882009934360870, // 5^-140 12486994201263968925, // 5^-126 17745086042373215101, // 5^-112 12608641982846233347, // 5^-98 17917957937422433684, // 5^-84 12731474852090538039, // 5^-70 18092513943330655534, // 5^-56 12855504354071922204, // 5^-42 18268770466636286477, // 5^-28 12980742146337069071, // 5^-14 9223372036854775808, // 5^0 13107200000000000000, // 5^14 9313225746154785156, // 5^28 13234889800848442797, // 5^42 9403954806578300063, // 5^56 13363823550460978230, // 5^70 9495567745759798747, // 5^84 13494013367335069727, // 5^98 9588073174409622174, // 5^112 13625471488026082303, // 5^126 9681479787123295682, // 5^140 13758210268297397763, // 5^154 9775796363198734982, // 5^168 13892242184281734271, // 5^182 9871031767461413346, // 5^196 14027579833653779454, // 5^210 9967194951097567535, // 5^224 14164235936814247246, // 5^238 10064294952495520794, // 5^252 14302223338085469768, // 5^266 10162340898095201970, // 5^280 14441555006918636608, // 5^294 10261342003245940623, // 5^308 14582244039112794984, // 5^322 10361307573072618726, // 5^336 14724303658045725350, // 5^350 10462247003350260393, // 5^364 14867747215916808149, // 5^378 10564169781387141817, // 5^392 15012588195001998509, // 5^406 10667085486916504429, // 5^420 15158840208921026870, // 5^434 ]; const BASE5_LARGE_EXPONENT: [i32; 68] = [ -1234, // 5^-504 -1201, // 5^-490 -1169, // 5^-476 -1136, // 5^-462 -1104, // 5^-448 -1071, // 5^-434 -1039, // 5^-420 -1006, // 5^-406 -974, // 5^-392 -941, // 5^-378 -909, // 5^-364 -876, // 5^-350 -844, // 5^-336 -811, // 5^-322 -779, // 5^-308 -746, // 5^-294 -714, // 5^-280 -681, // 5^-266 -649, // 5^-252 -616, // 5^-238 -584, // 5^-224 -551, // 5^-210 -519, // 5^-196 -486, // 5^-182 -454, // 5^-168 -421, // 5^-154 -389, // 5^-140 -356, // 5^-126 -324, // 5^-112 -291, // 5^-98 -259, // 5^-84 -226, // 5^-70 -194, // 5^-56 -161, // 5^-42 -129, // 5^-28 -96, // 5^-14 -63, // 5^0 -31, // 5^14 2, // 5^28 34, // 5^42 67, // 5^56 99, // 5^70 132, // 5^84 164, // 5^98 197, // 5^112 229, // 5^126 262, // 5^140 294, // 5^154 327, // 5^168 359, // 5^182 392, // 5^196 424, // 5^210 457, // 5^224 489, // 5^238 522, // 5^252 554, // 5^266 587, // 5^280 619, // 5^294 652, // 5^308 684, // 5^322 717, // 5^336 749, // 5^350 782, // 5^364 814, // 5^378 847, // 5^392 879, // 5^406 912, // 5^420 944, // 5^434 ]; const BASE5_SMALL_INT_POWERS: [u64; 14] = [1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125]; const BASE5_STEP: i32 = 14; const BASE5_BIAS: i32 = 504; // BASE6 const BASE6_SMALL_MANTISSA: [u64; 12] = [ 9223372036854775808, // 6^0 13835058055282163712, // 6^1 10376293541461622784, // 6^2 15564440312192434176, // 6^3 11673330234144325632, // 6^4 17509995351216488448, // 6^5 13132496513412366336, // 6^6 9849372385059274752, // 6^7 14774058577588912128, // 6^8 11080543933191684096, // 6^9 16620815899787526144, // 6^10 12465611924840644608, // 6^11 ]; const BASE6_SMALL_EXPONENT: [i32; 12] = [ -63, // 6^0 -61, // 6^1 -58, // 6^2 -56, // 6^3 -53, // 6^4 -51, // 6^5 -48, // 6^6 -45, // 6^7 -43, // 6^8 -40, // 6^9 -38, // 6^10 -35, // 6^11 ]; const BASE6_LARGE_MANTISSA: [u64; 71] = [ 11172994339528645078, // 6^-444 11325430459582219446, // 6^-432 11479946305982273645, // 6^-420 11636570252986002899, // 6^-408 11795331061968106016, // 6^-396 11956257886702331980, // 6^-384 12119380278715084095, // 6^-372 12284728192712064755, // 6^-360 12452331992078957377, // 6^-348 12622222454457155586, // 6^-336 12794430777395563548, // 6^-324 12968988584079505325, // 6^-312 13145927929137795237, // 6^-300 13325281304529035642, // 6^-288 13507081645508223020, // 6^-276 13691362336674758052, // 6^-264 13878157218102970303, // 6^-252 14067500591556283265, // 6^-240 14259427226786160917, // 6^-228 14453972367916992462, // 6^-216 14651171739918087751, // 6^-204 14851061555163971849, // 6^-192 15053678520084183432, // 6^-180 15259059841903798156, // 6^-168 15467243235475914756, // 6^-156 15678266930207358578, // 6^-144 15892169677078874302, // 6^-132 16108990755761097026, // 6^-120 16328769981827608423, // 6^-108 16551547714066402526, // 6^-96 16777364861891103792, // 6^-84 17006262892853298360, // 6^-72 17238283840257358043, // 6^-60 17473470310879155380, // 6^-48 17711865492790087155, // 6^-36 17953513163287843146, // 6^-24 18198457696935376453, // 6^-12 9223372036854775808, // 6^0 9349208943630483456, // 6^12 9476762676643233792, // 6^24 9606056659007943744, // 6^36 9737114633407288801, // 6^48 9869960666451650558, // 6^60 10004619153098548172, // 6^72 10141114821132365302, // 6^84 10279472735705195138, // 6^96 10419718303939637392, // 6^108 10561877279594392463, // 6^120 10705975767793509530, // 6^132 10852040229820157048, // 6^144 11000097487975795902, // 6^156 11150174730505647564, // 6^168 11302299516591361707, // 6^180 11456499781411800112, // 6^192 11612803841272866179, // 6^204 11771240398807322073, // 6^216 11931838548245548344, // 6^228 12094627780758213915, // 6^240 12259637989871837542, // 6^252 12426899476958235198, // 6^264 12596442956798861450, // 6^276 12768299563225066619, // 6^288 12942500854835305460, // 6^300 13119078820790347231, // 6^312 13298065886687551351, // 6^324 13479494920515287357, // 6^336 13663399238688592583, // 6^348 13849812612167175924, // 6^360 14038769272656891137, // 6^372 14230303918895818486, // 6^384 14424451723026109070, // 6^396 ]; const BASE6_LARGE_EXPONENT: [i32; 71] = [ -1211, // 6^-444 -1180, // 6^-432 -1149, // 6^-420 -1118, // 6^-408 -1087, // 6^-396 -1056, // 6^-384 -1025, // 6^-372 -994, // 6^-360 -963, // 6^-348 -932, // 6^-336 -901, // 6^-324 -870, // 6^-312 -839, // 6^-300 -808, // 6^-288 -777, // 6^-276 -746, // 6^-264 -715, // 6^-252 -684, // 6^-240 -653, // 6^-228 -622, // 6^-216 -591, // 6^-204 -560, // 6^-192 -529, // 6^-180 -498, // 6^-168 -467, // 6^-156 -436, // 6^-144 -405, // 6^-132 -374, // 6^-120 -343, // 6^-108 -312, // 6^-96 -281, // 6^-84 -250, // 6^-72 -219, // 6^-60 -188, // 6^-48 -157, // 6^-36 -126, // 6^-24 -95, // 6^-12 -63, // 6^0 -32, // 6^12 -1, // 6^24 30, // 6^36 61, // 6^48 92, // 6^60 123, // 6^72 154, // 6^84 185, // 6^96 216, // 6^108 247, // 6^120 278, // 6^132 309, // 6^144 340, // 6^156 371, // 6^168 402, // 6^180 433, // 6^192 464, // 6^204 495, // 6^216 526, // 6^228 557, // 6^240 588, // 6^252 619, // 6^264 650, // 6^276 681, // 6^288 712, // 6^300 743, // 6^312 774, // 6^324 805, // 6^336 836, // 6^348 867, // 6^360 898, // 6^372 929, // 6^384 960, // 6^396 ]; const BASE6_SMALL_INT_POWERS: [u64; 12] = [1, 6, 36, 216, 1296, 7776, 46656, 279936, 1679616, 10077696, 60466176, 362797056]; const BASE6_STEP: i32 = 12; const BASE6_BIAS: i32 = 444; // BASE7 const BASE7_SMALL_MANTISSA: [u64; 11] = [ 9223372036854775808, // 7^0 16140901064495857664, // 7^1 14123288431433875456, // 7^2 12357877377504641024, // 7^3 10813142705316560896, // 7^4 9461499867151990784, // 7^5 16557624767515983872, // 7^6 14487921671576485888, // 7^7 12676931462629425152, // 7^8 11092315029800747008, // 7^9 9705775651075653632, // 7^10 ]; const BASE7_SMALL_EXPONENT: [i32; 11] = [ -63, // 7^0 -61, // 7^1 -58, // 7^2 -55, // 7^3 -52, // 7^4 -49, // 7^5 -47, // 7^6 -44, // 7^7 -41, // 7^8 -38, // 7^9 -35, // 7^10 ]; const BASE7_LARGE_MANTISSA: [u64; 71] = [ 12225664820028455743, // 7^-407 11256958357801915874, // 7^-396 10365007820408367996, // 7^-385 9543731415037814164, // 7^-374 17575058485347314089, // 7^-363 16182490230010039076, // 7^-352 14900262793588950961, // 7^-341 13719633267955538670, // 7^-330 12632551493533408059, // 7^-319 11631605169031861852, // 7^-308 10709969310436274791, // 7^-297 9861359714639799269, // 7^-286 18159980220813419398, // 7^-275 16721065408999761282, // 7^-264 15396163707909854531, // 7^-253 14176241233598532153, // 7^-242 13052979906282242272, // 7^-231 12018720733250263776, // 7^-220 11066411585781870352, // 7^-209 10189559113984709052, // 7^-198 9382184471684205580, // 7^-187 17277565098945522629, // 7^-176 15908568875896010079, // 7^-165 14648045730389016129, // 7^-154 13487400745686688174, // 7^-143 12418720027433908743, // 7^-132 11434716742520575143, // 7^-121 10528681433580712628, // 7^-110 9694436270346269630, // 7^-99 17852585851834022264, // 7^-88 16438027581449061548, // 7^-77 15135552519453149331, // 7^-66 13936279698645574929, // 7^-55 12832031839555071753, // 7^-44 11815279593402393441, // 7^-33 10879090202998704701, // 7^-22 10017080231522506848, // 7^-11 9223372036854775808, // 7^0 16985107389382393856, // 7^11 15639284194331952196, // 7^22 14400097950748064600, // 7^33 13259099228230139701, // 7^44 12208508091080056405, // 7^55 11241161050565762112, // 7^66 10350462220447909415, // 7^77 9530338342721952463, // 7^88 17550394753834620135, // 7^99 16159780741186857313, // 7^110 14879352702091044991, // 7^121 13700379997665963732, // 7^132 12614823765422770599, // 7^143 11615282106028126090, // 7^154 10694939613220642893, // 7^165 9847520902748803399, // 7^176 18134495646931893353, // 7^187 16697600117649658875, // 7^198 15374557700263623520, // 7^209 14156347188413069088, // 7^220 13034662175384360011, // 7^231 12001854416615353596, // 7^242 11050881679899153397, // 7^253 10175259727702178785, // 7^264 9369018104186475301, // 7^275 17253318850937371954, // 7^286 15886243791070066478, // 7^297 14627489584451796037, // 7^308 13468473375910191470, // 7^319 12401292376951646786, // 7^330 11418669980349265042, // 7^341 10513906144367477972, // 7^352 9680831708316613461, // 7^363 ]; const BASE7_LARGE_EXPONENT: [i32; 71] = [ -1206, // 7^-407 -1175, // 7^-396 -1144, // 7^-385 -1113, // 7^-374 -1083, // 7^-363 -1052, // 7^-352 -1021, // 7^-341 -990, // 7^-330 -959, // 7^-319 -928, // 7^-308 -897, // 7^-297 -866, // 7^-286 -836, // 7^-275 -805, // 7^-264 -774, // 7^-253 -743, // 7^-242 -712, // 7^-231 -681, // 7^-220 -650, // 7^-209 -619, // 7^-198 -588, // 7^-187 -558, // 7^-176 -527, // 7^-165 -496, // 7^-154 -465, // 7^-143 -434, // 7^-132 -403, // 7^-121 -372, // 7^-110 -341, // 7^-99 -311, // 7^-88 -280, // 7^-77 -249, // 7^-66 -218, // 7^-55 -187, // 7^-44 -156, // 7^-33 -125, // 7^-22 -94, // 7^-11 -63, // 7^0 -33, // 7^11 -2, // 7^22 29, // 7^33 60, // 7^44 91, // 7^55 122, // 7^66 153, // 7^77 184, // 7^88 214, // 7^99 245, // 7^110 276, // 7^121 307, // 7^132 338, // 7^143 369, // 7^154 400, // 7^165 431, // 7^176 461, // 7^187 492, // 7^198 523, // 7^209 554, // 7^220 585, // 7^231 616, // 7^242 647, // 7^253 678, // 7^264 709, // 7^275 739, // 7^286 770, // 7^297 801, // 7^308 832, // 7^319 863, // 7^330 894, // 7^341 925, // 7^352 956, // 7^363 ]; const BASE7_SMALL_INT_POWERS: [u64; 11] = [1, 7, 49, 343, 2401, 16807, 117649, 823543, 5764801, 40353607, 282475249]; const BASE7_STEP: i32 = 11; const BASE7_BIAS: i32 = 407; // BASE9 const BASE9_SMALL_MANTISSA: [u64; 10] = [ 9223372036854775808, // 9^0 10376293541461622784, // 9^1 11673330234144325632, // 9^2 13132496513412366336, // 9^3 14774058577588912128, // 9^4 16620815899787526144, // 9^5 9349208943630483456, // 9^6 10517860061584293888, // 9^7 11832592569282330624, // 9^8 13311666640442621952, // 9^9 ]; const BASE9_SMALL_EXPONENT: [i32; 10] = [ -63, // 9^0 -60, // 9^1 -57, // 9^2 -54, // 9^3 -51, // 9^4 -48, // 9^5 -44, // 9^6 -41, // 9^7 -38, // 9^8 -35, // 9^9 ]; const BASE9_LARGE_MANTISSA: [u64; 69] = [ 16362187946641408838, // 9^-360 13283319235448605538, // 9^-350 10783800460320302292, // 9^-340 17509230984627012859, // 9^-330 14214523479040558273, // 9^-320 11539780240125690827, // 9^-310 9368342750761260524, // 9^-300 15211008194170796346, // 9^-290 12348756681875770872, // 9^-280 10025094302862174179, // 9^-270 16277349755993950451, // 9^-260 13214445025385558299, // 9^-250 10727886292707736997, // 9^-240 17418445358572088840, // 9^-230 14140820960965941427, // 9^-220 11479946305982273645, // 9^-210 9319767752666157840, // 9^-200 15132138887857638912, // 9^-190 12284728192712064755, // 9^-180 9973114038089604413, // 9^-170 16192951452641260116, // 9^-160 13145927929137795237, // 9^-150 10672262040895386089, // 9^-140 17328130457353990660, // 9^-130 14067500591556283265, // 9^-120 11420422611687500217, // 9^-110 9271444616666914905, // 9^-100 15053678520084183432, // 9^-90 12221031692227883264, // 9^-80 9921403291771844100, // 9^-70 16108990755761097026, // 9^-60 13077766095064811873, // 9^-50 10616926201665464118, // 9^-40 17238283840257358043, // 9^-30 13994560389365007134, // 9^-20 11361207548643088241, // 9^-10 9223372036854775808, // 9^0 14975624970497949696, // 9^10 12157665459056928801, // 9^20 9869960666451650558, // 9^30 16025465396357318008, // 9^40 13009957681126887596, // 9^50 10561877279594392463, // 9^60 17148903079221976570, // 9^70 13921998383219366688, // 9^80 11302299516591361707, // 9^90 18351097428184282358, // 9^100 14897976129740516999, // 9^110 12094627780758213915, // 9^120 9818784771917617934, // 9^130 15942373117198559022, // 9^140 12942500854835305460, // 9^150 10507113787012386253, // 9^160 17059985758777160561, // 9^170 13849812612167175924, // 9^180 11243696923572004730, // 9^190 18255946711954919292, // 9^200 14820729899390519784, // 9^210 12031916953769783440, // 9^220 9767874225166607426, // 9^230 15859711672757234610, // 9^240 12875393793202830082, // 9^250 10452634243963250834, // 9^260 16971529475976476179, // 9^270 13778001125423815423, // 9^280 11185398185879039609, // 9^290 18161289353620602647, // 9^300 14743884191906938838, // 9^310 11969531283362676572, // 9^320 ]; const BASE9_LARGE_EXPONENT: [i32; 69] = [ -1205, // 9^-360 -1173, // 9^-350 -1141, // 9^-340 -1110, // 9^-330 -1078, // 9^-320 -1046, // 9^-310 -1014, // 9^-300 -983, // 9^-290 -951, // 9^-280 -919, // 9^-270 -888, // 9^-260 -856, // 9^-250 -824, // 9^-240 -793, // 9^-230 -761, // 9^-220 -729, // 9^-210 -697, // 9^-200 -666, // 9^-190 -634, // 9^-180 -602, // 9^-170 -571, // 9^-160 -539, // 9^-150 -507, // 9^-140 -476, // 9^-130 -444, // 9^-120 -412, // 9^-110 -380, // 9^-100 -349, // 9^-90 -317, // 9^-80 -285, // 9^-70 -254, // 9^-60 -222, // 9^-50 -190, // 9^-40 -159, // 9^-30 -127, // 9^-20 -95, // 9^-10 -63, // 9^0 -32, // 9^10 0, // 9^20 32, // 9^30 63, // 9^40 95, // 9^50 127, // 9^60 158, // 9^70 190, // 9^80 222, // 9^90 253, // 9^100 285, // 9^110 317, // 9^120 349, // 9^130 380, // 9^140 412, // 9^150 444, // 9^160 475, // 9^170 507, // 9^180 539, // 9^190 570, // 9^200 602, // 9^210 634, // 9^220 666, // 9^230 697, // 9^240 729, // 9^250 761, // 9^260 792, // 9^270 824, // 9^280 856, // 9^290 887, // 9^300 919, // 9^310 951, // 9^320 ]; const BASE9_SMALL_INT_POWERS: [u64; 10] = [1, 9, 81, 729, 6561, 59049, 531441, 4782969, 43046721, 387420489]; const BASE9_STEP: i32 = 10; const BASE9_BIAS: i32 = 360; // BASE11 const BASE11_SMALL_MANTISSA: [u64; 9] = [ 9223372036854775808, // 11^0 12682136550675316736, // 11^1 17437937757178560512, // 11^2 11988582208060260352, // 11^3 16484300536082857984, // 11^4 11332956618556964864, // 11^5 15582815350515826688, // 11^6 10713185553479630848, // 11^7 14730630136034492416, // 11^8 ]; const BASE11_SMALL_EXPONENT: [i32; 9] = [ -63, // 11^0 -60, // 11^1 -57, // 11^2 -53, // 11^3 -50, // 11^4 -46, // 11^5 -43, // 11^6 -39, // 11^7 -36, // 11^8 ]; const BASE11_LARGE_MANTISSA: [u64; 70] = [ 9282833781626869722, // 11^-333 10192597509046958613, // 11^-324 11191522591630754840, // 11^-315 12288347284174558846, // 11^-306 13492666233761944748, // 11^-297 14815014410453217040, // 11^-288 16266959263598494876, // 11^-279 17861201909926315464, // 11^-270 9805844119283264859, // 11^-261 10766865452458105492, // 11^-252 11822071640254585128, // 11^-243 12980693265318349774, // 11^-234 14252865553152120313, // 11^-225 15649717031600177225, // 11^-216 17183466879401827195, // 11^-207 9433765907692842627, // 11^-198 10358321731667433590, // 11^-189 11373488609595385666, // 11^-180 12488146873940825498, // 11^-171 13712047173770907127, // 11^-162 15055895770097238115, // 11^-153 16531448190583591098, // 11^-144 18151612062879235750, // 11^-135 9965280013064351107, // 11^-126 10941926854184612877, // 11^-117 12014289927163860584, // 11^-108 13191749897208336388, // 11^-99 14484606781216284322, // 11^-90 15904170048801172427, // 11^-81 17462857553661839031, // 11^-72 9587152080358667750, // 11^-63 10526740509619734750, // 11^-54 11558413262671798860, // 11^-45 12691195059726361470, // 11^-36 13934995088312952370, // 11^-27 15300693685460773821, // 11^-18 16800237515163846269, // 11^-9 9223372036854775808, // 11^0 10127308218523713536, // 11^9 11119834626984462962, // 11^18 12209633543621683835, // 11^27 13406238156435497652, // 11^36 14720115953107913248, // 11^45 16162760287003157808, // 11^54 17746790917089950882, // 11^63 9743032200637278641, // 11^72 10697897654413860244, // 11^81 11746344656115154606, // 11^90 12897544661339799796, // 11^99 14161567973799797658, // 11^108 15549471836891389165, // 11^117 17073397158676562691, // 11^126 9373337358196117359, // 11^135 10291970884763903381, // 11^144 11300635050781198339, // 11^153 12408153305213523269, // 11^162 13624213838764580644, // 11^171 14959454332853289890, // 11^180 16425555014410689631, // 11^189 18035340830508227153, // 11^198 9901446818303059920, // 11^207 10871837689903097542, // 11^216 11937331677337075986, // 11^225 13107249357401447067, // 11^234 14391824769622635037, // 11^243 15802294940132787091, // 11^252 17350998179329134782, // 11^261 9525741006595626773, // 11^270 10459310846201225147, // 11^279 11484375157976259923, // 11^288 ]; const BASE11_LARGE_EXPONENT: [i32; 70] = [ -1215, // 11^-333 -1184, // 11^-324 -1153, // 11^-315 -1122, // 11^-306 -1091, // 11^-297 -1060, // 11^-288 -1029, // 11^-279 -998, // 11^-270 -966, // 11^-261 -935, // 11^-252 -904, // 11^-243 -873, // 11^-234 -842, // 11^-225 -811, // 11^-216 -780, // 11^-207 -748, // 11^-198 -717, // 11^-189 -686, // 11^-180 -655, // 11^-171 -624, // 11^-162 -593, // 11^-153 -562, // 11^-144 -531, // 11^-135 -499, // 11^-126 -468, // 11^-117 -437, // 11^-108 -406, // 11^-99 -375, // 11^-90 -344, // 11^-81 -313, // 11^-72 -281, // 11^-63 -250, // 11^-54 -219, // 11^-45 -188, // 11^-36 -157, // 11^-27 -126, // 11^-18 -95, // 11^-9 -63, // 11^0 -32, // 11^9 -1, // 11^18 30, // 11^27 61, // 11^36 92, // 11^45 123, // 11^54 154, // 11^63 186, // 11^72 217, // 11^81 248, // 11^90 279, // 11^99 310, // 11^108 341, // 11^117 372, // 11^126 404, // 11^135 435, // 11^144 466, // 11^153 497, // 11^162 528, // 11^171 559, // 11^180 590, // 11^189 621, // 11^198 653, // 11^207 684, // 11^216 715, // 11^225 746, // 11^234 777, // 11^243 808, // 11^252 839, // 11^261 871, // 11^270 902, // 11^279 933, // 11^288 ]; const BASE11_SMALL_INT_POWERS: [u64; 9] = [1, 11, 121, 1331, 14641, 161051, 1771561, 19487171, 214358881]; const BASE11_STEP: i32 = 9; const BASE11_BIAS: i32 = 333; // BASE12 const BASE12_SMALL_MANTISSA: [u64; 9] = [ 9223372036854775808, // 12^0 13835058055282163712, // 12^1 10376293541461622784, // 12^2 15564440312192434176, // 12^3 11673330234144325632, // 12^4 17509995351216488448, // 12^5 13132496513412366336, // 12^6 9849372385059274752, // 12^7 14774058577588912128, // 12^8 ]; const BASE12_SMALL_EXPONENT: [i32; 9] = [ -63, // 12^0 -60, // 12^1 -56, // 12^2 -53, // 12^3 -49, // 12^4 -46, // 12^5 -42, // 12^6 -38, // 12^7 -35, // 12^8 ]; const BASE12_LARGE_MANTISSA: [u64; 68] = [ 12794430777395563548, // 12^-324 15370653136686821126, // 12^-315 9232805349408163458, // 12^-306 11091876690210014731, // 12^-297 13325281304529035642, // 12^-288 16008393061343079134, // 12^-279 9615881366772943927, // 12^-270 11552086971569327107, // 12^-261 13878157218102970303, // 12^-252 16672593293696335722, // 12^-243 10014851495355986817, // 12^-234 12031391722600823274, // 12^-225 14453972367916992462, // 12^-216 17364351691754770668, // 12^-207 10430375193750279268, // 12^-198 12530583187169601247, // 12^-189 15053678520084183432, // 12^-180 18084811664478575592, // 12^-171 10863139281980340679, // 12^-162 13050486479932803075, // 12^-153 15678266930207358578, // 12^-144 9417582030861555141, // 12^-135 11313859076748534537, // 12^-126 13591960950173425616, // 12^-117 16328769981827608423, // 12^-108 9808324571298608904, // 12^-99 11783279573783601017, // 12^-90 14155901602220618825, // 12^-81 17006262892853298360, // 12^-72 10215279312745101062, // 12^-63 12272176679245716810, // 12^-54 14743240574804287352, // 12^-45 17711865492790087155, // 12^-36 10639118911577981124, // 12^-27 12781358492223474271, // 12^-18 15354948681789223882, // 12^-9 9223372036854775808, // 12^0 11080543933191684096, // 12^9 13311666640442621952, // 12^18 15992037016835457024, // 12^27 9606056659007943744, // 12^36 11540284009964194135, // 12^45 13863977671394362375, // 12^54 16655558624637160317, // 12^63 10004619153098548172, // 12^72 12019099047267988506, // 12^81 14439204501182606065, // 12^90 17346610241502516795, // 12^99 10419718303939637392, // 12^108 12517780479519279956, // 12^117 15038297923484984581, // 12^126 18066334108151547333, // 12^135 10852040229820157048, // 12^144 13037152578341684032, // 12^153 15662248181121787524, // 12^162 9407959928864140132, // 12^171 11302299516591361707, // 12^180 13578073815006577911, // 12^189 16312086602830473207, // 12^198 9798303241073980839, // 12^207 11771240398807322073, // 12^216 14141438279402131370, // 12^225 16988887307951181138, // 12^234 10204842190014742991, // 12^243 12259637989871837542, // 12^252 14728177157876426901, // 12^261 17693768981840924725, // 12^270 10628248744799039348, // 12^279 ]; const BASE12_LARGE_EXPONENT: [i32; 68] = [ -1225, // 12^-324 -1193, // 12^-315 -1160, // 12^-306 -1128, // 12^-297 -1096, // 12^-288 -1064, // 12^-279 -1031, // 12^-270 -999, // 12^-261 -967, // 12^-252 -935, // 12^-243 -902, // 12^-234 -870, // 12^-225 -838, // 12^-216 -806, // 12^-207 -773, // 12^-198 -741, // 12^-189 -709, // 12^-180 -677, // 12^-171 -644, // 12^-162 -612, // 12^-153 -580, // 12^-144 -547, // 12^-135 -515, // 12^-126 -483, // 12^-117 -451, // 12^-108 -418, // 12^-99 -386, // 12^-90 -354, // 12^-81 -322, // 12^-72 -289, // 12^-63 -257, // 12^-54 -225, // 12^-45 -193, // 12^-36 -160, // 12^-27 -128, // 12^-18 -96, // 12^-9 -63, // 12^0 -31, // 12^9 1, // 12^18 33, // 12^27 66, // 12^36 98, // 12^45 130, // 12^54 162, // 12^63 195, // 12^72 227, // 12^81 259, // 12^90 291, // 12^99 324, // 12^108 356, // 12^117 388, // 12^126 420, // 12^135 453, // 12^144 485, // 12^153 517, // 12^162 550, // 12^171 582, // 12^180 614, // 12^189 646, // 12^198 679, // 12^207 711, // 12^216 743, // 12^225 775, // 12^234 808, // 12^243 840, // 12^252 872, // 12^261 904, // 12^270 937, // 12^279 ]; const BASE12_SMALL_INT_POWERS: [u64; 9] = [1, 12, 144, 1728, 20736, 248832, 2985984, 35831808, 429981696]; const BASE12_STEP: i32 = 9; const BASE12_BIAS: i32 = 324; // BASE13 const BASE13_SMALL_MANTISSA: [u64; 8] = [ 9223372036854775808, // 13^0 14987979559889010688, // 13^1 12177733392409821184, // 13^2 9894408381332979712, // 13^3 16078413619666092032, // 13^4 13063711065978699776, // 13^5 10614265241107693568, // 13^6 17248181016800002048, // 13^7 ]; const BASE13_SMALL_EXPONENT: [i32; 8] = [ -63, // 13^0 -60, // 13^1 -56, // 13^2 -52, // 13^3 -49, // 13^4 -45, // 13^5 -41, // 13^6 -38, // 13^7 ]; const BASE13_LARGE_MANTISSA: [u64; 74] = [ 12711851154623003921, // 13^-312 9657300550123029827, // 13^-304 14673465379822171777, // 13^-296 11147555423761605318, // 13^-288 16937783776246970219, // 13^-280 12867777209673117558, // 13^-272 9775758889423702247, // 13^-264 14853452979012869128, // 13^-256 11284293521111612769, // 13^-248 17145545948207386966, // 13^-240 13025615884242430727, // 13^-232 9895670261906581517, // 13^-224 15035648341334079534, // 13^-216 11422708874734959378, // 13^-208 17355856571645749915, // 13^-200 13185390638896427802, // 13^-192 10017052490761162429, // 13^-184 15220078547640608376, // 13^-176 11562822058185475244, // 13^-168 17568746906366835671, // 13^-160 13347125221972482607, // 13^-152 10139923617799671626, // 13^-144 15406771010966328102, // 13^-136 11704653897376229735, // 13^-128 17784248595614306423, // 13^-120 13510843673109724761, // 13^-112 10264301906138736839, // 13^-104 15595753480598751694, // 13^-96 11848225473675019323, // 13^-88 18002393670774046392, // 13^-80 13676570326822204041, // 13^-72 10390205842913949994, // 13^-64 15787054046203585657, // 13^-56 11993558127037825287, // 13^-48 18223214556135190308, // 13^-40 13844329816115883890, // 13^-32 10517654142027727687, // 13^-24 15980701141999875583, // 13^-16 12140673459180707010, // 13^-8 9223372036854775808, // 13^0 14014147076150001664, // 13^8 10646665746930877456, // 13^16 16176723550986364864, // 13^24 12289593336790602348, // 13^32 9336507724055083356, // 13^40 14186047347943339851, // 13^48 10777259833438283283, // 13^56 16375150409219694755, // 13^64 12440339894775512302, // 13^72 9451031155744840189, // 13^80 14360056182125959135, // 13^88 10909455812579128852, // 13^96 16576011210145081669, // 13^104 12592935539554553092, // 13^112 9566959354269653198, // 13^120 14536199442736950948, // 13^128 11043273333482082198, // 13^136 16779335808980115413, // 13^144 12747402952388364654, // 13^152 9684309550774553205, // 13^160 14714503311068774005, // 13^168 11178732286295870598, // 13^176 16985154427152329948, // 13^184 12903765092750370582, // 13^192 9803099187765169579, // 13^200 14894994289558746218, // 13^208 11315852805145679810, // 13^216 17193497656791206265, // 13^224 13062045201739390598, // 13^232 9923345921700320715, // 13^240 15077699205728270417, // 13^248 11454655271125817073, // 13^256 17404396465275275042, // 13^264 13222266805534112801, // 13^272 ]; const BASE13_LARGE_EXPONENT: [i32; 74] = [ -1218, // 13^-312 -1188, // 13^-304 -1159, // 13^-296 -1129, // 13^-288 -1100, // 13^-280 -1070, // 13^-272 -1040, // 13^-264 -1011, // 13^-256 -981, // 13^-248 -952, // 13^-240 -922, // 13^-232 -892, // 13^-224 -863, // 13^-216 -833, // 13^-208 -804, // 13^-200 -774, // 13^-192 -744, // 13^-184 -715, // 13^-176 -685, // 13^-168 -656, // 13^-160 -626, // 13^-152 -596, // 13^-144 -567, // 13^-136 -537, // 13^-128 -508, // 13^-120 -478, // 13^-112 -448, // 13^-104 -419, // 13^-96 -389, // 13^-88 -360, // 13^-80 -330, // 13^-72 -300, // 13^-64 -271, // 13^-56 -241, // 13^-48 -212, // 13^-40 -182, // 13^-32 -152, // 13^-24 -123, // 13^-16 -93, // 13^-8 -63, // 13^0 -34, // 13^8 -4, // 13^16 25, // 13^24 55, // 13^32 85, // 13^40 114, // 13^48 144, // 13^56 173, // 13^64 203, // 13^72 233, // 13^80 262, // 13^88 292, // 13^96 321, // 13^104 351, // 13^112 381, // 13^120 410, // 13^128 440, // 13^136 469, // 13^144 499, // 13^152 529, // 13^160 558, // 13^168 588, // 13^176 617, // 13^184 647, // 13^192 677, // 13^200 706, // 13^208 736, // 13^216 765, // 13^224 795, // 13^232 825, // 13^240 854, // 13^248 884, // 13^256 913, // 13^264 943, // 13^272 ]; const BASE13_SMALL_INT_POWERS: [u64; 8] = [1, 13, 169, 2197, 28561, 371293, 4826809, 62748517]; const BASE13_STEP: i32 = 8; const BASE13_BIAS: i32 = 312; // BASE14 const BASE14_SMALL_MANTISSA: [u64; 8] = [ 9223372036854775808, // 14^0 16140901064495857664, // 14^1 14123288431433875456, // 14^2 12357877377504641024, // 14^3 10813142705316560896, // 14^4 9461499867151990784, // 14^5 16557624767515983872, // 14^6 14487921671576485888, // 14^7 ]; const BASE14_SMALL_EXPONENT: [i32; 8] = [ -63, // 14^0 -60, // 14^1 -56, // 14^2 -52, // 14^3 -48, // 14^4 -44, // 14^5 -41, // 14^6 -37, // 14^7 ]; const BASE14_LARGE_MANTISSA: [u64; 72] = [ 13636466802170654447, // 14^-304 9371223146631740442, // 14^-296 12880143300754023535, // 14^-288 17702928299982570560, // 14^-280 12165767999490239948, // 14^-272 16721065408999761282, // 14^-264 11491014312609104256, // 14^-256 15793659877858943182, // 14^-248 10853684694473876180, // 14^-240 14917691321465419740, // 14^-232 10251703482589146278, // 14^-224 14090306875260685218, // 14^-216 9683110137559136558, // 14^-208 13308811903980028150, // 14^-200 18292105715960495534, // 14^-192 12570661225733134820, // 14^-184 17277565098945522629, // 14^-176 11873450822826176619, // 14^-168 16319294256419936609, // 14^-160 11214910012329090474, // 14^-152 15414172280784786485, // 14^-144 10592894050889065017, // 14^-136 14559251360287507272, // 14^-128 10005377149705503250, // 14^-120 13751747178554400168, // 14^-112 9450445876917551117, // 14^-104 12989029846596759700, // 14^-96 17852585851834022264, // 14^-88 12268615337757900164, // 14^-80 16862422458582420498, // 14^-72 11588157397706317457, // 14^-64 15927176798452085633, // 14^-56 10945439903127358164, // 14^-48 15043802952525257461, // 14^-40 10338369644227094261, // 14^-32 14209423938610553080, // 14^-24 9764969507542378307, // 14^-16 13421322341453983785, // 14^-8 9223372036854775808, // 14^0 12676931462629425152, // 14^8 17423626702474969088, // 14^16 11973826961285400900, // 14^24 16457254800854930971, // 14^32 11309718958523667683, // 14^40 15544481077627229210, // 14^48 10682444579695049354, // 14^56 14682332800738954595, // 14^64 10089960910324183248, // 14^72 13868002115678253630, // 14^80 9530338342721952463, // 14^88 13098836900821174211, // 14^96 18003508583233548621, // 14^104 12372332129971187630, // 14^112 17004974516675479989, // 14^120 11686121713960805382, // 14^128 16061822448435536582, // 14^136 11037970794744924274, // 14^144 15170980709914287138, // 14^152 10425768466889213611, // 14^160 14329547997401095751, // 14^168 9847520902748803399, // 14^176 13534783923074532648, // 14^184 9301344858947275744, // 14^192 12784100090075520076, // 14^200 17570923086015569737, // 14^208 12075051662586407952, // 14^216 16596381640322157656, // 14^224 11405329403461315009, // 14^232 15675891482926176126, // 14^240 10772752153475797540, // 14^248 14806454750802381310, // 14^256 10175259727702178785, // 14^264 ]; const BASE14_LARGE_EXPONENT: [i32; 72] = [ -1221, // 14^-304 -1190, // 14^-296 -1160, // 14^-288 -1130, // 14^-280 -1099, // 14^-272 -1069, // 14^-264 -1038, // 14^-256 -1008, // 14^-248 -977, // 14^-240 -947, // 14^-232 -916, // 14^-224 -886, // 14^-216 -855, // 14^-208 -825, // 14^-200 -795, // 14^-192 -764, // 14^-184 -734, // 14^-176 -703, // 14^-168 -673, // 14^-160 -642, // 14^-152 -612, // 14^-144 -581, // 14^-136 -551, // 14^-128 -520, // 14^-120 -490, // 14^-112 -459, // 14^-104 -429, // 14^-96 -399, // 14^-88 -368, // 14^-80 -338, // 14^-72 -307, // 14^-64 -277, // 14^-56 -246, // 14^-48 -216, // 14^-40 -185, // 14^-32 -155, // 14^-24 -124, // 14^-16 -94, // 14^-8 -63, // 14^0 -33, // 14^8 -3, // 14^16 28, // 14^24 58, // 14^32 89, // 14^40 119, // 14^48 150, // 14^56 180, // 14^64 211, // 14^72 241, // 14^80 272, // 14^88 302, // 14^96 332, // 14^104 363, // 14^112 393, // 14^120 424, // 14^128 454, // 14^136 485, // 14^144 515, // 14^152 546, // 14^160 576, // 14^168 607, // 14^176 637, // 14^184 668, // 14^192 698, // 14^200 728, // 14^208 759, // 14^216 789, // 14^224 820, // 14^232 850, // 14^240 881, // 14^248 911, // 14^256 942, // 14^264 ]; const BASE14_SMALL_INT_POWERS: [u64; 8] = [1, 14, 196, 2744, 38416, 537824, 7529536, 105413504]; const BASE14_STEP: i32 = 8; const BASE14_BIAS: i32 = 304; // BASE15 const BASE15_SMALL_MANTISSA: [u64; 8] = [ 9223372036854775808, // 15^0 17293822569102704640, // 15^1 16212958658533785600, // 15^2 15199648742375424000, // 15^3 14249670695976960000, // 15^4 13359066277478400000, // 15^5 12524124635136000000, // 15^6 11741366845440000000, // 15^7 ]; const BASE15_SMALL_EXPONENT: [i32; 8] = [ -63, // 15^0 -60, // 15^1 -56, // 15^2 -52, // 15^3 -48, // 15^4 -44, // 15^5 -40, // 15^6 -36, // 15^7 ]; const BASE15_LARGE_MANTISSA: [u64; 70] = [ 13601350414362439244, // 15^-296 16232381325359158633, // 15^-288 9686178043528474499, // 15^-280 11559862131178364723, // 15^-272 13795989697002596758, // 15^-264 16464671426007778306, // 15^-256 9824790070164184132, // 15^-248 11725287122380398084, // 15^-240 13993414324420480958, // 15^-232 16700285665596816319, // 15^-224 9965385675239368708, // 15^-216 11893079393347852255, // 15^-208 14193664155710441018, // 15^-200 16939271613521887687, // 15^-192 10107993244338750184, // 15^-184 12063272820543086702, // 15^-176 14396779620362065880, // 15^-168 17181677519910502131, // 15^-160 10252641569253028545, // 15^-152 12235901765210495847, // 15^-144 14602801726422706134, // 15^-136 17427552325363535592, // 15^-128 10399359853791807565, // 15^-120 12411001080313881072, // 15^-112 14811772068776803956, // 15^-104 17676945670836105047, // 15^-96 10548177719679705225, // 15^-88 12588606117573098524, // 15^-80 15023732837543702665, // 15^-72 17929907907659841510, // 15^-64 10699125212536839185, // 15^-56 12768752734601403407, // 15^-48 15238726826595631383, // 15^-40 18186490107708584674, // 15^-32 10852232807944894743, // 15^-24 12951477302144931748, // 15^-16 15456797442197584532, // 15^-8 9223372036854775808, // 15^0 11007531417600000000, // 15^8 13136816711425781250, // 15^16 15677988711770840524, // 15^24 9355361174851030653, // 15^32 11165052395553650442, // 15^40 13324808381590173768, // 15^48 15902345292781888946, // 15^56 9489239115822963265, // 15^64 11324827544542942993, // 15^72 13515490267263203164, // 15^80 16129912481758560891, // 15^88 9625032889090827484, // 15^96 11486889122411397534, // 15^104 13708900866211693796, // 15^112 16360736223435182728, // 15^120 9762769910772315950, // 15^128 11651269848621662268, // 15^136 13905079227116716745, // 15^144 16594863120028599690, // 15^152 9902477989317744010, // 15^160 11818002910861417777, // 15^168 14104064957457333009, // 15^176 16832340440646942057, // 15^184 10044185331124443731, // 15^192 11987121971743813505, // 15^200 14305898231507155361, // 15^208 17073216130833033517, // 15^216 10187920546231501512, // 15^224 12158661175603789420, // 15^232 14510619798445343328, // 15^240 17317538822244368489, // 15^248 10333712654095989060, // 15^256 ]; const BASE15_LARGE_EXPONENT: [i32; 70] = [ -1220, // 15^-296 -1189, // 15^-288 -1157, // 15^-280 -1126, // 15^-272 -1095, // 15^-264 -1064, // 15^-256 -1032, // 15^-248 -1001, // 15^-240 -970, // 15^-232 -939, // 15^-224 -907, // 15^-216 -876, // 15^-208 -845, // 15^-200 -814, // 15^-192 -782, // 15^-184 -751, // 15^-176 -720, // 15^-168 -689, // 15^-160 -657, // 15^-152 -626, // 15^-144 -595, // 15^-136 -564, // 15^-128 -532, // 15^-120 -501, // 15^-112 -470, // 15^-104 -439, // 15^-96 -407, // 15^-88 -376, // 15^-80 -345, // 15^-72 -314, // 15^-64 -282, // 15^-56 -251, // 15^-48 -220, // 15^-40 -189, // 15^-32 -157, // 15^-24 -126, // 15^-16 -95, // 15^-8 -63, // 15^0 -32, // 15^8 -1, // 15^16 30, // 15^24 62, // 15^32 93, // 15^40 124, // 15^48 155, // 15^56 187, // 15^64 218, // 15^72 249, // 15^80 280, // 15^88 312, // 15^96 343, // 15^104 374, // 15^112 405, // 15^120 437, // 15^128 468, // 15^136 499, // 15^144 530, // 15^152 562, // 15^160 593, // 15^168 624, // 15^176 655, // 15^184 687, // 15^192 718, // 15^200 749, // 15^208 780, // 15^216 812, // 15^224 843, // 15^232 874, // 15^240 905, // 15^248 937, // 15^256 ]; const BASE15_SMALL_INT_POWERS: [u64; 8] = [1, 15, 225, 3375, 50625, 759375, 11390625, 170859375]; const BASE15_STEP: i32 = 8; const BASE15_BIAS: i32 = 296; // BASE17 const BASE17_SMALL_MANTISSA: [u64; 8] = [ 9223372036854775808, // 17^0 9799832789158199296, // 17^1 10412322338480586752, // 17^2 11063092484635623424, // 17^3 11754535764925349888, // 17^4 12489194250233184256, // 17^5 13269768890872758272, // 17^6 14099129446552305664, // 17^7 ]; const BASE17_SMALL_EXPONENT: [i32; 8] = [ -63, // 17^0 -59, // 17^1 -55, // 17^2 -51, // 17^3 -47, // 17^4 -43, // 17^5 -39, // 17^6 -35, // 17^7 ]; const BASE17_LARGE_MANTISSA: [u64; 67] = [ 13138227451101932889, // 17^-280 10669358063439695630, // 17^-272 17328852299072967575, // 17^-264 14072501842077846052, // 17^-256 11428068326595325663, // 17^-248 9280563409615280245, // 17^-240 15073213554289220394, // 17^-232 12240731344920942400, // 17^-224 9940514895438007254, // 17^-216 16145087021687770276, // 17^-208 13111183760586542995, // 17^-200 10647396286743453217, // 17^-192 17293182638130712658, // 17^-184 14043535043777936273, // 17^-176 11404544822822581011, // 17^-168 9261460323937079649, // 17^-160 15042186893809203473, // 17^-152 12215535057871861844, // 17^-144 9920053367473418578, // 17^-136 16111854019870470980, // 17^-128 13084195736727816960, // 17^-120 10625479716106730764, // 17^-112 17257586399518441101, // 17^-104 14014627870654357169, // 17^-96 11381069739763987898, // 17^-88 9242396559996829853, // 17^-80 15011224098520048145, // 17^-72 12190390634789334486, // 17^-64 9899633957460570790, // 17^-56 16078689424770850259, // 17^-48 13057263264941664926, // 17^-40 10603608258477502216, // 17^-32 17222063432103834911, // 17^-24 13985780199974813110, // 17^-16 11357642977750484199, // 17^-8 9223372036854775808, // 17^0 14980325036961824768, // 17^8 12165297968916717120, // 17^16 9879256578703990224, // 17^24 16045593095580712414, // 17^32 13030386230879856604, // 17^40 10581781820995279550, // 17^48 17186613585065666435, // 17^56 13956991909259640275, // 17^64 11334264437318166304, // 17^72 18408773347475537258, // 17^80 14949489577945200446, // 17^88 12140256953717114113, // 17^96 9858921144686656932, // 17^104 16012564891781700940, // 17^112 13003564520429535778, // 17^120 10560000310990718510, // 17^128 17151236707893158013, // 17^136 13928262876281286641, // 17^144 11310934019207866827, // 17^152 18370880780077845311, // 17^160 14918717590550882042, // 17^168 12115267482872925081, // 17^176 9838627569069637357, // 17^184 15979604673144701925, // 17^192 12976798019712735820, // 17^200 10538263635985225157, // 17^208 17115932650385342947, // 17^216 13899592979063793037, // 17^224 11287651624364733171, // 17^232 18333066210634546428, // 17^240 14888008944129060322, // 17^248 ]; const BASE17_LARGE_EXPONENT: [i32; 67] = [ -1208, // 17^-280 -1175, // 17^-272 -1143, // 17^-264 -1110, // 17^-256 -1077, // 17^-248 -1044, // 17^-240 -1012, // 17^-232 -979, // 17^-224 -946, // 17^-216 -914, // 17^-208 -881, // 17^-200 -848, // 17^-192 -816, // 17^-184 -783, // 17^-176 -750, // 17^-168 -717, // 17^-160 -685, // 17^-152 -652, // 17^-144 -619, // 17^-136 -587, // 17^-128 -554, // 17^-120 -521, // 17^-112 -489, // 17^-104 -456, // 17^-96 -423, // 17^-88 -390, // 17^-80 -358, // 17^-72 -325, // 17^-64 -292, // 17^-56 -260, // 17^-48 -227, // 17^-40 -194, // 17^-32 -162, // 17^-24 -129, // 17^-16 -96, // 17^-8 -63, // 17^0 -31, // 17^8 2, // 17^16 35, // 17^24 67, // 17^32 100, // 17^40 133, // 17^48 165, // 17^56 198, // 17^64 231, // 17^72 263, // 17^80 296, // 17^88 329, // 17^96 362, // 17^104 394, // 17^112 427, // 17^120 460, // 17^128 492, // 17^136 525, // 17^144 558, // 17^152 590, // 17^160 623, // 17^168 656, // 17^176 689, // 17^184 721, // 17^192 754, // 17^200 787, // 17^208 819, // 17^216 852, // 17^224 885, // 17^232 917, // 17^240 950, // 17^248 ]; const BASE17_SMALL_INT_POWERS: [u64; 8] = [1, 17, 289, 4913, 83521, 1419857, 24137569, 410338673]; const BASE17_STEP: i32 = 8; const BASE17_BIAS: i32 = 280; // BASE18 const BASE18_SMALL_MANTISSA: [u64; 7] = [ 9223372036854775808, // 18^0 10376293541461622784, // 18^1 11673330234144325632, // 18^2 13132496513412366336, // 18^3 14774058577588912128, // 18^4 16620815899787526144, // 18^5 9349208943630483456, // 18^6 ]; const BASE18_SMALL_EXPONENT: [i32; 7] = [ -63, // 18^0 -59, // 18^1 -55, // 18^2 -51, // 18^3 -47, // 18^4 -43, // 18^5 -38, // 18^6 ]; const BASE18_LARGE_MANTISSA: [u64; 75] = [ 14081888293732326968, // 18^-273 16058262627216485544, // 18^-266 18312018475493194258, // 18^-259 10441042983020688038, // 18^-252 11906429509033078491, // 18^-245 13577481089208229636, // 18^-238 15483062540952967857, // 18^-231 17656089820489710741, // 18^-224 10067049297406417285, // 18^-217 11479946305982273645, // 18^-210 13091141534609253262, // 18^-203 14928465875303384176, // 18^-196 17023656248839843776, // 18^-189 9706451905352742522, // 18^-182 11068739548514628780, // 18^-175 12622222454457155586, // 18^-168 14393734624570008992, // 18^-161 16413876176725623927, // 18^-154 9358770957364699929, // 18^-147 10672262040895386089, // 18^-140 12170099854822007158, // 18^-133 13878157218102970303, // 18^-126 15825938165500818674, // 18^-119 18047087583901234911, // 18^-112 10289986187706530766, // 18^-105 11734172092969064177, // 18^-98 13381047573408163051, // 18^-91 15259059841903798156, // 18^-84 17400648639910404101, // 18^-77 9921403291771844100, // 18^-70 11313859076748534537, // 18^-63 12901744183172431346, // 18^-56 14712486856947913357, // 18^-49 16777364861891103792, // 18^-42 9566022877229980327, // 18^-35 10908601492662859386, // 18^-28 12439609234991117453, // 18^-21 14185491882103974832, // 18^-14 16176406841720334625, // 18^-7 9223372036854775808, // 18^0 10517860061584293888, // 18^7 11994027762626592768, // 18^14 13677373641439044901, // 18^21 15596974880318657672, // 18^28 17785989605508530085, // 18^35 10141114821132365302, // 18^42 11564406827668344530, // 18^49 13187455978423603575, // 18^56 15038297923484984581, // 18^63 17148903079221976570, // 18^70 9777864433756263024, // 18^77 11150174730505647564, // 18^84 12715086956165281921, // 18^91 14499632535849309517, // 18^98 16534636719312342666, // 18^105 9427625519601420913, // 18^112 10750780249562856814, // 18^119 12259637989871837542, // 18^126 13980261911578014597, // 18^133 15942373117198559022, // 18^140 18179864026545065558, // 18^147 10365691907784965713, // 18^154 11820503010388934534, // 18^161 13479494920515287357, // 18^168 15371324143524666656, // 18^175 17528669087274082029, // 18^182 9994397265397337538, // 18^189 11397097657699641734, // 18^196 12996665188491343910, // 18^203 14820729899390519784, // 18^210 16900799671687597041, // 18^217 9636402237998480121, // 18^224 10988858503312433354, // 18^231 12531130210573617469, // 18^238 14289857705148955482, // 18^245 ]; const BASE18_LARGE_EXPONENT: [i32; 75] = [ -1202, // 18^-273 -1173, // 18^-266 -1144, // 18^-259 -1114, // 18^-252 -1085, // 18^-245 -1056, // 18^-238 -1027, // 18^-231 -998, // 18^-224 -968, // 18^-217 -939, // 18^-210 -910, // 18^-203 -881, // 18^-196 -852, // 18^-189 -822, // 18^-182 -793, // 18^-175 -764, // 18^-168 -735, // 18^-161 -706, // 18^-154 -676, // 18^-147 -647, // 18^-140 -618, // 18^-133 -589, // 18^-126 -560, // 18^-119 -531, // 18^-112 -501, // 18^-105 -472, // 18^-98 -443, // 18^-91 -414, // 18^-84 -385, // 18^-77 -355, // 18^-70 -326, // 18^-63 -297, // 18^-56 -268, // 18^-49 -239, // 18^-42 -209, // 18^-35 -180, // 18^-28 -151, // 18^-21 -122, // 18^-14 -93, // 18^-7 -63, // 18^0 -34, // 18^7 -5, // 18^14 24, // 18^21 53, // 18^28 82, // 18^35 112, // 18^42 141, // 18^49 170, // 18^56 199, // 18^63 228, // 18^70 258, // 18^77 287, // 18^84 316, // 18^91 345, // 18^98 374, // 18^105 404, // 18^112 433, // 18^119 462, // 18^126 491, // 18^133 520, // 18^140 549, // 18^147 579, // 18^154 608, // 18^161 637, // 18^168 666, // 18^175 695, // 18^182 725, // 18^189 754, // 18^196 783, // 18^203 812, // 18^210 841, // 18^217 871, // 18^224 900, // 18^231 929, // 18^238 958, // 18^245 ]; const BASE18_SMALL_INT_POWERS: [u64; 7] = [1, 18, 324, 5832, 104976, 1889568, 34012224]; const BASE18_STEP: i32 = 7; const BASE18_BIAS: i32 = 273; // BASE19 const BASE19_SMALL_MANTISSA: [u64; 7] = [ 9223372036854775808, // 19^0 10952754293765046272, // 19^1 13006395723845992448, // 19^2 15445094922067116032, // 19^3 18341050219954700288, // 19^4 10889998568098103296, // 19^5 12931873299616497664, // 19^6 ]; const BASE19_SMALL_EXPONENT: [i32; 7] = [ -63, // 19^0 -59, // 19^1 -55, // 19^2 -51, // 19^3 -47, // 19^4 -42, // 19^5 -38, // 19^6 ]; const BASE19_LARGE_MANTISSA: [u64; 74] = [ 11480257701232751935, // 19^-273 9557118560717499270, // 19^-266 15912276110980153383, // 19^-259 13246698229359450470, // 19^-252 11027650146079950824, // 19^-245 18360660994723606251, // 19^-238 15284936849533635885, // 19^-231 12724449003299523561, // 19^-224 10592886580523254223, // 19^-217 17636794501472422448, // 19^-210 14682330350779734844, // 19^-203 12222789379976654044, // 19^-196 10175263507767080823, // 19^-189 16941466343535111364, // 19^-182 14103481529006456400, // 19^-175 11740907617180962231, // 19^-168 9774105166278679843, // 19^-161 16273551401031031665, // 19^-154 13547453741119703900, // 19^-147 11278023975525727060, // 19^-140 9388762436329270793, // 19^-133 15631968911773566269, // 19^-126 13013347271048440836, // 19^-119 10833389456740556437, // 19^-112 18037223579289291900, // 19^-105 15015680722474235794, // 19^-98 12500297873901968386, // 19^-91 10406284591707172986, // 19^-84 17326108560931302042, // 19^-77 14423689608892845377, // 19^-70 12007475377523598784, // 19^-63 9996018276276719532, // 19^-56 16643029152771930644, // 19^-49 13855037662215477149, // 19^-42 11534082339177879647, // 19^-35 9601926652984804576, // 19^-28 15986880054797934009, // 19^-21 13308804739049304804, // 19^-14 11079352755197736707, // 19^-7 9223372036854775808, // 19^0 15356599543294590976, // 19^7 12784106972526145936, // 19^14 10642550821503597582, // 19^21 17719483767102098773, // 19^28 14751167752856224795, // 19^35 12280095342105548712, // 19^42 10222969742988875833, // 19^49 17020895596425699999, // 19^56 14169605026128220038, // 19^63 11795954299763191941, // 19^70 9819930589845265884, // 19^77 16349849166729084322, // 19^84 13610970328610229813, // 19^91 11330900450341615431, // 19^98 9432781198977253334, // 19^105 15705258648723927251, // 19^112 13074359725955544955, // 19^119 10884181283927938347, // 19^126 18121790237456409263, // 19^133 15086081021789818522, // 19^140 12558904921302722743, // 19^147 10455073958207408827, // 19^154 17407341190420966318, // 19^161 14491314386248513408, // 19^168 12063771850272711708, // 19^175 10042884128822494706, // 19^182 16721059197198717605, // 19^189 13919996342176535757, // 19^196 11588159331358018389, // 19^203 9646944825844903597, // 19^210 16061833775630288054, // 19^217 13371202432132867541, // 19^224 11131297769520092558, // 19^231 9266615374542536521, // 19^238 ]; const BASE19_LARGE_EXPONENT: [i32; 74] = [ -1223, // 19^-273 -1193, // 19^-266 -1164, // 19^-259 -1134, // 19^-252 -1104, // 19^-245 -1075, // 19^-238 -1045, // 19^-231 -1015, // 19^-224 -985, // 19^-217 -956, // 19^-210 -926, // 19^-203 -896, // 19^-196 -866, // 19^-189 -837, // 19^-182 -807, // 19^-175 -777, // 19^-168 -747, // 19^-161 -718, // 19^-154 -688, // 19^-147 -658, // 19^-140 -628, // 19^-133 -599, // 19^-126 -569, // 19^-119 -539, // 19^-112 -510, // 19^-105 -480, // 19^-98 -450, // 19^-91 -420, // 19^-84 -391, // 19^-77 -361, // 19^-70 -331, // 19^-63 -301, // 19^-56 -272, // 19^-49 -242, // 19^-42 -212, // 19^-35 -182, // 19^-28 -153, // 19^-21 -123, // 19^-14 -93, // 19^-7 -63, // 19^0 -34, // 19^7 -4, // 19^14 26, // 19^21 55, // 19^28 85, // 19^35 115, // 19^42 145, // 19^49 174, // 19^56 204, // 19^63 234, // 19^70 264, // 19^77 293, // 19^84 323, // 19^91 353, // 19^98 383, // 19^105 412, // 19^112 442, // 19^119 472, // 19^126 501, // 19^133 531, // 19^140 561, // 19^147 591, // 19^154 620, // 19^161 650, // 19^168 680, // 19^175 710, // 19^182 739, // 19^189 769, // 19^196 799, // 19^203 829, // 19^210 858, // 19^217 888, // 19^224 918, // 19^231 948, // 19^238 ]; const BASE19_SMALL_INT_POWERS: [u64; 7] = [1, 19, 361, 6859, 130321, 2476099, 47045881]; const BASE19_STEP: i32 = 7; const BASE19_BIAS: i32 = 273; // BASE20 const BASE20_SMALL_MANTISSA: [u64; 7] = [ 9223372036854775808, // 20^0 11529215046068469760, // 20^1 14411518807585587200, // 20^2 18014398509481984000, // 20^3 11258999068426240000, // 20^4 14073748835532800000, // 20^5 17592186044416000000, // 20^6 ]; const BASE20_SMALL_EXPONENT: [i32; 7] = [ -63, // 20^0 -59, // 20^1 -55, // 20^2 -51, // 20^3 -46, // 20^4 -42, // 20^5 -38, // 20^6 ]; const BASE20_LARGE_MANTISSA: [u64; 72] = [ 11896135267822264502, // 20^-266 14181298336770849826, // 20^-259 16905424996341287883, // 20^-252 10076418516839318205, // 20^-245 12012026926087520367, // 20^-238 14319451959237480602, // 20^-231 17070116948172426941, // 20^-224 10174582569701926077, // 20^-217 12129047596099288555, // 20^-210 14458951468586073584, // 20^-203 17236413322193710308, // 20^-196 10273702932711667006, // 20^-189 12247208276643356092, // 20^-182 14599809976391024699, // 20^-175 17404329748619824289, // 20^-168 10373788922202482396, // 20^-161 12366520073655226703, // 20^-154 14742040721959145907, // 20^-147 17573882009934360870, // 20^-140 10474849945267653984, // 20^-133 12486994201263968925, // 20^-126 14885657073574029118, // 20^-119 17745086042373215101, // 20^-112 10576895500643977583, // 20^-105 12608641982846233347, // 20^-98 15030672529752532658, // 20^-91 17917957937422433684, // 20^-84 10679935179604550411, // 20^-77 12731474852090538039, // 20^-70 15177100720513508366, // 20^-63 18092513943330655534, // 20^-56 10783978666860255917, // 20^-49 12855504354071922204, // 20^-42 15324955408658888583, // 20^-35 18268770466636286477, // 20^-28 10889035741470030830, // 20^-21 12980742146337069071, // 20^-14 15474250491067253436, // 20^-7 9223372036854775808, // 20^0 10995116277760000000, // 20^7 13107200000000000000, // 20^14 15625000000000000000, // 20^21 9313225746154785156, // 20^28 11102230246251565404, // 20^35 13234889800848442797, // 20^42 15777218104420236108, // 20^49 9403954806578300063, // 20^56 11210387714598536567, // 20^63 13363823550460978230, // 20^70 15930919111324522770, // 20^77 9495567745759798747, // 20^84 11319598848533390459, // 20^91 13494013367335069727, // 20^98 16086117467087590369, // 20^105 9588073174409622174, // 20^112 11429873912822749822, // 20^119 13625471488026082303, // 20^126 16242827758820155028, // 20^133 9681479787123295682, // 20^140 11541223272232169725, // 20^147 13758210268297397763, // 20^154 16401064715739962772, // 20^161 9775796363198734982, // 20^168 11653657392500323036, // 20^175 13892242184281734271, // 20^182 16560843210556190337, // 20^189 9871031767461413346, // 20^196 11767186841322676356, // 20^203 14027579833653779454, // 20^210 16722178260867332761, // 20^217 9967194951097567535, // 20^224 11881822289344748896, // 20^231 ]; const BASE20_LARGE_EXPONENT: [i32; 72] = [ -1213, // 20^-266 -1183, // 20^-259 -1153, // 20^-252 -1122, // 20^-245 -1092, // 20^-238 -1062, // 20^-231 -1032, // 20^-224 -1001, // 20^-217 -971, // 20^-210 -941, // 20^-203 -911, // 20^-196 -880, // 20^-189 -850, // 20^-182 -820, // 20^-175 -790, // 20^-168 -759, // 20^-161 -729, // 20^-154 -699, // 20^-147 -669, // 20^-140 -638, // 20^-133 -608, // 20^-126 -578, // 20^-119 -548, // 20^-112 -517, // 20^-105 -487, // 20^-98 -457, // 20^-91 -427, // 20^-84 -396, // 20^-77 -366, // 20^-70 -336, // 20^-63 -306, // 20^-56 -275, // 20^-49 -245, // 20^-42 -215, // 20^-35 -185, // 20^-28 -154, // 20^-21 -124, // 20^-14 -94, // 20^-7 -63, // 20^0 -33, // 20^7 -3, // 20^14 27, // 20^21 58, // 20^28 88, // 20^35 118, // 20^42 148, // 20^49 179, // 20^56 209, // 20^63 239, // 20^70 269, // 20^77 300, // 20^84 330, // 20^91 360, // 20^98 390, // 20^105 421, // 20^112 451, // 20^119 481, // 20^126 511, // 20^133 542, // 20^140 572, // 20^147 602, // 20^154 632, // 20^161 663, // 20^168 693, // 20^175 723, // 20^182 753, // 20^189 784, // 20^196 814, // 20^203 844, // 20^210 874, // 20^217 905, // 20^224 935, // 20^231 ]; const BASE20_SMALL_INT_POWERS: [u64; 7] = [1, 20, 400, 8000, 160000, 3200000, 64000000]; const BASE20_STEP: i32 = 7; const BASE20_BIAS: i32 = 266; // BASE21 const BASE21_SMALL_MANTISSA: [u64; 7] = [ 9223372036854775808, // 21^0 12105675798371893248, // 21^1 15888699485363109888, // 21^2 10426959037269540864, // 21^3 13685383736416272384, // 21^4 17962066154046357504, // 21^5 11787605913592922112, // 21^6 ]; const BASE21_SMALL_EXPONENT: [i32; 7] = [ -63, // 21^0 -59, // 21^1 -55, // 21^2 -50, // 21^3 -46, // 21^4 -42, // 21^5 -37, // 21^6 ]; const BASE21_LARGE_MANTISSA: [u64; 72] = [ 14408615719666154271, // 21^-266 12084465783258517647, // 21^-259 10135207719324857823, // 21^-252 17000740844691866712, // 21^-245 14258473889848767691, // 21^-238 11958542249702993646, // 21^-231 10029596003240171126, // 21^-224 16823588341749525709, // 21^-217 14109896580142091329, // 21^-210 11833930874797054029, // 21^-203 9925084790952075138, // 21^-196 16648281817731599335, // 21^-189 13962867487806377083, // 21^-182 11710617985478380225, // 21^-175 9821662614901370847, // 21^-168 16474802037018309233, // 21^-161 13817370479981011975, // 21^-154 11588590051161810088, // 21^-147 9719318127024052612, // 21^-140 16303129964430447286, // 21^-133 13673389591914329770, // 21^-126 11467833682254685835, // 21^-119 9618040097506134632, // 21^-112 16133246763140728476, // 21^-105 13530909025211868449, // 21^-98 11348335628687672485, // 21^-91 9517817413551452467, // 21^-84 15965133792606908039, // 21^-77 13389913146102881332, // 21^-70 11230082778460885572, // 21^-63 9418639078162304415, // 21^-56 15798772606526436117, // 21^-49 13250386483724911652, // 21^-42 11113062156205168633, // 21^-35 9320494208932798947, // 21^-28 15634144950812425486, // 21^-21 13112313728426242332, // 21^-14 10997260921758362571, // 21^-7 9223372036854775808, // 21^0 15471232761590710272, // 21^7 12975679730086034724, // 21^14 10882666368756410705, // 21^21 18254523810272339491, // 21^28 15310018163217775871, // 21^35 12840469496451971963, // 21^42 10769265923239144897, // 21^49 18064306536063374465, // 21^56 15150483466319342608, // 21^63 12706668191495224563, // 21^70 10657047142270599779, // 21^77 17876071379371335714, // 21^84 14992611165849387896, // 21^91 12574261133782557711, // 21^98 10545997712573703694, // 21^105 17689797685974006860, // 21^112 14836383939169393936, // 21^119 12443233794865401683, // 21^126 10436105449179196548, // 21^133 17505465016871978304, // 21^140 14681784644147610193, // 21^147 12313571797685708585, // 21^154 10327358294088626305, // 21^161 17323053146045965028, // 21^168 14528796317278122096, // 21^175 12185260914998420522, // 21^182 10219744314951277448, // 21^189 17142542058237493769, // 21^196 14377402171819519570, // 21^203 12058287067810376090, // 21^210 10113251703754886210, // 21^217 16963911946752716066, // 21^224 14227585595952961160, // 21^231 ]; const BASE21_LARGE_EXPONENT: [i32; 72] = [ -1232, // 21^-266 -1201, // 21^-259 -1170, // 21^-252 -1140, // 21^-245 -1109, // 21^-238 -1078, // 21^-231 -1047, // 21^-224 -1017, // 21^-217 -986, // 21^-210 -955, // 21^-203 -924, // 21^-196 -894, // 21^-189 -863, // 21^-182 -832, // 21^-175 -801, // 21^-168 -771, // 21^-161 -740, // 21^-154 -709, // 21^-147 -678, // 21^-140 -648, // 21^-133 -617, // 21^-126 -586, // 21^-119 -555, // 21^-112 -525, // 21^-105 -494, // 21^-98 -463, // 21^-91 -432, // 21^-84 -402, // 21^-77 -371, // 21^-70 -340, // 21^-63 -309, // 21^-56 -279, // 21^-49 -248, // 21^-42 -217, // 21^-35 -186, // 21^-28 -156, // 21^-21 -125, // 21^-14 -94, // 21^-7 -63, // 21^0 -33, // 21^7 -2, // 21^14 29, // 21^21 59, // 21^28 90, // 21^35 121, // 21^42 152, // 21^49 182, // 21^56 213, // 21^63 244, // 21^70 275, // 21^77 305, // 21^84 336, // 21^91 367, // 21^98 398, // 21^105 428, // 21^112 459, // 21^119 490, // 21^126 521, // 21^133 551, // 21^140 582, // 21^147 613, // 21^154 644, // 21^161 674, // 21^168 705, // 21^175 736, // 21^182 767, // 21^189 797, // 21^196 828, // 21^203 859, // 21^210 890, // 21^217 920, // 21^224 951, // 21^231 ]; const BASE21_SMALL_INT_POWERS: [u64; 7] = [1, 21, 441, 9261, 194481, 4084101, 85766121]; const BASE21_STEP: i32 = 7; const BASE21_BIAS: i32 = 266; // BASE22 const BASE22_SMALL_MANTISSA: [u64; 7] = [ 9223372036854775808, // 22^0 12682136550675316736, // 22^1 17437937757178560512, // 22^2 11988582208060260352, // 22^3 16484300536082857984, // 22^4 11332956618556964864, // 22^5 15582815350515826688, // 22^6 ]; const BASE22_SMALL_EXPONENT: [i32; 7] = [ -63, // 22^0 -59, // 22^1 -55, // 22^2 -50, // 22^3 -46, // 22^4 -41, // 22^5 -37, // 22^6 ]; const BASE22_LARGE_MANTISSA: [u64; 70] = [ 9269587019009961312, // 22^-259 10766865452458105492, // 22^-252 12505993140104023937, // 22^-245 14526035001637582317, // 22^-238 16872365953260472216, // 22^-231 9798845067792082715, // 22^-224 11381612386618310709, // 22^-217 13220037629231758864, // 22^-210 15355416173176400877, // 22^-203 17835713669231780592, // 22^-196 10358321731667433590, // 22^-189 12031459025026523680, // 22^-182 13974851334106036811, // 22^-175 16232151844936756579, // 22^-168 9427032431967498649, // 22^-161 10949742378252536811, // 22^-154 12718409426865212084, // 22^-147 14772762021382712235, // 22^-140 17158945778190527545, // 22^-133 9965280013064351107, // 22^-126 11574930887071326019, // 22^-119 13444582075449265201, // 22^-112 15616230364311619568, // 22^-105 18138656108661462534, // 22^-98 10534259477248206780, // 22^-91 12235815274209166465, // 22^-84 14212216411407346527, // 22^-77 16507857531195957209, // 22^-70 9587152080358667750, // 22^-63 11135725497779554116, // 22^-56 12934433638113158426, // 22^-49 15023679738882972932, // 22^-42 17450393207123747022, // 22^-35 10134541882409419905, // 22^-28 11771532933066741091, // 22^-21 13672940444874950532, // 22^-14 15881474526053323426, // 22^-7 9223372036854775808, // 22^0 10713185553479630848, // 22^7 12443642546855641088, // 22^14 14453613172379218947, // 22^21 16788246122479815273, // 22^28 9749991386498543747, // 22^35 11324867570234788254, // 22^42 13154127055020322136, // 22^49 15278859333807672616, // 22^56 17746790917089950882, // 22^63 10306678691583236909, // 22^70 11971474296148943805, // 22^77 13905177517602390611, // 22^84 16151223902158337584, // 22^91 9380032480974399852, // 22^98 10895150717634104284, // 22^105 12654999798852712250, // 22^112 14699110095811391320, // 22^119 17073397158676562691, // 22^126 9915596544207462992, // 22^133 11517222250937216925, // 22^140 13377551999629643946, // 22^147 15538373194824147716, // 22^154 18048222989401488392, // 22^161 10481739271897017716, // 22^168 12174811695150892652, // 22^175 14141359174025375600, // 22^182 16425555014410689631, // 22^189 9539353827706830891, // 22^196 11080206589104387250, // 22^203 12869946987462278079, // 22^210 14948776823616759120, // 22^217 17363391530672110525, // 22^224 ]; const BASE22_LARGE_EXPONENT: [i32; 70] = [ -1218, // 22^-259 -1187, // 22^-252 -1156, // 22^-245 -1125, // 22^-238 -1094, // 22^-231 -1062, // 22^-224 -1031, // 22^-217 -1000, // 22^-210 -969, // 22^-203 -938, // 22^-196 -906, // 22^-189 -875, // 22^-182 -844, // 22^-175 -813, // 22^-168 -781, // 22^-161 -750, // 22^-154 -719, // 22^-147 -688, // 22^-140 -657, // 22^-133 -625, // 22^-126 -594, // 22^-119 -563, // 22^-112 -532, // 22^-105 -501, // 22^-98 -469, // 22^-91 -438, // 22^-84 -407, // 22^-77 -376, // 22^-70 -344, // 22^-63 -313, // 22^-56 -282, // 22^-49 -251, // 22^-42 -220, // 22^-35 -188, // 22^-28 -157, // 22^-21 -126, // 22^-14 -95, // 22^-7 -63, // 22^0 -32, // 22^7 -1, // 22^14 30, // 22^21 61, // 22^28 93, // 22^35 124, // 22^42 155, // 22^49 186, // 22^56 217, // 22^63 249, // 22^70 280, // 22^77 311, // 22^84 342, // 22^91 374, // 22^98 405, // 22^105 436, // 22^112 467, // 22^119 498, // 22^126 530, // 22^133 561, // 22^140 592, // 22^147 623, // 22^154 654, // 22^161 686, // 22^168 717, // 22^175 748, // 22^182 779, // 22^189 811, // 22^196 842, // 22^203 873, // 22^210 904, // 22^217 935, // 22^224 ]; const BASE22_SMALL_INT_POWERS: [u64; 7] = [1, 22, 484, 10648, 234256, 5153632, 113379904]; const BASE22_STEP: i32 = 7; const BASE22_BIAS: i32 = 259; // BASE23 const BASE23_SMALL_MANTISSA: [u64; 7] = [ 9223372036854775808, // 23^0 13258597302978740224, // 23^1 9529616811515969536, // 23^2 13698824166554206208, // 23^3 9846029869710835712, // 23^4 14153667937709326336, // 23^5 10172948830228578304, // 23^6 ]; const BASE23_SMALL_EXPONENT: [i32; 7] = [ -63, // 23^0 -59, // 23^1 -54, // 23^2 -50, // 23^3 -45, // 23^4 -41, // 23^5 -36, // 23^6 ]; const BASE23_LARGE_MANTISSA: [u64; 69] = [ 9630971713765025029, // 23^-252 15269861356524917016, // 23^-245 12105147475110827234, // 23^-238 9596327823341159083, // 23^-231 15214933627595239789, // 23^-224 12061603644316153100, // 23^-217 9561808551614073801, // 23^-210 15160203481036150549, // 23^-203 12018216446491393101, // 23^-196 9527413450313687580, // 23^-189 15105670206117496642, // 23^-182 11974985318206853149, // 23^-175 9493142072782406120, // 23^-168 15051333094665716613, // 23^-161 11931909698059570948, // 23^-154 9458993973969322090, // 23^-147 14997191441054643808, // 23^-140 11888989026666025574, // 23^-133 9424968710424435661, // 23^-126 14943244542196343052, // 23^-119 11846222746654873270, // 23^-112 9391065840292895827, // 23^-105 14889491697531980297, // 23^-98 11803610302659709381, // 23^-91 9357284923309262442, // 23^-84 14835932209022725101, // 23^-77 11761151141311856318, // 23^-70 9323625520791788901, // 23^-63 14782565381140685845, // 23^-56 11718844711233177467, // 23^-49 9290087195636725377, // 23^-42 14729390520859877547, // 23^-35 11676690463028916948, // 23^-28 9256669512312642559, // 23^-21 14676406937647222172, // 23^-14 11634687849280565129, // 23^-7 9223372036854775808, // 23^0 14623613943453581312, // 23^7 11592836324538749809, // 23^14 18380388673718779295, // 23^21 14571010852704821123, // 23^28 11551135345316152959, // 23^35 18314271962956325083, // 23^42 14518596982292909406, // 23^49 11509584370080452960, // 23^56 18248393082825183718, // 23^63 14466371651567044709, // 23^70 11468182859247292218, // 23^77 18182751177816837937, // 23^84 14414334182324817337, // 23^91 11426930275173270071, // 23^98 18117345395500148774, // 23^105 14362483898803402166, // 23^112 11385826082148960918, // 23^119 18052174886510285819, // 23^126 14310820127670783127, // 23^133 11344869746391957446, // 23^140 17987238804537697299, // 23^147 14259342198017009262, // 23^154 11304060736039938888, // 23^161 17922536306317119829, // 23^168 14208049441345482237, // 23^175 11263398521143764220, // 23^182 17858066551616627705, // 23^189 14156941191564275184, // 23^196 11222882573660590193, // 23^203 17793828703226721580, // 23^210 14106016784977482782, // 23^217 11182512367447014130, // 23^224 ]; const BASE23_LARGE_EXPONENT: [i32; 69] = [ -1203, // 23^-252 -1172, // 23^-245 -1140, // 23^-238 -1108, // 23^-231 -1077, // 23^-224 -1045, // 23^-217 -1013, // 23^-210 -982, // 23^-203 -950, // 23^-196 -918, // 23^-189 -887, // 23^-182 -855, // 23^-175 -823, // 23^-168 -792, // 23^-161 -760, // 23^-154 -728, // 23^-147 -697, // 23^-140 -665, // 23^-133 -633, // 23^-126 -602, // 23^-119 -570, // 23^-112 -538, // 23^-105 -507, // 23^-98 -475, // 23^-91 -443, // 23^-84 -412, // 23^-77 -380, // 23^-70 -348, // 23^-63 -317, // 23^-56 -285, // 23^-49 -253, // 23^-42 -222, // 23^-35 -190, // 23^-28 -158, // 23^-21 -127, // 23^-14 -95, // 23^-7 -63, // 23^0 -32, // 23^7 0, // 23^14 31, // 23^21 63, // 23^28 95, // 23^35 126, // 23^42 158, // 23^49 190, // 23^56 221, // 23^63 253, // 23^70 285, // 23^77 316, // 23^84 348, // 23^91 380, // 23^98 411, // 23^105 443, // 23^112 475, // 23^119 506, // 23^126 538, // 23^133 570, // 23^140 601, // 23^147 633, // 23^154 665, // 23^161 696, // 23^168 728, // 23^175 760, // 23^182 791, // 23^189 823, // 23^196 855, // 23^203 886, // 23^210 918, // 23^217 950, // 23^224 ]; const BASE23_SMALL_INT_POWERS: [u64; 7] = [1, 23, 529, 12167, 279841, 6436343, 148035889]; const BASE23_STEP: i32 = 7; const BASE23_BIAS: i32 = 252; // BASE24 const BASE24_SMALL_MANTISSA: [u64; 7] = [ 9223372036854775808, // 24^0 13835058055282163712, // 24^1 10376293541461622784, // 24^2 15564440312192434176, // 24^3 11673330234144325632, // 24^4 17509995351216488448, // 24^5 13132496513412366336, // 24^6 ]; const BASE24_SMALL_EXPONENT: [i32; 7] = [ -63, // 24^0 -59, // 24^1 -54, // 24^2 -50, // 24^3 -45, // 24^4 -41, // 24^5 -36, // 24^6 ]; const BASE24_LARGE_MANTISSA: [u64; 68] = [ 13878157218102970303, // 24^-252 14820082927730076197, // 24^-245 15825938165500818674, // 24^-238 16900061898413227754, // 24^-231 18047087583901234911, // 24^-224 9635981578611328308, // 24^-217 10289986187706530766, // 24^-210 10988378804938565813, // 24^-203 11734172092969064177, // 24^-196 12530583187169601247, // 24^-189 13381047573408163051, // 24^-182 14289233907736158492, // 24^-175 15259059841903798156, // 24^-168 16294708922970511019, // 24^-161 17400648639910404101, // 24^-154 9290824847530286564, // 24^-147 9921403291771844100, // 24^-140 10594779784719249534, // 24^-133 11313859076748534537, // 24^-126 12081743066820822770, // 24^-119 12901744183172431346, // 24^-112 13777399672167044607, // 24^-105 14712486856947913357, // 24^-98 15711039431711468023, // 24^-91 16777364861891103792, // 24^-84 17916062965310470700, // 24^-77 9566022877229980327, // 24^-70 10215279312745101062, // 24^-63 10908601492662859386, // 24^-56 11648980207252770253, // 24^-49 12439609234991117453, // 24^-42 13283899119592565366, // 24^-35 14185491882103974832, // 24^-28 15148276731524117655, // 24^-21 16176406841720334625, // 24^-14 17274317267012876867, // 24^-7 9223372036854775808, // 24^0 9849372385059274752, // 24^7 10517860061584293888, // 24^14 11231718727873462272, // 24^21 11994027762626592768, // 24^28 12808075545343924992, // 24^35 13677373641439044901, // 24^42 14605671950110933202, // 24^49 15596974880318657672, // 24^56 16655558624637160317, // 24^63 17785989605508530085, // 24^70 9496572086730262523, // 24^77 10141114821132365302, // 24^84 10829403375886954548, // 24^91 11564406827668344530, // 24^98 12349295767632162835, // 24^105 13187455978423603575, // 24^112 14082503039459189950, // 24^119 15038297923484984581, // 24^126 16058963651690264296, // 24^133 17148903079221976570, // 24^140 18312817887821515019, // 24^147 9777864433756263024, // 24^154 10441498787414525016, // 24^161 11150174730505647564, // 24^168 11906949284968677354, // 24^175 12715086956165281921, // 24^182 13578073815006577911, // 24^189 14499632535849309517, // 24^196 15483738455030488239, // 24^203 16534636719312342666, // 24^210 17656860598210983110, // 24^217 ]; const BASE24_LARGE_EXPONENT: [i32; 68] = [ -1219, // 24^-252 -1187, // 24^-245 -1155, // 24^-238 -1123, // 24^-231 -1091, // 24^-224 -1058, // 24^-217 -1026, // 24^-210 -994, // 24^-203 -962, // 24^-196 -930, // 24^-189 -898, // 24^-182 -866, // 24^-175 -834, // 24^-168 -802, // 24^-161 -770, // 24^-154 -737, // 24^-147 -705, // 24^-140 -673, // 24^-133 -641, // 24^-126 -609, // 24^-119 -577, // 24^-112 -545, // 24^-105 -513, // 24^-98 -481, // 24^-91 -449, // 24^-84 -417, // 24^-77 -384, // 24^-70 -352, // 24^-63 -320, // 24^-56 -288, // 24^-49 -256, // 24^-42 -224, // 24^-35 -192, // 24^-28 -160, // 24^-21 -128, // 24^-14 -96, // 24^-7 -63, // 24^0 -31, // 24^7 1, // 24^14 33, // 24^21 65, // 24^28 97, // 24^35 129, // 24^42 161, // 24^49 193, // 24^56 225, // 24^63 257, // 24^70 290, // 24^77 322, // 24^84 354, // 24^91 386, // 24^98 418, // 24^105 450, // 24^112 482, // 24^119 514, // 24^126 546, // 24^133 578, // 24^140 610, // 24^147 643, // 24^154 675, // 24^161 707, // 24^168 739, // 24^175 771, // 24^182 803, // 24^189 835, // 24^196 867, // 24^203 899, // 24^210 931, // 24^217 ]; const BASE24_SMALL_INT_POWERS: [u64; 7] = [1, 24, 576, 13824, 331776, 7962624, 191102976]; const BASE24_STEP: i32 = 7; const BASE24_BIAS: i32 = 252; // BASE25 const BASE25_SMALL_MANTISSA: [u64; 7] = [ 9223372036854775808, // 25^0 14411518807585587200, // 25^1 11258999068426240000, // 25^2 17592186044416000000, // 25^3 13743895347200000000, // 25^4 10737418240000000000, // 25^5 16777216000000000000, // 25^6 ]; const BASE25_SMALL_EXPONENT: [i32; 7] = [ -63, // 25^0 -59, // 25^1 -54, // 25^2 -50, // 25^3 -45, // 25^4 -40, // 25^5 -36, // 25^6 ]; const BASE25_LARGE_MANTISSA: [u64; 68] = [ 15492890949478498119, // 25^-252 11008361120075348168, // 25^-245 15643822052986917253, // 25^-238 11115604119273511155, // 25^-231 15796223521069679172, // 25^-224 11223891875338892399, // 25^-217 15950109677957715915, // 25^-210 11333234566249726012, // 25^-203 16105494987428025427, // 25^-196 11443642469137689536, // 25^-189 16262394054163123565, // 25^-182 11555125961253852697, // 25^-175 16420821625123739831, // 25^-168 11667695520944036383, // 25^-161 16580792590934885855, // 25^-154 11781361728633673532, // 25^-147 16742321987285426889, // 25^-140 11896135267822264502, // 25^-133 16905424996341287883, // 25^-126 12012026926087520367, // 25^-119 17070116948172426941, // 25^-112 12129047596099288555, // 25^-105 17236413322193710308, // 25^-98 12247208276643356092, // 25^-91 17404329748619824289, // 25^-84 12366520073655226703, // 25^-77 17573882009934360870, // 25^-70 12486994201263968925, // 25^-63 17745086042373215101, // 25^-56 12608641982846233347, // 25^-49 17917957937422433684, // 25^-42 12731474852090538039, // 25^-35 18092513943330655534, // 25^-28 12855504354071922204, // 25^-21 18268770466636286477, // 25^-14 12980742146337069071, // 25^-7 9223372036854775808, // 25^0 13107200000000000000, // 25^7 9313225746154785156, // 25^14 13234889800848442797, // 25^21 9403954806578300063, // 25^28 13363823550460978230, // 25^35 9495567745759798747, // 25^42 13494013367335069727, // 25^49 9588073174409622174, // 25^56 13625471488026082303, // 25^63 9681479787123295682, // 25^70 13758210268297397763, // 25^77 9775796363198734982, // 25^84 13892242184281734271, // 25^91 9871031767461413346, // 25^98 14027579833653779454, // 25^105 9967194951097567535, // 25^112 14164235936814247246, // 25^119 10064294952495520794, // 25^126 14302223338085469768, // 25^133 10162340898095201970, // 25^140 14441555006918636608, // 25^147 10261342003245940623, // 25^154 14582244039112794984, // 25^161 10361307573072618726, // 25^168 14724303658045725350, // 25^175 10462247003350260393, // 25^182 14867747215916808149, // 25^189 10564169781387141817, // 25^196 15012588195001998509, // 25^203 10667085486916504429, // 25^210 15158840208921026870, // 25^217 ]; const BASE25_LARGE_EXPONENT: [i32; 68] = [ -1234, // 25^-252 -1201, // 25^-245 -1169, // 25^-238 -1136, // 25^-231 -1104, // 25^-224 -1071, // 25^-217 -1039, // 25^-210 -1006, // 25^-203 -974, // 25^-196 -941, // 25^-189 -909, // 25^-182 -876, // 25^-175 -844, // 25^-168 -811, // 25^-161 -779, // 25^-154 -746, // 25^-147 -714, // 25^-140 -681, // 25^-133 -649, // 25^-126 -616, // 25^-119 -584, // 25^-112 -551, // 25^-105 -519, // 25^-98 -486, // 25^-91 -454, // 25^-84 -421, // 25^-77 -389, // 25^-70 -356, // 25^-63 -324, // 25^-56 -291, // 25^-49 -259, // 25^-42 -226, // 25^-35 -194, // 25^-28 -161, // 25^-21 -129, // 25^-14 -96, // 25^-7 -63, // 25^0 -31, // 25^7 2, // 25^14 34, // 25^21 67, // 25^28 99, // 25^35 132, // 25^42 164, // 25^49 197, // 25^56 229, // 25^63 262, // 25^70 294, // 25^77 327, // 25^84 359, // 25^91 392, // 25^98 424, // 25^105 457, // 25^112 489, // 25^119 522, // 25^126 554, // 25^133 587, // 25^140 619, // 25^147 652, // 25^154 684, // 25^161 717, // 25^168 749, // 25^175 782, // 25^182 814, // 25^189 847, // 25^196 879, // 25^203 912, // 25^210 944, // 25^217 ]; const BASE25_SMALL_INT_POWERS: [u64; 7] = [1, 25, 625, 15625, 390625, 9765625, 244140625]; const BASE25_STEP: i32 = 7; const BASE25_BIAS: i32 = 252; // BASE26 const BASE26_SMALL_MANTISSA: [u64; 7] = [ 9223372036854775808, // 26^0 14987979559889010688, // 26^1 12177733392409821184, // 26^2 9894408381332979712, // 26^3 16078413619666092032, // 26^4 13063711065978699776, // 26^5 10614265241107693568, // 26^6 ]; const BASE26_SMALL_EXPONENT: [i32; 7] = [ -63, // 26^0 -59, // 26^1 -54, // 26^2 -49, // 26^3 -45, // 26^4 -40, // 26^5 -35, // 26^6 ]; const BASE26_LARGE_MANTISSA: [u64; 67] = [ 12105269954044049440, // 26^-245 11318739317371282802, // 26^-238 10583312905946974966, // 26^-231 9895670261906581517, // 26^-224 9252706671590202790, // 26^-217 17303038295456506514, // 26^-210 16178786644847745028, // 26^-203 15127582383507515360, // 26^-196 14144679313308326113, // 26^-189 13225639616708097270, // 26^-182 12366313819957994305, // 26^-175 11562822058185475244, // 26^-168 10811536557764206566, // 26^-161 10109065256878566708, // 26^-154 9452236490329416245, // 26^-147 17676169338865748372, // 26^-140 16527673784713390059, // 26^-133 15453800848879553322, // 26^-126 14449701983936623969, // 26^-119 13510843673109724761, // 26^-112 12632986961401522264, // 26^-105 11812168316666510159, // 26^-98 11044681734222321153, // 26^-91 10327062004200202236, // 26^-84 9656069066086567364, // 26^-77 18057346759632441273, // 26^-70 16884084494735168740, // 26^-63 15787054046203585657, // 26^-56 14761302310200400353, // 26^-49 13802198007013635263, // 26^-42 12905410770780760221, // 26^-35 12066891597841972649, // 26^-28 11282854565446737172, // 26^-21 10549759738273355365, // 26^-14 9864297185584324446, // 26^-7 9223372036854775808, // 26^0 17248181016800002048, // 26^7 16127493675824287744, // 26^14 15079622135830712445, // 26^21 14099835245963182583, // 26^28 13183709258266090507, // 26^35 12327107854416477244, // 26^42 11526163470203963629, // 26^49 10777259833438283283, // 26^56 10077015636442889080, // 26^63 9422269269415772631, // 26^70 17620129091456925542, // 26^77 16475274709425560342, // 26^84 15404806363345084091, // 26^91 14403890877545881062, // 26^98 13468009108242878856, // 26^105 12592935539554553092, // 26^112 11774719205254957782, // 26^119 11009665850120294209, // 26^126 10294321250328313309, // 26^133 9625455617601982106, // 26^140 18000098033363922638, // 26^147 16830555460575262708, // 26^154 15737003020008648959, // 26^161 14714503311068774005, // 26^168 13758439736979533044, // 26^175 12864495660801764695, // 26^182 12028634915772762381, // 26^189 11247083581971537298, // 26^196 10516312947031287874, // 26^203 9833023573966516058, // 26^210 18388260808361729691, // 26^217 ]; const BASE26_LARGE_EXPONENT: [i32; 67] = [ -1215, // 26^-245 -1182, // 26^-238 -1149, // 26^-231 -1116, // 26^-224 -1083, // 26^-217 -1051, // 26^-210 -1018, // 26^-203 -985, // 26^-196 -952, // 26^-189 -919, // 26^-182 -886, // 26^-175 -853, // 26^-168 -820, // 26^-161 -787, // 26^-154 -754, // 26^-147 -722, // 26^-140 -689, // 26^-133 -656, // 26^-126 -623, // 26^-119 -590, // 26^-112 -557, // 26^-105 -524, // 26^-98 -491, // 26^-91 -458, // 26^-84 -425, // 26^-77 -393, // 26^-70 -360, // 26^-63 -327, // 26^-56 -294, // 26^-49 -261, // 26^-42 -228, // 26^-35 -195, // 26^-28 -162, // 26^-21 -129, // 26^-14 -96, // 26^-7 -63, // 26^0 -31, // 26^7 2, // 26^14 35, // 26^21 68, // 26^28 101, // 26^35 134, // 26^42 167, // 26^49 200, // 26^56 233, // 26^63 266, // 26^70 298, // 26^77 331, // 26^84 364, // 26^91 397, // 26^98 430, // 26^105 463, // 26^112 496, // 26^119 529, // 26^126 562, // 26^133 595, // 26^140 627, // 26^147 660, // 26^154 693, // 26^161 726, // 26^168 759, // 26^175 792, // 26^182 825, // 26^189 858, // 26^196 891, // 26^203 924, // 26^210 956, // 26^217 ]; const BASE26_SMALL_INT_POWERS: [u64; 7] = [1, 26, 676, 17576, 456976, 11881376, 308915776]; const BASE26_STEP: i32 = 7; const BASE26_BIAS: i32 = 245; // BASE27 const BASE27_SMALL_MANTISSA: [u64; 6] = [ 9223372036854775808, // 27^0 15564440312192434176, // 27^1 13132496513412366336, // 27^2 11080543933191684096, // 27^3 9349208943630483456, // 27^4 15776790092376440832, // 27^5 ]; const BASE27_SMALL_EXPONENT: [i32; 6] = [ -63, // 27^0 -59, // 27^1 -54, // 27^2 -49, // 27^3 -44, // 27^4 -40, // 27^5 ]; const BASE27_LARGE_MANTISSA: [u64; 76] = [ 16362187946641408838, // 27^-240 11807394875954316034, // 27^-234 17041067394086403622, // 27^-228 12297292543386873229, // 27^-222 17748114058878258402, // 27^-216 12807516432401518638, // 27^-210 9242248309993244326, // 27^-204 13338909893173747895, // 27^-198 9625716122873707062, // 27^-192 13892351267110242231, // 27^-186 10025094302862174179, // 27^-180 14468755338661289290, // 27^-174 10441042983020688038, // 27^-168 15069074847369989965, // 27^-162 10874249685827050127, // 27^-156 15694302062657520659, // 27^-150 11325430459582219446, // 27^-144 16345470423947416967, // 27^-138 11795331061968106016, // 27^-132 17023656248839843776, // 27^-126 12284728192712064755, // 27^-120 17729980512159296735, // 27^-114 12794430777395563548, // 27^-108 9232805349408163458, // 27^-102 13325281304529035642, // 27^-96 9615881366772943927, // 27^-90 13878157218102970303, // 27^-84 10014851495355986817, // 27^-78 14453972367916992462, // 27^-72 10430375193750279268, // 27^-66 15053678520084183432, // 27^-60 10863139281980340679, // 27^-54 15678266930207358578, // 27^-48 11313859076748534537, // 27^-42 16328769981827608423, // 27^-36 11783279573783601017, // 27^-30 17006262892853298360, // 27^-24 12272176679245716810, // 27^-18 17711865492790087155, // 27^-12 12781358492223474271, // 27^-6 9223372036854775808, // 27^0 13311666640442621952, // 27^6 9606056659007943744, // 27^12 13863977671394362375, // 27^18 10004619153098548172, // 27^24 14439204501182606065, // 27^30 10419718303939637392, // 27^36 15038297923484984581, // 27^42 10852040229820157048, // 27^48 15662248181121787524, // 27^54 11302299516591361707, // 27^60 16312086602830473207, // 27^66 11771240398807322073, // 27^72 16988887307951181138, // 27^78 12259637989871837542, // 27^84 17693768981840924725, // 27^90 12768299563225066619, // 27^96 18427896724951050158, // 27^102 13298065886687551351, // 27^108 9596241989312152815, // 27^114 13849812612167175924, // 27^120 9994397265397337538, // 27^126 14424451723026109070, // 27^132 10409072302452601000, // 27^138 15022933041500086259, // 27^144 10840952517748290136, // 27^150 15646245798661648271, // 27^156 11290751767031273467, // 27^162 16295420269522331823, // 27^168 11759213524458657188, // 27^174 16971529475976476179, // 27^180 12247112111487835932, // 27^186 17675690960401445308, // 27^192 12755253976754113245, // 27^198 18409068632845853217, // 27^204 13284479029051404288, // 27^210 ]; const BASE27_LARGE_EXPONENT: [i32; 76] = [ -1205, // 27^-240 -1176, // 27^-234 -1148, // 27^-228 -1119, // 27^-222 -1091, // 27^-216 -1062, // 27^-210 -1033, // 27^-204 -1005, // 27^-198 -976, // 27^-192 -948, // 27^-186 -919, // 27^-180 -891, // 27^-174 -862, // 27^-168 -834, // 27^-162 -805, // 27^-156 -777, // 27^-150 -748, // 27^-144 -720, // 27^-138 -691, // 27^-132 -663, // 27^-126 -634, // 27^-120 -606, // 27^-114 -577, // 27^-108 -548, // 27^-102 -520, // 27^-96 -491, // 27^-90 -463, // 27^-84 -434, // 27^-78 -406, // 27^-72 -377, // 27^-66 -349, // 27^-60 -320, // 27^-54 -292, // 27^-48 -263, // 27^-42 -235, // 27^-36 -206, // 27^-30 -178, // 27^-24 -149, // 27^-18 -121, // 27^-12 -92, // 27^-6 -63, // 27^0 -35, // 27^6 -6, // 27^12 22, // 27^18 51, // 27^24 79, // 27^30 108, // 27^36 136, // 27^42 165, // 27^48 193, // 27^54 222, // 27^60 250, // 27^66 279, // 27^72 307, // 27^78 336, // 27^84 364, // 27^90 393, // 27^96 421, // 27^102 450, // 27^108 479, // 27^114 507, // 27^120 536, // 27^126 564, // 27^132 593, // 27^138 621, // 27^144 650, // 27^150 678, // 27^156 707, // 27^162 735, // 27^168 764, // 27^174 792, // 27^180 821, // 27^186 849, // 27^192 878, // 27^198 906, // 27^204 935, // 27^210 ]; const BASE27_SMALL_INT_POWERS: [u64; 6] = [1, 27, 729, 19683, 531441, 14348907]; const BASE27_STEP: i32 = 6; const BASE27_BIAS: i32 = 240; // BASE28 const BASE28_SMALL_MANTISSA: [u64; 6] = [ 9223372036854775808, // 28^0 16140901064495857664, // 28^1 14123288431433875456, // 28^2 12357877377504641024, // 28^3 10813142705316560896, // 28^4 9461499867151990784, // 28^5 ]; const BASE28_SMALL_EXPONENT: [i32; 6] = [ -63, // 28^0 -59, // 28^1 -54, // 28^2 -49, // 28^3 -44, // 28^4 -39, // 28^5 ]; const BASE28_LARGE_MANTISSA: [u64; 76] = [ 10853684694473876180, // 28^-240 9742165760957008810, // 28^-234 17488953546307848045, // 28^-228 15697920957714630238, // 28^-222 14090306875260685218, // 28^-216 12647327526607851831, // 28^-210 11352122773573968201, // 28^-204 10189559113984709052, // 28^-198 18292105715960495534, // 28^-192 16418822825447359765, // 28^-186 14737381642082644874, // 28^-180 13228135778880165762, // 28^-174 11873450822826176619, // 28^-168 10657498289906897377, // 28^-162 9566070681070377880, // 28^-156 17172830956378919788, // 28^-150 15414172280784786485, // 28^-144 13835616719528574716, // 28^-138 12418720027433908743, // 28^-132 11146926822720122755, // 28^-126 10005377149705503250, // 28^-120 17961465702601665525, // 28^-114 16122043445170466212, // 28^-108 14470995249030000148, // 28^-102 12989029846596759700, // 28^-96 11658831576707932907, // 28^-90 10464858064026730335, // 28^-84 9393158617970892313, // 28^-78 16862422458582420498, // 28^-72 15135552519453149331, // 28^-66 13585530230416439557, // 28^-60 12194244736314878063, // 28^-54 10945439903127358164, // 28^-48 9824524377159351811, // 28^-42 17636802191900948811, // 28^-36 15830628517722738088, // 28^-30 14209423938610553080, // 28^-24 12754245887402290033, // 28^-18 11448091693168579255, // 28^-12 10275699917675706335, // 28^-6 9223372036854775808, // 28^0 16557624767515983872, // 28^6 14861968965709594624, // 28^12 13339964194082398208, // 28^18 11973826961285400900, // 28^24 10747594971986893695, // 28^30 9646940619348801089, // 28^36 17318007155239366140, // 28^42 15544481077627229210, // 28^48 13952580675520064463, // 28^54 12523705779222565186, // 28^60 11241161050565762112, // 28^66 10089960910324183248, // 28^72 18113308885783841476, // 28^78 16258336464718499495, // 28^84 14593330587292989709, // 28^90 13098836900821174211, // 28^96 11757393360479052160, // 28^102 10553326198326110898, // 28^108 9472566787009190529, // 28^114 17004974516675479989, // 28^120 15263505912112072336, // 28^126 13700379997665963732, // 28^132 12297332812083457696, // 28^138 11037970794744924274, // 28^144 9907579239127697723, // 28^150 17785900724855568076, // 28^156 15964457964924108341, // 28^162 14329547997401095751, // 28^168 12862068117875988113, // 28^174 11544871917724549298, // 28^180 10362568941103939059, // 28^186 9301344858947275744, // 28^192 16697600117649658875, // 28^198 14987609529429357277, // 28^204 13452737987730670580, // 28^210 ]; const BASE28_LARGE_EXPONENT: [i32; 76] = [ -1217, // 28^-240 -1188, // 28^-234 -1160, // 28^-228 -1131, // 28^-222 -1102, // 28^-216 -1073, // 28^-210 -1044, // 28^-204 -1015, // 28^-198 -987, // 28^-192 -958, // 28^-186 -929, // 28^-180 -900, // 28^-174 -871, // 28^-168 -842, // 28^-162 -813, // 28^-156 -785, // 28^-150 -756, // 28^-144 -727, // 28^-138 -698, // 28^-132 -669, // 28^-126 -640, // 28^-120 -612, // 28^-114 -583, // 28^-108 -554, // 28^-102 -525, // 28^-96 -496, // 28^-90 -467, // 28^-84 -438, // 28^-78 -410, // 28^-72 -381, // 28^-66 -352, // 28^-60 -323, // 28^-54 -294, // 28^-48 -265, // 28^-42 -237, // 28^-36 -208, // 28^-30 -179, // 28^-24 -150, // 28^-18 -121, // 28^-12 -92, // 28^-6 -63, // 28^0 -35, // 28^6 -6, // 28^12 23, // 28^18 52, // 28^24 81, // 28^30 110, // 28^36 138, // 28^42 167, // 28^48 196, // 28^54 225, // 28^60 254, // 28^66 283, // 28^72 311, // 28^78 340, // 28^84 369, // 28^90 398, // 28^96 427, // 28^102 456, // 28^108 485, // 28^114 513, // 28^120 542, // 28^126 571, // 28^132 600, // 28^138 629, // 28^144 658, // 28^150 686, // 28^156 715, // 28^162 744, // 28^168 773, // 28^174 802, // 28^180 831, // 28^186 860, // 28^192 888, // 28^198 917, // 28^204 946, // 28^210 ]; const BASE28_SMALL_INT_POWERS: [u64; 6] = [1, 28, 784, 21952, 614656, 17210368]; const BASE28_STEP: i32 = 6; const BASE28_BIAS: i32 = 240; // BASE29 const BASE29_SMALL_MANTISSA: [u64; 6] = [ 9223372036854775808, // 29^0 16717361816799281152, // 29^1 15150109146474348544, // 29^2 13729786413992378368, // 29^3 12442618937680592896, // 29^4 11276123412273037312, // 29^5 ]; const BASE29_SMALL_EXPONENT: [i32; 6] = [ -63, // 29^0 -59, // 29^1 -54, // 29^2 -49, // 29^3 -44, // 29^4 -39, // 29^5 ]; const BASE29_LARGE_MANTISSA: [u64; 76] = [ 9780142334064946636, // 29^-240 10835857583212112985, // 29^-234 12005531775819627369, // 29^-228 13301466184228767173, // 29^-222 14737289938837575007, // 29^-216 16328103363438049788, // 29^-210 18090636782853846909, // 29^-204 10021713236516230810, // 29^-198 11103504802015131117, // 29^-192 12302070113036945059, // 29^-186 13630014285094069421, // 29^-180 15101303090037955289, // 29^-174 16731409831799452344, // 29^-168 9268739038298839376, // 29^-162 10269250974512215384, // 29^-156 11377762945074294339, // 29^-150 12605932989231929836, // 29^-144 13966677570638048918, // 29^-138 15474307417689145256, // 29^-132 17144678027117236568, // 29^-126 9497678206828984163, // 29^-120 10522902929736936910, // 29^-114 11658795303156142066, // 29^-108 12917301321555931503, // 29^-102 14311656487072982013, // 29^-96 15856525005124406387, // 29^-90 17568154005459773215, // 29^-84 9732272205284828726, // 29^-78 10782820124222926001, // 29^-72 11946769200332301461, // 29^-66 13236360495839591806, // 29^-60 14665156431661011058, // 29^-54 16248183421166822582, // 29^-48 18002089900515211938, // 29^-42 9972660708767378680, // 29^-36 11049157310268331325, // 29^-30 12241856093602695018, // 29^-24 13563300476969856592, // 29^-18 15027387875005778139, // 29^-12 16649515855621676607, // 29^-6 9223372036854775808, // 29^0 10218986842372440064, // 29^6 11322073062575009312, // 29^12 12544231674979455490, // 29^18 13898315921993315819, // 29^24 15398566486364679514, // 29^30 17060761258115507449, // 29^36 9451190634016324153, // 29^42 10471397266405980105, // 29^48 11601729872662437745, // 29^54 12854075976092328003, // 29^60 14241606296013212103, // 29^66 15778913262056350490, // 29^72 17482164480364512070, // 29^78 9684636382831873707, // 29^84 10730042263704319491, // 29^90 11888294245613666403, // 29^96 13171573475377840424, // 29^102 14593375990949121808, // 29^108 16168654657039833397, // 29^114 17913976421956996862, // 29^120 9923848274745194421, // 29^126 10995075829111145761, // 29^132 12181936799210906401, // 29^138 13496913207916061440, // 29^144 14953834447230017102, // 29^150 16568022719743769659, // 29^156 18356454179736676324, // 29^162 10168968734308426004, // 29^168 11266655761164621625, // 29^174 12482832365519782645, // 29^180 13830288877980342143, // 29^186 15323196278493163895, // 29^192 16977255230225892037, // 29^198 9404930600437880197, // 29^204 10420143703980341466, // 29^210 ]; const BASE29_LARGE_EXPONENT: [i32; 76] = [ -1229, // 29^-240 -1200, // 29^-234 -1171, // 29^-228 -1142, // 29^-222 -1113, // 29^-216 -1084, // 29^-210 -1055, // 29^-204 -1025, // 29^-198 -996, // 29^-192 -967, // 29^-186 -938, // 29^-180 -909, // 29^-174 -880, // 29^-168 -850, // 29^-162 -821, // 29^-156 -792, // 29^-150 -763, // 29^-144 -734, // 29^-138 -705, // 29^-132 -676, // 29^-126 -646, // 29^-120 -617, // 29^-114 -588, // 29^-108 -559, // 29^-102 -530, // 29^-96 -501, // 29^-90 -472, // 29^-84 -442, // 29^-78 -413, // 29^-72 -384, // 29^-66 -355, // 29^-60 -326, // 29^-54 -297, // 29^-48 -268, // 29^-42 -238, // 29^-36 -209, // 29^-30 -180, // 29^-24 -151, // 29^-18 -122, // 29^-12 -93, // 29^-6 -63, // 29^0 -34, // 29^6 -5, // 29^12 24, // 29^18 53, // 29^24 82, // 29^30 111, // 29^36 141, // 29^42 170, // 29^48 199, // 29^54 228, // 29^60 257, // 29^66 286, // 29^72 315, // 29^78 345, // 29^84 374, // 29^90 403, // 29^96 432, // 29^102 461, // 29^108 490, // 29^114 519, // 29^120 549, // 29^126 578, // 29^132 607, // 29^138 636, // 29^144 665, // 29^150 694, // 29^156 723, // 29^162 753, // 29^168 782, // 29^174 811, // 29^180 840, // 29^186 869, // 29^192 898, // 29^198 928, // 29^204 957, // 29^210 ]; const BASE29_SMALL_INT_POWERS: [u64; 6] = [1, 29, 841, 24389, 707281, 20511149]; const BASE29_STEP: i32 = 6; const BASE29_BIAS: i32 = 240; // BASE30 const BASE30_SMALL_MANTISSA: [u64; 6] = [ 9223372036854775808, // 30^0 17293822569102704640, // 30^1 16212958658533785600, // 30^2 15199648742375424000, // 30^3 14249670695976960000, // 30^4 13359066277478400000, // 30^5 ]; const BASE30_SMALL_EXPONENT: [i32; 6] = [ -63, // 30^0 -59, // 30^1 -54, // 30^2 -49, // 30^3 -44, // 30^4 -39, // 30^5 ]; const BASE30_LARGE_MANTISSA: [u64; 74] = [ 15921395853562858335, // 30^-234 10809579470425214363, // 30^-228 14677985448278451843, // 30^-222 9965385675239368708, // 30^-216 13531681443098000788, // 30^-210 18374241463874359754, // 30^-204 12474900136854879801, // 30^-198 16939271613521887687, // 30^-192 11500650091336533543, // 30^-186 15616368347004676150, // 30^-180 10602485877430447296, // 30^-174 14396779620362065880, // 30^-168 9774465433549085656, // 30^-162 13272436896445757604, // 30^-156 18022221508452589239, // 30^-150 12235901765210495847, // 30^-144 16614743297618723424, // 30^-138 11280316732790367097, // 30^-132 15317184660964044954, // 30^-126 10399359853791807565, // 30^-120 14120961229157126909, // 30^-114 9587202906660312336, // 30^-108 13018159044823362852, // 30^-102 17676945670836105047, // 30^-96 12001482205502242389, // 30^-90 16296432405358431306, // 30^-84 11064204595523231124, // 30^-78 15023732837543702665, // 30^-72 10200125387468709836, // 30^-66 13850427060322257636, // 30^-60 9403528018831206315, // 30^-54 12768752734601403407, // 30^-48 17338284744926585040, // 30^-42 11771553735296689434, // 30^-36 15984219821228248249, // 30^-30 10852232807944894743, // 30^-24 14735903063773789011, // 30^-18 10004707922685045925, // 30^-12 13585075876931470780, // 30^-6 9223372036854775808, // 30^0 12524124635136000000, // 30^6 17006112000000000000, // 30^12 11546030312776565551, // 30^18 15677988711770840524, // 30^24 10644322047830505987, // 30^30 14453587630518598230, // 30^36 9813034332029575584, // 30^42 13324808381590173768, // 30^48 18093335088676282534, // 30^54 12284183203843431517, // 30^60 16680303133282552614, // 30^66 11324827544542942993, // 30^72 15377624481863911156, // 30^78 10440394512637323916, // 30^84 14176680892170610158, // 30^90 9625032889090827484, // 30^96 13069527179276967861, // 30^102 17746696832949127203, // 30^108 12048838651943871501, // 30^114 16360736223435182728, // 30^120 11107862654034279481, // 30^126 15083014731837417449, // 30^132 10240373890390132852, // 30^138 13905079227116716745, // 30^144 9440633241616270046, // 30^150 12819136740897336720, // 30^156 17406699590597596894, // 30^162 11818002910861417777, // 30^168 16047291684929232224, // 30^174 10895054450550498712, // 30^180 14794049215412351417, // 30^186 10044185331124443731, // 30^192 13638680998961850032, // 30^198 9259766385185707988, // 30^204 ]; const BASE30_LARGE_EXPONENT: [i32; 74] = [ -1212, // 30^-234 -1182, // 30^-228 -1153, // 30^-222 -1123, // 30^-216 -1094, // 30^-210 -1065, // 30^-204 -1035, // 30^-198 -1006, // 30^-192 -976, // 30^-186 -947, // 30^-180 -917, // 30^-174 -888, // 30^-168 -858, // 30^-162 -829, // 30^-156 -800, // 30^-150 -770, // 30^-144 -741, // 30^-138 -711, // 30^-132 -682, // 30^-126 -652, // 30^-120 -623, // 30^-114 -593, // 30^-108 -564, // 30^-102 -535, // 30^-96 -505, // 30^-90 -476, // 30^-84 -446, // 30^-78 -417, // 30^-72 -387, // 30^-66 -358, // 30^-60 -328, // 30^-54 -299, // 30^-48 -270, // 30^-42 -240, // 30^-36 -211, // 30^-30 -181, // 30^-24 -152, // 30^-18 -122, // 30^-12 -93, // 30^-6 -63, // 30^0 -34, // 30^6 -5, // 30^12 25, // 30^18 54, // 30^24 84, // 30^30 113, // 30^36 143, // 30^42 172, // 30^48 201, // 30^54 231, // 30^60 260, // 30^66 290, // 30^72 319, // 30^78 349, // 30^84 378, // 30^90 408, // 30^96 437, // 30^102 466, // 30^108 496, // 30^114 525, // 30^120 555, // 30^126 584, // 30^132 614, // 30^138 643, // 30^144 673, // 30^150 702, // 30^156 731, // 30^162 761, // 30^168 790, // 30^174 820, // 30^180 849, // 30^186 879, // 30^192 908, // 30^198 938, // 30^204 ]; const BASE30_SMALL_INT_POWERS: [u64; 6] = [1, 30, 900, 27000, 810000, 24300000]; const BASE30_STEP: i32 = 6; const BASE30_BIAS: i32 = 234; // BASE31 const BASE31_SMALL_MANTISSA: [u64; 6] = [ 9223372036854775808, // 31^0 17870283321406128128, // 31^1 17311836967612186624, // 31^2 16770842062374305792, // 31^3 16246753247925108736, // 31^4 15739042208927449088, // 31^5 ]; const BASE31_SMALL_EXPONENT: [i32; 6] = [ -63, // 31^0 -59, // 31^1 -54, // 31^2 -49, // 31^3 -44, // 31^4 -39, // 31^5 ]; const BASE31_LARGE_MANTISSA: [u64; 74] = [ 15172192345302428421, // 31^-234 12540609161645107233, // 31^-228 10365468257053156090, // 31^-222 17135201456813756829, // 31^-216 14163138687236953263, // 31^-210 11706573627364173290, // 31^-204 9676094340331131706, // 31^-198 15995594383677739926, // 31^-192 13221193938792609146, // 31^-186 10928007110853986174, // 31^-180 18065136926019727780, // 31^-174 14931778907414090897, // 31^-168 12341894902482781431, // 31^-162 10201220546354171409, // 31^-156 16863682839241173595, // 31^-150 13938714372965575021, // 31^-144 11521075213714088050, // 31^-138 9522770215989197442, // 31^-132 15742133595063495983, // 31^-126 13011695363011784957, // 31^-120 10754845599386459585, // 31^-114 17778882864941161542, // 31^-108 14695174979700806287, // 31^-102 12146329402386737855, // 31^-96 10039575449430160254, // 31^-90 16596466614020050649, // 31^-84 13717846210614220387, // 31^-78 11338516145303865769, // 31^-72 9371875613960541536, // 31^-66 15492689060539222513, // 31^-60 12805516430937677459, // 31^-54 10584427946771654325, // 31^-48 17497164689077279120, // 31^-42 14462320197950402007, // 31^-36 11953862767183809017, // 31^-30 9880491726141866768, // 31^-24 16333484606893641287, // 31^-18 13500477850600094178, // 31^-12 11158849846261135900, // 31^-6 9223372036854775808, // 31^0 15247197139898466304, // 31^6 12602604540616796176, // 31^12 10416710674748495795, // 31^18 17219910524322248562, // 31^24 14233155154461633068, // 31^30 11764445893307051548, // 31^36 9723928789827359386, // 31^42 16074669723871456105, // 31^48 13286553836236866995, // 31^54 10982030478739077827, // 31^60 18154443194596327488, // 31^66 15005595201356001156, // 31^72 12402907923608447627, // 31^78 10251650993997756459, // 31^84 16947049635463054782, // 31^90 14007621382887632827, // 31^96 11578030455268066882, // 31^102 9569846696947249770, // 31^108 15819955934111728582, // 31^114 13076019589586139267, // 31^120 10808012931221917147, // 31^126 17866774016535005152, // 31^132 14767821605568725557, // 31^138 12206375631777172937, // 31^144 10089206793225315915, // 31^150 16678512408132988469, // 31^156 13785661343319529298, // 31^162 11394568893327831301, // 31^168 9418206136893990095, // 31^174 15569278253075119325, // 31^180 12868821397533098208, // 31^186 10636752807015729117, // 31^192 17583663147154342787, // 31^198 14533815689909759814, // 31^204 ]; const BASE31_LARGE_EXPONENT: [i32; 74] = [ -1223, // 31^-234 -1193, // 31^-228 -1163, // 31^-222 -1134, // 31^-216 -1104, // 31^-210 -1074, // 31^-204 -1044, // 31^-198 -1015, // 31^-192 -985, // 31^-186 -955, // 31^-180 -926, // 31^-174 -896, // 31^-168 -866, // 31^-162 -836, // 31^-156 -807, // 31^-150 -777, // 31^-144 -747, // 31^-138 -717, // 31^-132 -688, // 31^-126 -658, // 31^-120 -628, // 31^-114 -599, // 31^-108 -569, // 31^-102 -539, // 31^-96 -509, // 31^-90 -480, // 31^-84 -450, // 31^-78 -420, // 31^-72 -390, // 31^-66 -361, // 31^-60 -331, // 31^-54 -301, // 31^-48 -272, // 31^-42 -242, // 31^-36 -212, // 31^-30 -182, // 31^-24 -153, // 31^-18 -123, // 31^-12 -93, // 31^-6 -63, // 31^0 -34, // 31^6 -4, // 31^12 26, // 31^18 55, // 31^24 85, // 31^30 115, // 31^36 145, // 31^42 174, // 31^48 204, // 31^54 234, // 31^60 263, // 31^66 293, // 31^72 323, // 31^78 353, // 31^84 382, // 31^90 412, // 31^96 442, // 31^102 472, // 31^108 501, // 31^114 531, // 31^120 561, // 31^126 590, // 31^132 620, // 31^138 650, // 31^144 680, // 31^150 709, // 31^156 739, // 31^162 769, // 31^168 799, // 31^174 828, // 31^180 858, // 31^186 888, // 31^192 917, // 31^198 947, // 31^204 ]; const BASE31_SMALL_INT_POWERS: [u64; 6] = [1, 31, 961, 29791, 923521, 28629151]; const BASE31_STEP: i32 = 6; const BASE31_BIAS: i32 = 234; // BASE33 const BASE33_SMALL_MANTISSA: [u64; 6] = [ 9223372036854775808, // 33^0 9511602413006487552, // 33^1 9808839988412940288, // 33^2 10115366238050844672, // 33^3 10431471432989933568, // 33^4 10757454915270868992, // 33^5 ]; const BASE33_SMALL_EXPONENT: [i32; 6] = [ -63, // 33^0 -58, // 33^1 -53, // 33^2 -48, // 33^3 -43, // 33^4 -38, // 33^5 ]; const BASE33_LARGE_MANTISSA: [u64; 72] = [ 16952605037124200569, // 33^-228 10195070131008495069, // 33^-222 12262357879342609130, // 33^-216 14748836332546310936, // 33^-210 17739506162243888511, // 33^-204 10668301952265249182, // 33^-198 12831548466319904021, // 33^-192 15433443558330863109, // 33^-186 9281466718275888268, // 33^-180 11163500111543439891, // 33^-174 13427159577595330562, // 33^-168 16149828684624228128, // 33^-162 9712291160146516482, // 33^-156 11681684235978010467, // 33^-150 14050417593436164695, // 33^-144 16899466768835551431, // 33^-138 10163113486548439647, // 33^-132 12223921281461810852, // 33^-126 14702605819874780450, // 33^-120 17683901337162836029, // 33^-114 10634861953510936381, // 33^-108 12791327729538214791, // 33^-102 15385067131072375518, // 33^-96 9252373781378705800, // 33^-90 11128507904583594948, // 33^-84 13385071886268464065, // 33^-78 16099206734335173177, // 33^-72 9681847795705762071, // 33^-66 11645067770860388376, // 33^-60 14006376287807173243, // 33^-54 16846495063476347823, // 33^-48 10131257010808365886, // 33^-42 12185605163840289543, // 33^-36 14656520217639143557, // 33^-30 17628470806481188820, // 33^-24 10601526773079323099, // 33^-18 12751233065433685927, // 33^-12 15336842340660548274, // 33^-6 9223372036854775808, // 33^0 11093625381373083648, // 33^6 13343116119623879688, // 33^12 16048743459528137878, // 33^18 9651499856579507665, // 33^24 11608566080760702539, // 33^30 13962473030502269494, // 33^36 16793689398951866695, // 33^42 10099500389807484117, // 33^48 12147409148830342864, // 33^54 14610579071614836924, // 33^60 17573214023869781748, // 33^66 10568296082415350040, // 33^72 12711264078829073096, // 33^78 15288768711786753433, // 33^84 18388922397719682024, // 33^90 11058852198106072831, // 33^96 13301291864141109889, // 33^102 15998438362831755651, // 33^108 9621247043655259795, // 33^114 11572178805914439916, // 33^120 13918707388806312258, // 33^126 16741049254803901004, // 33^132 10067843310549183526, // 33^138 12109332859968012500, // 33^144 14564781929001072895, // 33^150 17518130444711929011, // 33^156 10535169553993820096, // 33^162 12671420375785822681, // 33^168 15240845770632227134, // 33^174 18331281964891256972, // 33^180 11024188012054395372, // 33^186 13259598707595875029, // 33^192 15948290948433680084, // 33^198 ]; const BASE33_LARGE_EXPONENT: [i32; 72] = [ -1214, // 33^-228 -1183, // 33^-222 -1153, // 33^-216 -1123, // 33^-210 -1093, // 33^-204 -1062, // 33^-198 -1032, // 33^-192 -1002, // 33^-186 -971, // 33^-180 -941, // 33^-174 -911, // 33^-168 -881, // 33^-162 -850, // 33^-156 -820, // 33^-150 -790, // 33^-144 -760, // 33^-138 -729, // 33^-132 -699, // 33^-126 -669, // 33^-120 -639, // 33^-114 -608, // 33^-108 -578, // 33^-102 -548, // 33^-96 -517, // 33^-90 -487, // 33^-84 -457, // 33^-78 -427, // 33^-72 -396, // 33^-66 -366, // 33^-60 -336, // 33^-54 -306, // 33^-48 -275, // 33^-42 -245, // 33^-36 -215, // 33^-30 -185, // 33^-24 -154, // 33^-18 -124, // 33^-12 -94, // 33^-6 -63, // 33^0 -33, // 33^6 -3, // 33^12 27, // 33^18 58, // 33^24 88, // 33^30 118, // 33^36 148, // 33^42 179, // 33^48 209, // 33^54 239, // 33^60 269, // 33^66 300, // 33^72 330, // 33^78 360, // 33^84 390, // 33^90 421, // 33^96 451, // 33^102 481, // 33^108 512, // 33^114 542, // 33^120 572, // 33^126 602, // 33^132 633, // 33^138 663, // 33^144 693, // 33^150 723, // 33^156 754, // 33^162 784, // 33^168 814, // 33^174 844, // 33^180 875, // 33^186 905, // 33^192 935, // 33^198 ]; const BASE33_SMALL_INT_POWERS: [u64; 6] = [1, 33, 1089, 35937, 1185921, 39135393]; const BASE33_STEP: i32 = 6; const BASE33_BIAS: i32 = 228; // BASE34 const BASE34_SMALL_MANTISSA: [u64; 6] = [ 9223372036854775808, // 34^0 9799832789158199296, // 34^1 10412322338480586752, // 34^2 11063092484635623424, // 34^3 11754535764925349888, // 34^4 12489194250233184256, // 34^5 ]; const BASE34_SMALL_EXPONENT: [i32; 6] = [ -63, // 34^0 -58, // 34^1 -53, // 34^2 -48, // 34^3 -43, // 34^4 -38, // 34^5 ]; const BASE34_LARGE_MANTISSA: [u64; 72] = [ 9604872659818954289, // 34^-228 13818638119852157632, // 34^-222 9940514895438007254, // 34^-216 14301530372152488549, // 34^-210 10287886147601198282, // 34^-204 14801297292224652053, // 34^-198 10647396286743453217, // 34^-192 15318528565264575918, // 34^-186 11019469506220361724, // 34^-180 15853834483014935870, // 34^-174 11404544822822581011, // 34^-168 16407846663860846991, // 34^-162 11803076594780713339, // 34^-156 16981218798089296108, // 34^-150 12215535057871861844, // 34^-144 17574627419191661979, // 34^-138 12642406880260427750, // 34^-132 18188772702119398880, // 34^-126 13084195736727816960, // 34^-120 9412189644717380884, // 34^-114 13541422902968601381, // 34^-108 9741098573165682574, // 34^-102 14014627870654357169, // 34^-96 10081501222766715924, // 34^-90 14504368983990906269, // 34^-84 10433799241558921201, // 34^-78 15011224098520048145, // 34^-72 10798408313169791102, // 34^-66 15535791262943115320, // 34^-60 11175758647289472494, // 34^-54 16078689424770850259, // 34^-48 11566295487283966163, // 34^-42 16640559160632214299, // 34^-36 11970479635546867736, // 34^-30 17222063432103834911, // 34^-24 12388787997209523031, // 34^-18 17823888367951909878, // 34^-12 12821714142851132552, // 34^-6 9223372036854775808, // 34^0 13269768890872758272, // 34^6 9545682734772404224, // 34^12 13733480910222387686, // 34^18 9879256578703990224, // 34^24 14213397344182222761, // 34^30 10224487159240697338, // 34^36 14710084455954213119, // 34^42 10581781820995279550, // 34^48 15224128296805573036, // 34^54 10951562143236309252, // 34^60 15756135397562640779, // 34^66 11334264437318166304, // 34^72 16306733484268988021, // 34^78 11730340261493716029, // 34^84 16876572218852198941, // 34^90 12140256953717114113, // 34^96 17466323965673246884, // 34^102 12564498183065403345, // 34^108 18076684584862935827, // 34^114 13003564520429535778, // 34^120 9354187126690740272, // 34^126 13457974029148190318, // 34^132 9681069157385005207, // 34^138 13928262876281286641, // 34^144 10019374079298318020, // 34^150 14414985965244449544, // 34^156 10369501065317377529, // 34^162 14918717590550882042, // 34^168 10731863237423767546, // 34^174 15440052115433190547, // 34^180 11106888154145020298, // 34^186 15979604673144701925, // 34^192 11495018315039655259, // 34^198 ]; const BASE34_LARGE_EXPONENT: [i32; 72] = [ -1223, // 34^-228 -1193, // 34^-222 -1162, // 34^-216 -1132, // 34^-210 -1101, // 34^-204 -1071, // 34^-198 -1040, // 34^-192 -1010, // 34^-186 -979, // 34^-180 -949, // 34^-174 -918, // 34^-168 -888, // 34^-162 -857, // 34^-156 -827, // 34^-150 -796, // 34^-144 -766, // 34^-138 -735, // 34^-132 -705, // 34^-126 -674, // 34^-120 -643, // 34^-114 -613, // 34^-108 -582, // 34^-102 -552, // 34^-96 -521, // 34^-90 -491, // 34^-84 -460, // 34^-78 -430, // 34^-72 -399, // 34^-66 -369, // 34^-60 -338, // 34^-54 -308, // 34^-48 -277, // 34^-42 -247, // 34^-36 -216, // 34^-30 -186, // 34^-24 -155, // 34^-18 -125, // 34^-12 -94, // 34^-6 -63, // 34^0 -33, // 34^6 -2, // 34^12 28, // 34^18 59, // 34^24 89, // 34^30 120, // 34^36 150, // 34^42 181, // 34^48 211, // 34^54 242, // 34^60 272, // 34^66 303, // 34^72 333, // 34^78 364, // 34^84 394, // 34^90 425, // 34^96 455, // 34^102 486, // 34^108 516, // 34^114 547, // 34^120 578, // 34^126 608, // 34^132 639, // 34^138 669, // 34^144 700, // 34^150 730, // 34^156 761, // 34^162 791, // 34^168 822, // 34^174 852, // 34^180 883, // 34^186 913, // 34^192 944, // 34^198 ]; const BASE34_SMALL_INT_POWERS: [u64; 6] = [1, 34, 1156, 39304, 1336336, 45435424]; const BASE34_STEP: i32 = 6; const BASE34_BIAS: i32 = 228; // BASE35 const BASE35_SMALL_MANTISSA: [u64; 6] = [ 9223372036854775808, // 35^0 10088063165309911040, // 35^1 11033819087057715200, // 35^2 12068239626469376000, // 35^3 13199637091450880000, // 35^4 14437103068774400000, // 35^5 ]; const BASE35_SMALL_EXPONENT: [i32; 6] = [ -63, // 35^0 -58, // 35^1 -53, // 35^2 -48, // 35^3 -43, // 35^4 -38, // 35^5 ]; const BASE35_LARGE_MANTISSA: [u64; 71] = [ 11348773864264802781, // 35^-222 9714654125541636184, // 35^-216 16631665395337738380, // 35^-210 14236857547774631404, // 35^-204 12186880148060573338, // 35^-198 10432080762542161338, // 35^-192 17859912908640730010, // 35^-186 15288248642090717076, // 35^-180 13086880531724678972, // 35^-174 11202489314578100722, // 35^-168 9589433214356533221, // 35^-162 16417284907013989533, // 35^-156 14053345890899718904, // 35^-150 12029792492965214691, // 35^-144 10297612294415481616, // 35^-138 17629700433836653197, // 35^-132 15091184660126225295, // 35^-126 12918191962520288360, // 35^-120 11058090357972464737, // 35^-114 9465826388078148767, // 35^-108 16205667761547463659, // 35^-102 13872199680760223069, // 35^-96 11874729681889289960, // 35^-90 10164877111271147984, // 35^-84 17402455374597619654, // 35^-78 14896660812999728329, // 35^-72 12751677771947325078, // 35^-66 10915552689343391453, // 35^-60 9343812841314943660, // 35^-54 15996778339727633381, // 35^-48 13693388426986467236, // 35^-42 11721665614797754707, // 35^-36 10033852871240677221, // 35^-30 17178139481236495112, // 35^-24 14704644358629538426, // 35^-18 12587309932484688516, // 35^-12 10774852316876721446, // 35^-6 9223372036854775808, // 35^0 15790581481472000000, // 35^6 13516882032226562500, // 35^12 11570574528082381959, // 35^18 9904517520440015906, // 35^24 16956714997100751955, // 35^30 14515102976976096155, // 35^36 12425060777883196253, // 35^42 10635965558010358334, // 35^48 18208967404416189641, // 35^54 15587042479907979542, // 35^60 13342650787080448100, // 35^66 11421430990225254489, // 35^72 9776849289257450184, // 35^78 16738144652217302890, // 35^84 14328004764601889967, // 35^90 12264902998508825496, // 35^96 10498869035448040891, // 35^102 17974255652391389054, // 35^108 15386127075531072702, // 35^114 13170665365099231511, // 35^120 11274209897518154234, // 35^126 9650826688689364000, // 35^132 16522391657019252092, // 35^138 14143318229301497845, // 35^144 12106809636745979660, // 35^150 10363539673224497244, // 35^156 17742569311160898016, // 35^162 15187801450438335382, // 35^168 13000896817848986534, // 35^174 11128886469837128365, // 35^180 9526428506723229038, // 35^186 16309419696153507876, // 35^192 13961012284800847178, // 35^198 ]; const BASE35_LARGE_EXPONENT: [i32; 71] = [ -1202, // 35^-222 -1171, // 35^-216 -1141, // 35^-210 -1110, // 35^-204 -1079, // 35^-198 -1048, // 35^-192 -1018, // 35^-186 -987, // 35^-180 -956, // 35^-174 -925, // 35^-168 -894, // 35^-162 -864, // 35^-156 -833, // 35^-150 -802, // 35^-144 -771, // 35^-138 -741, // 35^-132 -710, // 35^-126 -679, // 35^-120 -648, // 35^-114 -617, // 35^-108 -587, // 35^-102 -556, // 35^-96 -525, // 35^-90 -494, // 35^-84 -464, // 35^-78 -433, // 35^-72 -402, // 35^-66 -371, // 35^-60 -340, // 35^-54 -310, // 35^-48 -279, // 35^-42 -248, // 35^-36 -217, // 35^-30 -187, // 35^-24 -156, // 35^-18 -125, // 35^-12 -94, // 35^-6 -63, // 35^0 -33, // 35^6 -2, // 35^12 29, // 35^18 60, // 35^24 90, // 35^30 121, // 35^36 152, // 35^42 183, // 35^48 213, // 35^54 244, // 35^60 275, // 35^66 306, // 35^72 337, // 35^78 367, // 35^84 398, // 35^90 429, // 35^96 460, // 35^102 490, // 35^108 521, // 35^114 552, // 35^120 583, // 35^126 614, // 35^132 644, // 35^138 675, // 35^144 706, // 35^150 737, // 35^156 767, // 35^162 798, // 35^168 829, // 35^174 860, // 35^180 891, // 35^186 921, // 35^192 952, // 35^198 ]; const BASE35_SMALL_INT_POWERS: [u64; 6] = [1, 35, 1225, 42875, 1500625, 52521875]; const BASE35_STEP: i32 = 6; const BASE35_BIAS: i32 = 222; // BASE36 const BASE36_SMALL_MANTISSA: [u64; 6] = [ 9223372036854775808, // 36^0 10376293541461622784, // 36^1 11673330234144325632, // 36^2 13132496513412366336, // 36^3 14774058577588912128, // 36^4 16620815899787526144, // 36^5 ]; const BASE36_SMALL_EXPONENT: [i32; 6] = [ -63, // 36^0 -58, // 36^1 -53, // 36^2 -48, // 36^3 -43, // 36^4 -38, // 36^5 ]; const BASE36_LARGE_MANTISSA: [u64; 71] = [ 11172994339528645078, // 36^-222 11325430459582219446, // 36^-216 11479946305982273645, // 36^-210 11636570252986002899, // 36^-204 11795331061968106016, // 36^-198 11956257886702331980, // 36^-192 12119380278715084095, // 36^-186 12284728192712064755, // 36^-180 12452331992078957377, // 36^-174 12622222454457155586, // 36^-168 12794430777395563548, // 36^-162 12968988584079505325, // 36^-156 13145927929137795237, // 36^-150 13325281304529035642, // 36^-144 13507081645508223020, // 36^-138 13691362336674758052, // 36^-132 13878157218102970303, // 36^-126 14067500591556283265, // 36^-120 14259427226786160917, // 36^-114 14453972367916992462, // 36^-108 14651171739918087751, // 36^-102 14851061555163971849, // 36^-96 15053678520084183432, // 36^-90 15259059841903798156, // 36^-84 15467243235475914756, // 36^-78 15678266930207358578, // 36^-72 15892169677078874302, // 36^-66 16108990755761097026, // 36^-60 16328769981827608423, // 36^-54 16551547714066402526, // 36^-48 16777364861891103792, // 36^-42 17006262892853298360, // 36^-36 17238283840257358043, // 36^-30 17473470310879155380, // 36^-24 17711865492790087155, // 36^-18 17953513163287843146, // 36^-12 18198457696935376453, // 36^-6 9223372036854775808, // 36^0 9349208943630483456, // 36^6 9476762676643233792, // 36^12 9606056659007943744, // 36^18 9737114633407288801, // 36^24 9869960666451650558, // 36^30 10004619153098548172, // 36^36 10141114821132365302, // 36^42 10279472735705195138, // 36^48 10419718303939637392, // 36^54 10561877279594392463, // 36^60 10705975767793509530, // 36^66 10852040229820157048, // 36^72 11000097487975795902, // 36^78 11150174730505647564, // 36^84 11302299516591361707, // 36^90 11456499781411800112, // 36^96 11612803841272866179, // 36^102 11771240398807322073, // 36^108 11931838548245548344, // 36^114 12094627780758213915, // 36^120 12259637989871837542, // 36^126 12426899476958235198, // 36^132 12596442956798861450, // 36^138 12768299563225066619, // 36^144 12942500854835305460, // 36^150 13119078820790347231, // 36^156 13298065886687551351, // 36^162 13479494920515287357, // 36^168 13663399238688592583, // 36^174 13849812612167175924, // 36^180 14038769272656891137, // 36^186 14230303918895818486, // 36^192 14424451723026109070, // 36^198 ]; const BASE36_LARGE_EXPONENT: [i32; 71] = [ -1211, // 36^-222 -1180, // 36^-216 -1149, // 36^-210 -1118, // 36^-204 -1087, // 36^-198 -1056, // 36^-192 -1025, // 36^-186 -994, // 36^-180 -963, // 36^-174 -932, // 36^-168 -901, // 36^-162 -870, // 36^-156 -839, // 36^-150 -808, // 36^-144 -777, // 36^-138 -746, // 36^-132 -715, // 36^-126 -684, // 36^-120 -653, // 36^-114 -622, // 36^-108 -591, // 36^-102 -560, // 36^-96 -529, // 36^-90 -498, // 36^-84 -467, // 36^-78 -436, // 36^-72 -405, // 36^-66 -374, // 36^-60 -343, // 36^-54 -312, // 36^-48 -281, // 36^-42 -250, // 36^-36 -219, // 36^-30 -188, // 36^-24 -157, // 36^-18 -126, // 36^-12 -95, // 36^-6 -63, // 36^0 -32, // 36^6 -1, // 36^12 30, // 36^18 61, // 36^24 92, // 36^30 123, // 36^36 154, // 36^42 185, // 36^48 216, // 36^54 247, // 36^60 278, // 36^66 309, // 36^72 340, // 36^78 371, // 36^84 402, // 36^90 433, // 36^96 464, // 36^102 495, // 36^108 526, // 36^114 557, // 36^120 588, // 36^126 619, // 36^132 650, // 36^138 681, // 36^144 712, // 36^150 743, // 36^156 774, // 36^162 805, // 36^168 836, // 36^174 867, // 36^180 898, // 36^186 929, // 36^192 960, // 36^198 ]; const BASE36_SMALL_INT_POWERS: [u64; 6] = [1, 36, 1296, 46656, 1679616, 60466176]; const BASE36_STEP: i32 = 6; const BASE36_BIAS: i32 = 222; }} // cfg_if // HIGH LEVEL // ---------- pub(crate) const BASE10_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE10_SMALL_MANTISSA, exp: &BASE10_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE10_LARGE_MANTISSA, exp: &BASE10_LARGE_EXPONENT }, small_int: &BASE10_SMALL_INT_POWERS, step: BASE10_STEP, bias: BASE10_BIAS, }; cfg_if! { if #[cfg(feature = "radix")] { pub(crate) const BASE3_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE3_SMALL_MANTISSA, exp: &BASE3_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE3_LARGE_MANTISSA, exp: &BASE3_LARGE_EXPONENT }, small_int: &BASE3_SMALL_INT_POWERS, step: BASE3_STEP, bias: BASE3_BIAS, }; pub(crate) const BASE5_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE5_SMALL_MANTISSA, exp: &BASE5_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE5_LARGE_MANTISSA, exp: &BASE5_LARGE_EXPONENT }, small_int: &BASE5_SMALL_INT_POWERS, step: BASE5_STEP, bias: BASE5_BIAS, }; pub(crate) const BASE6_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE6_SMALL_MANTISSA, exp: &BASE6_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE6_LARGE_MANTISSA, exp: &BASE6_LARGE_EXPONENT }, small_int: &BASE6_SMALL_INT_POWERS, step: BASE6_STEP, bias: BASE6_BIAS, }; pub(crate) const BASE7_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE7_SMALL_MANTISSA, exp: &BASE7_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE7_LARGE_MANTISSA, exp: &BASE7_LARGE_EXPONENT }, small_int: &BASE7_SMALL_INT_POWERS, step: BASE7_STEP, bias: BASE7_BIAS, }; pub(crate) const BASE9_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE9_SMALL_MANTISSA, exp: &BASE9_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE9_LARGE_MANTISSA, exp: &BASE9_LARGE_EXPONENT }, small_int: &BASE9_SMALL_INT_POWERS, step: BASE9_STEP, bias: BASE9_BIAS, }; pub(crate) const BASE11_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE11_SMALL_MANTISSA, exp: &BASE11_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE11_LARGE_MANTISSA, exp: &BASE11_LARGE_EXPONENT }, small_int: &BASE11_SMALL_INT_POWERS, step: BASE11_STEP, bias: BASE11_BIAS, }; pub(crate) const BASE12_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE12_SMALL_MANTISSA, exp: &BASE12_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE12_LARGE_MANTISSA, exp: &BASE12_LARGE_EXPONENT }, small_int: &BASE12_SMALL_INT_POWERS, step: BASE12_STEP, bias: BASE12_BIAS, }; pub(crate) const BASE13_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE13_SMALL_MANTISSA, exp: &BASE13_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE13_LARGE_MANTISSA, exp: &BASE13_LARGE_EXPONENT }, small_int: &BASE13_SMALL_INT_POWERS, step: BASE13_STEP, bias: BASE13_BIAS, }; pub(crate) const BASE14_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE14_SMALL_MANTISSA, exp: &BASE14_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE14_LARGE_MANTISSA, exp: &BASE14_LARGE_EXPONENT }, small_int: &BASE14_SMALL_INT_POWERS, step: BASE14_STEP, bias: BASE14_BIAS, }; pub(crate) const BASE15_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE15_SMALL_MANTISSA, exp: &BASE15_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE15_LARGE_MANTISSA, exp: &BASE15_LARGE_EXPONENT }, small_int: &BASE15_SMALL_INT_POWERS, step: BASE15_STEP, bias: BASE15_BIAS, }; pub(crate) const BASE17_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE17_SMALL_MANTISSA, exp: &BASE17_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE17_LARGE_MANTISSA, exp: &BASE17_LARGE_EXPONENT }, small_int: &BASE17_SMALL_INT_POWERS, step: BASE17_STEP, bias: BASE17_BIAS, }; pub(crate) const BASE18_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE18_SMALL_MANTISSA, exp: &BASE18_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE18_LARGE_MANTISSA, exp: &BASE18_LARGE_EXPONENT }, small_int: &BASE18_SMALL_INT_POWERS, step: BASE18_STEP, bias: BASE18_BIAS, }; pub(crate) const BASE19_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE19_SMALL_MANTISSA, exp: &BASE19_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE19_LARGE_MANTISSA, exp: &BASE19_LARGE_EXPONENT }, small_int: &BASE19_SMALL_INT_POWERS, step: BASE19_STEP, bias: BASE19_BIAS, }; pub(crate) const BASE20_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE20_SMALL_MANTISSA, exp: &BASE20_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE20_LARGE_MANTISSA, exp: &BASE20_LARGE_EXPONENT }, small_int: &BASE20_SMALL_INT_POWERS, step: BASE20_STEP, bias: BASE20_BIAS, }; pub(crate) const BASE21_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE21_SMALL_MANTISSA, exp: &BASE21_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE21_LARGE_MANTISSA, exp: &BASE21_LARGE_EXPONENT }, small_int: &BASE21_SMALL_INT_POWERS, step: BASE21_STEP, bias: BASE21_BIAS, }; pub(crate) const BASE22_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE22_SMALL_MANTISSA, exp: &BASE22_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE22_LARGE_MANTISSA, exp: &BASE22_LARGE_EXPONENT }, small_int: &BASE22_SMALL_INT_POWERS, step: BASE22_STEP, bias: BASE22_BIAS, }; pub(crate) const BASE23_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE23_SMALL_MANTISSA, exp: &BASE23_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE23_LARGE_MANTISSA, exp: &BASE23_LARGE_EXPONENT }, small_int: &BASE23_SMALL_INT_POWERS, step: BASE23_STEP, bias: BASE23_BIAS, }; pub(crate) const BASE24_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE24_SMALL_MANTISSA, exp: &BASE24_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE24_LARGE_MANTISSA, exp: &BASE24_LARGE_EXPONENT }, small_int: &BASE24_SMALL_INT_POWERS, step: BASE24_STEP, bias: BASE24_BIAS, }; pub(crate) const BASE25_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE25_SMALL_MANTISSA, exp: &BASE25_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE25_LARGE_MANTISSA, exp: &BASE25_LARGE_EXPONENT }, small_int: &BASE25_SMALL_INT_POWERS, step: BASE25_STEP, bias: BASE25_BIAS, }; pub(crate) const BASE26_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE26_SMALL_MANTISSA, exp: &BASE26_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE26_LARGE_MANTISSA, exp: &BASE26_LARGE_EXPONENT }, small_int: &BASE26_SMALL_INT_POWERS, step: BASE26_STEP, bias: BASE26_BIAS, }; pub(crate) const BASE27_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE27_SMALL_MANTISSA, exp: &BASE27_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE27_LARGE_MANTISSA, exp: &BASE27_LARGE_EXPONENT }, small_int: &BASE27_SMALL_INT_POWERS, step: BASE27_STEP, bias: BASE27_BIAS, }; pub(crate) const BASE28_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE28_SMALL_MANTISSA, exp: &BASE28_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE28_LARGE_MANTISSA, exp: &BASE28_LARGE_EXPONENT }, small_int: &BASE28_SMALL_INT_POWERS, step: BASE28_STEP, bias: BASE28_BIAS, }; pub(crate) const BASE29_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE29_SMALL_MANTISSA, exp: &BASE29_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE29_LARGE_MANTISSA, exp: &BASE29_LARGE_EXPONENT }, small_int: &BASE29_SMALL_INT_POWERS, step: BASE29_STEP, bias: BASE29_BIAS, }; pub(crate) const BASE30_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE30_SMALL_MANTISSA, exp: &BASE30_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE30_LARGE_MANTISSA, exp: &BASE30_LARGE_EXPONENT }, small_int: &BASE30_SMALL_INT_POWERS, step: BASE30_STEP, bias: BASE30_BIAS, }; pub(crate) const BASE31_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE31_SMALL_MANTISSA, exp: &BASE31_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE31_LARGE_MANTISSA, exp: &BASE31_LARGE_EXPONENT }, small_int: &BASE31_SMALL_INT_POWERS, step: BASE31_STEP, bias: BASE31_BIAS, }; pub(crate) const BASE33_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE33_SMALL_MANTISSA, exp: &BASE33_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE33_LARGE_MANTISSA, exp: &BASE33_LARGE_EXPONENT }, small_int: &BASE33_SMALL_INT_POWERS, step: BASE33_STEP, bias: BASE33_BIAS, }; pub(crate) const BASE34_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE34_SMALL_MANTISSA, exp: &BASE34_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE34_LARGE_MANTISSA, exp: &BASE34_LARGE_EXPONENT }, small_int: &BASE34_SMALL_INT_POWERS, step: BASE34_STEP, bias: BASE34_BIAS, }; pub(crate) const BASE35_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE35_SMALL_MANTISSA, exp: &BASE35_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE35_LARGE_MANTISSA, exp: &BASE35_LARGE_EXPONENT }, small_int: &BASE35_SMALL_INT_POWERS, step: BASE35_STEP, bias: BASE35_BIAS, }; pub(crate) const BASE36_POWERS: ModeratePathPowers = ModeratePathPowers { small: ExtendedFloatArray { mant: &BASE36_SMALL_MANTISSA, exp: &BASE36_SMALL_EXPONENT }, large: ExtendedFloatArray { mant: &BASE36_LARGE_MANTISSA, exp: &BASE36_LARGE_EXPONENT }, small_int: &BASE36_SMALL_INT_POWERS, step: BASE36_STEP, bias: BASE36_BIAS, }; }} // cfg_if /// Get powers from base. pub(crate) fn get_powers(radix: u32) -> &'static ModeratePathPowers { debug_assert_radix!(radix); #[cfg(not(feature = "radix"))] { &BASE10_POWERS } #[cfg(feature = "radix")] { match radix { 3 => &BASE3_POWERS, 5 => &BASE5_POWERS, 6 => &BASE6_POWERS, 7 => &BASE7_POWERS, 9 => &BASE9_POWERS, 10 => &BASE10_POWERS, 11 => &BASE11_POWERS, 12 => &BASE12_POWERS, 13 => &BASE13_POWERS, 14 => &BASE14_POWERS, 15 => &BASE15_POWERS, 17 => &BASE17_POWERS, 18 => &BASE18_POWERS, 19 => &BASE19_POWERS, 20 => &BASE20_POWERS, 21 => &BASE21_POWERS, 22 => &BASE22_POWERS, 23 => &BASE23_POWERS, 24 => &BASE24_POWERS, 25 => &BASE25_POWERS, 26 => &BASE26_POWERS, 27 => &BASE27_POWERS, 28 => &BASE28_POWERS, 29 => &BASE29_POWERS, 30 => &BASE30_POWERS, 31 => &BASE31_POWERS, 33 => &BASE33_POWERS, 34 => &BASE34_POWERS, 35 => &BASE35_POWERS, 36 => &BASE36_POWERS, // Powers of 2, and others, should already be handled by now. _ => unreachable!(), } } } // TESTS // ----- #[cfg(test)] mod tests { use crate::util::test::*; use super::*; #[test] fn normalization_test() { // Ensure each valid is normalized. for base in BASE_POWN.iter().cloned() { let powers = get_powers(base); for idx in 0..powers.small.len() { let fp = powers.get_small(idx); assert_eq!(fp.mant.leading_zeros(), 0); } for idx in 0..powers.large.len() { let fp = powers.get_large(idx); assert_eq!(fp.mant.leading_zeros(), 0); } } } #[cfg(feature = "radix")] #[test] #[should_panic] fn pow2_test() { for base in BASE_POW2.iter().cloned() { let _ = get_powers(base); } } } lexical-core-0.7.6/src/atof/algorithm/correct.rs000075500000000000000000001332150000000000000177070ustar 00000000000000//! Correct algorithms for string-to-float conversions. //! //! This implementation is loosely based off the Golang implementation, //! found here: //! https://golang.org/src/strconv/atof.go use crate::atoi; use crate::float::*; use crate::util::*; use super::alias::*; use super::bhcomp; use super::cached::ModeratePathCache; use super::errors::FloatErrors; use super::format::*; use super::small_powers::get_small_powers_64; // HELPERS // ------- // Parse the raw float state into a mantissa, calculating the number // of truncated digits and the offset. perftools_inline!{ fn process_mantissa<'a, M, Data>(data: &Data, radix: u32) -> (M, usize) where M: Mantissa, Data: FastDataInterface<'a> { atoi::standalone_mantissa(data.integer_iter(), data.fraction_iter(), radix) }} // FAST // ---- // POWN /// Convert mantissa to exact value for a non-base2 power. /// /// Returns the resulting float and if the value can be represented exactly. fn fast_path(mantissa: u64, radix: u32, exponent: i32) -> Option where F: FloatType { debug_assert_radix!(radix); debug_assert!(pow2_exponent(radix) == 0, "Cannot use `fast_path` with a power of 2."); // `mantissa >> (F::MANTISSA_SIZE+1) != 0` effectively checks if the // value has a no bits above the hidden bit, which is what we want. let (min_exp, max_exp) = F::exponent_limit(radix); let shift_exp = F::mantissa_limit(radix); let mantissa_size = F::MANTISSA_SIZE + 1; if mantissa >> mantissa_size != 0 { // Would require truncation of the mantissa. None } else if exponent == 0 { // 0 exponent, same as value, exact representation. let float: F = as_cast(mantissa); Some(float) } else if exponent >= min_exp && exponent <= max_exp { // Value can be exactly represented, return the value. // Use powi, since it's correct, and faster on // the fast-path. let float: F = as_cast(mantissa); Some(float.pow(radix, exponent)) } else if exponent >= 0 && exponent <= max_exp + shift_exp { // Check to see if we have a disguised fast-path, where the // number of digits in the mantissa is very small, but and // so digits can be shifted from the exponent to the mantissa. // https://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ let small_powers = get_small_powers_64(radix); let shift = exponent - max_exp; let power = small_powers[shift.as_usize()]; // Compute the product of the power, if it overflows, // prematurely return early, otherwise, if we didn't overshoot, // we can get an exact value. let value = mantissa.checked_mul(power)?; if value >> mantissa_size != 0 { None } else { // Use powi, since it's correct, and faster on // the fast-path. let float: F = as_cast(value); Some(float.pow(radix, max_exp)) } } else { // Cannot be exactly represented, exponent too small or too big, // would require truncation. None } } // POW2 // Detect if a float representation is exactly halfway after truncation. #[cfg(feature = "radix")] perftools_inline!{ fn is_halfway(mantissa: u64) -> bool { // Get the leading and trailing zeros from the least-significant bit. let bit_length: i32 = 64 - mantissa.leading_zeros().as_i32(); let trailing_zeros: i32 = mantissa.trailing_zeros().as_i32(); // We need exactly mantissa+2 elements between these if it is halfway. // The hidden bit is mantissa+1 elements away, which is the last non- // truncated bit, while mantissa+2 bit_length - trailing_zeros == F::MANTISSA_SIZE + 2 }} // Detect if a float representation is odd after truncation. #[cfg(feature = "radix")] perftools_inline!{ fn is_odd(mantissa: u64) -> bool { // Get the leading and trailing zeros from the least-significant bit. let bit_length: i32 = 64 - mantissa.leading_zeros().as_i32(); let shift = bit_length - (F::MANTISSA_SIZE + 1); if shift >= 0 { // Have enough bits to have a full mantissa in the float, need to // check if that last bit is set. let mask = 1u64 << shift; mantissa & mask == mask } else { // Not enough bits for a full mantissa, must be even. false } }} /// Convert power-of-two to exact value. /// /// We will always get an exact representation. /// /// This works since multiplying by the exponent will not affect the /// mantissa unless the exponent is denormal, which will cause truncation /// regardless. #[cfg(feature = "radix")] fn pow2_fast_path(mantissa: u64, radix: u32, pow2_exp: i32, exponent: i32) -> F where F: FloatType { debug_assert!(pow2_exp != 0, "Not a power of 2."); // As long as the value is within the bounds, we can get an exact value. // Since any power of 2 only affects the exponent, we should be able to get // any exact value. // We know that if any value is > than max_exp, we get infinity, since // the mantissa must be positive. We know that the actual value that // causes underflow is 64, use 65 since that prevents inaccurate // rounding for any pow2_exp. let (min_exp, max_exp) = F::exponent_limit(radix); let underflow_exp = min_exp - (65 / pow2_exp); if exponent > max_exp { F::INFINITY } else if exponent < underflow_exp{ F::ZERO } else if exponent < min_exp { // We know the mantissa is somewhere <= 65 below min_exp. // May still underflow, but it's close. Use the first multiplication // which guarantees no truncation, and then the second multiplication // which will round to the accurate representation. let remainder = exponent - min_exp; let float: F = as_cast(mantissa); let float = float.pow2(pow2_exp * remainder).pow2(pow2_exp * min_exp); float } else { let float: F = as_cast(mantissa); let float = float.pow2(pow2_exp * exponent); float } } // MODERATE // -------- /// Multiply the floating-point by the exponent. /// /// Multiply by pre-calculated powers of the base, modify the extended- /// float, and return if new value and if the value can be represented /// accurately. fn multiply_exponent_extended(fp: &mut ExtendedFloat, radix: u32, exponent: i32, truncated: bool, kind: RoundingKind) -> bool where M: FloatErrors, F: FloatRounding, ExtendedFloat: ModeratePathCache { let powers = ExtendedFloat::::get_powers(radix); let exponent = exponent.saturating_add(powers.bias); let small_index = exponent % powers.step; let large_index = exponent / powers.step; if exponent < 0 { // Guaranteed underflow (assign 0). fp.mant = M::ZERO; true } else if large_index as usize >= powers.large.len() { // Overflow (assign infinity) fp.mant = M::ONE << 63; fp.exp = 0x7FF; true } else { // Within the valid exponent range, multiply by the large and small // exponents and return the resulting value. // Track errors to as a factor of unit in last-precision. let mut errors: u32 = 0; if truncated { errors += M::error_halfscale(); } // Multiply by the small power. // Check if we can directly multiply by an integer, if not, // use extended-precision multiplication. match fp.mant.overflowing_mul(powers.get_small_int(small_index.as_usize())) { // Overflow, multiplication unsuccessful, go slow path. (_, true) => { fp.normalize(); fp.imul(&powers.get_small(small_index.as_usize())); errors += M::error_halfscale(); }, // No overflow, multiplication successful. (mant, false) => { fp.mant = mant; fp.normalize(); }, } // Multiply by the large power fp.imul(&powers.get_large(large_index.as_usize())); if errors > 0 { errors += 1; } errors += M::error_halfscale(); // Normalize the floating point (and the errors). let shift = fp.normalize(); errors <<= shift; M::error_is_accurate::(errors, &fp, kind) } } // Create a precise native float using an intermediate extended-precision float. // // Return the float approximation and if the value can be accurately // represented with mantissa bits of precision. perftools_inline_always!{ pub(super) fn moderate_path(mantissa: M, radix: u32, exponent: i32, truncated: bool, kind: RoundingKind) -> (ExtendedFloat, bool) where M: FloatErrors, F: FloatRounding + StablePower, ExtendedFloat: ModeratePathCache { let mut fp = ExtendedFloat { mant: mantissa, exp: 0 }; let valid = multiply_exponent_extended::(&mut fp, radix, exponent, truncated, kind); (fp, valid) }} // TO NATIVE // --------- // POWN /// Fallback method. Do not inline so the stack requirements only occur /// if required. fn pown_fallback<'a, F, Data>(data: Data, mantissa: u64, radix: u32, lossy: bool, sign: Sign) -> F where F: FloatType, Data: SlowDataInterface<'a> { let kind = global_rounding(sign); // Moderate path (use an extended 80-bit representation). let exponent = data.mantissa_exponent(); let is_truncated = data.truncated_digits() != 0; let (fp, valid) = moderate_path::(mantissa, radix, exponent, is_truncated, kind); if valid || lossy { let float = fp.into_rounded_float_impl::(kind); return float; } // Slow path let b = fp.into_rounded_float_impl::(RoundingKind::Downward); if b.is_special() { // We have a non-finite number, we get to leave early. return b; } else { let float = bhcomp::atof(data, radix, b, kind); return float; } } /// Parse non-power-of-two radix string to native float. fn pown_to_native<'a, F, Data>(mut data: Data, bytes: &'a [u8], radix: u32, lossy: bool, sign: Sign) -> ParseResult<(F, *const u8)> where F: FloatType, Data: FastDataInterface<'a> { // Parse the mantissa and exponent. let ptr = data.extract(bytes, radix)?; let (mantissa, truncated) = process_mantissa::(&data, radix); // Process the state to a float. let float = if mantissa.is_zero() { // Literal 0, return early. // Value cannot be truncated, since truncation only occurs on // overflow or underflow. F::ZERO } else if truncated.is_zero() { // Try the fast path, no mantissa truncation. let mant_exp = data.mantissa_exponent(0); if let Some(float) = fast_path::(mantissa, radix, mant_exp) { float } else { let slow = data.to_slow(truncated); pown_fallback(slow, mantissa, radix, lossy, sign) } } else { // Can only use the moderate/slow path. let slow = data.to_slow(truncated); pown_fallback(slow, mantissa, radix, lossy, sign) }; Ok((float, ptr)) } // POW2 /// Parse power-of-two radix string to native float. #[cfg(feature = "radix")] fn pow2_to_native<'a, F, Data>(mut data: Data, bytes: &'a [u8], radix: u32, pow2_exp: i32, sign: Sign) -> ParseResult<(F, *const u8)> where F: FloatType, Data: FastDataInterface<'a> { // Parse the mantissa and exponent. let ptr = data.extract(bytes, radix)?; let (mut mantissa, truncated) = process_mantissa::(&data, radix); // We have a power of 2, can get an exact value even if the mantissa // was truncated. Check to see if there are any truncated digits, depending // on our rounding scheme. let mantissa_size = F::MANTISSA_SIZE + 1; let float = if !truncated.is_zero() { // Truncated mantissa. let kind = global_rounding(sign); let slow = data.to_slow(truncated); if kind != RoundingKind::Downward { if cfg!(feature = "rounding") || kind == RoundingKind::NearestTieEven { // Need to check if we're exactly halfway and if there are truncated digits. if is_halfway::(mantissa) && is_odd::(mantissa) { mantissa += 1; } } else if kind == RoundingKind::NearestTieAwayZero { // Need to check if we're exactly halfway and if there are truncated digits. if is_halfway::(mantissa) { mantissa += 1; } } else { // Need to check if there are any bytes present. // Check if there were any truncated bytes. let index = slow.mantissa_digits() - slow.truncated_digits(); let iter = slow.integer_iter().chain(slow.fraction_iter()).skip(index); let count = iter.take_while(|&&c| c == b'0').count(); let is_truncated = count < slow.truncated_digits(); if is_truncated { mantissa += 1; } } } // Create exact representation and return. let exponent = slow.mantissa_exponent().saturating_mul(pow2_exp); let fp = ExtendedFloat { mant: mantissa, exp: exponent }; fp.into_rounded_float_impl::(kind) } else if mantissa >> mantissa_size != 0 { // Would be truncated, use the extended float. let kind = global_rounding(sign); let slow = data.to_slow(truncated); let exponent = slow.mantissa_exponent().saturating_mul(pow2_exp); let fp = ExtendedFloat { mant: mantissa, exp: exponent }; fp.into_rounded_float_impl::(kind) } else { // Nothing above the hidden bit, so no rounding-error, can use the fast path. let mant_exp = data.mantissa_exponent(0); pow2_fast_path(mantissa, radix, pow2_exp, mant_exp) }; Ok((float, ptr)) } // Check if value is power of 2 and get the power. perftools_inline!{ fn pow2_exponent(radix: u32) -> i32 { match radix { 2 => 1, 4 => 2, 8 => 3, 16 => 4, 32 => 5, _ => 0, } }} // DISPATCHER // Parse native float from string. // // The float string must be non-special, non-zero, and positive. perftools_inline!{ fn to_native(bytes: &[u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(F, *const u8)> where F: FloatType { #[cfg(not(feature = "radix"))] { apply_interface!(pown_to_native, format, bytes, radix, lossy, sign) } #[cfg(feature = "radix")] { let pow2_exp = pow2_exponent(radix); match pow2_exp { 0 => apply_interface!(pown_to_native, format, bytes, radix, lossy, sign), _ => apply_interface!(pow2_to_native, format, bytes, radix, pow2_exp, sign) } } }} // ATOF/ATOD // --------- // Parse 32-bit float from string. perftools_inline!{ pub(crate) fn atof(bytes: &[u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(f32, *const u8)> { to_native::(bytes, radix, lossy, sign, format) }} // Parse 64-bit float from string. perftools_inline!{ pub(crate) fn atod(bytes: &[u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(f64, *const u8)> { to_native::(bytes, radix, lossy, sign, format) }} // TESTS // ----- #[cfg(test)] mod tests { use crate::util::test::*; use super::*; #[test] fn process_mantissa_test() { type Data<'a> = StandardFastDataInterface<'a>; // 64-bits let data = (b!("1"), Some(b!("2345")), None, 0).into(); assert_eq!((12345, 0), process_mantissa::(&data, 10)); let data = (b!("12"), Some(b!("345")), None, 0).into(); assert_eq!((12345, 0), process_mantissa::(&data, 10)); let data = (b!("12345"), Some(b!("6789")), None, 0).into(); assert_eq!((123456789, 0), process_mantissa::(&data, 10)); let data = (b!("1"), Some(b!("2345")), Some(b!("10")), 10).into(); assert_eq!((12345, 0), process_mantissa::(&data, 10)); let data = (b!("100000000000000000000"), None, None, 0).into(); assert_eq!((10000000000000000000, 1), process_mantissa::(&data, 10)); let data = (b!("100000000000000000001"), None, None, 0).into(); assert_eq!((10000000000000000000, 1), process_mantissa::(&data, 10)); let data = (b!("179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791"), Some(b!("9999999999999999999999999999999999999999999999999999999999999999999999")), None, 0).into(); assert_eq!((17976931348623158079, 359), process_mantissa::(&data, 10)); let data = (b!("1009"), None, Some(b!("-31")), -31).into(); assert_eq!((1009, 0), process_mantissa::(&data, 10)); // 128-bit let data = (b!("1"), Some(b!("2345")), None, 0).into(); assert_eq!((12345, 0), process_mantissa::(&data, 10)); let data = (b!("12"), Some(b!("345")), None, 0).into(); assert_eq!((12345, 0), process_mantissa::(&data, 10)); let data = (b!("12345"), Some(b!("6789")), None, 0).into(); assert_eq!((123456789, 0), process_mantissa::(&data, 10)); let data = (b!("1"), Some(b!("2345")), Some(b!("10")), 10).into(); assert_eq!((12345, 0), process_mantissa::(&data, 10)); let data = (b!("100000000000000000000"), None, None, 0).into(); assert_eq!((100000000000000000000, 0), process_mantissa::(&data, 10)); let data = (b!("100000000000000000001"), None, None, 0).into(); assert_eq!((100000000000000000001, 0), process_mantissa::(&data, 10)); } #[cfg(feature = "radix")] #[test] fn is_odd_test() { // Variant of b1000000000000000000000001, a halfway value for f32. assert!(is_odd::(0x1000002)); assert!(is_odd::(0x2000004)); assert!(is_odd::(0x8000010000000000)); assert!(!is_odd::(0x1000002)); assert!(!is_odd::(0x2000004)); assert!(!is_odd::(0x8000010000000000)); assert!(!is_odd::(0x1000001)); assert!(!is_odd::(0x2000002)); assert!(!is_odd::(0x8000008000000000)); assert!(!is_odd::(0x1000001)); assert!(!is_odd::(0x2000002)); assert!(!is_odd::(0x8000008000000000)); // Variant of b100000000000000000000000000000000000000000000000000001, // a halfway value for f64 assert!(!is_odd::(0x3f000000000002)); assert!(!is_odd::(0x3f000000000003)); assert!(!is_odd::(0xFC00000000000800)); assert!(!is_odd::(0xFC00000000000C00)); assert!(is_odd::(0x3f000000000002)); assert!(is_odd::(0x3f000000000003)); assert!(is_odd::(0xFC00000000000800)); assert!(is_odd::(0xFC00000000000C00)); assert!(!is_odd::(0x3f000000000001)); assert!(!is_odd::(0x3f000000000004)); assert!(!is_odd::(0xFC00000000000400)); assert!(!is_odd::(0xFC00000000001000)); assert!(!is_odd::(0x3f000000000001)); assert!(!is_odd::(0x3f000000000004)); assert!(!is_odd::(0xFC00000000000400)); assert!(!is_odd::(0xFC00000000001000)); } #[cfg(feature = "radix")] #[test] fn is_halfway_test() { // Variant of b1000000000000000000000001, a halfway value for f32. assert!(is_halfway::(0x1000001)); assert!(is_halfway::(0x2000002)); assert!(is_halfway::(0x8000008000000000)); assert!(!is_halfway::(0x1000001)); assert!(!is_halfway::(0x2000002)); assert!(!is_halfway::(0x8000008000000000)); // Variant of b10000000000000000000000001, which is 1-off a halfway value. assert!(!is_halfway::(0x2000001)); assert!(!is_halfway::(0x2000001)); // Variant of b100000000000000000000000000000000000000000000000000001, // a halfway value for f64 assert!(!is_halfway::(0x20000000000001)); assert!(!is_halfway::(0x40000000000002)); assert!(!is_halfway::(0x8000000000000400)); assert!(is_halfway::(0x20000000000001)); assert!(is_halfway::(0x40000000000002)); assert!(is_halfway::(0x8000000000000400)); // Variant of b111111000000000000000000000000000000000000000000000001, // a halfway value for f64. assert!(!is_halfway::(0x3f000000000001)); assert!(!is_halfway::(0xFC00000000000400)); assert!(is_halfway::(0x3f000000000001)); assert!(is_halfway::(0xFC00000000000400)); // Variant of b1000000000000000000000000000000000000000000000000000001, // which is 1-off a halfway value. assert!(!is_halfway::(0x40000000000001)); assert!(!is_halfway::(0x40000000000001)); } #[cfg(feature = "radix")] #[test] fn float_pow2_fast_path() { // Everything is valid. let mantissa = 1 << 63; for base in BASE_POW2.iter().cloned() { let (min_exp, max_exp) = f32::exponent_limit(base); let pow2_exp = pow2_exponent(base); for exp in min_exp-20..max_exp+30 { // Always valid, ignore result pow2_fast_path::(mantissa, base, pow2_exp, exp); } } } #[cfg(feature = "radix")] #[test] fn double_pow2_fast_path_test() { // Everything is valid. let mantissa = 1 << 63; for base in BASE_POW2.iter().cloned() { let (min_exp, max_exp) = f64::exponent_limit(base); let pow2_exp = pow2_exponent(base); for exp in min_exp-20..max_exp+30 { // Ignore result, always valid pow2_fast_path::(mantissa, base, pow2_exp, exp); } } } #[test] fn float_fast_path_test() { // valid let mantissa = (1 << f32::MANTISSA_SIZE) - 1; for base in BASE_POWN.iter().cloned() { let (min_exp, max_exp) = f32::exponent_limit(base); for exp in min_exp..max_exp+1 { let valid = fast_path::(mantissa, base, exp).is_some(); assert!(valid, "should be valid {:?}.", (mantissa, base, exp)); } } // Check slightly above valid exponents let f = fast_path::(123, 10, 15); assert_eq!(f, Some(1.23e+17)); // Exponent is 1 too high, pushes over the mantissa. let f = fast_path::(123, 10, 16); assert!(f.is_none()); // Mantissa is too large, checked_mul should overflow. let f = fast_path::(mantissa, 10, 11); assert!(f.is_none()); // invalid mantissa #[cfg(feature = "radix")] { let (_, max_exp) = f64::exponent_limit(3); let f = fast_path::(1<(mantissa, base, min_exp-1); assert!(f.is_none(), "exponent under min_exp"); let f = fast_path::(mantissa, base, max_exp+1); assert!(f.is_none(), "exponent above max_exp"); } } #[test] fn double_fast_path_test() { // valid let mantissa = (1 << f64::MANTISSA_SIZE) - 1; for base in BASE_POWN.iter().cloned() { let (min_exp, max_exp) = f64::exponent_limit(base); for exp in min_exp..max_exp+1 { let f = fast_path::(mantissa, base, exp); assert!(f.is_some(), "should be valid {:?}.", (mantissa, base, exp)); } } // invalid mantissa #[cfg(feature = "radix")] { let (_, max_exp) = f64::exponent_limit(3); let f = fast_path::(1<(mantissa, base, min_exp-1); assert!(f.is_none(), "exponent under min_exp"); let f = fast_path::(mantissa, base, max_exp+1); assert!(f.is_none(), "exponent above max_exp"); } } #[cfg(feature = "radix")] #[test] fn float_moderate_path_test() { // valid (overflowing small mult) let mantissa: u64 = 1 << 63; let (f, valid) = moderate_path::(mantissa, 3, 1, false, RoundingKind::NearestTieEven); assert_eq!(f.into_f32(), 2.7670116e+19); assert!(valid, "exponent should be valid"); let mantissa: u64 = 4746067219335938; let (f, valid) = moderate_path::(mantissa, 15, -9, false, RoundingKind::NearestTieEven); assert_eq!(f.into_f32(), 123456.1); assert!(valid, "exponent should be valid"); } #[cfg(feature = "radix")] #[test] fn double_moderate_path_test() { // valid (overflowing small mult) let mantissa: u64 = 1 << 63; let (f, valid) = moderate_path::(mantissa, 3, 1, false, RoundingKind::NearestTieEven); assert_eq!(f.into_f64(), 2.7670116110564327e+19); assert!(valid, "exponent should be valid"); // valid (ends of the earth, salting the earth) let (f, valid) = moderate_path::(mantissa, 3, -695, true, RoundingKind::NearestTieEven); assert_eq!(f.into_f64(), 2.32069302345e-313); assert!(valid, "exponent should be valid"); // invalid ("268A6.177777778", base 15) let mantissa: u64 = 4746067219335938; let (_, valid) = moderate_path::(mantissa, 15, -9, false, RoundingKind::NearestTieEven); assert!(!valid, "exponent should be invalid"); // valid ("268A6.177777778", base 15) // 123456.10000000001300614743687445, exactly, should not round up. let mantissa: u128 = 4746067219335938; let (f, valid) = moderate_path::(mantissa, 15, -9, false, RoundingKind::NearestTieEven); assert_eq!(f.into_f64(), 123456.1); assert!(valid, "exponent should be valid"); // Rounding error // Adapted from test-parse-random failures. let mantissa: u64 = 1009; let (_, valid) = moderate_path::(mantissa, 10, -31, false, RoundingKind::NearestTieEven); assert!(!valid, "exponent should be valid"); } #[test] fn atof_test() { let atof10 = move |x| match atof(x, 10, false, Sign::Positive, NumberFormat::standard().unwrap()) { Ok((v, p)) => Ok((v, distance(x.as_ptr(), p))), Err((v, p)) => Err((v, distance(x.as_ptr(), p))), }; assert_eq!(Ok((0.0, 1)), atof10(b"0")); assert_eq!(Ok((1.2345, 6)), atof10(b"1.2345")); assert_eq!(Ok((12.345, 6)), atof10(b"12.345")); assert_eq!(Ok((12345.6789, 10)), atof10(b"12345.6789")); assert_eq!(Ok((1.2345e10, 9)), atof10(b"1.2345e10")); assert_eq!(Ok((1.2345e-38, 10)), atof10(b"1.2345e-38")); // Check expected rounding, using borderline cases. // Round-down, halfway assert_eq!(Ok((16777216.0, 8)), atof10(b"16777216")); assert_eq!(Ok((16777216.0, 8)), atof10(b"16777217")); assert_eq!(Ok((16777218.0, 8)), atof10(b"16777218")); assert_eq!(Ok((33554432.0, 8)), atof10(b"33554432")); assert_eq!(Ok((33554432.0, 8)), atof10(b"33554434")); assert_eq!(Ok((33554436.0, 8)), atof10(b"33554436")); assert_eq!(Ok((17179869184.0, 11)), atof10(b"17179869184")); assert_eq!(Ok((17179869184.0, 11)), atof10(b"17179870208")); assert_eq!(Ok((17179871232.0, 11)), atof10(b"17179871232")); // Round-up, halfway assert_eq!(Ok((16777218.0, 8)), atof10(b"16777218")); assert_eq!(Ok((16777220.0, 8)), atof10(b"16777219")); assert_eq!(Ok((16777220.0, 8)), atof10(b"16777220")); assert_eq!(Ok((33554436.0, 8)), atof10(b"33554436")); assert_eq!(Ok((33554440.0, 8)), atof10(b"33554438")); assert_eq!(Ok((33554440.0, 8)), atof10(b"33554440")); assert_eq!(Ok((17179871232.0, 11)), atof10(b"17179871232")); assert_eq!(Ok((17179873280.0, 11)), atof10(b"17179872256")); assert_eq!(Ok((17179873280.0, 11)), atof10(b"17179873280")); // Round-up, above halfway assert_eq!(Ok((33554436.0, 8)), atof10(b"33554435")); assert_eq!(Ok((17179871232.0, 11)), atof10(b"17179870209")); // Check exactly halfway, round-up at halfway assert_eq!(Ok((1.0000001, 28)), atof10(b"1.00000017881393432617187499")); assert_eq!(Ok((1.0000002, 26)), atof10(b"1.000000178813934326171875")); assert_eq!(Ok((1.0000002, 28)), atof10(b"1.00000017881393432617187501")); // Invalid or partially-parsed assert_eq!(Err((ErrorCode::EmptyMantissa, 0)), atof10(b"e10")); assert_eq!(Err((ErrorCode::EmptyMantissa, 0)), atof10(b".")); assert_eq!(Err((ErrorCode::EmptyMantissa, 0)), atof10(b".e10")); assert_eq!(Err((ErrorCode::EmptyExponent, 2)), atof10(b"0e")); assert_eq!(Ok((1.23, 4)), atof10(b"1.23/")); } #[test] fn atod_test() { let adod_impl = move | x, r | match atod(x, r, false, Sign::Positive, NumberFormat::standard().unwrap()) { Ok((v, p)) => Ok((v, distance(x.as_ptr(), p))), Err((v, p)) => Err((v, distance(x.as_ptr(), p))), }; #[cfg(feature = "radix")] let atod2 = move |x| adod_impl(x, 2); let atod10 = move |x| adod_impl(x, 10); assert_eq!(Ok((0.0, 1)), atod10(b"0")); assert_eq!(Ok((1.2345, 6)), atod10(b"1.2345")); assert_eq!(Ok((12.345, 6)), atod10(b"12.345")); assert_eq!(Ok((12345.6789, 10)), atod10(b"12345.6789")); assert_eq!(Ok((1.2345e10, 9)), atod10(b"1.2345e10")); assert_eq!(Ok((1.2345e-308, 11)), atod10(b"1.2345e-308")); // Check expected rounding, using borderline cases. // Round-down, halfway assert_eq!(Ok((9007199254740992.0, 16)), atod10(b"9007199254740992")); assert_eq!(Ok((9007199254740992.0, 16)), atod10(b"9007199254740993")); assert_eq!(Ok((9007199254740994.0, 16)), atod10(b"9007199254740994")); assert_eq!(Ok((18014398509481984.0, 17)), atod10(b"18014398509481984")); assert_eq!(Ok((18014398509481984.0, 17)), atod10(b"18014398509481986")); assert_eq!(Ok((18014398509481988.0, 17)), atod10(b"18014398509481988")); assert_eq!(Ok((9223372036854775808.0, 19)), atod10(b"9223372036854775808")); assert_eq!(Ok((9223372036854775808.0, 19)), atod10(b"9223372036854776832")); assert_eq!(Ok((9223372036854777856.0, 19)), atod10(b"9223372036854777856")); assert_eq!(Ok((11417981541647679048466287755595961091061972992.0, 47)), atod10(b"11417981541647679048466287755595961091061972992")); assert_eq!(Ok((11417981541647679048466287755595961091061972992.0, 47)), atod10(b"11417981541647680316116887983825362587765178368")); assert_eq!(Ok((11417981541647681583767488212054764084468383744.0, 47)), atod10(b"11417981541647681583767488212054764084468383744")); // Round-up, halfway assert_eq!(Ok((9007199254740994.0, 16)), atod10(b"9007199254740994")); assert_eq!(Ok((9007199254740996.0, 16)), atod10(b"9007199254740995")); assert_eq!(Ok((9007199254740996.0, 16)), atod10(b"9007199254740996")); assert_eq!(Ok((18014398509481988.0, 17)), atod10(b"18014398509481988")); assert_eq!(Ok((18014398509481992.0, 17)), atod10(b"18014398509481990")); assert_eq!(Ok((18014398509481992.0, 17)), atod10(b"18014398509481992")); assert_eq!(Ok((9223372036854777856.0, 19)), atod10(b"9223372036854777856")); assert_eq!(Ok((9223372036854779904.0, 19)), atod10(b"9223372036854778880")); assert_eq!(Ok((9223372036854779904.0, 19)), atod10(b"9223372036854779904")); assert_eq!(Ok((11417981541647681583767488212054764084468383744.0, 47)), atod10(b"11417981541647681583767488212054764084468383744")); assert_eq!(Ok((11417981541647684119068688668513567077874794496.0, 47)), atod10(b"11417981541647682851418088440284165581171589120")); assert_eq!(Ok((11417981541647684119068688668513567077874794496.0, 47)), atod10(b"11417981541647684119068688668513567077874794496")); // Round-up, above halfway assert_eq!(Ok((9223372036854777856.0, 19)), atod10(b"9223372036854776833")); assert_eq!(Ok((11417981541647681583767488212054764084468383744.0, 47)), atod10(b"11417981541647680316116887983825362587765178369")); // Rounding error // Adapted from failures in strtod. assert_eq!(Ok((2.2250738585072014e-308, 23)), atod10(b"2.2250738585072014e-308")); assert_eq!(Ok((2.225073858507201e-308, 776)), atod10(b"2.2250738585072011360574097967091319759348195463516456480234261097248222220210769455165295239081350879141491589130396211068700864386945946455276572074078206217433799881410632673292535522868813721490129811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306666559949382757725720157630626906633326475653000092458883164330377797918696120494973903778297049050510806099407302629371289589500035837999672072543043602840788957717961509455167482434710307026091446215722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844239002654981983854879482922068947216898310996983658468140228542433306603398508864458040010349339704275671864433837704860378616227717385456230658746790140867233276367187499e-308")); assert_eq!(Ok((2.2250738585072014e-308, 774)), atod10(b"2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508791414915891303962110687008643869459464552765720740782062174337998814106326732925355228688137214901298112245145188984905722230728525513315575501591439747639798341180199932396254828901710708185069063066665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505108060994073026293712895895000358379996720725430436028407889577179615094551674824347103070260914462157228988025818254518032570701886087211312807951223342628836862232150377566662250398253433597456888442390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042756718644338377048603786162277173854562306587467901408672332763671875e-308")); assert_eq!(Ok((2.2250738585072014e-308, 776)), atod10(b"2.2250738585072011360574097967091319759348195463516456480234261097248222220210769455165295239081350879141491589130396211068700864386945946455276572074078206217433799881410632673292535522868813721490129811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306666559949382757725720157630626906633326475653000092458883164330377797918696120494973903778297049050510806099407302629371289589500035837999672072543043602840788957717961509455167482434710307026091446215722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844239002654981983854879482922068947216898310996983658468140228542433306603398508864458040010349339704275671864433837704860378616227717385456230658746790140867233276367187501e-308")); assert_eq!(Ok((1.7976931348623157e+308, 380)), atod10(b"179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791.9999999999999999999999999999999999999999999999999999999999999999999999")); assert_eq!(Ok((5e-324, 761)), atod10(b"7.4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984374999e-324")); assert_eq!(Ok((1e-323, 758)), atod10(b"7.4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375e-324")); assert_eq!(Ok((1e-323, 761)), atod10(b"7.4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375001e-324")); // Rounding error // Adapted from: // https://www.exploringbinary.com/glibc-strtod-incorrectly-converts-2-to-the-negative-1075/ #[cfg(feature = "radix")] assert_eq!(Ok((5e-324, 14)), atod2(b"1e-10000110010")); #[cfg(feature = "radix")] assert_eq!(Ok((0.0, 14)), atod2(b"1e-10000110011")); assert_eq!(Ok((0.0, 1077)), atod10(b"0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125")); // Rounding error // Adapted from: // https://www.exploringbinary.com/how-glibc-strtod-works/ assert_eq!(Ok((2.2250738585072011e-308, 1076)), atod10(b"0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375")); // Rounding error // Adapted from test-parse-random failures. assert_eq!(Ok((1.009e-28, 8)), atod10(b"1009e-31")); assert_eq!(Ok((f64::INFINITY, 9)), atod10(b"18294e304")); // Rounding error // Adapted from a @dangrabcad's issue #20. assert_eq!(Ok((7.689539722041643e164, 21)), atod10(b"7.689539722041643e164")); assert_eq!(Ok((7.689539722041643e164, 165)), atod10(b"768953972204164300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")); assert_eq!(Ok((7.689539722041643e164, 167)), atod10(b"768953972204164300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0")); // Check other cases similar to @dangrabcad's issue #20. assert_eq!(Ok((9223372036854777856.0, 21)), atod10(b"9223372036854776833.0")); assert_eq!(Ok((11417981541647681583767488212054764084468383744.0, 49)), atod10(b"11417981541647680316116887983825362587765178369.0")); assert_eq!(Ok((9007199254740996.0, 18)), atod10(b"9007199254740995.0")); assert_eq!(Ok((18014398509481992.0, 19)), atod10(b"18014398509481990.0")); assert_eq!(Ok((9223372036854779904.0, 21)), atod10(b"9223372036854778880.0")); assert_eq!(Ok((11417981541647684119068688668513567077874794496.0, 49)), atod10(b"11417981541647682851418088440284165581171589120.0")); // Check other cases ostensibly identified via proptest. assert_eq!(Ok((71610528364411830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0, 310)), atod10(b"71610528364411830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0")); assert_eq!(Ok((126769393745745060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0, 311)), atod10(b"126769393745745060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0")); assert_eq!(Ok((38652960461239320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0, 310)), atod10(b"38652960461239320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0")); } #[test] fn atof_lossy_test() { let atof10 = move |x| match atof(x, 10, true, Sign::Positive, NumberFormat::standard().unwrap()) { Ok((v, p)) => Ok((v, distance(x.as_ptr(), p))), Err((v, p)) => Err((v, distance(x.as_ptr(), p))), }; assert_eq!(Ok((1.2345, 6)), atof10(b"1.2345")); assert_eq!(Ok((12.345, 6)), atof10(b"12.345")); assert_eq!(Ok((12345.6789, 10)), atof10(b"12345.6789")); assert_eq!(Ok((1.2345e10, 9)), atof10(b"1.2345e10")); } #[test] fn atod_lossy_test() { let atod10 = move |x| match atod(x, 10, true, Sign::Positive, NumberFormat::standard().unwrap()) { Ok((v, p)) => Ok((v, distance(x.as_ptr(), p))), Err((v, p)) => Err((v, distance(x.as_ptr(), p))), }; assert_eq!(Ok((1.2345, 6)), atod10(b"1.2345")); assert_eq!(Ok((12.345, 6)), atod10(b"12.345")); assert_eq!(Ok((12345.6789, 10)), atod10(b"12345.6789")); assert_eq!(Ok((1.2345e10, 9)), atod10(b"1.2345e10")); } } lexical-core-0.7.6/src/atof/algorithm/errors.rs000075500000000000000000000167300000000000000175640ustar 00000000000000//! Estimate the error in an 80-bit approximation of a float. //! //! This estimates the error in a floating-point representation. //! //! This implementation is loosely based off the Golang implementation, //! found here: //! https://golang.org/src/strconv/atof.go use crate::float::*; use crate::util::*; pub trait FloatErrors: Mantissa { /// Get the full error scale. fn error_scale() -> u32; /// Get the half error scale. fn error_halfscale() -> u32; /// Determine if the number of errors is tolerable for float precision. fn error_is_accurate(count: u32, fp: &ExtendedFloat, kind: RoundingKind) -> bool; } perftools_inline!{ /// Check if the error is accurate with a round-nearest rounding scheme. fn nearest_error_is_accurate(errors: u64, fp: &ExtendedFloat, extrabits: u64) -> bool { // Round-to-nearest, need to use the halfway point. if extrabits == 65 { // Underflow, we have a shift larger than the mantissa. // Representation is valid **only** if the value is close enough // overflow to the next bit within errors. If it overflows, // the representation is **not** valid. !fp.mant.overflowing_add(errors).1 } else { let mask: u64 = lower_n_mask(extrabits); let extra: u64 = fp.mant & mask; // Round-to-nearest, need to check if we're close to halfway. // IE, b10100 | 100000, where `|` signifies the truncation point. let halfway: u64 = lower_n_halfway(extrabits); let cmp1 = halfway.wrapping_sub(errors) < extra; let cmp2 = extra < halfway.wrapping_add(errors); // If both comparisons are true, we have significant rounding error, // and the value cannot be exactly represented. Otherwise, the // representation is valid. !(cmp1 && cmp2) } }} perftools_inline!{ /// Check if the error is accurate with a round-toward rounding scheme. #[cfg(feature = "rounding")] fn toward_error_is_accurate(errors: u64, fp: &ExtendedFloat, extrabits: u64) -> bool { if extrabits == 65 { // Underflow, we have a literal 0. true } else { let mask: u64 = lower_n_mask(extrabits); let extra: u64 = fp.mant & mask; // Round-towards, need to use `1 << extrabits`. if extrabits == 64 { // Round toward something, we need to check if either operation can overflow, // since we cannot exactly represent the comparison point as the type // in question. let cmp1 = extra.checked_sub(errors).is_none(); let cmp2 = extra.checked_add(errors).is_none(); // If either comparison is true, we have significant rounding error, // since we cannot distinguish the value (1 << 64). cmp1 || cmp2 } else { // Round toward something, need to check if we're close to // IE, b10101 | 000000, where `|` signifies the truncation point. // If the extract bits +/- the error can overflow, then we have // an issue. let fullway: u64 = nth_bit(extrabits); let cmp1 = fullway.wrapping_sub(errors) < extra; let cmp2 = extra < fullway.wrapping_add(errors); // If both comparisons are true, we have significant rounding error, // and the value cannot be exactly represented. Otherwise, the // representation is valid. !(cmp1 && cmp2) } } }} impl FloatErrors for u64 { perftools_inline!{ fn error_scale() -> u32 { 8 }} perftools_inline!{ fn error_halfscale() -> u32 { u64::error_scale() / 2 }} perftools_inline!{ #[allow(unused_variables)] fn error_is_accurate(count: u32, fp: &ExtendedFloat, kind: RoundingKind) -> bool { // Determine if extended-precision float is a good approximation. // If the error has affected too many units, the float will be // inaccurate, or if the representation is too close to halfway // that any operations could affect this halfway representation. // See the documentation for dtoa for more information. let bias = -(F::EXPONENT_BIAS - F::MANTISSA_SIZE); let denormal_exp = bias - 63; // This is always a valid u32, since (denormal_exp - fp.exp) // will always be positive and the significand size is {23, 52}. let extrabits = match fp.exp <= denormal_exp { true => 64 - F::MANTISSA_SIZE + denormal_exp - fp.exp, false => 63 - F::MANTISSA_SIZE, }; // Our logic is as follows: we want to determine if the actual // mantissa and the errors during calculation differ significantly // from the rounding point. The rounding point for round-nearest // is the halfway point, IE, this when the truncated bits start // with b1000..., while the rounding point for the round-toward // is when the truncated bits are equal to 0. // To do so, we can check whether the rounding point +/- the error // are >/< the actual lower n bits. // // For whether we need to use signed or unsigned types for this // analysis, see this example, using u8 rather than u64 to simplify // things. // // # Comparisons // cmp1 = (halfway - errors) < extra // cmp1 = extra < (halfway + errors) // // # Large Extrabits, Low Errors // // extrabits = 8 // halfway = 0b10000000 // extra = 0b10000010 // errors = 0b00000100 // halfway - errors = 0b01111100 // halfway + errors = 0b10000100 // // Unsigned: // halfway - errors = 124 // halfway + errors = 132 // extra = 130 // cmp1 = true // cmp2 = true // Signed: // halfway - errors = 124 // halfway + errors = -124 // extra = -126 // cmp1 = false // cmp2 = true // // # Conclusion // // Since errors will always be small, and since we want to detect // if the representation is accurate, we need to use an **unsigned** // type for comparisons. let extrabits = extrabits.as_u64(); let errors = count.as_u64(); if extrabits > 65 { // Underflow, we have a literal 0. return true; } #[cfg(not(feature = "rounding"))] { nearest_error_is_accurate(errors, fp, extrabits) } #[cfg(feature = "rounding")] { if is_nearest(kind) { nearest_error_is_accurate(errors, fp, extrabits) } else { toward_error_is_accurate(errors, fp, extrabits) } } }} } // 128-bit representation is always accurate, ignore this. impl FloatErrors for u128 { perftools_inline!{ fn error_scale() -> u32 { 0 }} perftools_inline!{ fn error_halfscale() -> u32 { 0 }} perftools_inline!{ fn error_is_accurate(_: u32, _: &ExtendedFloat, _: RoundingKind) -> bool { // Ignore the halfway problem, use more bits to aim for accuracy, // but short-circuit to avoid extremely slow operations. true }} } lexical-core-0.7.6/src/atof/algorithm/format/exponent.rs000075500000000000000000000736020000000000000214010ustar 00000000000000//! Utilities to parse, extract, and interpret exponent components. use crate::atoi; use crate::lib::slice; use crate::util::*; use super::traits::*; /// The actual float-type doesn't matter, it just needs to be used for /// signed/unsigned detection during sign parsing. type FloatType = f64; // EXPONENT CALCULATION // Calculate the scientific notation exponent without overflow. // // For example, 0.1 would be -1, and 10 would be 1 in base 10. perftools_inline!{ #[cfg(feature = "correct")] pub(super) fn scientific_exponent(exponent: i32, integer_digits: usize, fraction_start: usize) -> i32 { if integer_digits == 0 { let fraction_start = fraction_start.try_i32_or_max(); exponent.saturating_sub(fraction_start).saturating_sub(1) } else { let integer_shift = (integer_digits - 1).try_i32_or_max(); exponent.saturating_add(integer_shift) } }} // Calculate the mantissa exponent without overflow. // // Remove the number of digits that contributed to the mantissa past // the dot, and add the number of truncated digits from the mantissa, // to calculate the scaling factor for the mantissa from a raw exponent. perftools_inline!{ #[cfg(feature = "correct")] pub(super) fn mantissa_exponent(raw_exponent: i32, fraction_digits: usize, truncated: usize) -> i32 { if fraction_digits > truncated { raw_exponent.saturating_sub((fraction_digits - truncated).try_i32_or_max()) } else { raw_exponent.saturating_add((truncated - fraction_digits).try_i32_or_max()) } }} // EXPONENT EXTRACTORS // Extract exponent substring and parse exponent. // Uses an abstract iterator to allow generic implementations // iterators to work. This only works with greedy iterators, where we // know exactly when we should stop upon encountering a given character. // // Precondition: // Iter should not implement ConsumedIterator, since it would break // the assumption in `extract_exponent_iltc`. perftools_inline!{ #[allow(unused_unsafe)] fn extract_and_parse_exponent<'a, Data, Iter>( data: &mut Data, iter: Iter, bytes: &'a [u8], radix: u32, sign: Sign ) -> &'a [u8] where Data: FastDataInterface<'a>, Iter: AsPtrIterator<'a, u8> { let (raw_exponent, ptr) = atoi::standalone_exponent(iter, radix, sign); data.set_raw_exponent(raw_exponent); unsafe { // Extract the exponent subslice. let first = bytes.as_ptr(); data.set_exponent(Some(slice::from_raw_parts(first, distance(first, ptr)))); // Return the remaining bytes. let last = index!(bytes[bytes.len()..]).as_ptr(); slice::from_raw_parts(ptr, distance(ptr, last)) } }} // Parse exponent. // This only works with exponents that may contain digit separators, // where the invalid (trailing) data has already been determined. perftools_inline!{ #[cfg(feature = "format")] fn parse_exponent<'a, Data>( data: &mut Data, bytes: &'a [u8], leading: &'a [u8], trailing: &'a [u8], radix: u32, digit_separator: u8, sign: Sign ) where Data: FastDataInterface<'a> { // Get an iterator over our digits and sign bits, and parse the exponent. let iter = iterate_digits_ignore_separator(leading, digit_separator); // Parse the exponent and store the extracted digits. let bytes_len = bytes.len() - trailing.len(); data.set_raw_exponent(atoi::standalone_exponent(iter, radix, sign).0); data.set_exponent(Some(&index!(bytes[..bytes_len]))); }} // PARSE THEN EXTRACT // These algorithms are slightly more efficient, since they only // require a single pass of the exponent string. These algorithms // must be able to parse until they reach an invalid character, // without any backsteps to find the correct subslice, that is, // they must be greedy. // Extract exponent substring and parse exponent. // Does not consume any digit separators. perftools_inline!{ fn extract_exponent<'a, Data>( data: &mut Data, bytes: &'a [u8], radix: u32, digit_separator: u8 ) -> &'a [u8] where Data: FastDataInterface<'a> { // Remove leading exponent character and parse exponent. let bytes = &index!(bytes[1..]); let (sign, digits) = parse_sign_no_separator::(bytes, digit_separator); let iter = iterate_digits_no_separator(digits, digit_separator); extract_and_parse_exponent(data, iter, bytes, radix, sign) }} // Extract exponent substring and parse exponent. // Consumes leading, internal, trailing, and consecutive digit separators. perftools_inline!{ #[cfg(feature = "format")] fn extract_exponent_iltc<'a, Data>( data: &mut Data, bytes: &'a [u8], radix: u32, digit_separator: u8 ) -> &'a [u8] where Data: FastDataInterface<'a> { // Remove leading exponent character and parse exponent. // We're not calling `consumed()`, so it's fine to have trailing underscores. let bytes = &index!(bytes[1..]); let (sign, digits) = parse_sign_lc_separator::(bytes, digit_separator); let iter = iterate_digits_ignore_separator(digits, digit_separator); extract_and_parse_exponent(data, iter, bytes, radix, sign) }} // EXTRACT THEN PARSE // These algorithms are less efficient, since they first extract the // subslice of valid data in the exponent, and then parse it, // using 2 passes over the input data. However, because they first extract // the data, they allow consumers that are not greedy, where there may // be backsteps to determine if an input is actually valid after reaching // the end or an invalid character. // Generate function definition to extraction exponent with digit separators. macro_rules! extract_exponent_separator { ( fn $name:ident, sign => $sign:ident, consume => $consume:ident ) => ( perftools_inline!{ #[cfg(feature = "format")] fn $name<'a, Data>( data: &mut Data, bytes: &'a [u8], radix: u32, digit_separator: u8 ) -> &'a [u8] where Data: FastDataInterface<'a> { let bytes = &index!(bytes[1..]); let (sign, digits) = $sign::(bytes, digit_separator); let (leading, trailing) = $consume(digits, radix, digit_separator); parse_exponent(data, bytes, leading, trailing, radix, digit_separator, sign); trailing }} ); } extract_exponent_separator!( fn extract_exponent_i, sign => parse_sign_no_separator, consume => consume_digits_i ); extract_exponent_separator!( fn extract_exponent_ic, sign => parse_sign_no_separator, consume => consume_digits_ic ); extract_exponent_separator!( fn extract_exponent_l, sign => parse_sign_l_separator, consume => consume_digits_l ); extract_exponent_separator!( fn extract_exponent_lc, sign => parse_sign_lc_separator, consume => consume_digits_lc ); extract_exponent_separator!( fn extract_exponent_t, sign => parse_sign_no_separator, consume => consume_digits_t ); extract_exponent_separator!( fn extract_exponent_tc, sign => parse_sign_no_separator, consume => consume_digits_tc ); extract_exponent_separator!( fn extract_exponent_il, sign => parse_sign_l_separator, consume => consume_digits_il ); extract_exponent_separator!( fn extract_exponent_ilc, sign => parse_sign_lc_separator, consume => consume_digits_ilc ); extract_exponent_separator!( fn extract_exponent_it, sign => parse_sign_no_separator, consume => consume_digits_it ); extract_exponent_separator!( fn extract_exponent_itc, sign => parse_sign_no_separator, consume => consume_digits_itc ); extract_exponent_separator!( fn extract_exponent_lt, sign => parse_sign_l_separator, consume => consume_digits_lt ); extract_exponent_separator!( fn extract_exponent_ltc, sign => parse_sign_lc_separator, consume => consume_digits_ltc ); extract_exponent_separator!( fn extract_exponent_ilt, sign => parse_sign_l_separator, consume => consume_digits_ilt ); // API // Extract exponent without a digit separator. perftools_inline!{ pub(crate) fn extract_exponent_no_separator<'a, Data>(data: &mut Data, bytes: &'a [u8], radix: u32, format: NumberFormat) -> &'a [u8] where Data: FastDataInterface<'a> { extract_exponent(data, bytes, radix, format.digit_separator()) }} // Extract exponent while ignoring the digit separator. perftools_inline!{ #[cfg(feature = "format")] pub(crate) fn extract_exponent_ignore_separator<'a, Data>(data: &mut Data, bytes: &'a [u8], radix: u32, format: NumberFormat) -> &'a [u8] where Data: FastDataInterface<'a> { extract_exponent_iltc(data, bytes, radix, format.digit_separator()) }} // Extract exponent with a digit separator in the exponent component. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn extract_exponent_separator<'a, Data>(data: &mut Data, bytes: &'a [u8], radix: u32, format: NumberFormat) -> &'a [u8] where Data: FastDataInterface<'a> { const I: NumberFormat = NumberFormat::EXPONENT_INTERNAL_DIGIT_SEPARATOR; const L: NumberFormat = NumberFormat::EXPONENT_LEADING_DIGIT_SEPARATOR; const T: NumberFormat = NumberFormat::EXPONENT_TRAILING_DIGIT_SEPARATOR; const C: NumberFormat = NumberFormat::EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR; const IL: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | L.bits()); const IT: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | T.bits()); const LT: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | T.bits()); const ILT: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | T.bits()); const IC: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | C.bits()); const LC: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | C.bits()); const TC: NumberFormat = NumberFormat::from_bits_truncate(T.bits() | C.bits()); const ILC: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | C.bits()); const ITC: NumberFormat = NumberFormat::from_bits_truncate(IT.bits() | C.bits()); const LTC: NumberFormat = NumberFormat::from_bits_truncate(LT.bits() | C.bits()); const ILTC: NumberFormat = NumberFormat::from_bits_truncate(ILT.bits() | C.bits()); let digit_separator = format.digit_separator(); match format & NumberFormat::EXPONENT_DIGIT_SEPARATOR_FLAG_MASK { I => extract_exponent_i(data, bytes, radix, digit_separator), IC => extract_exponent_ic(data, bytes, radix, digit_separator), L => extract_exponent_l(data, bytes, radix, digit_separator), LC => extract_exponent_lc(data, bytes, radix, digit_separator), T => extract_exponent_t(data, bytes, radix, digit_separator), TC => extract_exponent_tc(data, bytes, radix, digit_separator), IL => extract_exponent_il(data, bytes, radix, digit_separator), ILC => extract_exponent_ilc(data, bytes, radix, digit_separator), IT => extract_exponent_it(data, bytes, radix, digit_separator), ITC => extract_exponent_itc(data, bytes, radix, digit_separator), LT => extract_exponent_lt(data, bytes, radix, digit_separator), LTC => extract_exponent_ltc(data, bytes, radix, digit_separator), ILT => extract_exponent_ilt(data, bytes, radix, digit_separator), ILTC => extract_exponent_iltc(data, bytes, radix, digit_separator), _ => unreachable!() } }} // TESTS // ----- #[cfg(test)] mod test { use super::*; use super::super::standard::*; #[cfg(feature = "format")] use super::super::ignore::*; #[cfg(feature = "correct")] #[test] fn scientific_exponent_test() { // 0 digits in the integer assert_eq!(scientific_exponent(0, 0, 5), -6); assert_eq!(scientific_exponent(10, 0, 5), 4); assert_eq!(scientific_exponent(-10, 0, 5), -16); // >0 digits in the integer assert_eq!(scientific_exponent(0, 1, 5), 0); assert_eq!(scientific_exponent(0, 2, 5), 1); assert_eq!(scientific_exponent(0, 2, 20), 1); assert_eq!(scientific_exponent(10, 2, 20), 11); assert_eq!(scientific_exponent(-10, 2, 20), -9); // Underflow assert_eq!(scientific_exponent(i32::min_value(), 0, 0), i32::min_value()); assert_eq!(scientific_exponent(i32::min_value(), 0, 5), i32::min_value()); // Overflow assert_eq!(scientific_exponent(i32::max_value(), 0, 0), i32::max_value()-1); assert_eq!(scientific_exponent(i32::max_value(), 5, 0), i32::max_value()); } #[cfg(feature = "correct")] #[test] fn mantissa_exponent_test() { assert_eq!(mantissa_exponent(10, 5, 0), 5); assert_eq!(mantissa_exponent(0, 5, 0), -5); assert_eq!(mantissa_exponent(i32::max_value(), 5, 0), i32::max_value()-5); assert_eq!(mantissa_exponent(i32::max_value(), 0, 5), i32::max_value()); assert_eq!(mantissa_exponent(i32::min_value(), 5, 0), i32::min_value()); assert_eq!(mantissa_exponent(i32::min_value(), 0, 5), i32::min_value()+5); } #[test] fn extract_exponent_test() { // Allows present exponents. type Data<'a> = StandardFastDataInterface<'a>; let mut data = Data::new(NumberFormat::standard().unwrap()); extract_exponent(&mut data, b"e+23", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+23"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::standard().unwrap()); extract_exponent(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); } #[test] #[cfg(feature = "format")] fn extract_exponent_iltc_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_iltc(&mut data, b"e__+__2__3____", 10, b'_'); assert_eq!(data.exponent(), Some(b!("__+__2__3____"))); assert_eq!(data.raw_exponent(), 23); // Allows present exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_iltc(&mut data, b"e__+_2_3_", 10, b'_'); assert_eq!(data.exponent(), Some(b!("__+_2_3_"))); assert_eq!(data.raw_exponent(), 23); // Allows present exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_iltc(&mut data, b"e_+__2_3_", 10, b'_'); assert_eq!(data.exponent(), Some(b!("_+__2_3_"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_iltc(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); } #[test] #[cfg(feature = "format")] fn extract_exponent_i_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_i(&mut data, b"e+2_3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+2_3"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_i(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_i(&mut data, b"e+_2_3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+"))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_i(&mut data, b"e+2__3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+2"))); assert_eq!(data.raw_exponent(), 2); } #[test] #[cfg(feature = "format")] fn extract_exponent_ic_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ic(&mut data, b"e+2__3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+2__3"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ic(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ic(&mut data, b"e+_2_3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+"))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ic(&mut data, b"e_+2__3", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); } #[test] #[cfg(feature = "format")] fn extract_exponent_l_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_l(&mut data, b"e+_23", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+_23"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_l(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_l(&mut data, b"e+_2_3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+_2"))); assert_eq!(data.raw_exponent(), 2); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_l(&mut data, b"e_+__2__3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("_+"))); assert_eq!(data.raw_exponent(), 0); } #[test] #[cfg(feature = "format")] fn extract_exponent_lc_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_lc(&mut data, b"e+__23", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+__23"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_lc(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_lc(&mut data, b"e+_2_3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+_2"))); assert_eq!(data.raw_exponent(), 2); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_lc(&mut data, b"e_+__2__3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("_+__2"))); assert_eq!(data.raw_exponent(), 2); } #[test] #[cfg(feature = "format")] fn extract_exponent_t_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_t(&mut data, b"e+23_", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+23_"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_t(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_t(&mut data, b"e+23__", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+23"))); assert_eq!(data.raw_exponent(), 23); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_t(&mut data, b"e_+__2__3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("_"))); assert_eq!(data.raw_exponent(), 0); } #[test] #[cfg(feature = "format")] fn extract_exponent_tc_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_tc(&mut data, b"e+23__", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+23__"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_tc(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_tc(&mut data, b"e+_2_3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+"))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_tc(&mut data, b"e_+__2__3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("_"))); assert_eq!(data.raw_exponent(), 0); } #[test] #[cfg(feature = "format")] fn extract_exponent_il_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_il(&mut data, b"e+_2_3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+_2_3"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_il(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_il(&mut data, b"e+23__", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+23"))); assert_eq!(data.raw_exponent(), 23); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_il(&mut data, b"e+2__3__", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+2"))); assert_eq!(data.raw_exponent(), 2); } #[test] #[cfg(feature = "format")] fn extract_exponent_ilc_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ilc(&mut data, b"e+__2__3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+__2__3"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ilc(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ilc(&mut data, b"e+23__", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+23"))); assert_eq!(data.raw_exponent(), 23); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ilc(&mut data, b"e+2__3__", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+2__3"))); assert_eq!(data.raw_exponent(), 23); } #[test] #[cfg(feature = "format")] fn extract_exponent_it_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_it(&mut data, b"e+2_3_", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+2_3_"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_it(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_it(&mut data, b"e+_23", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+"))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_it(&mut data, b"e+2__3__", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+2"))); assert_eq!(data.raw_exponent(), 2); } #[test] #[cfg(feature = "format")] fn extract_exponent_itc_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_itc(&mut data, b"e+2__3__", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+2__3__"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_itc(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_itc(&mut data, b"e+_23", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+"))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_itc(&mut data, b"e_+2__3__", 10, b'_'); assert_eq!(data.exponent(), Some(b!("_"))); assert_eq!(data.raw_exponent(), 0); } #[test] #[cfg(feature = "format")] fn extract_exponent_lt_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_lt(&mut data, b"e_+_23_", 10, b'_'); assert_eq!(data.exponent(), Some(b!("_+_23_"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_lt(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_lt(&mut data, b"e+2_3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+2"))); assert_eq!(data.raw_exponent(), 2); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_lt(&mut data, b"e__+__2__3__", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); } #[test] #[cfg(feature = "format")] fn extract_exponent_ltc_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ltc(&mut data, b"e__+__23__", 10, b'_'); assert_eq!(data.exponent(), Some(b!("__+__23__"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ltc(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ltc(&mut data, b"e+2_3", 10, b'_'); assert_eq!(data.exponent(), Some(b!("+2"))); assert_eq!(data.raw_exponent(), 2); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ltc(&mut data, b"e__+__2__3__", 10, b'_'); assert_eq!(data.exponent(), Some(b!("__+__2"))); assert_eq!(data.raw_exponent(), 2); } #[test] #[cfg(feature = "format")] fn extract_exponent_ilt_test() { // Allows present exponents. type Data<'a> = IgnoreFastDataInterface<'a>; let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ilt(&mut data, b"e_+_2_3_", 10, b'_'); assert_eq!(data.exponent(), Some(b!("_+_2_3_"))); assert_eq!(data.raw_exponent(), 23); // Allows absent exponents. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ilt(&mut data, b"e", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); assert_eq!(data.raw_exponent(), 0); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ilt(&mut data, b"e__+_2_3_", 10, b'_'); assert_eq!(data.exponent(), Some(b!(""))); // Ignores invalid data. let mut data = Data::new(NumberFormat::ignore(b'_').unwrap()); extract_exponent_ilt(&mut data, b"e_+__2_3_", 10, b'_'); assert_eq!(data.exponent(), Some(b!("_+"))); } } lexical-core-0.7.6/src/atof/algorithm/format/generic.rs000075500000000000000000000357360000000000000211630ustar 00000000000000//! Generic float-parsing data interfaces. use crate::util::*; use super::exponent::*; use super::traits::*; use super::trim::*; use super::validate::*; // The following interfaces are named: // Generic*Interface, where * represents any combination of the following: // 1). [I]nteger. // 2). [F]raction. // 3). [E]xponent. /// Shared definition for all generic fast data interfaces. macro_rules! generic_data_interface { ( struct $fast:ident, struct $slow:ident, integer_iter => ( $integer_iter:tt, $integer_iter_fn:ident ), fraction_iter => ( $fraction_iter:tt, $fraction_iter_fn:ident ), exponent_iter => ( $exponent_iter:tt, $exponent_iter_fn:ident ), consume_integer_digits => $consume_integer_digits:expr, consume_fraction_digits => $consume_fraction_digits:expr, extract_exponent => $extract_exponent:expr, ltrim_zero => $ltrim_zero:ident, ltrim_separator => $ltrim_separator:ident, rtrim_zero => $rtrim_zero:ident, rtrim_separator => $rtrim_separator:ident ) => { data_interface!( struct $fast, struct $slow, fields => { format: NumberFormat, }, integer_iter => ($integer_iter, $integer_iter_fn), fraction_iter => ($fraction_iter, $fraction_iter_fn), exponent_iter => ($exponent_iter, $exponent_iter_fn), format => |this: &Self| this.format, consume_integer_digits => $consume_integer_digits, consume_fraction_digits => $consume_fraction_digits, extract_exponent => $extract_exponent, validate_mantissa => |this: &Self| validate_mantissa(this, this.format), validate_exponent => |this: &Self| validate_exponent(this, this.format), validate_exponent_fraction => |this: &Self| validate_exponent_fraction(this, this.format), validate_exponent_sign => |this: &Self| validate_exponent_sign(this, this.format), ltrim_zero => $ltrim_zero, ltrim_separator => $ltrim_separator, rtrim_zero => $rtrim_zero, rtrim_separator => $rtrim_separator, new => fn new(format: NumberFormat) -> Self { Self { format: format, integer: &[], fraction: None, exponent: None, raw_exponent: 0 } } ); }; } // Generic data interface without digit separators. generic_data_interface!( struct GenericFastDataInterface, struct GenericSlowDataInterface, integer_iter => (IteratorNoSeparator, iterate_digits_no_separator), fraction_iter => (IteratorNoSeparator, iterate_digits_no_separator), exponent_iter => (IteratorNoSeparator, iterate_digits_no_separator), consume_integer_digits => consume_digits_no_separator, consume_fraction_digits => consume_digits_no_separator, extract_exponent => extract_exponent_no_separator, ltrim_zero => ltrim_zero_no_separator, ltrim_separator => ltrim_separator_no_separator, rtrim_zero => rtrim_zero_no_separator, rtrim_separator => rtrim_separator_no_separator ); // Generic data interface with integer digit separators. generic_data_interface!( struct GenericIFastDataInterface, struct GenericISlowDataInterface, integer_iter => (IteratorSeparator, iterate_digits_ignore_separator), fraction_iter => (IteratorNoSeparator, iterate_digits_no_separator), exponent_iter => (IteratorNoSeparator, iterate_digits_no_separator), consume_integer_digits => consume_integer_digits_separator, consume_fraction_digits => consume_digits_no_separator, extract_exponent => extract_exponent_no_separator, ltrim_zero => ltrim_zero_separator, ltrim_separator => ltrim_separator_separator, rtrim_zero => rtrim_zero_separator, rtrim_separator => rtrim_separator_separator ); // Generic data interface with fraction digit separators. generic_data_interface!( struct GenericFFastDataInterface, struct GenericFSlowDataInterface, integer_iter => (IteratorNoSeparator, iterate_digits_no_separator), fraction_iter => (IteratorSeparator, iterate_digits_ignore_separator), exponent_iter => (IteratorNoSeparator, iterate_digits_no_separator), consume_integer_digits => consume_digits_no_separator, consume_fraction_digits => consume_fraction_digits_separator, extract_exponent => extract_exponent_no_separator, ltrim_zero => ltrim_zero_separator, ltrim_separator => ltrim_separator_separator, rtrim_zero => rtrim_zero_separator, rtrim_separator => rtrim_separator_separator ); // Generic data interface with exponent digit separators. generic_data_interface!( struct GenericEFastDataInterface, struct GenericESlowDataInterface, integer_iter => (IteratorNoSeparator, iterate_digits_no_separator), fraction_iter => (IteratorNoSeparator, iterate_digits_no_separator), exponent_iter => (IteratorSeparator, iterate_digits_ignore_separator), consume_integer_digits => consume_digits_no_separator, consume_fraction_digits => consume_digits_no_separator, extract_exponent => extract_exponent_separator, ltrim_zero => ltrim_zero_no_separator, ltrim_separator => ltrim_separator_no_separator, rtrim_zero => rtrim_zero_no_separator, rtrim_separator => rtrim_separator_no_separator ); // Generic data interface with integer and fraction digit separators. generic_data_interface!( struct GenericIFFastDataInterface, struct GenericIFSlowDataInterface, integer_iter => (IteratorSeparator, iterate_digits_ignore_separator), fraction_iter => (IteratorSeparator, iterate_digits_ignore_separator), exponent_iter => (IteratorNoSeparator, iterate_digits_no_separator), consume_integer_digits => consume_integer_digits_separator, consume_fraction_digits => consume_fraction_digits_separator, extract_exponent => extract_exponent_no_separator, ltrim_zero => ltrim_zero_separator, ltrim_separator => ltrim_separator_separator, rtrim_zero => rtrim_zero_separator, rtrim_separator => rtrim_separator_separator ); // Generic data interface with integer and exponent digit separators. generic_data_interface!( struct GenericIEFastDataInterface, struct GenericIESlowDataInterface, integer_iter => (IteratorSeparator, iterate_digits_ignore_separator), fraction_iter => (IteratorNoSeparator, iterate_digits_no_separator), exponent_iter => (IteratorSeparator, iterate_digits_ignore_separator), consume_integer_digits => consume_integer_digits_separator, consume_fraction_digits => consume_digits_no_separator, extract_exponent => extract_exponent_separator, ltrim_zero => ltrim_zero_separator, ltrim_separator => ltrim_separator_separator, rtrim_zero => rtrim_zero_separator, rtrim_separator => rtrim_separator_separator ); // Generic data interface with fraction and exponent digit separators. generic_data_interface!( struct GenericFEFastDataInterface, struct GenericFESlowDataInterface, integer_iter => (IteratorNoSeparator, iterate_digits_no_separator), fraction_iter => (IteratorSeparator, iterate_digits_ignore_separator), exponent_iter => (IteratorSeparator, iterate_digits_ignore_separator), consume_integer_digits => consume_digits_no_separator, consume_fraction_digits => consume_fraction_digits_separator, extract_exponent => extract_exponent_separator, ltrim_zero => ltrim_zero_separator, ltrim_separator => ltrim_separator_separator, rtrim_zero => rtrim_zero_separator, rtrim_separator => rtrim_separator_separator ); // Generic data interface with integer, fraction, and exponent digit separators. generic_data_interface!( struct GenericIFEFastDataInterface, struct GenericIFESlowDataInterface, integer_iter => (IteratorSeparator, iterate_digits_ignore_separator), fraction_iter => (IteratorSeparator, iterate_digits_ignore_separator), exponent_iter => (IteratorSeparator, iterate_digits_ignore_separator), consume_integer_digits => consume_integer_digits_separator, consume_fraction_digits => consume_fraction_digits_separator, extract_exponent => extract_exponent_separator, ltrim_zero => ltrim_zero_separator, ltrim_separator => ltrim_separator_separator, rtrim_zero => rtrim_zero_separator, rtrim_separator => rtrim_separator_separator ); // TESTS // ----- #[cfg(test)] mod tests { use super::*; macro_rules! generic { ($cls:ident, $integer:expr, $fraction:expr, $exponent:expr, $raw_exponent:expr) => { $cls { format: NumberFormat::default(), integer: $integer, fraction: $fraction, exponent: $exponent, raw_exponent: $raw_exponent } }; } #[test] fn extract_test() { type Generic<'a> = GenericFastDataInterface<'a>; let format = NumberFormat::from_separator(b'_'); Generic::new(format).run_tests([ // Valid ("1.2345", Ok(generic!(Generic, b"1", Some(b!("2345")), None, 0))), ("1009e-31", Ok(generic!(Generic, b"1009", None, Some(b!("-31")), -31))), // Invalid ("1.2_345e+10", Ok(generic!(Generic, b"1", Some(b!("2")), None, 0))), ("1_.2_345e+10", Ok(generic!(Generic, b"1", None, None, 0))), ("1.2345e+1_0", Ok(generic!(Generic, b"1", Some(b!("2345")), Some(b!("+1")), 1))) ].iter()) } #[test] fn extract_i_test() { type Generic<'a> = GenericIFastDataInterface<'a>; let format = NumberFormat::from_separator(b'_') | NumberFormat::INTEGER_DIGIT_SEPARATOR_FLAG_MASK; Generic::new(format).run_tests([ // Valid ("1.2345", Ok(generic!(Generic, b"1", Some(b!("2345")), None, 0))), ("1009e-31", Ok(generic!(Generic, b"1009", None, Some(b!("-31")), -31))), ("1_.2_345e+10", Ok(generic!(Generic, b"1_", Some(b!("2")), None, 0))), // Invalid ("1.2_345e+10", Ok(generic!(Generic, b"1", Some(b!("2")), None, 0))), ("1.2345e+1_0", Ok(generic!(Generic, b"1", Some(b!("2345")), Some(b!("+1")), 1))) ].iter()) } #[test] fn extract_f_test() { type Generic<'a> = GenericFFastDataInterface<'a>; let format = NumberFormat::from_separator(b'_') | NumberFormat::FRACTION_DIGIT_SEPARATOR_FLAG_MASK; Generic::new(format).run_tests([ // Valid ("1.2345", Ok(generic!(Generic, b"1", Some(b!("2345")), None, 0))), ("1009e-31", Ok(generic!(Generic, b"1009", None, Some(b!("-31")), -31))), ("1.2_345e+10", Ok(generic!(Generic, b"1", Some(b!("2_345")), Some(b!("+10")), 10))), // Invalid ("1_.2_345e+10", Ok(generic!(Generic, b"1", None, None, 0))), ("1.2345e+1_0", Ok(generic!(Generic, b"1", Some(b!("2345")), Some(b!("+1")), 1))) ].iter()) } #[test] fn extract_e_test() { type Generic<'a> = GenericEFastDataInterface<'a>; let format = NumberFormat::from_separator(b'_') | NumberFormat::EXPONENT_DIGIT_SEPARATOR_FLAG_MASK; Generic::new(format).run_tests([ // Valid ("1.2345", Ok(generic!(Generic, b"1", Some(b!("2345")), None, 0))), ("1009e-31", Ok(generic!(Generic, b"1009", None, Some(b!("-31")), -31))), ("1.2345e+1_0", Ok(generic!(Generic, b"1", Some(b!("2345")), Some(b!("+1_0")), 10))), // Invalid ("1_.2_345e+10", Ok(generic!(Generic, b"1", None, None, 0))), ("1.2_345e+10", Ok(generic!(Generic, b"1", Some(b!("2")), None, 0))) ].iter()) } #[test] fn extract_if_test() { type Generic<'a> = GenericIFFastDataInterface<'a>; let format = NumberFormat::from_separator(b'_') | NumberFormat::INTEGER_DIGIT_SEPARATOR_FLAG_MASK | NumberFormat::FRACTION_DIGIT_SEPARATOR_FLAG_MASK; Generic::new(format).run_tests([ // Valid ("1.2345", Ok(generic!(Generic, b"1", Some(b!("2345")), None, 0))), ("1009e-31", Ok(generic!(Generic, b"1009", None, Some(b!("-31")), -31))), ("1_.2_345e+10", Ok(generic!(Generic, b"1_", Some(b!("2_345")), Some(b!("+10")), 10))), ("1.2_345e+10", Ok(generic!(Generic, b"1", Some(b!("2_345")), Some(b!("+10")), 10))), // Invalid ("1.2345e+1_0", Ok(generic!(Generic, b"1", Some(b!("2345")), Some(b!("+1")), 1))) ].iter()) } #[test] fn extract_ie_test() { type Generic<'a> = GenericIEFastDataInterface<'a>; let format = NumberFormat::from_separator(b'_') | NumberFormat::INTEGER_DIGIT_SEPARATOR_FLAG_MASK | NumberFormat::EXPONENT_DIGIT_SEPARATOR_FLAG_MASK; Generic::new(format).run_tests([ // Valid ("1.2345", Ok(generic!(Generic, b"1", Some(b!("2345")), None, 0))), ("1009e-31", Ok(generic!(Generic, b"1009", None, Some(b!("-31")), -31))), ("1_.2345e+10", Ok(generic!(Generic, b"1_", Some(b!("2345")), Some(b!("+10")), 10))), ("1.2345e+1_0", Ok(generic!(Generic, b"1", Some(b!("2345")), Some(b!("+1_0")), 10))), // Invalid ("1.2_345e+10", Ok(generic!(Generic, b"1", Some(b!("2")), None, 0))) ].iter()) } #[test] fn extract_fe_test() { type Generic<'a> = GenericFEFastDataInterface<'a>; let format = NumberFormat::from_separator(b'_') | NumberFormat::FRACTION_DIGIT_SEPARATOR_FLAG_MASK | NumberFormat::EXPONENT_DIGIT_SEPARATOR_FLAG_MASK; Generic::new(format).run_tests([ // Valid ("1.2345", Ok(generic!(Generic, b"1", Some(b!("2345")), None, 0))), ("1009e-31", Ok(generic!(Generic, b"1009", None, Some(b!("-31")), -31))), ("1.2_345e+10", Ok(generic!(Generic, b"1", Some(b!("2_345")), Some(b!("+10")), 10))), ("1.2345e+1_0", Ok(generic!(Generic, b"1", Some(b!("2345")), Some(b!("+1_0")), 10))), // Invalid ("1_.2345e+10", Ok(generic!(Generic, b"1", None, None, 0))) ].iter()) } #[test] fn extract_ife_test() { type Generic<'a> = GenericIFEFastDataInterface<'a>; let format = NumberFormat::from_separator(b'_') | NumberFormat::INTEGER_DIGIT_SEPARATOR_FLAG_MASK | NumberFormat::FRACTION_DIGIT_SEPARATOR_FLAG_MASK | NumberFormat::EXPONENT_DIGIT_SEPARATOR_FLAG_MASK; Generic::new(format).run_tests([ // Valid ("1.2345", Ok(generic!(Generic, b"1", Some(b!("2345")), None, 0))), ("1009e-31", Ok(generic!(Generic, b"1009", None, Some(b!("-31")), -31))), ("1_.2345e+10", Ok(generic!(Generic, b"1_", Some(b!("2345")), Some(b!("+10")), 0))), ("1.2_345e+10", Ok(generic!(Generic, b"1", Some(b!("2_345")), Some(b!("+10")), 10))), ("1.2345e+1_0", Ok(generic!(Generic, b"1", Some(b!("2345")), Some(b!("+1_0")), 10))) ].iter()) } } lexical-core-0.7.6/src/atof/algorithm/format/ignore.rs000075500000000000000000000124310000000000000210150ustar 00000000000000//! Ignore float-parsing data interface. use crate::util::*; use super::exponent::*; use super::traits::*; use super::trim::*; use super::validate::*; // Ignore data interface for fast float parsers. // // Guaranteed to parse `NumberFormat::ignore(digit_separator)`. // // The requirements: // 1). Must contain significant digits. data_interface!( struct IgnoreFastDataInterface, struct IgnoreSlowDataInterface, fields => { format: NumberFormat, }, integer_iter => (IteratorSeparator, iterate_digits_ignore_separator), fraction_iter => (IteratorSeparator, iterate_digits_ignore_separator), exponent_iter => (IteratorSeparator, iterate_digits_ignore_separator), format => |this: &Self| this.format, consume_integer_digits => consume_digits_ignore_separator, consume_fraction_digits => consume_digits_ignore_separator, extract_exponent => extract_exponent_ignore_separator, validate_mantissa => validate_permissive_mantissa, validate_exponent => validate_optional_exponent, validate_exponent_fraction => validate_exponent_optional_fraction, validate_exponent_sign => validate_optional_exponent_sign, ltrim_zero => ltrim_zero_separator, ltrim_separator => ltrim_separator_separator, rtrim_zero => rtrim_zero_separator, rtrim_separator => rtrim_separator_separator, new => fn new(format: NumberFormat) -> Self { Self { format, integer: &[], fraction: None, exponent: None, raw_exponent: 0 } } ); // TESTS // ----- #[cfg(test)] mod tests { use super::*; macro_rules! ignore { ($integer:expr, $fraction:expr, $exponent:expr, $raw_exponent:expr) => { IgnoreFastDataInterface { format: NumberFormat::ignore(b'_').unwrap(), integer: $integer, fraction: $fraction, exponent: $exponent, raw_exponent: $raw_exponent } }; } #[test] fn extract_test() { IgnoreFastDataInterface::new(NumberFormat::ignore(b'_').unwrap()).run_tests([ // Valid ("1.2345", Ok(ignore!(b"1", Some(b!("2345")), None, 0))), ("12.345", Ok(ignore!(b"12", Some(b!("345")), None, 0))), ("12345.6789", Ok(ignore!(b"12345", Some(b!("6789")), None, 0))), ("1.2345e10", Ok(ignore!(b"1", Some(b!("2345")), Some(b!("10")), 10))), ("1.2345e+10", Ok(ignore!(b"1", Some(b!("2345")), Some(b!("+10")), 10))), ("1.2345e-10", Ok(ignore!(b"1", Some(b!("2345")), Some(b!("-10")), -10))), ("100000000000000000000", Ok(ignore!(b"100000000000000000000", None, None, 0))), ("100000000000000000001", Ok(ignore!(b"100000000000000000001", None, None, 0))), ("179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791.9999999999999999999999999999999999999999999999999999999999999999999999", Ok(ignore!(b"179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791", Some(b!("9999999999999999999999999999999999999999999999999999999999999999999999")), None, 0))), ("1009e-31", Ok(ignore!(b"1009", None, Some(b!("-31")), -31))), ("001.0", Ok(ignore!(b"1", Some(b!("")), None, 0))), ("1.", Ok(ignore!(b"1", Some(b!("")), None, 0))), ("12.", Ok(ignore!(b"12", Some(b!("")), None, 0))), ("1234567.", Ok(ignore!(b"1234567", Some(b!("")), None, 0))), (".1", Ok(ignore!(b"", Some(b!("1")), None, 0))), (".12", Ok(ignore!(b"", Some(b!("12")), None, 0))), (".1234567", Ok(ignore!(b"", Some(b!("1234567")), None, 0))), ("1.2345e", Ok(ignore!(b"1", Some(b!("2345")), Some(b!("")), 0))), (".3e", Ok(ignore!(b"", Some(b!("3")), Some(b!("")), 0))), ("_1.2345_e_+_10", Ok(ignore!(b"1", Some(b!("2345")), Some(b!("_+_10")), 10))), ("12__1_._23__45e+1__0_", Ok(ignore!(b"12__1_", Some(b!("_23__45")), Some(b!("+1__0_")), 10))), // Invalid ("", Err(ErrorCode::EmptyMantissa)), ("+", Err(ErrorCode::EmptyMantissa)), ("-", Err(ErrorCode::EmptyMantissa)), (".", Err(ErrorCode::EmptyMantissa)), ("+.", Err(ErrorCode::EmptyMantissa)), ("-.", Err(ErrorCode::EmptyMantissa)), ("e", Err(ErrorCode::EmptyMantissa)), ("E", Err(ErrorCode::EmptyMantissa)), ("e1", Err(ErrorCode::EmptyMantissa)), ("e+1", Err(ErrorCode::EmptyMantissa)), ("e-1", Err(ErrorCode::EmptyMantissa)), (".e", Err(ErrorCode::EmptyMantissa)), (".E", Err(ErrorCode::EmptyMantissa)), (".e1", Err(ErrorCode::EmptyMantissa)), (".e+1", Err(ErrorCode::EmptyMantissa)), (".e-1", Err(ErrorCode::EmptyMantissa)), ].iter()); } } lexical-core-0.7.6/src/atof/algorithm/format/interface.rs000075500000000000000000000041630000000000000214750ustar 00000000000000//! High-level data interface utilities. /// Convert format to interface, and call function with new item as first argument. #[cfg(not(feature = "format"))] macro_rules! apply_interface { ($fn:ident, $format:expr $(,$args:ident)*) => { $fn(StandardFastDataInterface::new($format) $(,$args)*) }; } /// Convert format to interface, and call function with new item as first argument. #[cfg(feature = "format")] macro_rules! apply_interface { ($fn:ident, $format:expr $(,$args:ident)*) => { match $format.interface_flags() { NumberFormat::PERMISSIVE_INTERFACE => $fn(PermissiveFastDataInterface::new($format) $(,$args)*), NumberFormat::STANDARD_INTERFACE => $fn(StandardFastDataInterface::new($format) $(,$args)*), NumberFormat::IGNORE_INTERFACE => $fn(IgnoreFastDataInterface::new($format) $(,$args)*), flags => { let integer = flags.intersects(NumberFormat::INTEGER_DIGIT_SEPARATOR_FLAG_MASK); let fraction = flags.intersects(NumberFormat::FRACTION_DIGIT_SEPARATOR_FLAG_MASK); let exponent = flags.intersects(NumberFormat::EXPONENT_DIGIT_SEPARATOR_FLAG_MASK); match (integer, fraction, exponent) { (true, true, true) => $fn(GenericIFEFastDataInterface::new($format) $(,$args)*), (false, true, true) => $fn(GenericFEFastDataInterface::new($format) $(,$args)*), (true, false, true) => $fn(GenericIEFastDataInterface::new($format) $(,$args)*), (true, true, false) => $fn(GenericIFFastDataInterface::new($format) $(,$args)*), (false, false, true) => $fn(GenericEFastDataInterface::new($format) $(,$args)*), (false, true, false) => $fn(GenericFFastDataInterface::new($format) $(,$args)*), (true, false, false) => $fn(GenericIFastDataInterface::new($format) $(,$args)*), (false, false, false) => $fn(GenericFastDataInterface::new($format) $(,$args)*) } } } }; } lexical-core-0.7.6/src/atof/algorithm/format/mod.rs000075500000000000000000000007550000000000000203170ustar 00000000000000//! Module specifying float. // Utilities. mod exponent; mod trim; mod validate; #[macro_use] mod interface; #[macro_use] mod traits; // Formats mod standard; cfg_if! { if #[cfg(feature = "format")] { mod generic; mod permissive; mod ignore; }} // Re-export interface and traits. pub(super) use standard::*; pub(super) use traits::*; cfg_if! { if #[cfg(feature = "format")] { pub(super) use generic::*; pub(super) use permissive::*; pub(super) use ignore::*; }} lexical-core-0.7.6/src/atof/algorithm/format/permissive.rs000075500000000000000000000121510000000000000217170ustar 00000000000000//! Permissive float-parsing data interface. use crate::util::*; use super::exponent::*; use super::traits::*; use super::trim::*; use super::validate::*; // Permissive data interface for fast float parsers. // // Guaranteed to parse `NumberFormat::permissive()`. // // The requirements: // 1). Must contain significant digits. // 2). Does not contain any digit separators. data_interface!( struct PermissiveFastDataInterface, struct PermissiveSlowDataInterface, fields => {}, integer_iter => (IteratorNoSeparator, iterate_digits_no_separator), fraction_iter => (IteratorNoSeparator, iterate_digits_no_separator), exponent_iter => (IteratorNoSeparator, iterate_digits_no_separator), format => |_| NumberFormat::default(), consume_integer_digits => consume_digits_no_separator, consume_fraction_digits => consume_digits_no_separator, extract_exponent => extract_exponent_no_separator, validate_mantissa => validate_permissive_mantissa, validate_exponent => validate_optional_exponent, validate_exponent_fraction => validate_exponent_optional_fraction, validate_exponent_sign => validate_optional_exponent_sign, ltrim_zero => ltrim_zero_no_separator, ltrim_separator => ltrim_separator_no_separator, rtrim_zero => rtrim_zero_no_separator, rtrim_separator => rtrim_separator_no_separator, new => fn new(format: NumberFormat) -> Self { Self { integer: &[], fraction: None, exponent: None, raw_exponent: 0 } } ); // TESTS // ----- #[cfg(test)] mod tests { use super::*; macro_rules! permissive { ($integer:expr, $fraction:expr, $exponent:expr, $raw_exponent:expr) => { PermissiveFastDataInterface { integer: $integer, fraction: $fraction, exponent: $exponent, raw_exponent: $raw_exponent } }; } #[test] fn extract_test() { PermissiveFastDataInterface::new(NumberFormat::permissive().unwrap()).run_tests([ // Valid ("1.2345", Ok(permissive!(b"1", Some(b!("2345")), None, 0))), ("12.345", Ok(permissive!(b"12", Some(b!("345")), None, 0))), ("12345.6789", Ok(permissive!(b"12345", Some(b!("6789")), None, 0))), ("1.2345e10", Ok(permissive!(b"1", Some(b!("2345")), Some(b!("10")), 10))), ("1.2345e+10", Ok(permissive!(b"1", Some(b!("2345")), Some(b!("+10")), 10))), ("1.2345e-10", Ok(permissive!(b"1", Some(b!("2345")), Some(b!("-10")), -10))), ("100000000000000000000", Ok(permissive!(b"100000000000000000000", None, None, 0))), ("100000000000000000001", Ok(permissive!(b"100000000000000000001", None, None, 0))), ("179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791.9999999999999999999999999999999999999999999999999999999999999999999999", Ok(permissive!(b"179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791", Some(b!("9999999999999999999999999999999999999999999999999999999999999999999999")), None, 0))), ("1009e-31", Ok(permissive!(b"1009", None, Some(b!("-31")), -31))), ("001.0", Ok(permissive!(b"1", Some(b!("")), None, 0))), ("1.", Ok(permissive!(b"1", Some(b!("")), None, 0))), ("12.", Ok(permissive!(b"12", Some(b!("")), None, 0))), ("1234567.", Ok(permissive!(b"1234567", Some(b!("")), None, 0))), (".1", Ok(permissive!(b"", Some(b!("1")), None, 0))), (".12", Ok(permissive!(b"", Some(b!("12")), None, 0))), (".1234567", Ok(permissive!(b"", Some(b!("1234567")), None, 0))), ("1.2345e", Ok(permissive!(b"1", Some(b!("2345")), Some(b!("")), 0))), (".3e", Ok(permissive!(b"", Some(b!("3")), Some(b!("")), 0))), // Invalid ("", Err(ErrorCode::EmptyMantissa)), ("+", Err(ErrorCode::EmptyMantissa)), ("-", Err(ErrorCode::EmptyMantissa)), (".", Err(ErrorCode::EmptyMantissa)), ("+.", Err(ErrorCode::EmptyMantissa)), ("-.", Err(ErrorCode::EmptyMantissa)), ("e", Err(ErrorCode::EmptyMantissa)), ("E", Err(ErrorCode::EmptyMantissa)), ("e1", Err(ErrorCode::EmptyMantissa)), ("e+1", Err(ErrorCode::EmptyMantissa)), ("e-1", Err(ErrorCode::EmptyMantissa)), (".e", Err(ErrorCode::EmptyMantissa)), (".E", Err(ErrorCode::EmptyMantissa)), (".e1", Err(ErrorCode::EmptyMantissa)), (".e+1", Err(ErrorCode::EmptyMantissa)), (".e-1", Err(ErrorCode::EmptyMantissa)), ].iter()); } } lexical-core-0.7.6/src/atof/algorithm/format/standard.rs000075500000000000000000000174770000000000000213510ustar 00000000000000//! Standard float-parsing data interface. use crate::util::*; use super::exponent::*; use super::traits::*; use super::trim::*; use super::validate::*; // Standard data interface for fast float parsers. // // Guaranteed to parse `NumberFormat::standard()`, and // therefore will track that exact specification. // // The requirements: // 1). Must contain significant digits. // 2). Must contain exponent digits if an exponent is present. // 3). Does not contain any digit separators. data_interface!( struct StandardFastDataInterface, struct StandardSlowDataInterface, fields => {}, integer_iter => (IteratorNoSeparator, iterate_digits_no_separator), fraction_iter => (IteratorNoSeparator, iterate_digits_no_separator), exponent_iter => (IteratorNoSeparator, iterate_digits_no_separator), format => |_| NumberFormat::default(), consume_integer_digits => consume_digits_no_separator, consume_fraction_digits => consume_digits_no_separator, extract_exponent => extract_exponent_no_separator, validate_mantissa => validate_permissive_mantissa, validate_exponent => validate_required_exponent, validate_exponent_fraction => validate_exponent_optional_fraction, validate_exponent_sign => validate_optional_exponent_sign, ltrim_zero => ltrim_zero_no_separator, ltrim_separator => ltrim_separator_no_separator, rtrim_zero => rtrim_zero_no_separator, rtrim_separator => rtrim_separator_no_separator, new => fn new(format: NumberFormat) -> Self { Self { integer: &[], fraction: None, exponent: None, raw_exponent: 0 } } ); // FROM type DataTuple<'a> = (&'a [u8], Option<&'a [u8]>, Option<&'a [u8]>, i32); // Add `From` to remove repition in unit-testing. impl<'a> From> for StandardFastDataInterface<'a> { perftools_inline!{ fn from(data: DataTuple<'a>) -> Self { StandardFastDataInterface { integer: data.0, fraction: data.1, exponent: data.2, raw_exponent: data.3 } }} } // TESTS // ----- #[cfg(test)] mod tests { use super::*; macro_rules! standard { ($integer:expr, $fraction:expr, $exponent:expr, $raw_exponent:expr) => { StandardFastDataInterface { integer: $integer, fraction: $fraction, exponent: $exponent, raw_exponent: $raw_exponent } }; } #[test] fn extract_test() { StandardFastDataInterface::new(NumberFormat::standard().unwrap()).run_tests([ // Valid ("1.2345", Ok(standard!(b"1", Some(b!("2345")), None, 0))), ("12.345", Ok(standard!(b"12", Some(b!("345")), None, 0))), ("12345.6789", Ok(standard!(b"12345", Some(b!("6789")), None, 0))), ("1.2345e10", Ok(standard!(b"1", Some(b!("2345")), Some(b!("10")), 10))), ("1.2345e+10", Ok(standard!(b"1", Some(b!("2345")), Some(b!("+10")), 10))), ("1.2345e-10", Ok(standard!(b"1", Some(b!("2345")), Some(b!("-10")), -10))), ("100000000000000000000", Ok(standard!(b"100000000000000000000", None, None, 0))), ("100000000000000000001", Ok(standard!(b"100000000000000000001", None, None, 0))), ("179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791.9999999999999999999999999999999999999999999999999999999999999999999999", Ok(standard!(b"179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791", Some(b!("9999999999999999999999999999999999999999999999999999999999999999999999")), None, 0))), ("1009e-31", Ok(standard!(b"1009", None, Some(b!("-31")), -31))), ("001.0", Ok(standard!(b"1", Some(b!("")), None, 0))), ("1.", Ok(standard!(b"1", Some(b!("")), None, 0))), ("12.", Ok(standard!(b"12", Some(b!("")), None, 0))), ("1234567.", Ok(standard!(b"1234567", Some(b!("")), None, 0))), (".1", Ok(standard!(b"", Some(b!("1")), None, 0))), (".12", Ok(standard!(b"", Some(b!("12")), None, 0))), (".1234567", Ok(standard!(b"", Some(b!("1234567")), None, 0))), // Invalid ("1.2345e", Err(ErrorCode::EmptyExponent)), ("", Err(ErrorCode::EmptyMantissa)), ("+", Err(ErrorCode::EmptyMantissa)), ("-", Err(ErrorCode::EmptyMantissa)), (".", Err(ErrorCode::EmptyMantissa)), ("+.", Err(ErrorCode::EmptyMantissa)), ("-.", Err(ErrorCode::EmptyMantissa)), ("e", Err(ErrorCode::EmptyMantissa)), ("E", Err(ErrorCode::EmptyMantissa)), ("e1", Err(ErrorCode::EmptyMantissa)), ("e+1", Err(ErrorCode::EmptyMantissa)), ("e-1", Err(ErrorCode::EmptyMantissa)), (".e", Err(ErrorCode::EmptyMantissa)), (".E", Err(ErrorCode::EmptyMantissa)), (".e1", Err(ErrorCode::EmptyMantissa)), (".e+1", Err(ErrorCode::EmptyMantissa)), (".e-1", Err(ErrorCode::EmptyMantissa)), (".3e", Err(ErrorCode::EmptyExponent)) ].iter()); } #[test] fn fast_data_interface_test() { type Data<'a> = StandardFastDataInterface<'a>; // Check "1.2345". let data = Data { integer: b"1", fraction: Some(b!("2345")), exponent: None, raw_exponent: 0 }; assert!(data.integer_iter().eq(b"1".iter())); assert!(data.fraction_iter().eq(b"2345".iter())); #[cfg(feature = "correct")] assert_eq!(data.digits_start(), 0); } #[cfg(feature = "correct")] #[test] fn slow_data_interface_test() { type Data<'a> = StandardSlowDataInterface<'a>; // Check "1.2345", simple. let data = Data { integer: b"1", fraction: b"2345", digits_start: 0, truncated_digits: 0, raw_exponent: 0 }; assert_eq!(data.integer_digits(), 1); assert!(data.integer_iter().eq(b"1".iter())); assert_eq!(data.fraction_digits(), 4); assert!(data.fraction_iter().eq(b"2345".iter())); assert_eq!(data.significant_fraction_digits(), 4); assert!(data.significant_fraction_iter().eq(b"2345".iter())); assert_eq!(data.mantissa_digits(), 5); assert_eq!(data.digits_start(), 0); assert_eq!(data.truncated_digits(), 0); assert_eq!(data.raw_exponent(), 0); assert_eq!(data.mantissa_exponent(), -4); assert_eq!(data.scientific_exponent(), 0); // Check "0.12345", simple. let data = Data { integer: b"", fraction: b"12345", digits_start: 0, truncated_digits: 0, raw_exponent: 0 }; assert_eq!(data.integer_digits(), 0); assert!(data.integer_iter().eq(b"".iter())); assert_eq!(data.fraction_digits(), 5); assert!(data.fraction_iter().eq(b"12345".iter())); assert_eq!(data.significant_fraction_digits(), 5); assert!(data.significant_fraction_iter().eq(b"12345".iter())); assert_eq!(data.mantissa_digits(), 5); assert_eq!(data.digits_start(), 0); assert_eq!(data.truncated_digits(), 0); assert_eq!(data.raw_exponent(), 0); assert_eq!(data.mantissa_exponent(), -5); assert_eq!(data.scientific_exponent(), -1); } } lexical-core-0.7.6/src/atof/algorithm/format/traits.rs000075500000000000000000000541060000000000000210450ustar 00000000000000//! Traits that provide format-dependent data for floating parsing algorithms. use crate::util::*; #[cfg(feature = "correct")] use super::exponent::*; /// Private data interface for local utilities. pub(crate) trait FastDataInterfaceImpl<'a>: Sized { /// Get integer component of float. fn integer(&self) -> &'a [u8]; /// Set integer component of float. fn set_integer(&mut self, integer: &'a [u8]); /// Get fraction component of float. fn fraction(&self) -> Option<&'a [u8]>; /// Set fraction component of float. fn set_fraction(&mut self, fraction: Option<&'a [u8]>); /// Get exponent component of float. fn exponent(&self) -> Option<&'a [u8]>; /// Set exponent component of float. fn set_exponent(&mut self, exponent: Option<&'a [u8]>); /// Get raw exponent component of float. fn raw_exponent(&self) -> i32; /// Set raw exponent component of float. fn set_raw_exponent(&mut self, raw_exponent: i32); } /// Private data interface for local utilities. #[cfg(feature = "correct")] pub(crate) trait SlowDataInterfaceImpl<'a>: Sized { /// Get integer component of float. fn integer(&self) -> &'a [u8]; /// Set integer component of float. fn set_integer(&mut self, integer: &'a [u8]); /// Get fraction component of float. fn fraction(&self) -> &'a [u8]; /// Set fraction component of float. fn set_fraction(&mut self, fraction: &'a [u8]); /// Get raw exponent component of float. fn raw_exponent(&self) -> i32; /// Set raw exponent component of float. fn set_raw_exponent(&mut self, raw_exponent: i32); } // Implement FastDataInterfaceImpl for a default structure. macro_rules! fast_data_interface_impl { ($name:ident) => ( impl<'a> FastDataInterfaceImpl<'a> for $name<'a> { perftools_inline!{ fn integer(&self) -> &'a [u8] { self.integer }} perftools_inline!{ fn set_integer(&mut self, integer: &'a [u8]) { self.integer = integer }} perftools_inline!{ fn fraction(&self) -> Option<&'a [u8]> { self.fraction }} perftools_inline!{ fn set_fraction(&mut self, fraction: Option<&'a [u8]>) { self.fraction = fraction }} perftools_inline!{ fn exponent(&self) -> Option<&'a [u8]> { self.exponent }} perftools_inline!{ fn set_exponent(&mut self, exponent: Option<&'a [u8]>) { self.exponent = exponent }} perftools_inline!{ fn raw_exponent(&self) -> i32 { self.raw_exponent }} perftools_inline!{ fn set_raw_exponent(&mut self, raw_exponent: i32) { self.raw_exponent = raw_exponent }} } ); } // Implement SlowDataInterfaceImpl for a default structure. #[cfg(feature = "correct")] macro_rules! slow_data_interface_impl { ($name:ident) => ( impl<'a> SlowDataInterfaceImpl<'a> for $name<'a> { perftools_inline!{ fn integer(&self) -> &'a [u8] { self.integer }} perftools_inline!{ fn set_integer(&mut self, integer: &'a [u8]) { self.integer = integer }} perftools_inline!{ fn fraction(&self) -> &'a [u8] { self.fraction }} perftools_inline!{ fn set_fraction(&mut self, fraction: &'a [u8]) { self.fraction = fraction }} perftools_inline!{ fn raw_exponent(&self) -> i32 { self.raw_exponent }} perftools_inline!{ fn set_raw_exponent(&mut self, raw_exponent: i32) { self.raw_exponent = raw_exponent }} } ); } // PUBLIC /// Data interface for fast float parsers. pub(crate) trait FastDataInterface<'a>: FastDataInterfaceImpl<'a> { /// Integer digits iterator type. type IntegerIter: ConsumedIterator + AsPtrIterator<'a, u8>; /// Float digits iterator type. type FractionIter: ConsumedIterator + AsPtrIterator<'a, u8>; /// Exponent digits iterator type. type ExponentIter: ConsumedIterator + AsPtrIterator<'a, u8>; /// Associated slow data type. #[cfg(feature = "correct")] type SlowInterface: SlowDataInterface<'a>; /// Create new float data from format specification. fn new(format: NumberFormat) -> Self; // DATA /// Iterate over all integer digits. fn integer_iter(&self) -> Self::IntegerIter; /// Iterate over all fraction digits fn fraction_iter(&self) -> Self::FractionIter; /// Iterate over all exponent digits fn exponent_iter(&self) -> Self::ExponentIter; /// Get the number format. fn format(&self) -> NumberFormat; perftools_inline!{ /// Get the mantissa exponent from the raw exponent. #[cfg(feature = "correct")] fn mantissa_exponent(&self, truncated_digits: usize) -> i32 { mantissa_exponent(self.raw_exponent(), self.fraction_iter().count(), truncated_digits) }} // EXTRACT // Consume integer digits until a non-digit character is found. fn consume_integer_digits(&self, bytes: &'a [u8], radix: u32) -> (&'a [u8], &'a [u8]); // Consume fraction digits until a non-digit character is found. fn consume_fraction_digits(&self, bytes: &'a [u8], radix: u32) -> (&'a [u8], &'a [u8]); // Extract the integer substring from the float. perftools_inline!{ fn extract_integer(&mut self, bytes: &'a [u8], radix: u32) -> &'a [u8] { let result = self.consume_integer_digits(bytes, radix); self.set_integer(result.0); result.1 }} // Extract the fraction substring from the float. // // Preconditions: // `bytes.len()` >= 1 and `bytes[0] == b'.'`. perftools_inline!{ fn extract_fraction(&mut self, bytes: &'a [u8], radix: u32) -> &'a [u8] { let digits = &index!(bytes[1..]); let result = self.consume_fraction_digits(digits, radix); self.set_fraction(Some(result.0)); result.1 }} // Extract and parse the exponent substring from the float. fn extract_exponent(&mut self, bytes: &'a [u8], radix: u32) -> &'a [u8]; // Validate the extracted mantissa components. fn validate_mantissa(&self) -> ParseResult<()>; // Validate the extracted exponent component. fn validate_exponent(&self) -> ParseResult<()>; // Validate the extracted exponent depending on the fraction component. fn validate_exponent_fraction(&self) -> ParseResult<()>; // Validate the extracted exponent sign. fn validate_exponent_sign(&self) -> ParseResult<()>; // Trim leading 0s and digit separators. fn ltrim_zero(&self, bytes: &'a [u8]) -> (&'a [u8], usize); // Trim leading digit separators. fn ltrim_separator(&self, bytes: &'a [u8]) -> (&'a [u8], usize); // Trim trailing 0s and digit separators. fn rtrim_zero(&self, bytes: &'a [u8]) -> (&'a [u8], usize); // Trim trailing digit separators. fn rtrim_separator(&self, bytes: &'a [u8]) -> (&'a [u8], usize); // Post-process float to trim leading and trailing 0s and digit separators. // This is required for accurate results in the slow-path algorithm, // otherwise, we may incorrect guess the mantissa or scientific exponent. perftools_inline!{ fn trim(&mut self) { self.set_integer(self.ltrim_zero(self.integer()).0); self.set_fraction(self.fraction().map(|x| self.rtrim_zero(x).0)); }} perftools_inline!{ /// Extract float subcomponents from input bytes. fn extract(&mut self, bytes: &'a [u8], radix: u32) -> ParseResult<*const u8> { // Parse the integer, aka, the digits preceding any control characters. let mut digits = bytes; digits = self.extract_integer(digits, radix); // Parse and validate a fraction, if present. let exp_char = exponent_notation_char(radix).to_ascii_lowercase(); if let Some(&b'.') = digits.first() { digits = self.extract_fraction(digits, radix); } self.validate_mantissa()?; // Parse and validate an exponent, if present. if let Some(&c) = digits.first() { if c.to_ascii_lowercase() == exp_char { digits = self.extract_exponent(digits, radix); } } self.validate_exponent()?; self.validate_exponent_fraction()?; self.validate_exponent_sign()?; // Trim the remaining digits. self.trim(); Ok(digits.as_ptr()) }} // TO SLOW DATA // Calculate the digit start from the integer and fraction slices. perftools_inline!{ #[cfg(feature = "correct")] fn digits_start(&self) -> usize { // If there are no returned values in the integer iterator // since we've trimmed leading 0s, then we have to trim // leading zeros to get to the start of the significant // digits in the fraction. match self.integer().is_empty() { true => self.ltrim_zero(self.fraction().unwrap_or(&[])).1, false => 0, } }} /// Process float data for moderate/slow float parsers. #[cfg(feature = "correct")] fn to_slow(self, truncated_digits: usize) -> Self::SlowInterface; // TESTS #[cfg(test)] fn clear(&mut self) { self.set_integer(&[]); self.set_fraction(None); self.set_exponent(None); self.set_raw_exponent(0); } /// Check the float state parses the desired data. #[cfg(test)] fn check_extract(&mut self, digits: &'a [u8], expected: &ParseTestResult) { let expected = expected.as_ref(); match self.extract(digits, 10) { Ok(_) => { let expected = expected.unwrap(); assert_eq!(self.integer(), expected.integer()); assert_eq!(self.fraction(), expected.fraction()); assert_eq!(self.exponent(), expected.exponent()); }, Err((c, _)) => assert_eq!(c, *expected.err().unwrap()), } } // Run series of tests. #[cfg(test)] fn run_tests(&mut self, tests: Iter) where Iter: Iterator)>, Self: 'a { for value in tests { self.check_extract(value.0.as_bytes(), &value.1); self.clear(); } } } /// Shared definition for all fast data interfaces. macro_rules! fast_data_interface { ( struct $name:ident, fields => { $( $field:ident : $type:tt, )* }, integer_iter => ( $integer_iter:tt, $integer_iter_fn:ident ), fraction_iter => ( $fraction_iter:tt, $fraction_iter_fn:ident ), exponent_iter => ( $exponent_iter:tt, $exponent_iter_fn:ident ), format => $format:expr, slow_interface => $slow_interface:tt, consume_integer_digits => $consume_integer_digits:expr, consume_fraction_digits => $consume_fraction_digits:expr, extract_exponent => $extract_exponent:expr, validate_mantissa => $validate_mantissa:expr, validate_exponent => $validate_exponent:expr, validate_exponent_fraction => $validate_exponent_fraction:expr, validate_exponent_sign => $validate_exponent_sign:expr, ltrim_zero => $ltrim_zero:ident, ltrim_separator => $ltrim_separator:ident, rtrim_zero => $rtrim_zero:ident, rtrim_separator => $rtrim_separator:ident, new => $($new:tt)* ) => ( pub(crate) struct $name<'a> { $( $field : $type, )* integer: &'a [u8], fraction: Option<&'a [u8]>, exponent: Option<&'a [u8]>, raw_exponent: i32 } fast_data_interface_impl!($name); impl<'a> FastDataInterface<'a> for $name<'a> { type IntegerIter = $integer_iter<'a>; type FractionIter = $fraction_iter<'a>; type ExponentIter = $exponent_iter<'a>; #[cfg(feature = "correct")] type SlowInterface = $slow_interface<'a>; perftools_inline!{ #[allow(unused_variables)] $($new)* } // DATA perftools_inline!{ fn integer_iter(&self) -> Self::IntegerIter { $integer_iter_fn(self.integer, self.format().digit_separator()) }} perftools_inline!{ fn fraction_iter(&self) -> Self::FractionIter { let fraction = self.fraction.unwrap_or(&[]); $fraction_iter_fn(fraction, self.format().digit_separator()) }} perftools_inline!{ fn exponent_iter(&self) -> Self::ExponentIter { let exponent = self.exponent.unwrap_or(&[]); $exponent_iter_fn(exponent, self.format().digit_separator()) }} perftools_inline!{ fn format(&self) -> NumberFormat { $format(self) }} perftools_inline!{ fn consume_integer_digits(&self, digits: &'a [u8], radix: u32) -> (&'a [u8], &'a [u8]) { $consume_integer_digits(digits, radix, self.format()) }} perftools_inline!{ fn consume_fraction_digits(&self, digits: &'a [u8], radix: u32) -> (&'a [u8], &'a [u8]) { $consume_fraction_digits(digits, radix, self.format()) }} perftools_inline!{ fn extract_exponent(&mut self, bytes: &'a [u8], radix: u32) -> &'a [u8] { $extract_exponent(self, bytes, radix, self.format()) }} perftools_inline!{ fn validate_mantissa(&self) -> ParseResult<()> { $validate_mantissa(self) }} perftools_inline!{ fn validate_exponent(&self) -> ParseResult<()> { $validate_exponent(self) }} perftools_inline!{ fn validate_exponent_fraction(&self) -> ParseResult<()> { $validate_exponent_fraction(self) }} perftools_inline!{ fn validate_exponent_sign(&self) -> ParseResult<()> { $validate_exponent_sign(self) }} perftools_inline!{ fn ltrim_zero(&self, bytes: &'a [u8]) -> (&'a [u8], usize) { $ltrim_zero(bytes, self.format().digit_separator()) }} perftools_inline!{ fn ltrim_separator(&self, bytes: &'a [u8]) -> (&'a [u8], usize) { $ltrim_separator(bytes, self.format().digit_separator()) }} perftools_inline!{ fn rtrim_zero(&self, bytes: &'a [u8]) -> (&'a [u8], usize) { $rtrim_zero(bytes, self.format().digit_separator()) }} perftools_inline!{ fn rtrim_separator(&self, bytes: &'a [u8]) -> (&'a [u8], usize) { $rtrim_separator(bytes, self.format().digit_separator()) }} // TO SLOW DATA #[cfg(feature = "correct")] perftools_inline!{ fn to_slow(self, truncated_digits: usize) -> Self::SlowInterface { let digits_start = self.digits_start(); Self::SlowInterface { $( $field: self.$field, )* digits_start, truncated_digits, integer: self.integer, fraction: self.fraction.unwrap_or(&[]), raw_exponent: self.raw_exponent } }} } ); } /// Data interface for moderate/slow float parsers. #[cfg(feature = "correct")] pub(crate) trait SlowDataInterface<'a>: SlowDataInterfaceImpl<'a> { /// Integer digits iterator type. type IntegerIter: ConsumedIterator + AsPtrIterator<'a, u8>; /// Float digits iterator type. type FractionIter: ConsumedIterator + AsPtrIterator<'a, u8>; /// Iterate over all integer digits. fn integer_iter(&self) -> Self::IntegerIter; perftools_inline!{ /// Get number of all integer digits. fn integer_digits(&self) -> usize { self.integer_iter().count() }} /// Iterate over all fraction digits fn fraction_iter(&self) -> Self::FractionIter; perftools_inline!{ /// Get number of all fraction digits. fn fraction_digits(&self) -> usize { self.fraction_iter().count() }} /// Iterate over significant fraction digits. fn significant_fraction_iter(&self) -> Self::FractionIter; perftools_inline!{ /// Get number of significant fraction digits. fn significant_fraction_digits(&self) -> usize { self.significant_fraction_iter().count() }} perftools_inline!{ /// Get the number of digits in the mantissa. /// Cannot overflow, since this is based off a single usize input string. fn mantissa_digits(&self) -> usize { self.integer_digits() + self.significant_fraction_digits() }} /// Get the number format. fn format(&self) -> NumberFormat; /// Get index to start of significant digits in the fraction. fn digits_start(&self) -> usize; /// Get number of truncated digits. fn truncated_digits(&self) -> usize; perftools_inline!{ /// Get the mantissa exponent from the raw exponent. fn mantissa_exponent(&self) -> i32 { mantissa_exponent(self.raw_exponent(), self.fraction_digits(), self.truncated_digits()) }} perftools_inline!{ /// Get the scientific exponent from the raw exponent. fn scientific_exponent(&self) -> i32 { scientific_exponent(self.raw_exponent(), self.integer_digits(), self.digits_start()) }} } /// Shared definition for all slow data interfaces. macro_rules! slow_data_interface { ( struct $name:ident, fields => { $( $field:ident : $type:tt, )* }, integer_iter => ( $integer_iter:tt, $integer_iter_fn:ident ), fraction_iter => ( $fraction_iter:tt, $fraction_iter_fn:ident ), format => $format:expr ) => ( #[cfg(feature = "correct")] pub(crate) struct $name<'a> { $( $field : $type, )* integer: &'a [u8], fraction: &'a [u8], digits_start: usize, truncated_digits: usize, raw_exponent: i32 } #[cfg(feature = "correct")] slow_data_interface_impl!($name); #[cfg(feature = "correct")] impl<'a> SlowDataInterface<'a> for $name<'a> { type IntegerIter = $integer_iter<'a>; type FractionIter = $fraction_iter<'a>; // DATA perftools_inline!{ fn integer_iter(&self) -> Self::IntegerIter { $integer_iter_fn(self.integer, self.format().digit_separator()) }} perftools_inline!{ fn fraction_iter(&self) -> Self::FractionIter { $fraction_iter_fn(self.fraction, self.format().digit_separator()) }} perftools_inline!{ fn significant_fraction_iter(&self) -> Self::FractionIter { let fraction = &index!(self.fraction[self.digits_start..]); $fraction_iter_fn(fraction, self.format().digit_separator()) }} perftools_inline!{ fn format(&self) -> NumberFormat { $format(self) }} perftools_inline!{ fn digits_start(&self) -> usize { self.digits_start }} perftools_inline!{ fn truncated_digits(&self) -> usize { self.truncated_digits }} } ); } /// Shared definition for all data interfaces. macro_rules! data_interface { ( struct $fast:ident, struct $slow:ident, fields => { $( $field:ident : $type:tt, )* }, integer_iter => ( $integer_iter:tt, $integer_iter_fn:ident ), fraction_iter => ( $fraction_iter:tt, $fraction_iter_fn:ident ), exponent_iter => ( $exponent_iter:tt, $exponent_iter_fn:ident ), format => $format:expr, consume_integer_digits => $consume_integer_digits:expr, consume_fraction_digits => $consume_fraction_digits:expr, extract_exponent => $extract_exponent:expr, validate_mantissa => $validate_mantissa:expr, validate_exponent => $validate_exponent:expr, validate_exponent_fraction => $validate_exponent_fraction:expr, validate_exponent_sign => $validate_exponent_sign:expr, ltrim_zero => $ltrim_zero:ident, ltrim_separator => $ltrim_separator:ident, rtrim_zero => $rtrim_zero:ident, rtrim_separator => $rtrim_separator:ident, new => $($new:tt)* ) => ( fast_data_interface!( struct $fast, fields => { $( $field : $type , )* }, integer_iter => ($integer_iter, $integer_iter_fn), fraction_iter => ($fraction_iter, $fraction_iter_fn), exponent_iter => ($exponent_iter, $exponent_iter_fn), format => $format, slow_interface => $slow, consume_integer_digits => $consume_integer_digits, consume_fraction_digits => $consume_fraction_digits, extract_exponent => $extract_exponent, validate_mantissa => $validate_mantissa, validate_exponent => $validate_exponent, validate_exponent_fraction => $validate_exponent_fraction, validate_exponent_sign => $validate_exponent_sign, ltrim_zero => $ltrim_zero, ltrim_separator => $ltrim_separator, rtrim_zero => $rtrim_zero, rtrim_separator => $rtrim_separator, new => $($new)* ); slow_data_interface!( struct $slow, fields => { $( $field : $type , )* }, integer_iter => ($integer_iter, $integer_iter_fn), fraction_iter => ($fraction_iter, $fraction_iter_fn), format => $format ); ); } lexical-core-0.7.6/src/atof/algorithm/format/trim.rs000075500000000000000000000056200000000000000205070ustar 00000000000000//! Trim leading and trailing 0s and digit separators. use crate::util::*; // TRIM // Trim leading 0s. // Does not consume any digit separators. perftools_inline!{ pub(super) fn ltrim_zero_no_separator<'a>(bytes: &'a [u8], _: u8) -> (&'a [u8], usize) { ltrim_char_slice(bytes, b'0') }} // Trim leading 0s and digit separators. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn ltrim_zero_separator<'a>(bytes: &'a [u8], digit_separator: u8) -> (&'a [u8], usize) { ltrim_char2_slice(bytes, b'0', digit_separator) }} // Trim leading digit separators (so, nothing). // Does not consume any digit separators. perftools_inline!{ pub(super) fn ltrim_separator_no_separator<'a>(bytes: &'a [u8], _: u8) -> (&'a [u8], usize) { (bytes, 0) }} // Trim leading digit separators. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn ltrim_separator_separator<'a>(bytes: &'a [u8], digit_separator: u8) -> (&'a [u8], usize) { ltrim_char_slice(bytes, digit_separator) }} // Trim trailing 0s. // Does not consume any digit separators. perftools_inline!{ pub(super) fn rtrim_zero_no_separator<'a>(bytes: &'a [u8], _: u8) -> (&'a [u8], usize) { rtrim_char_slice(bytes, b'0') }} // Trim trailing 0s and digit separators. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn rtrim_zero_separator<'a>(bytes: &'a [u8], digit_separator: u8) -> (&'a [u8], usize) { rtrim_char2_slice(bytes, b'0', digit_separator) }} // Trim trailing digit separators (so, nothing). // Does not consume any digit separators. perftools_inline!{ pub(super) fn rtrim_separator_no_separator<'a>(bytes: &'a [u8], _: u8) -> (&'a [u8], usize) { (bytes, 0) }} // Trim trailing digit separators. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn rtrim_separator_separator<'a>(bytes: &'a [u8], digit_separator: u8) -> (&'a [u8], usize) { rtrim_char_slice(bytes, digit_separator) }} // TESTS // ----- #[cfg(test)] mod tests { use super::*; #[test] fn trim_zero_no_separator_test() { assert_eq!(ltrim_zero_no_separator(b!("01"), b'_'), (b!("1"), 1)); assert_eq!(rtrim_zero_no_separator(b!("23450"), b'_'), (b!("2345"), 1)); } #[test] fn trim_separator_no_separator_test() { assert_eq!(ltrim_separator_no_separator(b!("01"), b'_'), (b!("01"), 0)); assert_eq!(rtrim_separator_no_separator(b!("23450"), b'_'), (b!("23450"), 0)); } #[test] #[cfg(feature = "format")] fn trim_zero_iltc_separator_test() { assert_eq!(ltrim_zero_separator(b!("0_1_2"), b'_'), (b!("1_2"), 2)); assert_eq!(rtrim_zero_separator(b!("2345_0_"), b'_'), (b!("2345"), 3)); } #[test] #[cfg(feature = "format")] fn trim_separator_iltc_separator_test() { assert_eq!(ltrim_separator_separator(b!("0_1_2"), b'_'), (b!("0_1_2"), 0)); assert_eq!(rtrim_separator_separator(b!("2345_0_"), b'_'), (b!("2345_0"), 1)); } } lexical-core-0.7.6/src/atof/algorithm/format/validate.rs000075500000000000000000000467310000000000000213350ustar 00000000000000//! Validate buffers and other information. use crate::util::*; use super::traits::*; // HELPERS // Determine if the integer component is empty. perftools_inline!{ fn is_integer_empty<'a, Data>(data: &Data) -> bool where Data: FastDataInterface<'a> { data.integer_iter().next().is_none() }} // Determine if the fraction component is empty. perftools_inline!{ fn is_fraction_empty<'a, Data>(data: &Data) -> bool where Data: FastDataInterface<'a> { data.fraction_iter().next().is_none() }} // Determine if the fraction component exists. perftools_inline!{ #[cfg(feature = "format")] fn has_fraction<'a, Data>(data: &Data) -> bool where Data: FastDataInterface<'a> { data.fraction().is_some() }} // Determine if the exponent component exists. perftools_inline!{ fn has_exponent<'a, Data>(data: &Data) -> bool where Data: FastDataInterface<'a> { data.exponent().is_some() }} // Unwrap option to get the pointer. perftools_inline!{ fn option_as_ptr(option: Option<&[u8]>) -> *const u8 { option.unwrap().as_ptr() }} // MANTISSA // Validate the extracted integer has no leading zeros. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_no_leading_zeros<'a, Data>(data: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { // Check if the next character is a sign symbol. let mut iter = data.integer_iter(); match iter.next() { Some(&b'0') => (), _ => return Ok(()) }; // Only here if we have a leading 0 symbol. match iter.next() { Some(_) => Err((ErrorCode::InvalidLeadingZeros, data.integer().as_ptr())), None => Ok(()) } }} // Validate the extracted mantissa float components. // 1. Validate non-empty significant digits (integer or fraction). perftools_inline!{ pub(super) fn validate_permissive_mantissa<'a, Data>(data: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { let integer_empty = is_integer_empty(data); let fraction_empty = is_fraction_empty(data); if integer_empty && fraction_empty { // Invalid floating-point number, no integer or fraction components. Err((ErrorCode::EmptyMantissa, data.integer().as_ptr())) } else { Ok(()) } }} // Validate the extracted mantissa float components. // 1. Validate integer component is non-empty. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_required_integer<'a, Data>(data: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { if is_integer_empty(data) { // Invalid floating-point number, no integer component. Err((ErrorCode::EmptyInteger, data.integer().as_ptr())) } else { Ok(()) } }} // Validate the extracted mantissa float components. // 1. Validate fraction component is non-empty if present. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_required_fraction<'a, Data>(data: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { if has_fraction(data) && is_fraction_empty(data) { // Invalid floating-point number, no fraction component. Err((ErrorCode::EmptyFraction, option_as_ptr(data.fraction()))) } else { Ok(()) } }} // Validate the extracted mantissa float components. // 1. Validate integer component is non-empty. // 2. Validate fraction component is non-empty if present. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_required_digits<'a, Data>(data: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { if is_integer_empty(data) { // Invalid floating-point number, no integer component. Err((ErrorCode::EmptyInteger, data.integer().as_ptr())) } else if has_fraction(data) && is_fraction_empty(data) { // Invalid floating-point number, no fraction component. Err((ErrorCode::EmptyFraction, option_as_ptr(data.fraction()))) } else { Ok(()) } }} // Validate mantissa depending on float format. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_mantissa<'a, Data>(data: &Data, format: NumberFormat) -> ParseResult<()> where Data: FastDataInterface<'a> { // Check no leading zeros. if format.no_float_leading_zeros() { validate_no_leading_zeros(data)?; } // Check required digits. let required_integer = format.required_integer_digits(); let required_fraction = format.required_fraction_digits(); match (required_integer, required_fraction) { (true, true) => validate_required_digits(data), (false, true) => validate_required_fraction(data), (true, false) => validate_required_integer(data), (false, false) => validate_permissive_mantissa(data) } }} // EXPONENT // Validate the required exponent component. // 1). If the exponent has been defined, ensure at least 1 digit follows it. perftools_inline!{ pub(super) fn validate_required_exponent<'a, Data>(data: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { // If we don't have an exponent stored, we're fine. if !has_exponent(data) { return Ok(()) } // Check if the next character is a sign symbol. let mut iter = data.exponent_iter(); match iter.next() { Some(&b'+') | Some(&b'-') => (), Some(_) => return Ok(()), None => return Err((ErrorCode::EmptyExponent, option_as_ptr(data.exponent()))) }; // Only here if we have a sign symbol. match iter.next() { Some(_) => Ok(()), None => Err((ErrorCode::EmptyExponent, option_as_ptr(data.exponent()))) } }} // Validate optional exponent component. // A no-op, since the data is optional. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_optional_exponent<'a, Data>(_: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { Ok(()) }} // Validate invalid exponent component. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_invalid_exponent<'a, Data>(data: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { match has_exponent(data) { true => return Err((ErrorCode::InvalidExponent, option_as_ptr(data.exponent()))), false => Ok(()) } }} // Validate exponent depending on float format. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_exponent<'a, Data>(data: &Data, format: NumberFormat) -> ParseResult<()> where Data: FastDataInterface<'a> { let required = format.required_exponent_digits(); let invalid = format.no_exponent_notation(); match (required, invalid) { (true, _) => validate_required_exponent(data), (_, true) => validate_invalid_exponent(data), (false, false) => validate_optional_exponent(data) } }} // EXPONENT SIGN // Validate optional exponent sign. // A no-op, since the data is optional. perftools_inline!{ pub(super) fn validate_optional_exponent_sign<'a, Data>(_: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { Ok(()) }} // Validate a required exponent sign. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_required_exponent_sign<'a, Data>(data: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { // Check if the next character is a sign symbol. let mut iter = data.exponent_iter(); match iter.next() { Some(&b'+') | Some(&b'-') => Ok(()), _ if has_exponent(data) => Err((ErrorCode::MissingExponentSign, option_as_ptr(data.exponent()))), _ => Ok(()) } }} // Validate a required exponent sign. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_no_positive_exponent_sign<'a, Data>(data: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { // Check if the next character is a sign symbol. let mut iter = data.exponent_iter(); match iter.next() { Some(&b'+') => Err((ErrorCode::InvalidPositiveExponentSign, option_as_ptr(data.exponent()))), _ => Ok(()) } }} // Validate exponent sign depending on float format. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_exponent_sign<'a, Data>(data: &Data, format: NumberFormat) -> ParseResult<()> where Data: FastDataInterface<'a> { let required = format.required_exponent_sign(); let no_positive = format.no_positive_exponent_sign(); match (required, no_positive) { (true, _) => validate_required_exponent_sign(data), (_, true) => validate_no_positive_exponent_sign(data), (false, false) => validate_optional_exponent_sign(data) } }} // EXPONENT FRACTION // Validate an exponent may occur with or without a fraction. perftools_inline!{ pub(super) fn validate_exponent_optional_fraction<'a, Data>(_: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { Ok(()) }} // Validate an exponent requires a fraction component. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_exponent_required_fraction<'a, Data>(data: &Data) -> ParseResult<()> where Data: FastDataInterface<'a> { match has_exponent(data) && !has_fraction(data) { true => Err((ErrorCode::ExponentWithoutFraction, option_as_ptr(data.exponent()))), false => Ok(()) } }} // Validate exponent fraction depending on float format. perftools_inline!{ #[cfg(feature = "format")] pub(super) fn validate_exponent_fraction<'a, Data>(data: &Data, format: NumberFormat) -> ParseResult<()> where Data: FastDataInterface<'a> { match format.no_exponent_without_fraction() { true => validate_exponent_required_fraction(data), false => validate_exponent_optional_fraction(data) } }} // TESTS // ----- #[cfg(test)] mod tests { use super::*; use super::super::standard::*; #[test] #[cfg(feature = "format")] fn validate_no_leading_zeros_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("01"), Some(b!("23450")), None, 0).into(); assert!(validate_no_leading_zeros(&data).is_err()); let data: Data = (b!("1"), Some(b!("23450")), None, 0).into(); assert!(validate_no_leading_zeros(&data).is_ok()); let data: Data = (b!("0"), Some(b!("23450")), None, 0).into(); assert!(validate_no_leading_zeros(&data).is_ok()); let data: Data = (b!(""), Some(b!("23450")), None, 0).into(); assert!(validate_no_leading_zeros(&data).is_ok()); } #[test] fn validate_permissive_mantissa_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("01"), Some(b!("23450")), None, 0).into(); assert!(validate_permissive_mantissa(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_permissive_mantissa(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_permissive_mantissa(&data).is_ok()); let data: Data = (b!(""), Some(b!("")), Some(b!("+")), 0).into(); assert!(validate_permissive_mantissa(&data).is_err()); } #[test] #[cfg(feature = "format")] fn validate_required_integer_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("01"), Some(b!("23450")), None, 0).into(); assert!(validate_required_integer(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_required_integer(&data).is_ok()); let data: Data = (b!(""), Some(b!("0")), Some(b!("")), 0).into(); assert!(validate_required_integer(&data).is_err()); let data: Data = (b!(""), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_required_integer(&data).is_err()); } #[test] #[cfg(feature = "format")] fn validate_required_fraction_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("01"), Some(b!("23450")), None, 0).into(); assert!(validate_required_fraction(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_required_fraction(&data).is_err()); let data: Data = (b!(""), Some(b!("0")), Some(b!("")), 0).into(); assert!(validate_required_fraction(&data).is_ok()); let data: Data = (b!(""), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_required_fraction(&data).is_err()); } #[test] #[cfg(feature = "format")] fn validate_required_digits_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("01"), Some(b!("23450")), None, 0).into(); assert!(validate_required_digits(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_required_digits(&data).is_err()); let data: Data = (b!(""), Some(b!("0")), Some(b!("")), 0).into(); assert!(validate_required_digits(&data).is_err()); let data: Data = (b!(""), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_required_digits(&data).is_err()); } #[test] fn validate_required_exponent_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("01"), Some(b!("23450")), None, 0).into(); assert!(validate_required_exponent(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_required_exponent(&data).is_err()); let data: Data = (b!(""), Some(b!("")), Some(b!("+")), 0).into(); assert!(validate_required_exponent(&data).is_err()); let data: Data = (b!(""), Some(b!("")), Some(b!("2")), 0).into(); assert!(validate_required_exponent(&data).is_ok()); let data: Data = (b!(""), Some(b!("")), Some(b!("+2")), 0).into(); assert!(validate_required_exponent(&data).is_ok()); } #[test] #[cfg(feature = "format")] fn validate_optional_exponent_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("0"), Some(b!("")), None, 0).into(); assert!(validate_optional_exponent(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_optional_exponent(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("+")), 0).into(); assert!(validate_optional_exponent(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("2")), 0).into(); assert!(validate_optional_exponent(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("+2")), 0).into(); assert!(validate_optional_exponent(&data).is_ok()); } #[test] #[cfg(feature = "format")] fn validate_invalid_exponent_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("0"), Some(b!("")), None, 0).into(); assert!(validate_invalid_exponent(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_invalid_exponent(&data).is_err()); let data: Data = (b!("0"), Some(b!("")), Some(b!("+")), 0).into(); assert!(validate_invalid_exponent(&data).is_err()); let data: Data = (b!("0"), Some(b!("")), Some(b!("2")), 0).into(); assert!(validate_invalid_exponent(&data).is_err()); let data: Data = (b!("0"), Some(b!("")), Some(b!("+2")), 0).into(); assert!(validate_invalid_exponent(&data).is_err()); } #[test] fn validate_optional_exponent_sign_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("0"), Some(b!("")), None, 0).into(); assert!(validate_optional_exponent_sign(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_optional_exponent_sign(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("+")), 0).into(); assert!(validate_optional_exponent_sign(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("2")), 0).into(); assert!(validate_optional_exponent_sign(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("+2")), 0).into(); assert!(validate_optional_exponent_sign(&data).is_ok()); } #[test] #[cfg(feature = "format")] fn validate_required_exponent_sign_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("0"), Some(b!("")), None, 0).into(); assert!(validate_required_exponent_sign(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_required_exponent_sign(&data).is_err()); let data: Data = (b!("0"), Some(b!("")), Some(b!("+")), 0).into(); assert!(validate_required_exponent_sign(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("2")), 0).into(); assert!(validate_required_exponent_sign(&data).is_err()); let data: Data = (b!("0"), Some(b!("")), Some(b!("+2")), 0).into(); assert!(validate_required_exponent_sign(&data).is_ok()); } #[test] #[cfg(feature = "format")] fn validate_no_positive_exponent_sign_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("0"), Some(b!("")), None, 0).into(); assert!(validate_no_positive_exponent_sign(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_no_positive_exponent_sign(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("+")), 0).into(); assert!(validate_no_positive_exponent_sign(&data).is_err()); let data: Data = (b!("0"), Some(b!("")), Some(b!("2")), 0).into(); assert!(validate_no_positive_exponent_sign(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("+2")), 0).into(); assert!(validate_no_positive_exponent_sign(&data).is_err()); let data: Data = (b!("0"), Some(b!("")), Some(b!("-2")), 0).into(); assert!(validate_no_positive_exponent_sign(&data).is_ok()); } #[test] fn validate_exponent_optional_fraction_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("0"), Some(b!("")), None, 0).into(); assert!(validate_exponent_optional_fraction(&data).is_ok()); let data: Data = (b!(""), Some(b!("0")), None, 0).into(); assert!(validate_exponent_optional_fraction(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_exponent_optional_fraction(&data).is_ok()); let data: Data = (b!(""), Some(b!("0")), Some(b!("+")), 0).into(); assert!(validate_exponent_optional_fraction(&data).is_ok()); } #[test] #[cfg(feature = "format")] fn validate_exponent_required_fraction_test() { type Data<'a> = StandardFastDataInterface<'a>; let data: Data = (b!("0"), Some(b!("")), None, 0).into(); assert!(validate_exponent_required_fraction(&data).is_ok()); let data: Data = (b!("0"), Some(b!("")), Some(b!("")), 0).into(); assert!(validate_exponent_required_fraction(&data).is_ok()); let data: Data = (b!("0"), None, Some(b!("")), 0).into(); assert!(validate_exponent_required_fraction(&data).is_err()); let data: Data = (b!(""), Some(b!("0")), Some(b!("+")), 0).into(); assert!(validate_exponent_required_fraction(&data).is_ok()); } } lexical-core-0.7.6/src/atof/algorithm/incorrect.rs000075500000000000000000000140320000000000000202310ustar 00000000000000//! Incorrect, fast algorithms for string-to-float conversions. use crate::atoi; use crate::util::*; use super::format::*; // FRACTION type Wrapped = WrappedFloat; // Process the integer component of the raw float. perftools_inline!{ fn process_integer<'a, F, Data>(data: &Data, radix: u32) -> F where F: StablePower, Data: FastDataInterface<'a> { match data.integer().len() { 0 => F::ZERO, // Cannot overflow and cannot have invalid digits. _ => atoi::standalone_mantissa::, _>(data.integer_iter(), radix) .into_inner() } }} // Process the fraction component of the raw float. perftools_inline!{ fn process_fraction<'a, F, Data>(data: &Data, radix: u32) -> F where F: StablePower, Data: FastDataInterface<'a> { // We don't really care about numerical precision, so just break // the fraction into 12-digit pieces. // 12 is the maximum number of digits we can use without // potentially overflowing a 36-radix float string. let mut fraction = F::ZERO; let mut digits: i32 = 0; let mut iter = data.fraction_iter(); while !iter.consumed() { let (value, length) = atoi::standalone_mantissa_n::(&mut iter, radix, 12); digits = digits.saturating_add(length.as_i32()); if !value.is_zero() { fraction += F::iterative_pow(as_cast(value), radix, -digits); } } fraction }} // Convert the float string to a native floating-point number. perftools_inline!{ fn to_native<'a, F, Data>(mut data: Data, bytes: &'a [u8], radix: u32) -> ParseResult<(F, *const u8)> where F: StablePower, Data: FastDataInterface<'a> { let ptr = data.extract(bytes, radix)?; let integer: F = process_integer(&data, radix); let fraction: F = process_fraction(&data, radix); let mut value = integer + fraction; if !data.raw_exponent().is_zero() && !value.is_zero() { value = value.iterative_pow(radix, data.raw_exponent()); } Ok((value, ptr)) }} perftools_inline!{ pub(crate) fn atof_generic<'a, F>(bytes: &'a [u8], radix: u32, _: bool, _: Sign, format: NumberFormat) -> ParseResult<(F, *const u8)> where F: StablePower { apply_interface!(to_native, format, bytes, radix) }} // ATOF/ATOD // --------- // Parse 32-bit float from string. perftools_inline!{ pub(crate) fn atof<'a>(bytes: &'a [u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(f32, *const u8)> { atof_generic(bytes, radix, lossy, sign, format) }} // Parse 64-bit float from string. perftools_inline!{ pub(crate) fn atod<'a>(bytes: &'a [u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(f64, *const u8)> { atof_generic(bytes, radix, lossy, sign, format) }} // TESTS // ----- #[cfg(test)] mod tests { use super::*; #[test] fn process_integer_test() { type Data<'a> = StandardFastDataInterface<'a>; let data = (b!("1"), Some(b!("2345")), None, 0).into(); assert_eq!(1.0, process_integer::(&data, 10)); let data = (b!("12"), Some(b!("345")), None, 0).into(); assert_eq!(12.0, process_integer::(&data, 10)); let data = (b!("12345"), Some(b!("6789")), None, 0).into(); assert_eq!(12345.0, process_integer::(&data, 10)); } #[test] fn process_fraction_test() { type Data<'a> = StandardFastDataInterface<'a>; let data = (b!("1"), Some(b!("2345")), None, 0).into(); assert_eq!(0.2345, process_fraction::(&data, 10)); let data = (b!("12"), Some(b!("345")), None, 0).into(); assert_eq!(0.345, process_fraction::(&data, 10)); let data = (b!("12345"), Some(b!("6789")), None, 0).into(); assert_eq!(0.6789, process_fraction::(&data, 10)); } #[test] fn atof_test() { let atof10 = move |x| match atof(x, 10, false, Sign::Positive, NumberFormat::standard().unwrap()) { Ok((v, p)) => Ok((v, distance(x.as_ptr(), p))), Err((v, p)) => Err((v, distance(x.as_ptr(), p))), }; assert_eq!(Ok((1.2345, 6)), atof10(b"1.2345")); assert_eq!(Ok((12.345, 6)), atof10(b"12.345")); assert_eq!(Ok((12345.6789, 10)), atof10(b"12345.6789")); assert_f32_eq!(1.2345e10, atof10(b"1.2345e10").unwrap().0); } #[test] fn atod_test() { let atod10 = move |x| match atod(x, 10, false, Sign::Positive, NumberFormat::standard().unwrap()) { Ok((v, p)) => Ok((v, distance(x.as_ptr(), p))), Err((v, p)) => Err((v, distance(x.as_ptr(), p))), }; assert_eq!(Ok((1.2345, 6)), atod10(b"1.2345")); assert_eq!(Ok((12.345, 6)), atod10(b"12.345")); assert_eq!(Ok((12345.6789, 10)), atod10(b"12345.6789")); assert_f64_eq!(1.2345e10, atod10(b"1.2345e10").unwrap().0); } // Lossy // Just a synonym for the regular overloads, since we're not using the // correct feature. Use the same tests. #[test] fn atof_lossy_test() { let atof10 = move |x| match atof(x, 10, true, Sign::Positive, NumberFormat::standard().unwrap()) { Ok((v, p)) => Ok((v, distance(x.as_ptr(), p))), Err((v, p)) => Err((v, distance(x.as_ptr(), p))), }; assert_eq!(Ok((1.2345, 6)), atof10(b"1.2345")); assert_eq!(Ok((12.345, 6)), atof10(b"12.345")); assert_eq!(Ok((12345.6789, 10)), atof10(b"12345.6789")); assert_f32_eq!(1.2345e10, atof10(b"1.2345e10").unwrap().0); } #[test] fn atod_lossy_test() { let atod10 = move |x| match atod(x, 10, true, Sign::Positive, NumberFormat::standard().unwrap()) { Ok((v, p)) => Ok((v, distance(x.as_ptr(), p))), Err((v, p)) => Err((v, distance(x.as_ptr(), p))), }; assert_eq!(Ok((1.2345, 6)), atod10(b"1.2345")); assert_eq!(Ok((12.345, 6)), atod10(b"12.345")); assert_eq!(Ok((12345.6789, 10)), atod10(b"12345.6789")); assert_f64_eq!(1.2345e10, atod10(b"1.2345e10").unwrap().0); } } lexical-core-0.7.6/src/atof/algorithm/large_powers.rs000075500000000000000000000021370000000000000207350ustar 00000000000000//! Precalculated large powers for prime numbers for `b^2^i`. //! //! We only need powers such that `b^n <= 2^1075` for `bigcomp`. //! However, for `bhcomp`, we need at least as many digits as are //! input. We tentatively accept up to ~2^15. //! //! The larger powers are **quite** large (~3Kb per radix), so we'd rather //! not include them in binaries unless necessary. use super::math::Limb; #[cfg(limb_width_32)] use super::large_powers_32::*; #[cfg(limb_width_64)] use super::large_powers_64::*; // HELPER /// Get the correct large power from the radix. #[allow(unused_variables)] pub(in crate::atof::algorithm) fn get_large_powers(radix: u32) -> &'static [&'static [Limb]] { #[cfg(not(feature = "radix"))] { &POW5 } #[cfg(feature = "radix")] { match radix { 3 => &POW3, 5 => &POW5, 7 => &POW7, 11 => &POW11, 13 => &POW13, 17 => &POW17, 19 => &POW19, 23 => &POW23, 29 => &POW29, 31 => &POW31, _ => unreachable!(), } } } lexical-core-0.7.6/src/atof/algorithm/large_powers_32.rs000075500000000000000000005104260000000000000212460ustar 00000000000000//! Precalculated large powers for 32-bit limbs. // PRIME (EXCEPT 2) /// Large powers (&[u32]) for base5 operations. const POW5_1: [u32; 1] = [5]; const POW5_2: [u32; 1] = [25]; const POW5_3: [u32; 1] = [625]; const POW5_4: [u32; 1] = [390625]; const POW5_5: [u32; 2] = [2264035265, 35]; const POW5_6: [u32; 3] = [2242703233, 762134875, 1262]; const POW5_7: [u32; 5] = [3211403009, 1849224548, 3668416493, 3913284084, 1593091]; const POW5_8: [u32; 10] = [781532673, 64985353, 253049085, 594863151, 3553621484, 3288652808, 3167596762, 2788392729, 3911132675, 590]; const POW5_9: [u32; 19] = [2553183233, 3201533787, 3638140786, 303378311, 1809731782, 3477761648, 3583367183, 649228654, 2915460784, 487929380, 1011012442, 1677677582, 3428152256, 1710878487, 1438394610, 2161952759, 4100910556, 1608314830, 349175]; const POW5_10: [u32; 38] = [4234999809, 2012377703, 2408924892, 1570150255, 3090844311, 3273530073, 1187251475, 2498123591, 3364452033, 1148564857, 687371067, 2854068671, 1883165473, 505794538, 2988060450, 3159489326, 2531348317, 3215191468, 849106862, 3892080979, 3288073877, 2242451748, 4183778142, 2995818208, 2477501924, 325481258, 2487842652, 1774082830, 1933815724, 2962865281, 1168579910, 2724829000, 2360374019, 2315984659, 2360052375, 3251779801, 1664357844, 28]; const POW5_11: [u32; 75] = [689565697, 4116392818, 1853628763, 516071302, 2568769159, 365238920, 336250165, 1283268122, 3425490969, 248595470, 2305176814, 2111925499, 507770399, 2681111421, 589114268, 591287751, 1708941527, 4098957707, 475844916, 3378731398, 2452339615, 2817037361, 2678008327, 1656645978, 2383430340, 73103988, 448667107, 2329420453, 3124020241, 3625235717, 3208634035, 2412059158, 2981664444, 4117622508, 838560765, 3069470027, 270153238, 1802868219, 3692709886, 2161737865, 2159912357, 2585798786, 837488486, 4237238160, 2540319504, 3798629246, 3748148874, 1021550776, 2386715342, 1973637538, 1823520457, 1146713475, 833971519, 3277251466, 905620390, 26278816, 2680483154, 2294040859, 373297482, 5996609, 4109575006, 512575049, 917036550, 1942311753, 2816916778, 3248920332, 1192784020, 3537586671, 2456567643, 2925660628, 759380297, 888447942, 3559939476, 3654687237, 805]; const POW5_12: [u32; 149] = [322166785, 3809044581, 2994556223, 1239584207, 3962455841, 4001882964, 3053876612, 915114683, 2783289745, 785739093, 4253185907, 3931164994, 1370983858, 2553556126, 3360742076, 2255410929, 422849554, 2457422215, 3539495362, 1720790602, 1908931983, 1470596141, 592794347, 4219465164, 4085652704, 941661409, 2534650953, 885063988, 2355909854, 2812815516, 767256131, 3821757683, 2155151105, 3817418473, 281116564, 2834395026, 2821201622, 2524625843, 1511330880, 2572352493, 330571332, 2951088579, 2730271766, 4044456479, 4212286644, 2444937588, 3603420843, 2387148597, 1142537539, 3299235429, 1751012624, 861228086, 2873722519, 230498814, 1023297821, 2553128038, 3421129895, 2651917435, 2042981258, 1606787143, 2228751918, 447345732, 1930371132, 1784132011, 3612538790, 2275925090, 2487567871, 1080427616, 2009179183, 3383506781, 3899054063, 1950782960, 2168622213, 2717674390, 3616636027, 2079341593, 1530129217, 1461057425, 2406264415, 3674671357, 2972036238, 2019354295, 1455849819, 1866918619, 1324269294, 424891864, 2722422332, 2641594816, 1400249021, 3482963993, 3734946379, 225889849, 1891545473, 777383150, 3589824633, 4117601611, 4220028667, 334453379, 1083130821, 1060342180, 4208163139, 1489826908, 4163762246, 1096580926, 689301528, 2336054516, 1782865703, 4175148410, 3398369392, 2329412588, 3001580596, 59740741, 3202189932, 3351895776, 246185302, 718535188, 3772647488, 4151666556, 4055698133, 2461934110, 2281316281, 3466396836, 3536023465, 1064267812, 2955456354, 2423805422, 3627960790, 1325057500, 3876919979, 2009959531, 175455101, 184092852, 2358785571, 3842977831, 2485266289, 487121622, 4159252710, 4075707558, 459389244, 300652075, 2521346588, 3458976673, 888631636, 2076098096, 3844514585, 2363697580, 3729421522, 3051115477, 649395]; const POW5_13: [u32; 298] = [711442433, 3564261005, 2399042279, 4170849936, 4010295575, 1423987028, 330414929, 1349249065, 4213813618, 3852031822, 4040843590, 2154565331, 3094013374, 1159028371, 3227065538, 2115927092, 2085102554, 488590542, 2609619432, 3602898805, 3812736528, 3269439096, 23816114, 253984538, 1035905997, 2942969204, 3400787671, 338562688, 1637191975, 740509713, 2264962817, 3410753922, 4162231428, 2282041228, 1759373012, 3155367777, 4278913285, 1420532801, 1981002276, 438054990, 1006507643, 1142697287, 1332538012, 2029019521, 3949305784, 818392641, 2491288846, 2716584663, 3648886102, 556814413, 444795339, 4071412999, 1066321706, 4253169466, 2510832316, 672091442, 4083256000, 2165985028, 1841538484, 3549854235, 364431512, 3707648143, 1162785440, 2268641545, 281340310, 735693841, 848809228, 1700785200, 2919703985, 4094234344, 58530286, 965505005, 1000010347, 3381961808, 3040089923, 1973852082, 2890971585, 1019960210, 4292895237, 2821887841, 3756675650, 3951282907, 3885870583, 1008791145, 503998487, 1881258362, 1949332730, 392996726, 2012973814, 3970014187, 2461725150, 2942547730, 3728066699, 2766901132, 3778532841, 1085564064, 2278673896, 1116879805, 3448726271, 774279411, 157211670, 1506320155, 531168605, 1362654525, 956967721, 2148871960, 769186085, 4186232894, 2055679604, 3248365487, 3981268013, 3975787984, 2489510517, 3309046495, 212771124, 933418041, 3371839114, 562115198, 1853601831, 757336096, 1354633440, 1486083256, 2872126393, 522920738, 1141587749, 3210903262, 1926940553, 3054024853, 2021162538, 2262742000, 1877899947, 3147002868, 669840763, 4158174590, 4238502559, 1023731922, 3386840011, 829588074, 3449720188, 2835142880, 2999162007, 813056473, 482949569, 638108879, 3067201471, 1026714238, 4004452838, 2383667807, 3999477803, 771648919, 630660440, 3827121348, 176185980, 2878191002, 2666149832, 3909811063, 2429163983, 2665690412, 907266128, 4269332098, 2022665808, 1527122180, 3072053668, 1072477492, 3006022924, 549664855, 2800340954, 37352654, 1212772743, 2711280533, 3029527946, 2511120040, 1305308377, 3474662224, 4226330922, 442988428, 954940108, 3274548099, 4212288177, 2688499880, 3982226758, 3922609956, 1279948029, 1939943640, 3650489901, 2733364929, 2494263275, 1864579964, 1225941120, 2390465139, 1267503249, 3533240729, 904410805, 2842550015, 2517736241, 1796069820, 3335274381, 673539835, 1924694759, 3598098235, 2792633405, 16535707, 3703535497, 3592841791, 2929082877, 1317622811, 294990855, 1396706563, 2383271770, 3853857605, 277813677, 277580220, 1101318484, 3761974115, 1132150143, 2544692622, 3419825776, 743770306, 1695464553, 1548693232, 2421159615, 2575672031, 2678971806, 1591267897, 626546738, 3823443129, 267710932, 1455435162, 2353985540, 3248523795, 335348168, 3872552561, 2814522612, 2634118860, 3503767026, 1301019273, 1414467789, 722985138, 3070909565, 4253482569, 3744939841, 558142907, 2229819389, 13833173, 77003966, 2763671364, 3905603970, 2931990126, 2280419384, 1879090457, 2934846267, 4284933164, 2331863845, 62191163, 3178861020, 1522063815, 785672270, 1215568492, 2936443917, 802972489, 2956820173, 3916732783, 2893572089, 1391232801, 3168640330, 2396859648, 894950918, 1103583736, 961991865, 2807302642, 305977505, 3054505899, 1048256994, 781017659, 2459278754, 3164823415, 537658277, 905753687, 464963300, 4149131560, 1029507924, 2278300961, 1231291503, 414073408, 3630740085, 2345841814, 475358196, 3258243317, 4167625072, 4178911231, 2927355042, 655438830, 3138378018, 623200562, 2785714112, 273403236, 807993669, 98]; const POW5_14: [u32; 595] = [1691320321, 2671006246, 1682531301, 2072858707, 1240508969, 3108358191, 1125119096, 2470144952, 1610099978, 1690632660, 1941696884, 2663506355, 1006364675, 3909158537, 4147711374, 1072663936, 4078768933, 745751659, 4123687570, 471458681, 655028926, 4113407388, 3945524552, 985625313, 1254424514, 2127508744, 570530434, 945388122, 3194649404, 2589065070, 2731705399, 202030749, 2090780394, 3348662271, 1481754777, 1130635472, 4025144705, 1924486271, 2578567861, 125491448, 1558036315, 994248173, 3817216711, 763950077, 1030439870, 959586474, 3845661701, 483795093, 1637944470, 2275463649, 3398804829, 1758016486, 2665513698, 2004912571, 1094885097, 4223064276, 3307819021, 651121777, 1757003305, 3603542336, 129917786, 2215974994, 3042386306, 2205352757, 3944939700, 3710987569, 97967515, 1217242524, 930630949, 3660328512, 1787663098, 1784141600, 2500542892, 4034561586, 3444961378, 785043562, 3869499367, 885623728, 2625011087, 3053789617, 1965731793, 3900511934, 2648823592, 3851062028, 3321968688, 799195417, 1011847510, 1369129160, 1348009103, 2876796955, 2915408967, 3305284948, 263399535, 1715990604, 2645821294, 1587844552, 2624912049, 3035631499, 2306636348, 3499275462, 675152704, 854794152, 4004972748, 1739996642, 1333476491, 4012621867, 3658792931, 3297985728, 2864481726, 3066357406, 785287846, 1671499798, 433044045, 1919608025, 264833858, 3999983367, 1116778570, 1301982149, 4213901070, 4081649357, 536169226, 1389008649, 188923873, 373495152, 2551132278, 1800758715, 3951840330, 2632334454, 3118778225, 1034046547, 1862428410, 3037609062, 1994608505, 29051798, 2571685694, 264151332, 2260643090, 2717535964, 3508441116, 3283713017, 1903365635, 923575694, 1219598101, 2288281570, 3676533911, 1014136356, 555142354, 2389170030, 4185108175, 884862419, 836141292, 2957159173, 1997444768, 4233903127, 2876184692, 3089125070, 1480848293, 1097600237, 299700527, 2507669891, 2982628312, 2114881043, 2529576251, 2812279824, 2987750993, 4241938954, 2204775591, 1037094060, 829315638, 1231047149, 52608178, 3735136637, 3455232602, 962039123, 488286513, 50685385, 3516451821, 843975207, 1572355722, 675489076, 2428445672, 1555117248, 3708476086, 10375249, 4172112346, 2117510871, 2227658327, 3187664554, 3050656558, 328034318, 3179601324, 1247769761, 3439263953, 1431538938, 2962525068, 1213366289, 3813013550, 2651093719, 1860661503, 3933716208, 264320617, 789980519, 2257856172, 102000748, 977269860, 1113845122, 3008928583, 1461738106, 557786285, 2926560363, 1038106190, 3643478847, 828004507, 457818698, 1933056971, 373408056, 2076808229, 3160935130, 2781854874, 2519636100, 177606000, 4237103862, 3977834316, 1621936232, 2599050516, 319893558, 3343370366, 765044144, 976657331, 7026264, 294277429, 3829376742, 3029627280, 2705178718, 3614653880, 230519152, 3288033233, 293525479, 3805751881, 3227511198, 2520308544, 3648103003, 1111086184, 437622105, 2232033852, 3239146386, 584244184, 1450926016, 2462430443, 3226534010, 298582169, 4214576928, 1762099469, 964985185, 1585788148, 1641127666, 787006566, 2315956284, 3258232694, 2275058964, 2541003317, 1508235863, 2613339827, 4080647514, 1152057965, 3149266279, 731345410, 914737650, 65395712, 1884566942, 1379520432, 2611027720, 4163073378, 2619704967, 2746552541, 1388822415, 3005141199, 843440249, 4288674003, 3136174279, 4051522914, 4144149433, 3427566947, 3419023197, 3758479825, 3893877676, 96899594, 1657725776, 253618880, 434129337, 1499045748, 2996992534, 4036042074, 2110713869, 906222950, 928326225, 2541827893, 1604330202, 226792470, 4022228930, 815850898, 1466012310, 3377712199, 292769859, 2822055597, 3225701344, 3052947004, 385831222, 705324593, 4030158636, 3540280538, 2982120874, 2136414455, 255762046, 3852783591, 3262064164, 2358991588, 3756586117, 4143612643, 3326743817, 2897365738, 807711264, 3719310016, 3721264861, 3627337076, 944539331, 3640975513, 3712525681, 1162911839, 2008243316, 2179489649, 2867584109, 261861553, 3570253908, 2062868357, 2220328623, 3857004679, 3744109002, 4138041873, 1451860932, 2364975637, 2802161722, 2680106834, 753401584, 1223182946, 1245401957, 4163377735, 3565815922, 2216942838, 4036140094, 71979081, 3924559643, 400477238, 551750683, 1174153235, 859969898, 1185921017, 1711399735, 812991545, 4051735761, 3549118738, 1631653329, 3631835958, 3648867800, 1206500363, 2155893137, 361030362, 3454286017, 2505909489, 1083595169, 453595313, 1510564703, 1706163902, 1632924345, 1381875722, 1661526119, 1082778324, 3571910052, 1140625929, 851544870, 1145546234, 2938573139, 907528924, 1304752338, 1764668294, 1788942063, 1700368828, 104979467, 1413911959, 3327497828, 1956384744, 1272712474, 2815637534, 3307809377, 1320574940, 1111968962, 4073107827, 434096622, 169451929, 3201183459, 3331028877, 2852366972, 3369830128, 2924794558, 3106537952, 3739481231, 1612955817, 4138608722, 2721281595, 2755775390, 843505117, 982234295, 1157276611, 814674632, 4246504726, 3532006708, 992340967, 1647538031, 204696133, 193866982, 3899126129, 300851698, 1379496684, 1759463683, 1354782756, 1374637239, 3410883240, 1073406229, 3038431791, 1053909855, 3607043270, 173719711, 3733903830, 171820911, 1573050589, 932781534, 4183534770, 2158849555, 372245998, 3573073830, 841339264, 2759200520, 1610547277, 2603293319, 3890906486, 1557138278, 3964109906, 677238797, 537994297, 1124184993, 4287078344, 4207654540, 2943022776, 2977947524, 3255359985, 4098397558, 2274666217, 2915862060, 243524940, 2467726756, 2869020032, 507521339, 3403121914, 522051455, 1803903108, 3471254194, 473535371, 1948602036, 3352095732, 3116527002, 1795743673, 775867940, 2551469548, 3757442064, 3162525227, 3765412747, 3040105484, 1927625810, 48214767, 2997207130, 1342349989, 2536583992, 1501320191, 3592287317, 887432730, 967585477, 3334212779, 948663609, 1064513472, 15386372, 2465931737, 3230242590, 3036652803, 2063155087, 1927500726, 2821790499, 2187774383, 501520074, 3688568496, 3606711121, 2576459247, 3176542345, 378322447, 156541411, 1400607301, 1406179107, 677848877, 2253753529, 193196070, 4207435024, 4166396241, 509467541, 2906024136, 1221753746, 3375413222, 431327897, 2749265123, 2848827671, 3412997614, 2051920238, 1283516885, 1300498239, 1957256104, 2634010560, 3531900395, 360276850, 1461184973, 2012063967, 2873572430, 2914608609, 4289554777, 1539331673, 1859532928, 4213441063, 538215691, 3512720863, 4258743698, 3040408445, 982396546, 343095663, 4138069496, 1021581857, 214185242, 1968079460, 2864275059, 3347192726, 4096783459, 3259169450, 3707808869, 142485006, 399610869, 230556456, 2219467721, 4191227798, 2242548189, 3136366572, 179755707, 3464881829, 452317775, 3887426070, 3446430233, 1473370015, 1576807208, 3964523248, 419325089, 2373067114, 1596072055, 1928415752, 3635452689, 1005598891, 3335462724, 3290848636, 3669078247, 1178176812, 2110774376, 3068593619, 1253036518, 908857731, 3631223047, 4138506423, 2903592318, 3596915748, 3289036113, 3721512676, 2704409359, 3386016968, 3676268074, 2185259502, 1096257611, 3360076717, 3548676554, 170167319, 3360064287, 3899940843, 9640]; pub(super) const POW5: [&'static [u32]; 14] = [ &POW5_1, &POW5_2, &POW5_3, &POW5_4, &POW5_5, &POW5_6, &POW5_7, &POW5_8, &POW5_9, &POW5_10, &POW5_11, &POW5_12, &POW5_13, &POW5_14, ]; cfg_if! { if #[cfg(feature = "radix")] { /// Large powers (&[u32]) for base3 operations. const POW3_1: [u32; 1] = [3]; const POW3_2: [u32; 1] = [9]; const POW3_3: [u32; 1] = [81]; const POW3_4: [u32; 1] = [6561]; const POW3_5: [u32; 1] = [43046721]; const POW3_6: [u32; 2] = [3793632897, 431439]; const POW3_7: [u32; 4] = [2038349057, 2033330060, 1456779151, 43]; const POW3_8: [u32; 7] = [2324068865, 2151814273, 4219200356, 3831009148, 1515007727, 1223069914, 1878]; const POW3_9: [u32; 13] = [120648705, 3524288303, 123305297, 1973552606, 1582677123, 4275192449, 223346561, 3350064824, 1500483036, 1257605964, 1367913622, 2878850248, 3527953]; const POW3_10: [u32; 26] = [1995565057, 493227282, 1124501772, 1987702555, 1293151165, 901580639, 3173678675, 2491643407, 2858789928, 4190666723, 3234280160, 1552091534, 1098766192, 535263123, 671427889, 2428827667, 442154954, 3812608783, 2997209821, 882392610, 726842283, 3784254415, 1868908668, 1167284160, 3936843162, 2897]; const POW3_11: [u32; 51] = [2418266113, 2644811931, 291457750, 1228555692, 4188395951, 1879994809, 3593180558, 10265866, 1663691138, 843910177, 428616802, 383870689, 363531492, 132717144, 1517834416, 1163669408, 3198438890, 2668578238, 3647540890, 862346293, 2517635987, 240350806, 3915968527, 1177122755, 748979939, 2832571033, 89370928, 1833830663, 2468463247, 2650192631, 2242055147, 1865594656, 4265350596, 1503068824, 1868812441, 2681777372, 2889847246, 3308916069, 983500879, 3408251151, 2154883072, 49524507, 3278693234, 4217536798, 4081384898, 3784867324, 607038776, 4050474118, 1564906641, 3106553379, 8397920]; const POW3_12: [u32; 102] = [2840043521, 1540321337, 767411044, 3396833747, 259596680, 3733039683, 207521616, 948242495, 781132489, 2161879572, 891872999, 895088354, 1052134478, 3366112117, 2144001521, 2587580027, 3486676624, 1606020622, 1120717714, 3202521782, 2600718456, 1561168670, 4008838462, 4289731214, 2853963150, 2124711879, 2426069860, 4179412452, 2514942520, 782315593, 637303440, 2034234560, 1899461323, 1365048154, 143638530, 1091043496, 2313128713, 1632823752, 1501556769, 1617441271, 3832922217, 4022881155, 2291639705, 2009961883, 2923031135, 104349646, 721181067, 3110549978, 1118342134, 3111544970, 3523576724, 3188223411, 1433909029, 715526501, 480052905, 3456303432, 1911699360, 2383287320, 806454471, 3619655246, 797999986, 3490535011, 727608595, 3007402875, 412470314, 311012536, 4082475156, 1929900167, 2743731994, 123772258, 3183779998, 331631487, 2482139594, 2030549481, 886716221, 3336904643, 1675792966, 708537412, 3256221032, 1941911759, 3257054398, 2644783750, 2889722204, 2012789015, 3141472195, 2208384519, 4290796508, 3164140686, 798188221, 3588366685, 2275055709, 1007570156, 895359884, 308610244, 3285989372, 453890838, 2972940297, 3657184703, 4029262500, 1785980957, 1709474525, 16420]; const POW3_13: [u32; 203] = [1989099521, 4118005181, 2784736632, 1591520375, 3149497838, 120872100, 3268194218, 2541515075, 1443129394, 2450564616, 4211997843, 3010894003, 3488508283, 3168823743, 4221978727, 1814219615, 2257880666, 2937457502, 726097399, 1432510431, 3623148218, 4212655794, 674028783, 1070458814, 2999384570, 1057211904, 1214775680, 1198321802, 1742834418, 3976283753, 1704638003, 1150196049, 862607433, 3094934565, 1717221074, 2662007806, 1439914256, 440811537, 2348627913, 1256162099, 267894251, 786369445, 1766348239, 3821736572, 3346805441, 153712663, 3885791558, 2372893612, 3047484027, 1233249852, 2901680213, 1633905397, 1227232372, 2772305912, 3924643248, 2682967226, 452577852, 4125302502, 3281241925, 4238233594, 2716754899, 3041594220, 2682018838, 626131564, 1963041990, 2065902713, 2603950262, 3095577885, 1839434394, 4180555672, 84786972, 4278806346, 3035916175, 2330476828, 1488573301, 2500745307, 851546392, 856436551, 3255008763, 1254027339, 3922579641, 684521982, 3718279773, 201247274, 2865772478, 1661217807, 2452776392, 2994094948, 1563975657, 3404497195, 26262692, 1976116320, 2717359634, 3933383310, 2639054358, 433403848, 3618223885, 515738077, 1166242878, 2870355216, 2931111594, 3146034481, 1341461620, 2902728897, 445742713, 2516857131, 3214583960, 2398636469, 272528879, 1474549553, 4074162653, 2846904993, 3653153845, 1143580991, 2862624787, 1146152282, 678419602, 676200709, 3450362083, 3496513874, 1340992762, 4202699539, 2772946083, 1813525850, 3647968120, 2351713161, 2620418793, 1432172974, 1926349909, 3142386689, 798457517, 2602933474, 1282058432, 1591224320, 2716997635, 1470549750, 3231957967, 1843138204, 916505043, 944975043, 3562455555, 142650189, 3496720432, 172385644, 1321658753, 3705048361, 2722721050, 1309746413, 3948489302, 1278815165, 2862992204, 416184660, 1314168979, 3057292743, 3306397597, 3990492847, 4077152808, 728714950, 1739211429, 2747763777, 1272802838, 311396446, 3721256556, 3351298146, 3532437535, 1181844299, 4211695344, 3293791810, 463498694, 467923860, 3160877532, 1513252595, 2210598062, 375855701, 2032403348, 126535477, 2612392194, 2324015344, 3456022262, 3450499670, 2870619468, 794761483, 3000301945, 2387559626, 2662253415, 3659359224, 1026083388, 1046817774, 3912755589, 2122896674, 3271718598, 2001918117, 1779848570, 2511901175, 2480900964, 1524873519, 2123619892, 3128581558, 2498944444, 637563527, 4159894460, 306290363, 269629471]; const POW3_14: [u32; 406] = [2099150849, 701786787, 1755792598, 784340596, 1318601904, 3847911731, 587073536, 365758857, 458403624, 386356260, 1762699493, 3433357154, 2584239718, 3024933458, 992158912, 190818046, 626134648, 3100287313, 2050339901, 3193336121, 865261815, 4032628840, 3544894355, 1343940016, 2256792156, 660366745, 3495038095, 1796842708, 2708197863, 488865090, 3019365153, 3547886422, 338978285, 2879593856, 1161424980, 2532570101, 919483686, 285229234, 1471360694, 962282435, 3522233567, 812073225, 2974433512, 2062552230, 4142366515, 3030097561, 2370820074, 1533608708, 3136743081, 677180323, 2026099629, 3988538975, 2882718020, 2791855106, 901454064, 1733181317, 1815926074, 2641249342, 205063446, 1605355824, 1412530368, 392610986, 1165183496, 1547418282, 234904178, 1452470696, 4153026085, 1039567861, 976503900, 3326386007, 398523011, 636629983, 988936191, 180109784, 35078416, 3316096777, 446118631, 3363780714, 2778228881, 1121420008, 2277227294, 3286959436, 3390534136, 3471230490, 26261918, 1529388667, 1337804871, 157925485, 4005827295, 1940455666, 2179129784, 2230764206, 4133049885, 787743620, 206584505, 536424564, 2347733349, 2127350488, 3622501416, 2681290576, 29689975, 3157055732, 3755589600, 3964024562, 1703745931, 444745493, 1685391633, 3847735038, 1141249397, 4124411194, 2699168764, 2516945277, 1379343014, 1735161321, 2518007387, 4154772473, 2516518603, 77667182, 2901149252, 1077617976, 3033704680, 2341748280, 3239557938, 3625034956, 3851721623, 958796982, 1030859667, 1614720586, 1417286859, 3019299795, 3316288320, 2053046853, 1205913034, 406765224, 4163409034, 3644521955, 678788809, 1048403252, 2180427097, 1510574153, 1320493806, 4279263604, 281966796, 2685455103, 2666190803, 3067005562, 3221244892, 1971957474, 849438589, 1584595613, 2454213790, 2156344722, 3770071351, 2205912499, 2893248775, 1629808101, 252803404, 1632951746, 3155742212, 166264103, 492569650, 2230310542, 3689268700, 4204139123, 3759547874, 326889610, 711452220, 4058365029, 1128589942, 789582083, 4071978836, 2696635374, 3923925207, 1293857747, 2987905449, 3346858289, 28115676, 715947610, 608126801, 1751549604, 3309338460, 1129461952, 552591053, 267524979, 1414364888, 2528558825, 3781593658, 2335318828, 4139346762, 2281798865, 3588226868, 2855371367, 308801770, 2067748732, 2361054051, 3541790565, 1015821430, 1667098714, 2017648993, 2672308018, 1576401102, 59885878, 2536836354, 769548065, 3150906464, 3038028751, 2097625751, 4213561908, 1337967423, 2931763012, 2256338530, 3526977155, 2211626795, 3921745985, 4044006804, 2620267187, 1303853568, 138250406, 676718200, 2434799399, 1034944144, 2790768247, 1949560037, 2657385661, 1401109267, 2969455499, 2342873842, 4292623932, 3148918694, 169039494, 1361292240, 1689965319, 270493791, 1171826919, 1200742270, 2846839124, 3153980733, 3233534339, 3824262631, 326024744, 3780525617, 1649806460, 1500987616, 288775088, 3535410573, 3275414509, 3158560889, 2281111300, 3764770800, 1798194300, 2256605564, 1104786778, 147494599, 1948189160, 469870811, 3275616186, 1215054053, 1802946482, 215038054, 3232037233, 3945501635, 1363902757, 404304310, 2741496635, 4006384272, 3104805825, 2707083507, 1268576851, 74077974, 1902096819, 2500280581, 2077772156, 252830146, 330674602, 182339026, 3998928, 679066470, 2193213293, 2297252499, 3199220015, 2916487180, 34820209, 3043558828, 496902160, 1912842248, 2761877593, 81053742, 31423440, 1623392413, 3681614180, 3706303025, 3609099829, 319355607, 2116802460, 1631992176, 326568575, 308633459, 2253446077, 2505725839, 1658619050, 3717100624, 3124457627, 3938979720, 378615080, 796775517, 2484425710, 2370945803, 3635404255, 1642897911, 3461267096, 980851450, 669484175, 3957917346, 1291209040, 3534600633, 908358350, 1171284312, 1173895248, 2045404622, 2383359933, 694807182, 782712160, 276844360, 3279951877, 662528357, 1140187597, 962859221, 609598977, 3224082259, 606343511, 1007222254, 3312403701, 3723085654, 2896760681, 1268912052, 2669270762, 2776585343, 2328099212, 1913949529, 1705013131, 1352980727, 3247747100, 3237280485, 3725838632, 1816740850, 2095343623, 2604445469, 2014122662, 2278326090, 2137889241, 2073810843, 3230036038, 2722123549, 625335738, 2143934557, 3485229053, 907622657, 389106053, 517294670, 3975094579, 3460497132, 2753230712, 3618500254, 1767180180, 450598903, 318120517, 1371944747, 4270384812, 4064996567, 4062789116, 2378871712, 2581768669, 1541615487, 3183806363, 2187213713, 592752252, 2581891948, 105706307, 1271739594, 2675380672, 4001439490, 4045432171, 1661211140, 169691080, 3239633127, 1859466085, 4177368645, 4254065357, 1214584656, 4106228738, 1588437889, 4216163436, 1823694050, 1947452389, 3346370711, 3092250440, 808677001, 2442695134, 2423455871, 305111635, 781955824, 3233596643, 2406310476, 4094768582, 3539230931, 16926799]; const POW3_15: [u32; 812] = [977076225, 665231849, 1569936694, 3300462826, 3759246837, 326316884, 2798287963, 3779953373, 2277747800, 689807777, 829104887, 2397668658, 1709214325, 4206373129, 3483391277, 462393218, 116664855, 3637894846, 2827889973, 2289639987, 3701261422, 4131673423, 1392299185, 18191081, 1308379809, 2813448616, 2137621016, 3532900543, 1569394972, 2216088761, 3605559987, 2480823850, 153023415, 2537218497, 754662786, 2688938781, 104227757, 3786462738, 1526336091, 4226287732, 2226740239, 221297306, 2380509180, 1464866741, 2133456807, 96068661, 76554789, 1194672402, 1286883027, 2750574887, 3680268940, 1148071571, 1618401263, 2273043207, 4233533562, 3294809827, 3038764813, 2260406468, 2751753334, 1445140655, 951517675, 2699714925, 797923648, 1411860472, 1216680597, 1265156686, 3093702682, 3635681048, 103475451, 1351713669, 1822435752, 1075856608, 617029753, 2108292708, 2265794484, 3444562046, 3013856539, 3374113009, 1273744434, 1798683062, 731085671, 1174843365, 1264751086, 3613934285, 234566293, 759631509, 2924341480, 1364564907, 1422066798, 3499662881, 3217435347, 1735515946, 783210314, 1463486206, 503941910, 573961175, 3116332448, 1988468357, 1619292039, 494673558, 289406169, 3681947934, 2354543125, 576799059, 604599075, 2021838681, 2539335679, 3620888342, 3440021174, 3167827176, 3202187935, 3409546789, 1753251271, 3951582214, 521441946, 3520318558, 2949580253, 1744686194, 3722262649, 623707689, 2906626542, 3122971166, 3666397302, 1405545324, 3247824480, 50348455, 2950984894, 4100482143, 2601927701, 769445341, 3282420320, 1612837839, 3846723436, 3100293446, 3454749416, 3832773649, 4106402262, 2132557325, 3697449131, 911174079, 1113364369, 4157715961, 3459844844, 884122317, 2104093387, 2246217016, 1014013752, 1363067164, 2136896341, 638524480, 856226478, 2613694659, 3809502541, 1101617889, 1348584245, 4085070738, 2653090842, 3548571547, 3638729786, 3978827176, 2701180571, 2431405901, 1991357722, 2789553889, 1215139818, 149948434, 1862909929, 524705816, 3865681882, 3085477434, 1234829146, 261905085, 2486282815, 902059058, 1115268482, 3234668970, 633446375, 2133637664, 208465789, 1168192927, 91089615, 2600824463, 821516792, 655082941, 2827356163, 958520014, 459754197, 3190418314, 2477738486, 2276057265, 2937046308, 4129474599, 2953340360, 720300476, 3071321147, 1961269026, 2626964164, 3295057101, 351312209, 3989328611, 4016287034, 2784297095, 2584564549, 4235964864, 3020191779, 3613856936, 3834427981, 2394222409, 4238789829, 4268785928, 3051356005, 3293606548, 3630736032, 422867984, 432824566, 3901098751, 2390975830, 3134306497, 2564921837, 4140939134, 1810973406, 232764264, 69946565, 1089005411, 288255572, 2307356902, 721551027, 2799884692, 4290562898, 3755023645, 3388258631, 1735432797, 3975130945, 3656271477, 980084222, 1693335884, 1128682411, 459254825, 4286436860, 1282800380, 3201300723, 2913660195, 1230767939, 2564841558, 2901607613, 2047657105, 312129423, 3670907676, 747204213, 398567505, 1017711391, 3562607879, 1151347463, 3504014102, 2885816569, 3702067617, 71206157, 3414390270, 875720752, 756309280, 2064378149, 3801432071, 2624302272, 4115743361, 2437234452, 4096619154, 2014005425, 837832307, 606482339, 1435363044, 3220253675, 2923815073, 3601698132, 2353903620, 320691909, 2980412705, 3629142485, 527344715, 712935520, 3244244787, 3953180185, 2997173735, 1152679787, 4141514275, 2153167521, 1995499395, 2881799696, 1641155614, 2156166469, 1572616433, 1510630704, 644378049, 4087657681, 3978892094, 691499394, 1761722997, 3050169641, 129094026, 2242972306, 3174880108, 4111928597, 2556230763, 1057341631, 3171345450, 4263386100, 3631765252, 1299324510, 2638754245, 2928716291, 2489288192, 1674137302, 2117213443, 882713605, 1721601475, 454277280, 2909840013, 4261878591, 4022483988, 3544985560, 458094242, 2961271485, 3048055976, 1376883343, 449828671, 564618158, 4214664377, 1215494659, 2499909252, 4219176856, 2811094696, 1385141981, 2701051365, 1856463317, 3584408118, 2968635820, 10172405, 2056014449, 3384619603, 2280278205, 3805365066, 901038155, 2068856942, 307396294, 3069118749, 998505300, 2487723299, 3358590131, 2731763005, 2707256312, 1883994053, 3799343800, 2732088777, 3387374759, 2710407985, 2023144656, 1627017642, 2744538970, 1417526901, 1979078266, 3955229367, 836934913, 3899152926, 3259588588, 4063607839, 1894138936, 4153978973, 2768699532, 3020574603, 2328913378, 1569099469, 799511246, 1133327297, 300277759, 3974871327, 2460059461, 3899205157, 3064672977, 1872540621, 945262695, 325232699, 76534068, 1479292589, 79858847, 4048780148, 4214538964, 3544736689, 3122263589, 3478566613, 81585786, 1883073293, 1586951053, 2187904173, 310461746, 3417021150, 921595721, 2053427479, 576973815, 3088873149, 254955010, 136832176, 4131280646, 396511795, 933966624, 596695524, 1886566601, 538546092, 1777359054, 1782863433, 4088120414, 2692527488, 1994469219, 1205575334, 2220302319, 3071518678, 1822291831, 555715043, 1382151022, 1251562657, 3366152646, 2235627699, 3309035321, 2952465262, 1588243565, 616371241, 1537858556, 3733502239, 3038942605, 2943072839, 1772377061, 212909121, 280698560, 1185201976, 1806348826, 3495857928, 1360522891, 667653581, 4169340271, 518461107, 4110527590, 2668038607, 2414610661, 1865330298, 825331100, 2444783573, 2466941253, 3650347584, 1397625664, 1980523468, 3793438624, 2690589061, 1195952221, 3747602114, 2374869194, 414544833, 27677727, 3400143154, 2210677843, 238322055, 2955979780, 1742604312, 1635554129, 4288342779, 3525767625, 3575812701, 3852420364, 774768456, 1506764262, 2429709095, 650578902, 340564538, 3927129992, 4056828676, 166703365, 33948809, 3717821049, 1509919413, 3567916042, 3981250677, 1927530024, 224725383, 600599372, 1383643164, 2138194201, 4215725040, 694881644, 3312648852, 772708618, 3733439657, 4142109032, 3690065639, 577875182, 2042961772, 2305850905, 2666010309, 4139127974, 3625925851, 37363622, 1484971370, 4226846556, 992135373, 1354091842, 2706219413, 4006422807, 3356274389, 1898412496, 372485657, 3113085433, 2469075819, 3700417951, 661665232, 2175263303, 4151002255, 1322953602, 1398857372, 4092760541, 460708877, 1380138655, 1173256788, 3543568491, 372513444, 3618774273, 171778171, 2906866967, 2741819333, 2449184156, 223365344, 4074821242, 389134615, 3872232579, 2182620296, 1144968045, 1253477771, 1488762008, 950621237, 2808471730, 1754633513, 1343614188, 707229382, 1587254860, 4057654663, 2471650257, 3003858919, 1521938392, 2801431700, 4041731793, 1665613244, 1764345685, 2682613774, 1089317494, 3920898996, 1631542663, 1152751820, 2593297577, 2401176124, 3427924880, 2895054615, 2841733279, 3854928360, 3715787645, 3776522603, 2555629509, 4206541732, 3223789014, 3740340293, 3320164578, 435177505, 2523400968, 563655360, 1581191127, 1144707279, 855705671, 1764404902, 1980422602, 3193983722, 1784826658, 2033241881, 3298662269, 4052448551, 1814214611, 2414784682, 1392057948, 1530764508, 4236021491, 2631121997, 1558832356, 65806235, 2439716846, 2333677941, 3855912835, 3323178073, 1648841414, 3829450625, 2677208545, 3734992945, 3608554434, 4151698100, 2265494611, 973831956, 1127908087, 2675067860, 2242029652, 1172430891, 386583169, 891502608, 3159236118, 91249420, 924134833, 655922446, 3878261204, 2569875981, 306765063, 3997879750, 922838874, 469732202, 3413422760, 2100428547, 1134345585, 2671194616, 744990806, 2212196019, 4048773444, 3791713114, 465130004, 396721512, 3896966880, 2771391871, 2858000595, 3584483877, 2691782662, 71701344, 3267381379, 2627664943, 487370091, 1128409664, 555841047, 682672357, 2207620346, 1974862125, 1961136721, 2764165810, 633378149, 3686514390, 1628451091, 1244377725, 4021981336, 2632625717, 212003232, 4213777100, 1614360497, 2205714513, 1193502716, 2965908528, 2556543713, 2169587738, 1716921633, 3361580901, 1270997602, 3251480352, 1461993621, 4009359607, 872306146, 2274523155, 2334723523, 3398888123, 4015291819, 12680754, 2805358789, 2247586482, 28821447, 4228210838, 2867165351, 4209425414, 922472442, 3643667272, 1313769367, 1778529406, 584053570, 83932611, 3878783785, 4196858881, 1254933100, 30545947, 2451049957, 154913180, 3845798874, 1409060809, 3698149006, 527499883, 3434852678, 1979037736, 401474618, 2713075691, 2032852562, 3315343561, 3117156026, 3181822096, 2967959904, 1867039832, 1567241529, 1015814356, 2412089990, 1113107588, 602907863, 159564957, 2080426894, 198488940, 3985292030, 55282183, 3166735149, 1314890162, 119232860, 3469854015, 4174956040, 2691924814, 1006559213, 1532043124, 3780490932, 735080823, 4038443176, 1464982680, 2188164698, 1105691252, 2832066849, 642565775, 2809009489, 3698954670, 1268079142, 3380048275, 2662521390, 3640101839, 1367787965, 1769983508, 1558676012, 3821420353, 557271040, 200032047, 2391640791, 3185110957, 3370102276, 4192700174, 1951921206, 2393913997, 2256077493, 3912963808, 890212418, 410895905, 793331347, 1194949436, 1163600753, 3261321478, 1478141486, 3778505335, 1148133083, 1580132921, 2075844758, 2044688990, 3252322700, 3450246327, 1665549940, 885615587, 3053594569, 2064590405, 882713210, 1035067905, 2624489169, 422434002, 861334403, 1732796031, 3463839962, 2080242549, 1471721702, 3879684426, 1737303084, 452970607, 2407914145, 1453526573, 2797693217, 699390353, 3388187217, 1293310005, 3490803260, 1346814231, 147543365, 3807051994, 513089673, 3224976654, 2555625000, 2421574820, 2500076521, 3147402354, 3326543525, 1259937196, 3089525877, 3832036063, 1145039035, 3033684338, 3430207412, 789393924, 3750175001, 2595067644, 2026469744, 2973210731, 77465930, 199452807, 3866340586, 786433973, 1959614337, 2595721884, 707599685, 2186856175, 3578934304, 66709]; pub(super) const POW3: [&'static [u32]; 15] = [ &POW3_1, &POW3_2, &POW3_3, &POW3_4, &POW3_5, &POW3_6, &POW3_7, &POW3_8, &POW3_9, &POW3_10, &POW3_11, &POW3_12, &POW3_13, &POW3_14, &POW3_15, ]; /// Large powers (&[u32]) for base7 operations. const POW7_1: [u32; 1] = [7]; const POW7_2: [u32; 1] = [49]; const POW7_3: [u32; 1] = [2401]; const POW7_4: [u32; 1] = [5764801]; const POW7_5: [u32; 2] = [2768600449, 7737]; const POW7_6: [u32; 3] = [1855011585, 809251672, 59871144]; const POW7_7: [u32; 6] = [3233510913, 429135816, 2162242590, 3594221799, 4265959880, 834593]; const POW7_8: [u32; 12] = [467332097, 140397015, 2040215064, 1542555902, 642371654, 3366106563, 831699702, 4090248544, 1331205625, 2632189658, 762431610, 162]; const POW7_9: [u32; 23] = [21354497, 135586989, 282407512, 217755548, 3801957565, 1769047343, 3062175267, 1076844155, 1124873580, 2147641037, 1086167164, 3185325477, 3247742386, 2077448856, 1351003107, 2494468834, 1425599169, 1702421937, 627210051, 1827625163, 1157572577, 2350050876, 26301]; const POW7_10: [u32; 45] = [684437505, 4048640024, 292557896, 3831731169, 3332525442, 473405432, 318170344, 90380968, 1033695812, 2724674731, 3595206122, 3629228025, 4209239057, 3965362365, 2238697023, 3154103790, 4052343864, 307061298, 318989332, 3153953031, 3156479151, 3680726623, 4137569985, 2873142659, 111620858, 2694718026, 9322418, 1564274048, 34089246, 3248975485, 350774805, 3831801630, 1993467950, 948561877, 2841933524, 572639019, 4216663619, 2647977339, 3749591258, 2896152255, 2891627799, 2539551806, 2116905892, 913342961, 691771383]; const POW7_11: [u32; 90] = [3935789057, 4166252864, 1130174762, 746642697, 2097267391, 230814212, 262482422, 3074840744, 4242045452, 4198780607, 1168143213, 3832006688, 635278146, 3974112408, 2693579674, 4052193596, 224135106, 224110576, 1831951626, 884408112, 4161923167, 2530538468, 1766697210, 3734044005, 2193311966, 3643962908, 2508922853, 1237927695, 826765018, 301294391, 1355373603, 1013255492, 201605170, 4021658079, 1585360530, 2707437896, 1900635396, 1905296076, 1675742546, 1310459767, 3490908979, 1638170283, 4030411698, 3455559243, 2381042632, 3337653594, 279126172, 981840272, 4256082875, 2339121715, 620004595, 3193169600, 1024613477, 1289526822, 3754565871, 3118997668, 3220746202, 1344646439, 1144771397, 110884155, 2555110865, 1640054265, 266135361, 261538498, 2590652801, 3038147251, 4191122774, 4053161994, 3178416621, 3431021971, 1510437530, 2311593861, 420559473, 3882531531, 1283913491, 4286998498, 297948899, 1491612193, 2971470854, 1136813312, 1037229141, 134785729, 763322283, 3085025371, 3408591202, 487574582, 1031455143, 297009289, 2509812334, 111420556]; const POW7_12: [u32; 180] = [959365121, 3423668100, 712143694, 444296678, 48418474, 142336985, 3887558252, 3943006832, 3576330202, 4129514092, 42707875, 2694838052, 4082217492, 1355779148, 1861261927, 4159987319, 2544936187, 3806468287, 2398026180, 3957753963, 402448149, 2470238010, 66876637, 2170332003, 2407422937, 1228991919, 2304511904, 3264332932, 2065315545, 2762340589, 334250829, 4004573477, 3741920693, 2645443327, 2594766859, 895785842, 685096937, 3987524779, 1950352476, 2513536865, 1885951213, 4205468775, 3467243111, 4147994187, 1971851587, 558300163, 2061929723, 2784144437, 2922857092, 983256724, 230712609, 3933689823, 3690771138, 339563475, 24292607, 3371043320, 1273540978, 999150964, 1547569001, 1982341170, 1284932132, 4168068064, 3400761299, 3440883534, 3651096652, 3298235049, 708333125, 2267355819, 1643664806, 4114241045, 2619840477, 4293837164, 2866213855, 333068409, 2378301991, 991300859, 3044159605, 4196815209, 4135023850, 2196188706, 962925211, 2245320399, 564630964, 2457639540, 3232877080, 3055780701, 980341, 2711742573, 861530545, 3387314866, 3853131369, 32864486, 2678257946, 2669908999, 2000719590, 4085016586, 783013123, 3352468813, 3041875261, 672636292, 130345520, 3182074148, 2375468194, 144749725, 455673297, 3298407527, 2300894874, 2550621169, 2686545759, 2253272293, 2104008843, 3417084127, 3977810179, 3028718465, 3616280352, 472810701, 2435685230, 1140184549, 1815608139, 820551257, 1499547529, 3723830388, 3341076506, 1943874127, 2208139362, 843305710, 3253353809, 450882879, 2226491280, 2792190206, 2983548622, 1950750459, 2107941997, 1949146725, 3541495173, 1504541620, 4057108078, 1764274118, 2345724503, 4134715625, 3990303177, 853336782, 2849901989, 4105387281, 2811829615, 2395277513, 1705693013, 3132275041, 962121883, 1160904978, 716319733, 1865107910, 2767053744, 597618956, 1268902401, 3183068659, 465089785, 4051212113, 2371235036, 153181892, 1517303695, 4284973800, 2302738028, 2923330867, 1156795778, 3306600239, 3325535674, 4131001630, 3795322436, 1518142203, 42963, 1989482042, 462137403, 274966593, 1990974015, 2775016969, 2607645715, 2927122125, 1884990280, 2890485]; const POW7_13: [u32; 360] = [39682049, 2879252754, 3905716286, 2731189630, 966550211, 3252116258, 1335121684, 681044725, 2706091913, 648576539, 1423719455, 2112883936, 446026994, 788763554, 3766400133, 3802304351, 230490497, 1165165563, 11106404, 306247384, 2988589671, 1661613069, 439656198, 1535870016, 3928833501, 3568921325, 1383527719, 966546572, 2522388907, 633790419, 4215157643, 2929987618, 179646966, 1117925074, 4104859487, 290750689, 472489963, 2821759338, 2262625157, 1313217641, 3057814726, 574179583, 1571020465, 2183096229, 4252706683, 2950945461, 225603735, 3822968681, 1486094954, 3059720615, 1450766227, 3907188135, 871584955, 1088147742, 2446721734, 359320498, 1045473649, 152701656, 2073984609, 1019883931, 900397467, 4005214849, 1127792464, 2304454455, 455034548, 43343476, 4155327021, 2523732159, 638983805, 2892302829, 4283759155, 2943823736, 733632460, 2081380126, 2068191087, 3773292338, 3545085461, 2480295365, 2977057353, 1465321450, 4251560853, 2330236178, 200580713, 3888643412, 2710299332, 508228750, 3563957841, 611964264, 2420910703, 3715783850, 1060180261, 3687212695, 57436190, 2594481263, 3517172044, 2710085974, 1386435930, 2003427645, 1887681247, 67580893, 2492380859, 2530292932, 4141927460, 326169307, 3038495324, 1595985242, 4038575285, 871235333, 197140807, 2932035130, 3876347670, 102413750, 1348655981, 3781071583, 991687143, 2244663491, 3034023638, 2226118165, 4266682441, 2558001305, 652816556, 1306666356, 2409492116, 1189710321, 641930377, 121304481, 988012863, 1120045908, 2647024674, 1693808083, 2400379292, 4130523923, 2228041005, 3088521292, 3953572113, 1315146663, 1730466124, 448651717, 3142660598, 2888439717, 2144478006, 1952012792, 1281347257, 3034776202, 3385354032, 1610743174, 3250198660, 2062397168, 7849456, 2951565047, 1210878543, 3197024034, 3936553620, 1576601042, 1703562519, 2038817515, 1911545912, 3115087069, 2546337969, 1477903667, 1111933258, 788616929, 2725714831, 3330901336, 1035806609, 2773494881, 1840946151, 3387943085, 3856066552, 3124046370, 142112852, 3468696704, 1443178086, 4025409800, 3051817770, 3710270826, 1815171402, 2543269087, 1648373362, 1343483240, 4281806129, 1455193863, 2812972380, 1656167148, 1786309504, 3815616779, 1363050615, 3979406714, 2704972290, 496180240, 604853040, 3222170484, 1533573479, 2064025049, 525044436, 1431874076, 298038857, 3499922978, 2897172967, 949779672, 2390963596, 4226088650, 1288804277, 114574730, 3602333058, 4093682466, 958318090, 4092877466, 3776234353, 2890875716, 1589722447, 70461774, 3108903503, 1694441784, 52774611, 4265039878, 384595410, 1941048036, 4144534331, 2615953628, 245732993, 3234665791, 4163933482, 1697208095, 920250943, 1613357097, 3496559205, 3015994176, 40127559, 3369681758, 322792290, 3524996575, 3994827051, 393680817, 3200838249, 1153726347, 2406622498, 3869429162, 425402345, 2207346618, 365059, 2913999903, 4229175742, 2389219440, 1271061414, 1326457181, 450511120, 3944707822, 3886268527, 789528580, 852899589, 2410522351, 4038073280, 2914394560, 1370579794, 2293563894, 2719647097, 3380071952, 3067201483, 1763398529, 2991294230, 2209995439, 3200272980, 2005056358, 1166615296, 880283180, 3472909777, 342105901, 4124970840, 3561185389, 4208382111, 2839271323, 1206554429, 3696465541, 3706600000, 4229678662, 927942557, 3432267311, 1525401348, 2926457083, 3636398962, 744164581, 2280802780, 1850592388, 3725781290, 1981983136, 2894286166, 3518902953, 4130465722, 2780390157, 294854241, 4252673443, 2401608171, 1052084730, 1085373656, 1581328005, 3173411406, 3835729745, 2899844887, 3136848387, 1454757175, 3772637913, 1260190546, 2099037014, 3394671557, 1749814814, 3800071156, 2262535435, 33126042, 2981030374, 2265695734, 2284915338, 3206556658, 2832368439, 1417325431, 1582639928, 2632360018, 1712991880, 2547303465, 1517517778, 3660163307, 1046516952, 2374217362, 2927717337, 2513567247, 4244432732, 3248485883, 3851115926, 1003869639, 3947494045, 703696287, 1034178955, 1036111252, 1790993163, 3023345892, 3450329516, 1660808035, 3850898253, 1771224094, 579613367, 2072593500, 2421697040, 3247577931, 1513830843, 266394078, 1416619970, 1337774628, 1654066033, 3821326261, 1375198867, 1094040881, 1528646615, 3652940609, 2913873658, 1945416978, 1951666989, 3036904715, 2325875688, 1194681677, 1945]; const POW7_14: [u32; 719] = [1153105921, 3748096586, 978622910, 3057108446, 4163170541, 1475680606, 2896837077, 1817581710, 4230906863, 923122206, 2922006298, 2809572217, 3083308048, 231281980, 627002913, 106338948, 89650935, 1486504804, 2516894440, 3179661582, 3612364719, 1773194738, 4088816374, 354575531, 3666777246, 1576096274, 4233470586, 2095621999, 2970035246, 4110595912, 1358918312, 3628722034, 1149966972, 591400841, 3187581789, 4193396823, 12888783, 574915035, 2249808107, 3381397609, 2623734857, 740709562, 2546218981, 1725780745, 3351544684, 3633549760, 513705480, 3197256058, 1040246531, 1592866823, 2459213266, 3905053856, 2914075030, 915653484, 2333738230, 217825286, 2444620904, 2078822099, 608853997, 102326136, 1311845337, 871277544, 820523394, 1738639497, 4065841057, 1613004231, 2660853222, 2868364490, 1224390301, 513979072, 2055102626, 2109197819, 2669136545, 2085059472, 662164683, 394805015, 3659253988, 2984019579, 2109740354, 1779344816, 304690248, 1330182754, 2018784696, 2900087501, 3007768746, 2102207330, 2981687066, 612325851, 2279869201, 1529453769, 1972024802, 1499876922, 516721211, 321506622, 2707831412, 1201984786, 2336323361, 4219002744, 438957379, 828217643, 4194939659, 2231811303, 384618266, 2593821208, 3563124922, 4107917569, 3403654838, 2049628812, 1052405170, 3716531778, 1929466028, 3972824820, 824258969, 2497221351, 4151283990, 3657604243, 1007508491, 2276339330, 3866424680, 2244938938, 1571583002, 1949328097, 2674201210, 3934027974, 1820081934, 373810442, 1158794837, 1535976805, 2594293063, 1265703501, 1302223049, 1577048594, 151730989, 611882750, 3680638713, 1504655705, 2540403722, 3694579162, 461807637, 3019726503, 3612147647, 3015269393, 2204949105, 526872857, 1035176768, 1835861107, 2364218155, 2681021965, 2554335141, 1288907257, 2605885745, 3807016274, 2952394860, 1044216606, 82999816, 2830344404, 3205579736, 3705177523, 2769864739, 1456121549, 3573727012, 412745620, 2189310813, 187260800, 2590038269, 2420082833, 2314343445, 4136873716, 3047185979, 3178516382, 3032609299, 642806458, 1454301025, 82252124, 3275337515, 1734026600, 3741465849, 2676973446, 2749492780, 3078811183, 3652601975, 523379590, 3297473030, 2317427843, 32842235, 2816337061, 2475200552, 423232845, 497187125, 4214825014, 2174134877, 1493591393, 3250970901, 2332110719, 3959711000, 3929962791, 3625751890, 2435618294, 197650571, 2581084028, 359459964, 1836929608, 209890023, 703580385, 2177789617, 951344639, 2664644557, 2436893896, 2571451997, 3806745872, 3547944748, 4040254763, 386888799, 140028986, 3881171361, 1501141365, 4056634011, 4189900791, 1966959141, 1613488508, 989474367, 854455994, 136161545, 791237984, 3698679741, 535816137, 979707224, 3335735253, 676376709, 1517887200, 1144246118, 1274409907, 1616516914, 912735086, 2379244426, 2517318681, 1597046559, 12333141, 1073220241, 4220849166, 3636789234, 2358542730, 54029752, 1937294786, 2672023367, 3546104798, 3811752789, 2427341597, 3076000293, 1991184063, 3753278648, 121003404, 3652600541, 1984852734, 912364563, 2047474216, 1935941550, 3764307070, 1582175758, 127440725, 2330212039, 526839080, 3312028891, 1394970791, 1474372973, 2540744706, 1738211591, 3837815516, 3252079654, 2301442285, 1613562956, 2499277553, 3441096592, 2747500539, 2287259636, 2807578121, 1677289991, 1665996425, 2217022758, 3756818249, 2980850970, 1544637470, 1633921400, 4205764903, 792411862, 583762863, 2189836678, 1922953239, 1346364866, 3014148848, 2340843708, 1670072191, 1255400575, 3606338005, 2570968473, 2425790420, 707900326, 2143152343, 2745029367, 670293110, 3999614746, 3370996986, 491656146, 1532127729, 77134227, 4178304080, 3558559758, 3725562259, 2466603336, 2438859951, 3311034008, 1514769094, 374651559, 1633871428, 1447594957, 2427805085, 2684566455, 1732135452, 757320869, 3768098156, 3397376950, 1480382334, 588057005, 2957530935, 2011613980, 1687967416, 1777963549, 1233920782, 2294471781, 112108380, 3009690358, 3736688893, 72034545, 4246427889, 2695216477, 530287243, 2050752351, 652291986, 1662763440, 3689402310, 2144301097, 2283252203, 3479162609, 3066689563, 2807261412, 4146952328, 1437257025, 55350497, 3459772015, 369017485, 738846542, 805222689, 2961340083, 3475656112, 3326516981, 2800947885, 2336052516, 2654129831, 238976140, 83443562, 330221668, 3317802863, 666725705, 3383708319, 993009182, 254579037, 4242485096, 1579429492, 3811867359, 3450480200, 1481985188, 1482644519, 2910231812, 3308446917, 3011690497, 2304226970, 1134916107, 488410008, 857142045, 3986457525, 1456260330, 843366222, 3304110132, 4138476730, 736041681, 1547352989, 3049665367, 3506381443, 4124716701, 3381880597, 1915742763, 1808725730, 4105410130, 2198569419, 1386329308, 2356293163, 2685388559, 1719133264, 4228371740, 1468536490, 2067459757, 1718630680, 2324243436, 2952968880, 4076335840, 2403998755, 809862168, 2806524602, 2802419727, 3923693949, 255077309, 4150937580, 822572440, 3602578857, 1263840496, 2488015830, 902056622, 1643356219, 2838629771, 3610298087, 2179873862, 606152528, 2437557331, 3488800879, 876430535, 3098692439, 3125969266, 3160034175, 3523921867, 115637708, 2818674504, 2793552788, 3727731629, 3585445699, 1835434236, 1669933918, 3922127915, 999653945, 2175581148, 3020535201, 3928723015, 3317467748, 1944034356, 217205701, 378862281, 807325426, 867399702, 290496724, 175373522, 3580436040, 568376999, 881149950, 1005592714, 1887045576, 747546941, 2914821352, 3305251061, 1279405556, 881399316, 547602040, 200297724, 1560896296, 2935557875, 748832393, 373218117, 3073301090, 1618010803, 2434671440, 797497944, 419297674, 1553563068, 2313622833, 3559700525, 1635613056, 1123818923, 4112032971, 528915762, 2109047881, 4145488685, 155480440, 2423616749, 1183660032, 2477160975, 828160843, 1484661647, 2471164875, 1489334933, 1012896981, 2338203819, 339361895, 4078634584, 2068779935, 1102030564, 2402077859, 913116273, 809671166, 3761753718, 3940674856, 1742006890, 3686867776, 3967164332, 3646017009, 1331274146, 1731062675, 2538196931, 2828367729, 1244400705, 1319780385, 1316177888, 1870289197, 1316080050, 3170658907, 4107182519, 1177187703, 569255601, 479247227, 1380242537, 555072541, 2004418401, 4282549996, 3119355810, 837186318, 2369247570, 1099970852, 561838147, 20602717, 1138744095, 2891632962, 1493526963, 3499306068, 62201839, 2433802059, 894372251, 2751097797, 1714035873, 3101021033, 2512576194, 3972865821, 1099362247, 3724167579, 1331499754, 776982313, 904336468, 2796586040, 1946476205, 1306766676, 796080494, 3388182499, 2603454905, 427659975, 4154723015, 390160151, 313493660, 1526895795, 2230189943, 4227662425, 3170756818, 3030306231, 8858515, 1122624576, 2923206001, 3469487704, 2441063536, 4202927798, 4084007727, 935649002, 1963520419, 2649713081, 3337381769, 3607591719, 78688266, 520191842, 4042543809, 2517983022, 266942687, 2568707342, 1145096805, 2989583839, 3454749423, 2941347316, 433006007, 3385957842, 2158533973, 1297931376, 1287013961, 2104630109, 2054364877, 1545615453, 2448905893, 3540073710, 1623584004, 1967252767, 1994341042, 1310732054, 2013842419, 3333117969, 2210515758, 2296487942, 1395582116, 3375670959, 2892151175, 4011817996, 619230196, 495042200, 2620782475, 1695574355, 553255419, 3803106015, 4208410060, 2286831406, 1193771919, 3298509554, 3411559309, 4180378230, 2855176103, 1875028861, 2414766865, 1354638132, 4041297731, 3889126499, 100683305, 774308857, 2008948704, 2621007698, 1317839822, 1977505935, 1699489450, 1576232670, 1207737392, 1880318149, 1893164693, 4268540102, 1446410475, 2209518770, 2798189966, 295412899, 1449048199, 1905265270, 3671064440, 260580421, 4150015275, 3668501119, 2341543178, 1698397458, 1549193903, 2671077356, 313973002, 4188990811, 3758641278, 2621061863, 3011353435, 3720176335, 2831212049, 3900897064, 1409175473, 3103835334, 3443002515, 2562592851, 2448088013, 1820389257, 1450260636, 1771109840, 3036330463, 1646746416, 518150615, 1801754979, 3595046886, 2104281978, 2267537723, 857190932, 1871647842, 2990058049, 580273327, 2686857724, 1637859671, 2414777686, 3107828639, 3139674888, 3467628273, 2709878525, 1038907005, 4075121701, 2814464206, 3864794613, 2660278673, 2599961839, 2030885286, 2827273080, 527219392, 4018232299, 1368084053, 3869553637, 1389963880, 1571327879, 4225101988, 1861605877, 2197582553, 3851374488, 208574880, 1204848641, 4294490766, 2842385856, 913263915, 1958032961, 1454915737, 2843434041, 2490051537, 2118049584, 4281828637, 2544353302, 1823440601, 2427463976, 89726641, 4097444643, 1640965918, 532209431, 2943387299, 489422232, 3784107]; pub(super) const POW7: [&'static [u32]; 14] = [ &POW7_1, &POW7_2, &POW7_3, &POW7_4, &POW7_5, &POW7_6, &POW7_7, &POW7_8, &POW7_9, &POW7_10, &POW7_11, &POW7_12, &POW7_13, &POW7_14, ]; /// Large powers (&[u32]) for base11 operations. const POW11_1: [u32; 1] = [11]; const POW11_2: [u32; 1] = [121]; const POW11_3: [u32; 1] = [14641]; const POW11_4: [u32; 1] = [214358881]; const POW11_5: [u32; 2] = [772479681, 10698505]; const POW11_6: [u32; 4] = [2875311489, 3456163242, 1429612321, 26649]; const POW11_7: [u32; 7] = [2585905921, 2073480325, 1636806860, 3370723472, 3947938656, 3233553771, 710186941]; const POW11_8: [u32; 14] = [725390849, 983511997, 1546466724, 1452173552, 4110885543, 3594965768, 3109748563, 3754293795, 4268788147, 2994526333, 3490277564, 3382469739, 833985310, 117431742]; const POW11_9: [u32; 28] = [4267518977, 3418704948, 4145983365, 2633889206, 1401015784, 2168955970, 4023491585, 2524575715, 1049283211, 445723862, 2434794608, 580179552, 2985579862, 2834866824, 480627468, 2191904507, 996937640, 2935962584, 1843145488, 1510931281, 327439189, 27267795, 129172641, 339183348, 3871693391, 3654642246, 1800239665, 3210784]; const POW11_10: [u32; 56] = [4232730625, 4097932706, 1490802744, 1867908586, 2724996515, 2011879905, 326698679, 4127462488, 840325205, 2229494804, 1262994467, 482469434, 1420581911, 3335497932, 1947974370, 115845259, 107144140, 4106149828, 1698261230, 2710549612, 635562105, 955831875, 3553998392, 186570327, 2293025151, 3737801843, 2669890933, 2617861926, 811827227, 1669377375, 2900245233, 1521548800, 1807704428, 414015847, 4291805179, 2832878152, 4263613655, 1607020746, 4106685115, 1439641309, 1239778605, 3869166695, 2478617187, 2371970986, 314417574, 782839013, 2698203809, 2206976258, 2530586241, 2282465641, 4070492013, 3894191130, 926862392, 2441413722, 1215075862, 2400]; const POW11_11: [u32; 111] = [4141133825, 2032979484, 3524827159, 1779079378, 4024400033, 1736752743, 2286386169, 2281943783, 2312119071, 1441879824, 2106994417, 2198887008, 3538871549, 3308641462, 1802204363, 720418141, 784183413, 155727697, 400164668, 813106568, 422073521, 22474994, 2846752640, 2303474280, 2066227883, 1503268392, 250830710, 2090036307, 2739805682, 1001846430, 3888615633, 2916606130, 3948696965, 4099947954, 2539164700, 3619344625, 1436649263, 390608915, 4179636138, 1731812072, 3606488196, 2063647324, 350623992, 170798726, 1288828649, 1497761545, 2941359089, 4222238530, 2336294577, 2515641214, 197418423, 4025643045, 3210677689, 2358071829, 3406251140, 3112734109, 4192102319, 1407631921, 4084900893, 1332291286, 1473052503, 3193020458, 3582429336, 2287319506, 2689946046, 590828939, 1092703632, 3967962452, 1955093624, 3766411750, 668711646, 3860644732, 647459628, 3424440292, 2712061312, 3397247314, 3045422855, 1832687227, 1747645833, 1244959344, 152949509, 1075533131, 202325721, 815802040, 3793027242, 2431666777, 4145768276, 92597003, 3756449424, 771389754, 2833191593, 4152921425, 1032605176, 439850745, 1990627130, 3239738123, 2963980584, 3329048404, 3214391679, 3009295430, 3682028224, 220913858, 2536745075, 2023812800, 2800493459, 3121880805, 974926757, 2069202727, 720743103, 142305700, 5761358]; const POW11_12: [u32; 222] = [3869859841, 2854063917, 1889884208, 2022964038, 3603195100, 502071371, 474465694, 4152855322, 1398326773, 4275106380, 887147922, 1691233063, 2011450311, 388838798, 3801654612, 1331477005, 747816233, 1900605903, 1009749887, 2645734039, 1539916229, 946336119, 851071301, 2692816950, 2662152929, 588635876, 3187004443, 3576613079, 1981871555, 1738099482, 3380892176, 1796956124, 3397525580, 657292099, 2591699721, 3149742663, 4041201154, 2195797098, 3351045615, 904595538, 1334241505, 1521739205, 2828238575, 1038796987, 2547250474, 4200726341, 2703556888, 1739688469, 209829270, 3962781589, 4264971273, 1149735334, 2167150866, 939580810, 239676954, 3218166905, 1552866, 3227504832, 1404487130, 2131450362, 1742093842, 3923402526, 427152929, 2927933153, 2471455735, 1995653969, 162843970, 3235954335, 1548968465, 188747565, 45604216, 1855505400, 1992538720, 997981727, 1559880400, 3491821681, 1490986077, 1924332905, 621812681, 3676379956, 3975921387, 275936914, 4032514215, 3879034146, 3403485904, 595163544, 2554398869, 1953178592, 2826546226, 4184318576, 2722054308, 353502213, 4049756048, 3477037883, 1376236983, 3590379845, 3196628706, 3500798689, 4241740474, 867181969, 779564930, 3911113180, 751942860, 2089630146, 3098914351, 170156892, 2972958347, 2030930695, 630104136, 4174596611, 3610904270, 266982989, 584140030, 4140942458, 3586658039, 3868077426, 3846170377, 2104241794, 975478838, 1543171979, 66720657, 77614061, 737768900, 3576929742, 4024034598, 3067027138, 2170480890, 3649174216, 2001675371, 2111191181, 3801182046, 398908084, 1346485642, 4122990553, 382415280, 850245041, 3284568739, 2534805287, 2823194212, 577939938, 2036269819, 2937472987, 311426674, 367746621, 1689857062, 3424697633, 58605103, 11984314, 877875338, 444100515, 2306970422, 64456454, 3583517780, 4229732174, 4274921429, 2252255259, 3825433926, 1695539474, 1778915798, 2673475271, 2477589530, 25638469, 272317646, 2790651081, 1511598805, 2775216623, 2521592706, 1041000893, 755617320, 2097900204, 462265493, 3907772707, 1663734723, 3889590955, 3920735492, 2602716974, 3960180417, 1970046431, 1435078416, 2818559054, 2384120597, 3902012439, 3472928531, 3458904990, 1151760472, 2654969323, 1576704615, 3965273527, 1465371726, 1704948267, 3067789515, 2045561924, 1391284099, 296961224, 149394475, 636839124, 2476458570, 1406040725, 4203739580, 425906425, 3896729981, 1154686444, 243822498, 3013347645, 780439327, 3321355321, 1150372588, 3909023926, 3283498893, 1381234586, 3540879757, 1738538592, 1861402027, 2769530245, 3578873312, 78385056, 1954255545, 1485602757, 1588799125, 2673761104, 1739122459, 7728]; const POW11_13: [u32; 443] = [2974990337, 886810347, 1235367469, 3247998528, 1266708286, 2281334753, 3508173699, 3584374607, 927020900, 1956332791, 423255369, 2478161032, 1110082262, 179285634, 76779911, 2944469863, 1014042971, 3004104218, 40989949, 1097347567, 2144381125, 2982306288, 1594568231, 840934796, 668771519, 2512929418, 1926593062, 2286317039, 115375215, 2422055400, 3496946850, 721689833, 1760159277, 303610295, 3444971505, 4005211476, 3030238888, 2747270777, 471274338, 1231716495, 3743325078, 1580360895, 345974508, 3614608741, 4290395798, 4142762147, 3552241329, 3959257273, 3114916710, 2989797040, 2743528887, 4144868575, 2329751946, 2023346244, 2722914919, 3963062858, 3805443369, 2843879915, 3376707268, 452779392, 4202201503, 2882236683, 3983056802, 1841321863, 1943804249, 695628442, 2250666831, 474733573, 1309970587, 1574342593, 3436394886, 2079535374, 1473583641, 1801902801, 3293611912, 2392725287, 3312283079, 1033749601, 954822500, 3163673053, 2185522280, 2463483901, 1770933757, 786641795, 2301956811, 2686259278, 39312491, 3914666264, 1762789717, 1837306708, 1007435468, 2177160075, 3296655398, 1282950346, 2038964665, 2580894214, 2751586561, 2917187922, 2937144239, 645598957, 2684220382, 2702748272, 3590116382, 2459018264, 1540131195, 2198036930, 150782656, 2604814448, 63350345, 4217056873, 888507216, 2197882270, 3540801146, 2903226106, 722862329, 3395604303, 3970614305, 44729879, 508855665, 1572645425, 1260787290, 1054909269, 3167223460, 107910164, 3952497435, 1466355981, 3846625768, 29242262, 3180243996, 2569443999, 4266302660, 4103339395, 3283032177, 3672978853, 594635929, 3416582250, 1237100891, 281707214, 390060316, 3627008920, 2684206858, 2926850740, 3020008643, 2691769288, 3673654227, 1082908754, 3040464583, 1704951909, 3794131135, 2749543778, 718192982, 563547953, 2828954940, 3959732687, 2656908980, 2138436744, 486521795, 1171424981, 1625045989, 724353093, 412005125, 3032400303, 1828341894, 1945517046, 150116753, 773231125, 1705584394, 1466940545, 859075406, 4132076121, 83313068, 639737848, 1676217023, 816236605, 1497752199, 823896869, 3749261953, 1261979817, 2748516810, 3621634515, 4030362957, 3373576215, 298434919, 1129231193, 4262487017, 3332018489, 4019029330, 2163521164, 1079519614, 2725808019, 3541407711, 2631878018, 2548421851, 2117515271, 1054311869, 2464880688, 4203703314, 4181753824, 3365161331, 2018783743, 2560337842, 2014785831, 1932415105, 1762245993, 884237557, 3230276329, 20454952, 3683272639, 356236860, 3499440238, 1990782775, 3224132926, 416822690, 4242275363, 364749046, 2007597332, 1605047707, 2521834722, 1912978517, 810916178, 3542071297, 1801734579, 1143093630, 556038080, 2067456433, 1014687787, 232532349, 1748043586, 2069484578, 20784607, 2276087048, 3157699876, 1968607472, 3831090736, 1654015548, 3726576643, 2830024300, 3647816176, 4099267749, 1298173212, 155940039, 2428617961, 1546314543, 2714667295, 2830915896, 1139822374, 797836549, 1418220596, 4066046461, 4146345735, 2259397643, 2228421691, 2468365576, 1370849257, 4079360423, 1139661317, 3949688523, 61570993, 1159761556, 2811376232, 737984647, 1393665393, 4010402903, 2079282959, 291080581, 135460766, 1037662671, 4177242690, 374053900, 3682728148, 94673243, 545582988, 3154559367, 95206075, 363445988, 1013020252, 428519276, 3952976820, 555114629, 928853924, 2720137936, 2746901602, 3444735454, 600310186, 2018362055, 1843342515, 3880080454, 984961881, 3907780401, 3056144783, 3184949149, 3950783192, 193469505, 2635151519, 817462585, 2945037563, 1993534483, 724379440, 1333667479, 2492836205, 3381464640, 3368271876, 2031170389, 4067633372, 3924918837, 4286754266, 3458306614, 734339222, 614342218, 236164084, 1584809905, 2111183392, 1306657771, 2141200365, 3124308398, 4270571755, 3550451412, 478128667, 2686883913, 3611569215, 2910085506, 3018633570, 273750991, 1072897033, 2493114187, 4186065849, 1596097473, 3699214752, 339363728, 1441513643, 3507673604, 3995323433, 3867827003, 4077574071, 3757981427, 2425459708, 627460790, 4206690153, 664849414, 1445743014, 787429280, 1567786561, 193640995, 1063599729, 1475528048, 2643870666, 701285894, 3591459499, 2279084258, 3955873780, 1287087372, 2251837591, 1146015384, 3051667063, 2550050456, 2516734256, 4208571648, 598826918, 2304366111, 2851076526, 1993463006, 3839353374, 967227050, 95846598, 1609952768, 435034943, 3531583260, 2568808904, 3619367599, 1477226707, 51110073, 177139523, 3888931447, 769851956, 2495542158, 1592424566, 2778962622, 3834261637, 1659135327, 491759826, 1112811379, 2944548908, 2883134377, 2326760206, 2945056646, 3496435689, 1692799806, 349018150, 1764242425, 2855067765, 3748713256, 245165772, 1825448728, 588045899, 1967959460, 2182946280, 44403394, 618505048, 415106561, 1298153882, 2503705565, 513469357, 964967278, 939724558, 386295402, 3569810726, 4168598696, 3553597393, 1627215002, 2889135, 3373164162, 505222248, 489875874, 1209335956, 2847054290, 4284077100, 2379694006, 34096050, 1229732749, 1354001516, 3061649930, 3736286526, 1243461683, 4049558096, 1418890796, 3369219718, 945406425, 878930290, 1700641215, 4079722516, 2452574684, 314984708, 3198984676, 2894702689, 1109209654, 1293554534, 464385312, 32630398, 1116566508, 1339200257, 1072368191, 2675604766, 59728242]; const POW11_14: [u32; 886] = [4070932481, 1131894294, 2541580517, 3314335917, 2621222710, 2869536534, 2259585760, 308457433, 3075365252, 141385081, 2209617233, 342003376, 987047251, 2752647932, 415512433, 412750028, 3888010303, 1026392053, 531725674, 41885172, 517497408, 4045966437, 898789227, 399141194, 829183925, 3196159056, 1556167610, 3587980714, 1523862219, 1639041152, 2084734832, 3189329044, 1765573105, 2141192374, 4156227592, 979640142, 4121679305, 1782014569, 1070929751, 1648884387, 3147541389, 4220465729, 4098653625, 303180016, 2564515297, 530392946, 4081743324, 4022373073, 3566899890, 4108692210, 2801029917, 247188192, 3415226323, 1401953185, 1200397516, 2396501541, 1492430773, 3144686397, 1281203173, 191964542, 468640886, 1843861327, 1099663598, 462374683, 1868051233, 1403316667, 2830773658, 1278003691, 3698875734, 1490478002, 1251588998, 3783559703, 1288390447, 3599829920, 403631845, 501073745, 3628790866, 1995096702, 300244162, 2685729029, 1043247117, 1270609242, 1883655131, 4215435320, 4100429127, 336720770, 142595584, 1383060640, 2439149541, 1099753346, 53064458, 2638552127, 3353382228, 2610244989, 491489225, 3786668044, 2121735204, 1532806824, 1413969261, 808886062, 2568527399, 273744004, 2952477361, 2331629037, 3112996173, 112329411, 1544537734, 2946414591, 376685424, 2808148785, 1507936170, 3811722359, 1159670939, 3195571284, 285012140, 2124103551, 3578311259, 564467310, 3477123971, 1650281466, 2410688778, 3398337318, 2986299181, 3717975184, 3060601431, 4017903284, 2653122359, 4070291299, 849084145, 951004750, 1212614599, 3981119203, 2566703780, 1982735235, 846636004, 532784497, 1999973932, 3795100102, 2105545697, 1993347610, 1699669179, 2624964597, 6140530, 1674556546, 966678971, 2090523086, 3887825235, 3241893962, 2586004674, 1357877398, 2064685679, 2290546241, 992284202, 4202912844, 3927220794, 1079658617, 3440308624, 1453049536, 3873319046, 1718339831, 170237072, 2476995681, 385924417, 2221877126, 1588774856, 124201159, 4253033542, 3719812823, 4287560623, 3170521061, 1364694937, 2392634924, 2906240203, 3543369279, 3697755918, 1566290098, 3930668148, 519398905, 3876359489, 2333254569, 1947490476, 375504323, 4047613257, 1639438905, 2964150195, 1232039149, 291272726, 2474215855, 767387170, 852077576, 3180450827, 359841564, 798542523, 3380604431, 2033268447, 298113335, 2521370110, 3771794538, 3757914067, 1995944575, 1984985073, 3977002802, 3290665163, 4260261825, 3644465517, 3428014918, 3164649324, 2041307645, 3402977909, 2926411733, 545291530, 2445788464, 1415275564, 4187220013, 2556979554, 76532612, 1348025426, 506304002, 2479294010, 664845898, 2016498767, 2097610119, 412114424, 2532825482, 1545363882, 4019613161, 3830197079, 52003152, 784340115, 1338279932, 403817189, 3728186790, 4067803879, 995325116, 1394408747, 1326695547, 3494336040, 654333105, 4209872954, 468141302, 3081362583, 2113191305, 1628052800, 3960313831, 1850082798, 3855146531, 2163433175, 4280472630, 3986310002, 3667616803, 617338426, 1442514807, 1696333813, 3221981896, 3998802600, 930750551, 2045906298, 3174131745, 749316339, 2461355189, 4013720187, 3463722134, 3925206244, 903351518, 1436125350, 4246085443, 2955864459, 3038951335, 234079060, 2154079368, 2420162185, 2423173754, 2033757437, 1056733160, 1739561183, 2074753830, 2583049296, 2408306266, 2635307150, 3523389815, 2223713888, 1831163316, 278004040, 1130207121, 3269180378, 3373831537, 1667568560, 447719129, 104696336, 2978338186, 2656085147, 1145580331, 3213259943, 569625455, 339198509, 633080196, 1722577508, 2328208384, 3280823183, 1125969106, 3022600006, 1395727915, 668084278, 3511880526, 3676744300, 4169664813, 3126915500, 2003076035, 2179608109, 3092578470, 1002151320, 1741503696, 844041551, 658131435, 4289916842, 2198587284, 11810130, 3188560700, 1612596425, 947822095, 3422109094, 3145469557, 2317999441, 930277130, 3775579768, 3609086377, 1009443894, 2280721933, 4202076109, 366005216, 3941500782, 3060068449, 1633301684, 2245956492, 3366817402, 2043701019, 1885260207, 2300661209, 1521660573, 1980947376, 3952259346, 3519811464, 2028050103, 3836092415, 2244422455, 2212774592, 1350469798, 3297244715, 2291378428, 2333522621, 3669290718, 180390701, 60300764, 84512031, 2268736806, 632136814, 3182303842, 4119844270, 3259697275, 282630540, 801642006, 2803409553, 2595474417, 2341819055, 1144853912, 525300043, 1135530042, 4229268371, 256930731, 2961900081, 127363863, 3581059085, 1296651780, 2140749214, 974771997, 324842794, 3893679710, 2062677328, 4222442, 1791165587, 859905573, 4116030842, 2946754764, 1176093473, 3167096377, 2766703440, 1003207502, 1268406517, 2969773597, 759332428, 803908399, 1633524313, 2588734550, 2886893338, 3804778649, 3871545617, 3679188802, 1039963565, 2302174152, 2683894558, 1011336061, 3468446669, 3864182200, 1733740316, 1940646178, 143259692, 4252132355, 3590449941, 3046112866, 3705447583, 257756962, 2427814998, 2430857633, 103329624, 4077938023, 1303147448, 3602884249, 1475689568, 397342958, 3081227134, 2830662621, 4138610654, 97172805, 2119432886, 3306055932, 3109151444, 3729428721, 219796604, 3232963899, 2090178124, 1302726280, 872678205, 4199692655, 768054, 1732174930, 1964058489, 632528501, 2759426115, 450224041, 3800921670, 1009505843, 1400793450, 2940475260, 2713485302, 3113099991, 319009507, 2285161383, 3440575161, 770343811, 2509003244, 1340453413, 1032213360, 3878004983, 3454397903, 1154514660, 1090893710, 2576207997, 1724848192, 1985365162, 3538901477, 2447045019, 514898869, 2283491244, 2368316641, 4063318665, 2986655158, 4076216358, 2550056126, 2878339444, 1148639848, 837491563, 1704283458, 1378661113, 4098522605, 3371463500, 1030746799, 2917554515, 1341204917, 3387830943, 611879271, 315404268, 3294079476, 86241882, 3748484102, 2352320584, 774672579, 844276536, 1249900953, 336052797, 2151721035, 586962547, 3641645058, 2341962484, 2208872600, 1269015893, 4105434232, 3543579581, 2965497267, 4023218637, 2321691548, 3392055752, 3997297637, 1959011850, 96508499, 766563511, 1356783068, 1130708583, 2005327310, 2753738818, 155641301, 765599089, 1045643795, 417019531, 4279177501, 3141781224, 2330999246, 1175129605, 3274946160, 325263414, 3715586975, 4087778066, 2820246349, 2953573922, 314003702, 2427613123, 4290348179, 992235384, 138456964, 2981343154, 2109809464, 4284604113, 3950505789, 881086028, 1738915794, 4189931245, 106478441, 2642176795, 3416075864, 3989123265, 387883555, 3991266157, 3972565066, 3187826264, 338642415, 1495975504, 2136825939, 762375475, 508049359, 131999286, 2970554320, 3966422178, 2705492368, 4289705839, 2104019310, 596636472, 3065570912, 3289124724, 1855567379, 20159508, 2457906835, 1788340431, 707498337, 4221485148, 2706774190, 4015950809, 117987882, 3035391549, 2524048164, 457807155, 3396518424, 1288466349, 90439263, 2164109950, 708733436, 1355156843, 2280665581, 1737724469, 2022775283, 529606498, 2452894920, 3461564193, 1954946106, 3609082938, 4218678935, 1298958447, 3837284047, 2129379103, 2948380137, 2299353551, 1424725141, 536058925, 503230181, 1996902958, 2400752447, 1496876021, 3404123439, 2358739091, 2151289701, 1443733466, 2818061111, 3082508621, 2709122055, 992958633, 1512850725, 3012822226, 3384645338, 533725542, 4044430918, 272943741, 943999291, 1766065436, 2877732382, 3835412802, 718108910, 1397588672, 2680041715, 2282977712, 3270916867, 3722273660, 826652679, 4143202450, 1650020929, 4010941523, 2718815727, 1602960184, 1427517158, 3644929012, 857260087, 3243666693, 3340410932, 3676495307, 4030353869, 2792872295, 2156212200, 4025830339, 3870363358, 3850982905, 2546524745, 1538610575, 3594745811, 3951971938, 3137413934, 8469919, 4235244239, 1270322934, 1228060597, 3877519911, 1160386569, 2010570083, 1629837228, 2571271563, 578136632, 2489161866, 655133121, 1500184496, 190202049, 2458685579, 403297538, 778321025, 3734551682, 2631438217, 32541742, 2466777289, 4128937423, 893637377, 1073285338, 492763568, 3239505966, 2269081088, 712333859, 830437732, 3447526734, 3696521755, 1296725656, 608606261, 3347056464, 2897155532, 1817848162, 697798988, 132644033, 4219025119, 12060084, 1451516218, 2212982342, 3664925880, 2146221586, 1575731675, 2533044067, 1755593894, 2058968296, 4290028320, 1455009286, 66037293, 573802245, 3036270415, 2552709177, 2564995126, 1200668905, 126743679, 1273110179, 1437985708, 506765039, 375995703, 1631860051, 337395672, 1544295859, 139177756, 4224519853, 1160719268, 1886998076, 3127117391, 2088826595, 199063578, 1399636190, 2790105408, 927425914, 3200190318, 904924367, 2965435123, 3940870390, 2208604356, 3726163018, 1459478394, 338517128, 3779374617, 992010876, 551173706, 4223223345, 3035093341, 3888145231, 1232373136, 1733768816, 1795904673, 2551527730, 2752925555, 1196709495, 3342895187, 4110270879, 2743430114, 1754629452, 2348271519, 1771309554, 2341244584, 3390218226, 1385211349, 3063788339, 2485171731, 2885497667, 3304778666, 1809504693, 2992696783, 1428344003, 623630415, 936927397, 1569189475, 3214559426, 887178239, 2619861432, 1890694716, 1535366889, 199677522, 3432642120, 3647950708, 692899641, 1637087898, 2749418322, 1977363022, 4099800292, 2404536715, 1423983840, 727951753, 3983837110, 2974501161, 340512213, 989883469, 863907583, 2582484458, 2586599347, 944006389, 2185993602, 4162703295, 1418591485, 1362602198, 3388441084, 1053587319, 598791580, 1292863440, 3094564285, 3653072303, 2477921523, 670324931, 242053704, 2706816646, 585803084, 3709712346, 1235872749, 3683668463, 1248998175, 3313218763, 2228491170, 503151767, 1010983578, 2816330914, 3218773763, 1596737466, 3055840371, 2168180487, 1523514012, 1495001033, 3644591539, 444548763, 296729366, 1778637469, 1193855794, 3405789531, 3354183376, 3728215902, 3103751643, 1527238010, 2420400493, 1402016200, 1617688348, 3238327513, 1969615161, 2342876063, 3288511060, 3790922492, 2000550945, 3318981623, 4021432786, 3510791403, 2331892605, 2557162884, 4202413135, 3305792408, 3474494290, 3325017089, 3904897310, 1684472309, 3007641723, 4154313981, 4276823588, 2362703100, 3764623176, 3532967864, 476776680, 1141442939, 306204369, 3779583093, 3291937717, 3308501447, 192247119, 2410509919, 711399214, 1829817082, 347516703, 688605891, 4157145667, 352944182, 3251086987, 3719124641, 238052721, 209502934, 4029082102, 2806990453, 3373411417, 2081377628, 828649400, 722547061, 2282664078, 3575173360, 1359901770, 2464158424, 4066308244, 3464822223, 177133317, 4226125148, 2593495596, 829439895, 1047772155, 2185360966, 3933664574, 185903185, 3163334715, 3001227763, 830614]; pub(super) const POW11: [&'static [u32]; 14] = [ &POW11_1, &POW11_2, &POW11_3, &POW11_4, &POW11_5, &POW11_6, &POW11_7, &POW11_8, &POW11_9, &POW11_10, &POW11_11, &POW11_12, &POW11_13, &POW11_14, ]; /// Large powers (&[u32]) for base13 operations. const POW13_1: [u32; 1] = [13]; const POW13_2: [u32; 1] = [169]; const POW13_3: [u32; 1] = [28561]; const POW13_4: [u32; 1] = [815730721]; const POW13_5: [u32; 2] = [1778525249, 154929377]; const POW13_6: [u32; 4] = [1780897921, 912625740, 57455785, 5588660]; const POW13_7: [u32; 8] = [954528001, 2552460193, 811089956, 1065775915, 3255164516, 1007972746, 118568612, 7272]; const POW13_8: [u32; 15] = [2628444673, 1667825520, 3480482745, 1792807966, 2982160738, 2216443239, 1414760918, 1741036037, 3705043424, 136135250, 395110073, 1084641480, 2452973265, 2183283898, 52882385]; const POW13_9: [u32; 30] = [685360129, 1249145954, 645630652, 1995019793, 3253088488, 1804068787, 392320294, 1343267562, 507087513, 2330257028, 3658736453, 3072903141, 2377702882, 4240373633, 2610933614, 2563321149, 1240024358, 1174015769, 312909694, 3764772638, 510500093, 1167371064, 563930725, 3086997765, 1545500121, 2429233725, 68804066, 1863990200, 3296313385, 651121]; const POW13_10: [u32; 60] = [801343489, 3687300930, 3650812618, 1292855309, 2657805576, 2016037326, 2874760646, 4032262657, 3967567070, 883767154, 3799873193, 1340661027, 2187028009, 519274923, 858329769, 1315293196, 1461381497, 2243176904, 2753124609, 1955575782, 3920557849, 3872634657, 1019315217, 2838082753, 4120836809, 3754077040, 3026025179, 3031194929, 939865930, 3056830274, 985854548, 1576100855, 1107911373, 110425770, 1299195383, 1944865273, 2937643568, 2194411508, 2836927120, 1383249273, 57765149, 3867259877, 1932068233, 109231726, 906092787, 3309745783, 2104989599, 791524559, 2729013296, 3986268043, 477685452, 2884389037, 612321482, 3705313463, 2993214628, 3749675120, 3978557831, 3791485445, 3052761081, 98]; const POW13_11: [u32; 119] = [3620147201, 2520448972, 3203085989, 1217137342, 484743908, 1266092962, 4017933550, 613421828, 1157475910, 1814056583, 2810379772, 2293156651, 1965199283, 1927758316, 2374138670, 479770094, 262749610, 2384139334, 1670384786, 2884741713, 3251648127, 2797691182, 2810917987, 3630241364, 2157703366, 2088147519, 1236575574, 3715291775, 454175536, 4102988862, 2473058752, 663798426, 2536668137, 3238952308, 1835701502, 1702835847, 1052170065, 1687755339, 2826467910, 1535016938, 3193994837, 3446775204, 2204416003, 3656812722, 2730402046, 1893756449, 2053075260, 860659233, 1806071445, 2655250301, 4258151335, 1844307072, 1274603853, 1527617519, 2253700363, 2821044754, 419774276, 527694400, 4022163085, 1101339995, 2025426409, 3797830892, 3487708653, 3598614153, 1916423427, 897070156, 1895034986, 413560392, 280773718, 2448371825, 165282340, 179165469, 1030808076, 39526810, 3877992771, 2162336219, 2334849212, 3701673118, 3052707624, 1966847591, 2558342553, 3106702943, 1120734167, 3082482115, 117878845, 1243873970, 749558131, 2716083794, 2654625971, 285288667, 1341977361, 3231619945, 2142906861, 3563550616, 1991443713, 1969042993, 841057806, 1671882063, 2685874009, 1179964040, 3849314352, 131899846, 1283609696, 3137550223, 3712908318, 3301971787, 3577169086, 4263774890, 4235897085, 2488576797, 876167408, 3032262832, 797148112, 2583748789, 886261242, 3063930978, 3840348196, 3510548215, 9743]; const POW13_12: [u32; 237] = [2425233409, 2574743363, 4101624837, 2153042727, 1531252719, 4036354306, 2401474531, 2403619786, 1719472816, 350359211, 451450518, 2224633991, 1428121154, 1999448647, 1585463868, 1206872105, 869324018, 848230480, 2750061047, 4284173396, 486383658, 831827024, 675124885, 984738848, 2138354606, 827070744, 3016864193, 431856008, 943413656, 3266222201, 2837427173, 3463873313, 677794294, 2548501243, 178001789, 337320639, 4034985727, 1808420373, 1344978182, 3912589803, 1033442872, 52718543, 2250494829, 3558544136, 3122831758, 346404849, 668684072, 2406040350, 2420354654, 637393673, 4098750334, 2939549086, 1264791761, 2859564186, 3468812613, 4008674017, 4254115003, 2544764869, 3867714930, 2529930645, 1851568576, 775869569, 1482041037, 1137060211, 643668385, 4102840359, 2555794241, 206916058, 983377758, 1396985722, 957949107, 2024380604, 2199022796, 1499271974, 469023693, 1177083598, 1752268915, 4060513915, 1446807110, 440224784, 3705711514, 1983674577, 3576135134, 2983057703, 3538843950, 2737247417, 1005612404, 2991215791, 983614109, 743993101, 1647755052, 1259263581, 319781774, 1611804733, 1083833261, 1208608074, 2367174970, 3194329404, 1177756119, 2474980291, 2369559203, 2068529994, 1297717025, 1454638114, 2734555032, 811712058, 1336242572, 2310255276, 2387114925, 3271408028, 2502887356, 2094479200, 474660715, 3350628624, 3403940146, 2050141589, 1833993774, 364733640, 3218126981, 3477723798, 380035144, 1826185561, 873938827, 1714280976, 1858073373, 2083003323, 1474730733, 2882374875, 904986443, 2473857363, 3269354893, 3448104725, 2169444320, 2235183121, 2575197543, 2290535644, 1321689261, 1935808522, 1112616083, 1754300357, 1425341447, 4085151395, 1182577983, 1254051060, 4119729564, 2401638640, 3454808266, 2309994520, 1640684696, 1224355549, 2182651080, 3869604543, 1863319579, 3078167217, 1904866486, 3792869478, 1355205715, 1864150525, 299187236, 1185533991, 882246841, 2345090191, 3112757939, 3285727616, 509028476, 76970100, 3315151085, 3688079555, 2862397804, 2196302659, 1155354124, 4085531211, 3884726114, 2096383930, 256229858, 3034840193, 823572967, 3539255498, 2332934609, 1314879257, 3110127578, 3138071632, 424647373, 2353538903, 525324637, 2245908706, 1032785158, 3572623713, 1981528100, 1742376255, 2042281104, 2047789421, 3137387214, 4164202311, 1795955008, 1524631721, 628395172, 1467338913, 4175798669, 2970351306, 1934462376, 3084449096, 3326694779, 509857835, 2919086400, 2663173614, 2779131459, 3282039794, 3983826989, 1917509999, 3495152555, 4174987179, 4092034002, 2311496518, 110257144, 2327334555, 2213388081, 2124473154, 3729882918, 4189444486, 3424543753, 2265140621, 3633421397, 3968371473, 33820435, 4070867890, 791648135, 1518365079, 1843767356, 2800735357, 3415928287, 1970816581, 930922651, 2933175509, 1383619664, 3467804447, 94941976]; const POW13_13: [u32; 474] = [2770092033, 280224110, 246091942, 374836744, 3607013529, 253512952, 177646904, 3922117122, 2148254347, 3223611726, 3865501515, 2626156833, 989547111, 974283937, 3003459491, 3170742052, 2589703124, 2581400182, 2165153230, 2985830471, 1475784315, 3504033590, 2881668895, 2316680387, 3511038643, 3397084274, 2578493341, 1960520677, 73504101, 3051337079, 1504567381, 518177353, 3575573965, 3057255272, 3216184760, 3346547012, 393673973, 317565720, 957485750, 813335576, 3709344008, 46126917, 2611447377, 4126735737, 3595823679, 3611359744, 2031678107, 2191428280, 1411860804, 3051745288, 3280383825, 3335460735, 2226183551, 4025871240, 837606713, 3006379156, 686664223, 2768120872, 339578215, 3917147530, 1273686782, 1549830028, 3078670208, 2494099685, 1042732950, 3163033797, 86441987, 1281815991, 348421568, 217001506, 4017340371, 4019844214, 3556283649, 2146097930, 2270174349, 1719863819, 2763306949, 3697682472, 276478498, 1999857109, 2253852500, 2852185129, 3282813689, 3353376613, 394482546, 3535818980, 1110676660, 3186472404, 800893469, 3992983194, 2176615172, 3948360834, 639471592, 103908103, 202243463, 113430590, 1331890480, 2630431929, 528384611, 1600167062, 2598772260, 1912111261, 4293437669, 776014103, 1566456533, 1609790320, 3159532308, 2128884070, 1533748912, 3911012398, 2872566187, 75228133, 1378524420, 3108914974, 3868458668, 2981751804, 107089968, 4253406523, 3961903717, 1020359712, 2004968899, 197361203, 2041843185, 214556791, 4079590443, 794785720, 746147898, 1233829155, 3762541793, 3863505596, 3628747110, 158785463, 1873132594, 4010432341, 4073167215, 3179777450, 797445362, 3710062573, 4223428401, 1389616073, 1893581875, 2546613520, 1245613358, 3803671791, 1988518811, 2888476702, 2567029727, 2341492200, 3193553523, 2222450177, 714099752, 1450703628, 3150528499, 401219602, 689603544, 759986930, 3078711132, 2808389020, 2591337821, 3677239533, 1644870392, 645042089, 2259101651, 2035601092, 1917023803, 2922085335, 4187753069, 1317058292, 2373086190, 3513129050, 3133275789, 2552447641, 2928047049, 2556372464, 1909569339, 3211899072, 4676947, 1035632270, 2488097790, 9003917, 3830909762, 1434251395, 866919600, 292794276, 327039161, 740061955, 3686185869, 3001893598, 1400171098, 359791510, 3510621913, 3461839011, 2188755022, 2894813905, 3662814350, 243919073, 1670424940, 2987320578, 1546978015, 3950456083, 1167806508, 3562314041, 3879472154, 639979027, 2408265652, 3361581149, 1465489790, 1195818519, 2217402719, 2691027340, 2017525845, 2317038524, 3174058830, 2120025818, 2688173402, 2943399075, 99619204, 3434080855, 4274885553, 1820238284, 1763571765, 762452581, 79715782, 2145788487, 2661559287, 648455633, 722916325, 1850179877, 3031761966, 2300516444, 2624237337, 1702671866, 3569612857, 1582992344, 2684356765, 1210899082, 1397665657, 1271600252, 3524956906, 1552340482, 1363082597, 2529231496, 2542055832, 1159800647, 1169650988, 4285318734, 1452462859, 611511573, 3612626278, 587667021, 3623373186, 2194342199, 4291509347, 2185971813, 502535224, 601182308, 3908631698, 805942480, 1879472563, 1607395107, 1129122572, 3298848373, 174698773, 2785240237, 1444202161, 4243527810, 259356752, 2850901382, 3933623322, 4115636047, 547038038, 3655462568, 3502451555, 926079503, 1722207232, 4138993533, 1039107710, 3298283152, 2282624588, 2945236299, 759263377, 3391272306, 3433251348, 4265990061, 3149069185, 2403408177, 1162778116, 4134714139, 3813329316, 1171827073, 400581629, 3009999040, 4061326516, 1261810447, 511899134, 2451111623, 1355824333, 791974327, 3686088002, 4101109368, 219973590, 1120035633, 53961656, 816734567, 979301214, 3640215323, 3764031081, 2185919590, 860594344, 4206263253, 2200598939, 3583011712, 699277704, 107496135, 3983224148, 3690497201, 3903478923, 3285573455, 2116551127, 1162978445, 2559642491, 2515822592, 4067740483, 922254774, 2800200216, 2402553132, 4239545323, 1337189450, 2181950874, 2372338711, 547750316, 1309058307, 904368026, 3666222198, 1068046481, 3277822362, 3817944533, 417730359, 1546943492, 3852618022, 537109694, 1098971095, 3302128171, 2727628990, 2165459563, 3684942333, 849597304, 1763743193, 1883968625, 830232956, 318348250, 2931492361, 2026235029, 112878337, 723329677, 3587687010, 1792817637, 1493742140, 1187328123, 3993625964, 1839596571, 1858019152, 573000935, 2404658877, 1742169035, 2851996326, 1045595807, 2425224508, 1482513435, 4074947726, 669697757, 2558647442, 93498172, 1220328942, 3225739130, 574036431, 1293679291, 2345754323, 1066530946, 3988256419, 2671745740, 2527519788, 4253346119, 3473651924, 921950866, 3552188502, 179378863, 2136216814, 1085209858, 506391777, 3040955182, 734408408, 2240296289, 2353189990, 1525516884, 350519298, 4034989771, 3125870643, 2498034387, 3325926792, 2730601914, 1965324699, 579502103, 1181376476, 2504227516, 1399468995, 352661714, 1984723490, 3666746672, 3080165925, 1879443766, 849919215, 790324719, 1569814023, 2458343887, 4014421975, 755780875, 3186796623, 379409846, 257726134, 918072968, 4176579022, 4264622186, 214176848, 3857236105, 2402509578, 3828635205, 3694477513, 711561401, 1845924925, 1234827689, 2036365951, 2239015709, 2041164661, 2616341638, 1012632782, 2595136816, 2122924896, 1366611735, 1961650896, 474321148, 2926691709, 333195756, 3381411750, 541637243, 3858321538, 2241353192, 2749834711, 4031206761, 51329255, 3462462125, 2669823769, 823300936, 1674034500, 3485087004, 2450138386, 231547375, 452303643, 3414776178, 3326617885, 3875604562, 4021341687, 4068217451, 2155536911, 1728551567, 3648149057, 4145014037, 749726987, 420081287, 2712204900, 2278319478, 410408403, 2246964915, 2098730]; const POW13_14: [u32; 948] = [1513652225, 2561421435, 568016091, 3219124610, 1567548994, 3140672003, 3901443699, 2182387622, 4141196970, 366544369, 3676769560, 1911033767, 3242806085, 3748543015, 192824234, 1956115948, 1696291081, 1211388376, 700323856, 1515270072, 1084306770, 2465771648, 1542369175, 3166292813, 1509064568, 2196599076, 1239276043, 2364515323, 3741001254, 943293, 1432737829, 1555653668, 3641646355, 3313476148, 1069086654, 2865509789, 681536068, 3319239661, 2983083463, 1630276271, 1686018834, 3982604714, 2499040238, 4080953275, 3186544137, 3492167634, 3859279674, 4002574719, 2303161186, 1165791332, 3824318502, 2061358225, 937392540, 3954310122, 282436525, 474293277, 4238882128, 7082045, 1225756846, 1870807289, 1085028422, 1406801929, 3672630733, 3697064332, 2065063721, 2263797067, 11961925, 3559293097, 390564761, 656808016, 692370340, 2322676275, 546038800, 1672419195, 2556287572, 317711936, 1327212729, 4259953, 197577355, 134308044, 2271578320, 1386560190, 3050738733, 1718060978, 2130640554, 1331375940, 624111047, 3525554789, 1985521375, 2586019191, 1558402647, 3909440642, 856980417, 60053137, 913591866, 2898291345, 3513718336, 329509821, 2417319852, 4168311558, 664301251, 636015145, 2271617140, 1452171662, 2458460330, 1505883977, 1445507301, 302456227, 3822965831, 92894040, 3072167418, 1758772508, 2961726038, 3942910328, 1720364146, 300138901, 1080779583, 608595466, 287672053, 2991774865, 762076370, 76860426, 1501520728, 1340523011, 3081299408, 1760038262, 333139184, 1290564990, 76012907, 356964572, 859660282, 1728034276, 4082308696, 3863777730, 1111208589, 4167045508, 2377192236, 2115772327, 252081885, 2110972140, 3423848279, 1825612364, 4007303109, 3940132191, 529705551, 1131819847, 592386154, 767211996, 139345560, 2560638736, 1895474888, 3572412807, 1881983119, 306828160, 4280170547, 3436356640, 36724135, 298470868, 4009401144, 1201965222, 1907743005, 2272048226, 2027347658, 3171140097, 2209466522, 1141566160, 1535992603, 3480643687, 1411494951, 497705101, 325571997, 863779574, 1184765804, 268740290, 3578205385, 689075140, 2224186343, 674642629, 1777572359, 2532206686, 1918297826, 2786087730, 4275399690, 862160943, 3259486169, 482763122, 3311818353, 3745176056, 1712996127, 2457056529, 3105386152, 2913799945, 1952930022, 3669936214, 2031184872, 2112139107, 2357143158, 2447231606, 507345305, 4094940971, 3926425827, 3724336083, 1509694285, 151207944, 3864335236, 727913605, 3187844539, 872137891, 1332616877, 638024373, 3801449042, 573612644, 575875522, 3238993358, 2861607758, 2548845838, 3141071378, 2334409874, 4289008640, 870877795, 1278831489, 3428774005, 4271138832, 1818592575, 878735662, 3620716114, 1945114857, 839824163, 2157168551, 4219212498, 3329653447, 3874762373, 3680159945, 244325794, 3271264534, 1473424871, 3737837342, 3519006596, 2834960577, 3436012911, 3683895049, 4176039645, 2376577933, 3247021487, 513042186, 768601904, 3622268649, 867697180, 2366161934, 3939446948, 2835080666, 3537114981, 1849443514, 2370190814, 3809085128, 3267234068, 719980388, 1621149743, 2686272540, 1262781703, 379346578, 1557964862, 2566561722, 2280542739, 1233009971, 3097781731, 473123888, 1508969395, 166217313, 1439964413, 3646047105, 3595493850, 4093783883, 2795147704, 4123805955, 1250668369, 2283708785, 4245016844, 2370592816, 3828877629, 2787374354, 2139886021, 1208299774, 1237413658, 169664298, 3173462107, 187208603, 2350252003, 892173722, 1004799120, 1328565147, 1789812913, 2527558555, 3872714659, 436946276, 3539454332, 571491969, 189796439, 1759928285, 2669584886, 718645501, 3223822936, 2575652450, 1909911646, 1050893712, 3043752848, 354123663, 487623292, 3025255091, 374157101, 2780753679, 194255140, 3725060196, 3685000348, 1428039010, 4159354712, 4012044805, 3798775630, 20529910, 2559898033, 3760819554, 1905045719, 4136414273, 1334841817, 1687195975, 396189875, 125555202, 2020505664, 3220241916, 2924152273, 1863085422, 500567270, 195508168, 1089450990, 2248396770, 1138761945, 3890258299, 2873381448, 3780002525, 3957311268, 687889825, 1668858664, 1655301133, 15032665, 1027527896, 3031209921, 604531171, 188027538, 3397073288, 3066311381, 2394581530, 303094307, 396468081, 2601109216, 2132608852, 2544917816, 2811813849, 1747120901, 2708158049, 863836234, 2697246800, 1710479489, 2729997963, 4131856113, 2321916459, 1262031341, 232880161, 1058563119, 4099189568, 1755908884, 3803044948, 1379125605, 1386052163, 1738771205, 1749683758, 2024467163, 1809475648, 2754470451, 2421546076, 1874430359, 2069109089, 1152782153, 991766383, 1737431140, 269673911, 2437505434, 2400728955, 1431646091, 1518987122, 2186573637, 339196051, 2764190315, 2259560835, 1282592948, 385468243, 4224274421, 576119317, 3614677639, 4077356423, 1125313062, 3470202367, 1919613845, 4086285995, 1177477287, 1673930406, 705504836, 2454248004, 3209530252, 2088988744, 4246583497, 1590352726, 3112690209, 2013531390, 3100368545, 3437386857, 3717564705, 1286589729, 718408048, 905320788, 2180204187, 2467325432, 3761853951, 3456699635, 2225751987, 1172971511, 733477348, 3854435069, 2062050530, 846090884, 719789043, 1202566603, 2104825256, 2675059687, 319293190, 3793179115, 3001011882, 1431545052, 3969584490, 128832074, 3901679260, 3656005145, 2737768227, 3888240409, 1806666537, 67018228, 2350913546, 1861921716, 3862626538, 4097865829, 2778774693, 794562701, 2871622549, 3207270794, 921035565, 2952602132, 960502613, 284709072, 1063639601, 1270411333, 4218699110, 2004386441, 1244682346, 1409678825, 115127831, 4190053265, 1862167526, 2739270424, 219481578, 3279781500, 3827260408, 2695400129, 298768304, 2646618453, 3569808749, 1266254550, 4053619764, 2493810128, 2777409661, 1011099958, 2293535048, 1538972312, 403680299, 2974007309, 2874111038, 3709710526, 656396871, 3952406898, 1858557412, 2334590495, 968681341, 966614911, 3222900426, 2213498955, 1818090739, 3542494106, 3166652381, 3192598200, 604136432, 3368065402, 3682460660, 689589424, 695654418, 121724358, 2920509093, 2198787760, 890996897, 669876185, 3690589436, 1070026100, 2332305551, 4278372981, 1574424533, 3582500652, 1235862574, 3850504962, 968104830, 3633004844, 1578094246, 3003761403, 3963252178, 3840627084, 1693470859, 81769956, 466743567, 713232122, 1407990440, 302068389, 445519817, 1064709610, 227912160, 2386646931, 3986077052, 4064515613, 1678703953, 4241671000, 1681278033, 1917715036, 2061733932, 2732251455, 1894829556, 3512167475, 3522668618, 3656561203, 4246783356, 1548504543, 3310397548, 3132349564, 405441083, 1890605897, 291119375, 1279935057, 1127928022, 3720852427, 755282063, 634444696, 528643617, 892885284, 406515873, 3274379684, 2703617700, 3403237914, 3915236057, 3184451645, 3061575457, 2105702428, 2973892165, 3999271114, 4220671200, 2503013152, 2707203603, 27691282, 3046681132, 1274969825, 1900657527, 2401297211, 1552686090, 227547796, 2045679188, 4173296788, 2776138215, 591988920, 2131566845, 2003789538, 1235232893, 3340198667, 3333296244, 2018829707, 2454383771, 1982743622, 3479308400, 3863852620, 1843512509, 2509383589, 3639484414, 466868776, 3008250020, 778970280, 2551780482, 4099311632, 3662393901, 489399479, 3093439758, 3216889430, 3027882678, 1720491014, 611553651, 3358642299, 713635213, 1447045321, 2800156197, 2137306122, 2459446301, 1759310149, 547011719, 1432342532, 4199872702, 1895280434, 3406272363, 216310692, 3843975459, 2857117203, 4062571918, 536631140, 1530351545, 2202767419, 4251275457, 1033942363, 1710252604, 1209244418, 854719529, 1827039250, 1721644441, 2392598670, 298698364, 3362109492, 2412492131, 3294067883, 1963247666, 348649514, 2261373206, 938962700, 750409289, 3763953107, 356905891, 2430006041, 3980385739, 717486472, 1098229618, 2187536344, 1411854270, 648813363, 2036353351, 4018623382, 268372487, 670309263, 2712132306, 578773468, 3590008529, 1467649524, 1615886356, 838976389, 1947563188, 544421144, 2717842254, 516155658, 2022510534, 198574402, 3109744008, 4090909930, 2752050324, 3484409074, 2934380843, 3509731361, 422644402, 2439130793, 2971079069, 3031992074, 2924654189, 490468002, 1865664422, 2831427047, 1903651532, 3500580721, 2196852090, 2284208344, 3912911632, 3628348878, 1194228659, 2662145560, 1698198936, 3608826986, 2296769476, 208592660, 1778240109, 2294936288, 2463134109, 2193491972, 2222032594, 2911161316, 3798448785, 182161400, 2335547072, 3311803402, 2366498045, 799281076, 760849489, 2583953491, 730201846, 2567758141, 862894082, 3268126212, 2202597914, 3472692951, 2541602720, 3855357471, 1670106726, 1458362949, 582777374, 3032782867, 1913202013, 2770672567, 654399100, 1581322803, 3325054319, 1915420607, 384321647, 3612199730, 2571660929, 194766147, 2497927899, 783080414, 47229788, 1102095090, 44506115, 2027940288, 1762855022, 260908886, 832440255, 3225197671, 3726417634, 1206263839, 610637814, 2208683705, 2133435355, 3346426517, 224534500, 331233567, 3117629849, 4091918435, 2432831282, 4173196902, 4185058230, 3544764999, 1899728526, 3483314643, 1787603337, 2012280234, 1582069083, 1854338184, 608566817, 292018758, 68148185, 1784644537, 162824350, 46084345, 1399098201, 1011250592, 1119676264, 4100416618, 610831036, 2628823081, 3471721533, 3416232519, 1200121027, 3007148243, 1070271576, 2418754722, 2133851283, 1604771026, 2823776969, 3826842772, 3172890451, 1425697732, 2726151980, 2963167702, 17686890, 1194564047, 1804687131, 3950206041, 421525065, 1333016152, 2466497591, 372565849, 681921832, 2957148092, 2661466908, 296262422, 804942293, 3815683888, 2376634571, 1899045977, 384927800, 2809050809, 1836583241, 2993834542, 1085356114, 3292258341, 1028941227, 1638891302, 2140584062, 113470547, 149891607, 868278739, 1752309909, 1361127472, 4000144082, 1412503340, 528978060, 325410307, 2201220004, 270121903, 4019419590, 864855298, 842515367, 3573287403, 3929124052, 1218070028, 214091141, 2473026042, 3930593534, 426335338, 1513416994, 101725441, 1898194862, 3769220994, 3358173240, 3251806489, 2346613945, 1822324793, 385846400, 1905141224, 3762370339, 3671341477, 2733102709, 322430576, 2794508835, 2474465429, 2043541568, 2738081290, 3885575667, 2009733977, 4225772572, 921826531, 3187755075, 1875257447, 1621428986, 3859138601, 1871313650, 3309224894, 136404944, 3926302281, 3095910985, 2755740164, 2232225837, 1221715843, 3881886774, 770005275, 363454342, 761530375, 2038996127, 1629145929, 2924898105, 751524179, 623104484, 3339997361, 3853611564, 1008822372, 321609560, 1196466737, 3038983061, 211222827, 2079451992, 2543829854, 4054374694, 1360599687, 2016528549, 2377504097, 1187988191, 929094844, 1785919608, 1879099701, 994220924, 1227457127, 2677672527, 3465041955, 84769360, 2436251402, 331603758, 1135534070, 1903010537, 2648205504, 1118585624, 970619688, 4220032948, 2220352008, 1183597872, 4286883798, 4053369708, 1816754731, 3426271933, 3929750343, 2771249666, 2749699081, 2457642363, 3992523278, 1613632090, 2397782377, 3735099573, 3798575094, 399742811, 2994377476, 2714996325, 1705111263, 2267158662, 3635994134, 3159268715, 1991382833, 70956919, 1127357667, 1823907249, 8950685, 816809301, 1310535478, 1087069453, 1468526264, 1582856215, 1085290774, 2479625835, 1334283253, 601399030, 4123082659, 4184693207, 1371028573, 3674475575, 3565090678, 209491207, 2328330453, 1025]; pub(super) const POW13: [&'static [u32]; 14] = [ &POW13_1, &POW13_2, &POW13_3, &POW13_4, &POW13_5, &POW13_6, &POW13_7, &POW13_8, &POW13_9, &POW13_10, &POW13_11, &POW13_12, &POW13_13, &POW13_14, ]; /// Large powers (&[u32]) for base17 operations. const POW17_1: [u32; 1] = [17]; const POW17_2: [u32; 1] = [289]; const POW17_3: [u32; 1] = [83521]; const POW17_4: [u32; 2] = [2680790145, 1]; const POW17_5: [u32; 3] = [1614772481, 2739882033, 2]; const POW17_6: [u32; 5] = [2276454913, 2771029215, 73658097, 4117442370, 6]; const POW17_7: [u32; 9] = [3492013057, 3480731623, 2144081192, 1009276412, 4254173166, 4151923560, 452949210, 1816956013, 48]; const POW17_8: [u32; 17] = [3277309953, 1864847191, 707834086, 1365492312, 4096642650, 2628241885, 1040897072, 3647618881, 4287772355, 126927969, 3695747218, 1041208948, 524092261, 1484945811, 3697469546, 3397736009, 2344]; const POW17_9: [u32; 33] = [317689857, 1450665849, 1775742626, 792817246, 735751321, 1553574078, 160284371, 1873256746, 2085456896, 2906891001, 2367433931, 2570134778, 3520334249, 99950267, 475720041, 4178498415, 925636968, 3880190760, 4090350540, 1913195868, 737980718, 2149816287, 3313879437, 1462712522, 3066369386, 2488096894, 2055534827, 1929403434, 1042156826, 164256614, 685827684, 1240652339, 5498045]; const POW17_10: [u32; 66] = [1457463297, 984317792, 129815356, 1108536177, 928471766, 2693550375, 2072553947, 1297125867, 1133000653, 1362423844, 2622920053, 2400166317, 2898543712, 3911312760, 340195761, 1832344099, 4238200431, 4289498679, 705322524, 3307021183, 2157383404, 2978222774, 3893788760, 2997995349, 3286528627, 3564068084, 1266442040, 2127456684, 697216183, 818919725, 399364822, 3518519912, 3208026815, 3949195313, 3259276073, 3282846545, 1676913258, 3748532885, 4097340895, 2606771886, 61542262, 928806234, 3952687047, 733904288, 708149719, 1985158190, 3554113964, 3778903691, 3310198145, 3418861933, 2384303007, 1529238789, 2412994435, 3893269128, 1436629905, 3992557715, 1329675393, 3885197615, 1566768946, 690629475, 2807722067, 656572394, 3411636943, 1472870658, 522169128, 7038]; const POW17_11: [u32; 131] = [1908293633, 3689523897, 2822932863, 4126052176, 3318263763, 3554909022, 3131835113, 784466375, 3362613358, 1594674871, 1342349825, 363201666, 3676246246, 3527189453, 4228641855, 3365544222, 2883906697, 1582601823, 2762086834, 444671130, 2667867771, 3306000853, 3176478884, 3611595152, 768565409, 1351677235, 1170484663, 1819794577, 2852094787, 3425809562, 3324861987, 167440938, 181440877, 3524867703, 875516746, 3772659731, 3494739066, 950227557, 4090892939, 3436199439, 2002989813, 2259107998, 514339703, 2959546, 4187061166, 279847702, 1113414927, 758547077, 2853043995, 2873726472, 2287854644, 586017138, 2360476349, 3937610949, 3442197266, 4107701379, 2564015432, 1436806687, 3123130272, 2028236154, 271886327, 2209938990, 804782749, 1603918673, 1581219264, 895483627, 1680234075, 2696502106, 2687909103, 1540265941, 529828618, 1934284392, 2534313015, 1183476453, 3357634495, 2329916589, 824072586, 3201172191, 354985910, 3218236432, 3073740731, 3761536584, 2028365300, 3397332515, 2172674274, 3767236113, 3476937416, 411868655, 1526749518, 2890623234, 275778389, 1862954273, 1889470767, 3943776092, 1863934473, 3244088512, 2671715289, 144944824, 2265756264, 764669572, 3040952776, 1765360244, 1115262701, 1619170671, 4212058315, 497757440, 4033354219, 893706607, 1084351448, 4095156874, 625437665, 1734599070, 4247172012, 4071352317, 1515537083, 1809169497, 2031873292, 2971219249, 3025150444, 3436736022, 1247708329, 201175674, 4101671226, 1644588900, 3326030287, 2437954544, 3174945387, 1000881834, 3196968465, 1427090841, 49535155]; const POW17_12: [u32; 262] = [4085022721, 2085967701, 1271919158, 44627928, 174363308, 2296121937, 2273963065, 3579431623, 1831121498, 1096894109, 3924357025, 2130068491, 2853365964, 1456617496, 2555178632, 3746749536, 1383109574, 4261474331, 436085303, 1293151098, 441533120, 1560211791, 3021758582, 4130670084, 19616318, 4095949148, 299409815, 1030209244, 1017224504, 3231906507, 1156282507, 1702927686, 2584098128, 492684726, 2159222556, 3752625501, 1456067947, 1084048890, 3453698315, 1591197554, 469559807, 851103264, 1113417463, 2668783582, 3284889668, 2346329028, 2859144744, 3057119932, 685449570, 1371349121, 920431876, 1427880275, 1652896932, 2264698818, 3897036934, 1221702260, 2212511271, 1987473568, 3854708112, 174246271, 540141811, 202099746, 2095338732, 645481146, 172501779, 3576793478, 283247730, 787654734, 2208423693, 1891955499, 2872549476, 935317575, 576771104, 1837844074, 3735762380, 1297782969, 1536128999, 1891495801, 1560967616, 3658718251, 3609644461, 3834598381, 3653579888, 2151769073, 862856085, 1438108966, 3966205101, 2513991516, 2033733267, 3497662243, 738646014, 3359330046, 1716117831, 1567957198, 2441990387, 2462302078, 3146031357, 3854102737, 2477210531, 292734252, 536678863, 909946955, 597585563, 1062761901, 2519377479, 2829303059, 995785540, 106677374, 2472390202, 953709486, 3167979348, 1723625740, 1854305745, 751864725, 1017260449, 962057863, 4090581882, 2249910134, 3926571064, 2150011692, 865882320, 928188638, 2537577815, 1998444138, 647936451, 3788138743, 11890717, 1299876652, 1052111241, 967696368, 3105978598, 2381554820, 843522982, 3559778921, 3374913697, 3014493578, 3433375089, 1476534227, 3851837465, 3550982465, 1947597635, 2617914116, 106488640, 212144176, 2408832624, 1301908012, 1665491697, 1379419294, 564803941, 3758117497, 1390844977, 29202037, 1842462665, 403468144, 2251965155, 131885595, 2635790422, 3212943466, 2591184548, 163518376, 1138906802, 2811232560, 1308265054, 772614419, 486210035, 2876589880, 1560778969, 4102610143, 2398046952, 414553900, 1138663335, 3092278650, 1164462332, 1074765431, 1294746920, 4168075562, 3198096521, 525130810, 4196764428, 1193236444, 1829545935, 2602603448, 3748322696, 2531099143, 2959009708, 3100670387, 2579785316, 382627899, 1714279389, 2236320312, 495836236, 2042911161, 51711653, 731191632, 4175109342, 3152106635, 2765872876, 1590115393, 2193625718, 4263502234, 1016876936, 4151561832, 605147024, 1598400881, 3018525409, 2654779395, 403909671, 1064515905, 762427870, 1495038862, 1837964475, 446573324, 2637178619, 725348654, 3025474236, 2784974393, 4013523660, 3185945252, 2195374701, 1059401852, 2957046851, 174542286, 2481692364, 1660288373, 2984571049, 1608858050, 1730035028, 890242804, 1883861595, 3561450135, 939429604, 529468388, 1256327278, 1400120915, 260360173, 1610973719, 2342985870, 1734243871, 3419599710, 4052964039, 3199610118, 1332281756, 1495544395, 482759947, 3706968720, 1387748444, 138131933, 3582340586, 3708359744, 3367255753, 1454884494, 955331047, 4232050806, 1692999880, 2390083316, 1121736953, 2141922999, 2203079571, 2702128415, 2113771929, 3912685476, 571303]; const POW17_13: [u32; 524] = [653852673, 804079160, 317045108, 3382101936, 1130367358, 1227772723, 4173914146, 3339195028, 3542063781, 2657877445, 3894315327, 3230922447, 4236383890, 74823206, 2713476980, 71935918, 3620482072, 3704646672, 336255660, 232091333, 3791099718, 3650314826, 366776504, 1444273864, 1120618892, 832839135, 609493913, 3201718649, 2486986236, 523770901, 1256029734, 2712373222, 3262555274, 2506465289, 313435995, 1170776324, 2820914572, 3104396610, 2910509361, 2468198655, 597764295, 87220591, 3201602912, 2057714627, 4187173982, 2915554184, 2122327454, 3466244712, 1117527356, 1834344467, 3185473027, 2323452348, 2197006662, 918358991, 1904036828, 3034522700, 1505524446, 3966195641, 2595798511, 3570966377, 297776101, 3314296794, 4028994078, 851938039, 3387562221, 2868368863, 2075437202, 4044965662, 667890580, 749943233, 2295967072, 3166655855, 4046713910, 288763546, 1802946687, 573814020, 3577395284, 1418065602, 613718014, 1108079389, 4144561354, 3158868488, 366065647, 517765378, 1252908858, 1800108071, 2039996851, 3103091418, 3035738119, 2311487556, 1484469507, 3811702428, 1485945074, 2186456769, 1440424806, 3219088477, 433920879, 1422162825, 2580724280, 3492571424, 3778679178, 1894964076, 3681876024, 185171109, 4081206146, 798917859, 1622533717, 953272728, 2232493014, 3214889684, 3936812384, 2566447781, 185469242, 130567499, 1369584753, 3152723673, 718117334, 1363850836, 1111801416, 76218431, 3144698431, 986789270, 4225990079, 1780295982, 2604050341, 1696265807, 3843667692, 907399108, 924884706, 249967460, 1558341531, 2528047802, 2518503920, 782994105, 1567940528, 1213726789, 1271011848, 401704401, 3311358501, 2783606812, 740870759, 2243045410, 3792179791, 2296007301, 3397510700, 2429904720, 3177665560, 3222432088, 3273294152, 96430915, 3271992663, 2641596440, 817687428, 1255065052, 236752853, 2979142313, 4240368624, 3772355931, 1589141692, 654783556, 2510746811, 152515501, 3713061712, 4012073196, 3156953387, 2580252737, 3438325899, 4294242085, 700415702, 1934727278, 2461513951, 451545344, 2357896586, 621639245, 759303246, 2225149225, 970127902, 884863837, 3728550998, 2754966688, 3219134282, 3682522197, 2219314299, 2364077779, 3612037037, 1302499120, 828188324, 2391024989, 2626738557, 883556972, 1546920446, 2341614606, 1520229141, 2968132573, 2697752544, 2479047703, 914636198, 2966521022, 1565555576, 2131686145, 267371516, 1237209139, 657787771, 1847745685, 3652066149, 2806093487, 626954154, 1078641188, 861789609, 4047429839, 1115869132, 2337343572, 2615394121, 2096333782, 1138444742, 2803024457, 131733434, 3143027078, 2985106047, 2826591279, 2642089216, 3944409184, 3633985939, 112520625, 3018084251, 2902017751, 2379500901, 470467556, 4020793048, 527244468, 352974788, 104402052, 2392599968, 2967330921, 567027142, 1483285025, 2942011053, 3332847706, 3197112695, 3724457591, 525975090, 241229588, 3492017920, 2614767616, 3535332976, 3207066141, 1072491264, 4162339653, 3820310096, 498690043, 1552583229, 3214142499, 1877255302, 1796230911, 3836721678, 1290150340, 313362434, 3188934567, 629795581, 3722093035, 946136182, 1343568012, 1144246267, 1290859252, 2467260418, 737358861, 3351888966, 4247954332, 2056378976, 1923963393, 833559643, 2304209581, 248746521, 734365562, 3718828583, 3109765686, 2181915489, 1003856590, 842334805, 3685181364, 1796224132, 1310504456, 3600986180, 4000748173, 2108016032, 2100281436, 653200590, 2344231620, 3671081413, 980655718, 975271315, 4081644043, 3387949569, 2648901384, 1374091753, 2154882951, 3118633206, 1876114421, 2130585588, 1625918937, 2697933051, 2678682545, 2083275865, 3650477692, 3245973132, 3362683911, 1015800757, 2255754549, 2907822735, 3163319592, 3131108494, 3005746967, 2944601521, 3400077278, 111205239, 65939123, 3042606419, 2397248111, 1765631252, 1151241243, 3815617887, 1663933225, 4196394528, 3530711924, 2041739626, 1497457836, 953998311, 570299149, 1311040112, 1031912543, 3952297037, 1429571434, 255646515, 1222461235, 358668034, 1291853262, 2561065587, 2494917777, 1038769745, 777198421, 2474384421, 4060113779, 725387790, 1595744499, 3739635811, 3812095211, 862373119, 3419451045, 1346587053, 1599169722, 824353531, 4259087799, 4091898003, 1693692162, 3916338621, 3488559751, 2521899964, 380859707, 3433232441, 623595720, 4024482943, 81903787, 949716956, 1488402371, 3919092307, 1938231947, 3428304871, 2170138389, 2143978663, 1457524934, 1352559918, 1478138542, 3260047087, 2141004915, 2901137763, 3904369290, 3759282057, 223943031, 875457119, 2131919520, 1568150650, 3649244639, 4205983702, 1267114280, 3929274314, 2066798261, 148847134, 1702265052, 3996556009, 1917239926, 3088056852, 3563887171, 1685277956, 1746697736, 1666454561, 1097111846, 141402998, 3358200408, 1225064452, 337312220, 864053464, 1415344927, 186648222, 633455815, 3895168635, 2402380352, 2939714357, 4217314923, 2268288847, 1491107257, 3936594949, 2155373198, 2109326196, 4118071792, 2002361849, 2353074369, 2559517815, 1773929122, 851200359, 875535853, 600517347, 3914683899, 2125327927, 2675990885, 589214872, 3068643885, 2281933169, 3224556846, 1547148234, 3507824974, 527664256, 726590753, 3431953398, 3204653402, 1123510277, 658746889, 3442991421, 2494213803, 2858333528, 2299417507, 1694766033, 4105482648, 2271222974, 279971142, 3425485238, 1875763912, 163514685, 855584457, 4127771402, 4027007331, 294343798, 3390077754, 1881338062, 3038077868, 2750900911, 3776107425, 282274049, 1316767029, 2839656145, 1706342088, 3997887022, 3245969985, 3158904772, 128653744, 163806714, 2959247222, 4134428955, 288596525, 906847794, 4139446572, 3944785016, 1365830554, 627418401, 1425486391, 4107966312, 3717061340, 3695004161, 1659726457, 4017260558, 430318666, 10830527, 1112525155, 1465704640, 2588279261, 2712586113, 2293334594, 2304990040, 1342029279, 1148007717, 1117909867, 1908885335, 2108935559, 61143512, 3245889886, 2849144913, 1585177368, 3231792894, 2868854115, 455631408, 3737249491, 1511987494, 1520617731, 4130027243, 2830658473, 52316930, 1072967416, 1015556087, 4106393656, 2586008251, 3105140800, 637395747, 2926208061, 2194055491, 4243576748, 751283033, 2540338189, 3953438836, 2005809997, 229028678, 1219407764, 2826213775, 4237771999, 4265611515, 75]; pub(super) const POW17: [&'static [u32]; 13] = [ &POW17_1, &POW17_2, &POW17_3, &POW17_4, &POW17_5, &POW17_6, &POW17_7, &POW17_8, &POW17_9, &POW17_10, &POW17_11, &POW17_12, &POW17_13, ]; /// Large powers (&[u32]) for base19 operations. const POW19_1: [u32; 1] = [19]; const POW19_2: [u32; 1] = [361]; const POW19_3: [u32; 1] = [130321]; const POW19_4: [u32; 2] = [4098661153, 3]; const POW19_5: [u32; 3] = [1637415489, 2733490537, 15]; const POW19_6: [u32; 5] = [1674773633, 2120389729, 2125575713, 2140041202, 244]; const POW19_7: [u32; 9] = [851069185, 953120046, 3422911417, 3249671984, 1253122465, 387558350, 2121285446, 1729366164, 59779]; const POW19_8: [u32; 17] = [2386924033, 190345838, 2985903449, 2575403751, 3663280926, 3225853746, 4150572491, 603254694, 1674172707, 3673007190, 1176051141, 3802513312, 1962388533, 482203478, 2403994182, 530593434, 3573576981]; const POW19_9: [u32; 34] = [600777729, 4287864253, 879263622, 662006526, 209087784, 1566861921, 1868491450, 2979970599, 2251023872, 619496482, 1962810147, 2474730226, 1043946239, 2571498863, 24001819, 1859204983, 2472425095, 339377689, 866657198, 990396938, 2881482992, 3673813, 1416246612, 2126450992, 810411284, 2469838367, 1356652332, 2422736342, 1273451346, 3772130430, 2531937001, 3633029867, 1546447747, 2973352661]; const POW19_10: [u32; 68] = [2226014209, 1311551213, 19006035, 3560028624, 3400822883, 2260137902, 2626308946, 397916838, 2154438492, 3267979482, 51974750, 3434718507, 352206864, 1183471152, 2304943612, 3788818754, 190140117, 170026499, 3825508396, 1347714733, 389308855, 1686258633, 1915096964, 1618679228, 56663032, 1502877569, 1787809606, 3171026396, 3411597083, 153287481, 3487511685, 3169928240, 3583116939, 1767370122, 487663870, 3505082218, 2006247521, 4220801096, 3037411207, 358526239, 4042932841, 1595456929, 1024170034, 3237701565, 2043937592, 3040155548, 2347496689, 1142942189, 2961469253, 163240502, 1637537269, 3146413046, 2853742643, 960593755, 2146471541, 407701098, 3202413246, 3392470930, 2399295285, 2816655148, 4137870176, 3139435252, 3999095315, 153016687, 3766844738, 3406533690, 1623276339, 2058415219]; const POW19_11: [u32; 136] = [4254896129, 900652736, 980304171, 2237494519, 806622219, 1481372569, 1594893306, 1429651042, 520461233, 1384169010, 1860986400, 3353153719, 521012967, 1061918539, 3585061057, 593465121, 4090592225, 511257954, 2042776089, 136083668, 3963988729, 2231773506, 1896847515, 2755786263, 437517368, 3542151637, 284143785, 888382325, 2229806951, 2282519678, 1727256475, 2202818889, 2173872667, 1234038854, 1585204565, 1378039623, 1024316507, 2844837976, 3737636296, 1501749607, 1687087875, 3587579209, 2909567867, 2902509091, 3536167724, 2520584651, 3701257854, 959596522, 2000373416, 638415389, 550367812, 2494901029, 3102796157, 3546334266, 1096826775, 1944229679, 1295092879, 2779719369, 1065888657, 1798890005, 3807924864, 2275240966, 2908136145, 4155123706, 3032995156, 3718296519, 267222915, 857395390, 340092803, 2424871771, 2044596141, 2628187515, 2157533238, 70172775, 2930304387, 1898292758, 2605936345, 3125842343, 4069912846, 1567585176, 3029314262, 1529860590, 1833219710, 240562859, 431586267, 2936800789, 3270111111, 2211649058, 2928629166, 2193374933, 2533225289, 2073294107, 1616302889, 3713955772, 1100750018, 1396681706, 3028822840, 3385342207, 3291026658, 2155875215, 937347553, 3624152314, 900975440, 2768781459, 3403238712, 1375102474, 680803628, 503869938, 420124670, 83031187, 3023590859, 4053349732, 2761177557, 1235737784, 3055076616, 3625956358, 4040355971, 975831122, 1148785172, 2676068949, 277739707, 3985956042, 2081975591, 1118499225, 1493547608, 2094944807, 2143099536, 3089923066, 889986503, 4024266613, 2416103842, 2307158933, 3736694398, 470967898, 4047643779, 986520483]; const POW19_12: [u32; 272] = [3426295809, 456430049, 1640218659, 3007079176, 959876987, 2223467885, 4076124500, 417888859, 1037880115, 2378369546, 2319054386, 1030664361, 3083754353, 1253520369, 1805795630, 466075093, 2198447969, 3550793507, 3483002958, 3696527081, 4109159608, 1034772337, 2864538764, 1845561056, 3844244629, 3328643887, 1623928805, 94248299, 3464429028, 279508986, 4121047871, 3703811188, 334236727, 3416012628, 1785319913, 350924216, 2805337799, 1595308984, 3493323566, 1994363794, 111516809, 1091882592, 1530881168, 176026905, 169089692, 3569082320, 4163151425, 2460214920, 1021156045, 3151009207, 985865882, 2997649065, 3116091745, 463670204, 2092181874, 4040408465, 2135545971, 3099695959, 3688345583, 2676964065, 1625226024, 3190311882, 87375303, 57511715, 2176616519, 2922021671, 131894521, 4045480739, 3029371625, 3683791277, 183182440, 2918812480, 679022819, 548831725, 545194003, 150746027, 2384861643, 774162756, 2307333480, 4063401231, 905006671, 1286321744, 1471072142, 2369239251, 4157285691, 2832213518, 3542764709, 275213133, 3264190258, 2673529100, 4162262270, 1352735401, 2495929144, 339616562, 99498066, 1548873055, 3278885527, 4030169179, 1520494036, 2805618981, 1493269915, 3893155572, 1427410907, 222948129, 453116650, 200054796, 3229577687, 2380861490, 2671152624, 2551740703, 1648910867, 337009883, 934844752, 3866683384, 1968565113, 4068714733, 3311509119, 1522688853, 2991638604, 2013517995, 481294794, 2578892484, 2175664801, 118823337, 3395067020, 3788021466, 996427616, 1991957499, 3061191301, 2685798947, 737155512, 2806053612, 2652347270, 646385592, 718776402, 3056261309, 1671840470, 3664347811, 2067964160, 4279377199, 864814793, 2733297930, 1857065174, 664714154, 2568338541, 4114063995, 1857735519, 334586826, 2193181127, 4282352547, 755179073, 2595052814, 3360639724, 2048031108, 2536631630, 3730675741, 288445910, 2488075713, 3340156953, 1759689498, 1699524541, 3465719663, 161191240, 2305028968, 663140709, 424749294, 3203217945, 980017320, 2641622629, 3179262525, 2268258129, 3703847754, 1953149931, 2034331792, 2453785789, 2645877717, 4149107306, 2444326557, 181780619, 641344048, 947653609, 494564618, 4165372872, 1009533988, 2247525603, 4272908696, 2399217132, 1227010564, 319655213, 2799392398, 3561139967, 4280646442, 705080968, 2030943653, 3077510072, 2623422447, 4145844983, 1555248449, 2666106573, 117240579, 321366571, 556728016, 1710553605, 802873415, 1550782081, 3989893606, 1992495208, 405282038, 720198523, 1022727910, 3080262583, 2885853759, 853837388, 3228366717, 3649328617, 97009278, 944298843, 2405349692, 3574066585, 2478557666, 3197441940, 1581669964, 3284119736, 2738233173, 3586426533, 1291387723, 2963731997, 1169402355, 1172500732, 3858949327, 4048579900, 3512967151, 277988563, 575774030, 3203736845, 3196420723, 2699397170, 189743599, 3290783293, 2310014003, 4154330172, 3890826007, 3698234563, 2259699940, 2728960897, 2813861197, 3040889884, 3943121979, 3924249142, 3370921844, 1739074773, 2250012001, 3311607808, 4275228102, 3032334483, 501818730, 2564077082, 289590731, 2811899264, 2262280121, 48124927, 3551007956, 3187578938, 3342870504, 1670700644, 400340834, 2974288493, 3545233831, 1864662781, 4093578384, 2430491226, 226596059]; const POW19_13: [u32; 544] = [3698475009, 2348710786, 1125569724, 27387644, 1693267154, 525565825, 3221818805, 627963023, 1871616018, 1703673704, 2288610982, 4012520689, 1077215743, 3542560748, 352715808, 1026708448, 763132536, 1292513486, 3128094965, 2432068461, 3144078469, 3639513047, 2452365249, 3897634097, 3158041736, 2842036982, 750624087, 2448194546, 1445977927, 2281412423, 2559176832, 2121789021, 820711812, 445943201, 4107798256, 1205099379, 3734091239, 262484112, 1708009319, 2341670672, 2385931575, 1604531876, 2763730110, 2987878241, 2598893428, 4080242107, 658701652, 3278278300, 495685585, 707364982, 2953115421, 2331439434, 695374200, 3059863288, 2673841031, 945337560, 2963017008, 2600811093, 2010921721, 2190994195, 1441728782, 874413108, 1340547061, 253295198, 1830889962, 1106390773, 267733138, 1078616913, 2176681734, 1037756416, 3496174982, 4160304534, 3708573742, 3606953911, 759922554, 908768211, 36301915, 2731180088, 2431564390, 3111240551, 1796201297, 1449677007, 2077716548, 3012974782, 3253299885, 1395989820, 4093069628, 3976864013, 2222800946, 3966075865, 1440883596, 2937249133, 1960613258, 3866722429, 3045749476, 4218987064, 2538371182, 3675801283, 841605258, 2239840858, 2661704789, 2124919157, 3178074258, 246943499, 3626277666, 2151349822, 1757973659, 2937817170, 3911039073, 2603480839, 1410754424, 3628086132, 3410926441, 1394153497, 161038440, 4048050492, 2857121086, 2302352481, 3355362520, 837134425, 4091164381, 2181027065, 1448048876, 1990829837, 4233637301, 4210787010, 3799162065, 3587407276, 2865177792, 69460099, 2373511514, 4056317445, 1815952152, 1832959647, 3225977, 2432637060, 1949712484, 3303591154, 2355390943, 3886644230, 365475074, 4141964206, 2626358532, 1941078737, 2622974917, 618116244, 4275387220, 594915216, 1224569507, 3845674819, 3912729408, 3090512886, 1189631081, 1022115508, 1984805740, 3021120626, 1759395566, 55950297, 1460793026, 1462014826, 2281305419, 135943629, 2549233697, 3448970082, 698019423, 1750514438, 1083912407, 1792619850, 2397984834, 180833955, 2525167464, 736145625, 4279871585, 4016857381, 4036939174, 2105463069, 498683168, 4159081386, 3370439434, 607760224, 836741276, 714413915, 778783896, 4218365807, 260504127, 2427279166, 3994847061, 745700051, 405317637, 437018589, 1108173734, 1038879664, 3107146829, 1753820698, 13154889, 4089222476, 783840504, 3758645013, 3296239984, 1465674627, 3860937699, 2330242899, 3356964930, 3428227399, 1170326701, 4027939567, 272867974, 1139814414, 1686357188, 4137535440, 935295564, 658917480, 3581653950, 2471701971, 2281752281, 229936885, 2479291357, 2273019496, 522521942, 3877448615, 2990128797, 378293256, 33829329, 47693473, 3264019538, 3673586715, 810931650, 3588924867, 881802719, 849877068, 3519113866, 2648824723, 298764587, 1061117323, 3497516460, 774097362, 2829082334, 2354372120, 290967978, 2228127560, 2448428118, 712297790, 2212669481, 4117664708, 2844307473, 2448759562, 3909013179, 82446222, 4063738208, 2548920436, 1399220080, 2174367894, 572159520, 2576016842, 1633755072, 1332574234, 90563630, 3403454573, 2306449586, 1836111429, 3847263182, 3157943865, 3187263043, 2336380071, 57204767, 3374191127, 2263034681, 1024000143, 2635372492, 3261928202, 797536801, 3763489472, 2206747643, 2978801531, 4291367355, 1851048078, 1583883821, 3058137808, 2876732371, 238942589, 987844605, 541104707, 4269758182, 726401954, 517779157, 3932852177, 2519316915, 215545279, 1170775446, 2679061552, 139443286, 3996718746, 3408745927, 1586582409, 1454370473, 3045247666, 2444884360, 3059683652, 3318906948, 1283666682, 4193821293, 834087456, 1135898775, 1334330677, 3583264251, 1256013730, 3356123107, 3794612215, 4184288324, 4209598392, 1148473112, 4097605935, 1368958267, 3522601735, 922959283, 4068741403, 3701983404, 3107114321, 461316967, 1960582466, 2441363463, 1407849835, 2168499426, 3799713542, 83435149, 1647227160, 2206800003, 3640079826, 2946722865, 1140599594, 1069261201, 3689142171, 4081025932, 91001280, 3621475658, 4210903522, 186355933, 748465236, 202779544, 1331032212, 3297032193, 14749470, 335754767, 703241747, 4055911534, 141500073, 3860904859, 801854871, 3134540418, 3697700580, 1121562158, 1292698770, 2759792766, 2163162039, 4214972901, 69131059, 2439268588, 1646213910, 3568299259, 416961787, 233508894, 3405225790, 2707437307, 169033690, 2763821461, 3371930561, 2671731524, 2218631372, 3556740456, 4196704464, 3270298054, 4025382741, 2046909602, 2072061389, 1575451198, 4188215372, 3836979169, 1617568182, 4287398767, 1420826033, 539985529, 213746114, 2053529503, 3280856001, 262261005, 2719073765, 2076616586, 3880611696, 4283397239, 4217794368, 3892326973, 3101643777, 1107439832, 320556763, 2418357014, 2613973143, 3590814049, 262032528, 1405627149, 2915350870, 1135921419, 857282742, 1554243154, 3702194247, 2756742536, 303554327, 2668112029, 2816621037, 1216972063, 3132436655, 2248364458, 1635977659, 375283790, 2351775118, 1477024371, 227015564, 3995133651, 1177315689, 3956504171, 4043948729, 1505950922, 3733597925, 1942915677, 1208783370, 77892568, 3780201208, 3992211952, 585713512, 3794452100, 2872133197, 1268675185, 2222307392, 1786705831, 1154148139, 2449697059, 3562775153, 4243048772, 2239913232, 1821035718, 785641329, 1483537159, 3966867099, 3711390631, 4160723913, 4128180782, 3845419982, 3498967752, 3623467449, 4023386558, 2080345519, 1829865640, 2066544244, 4269343993, 1707442400, 3652540860, 1580459142, 3170722747, 2635513381, 819917600, 963481752, 3956002458, 4207297868, 4146519668, 684565896, 330723648, 2732580672, 2460677898, 921005803, 328628933, 3004678593, 1290348712, 3375692685, 1995878766, 1738267363, 2136007949, 110895732, 2392525990, 3693450969, 225201216, 3171073045, 3478244004, 4155779732, 50953808, 825956166, 1897027940, 936075529, 3324254947, 3244913167, 774896874, 1181764826, 3286855052, 3636573853, 2004728685, 954948499, 480128314, 2144898790, 3707494056, 1991944670, 1023933339, 2129301216, 3774884033, 279325989, 1411971072, 631884243, 2797000113, 2469417595, 1059902555, 2554835918, 472620564, 1606463096, 45490379, 4072472094, 2574648783, 2363640954, 3956224404, 1251461196, 1488722722, 3112095189, 4023319800, 3492404471, 2694941226, 154487917, 133194553, 1842024384, 3321045507, 311009458, 2582077646, 1622864329, 4265317991, 3217905926, 2587369922, 2173669452, 985706565, 4174931395, 3045862001, 1615132599, 4171162099, 734562947, 2126761952, 852377186, 3655493546, 2471786196, 2827825430, 11954869]; pub(super) const POW19: [&'static [u32]; 13] = [ &POW19_1, &POW19_2, &POW19_3, &POW19_4, &POW19_5, &POW19_6, &POW19_7, &POW19_8, &POW19_9, &POW19_10, &POW19_11, &POW19_12, &POW19_13, ]; /// Large powers (&[u32]) for base23 operations. const POW23_1: [u32; 1] = [23]; const POW23_2: [u32; 1] = [529]; const POW23_3: [u32; 1] = [279841]; const POW23_4: [u32; 2] = [1001573953, 18]; const POW23_5: [u32; 3] = [1854975105, 1930488089, 332]; const POW23_6: [u32; 5] = [1633523969, 2552572211, 2550303091, 2811546753, 110522]; const POW23_7: [u32; 10] = [1210855937, 1436506257, 788091685, 4255817435, 2500410572, 2361723765, 2618086504, 4203283319, 3625322590, 2]; const POW23_8: [u32; 19] = [3390858241, 538851, 3291369078, 492442738, 2850638734, 3029803664, 2378638741, 755966606, 185069185, 2748924587, 3547456468, 2115104919, 3398114034, 3022323801, 3693445824, 1646113784, 2709808682, 381505921, 8]; const POW23_9: [u32; 37] = [2605238273, 3116014269, 2992234958, 1161074084, 479530153, 3899908674, 2110077101, 945664495, 1886615027, 178825347, 3336466241, 1535044871, 3130879489, 2072972949, 3321140195, 1277356633, 557957570, 1424987297, 2661331017, 3155813457, 1979672171, 69442422, 1465357477, 1292379284, 4001039347, 2329370010, 3548005518, 2351685740, 4050637122, 1246418910, 3135187870, 2896849915, 3344622137, 994758688, 3546606478, 1843015197, 65]; const POW23_10: [u32; 73] = [1389465601, 1270725724, 2430805426, 793913803, 1730617534, 830391743, 1447514731, 618344372, 623481912, 3084697698, 193767822, 3851124886, 255326659, 3713486952, 1566487911, 1755920970, 2992359304, 966788492, 3740415920, 159326876, 58388316, 3618138013, 1211637293, 3982421756, 447680048, 977798062, 1729585872, 29528160, 3511980698, 2986171906, 721298031, 4087122058, 1337589914, 2891941726, 1799086713, 677396911, 3673570755, 3849306605, 3461700235, 1874006132, 2569805975, 1563150380, 4669777, 2045351581, 374132179, 2011356629, 918291745, 3147334072, 236807592, 2435596618, 26881790, 2019016339, 1175120407, 1285033588, 272812424, 2679220483, 4186085566, 2453245162, 420923676, 1014007343, 1216833656, 3376737166, 3242365153, 838929369, 4111422289, 2611056369, 1954578150, 3133421373, 1159123251, 1087135977, 1381913124, 4159631453, 4280]; const POW23_11: [u32; 145] = [379789313, 2758141061, 71522850, 1119530638, 3978370053, 1160536233, 803554839, 4138152392, 3767315879, 2206196210, 1579030902, 1743902133, 2467116037, 2987035458, 3012122326, 432014986, 1690767645, 4236672118, 823127706, 3913278592, 1175238479, 39484736, 2726235066, 429737273, 3996909923, 3231819960, 3841170194, 3549092869, 156053954, 4177621645, 3218207888, 3773558946, 291467074, 2735794354, 2817713113, 2107057369, 4062136853, 1239339744, 1963513639, 2850418918, 3316030415, 2583849721, 4178950459, 3643813342, 3629742336, 4063289682, 2858387189, 401584375, 2351321327, 1961707692, 3148842945, 103814549, 3501419191, 2975550077, 1101977746, 2679908101, 3834230311, 188877196, 1948690137, 2620024128, 289849790, 457761556, 3006912097, 2159899689, 3894307461, 2329790703, 1426201101, 3005856300, 3111020731, 2546062547, 3089661554, 4084360158, 2272224239, 651696083, 1286065301, 1757277020, 1138141021, 2237865833, 642045488, 4203444687, 2023651164, 2966208508, 1092430863, 3622977179, 2319864750, 93603986, 2769608280, 887833271, 1586054297, 3225966370, 2510175321, 98568386, 655221764, 2788081662, 3922902292, 2900505997, 1887368825, 3533864638, 425446961, 3961415955, 1151618629, 1646022686, 3222130023, 3474940252, 1361296164, 659675733, 693297050, 3373397441, 1215971414, 2340864725, 407181956, 872585078, 3031994095, 2114550411, 2349517248, 700038787, 787928209, 1323880295, 1010311499, 1467760695, 3061713726, 3939092210, 1720173567, 121727021, 4004998533, 790233415, 2624290768, 4130208598, 1193155313, 2097752256, 1268873715, 2041343193, 3277403825, 1353198293, 648245758, 2548770238, 1282528946, 3619875585, 2095010525, 2649414752, 1890794924, 795315762, 369156751, 899949386, 18326691]; const POW23_12: [u32; 290] = [4047912961, 2706078331, 542992255, 1637665820, 2741142721, 4065827615, 1270610388, 3130100114, 3409680144, 3226805914, 3382630134, 1695211647, 835807866, 1253342310, 1867751943, 3414562408, 4131807098, 1838155340, 272019709, 475330415, 2848842812, 2628625154, 1779768443, 3660761624, 28646505, 4064911928, 1324601206, 2648009214, 3009464369, 4040162765, 4032792242, 3188403026, 2627115900, 3600369684, 1661889763, 2461085059, 2557186775, 1547903206, 2444484871, 2002767868, 3963260566, 4277655133, 3164618438, 1526177493, 3687429330, 3036799512, 1342125841, 886772701, 3065742182, 3228196492, 2175413217, 1149380218, 1160578103, 425846651, 3233169681, 3301185752, 3653989427, 1932531647, 1176656790, 2479866857, 1697450058, 2696979544, 4171688849, 1984257175, 2376794540, 268070975, 1584360037, 435144812, 341033877, 3377520632, 4090216239, 2751416470, 1489343099, 4012274079, 3182747585, 1106761117, 3074921942, 2826597558, 530613369, 1408107841, 2909853108, 2052055873, 2151637918, 3775153332, 1697210164, 2748383243, 388425896, 3902000475, 44444877, 190299373, 3802467288, 2432430955, 3573228694, 4234613504, 663227232, 3504998182, 2818568140, 2089079729, 1764011739, 2345693684, 2156823721, 479848277, 2482061478, 286763971, 460347807, 34719071, 3309308291, 2058164715, 4097499901, 3229558899, 3934884672, 1978363444, 2053796824, 2811196783, 1095805763, 1217074101, 264596232, 2900338186, 999456882, 1879395680, 260962281, 4134975577, 2801571397, 2888997548, 321354816, 224916052, 1371339964, 3611483631, 1647901049, 491660493, 8514499, 2355964689, 1047118756, 754250461, 919479968, 1046073168, 517250720, 3251815459, 45306865, 1906674686, 2805610381, 3032672849, 2114249531, 277875506, 3426639681, 2424703720, 2261633930, 3648844959, 185410792, 2668214722, 391505289, 2161966703, 2612423299, 2978933815, 2442786080, 368451385, 3270180305, 287202057, 781208358, 3581321000, 1724769350, 1359713574, 2429054300, 270136631, 420238567, 3404338829, 23256407, 2684317479, 3905086894, 2918661679, 2047888093, 2662771914, 3989908354, 3417530629, 2094001687, 361580016, 3086435457, 965781219, 4249366685, 448816469, 251000905, 3512983509, 399664727, 3319202455, 2991935997, 238214973, 2059177992, 924510095, 2738727311, 1408152090, 1366672482, 544745176, 2718822597, 3342403313, 3069625731, 1122889278, 2352618905, 4032627128, 2739922667, 3448136107, 2173196206, 1213124524, 181560319, 1137248410, 3748611021, 1634052255, 1140008267, 1000807011, 266130147, 3968119094, 1663575010, 2544232626, 387355496, 536092600, 3034262090, 2275205838, 1992098149, 904357246, 2047404193, 504923133, 3579921170, 1631109480, 3686011874, 2301805038, 2932643745, 1516851640, 2629543965, 1734466704, 1916624342, 3614123815, 1985797395, 1822045299, 1571737744, 328376417, 3307293173, 3298812782, 3929675526, 381933809, 8956221, 2330861594, 3129515112, 843570113, 4249041719, 2832931138, 2596533158, 3295015771, 2890813875, 578570402, 3426929694, 3286268033, 2079105775, 2984649912, 3249157295, 1209368491, 2149367866, 1110834557, 3595580613, 3493621749, 2880729144, 2806520113, 1886576060, 3568463889, 1694305802, 878278620, 809891654, 1983193009, 1867229389, 4162557282, 2356690531, 521290693, 1959127013, 4142787822, 499367916, 2474576428, 2093902775, 13158038, 292424669, 3987092736, 2963112161, 2440758231, 580917628, 3344986760, 3870742929, 2276641489, 3392631670, 2272346511, 3831968049, 2465542736, 1168142476, 78200]; const POW23_13: [u32; 580] = [4069294081, 1954401470, 2426562721, 2785656499, 2436180519, 1555477753, 26008596, 2550420690, 2660826980, 1910178312, 751335956, 3784438901, 3887774093, 1253188426, 2461159114, 2396898009, 536785702, 1539400130, 3340993484, 723696446, 2866420198, 137664586, 28452047, 2346439400, 710205197, 773955028, 1295618182, 2168257280, 823750549, 4107353467, 194544918, 1399866117, 4080865184, 4294414893, 2716211388, 30877716, 2805600161, 1168681766, 3675200818, 826363708, 1788156611, 2383043973, 3368147427, 2635875110, 2897736799, 2501181051, 640939406, 742206169, 1553972078, 82055010, 1960090306, 2044466541, 3382908180, 2691915312, 3811761225, 978356366, 2121280903, 1044872173, 1689233681, 3523820819, 2719151474, 1557860688, 2816310055, 3007778646, 1955415889, 2709007886, 824179083, 4157845984, 1668333438, 1323991598, 2512532644, 115219799, 1798362470, 3294560066, 4165155070, 2094351775, 3845308917, 3592861001, 4037342980, 836321446, 1146169325, 3788391498, 3845351500, 4123710833, 2287261707, 3001660701, 365734328, 1373840209, 379319944, 3304703246, 2667248859, 3469642195, 1491933952, 1800417045, 4188345322, 3836015449, 2289088224, 1881030843, 2117857271, 227625765, 3378234399, 3686254475, 2839453187, 2345076086, 325108888, 316281677, 144330590, 185763391, 2751272900, 3413189564, 2095740472, 2304249401, 3738777365, 3589204737, 3926188970, 1855205086, 971129436, 1728588995, 1912872952, 4155583376, 3490428049, 67177501, 939790347, 3681278908, 1257097516, 2165164581, 197355782, 3182242994, 2304233930, 2399030398, 2931875554, 1536732010, 2218690775, 1447885919, 4040462315, 854495807, 180717071, 2262287620, 2620208073, 3231180781, 3311643465, 724991797, 3699878088, 2946011589, 3890861432, 1043419275, 92510136, 4007698002, 1864878984, 304713154, 1813086879, 2824742219, 577583630, 2786013288, 117739258, 3826637508, 3801221845, 1137785848, 3296897084, 1076447441, 3166882710, 3103335519, 3153904328, 2340551809, 3629195646, 299740308, 239096656, 3194262602, 3177130873, 3245830874, 2835384678, 3761796838, 4294537490, 2190208216, 1386675137, 3366893001, 607433185, 1897011430, 1418554732, 2272214293, 1735757754, 2507633226, 2029556540, 2826896662, 4046611314, 810189824, 922331213, 958459530, 3657536577, 1086105018, 3758440273, 1579013403, 204829439, 338418247, 1660430527, 3668379592, 2730295562, 223749203, 3117457472, 307354783, 3841575, 3276225973, 2970415599, 3695857983, 2939332526, 2757720255, 2767717659, 4239836917, 2359756599, 1282847416, 221814126, 3738616852, 332100895, 2827681514, 1399634935, 2631257341, 1044381446, 3617910905, 1189777580, 903799496, 1144824547, 485155442, 2947328600, 1686177123, 2947084384, 3941590708, 3197580207, 614109925, 3653865495, 1435212859, 3391256022, 1006926394, 2902917026, 801475739, 3070880610, 1276574800, 2142234948, 3356519153, 2035630764, 3205171983, 1332734318, 4078069739, 1428897349, 342772171, 2097758727, 2225548100, 4118513652, 2062957901, 3528788113, 2427038307, 3572649043, 4129470847, 3666530417, 2690176479, 2531735868, 164025276, 3432026166, 682738945, 3631838634, 657685579, 618943277, 996863671, 2187701409, 4019922914, 3644683240, 857254337, 409516993, 2681090225, 1635520229, 229516358, 3151916241, 694772196, 2435581206, 1125534899, 1910166927, 2448255279, 697647330, 1830318100, 1609142992, 3611999617, 1847492473, 1355259976, 3708210041, 2735959343, 293575348, 2975059905, 4274837588, 3745372880, 4076667507, 3873563731, 3099420835, 1001674783, 3547607037, 1838139501, 3326132470, 356100529, 2607636644, 3791208868, 2579299845, 3155313575, 309611805, 3292634034, 3698684191, 2375433324, 3877927092, 3763165659, 531649305, 3837201187, 2282886327, 3002787250, 1223950399, 3649652961, 1184782172, 3466130022, 1238685353, 180270883, 1752600178, 726733767, 52593246, 2618104701, 2843395146, 1428755413, 2660004701, 1927047974, 2869239333, 1007878885, 1944014181, 2497293477, 1862749216, 2028701675, 216388274, 771716445, 3598106963, 1505785136, 1371557563, 2522177212, 3753067627, 207338163, 1955929058, 3148350200, 1957377172, 2164175391, 1006133080, 218924664, 4237756727, 4124313905, 963598878, 499215679, 1172118642, 352801645, 3711486055, 2704856106, 843526135, 2380772459, 3349025226, 4273981066, 3853711389, 3666535652, 3757224559, 3343712598, 4110824240, 2216790611, 2036434305, 1637307214, 1895812213, 1109890606, 960516819, 416511472, 1428970943, 714117557, 1042867327, 3584887456, 1200174443, 4106051533, 2966846591, 4286452120, 907712294, 3028289635, 608526429, 2369063090, 71802511, 3188847921, 46576398, 3655681067, 3295512953, 3638105274, 2119636724, 2572108308, 763014256, 4016048453, 2184788569, 3419569661, 3686207017, 3368449948, 1683363159, 2266607979, 4157176569, 3329606707, 2406202189, 2840460639, 4002433436, 1857236927, 1186011215, 2565743137, 2506474626, 2869693354, 3765518931, 1708079424, 2703237025, 2402297528, 563068429, 1459608153, 2846473058, 2604689849, 2216300800, 2424306645, 529388414, 2318346844, 2403016497, 3445305487, 994471558, 2958786303, 3964318006, 4180280941, 3250713050, 3786273909, 969898182, 1008973939, 122032332, 2129955944, 638544021, 2812683054, 2775574130, 1576693875, 525779223, 420097599, 3642591110, 2993241847, 2620193437, 4269035410, 1575785715, 3444471787, 4294921544, 2478645296, 1930412589, 441446086, 2060156797, 554640781, 1583647825, 2456879323, 2790030200, 2100532777, 2854768645, 787011355, 2298053187, 1455122573, 582074911, 14997701, 3518950742, 2881834507, 1940098452, 1701395718, 3034550474, 2087613597, 250442365, 1580048717, 3790302087, 2344367410, 2437266339, 3023419473, 3840138892, 3550683195, 960677531, 4143492805, 467899094, 3581822845, 2855355044, 1254323525, 3603167711, 3285584259, 3091552660, 1528201745, 2387950529, 3188835330, 124684358, 1610853249, 716458711, 3435200986, 2378854294, 199806670, 4193966026, 2799407192, 3782350066, 868481059, 443682634, 3674611533, 763113571, 2754086452, 2528179471, 1576625559, 510326000, 1657616019, 1833044432, 2723855909, 152377489, 998028148, 337731178, 3265443092, 3700237320, 2940004226, 971765863, 2450784377, 3215723394, 3678551205, 4061391272, 3851851231, 2899339302, 1248189013, 570675688, 1276023275, 3759158608, 2500824135, 2509074472, 2527752661, 988837119, 1475656310, 706394433, 2455979371, 2436825652, 2507640175, 626513663, 4005398074, 2644648308, 1290976833, 1654396564, 110135643, 3263622255, 463879869, 1888262729, 4215769909, 1934613129, 3483952775, 1724048463, 3932205985, 2088081195, 861756285, 1594614133, 2492863394, 722201448, 1550394506, 571927635, 2659445340, 2801880457, 3132851170, 165526633, 683594542, 3481462370, 2478620971, 2302899208, 3801656181, 1601163220, 3263774847, 1631993133, 1238601788, 1247510535, 1461290983, 4238127104, 2128496266, 90140812, 1830400869, 751828593, 621557169, 1723496903, 3957415136, 3262786214, 549825854, 2955876730, 2777176878, 1820315241, 1]; pub(super) const POW23: [&'static [u32]; 13] = [ &POW23_1, &POW23_2, &POW23_3, &POW23_4, &POW23_5, &POW23_6, &POW23_7, &POW23_8, &POW23_9, &POW23_10, &POW23_11, &POW23_12, &POW23_13, ]; /// Large powers (&[u32]) for base29 operations. const POW29_1: [u32; 1] = [29]; const POW29_2: [u32; 1] = [841]; const POW29_3: [u32; 1] = [707281]; const POW29_4: [u32; 2] = [2030206625, 116]; const POW29_5: [u32; 3] = [1797710145, 3816168866, 13565]; const POW29_6: [u32; 5] = [4219425409, 2265142903, 4119564573, 1570454940, 184033331]; const POW29_7: [u32; 10] = [3969180929, 1340492553, 1739183727, 105569977, 1767257366, 1739519195, 3874617455, 3771111571, 1793220428, 7885570]; const POW29_8: [u32; 20] = [1845676545, 3608513765, 1294341313, 344489966, 566774291, 427680924, 163628113, 422450508, 3222465417, 3727450692, 2861254789, 883344622, 1689193932, 1672377999, 1874044950, 3963222593, 1712211922, 4194848827, 3979265421, 14477]; const POW29_9: [u32; 39] = [2741605377, 3747537770, 2886285109, 1412328910, 1983065589, 3689472563, 746895763, 1865898533, 3190488753, 2306727561, 93165003, 393896841, 3469007245, 350649525, 2503345911, 993127718, 3133114464, 821782878, 626409599, 381575402, 45686706, 1602747444, 2383280150, 2768255957, 404622700, 1968885784, 1077673669, 3777279179, 1028090331, 643293672, 4270324062, 58968547, 538879074, 3280367964, 1962916813, 2823720265, 2293198637, 2545114653, 209610355]; const POW29_10: [u32; 78] = [73607169, 1727263960, 1550447109, 223139752, 474733911, 2907675967, 3776691901, 2917289149, 8658750, 572966205, 3934783264, 3097006194, 1229111012, 552677943, 244540825, 2659847833, 3839719922, 4256484087, 4285080068, 3146272340, 2443489594, 890208720, 2265994015, 386119463, 949159946, 22693323, 1194056901, 1827462345, 4016125523, 3968753268, 960638922, 2816452726, 1620062006, 545777120, 414071121, 3769697272, 204797, 2016773156, 2535915665, 599464091, 1031205166, 917030052, 2226442601, 3339166097, 1797305811, 541956524, 2958721485, 3048266196, 4259459440, 1379998557, 4176468795, 2567940618, 4181173209, 3739384482, 3312759079, 2983647679, 1436244967, 3871463862, 1499007172, 2101608748, 3148042606, 3529524040, 4136411945, 936705246, 3326082955, 2710274333, 1883484962, 361100589, 3022765025, 3931132428, 2649068847, 2761797091, 3525392638, 859192676, 3927252476, 4260244805, 3640817271, 10229763]; const POW29_11: [u32; 156] = [4278603777, 697215319, 202853069, 2954909114, 1550962014, 1496023878, 1782193615, 3665399447, 3085565264, 2841551794, 3719475863, 1273167982, 2320235283, 2098517552, 44349562, 862793635, 2953154376, 1587005149, 3168348248, 1764782146, 2062885846, 1072560879, 1789045518, 2917948689, 2924957515, 2555853131, 2939971233, 681122998, 3174781702, 2662376941, 4123393835, 1483261462, 3334085387, 841325466, 4161363919, 1996038917, 2662316806, 4117921344, 1854020894, 2163718449, 624914160, 4143716802, 1152477144, 3761430858, 3634337359, 740859484, 3562428707, 4026862771, 678311050, 1940514605, 2932426120, 2325287144, 4183216363, 962659255, 3417669325, 2479541064, 298477652, 4169501017, 3758278103, 1711340542, 96141647, 3215275776, 1919119895, 9401932, 2882445344, 1060594142, 355920713, 385890957, 1054224959, 569979766, 3797736015, 3397125441, 195938544, 995733397, 2588893058, 2042240136, 1709410972, 4120956638, 3141477629, 2131485274, 771892488, 2816894770, 3054172189, 3611267231, 2977682122, 685750076, 4150739665, 3619886069, 3053318796, 899466401, 454257567, 4246663479, 2422422368, 2084224089, 3446576329, 1212477009, 506911052, 2987008999, 2040308234, 3639166139, 2462919952, 4272561960, 2096264055, 3729176847, 2102556768, 2603507063, 1899102954, 1553729706, 122344717, 859323548, 1649990386, 1521267614, 1927659096, 2731685046, 3916751522, 198593844, 1228999290, 3674435493, 3172342912, 1702890034, 1328949637, 3890640112, 1647424304, 2639285503, 341668221, 4107683075, 658508302, 1929600924, 168815462, 3733313214, 3380373144, 3663192695, 1301952946, 1856661354, 490667334, 1640212579, 2118340383, 884101983, 3676138166, 3368341196, 1984411539, 4128071055, 607633591, 208516855, 1101438860, 2842144949, 724302134, 1515113562, 72509015, 3435476047, 3059758279, 3665234599, 1182272530, 2792877457, 1190212543, 24365]; const POW29_12: [u32; 311] = [3607928833, 3172288055, 199160624, 3815140915, 4105135486, 354905100, 3334288201, 2374822670, 1591127775, 257429645, 1191501490, 1839186182, 4012788896, 4287636051, 442130510, 1519890657, 1288950902, 158929220, 4220851980, 3951512010, 4194716349, 28529624, 3940969666, 315223375, 816580711, 1792851290, 845620169, 2590898178, 2193361451, 260246424, 953995987, 293040003, 378698822, 1766866274, 3894726485, 3059015199, 2210108283, 685592791, 3465961704, 4117926780, 2444200593, 2515179420, 2695137729, 864772394, 3019284117, 1419771309, 703241944, 3693031146, 4033289377, 2451600091, 3740912397, 1363611801, 1100094045, 1789977742, 1402519375, 2934850417, 2560495362, 1713428760, 4209170350, 1296762553, 4177610136, 1073420145, 3871056953, 3387126897, 512427028, 2665482997, 3291283379, 2751792998, 661182206, 2101149465, 788878807, 4100594244, 99048184, 146464003, 3380645691, 3819035076, 3603170945, 701081015, 3720253032, 130253503, 3679112580, 1794752709, 1209476919, 2671937841, 87671778, 1752746183, 4041650367, 4290916551, 4167356879, 3876112030, 1108122061, 3491100392, 1489365511, 373185189, 1883413925, 2425193676, 2323548305, 908560591, 1948021589, 3776848200, 47334853, 2963562145, 3102090119, 3742296626, 3195412642, 2807873934, 3274976012, 1756841097, 650785134, 651748604, 2981868088, 389371324, 3895577665, 2011007468, 1241038096, 560605404, 2680398066, 2580194201, 3768424261, 1401956559, 2125168161, 1817282670, 1069321318, 611379508, 4080385706, 3777745780, 1405905850, 2342863597, 2922904845, 580076185, 3201346217, 3927498483, 3584531193, 1264830103, 2227961968, 1490369089, 2482481839, 3009000827, 969504404, 3905341734, 2874668988, 2045899191, 1089128399, 1504976194, 2833313782, 3063026411, 911402527, 1265656537, 1000807348, 3466284855, 2416281739, 1318343005, 626681002, 1411270607, 627171802, 3899677631, 2769301206, 1951203588, 2499971370, 776095777, 3786039761, 1317617964, 3185899345, 4132713697, 1305149308, 3763748177, 1703616143, 2381192787, 423169192, 2338580159, 164376048, 3534014631, 2435384891, 2536480092, 2611549869, 3390039588, 2506328084, 4047419198, 3611123991, 144779922, 994101540, 2523775857, 3972705149, 458202001, 3947530004, 1902196855, 2482166846, 2510589980, 793211894, 3979960687, 1791603334, 2677229163, 3963053333, 2889462311, 3639690090, 1727091983, 2132273135, 4260113040, 4136804362, 366651068, 4014155770, 3108998370, 3524928879, 163789635, 1857975067, 2175199387, 3061735179, 1671255764, 2487618669, 170315554, 3600792564, 3129952624, 1895671812, 2394379137, 1058623778, 3720215419, 1625703422, 1854220682, 1922473404, 1319953466, 3003019916, 3369563474, 1720693313, 3027887928, 2700242801, 2236329480, 2274388727, 3748013616, 1803164013, 1997843968, 3591495713, 1395040688, 2646289185, 1044704746, 2468273032, 3399212506, 2308715228, 3242205410, 466084230, 2675183433, 1513832991, 2588626825, 3740540717, 2653270253, 2476312429, 891627129, 450536579, 3552176684, 465569917, 3776661276, 1494793834, 2304900165, 1244037087, 3765131358, 1421214113, 2216329758, 2377502548, 3461492606, 417469843, 3927482701, 1900648322, 237767264, 2245383962, 2743269639, 455634196, 656163457, 3436736663, 3007991801, 3500075783, 151551344, 1861964282, 2332367313, 227261633, 928786803, 442629844, 223744743, 2914982971, 2271868058, 3591067978, 4217647960, 374514385, 4230019140, 1550676035, 3377325821, 3678940869, 1049269419, 2477001772, 812696853, 3495418575, 3427581880, 1068364743, 1305279423, 3640508285, 1573640499, 2030179892, 453940246, 555867500, 2104328489, 1169480451, 1057036024, 1007972776, 3374167874, 587514179, 3159698528, 1705338233, 2465824868, 1335209891, 957788808, 3503441638, 148716156, 593666729]; const POW29_13: [u32; 622] = [303644673, 3183313359, 1076783228, 999911089, 3398129928, 2779329913, 1032887498, 3986457683, 2955592949, 1691800665, 3824605515, 2804753885, 3452962860, 1060557084, 3938354736, 1895760521, 2235469582, 3475924610, 158840748, 2465874169, 1305903705, 47725050, 72716818, 4282885909, 4241690860, 4207749816, 1075135789, 3023104985, 3829299750, 3029023672, 1193029810, 3128772959, 3866776527, 4003411115, 2382880661, 4163238484, 3751602836, 2035172010, 541641876, 245401834, 1858547923, 2201891579, 4173044206, 2941936212, 218252298, 1820008548, 33580923, 167399357, 1543106286, 2446335653, 2111948432, 3883029972, 3496468947, 752335179, 817552192, 1917461340, 1324761443, 168684988, 2104242380, 3124339844, 1141408612, 2074356148, 1167598633, 3357103207, 2471197125, 4200966721, 2402964820, 1333066366, 3391310489, 3043470037, 895188397, 2392954091, 2952156610, 2798187726, 3425704694, 4109012957, 1888190658, 1345700401, 721060681, 3876834174, 2209380659, 4092844177, 1823377013, 4248159515, 2632724164, 2063037533, 2902415591, 490954952, 1044158739, 2951434559, 2521421609, 997866532, 1952446248, 2160056446, 3186384396, 2535960823, 838019242, 3119346130, 3861853776, 3623933842, 857167795, 2250467289, 1780232445, 1277821502, 2082379725, 3495661016, 3018854047, 1345333239, 4280922518, 3466106207, 2579113204, 39317414, 1472739731, 1792810543, 2185078144, 1487293172, 401857417, 2146057477, 3143789664, 2699086962, 827996356, 4064349888, 1662353986, 1797375974, 979056531, 1344912360, 765649955, 2771210394, 1164010295, 3788606568, 2802032172, 4231796015, 4001203572, 313890799, 3052869518, 1301272702, 4070120662, 3340639114, 2007663329, 604496786, 3897245152, 3026622833, 4284829951, 1828563085, 1540793618, 1729659901, 3154823257, 2135200319, 4183552731, 2997372558, 111567451, 532555489, 687137494, 3599716408, 2316350567, 251811707, 1434760416, 1432186602, 1096469152, 2624751716, 1368985992, 3212505234, 3055001132, 2473674731, 2150232166, 146699872, 2837058512, 2647805246, 2096270624, 250307650, 844431077, 1246568178, 555089930, 4063302278, 3306804856, 2060007132, 1539650155, 3433967093, 2830736770, 4223922604, 3733371591, 1905078074, 268715723, 1802178127, 2026703815, 2324444230, 3440092954, 2057951711, 136534841, 3684051805, 2104244864, 1744845513, 2192314422, 2305196093, 131872073, 438869222, 674629894, 3299635811, 1106938552, 3254925718, 3192711691, 3146361283, 1755736231, 1291673623, 4261541459, 1986268199, 1315835509, 3009412613, 2973425468, 3640768416, 4224096917, 2882674484, 3355313666, 1279142813, 1160361149, 50119274, 949924603, 2933555006, 1274125673, 2472227477, 1519351166, 201587781, 1074748878, 4229158278, 603906850, 990754641, 4294456296, 345136702, 3560171052, 627635694, 4101663877, 142723961, 2378988083, 1245764179, 2973857140, 2478095233, 62555848, 1808536722, 3025895988, 3104995285, 3373929246, 4169827753, 2840358176, 81042179, 285927421, 3337938645, 1305479039, 2862535986, 1874603606, 807474687, 1660116983, 3434786736, 3554253119, 2702055524, 438987431, 2307841985, 1455140514, 2845740475, 1883605201, 1280643263, 581237717, 224756748, 1269082234, 1890630962, 4176579598, 2418094911, 521775027, 2584291463, 76563234, 4224875385, 2855407519, 2144695537, 3277115083, 3756289399, 2153175735, 3604124288, 3258293705, 2042617615, 2472190561, 252576920, 4001317443, 1212884260, 1549325556, 4088074707, 22493855, 33328745, 2960453593, 2527772030, 2591296152, 619193823, 3989256628, 3906079973, 1210839857, 1234498834, 4223523499, 973035588, 3177917377, 2556043565, 1271906994, 2006279264, 156770796, 3884106513, 831340199, 4053124734, 2982401735, 4001576003, 2516342895, 2930489120, 2028053718, 519993087, 936909979, 1071994874, 725603483, 3497336401, 3610814535, 3930657257, 3977278599, 1010148812, 580900628, 593301858, 3327728996, 328744601, 3945396574, 2505306274, 2342321917, 2815739140, 3389869102, 3085070177, 1610655666, 4093683037, 3192440806, 602451862, 3851066731, 2144890088, 950713960, 4287963561, 3286490648, 136894868, 3319128654, 3904646232, 3985523626, 4197905340, 1694102576, 501793921, 1206701048, 2833568710, 3371724344, 3052249003, 1744131785, 2083286690, 1859301448, 1371001931, 3286393557, 3401800068, 34471061, 3591009703, 2518753186, 874480531, 2566451611, 1477745000, 328163581, 244124411, 2892083124, 2298202563, 2167594460, 2538473758, 2357707143, 977661367, 1581329216, 1592884799, 3698473987, 3185681363, 2455621907, 3364832939, 1054679906, 2217747561, 4105059165, 3959399075, 3548450065, 3774469321, 3791714722, 3553057415, 2063297147, 1807493563, 3977593379, 3254904003, 2599804607, 2020243000, 1118199017, 1564055810, 3370022, 1734908882, 3623326673, 2966995191, 3642308246, 3449150232, 1502085375, 3446684038, 718560555, 1447552798, 2812607505, 3644257274, 444292967, 3362075634, 1643860215, 3089826123, 2115551495, 1254916978, 1087167284, 869638441, 2010653041, 2527916487, 1285767759, 2416012550, 3547777031, 915740087, 2729231436, 162451211, 365493721, 3877582547, 2277113986, 572868686, 1262230636, 1895163344, 628196366, 2922199147, 4037231086, 3420625536, 2410166508, 1909185220, 2702337144, 2725970107, 4261606944, 3751913945, 3050620361, 990491761, 3145229247, 3237716436, 4082857938, 390867178, 1768964419, 751005573, 2546755211, 1112835765, 820035761, 986213907, 2473306682, 1360563042, 1905677837, 3181662095, 2911801772, 1901440501, 344892035, 3006094535, 2680608443, 3732710880, 3541067859, 4055206617, 2202617299, 2080481907, 86028653, 2033998330, 1363819323, 3777887954, 399211942, 977260394, 3736523869, 1913224162, 4013933894, 1529265582, 2007809405, 1095173889, 3696356081, 4229713491, 2687125930, 2108457172, 938560412, 3425892164, 3351361513, 3939588737, 3509314163, 3847320545, 3911595459, 149317008, 3256445432, 3557227499, 1627632369, 1142527704, 527475203, 1273749217, 544269845, 1653200233, 212332584, 3154602799, 2554156023, 3164377227, 1953273019, 3124461181, 281702484, 2973367854, 2084540394, 391716868, 533992137, 3772849927, 10812354, 496132998, 3916517968, 907608417, 1716473062, 3447839240, 990843744, 3014585829, 3774531883, 3979986077, 1490012160, 1053656454, 2965511562, 3121392799, 4288672751, 402781092, 428614128, 3818398840, 810522711, 1659949872, 54897046, 3971042606, 3321161469, 1385187039, 2492529446, 3067064010, 183154593, 2655170055, 1663939522, 1573558418, 3519154304, 1154816616, 4111070745, 705578613, 1942823529, 1774191611, 630059831, 4180110313, 3706196772, 100307053, 2381605985, 1985147547, 3386256081, 468300529, 2951787591, 389561435, 4254671518, 3867720458, 3183869016, 1500247372, 2558315356, 1480087440, 55126764, 1210148925, 3681601188, 3519747474, 3340697889, 2797517767, 855268, 2128908273, 2509415773, 3803681356, 3796106933, 128933844, 69661913, 684821642, 1456666030, 3909086261, 133474552, 2814021940, 1385209203, 1521674972, 1988313066, 2379102257, 2348906564, 4158524805, 338482558, 3888007623, 1995626085, 2428026966, 1046401992, 575781181, 2301318754, 181133530, 753396344, 3655347530, 4292433521, 3945538019, 1452083430, 1405107381, 283647490, 3917176879, 3188796574, 2707263909, 1329780507, 3512292689, 2188459725, 3736113550, 1278090504, 1315319779, 1591842429, 3936306061, 703921010, 4281991091, 2117759127, 3819397001, 676858981, 1122763461, 2597188748, 503031614, 2595031841, 1860404840, 2527881539, 457668224, 3911672161, 2601854028, 691119667, 82058875]; pub(super) const POW29: [&'static [u32]; 13] = [ &POW29_1, &POW29_2, &POW29_3, &POW29_4, &POW29_5, &POW29_6, &POW29_7, &POW29_8, &POW29_9, &POW29_10, &POW29_11, &POW29_12, &POW29_13, ]; /// Large powers (&[u32]) for base31 operations. const POW31_1: [u32; 1] = [31]; const POW31_2: [u32; 1] = [961]; const POW31_3: [u32; 1] = [923521]; const POW31_4: [u32; 2] = [2487512833, 198]; const POW31_5: [u32; 3] = [1353309697, 2948261936, 39433]; const POW31_6: [u32; 5] = [2111290369, 854830039, 1377820608, 3005187674, 1555015626]; const POW31_7: [u32; 10] = [1304393729, 558465812, 2768012290, 3935646446, 3376640041, 1419477874, 1557778152, 3873581017, 2245632988, 563001632]; const POW31_8: [u32; 20] = [3820941313, 3840574348, 1970562388, 1279978999, 91057081, 172159608, 7026786, 3609778129, 320477644, 2720004857, 2683868502, 3872769187, 1705702550, 1250974998, 1821061582, 2142610495, 2457779444, 131107681, 1215733575, 73800524]; const POW31_9: [u32; 40] = [3900563457, 3605508898, 1080835543, 1839856042, 1887789426, 506338258, 1664410539, 1941444729, 2303133992, 1204730127, 4228901863, 3235428013, 108090832, 4278312395, 4187964700, 878213001, 1487687387, 2089710316, 1913306896, 866021004, 281352193, 3790189294, 1071396380, 1070474072, 1560701226, 508984177, 2267895212, 3095779249, 3222665897, 3587404114, 523699303, 1215001001, 2154196787, 3884596454, 2367833007, 2975277751, 3968326605, 1164131563, 636920197, 1268116]; const POW31_10: [u32; 80] = [1425784833, 2309179946, 605198140, 4075439659, 2712533997, 103860628, 3011372056, 1930212728, 1296157408, 1058369540, 1528293566, 1111476611, 2626896309, 2709728996, 1397738171, 1300019571, 3454944728, 681924413, 506805944, 223257902, 3164499261, 877689735, 252073363, 1368223871, 1957508588, 2561824618, 745102383, 3229593914, 1953834733, 4023459261, 2970522886, 3289050300, 1988414496, 3618191877, 2791612790, 3753666209, 551881119, 2867462426, 2431166687, 1542558833, 3082166710, 1692150099, 862968556, 1700789331, 1196859083, 1734165634, 2284249015, 3240024613, 3607341121, 3616513708, 3272709503, 3622879435, 741213114, 1560534899, 3403198491, 3230513765, 4203027176, 579111566, 2236689072, 1728386745, 3852156906, 3851502305, 3358676318, 1552411624, 2866922094, 387134890, 3075002974, 2260892662, 124842076, 496426192, 700274592, 1288973540, 2534470918, 1648355020, 2966648217, 3670674092, 2654505063, 1625485661, 1800796861, 374]; const POW31_11: [u32; 159] = [3120005121, 488096230, 4043397809, 3846877022, 2483592266, 1741088811, 1435142880, 2050319480, 517262951, 722574780, 238070319, 786965630, 322204487, 1103090908, 2967926613, 2315724446, 2772989472, 1810548431, 1359881341, 4051147333, 1218086232, 776892200, 1943969984, 819401991, 3332468732, 1228365157, 19838017, 3010084475, 918974391, 3616871658, 3127018519, 2188858850, 3991305607, 1675249399, 1788150933, 1662898117, 1569457105, 3386262069, 3142393857, 283522619, 2220147540, 2991940678, 958689879, 4038295507, 2789663217, 2933447657, 1366791790, 1923121992, 1038666084, 79141466, 1862841584, 4172033108, 1515140411, 1459517991, 2435126659, 1263530374, 3461849730, 1023461415, 360959558, 1480477433, 4015033035, 2612764845, 411967187, 640257764, 3364343281, 742559927, 429175685, 1115349365, 1534393072, 273676385, 41832834, 1338543611, 737323479, 1609524875, 1031988474, 1156849110, 3163325674, 1359180346, 1113088160, 879320928, 1185571731, 2639531511, 2496406806, 462087665, 1734468616, 1613759369, 922076852, 1592024184, 1673328534, 3345308531, 2736181850, 4022461859, 1053087598, 722982409, 841417491, 2932897596, 2825857611, 1506576220, 3356827401, 838819962, 4246599948, 2694391874, 1631357300, 2587807358, 885057850, 254343006, 1347746364, 2524302616, 2190891935, 242348930, 991113938, 3891063097, 2249770445, 1391269286, 1741318817, 3470463227, 1941278356, 3112312335, 3611229996, 1591476171, 3905400994, 4270906928, 728748276, 29536128, 201741823, 1083723043, 871807055, 1207413132, 1311110999, 3698150249, 754440540, 2435230741, 1700095394, 2263890850, 3675382371, 2041485294, 3739417473, 697942096, 2689881429, 3435609081, 3358084069, 412824872, 2743917970, 1687371847, 1412072137, 2638121547, 1733477680, 1180409564, 3573621075, 1182797785, 4279670835, 622698019, 1631163303, 1252862013, 4187932825, 1254825595, 3715086166, 3426328017, 140189]; const POW31_12: [u32; 318] = [3018784769, 419506709, 3233212213, 2647101854, 1477793438, 2458093334, 2288485237, 3429482278, 2831108905, 3809323989, 403137974, 3835811100, 1610459238, 4109149581, 1610747818, 1074953727, 2920186091, 2577002919, 2589919117, 462552040, 1462936280, 3094523706, 4105142664, 858835160, 2719310131, 2913242650, 3972794176, 1676912351, 4280513099, 923764361, 465224322, 2812484591, 3066396016, 1348073152, 4199723738, 1500985824, 3375336889, 4146043012, 1454194161, 851561957, 4247797608, 1024323299, 4070074584, 4209776858, 1943151726, 1029649909, 1083700918, 1639565385, 3862138132, 1112783654, 1468101321, 4135322607, 1062896025, 1603454720, 3050916297, 1596325937, 3696381945, 1554644965, 3298910421, 3289579255, 292490621, 616477315, 564799944, 1151973107, 1537218851, 1174576388, 3905729297, 465868533, 698473488, 1792091640, 2945073796, 3189415559, 2446703543, 2912460746, 637266798, 3657401194, 1510126640, 4115069262, 3648087043, 605289505, 2464500956, 467870221, 2105706646, 2130955145, 486376380, 1951498815, 4290218813, 2179473839, 1935789855, 1825772748, 172130114, 1197404015, 2603367882, 2460444193, 3307498781, 3862141976, 753261873, 615019379, 2914438021, 2627031896, 3239475496, 2496043199, 2168300320, 1171971473, 3599919440, 3109516901, 2958093187, 11899504, 2740177559, 3903901458, 884552025, 3093790134, 957145515, 4084008785, 2307781754, 3738538007, 293067613, 3597823465, 3240542144, 368882458, 1670042397, 4152571281, 309483204, 3669862414, 1884363565, 4128384557, 1387982208, 3697023611, 3698061679, 3152908271, 320634861, 3132422725, 1788486808, 4229940495, 3381901194, 4250442499, 3601486272, 1145260618, 1550198089, 34745150, 3956057056, 595514528, 3828247218, 1473795595, 2609913194, 1703863313, 3811751146, 486210934, 9348244, 591691691, 3467033910, 88755306, 3005002439, 3743182597, 2996665153, 1970416184, 3788536607, 153893617, 128047321, 632017363, 397418666, 2881420714, 2956471890, 1181119044, 3036255393, 98507404, 1035178092, 3324933040, 3782741863, 4176523726, 1631122807, 4248599254, 3528346344, 3766981847, 2039336580, 3031794437, 2305122739, 2074825435, 2112728216, 2645744926, 4103404197, 2500935439, 3610013250, 2335060409, 2358894139, 3742733646, 2429514141, 877651683, 3173403496, 2271349607, 526525851, 3426636266, 3558349301, 1762698863, 3219633537, 1000803285, 3026367708, 3237224684, 3661302038, 3560761596, 3274671807, 123055829, 2430724955, 3583392084, 1620450329, 786940026, 2666934574, 3175328535, 2721719547, 4111833181, 1260489798, 2748812635, 1759741972, 3643279594, 4178723567, 1785976326, 1775532742, 3394440427, 1092540046, 725274647, 3353843106, 1487980419, 1893843101, 720244643, 3576064213, 4284131422, 3548959637, 3093012789, 1784730937, 3554465193, 3635561711, 2923335044, 3242071688, 1728240122, 2457964547, 2309058770, 1311798242, 1796666200, 1421606769, 1003035025, 509218541, 1001007100, 2513790966, 2579349489, 2368558506, 1674638636, 1848570716, 3360991553, 1519298938, 3041316120, 563730877, 3258334470, 502273689, 18205981, 3522179972, 3882181459, 1213464180, 587602597, 3241644306, 4042784099, 1975158053, 3023488285, 4207961823, 1353678974, 1769145680, 3428501067, 2345068356, 2217643002, 1333238334, 487305453, 437806812, 87016367, 2947505658, 1900708318, 1838188938, 3294142465, 231538659, 757985396, 3106426697, 2999167873, 3665346125, 1491136468, 658022211, 2005742040, 4154854801, 2804986423, 3137674860, 971420416, 1203598082, 1094155649, 2743938545, 2028706224, 2688847041, 915909610, 238345560, 2287176763, 3035995830, 1160017862, 2848858409, 2673211775, 591232133, 1109898692, 2700262121, 4215639262, 127379574, 3675139257, 1802194813, 3124284639, 2162602875, 18064492, 3219263946, 3310803175, 2740665076, 1138589124, 640377103, 1510362163, 2473310210, 4]; const POW31_13: [u32; 635] = [1742602241, 2712694092, 3969844521, 4030024960, 3498984537, 3608158682, 576130865, 413907429, 685334448, 2310203983, 3614129488, 2826104460, 2409640991, 4063374733, 1477292428, 2081766794, 1394595811, 3345035813, 1099378286, 2815653833, 2904983105, 1424980588, 3595308604, 940700773, 3922907263, 3759905200, 2635160994, 2709716432, 3907941784, 1665894635, 4207386969, 1733690565, 164929134, 3300318735, 354481355, 2562427821, 2160848272, 961345105, 3365044123, 1843189937, 3084862570, 3974595972, 237355324, 1936488715, 2701673480, 3942094087, 3512375909, 1422117058, 1210054132, 4128467560, 971193828, 2322652741, 1550099421, 4084627544, 2753748181, 2111537343, 1614730916, 2657905887, 569549264, 3245912140, 2344967673, 2243340516, 253999102, 2004450639, 284115510, 1273879578, 761323451, 588931017, 2330833468, 1304890665, 884856597, 1180867463, 612510327, 2307123015, 248328847, 3566610571, 1084727639, 3566188200, 2109971242, 1692532445, 516814364, 4198410336, 11582444, 2177407516, 3708307492, 1709899827, 2874710400, 1274525827, 2111164058, 4070338644, 400439673, 1356063997, 1478669924, 3784739233, 3970025643, 2667544651, 4069878409, 1030572482, 2880952372, 389293382, 982675512, 459875096, 3712204933, 2687344655, 3004405439, 284104407, 3944193068, 831810388, 1308948787, 3959581066, 2488261527, 107772095, 164213469, 1384608366, 2311715038, 2558943373, 473580057, 1704616716, 496989078, 2688908018, 1574625329, 1060021895, 1490036773, 1540921, 3096216483, 3100373184, 1537788597, 17470621, 3188476918, 2453383104, 1431325646, 195756539, 2880896207, 646593199, 90330352, 3961124530, 1827399992, 1633344461, 3741151065, 1526580449, 2019661887, 735159922, 3221729095, 2755534372, 3621298717, 966384068, 482669086, 945383312, 2441376446, 927823971, 1967343761, 2258372909, 646033921, 1652706794, 3471710200, 58292462, 3535345003, 3002082721, 213539009, 2776339201, 3562761185, 1954167026, 3302407048, 1304646401, 4213703860, 1004101238, 3169011127, 4148571839, 2564293074, 1729630728, 2766453747, 3210948511, 884630112, 3920666526, 2005012169, 3525795472, 3931451014, 6224738, 910001578, 1304686443, 151718680, 407491051, 2619604510, 3159210219, 3816730597, 880480511, 1115767705, 3002908945, 2707114743, 635594262, 1726018006, 696637100, 513482034, 3305263239, 2798416989, 1723305, 2011353818, 705861072, 2723201758, 2924166530, 1108452763, 2068774330, 1495460864, 1691603250, 456651540, 456923474, 1959681531, 857783853, 3930669182, 2383874766, 4287839069, 2976331139, 1208460834, 2885060970, 3047970969, 238351352, 3336153557, 2899307923, 2271879335, 3093104656, 3344624615, 3855037668, 1130818629, 1235935730, 1643697088, 651097950, 918462320, 3717032221, 3197438660, 4188258045, 2522845555, 3271357381, 1538710606, 677340008, 2468511212, 4254079112, 658921195, 4067520048, 116661002, 2150343726, 2817660409, 3586583391, 1482025530, 1260675908, 1452495403, 2959503405, 756029845, 2642229035, 1498028053, 3091970612, 569961004, 2329761040, 4292169792, 90222790, 190387838, 2781559307, 2917291193, 2691026458, 1075189898, 4059944629, 4114364763, 3830989952, 3351765634, 4282342604, 3939445622, 1284783665, 2376071789, 925272463, 2364509562, 3703468763, 3311558520, 2980519534, 702072550, 1131176482, 1015663272, 2170462071, 2320129449, 3328536099, 2523170352, 2233495964, 953653350, 537220430, 3258604626, 788472508, 1513210443, 2269189121, 225396670, 4042124581, 3970457239, 542819208, 1064864224, 15599949, 3681733175, 3568163747, 435612715, 515167662, 2920074478, 858295613, 2021232959, 4294514297, 199939877, 874059115, 3043261335, 724543880, 557003460, 3496395691, 3514106423, 3550568600, 279845898, 2255561333, 2695916856, 3171370168, 1096833516, 1441325713, 433034286, 2374659071, 1330891183, 4223843286, 962673246, 2140818628, 4225430131, 1684729340, 2705128107, 707784248, 509351241, 1260865699, 4171859855, 3798313893, 3744144457, 3832767151, 3214278779, 2126972581, 1322182129, 999821442, 2984750496, 3230061016, 191820816, 703926511, 578693817, 3767317383, 3819895309, 3867149923, 626736563, 3759588883, 2948954341, 899990890, 3298124329, 2807236639, 3843579196, 1175298984, 3320790919, 308595574, 1591588158, 899369493, 14799420, 2829862714, 2944200479, 3157141718, 2376984832, 3809211207, 1128878942, 1752683221, 3037718287, 2495148815, 2642325320, 2667307900, 1681086360, 2491706114, 50620460, 2496263600, 138337152, 2966611559, 3819947952, 3357831871, 3714499188, 2742600654, 891376157, 1263040894, 1397195941, 1196628561, 3169290598, 4112182048, 1817194505, 2720356475, 3592261524, 1979701283, 3382271511, 2761309276, 2534251817, 2909157238, 3884612364, 1957501749, 3335269372, 1110221348, 3582796558, 4265299726, 3328991437, 1962564627, 1576239011, 2318280151, 383073149, 3592155296, 3655169945, 1162442196, 4292171127, 2429088230, 3359427039, 4268348448, 3706225061, 723682994, 578194845, 2536702371, 383875365, 577216906, 1997248387, 856921253, 2139686297, 1837767581, 2120201901, 3189412593, 2707332447, 2109041594, 2377975350, 1903059381, 2323705884, 3506337925, 679208764, 1467729428, 569461524, 2249943848, 1871392477, 2418401166, 3339243325, 1947645141, 1716848793, 1375820726, 4087047552, 1747489454, 22815696, 3454086193, 897252209, 1671384647, 2815952662, 755326187, 2074696402, 1741175855, 3659919168, 2313570242, 1953266518, 1679709350, 767347542, 2664118553, 3559981454, 2161973795, 3514438343, 2134804417, 2712509674, 3949219881, 514783764, 2532009617, 1330811725, 3863190624, 1934885504, 700124836, 3141348565, 3774480605, 353971280, 2085103681, 3491245646, 463693460, 2098012506, 3954253967, 1400103191, 36511640, 752541941, 3738400088, 4114201656, 846741457, 1589107444, 2083233961, 1096448150, 2585105136, 3353854165, 1424813123, 2632857786, 22520950, 2989071093, 3012014911, 142167267, 2136931379, 2710847877, 1308539610, 2128524691, 2738618409, 232439464, 2971331669, 699686869, 856592908, 2619308329, 3107261014, 333379732, 3824336016, 1051187204, 3546514611, 1464263119, 2181070272, 133096427, 3615003023, 3471075976, 52815242, 3379588565, 56641150, 4047976038, 1413000684, 1648150629, 2099201989, 39240609, 3758920611, 4250815576, 387627480, 3569186946, 3965003118, 414323464, 1539237033, 1509126441, 4143406457, 2920674546, 3532744036, 2718781690, 3841783144, 1973748669, 3087881975, 1033502228, 1260936963, 3096176660, 2292436222, 2666901210, 3495175453, 2299822890, 2165980566, 1556534880, 2359613267, 1439966100, 3208895672, 3703730780, 549009779, 462732450, 1564638356, 2188371518, 2261740360, 1049543683, 3432977622, 563988795, 3063490889, 143883901, 3110230930, 3327294448, 1676983126, 1158668336, 930878540, 3916676239, 2896575052, 3894139248, 1411023284, 650666444, 413987502, 2304139707, 722081477, 3130866484, 3715828678, 3222365880, 887685607, 2283444283, 740343702, 1508259186, 1117792936, 2068700327, 1060755268, 873702885, 2332769466, 3625190651, 2375782112, 3829179462, 2260661047, 3495790441, 1914553319, 939689320, 3253990951, 1252334930, 3296139429, 3282440456, 1306898975, 2892499023, 1550191943, 838881807, 2388933249, 1552390444, 1688912152, 3124757624, 466908810, 71552052, 2417772964, 3246482, 2470839226, 2377505316, 4161279486, 3383731011, 3007865013, 4264254790, 2600609437, 1713854493, 4286450349, 3144723533, 1759591282, 4155149512, 1879878928, 1555014535, 394741672, 505005590, 556141291, 1812252180, 896817811, 395900714, 1974143062, 3863368026, 205727200, 1039736694, 62236392, 1026952601, 3391053023, 1572679856, 926803867, 3654303694, 4030898872, 20]; pub(super) const POW31: [&'static [u32]; 13] = [ &POW31_1, &POW31_2, &POW31_3, &POW31_4, &POW31_5, &POW31_6, &POW31_7, &POW31_8, &POW31_9, &POW31_10, &POW31_11, &POW31_12, &POW31_13, ]; }} // cfg_if lexical-core-0.7.6/src/atof/algorithm/large_powers_64.rs000075500000000000000000004545330000000000000212610ustar 00000000000000//! Precalculated large powers for 64-bit limbs. /// Large powers (&[u64]) for base5 operations. const POW5_1: [u64; 1] = [5]; const POW5_2: [u64; 1] = [25]; const POW5_3: [u64; 1] = [625]; const POW5_4: [u64; 1] = [390625]; const POW5_5: [u64; 1] = [152587890625]; const POW5_6: [u64; 2] = [3273344365508751233, 1262]; const POW5_7: [u64; 3] = [7942358959831785217, 16807427164405733357, 1593091]; const POW5_8: [u64; 5] = [279109966635548161, 2554917779393558781, 14124656261812188652, 11976055582626787546, 2537941837315]; const POW5_9: [u64; 10] = [13750482914757213185, 1302999927698857842, 14936872543252795590, 2788415840139466767, 2095640732773017264, 7205570348933370714, 7348167152523113408, 9285516396840364274, 6907659600622710236, 349175]; const POW5_10: [u64; 19] = [8643096425819600897, 6743743997439985372, 14059704609098336919, 10729359125898331411, 4933048501514368705, 12258131603170554683, 2172371001088594721, 13569903330219142946, 13809142207969578845, 16716360519037769646, 9631256923806107285, 12866941232305103710, 1397931361048440292, 7619627737732970332, 12725409486282665900, 11703051443360963910, 9947078370803086083, 13966287901448440471, 121923442132]; const POW5_11: [u64; 38] = [17679772531488845825, 2216509366347768155, 1568689219195129479, 5511594616325588277, 1067709417009240089, 9070650952098657518, 11515285870634858015, 2539561553659505564, 17604889300961091799, 14511540856854204724, 12099083339557485471, 7115240299237943815, 313979240050606788, 10004784664717172195, 15570268847930131473, 10359715202835930803, 17685054012115162812, 13183273382855797757, 7743260039872919062, 9284593436392572926, 11105921222066415013, 18198799323400703846, 16314988383739458320, 4387527177871570570, 8476708682254672590, 4925096874831034057, 14075687868072027455, 112866656203221926, 9852830467773230418, 25755239915196746, 2201493076310172510, 8342165458688466438, 13954006576066379050, 15193819059903295636, 12565616718911389531, 3815854855847885129, 15696762163583540628, 805]; const POW5_12: [u64; 75] = [16359721904723189761, 5323973632697650495, 17187956456762001185, 3930387638628283780, 3374723710406992273, 16884225088663222131, 10967440051041439154, 9686916182456720060, 10554548046311730194, 7390739362393647554, 6316162333127736719, 18122464886584070891, 4044404959645932768, 3801320885861987401, 12080950653257274590, 16414324262488991299, 16395687498836410113, 12173633940896186260, 10843185433142632150, 11048169832730399808, 12674828934734683716, 17370808310130582550, 10500926985433408692, 10252725158410704555, 14170108270502067523, 3698946465517688080, 989984870770509463, 10965601426733943069, 11389898658438335655, 6901098232861256586, 1921335291173932590, 7662788640922083388, 9775023833308395430, 4640401278902814207, 14532050972198413359, 8378549018693130223, 11672322628395371653, 8930704142764178555, 6275193859483102017, 15782593304269205087, 8673060659034172558, 8018354414354334043, 1824896661540749038, 11345563346725559868, 14959216444480821949, 970189517688324683, 3338835207603007873, 17684964260791738489, 1436466329061721851, 4554134986752476101, 6398757850768963907, 4709779218751158342, 10033277748582410264, 17932125878679265063, 10004750887749091440, 256584531835386932, 14396282740722731628, 3086085133731396950, 17831272085689600064, 10573926491412564693, 14888061047859191737, 4570995450261499817, 10410165022312935266, 5691078631447480790, 8632710455805418155, 790672778942823293, 16505464105756800547, 2092171438149740401, 17505030673829275878, 1291290830058928444, 14856191690683232796, 8916773426496500052, 10152003807578858265, 13104441193763861714, 649395]; const POW5_13: [u64; 149] = [15308384451594534913, 17913664074042735335, 6115977719198531863, 5794980608663993169, 16544350702855106930, 9253787637781258566, 4977988951675168190, 9087837664087448770, 2098480401110016986, 15474332540882100712, 14042133997396540944, 1090855284423485362, 12639956485351058381, 1454115676006639319, 3180465001342538023, 14649076551958697729, 9801292446545910916, 13552201410826594004, 6101141927469189381, 1881431857880609316, 4907847477899433595, 8714572486973123228, 3514969632331374520, 11667642286891470094, 2391499697425323350, 17486585679659076043, 18267223761882105642, 2886610765822313148, 9302834862968900288, 15246507846733637044, 15924227519624562840, 9743741243284697760, 3159780987244964246, 7304816812369628428, 17584602612559717809, 4146812420657846766, 14525415362681041515, 8477630142371600195, 4380695748062263745, 12119915994367943173, 16970630866565485122, 4332724980155264503, 8079943140620527639, 1687908087554405626, 17051081099834002166, 12638146269730763230, 11883749876933445771, 4662462156371383785, 4796962238316531176, 3325504751659868927, 6469595803187862550, 5852556621152583005, 9229334792448387881, 17979733373938620709, 13951623534175792756, 17075879371091039277, 14212246479457938037, 4008999959804158260, 2414266395366403722, 3252733766253918247, 6382678985007829216, 2245927470982310841, 13790724502051307301, 13116936866733148041, 9718402891306794538, 13516274400356104875, 17859223875778049403, 4396895129099725471, 3563053650368467915, 12176845952536972668, 3492050964335269015, 2740656767075170753, 4409704077614761919, 10237775279597492710, 3314206875098230827, 16437361028114095448, 12361736225407656572, 16792510651790145480, 11449053143229929935, 18336641737580333136, 6558939822118891088, 4606255756908155300, 2360792578991605004, 160428430149144538, 11644861220729221511, 10785178451159739786, 14923560618031934681, 1902620814992781610, 14064076995338910412, 11547019064112212657, 16847481479966225734, 8331994491163145469, 11739712981738851885, 8008309968651120619, 10266969595459035264, 15175153381217702033, 12208659352573720245, 7714061140750342961, 2892831567213510541, 15453714249045017319, 71020323573871677, 15431137995750602633, 5659146884637671933, 5998809010488554503, 16552192379299157850, 1192197967194298797, 16157555793424861524, 10929371590994640255, 3194469143425738352, 6651586784672005225, 11062427140788057791, 6834443579468668318, 16421563197797455922, 6251046422506172884, 13952303462156793860, 16632486601871393224, 11313454360291325172, 5587835232504462834, 3105197524618514637, 18268568531031972989, 2397205535804309313, 59413027864729597, 11869878125348715710, 12592801707270523266, 8070632061321113656, 18403647807860650811, 267109013517069093, 6537214311028855260, 5220826919973709902, 3448740582779163661, 16822239213112884941, 5975299384311048185, 10294433804430712138, 4739856055412448774, 12057273038326387897, 13119002941950056609, 3354445304051737058, 13592813067499314594, 3890182464434078629, 17820384357466425060, 9785228118969879380, 1778431746734556271, 10075313876350055029, 13994048489400919028, 17948287074199726448, 2815088342305858722, 2676626035777198370, 1174257960026283968, 421714788677]; const POW5_14: [u64; 298] = [11471884475673051137, 8902860357476377573, 13350296775839230505, 10609191786344608888, 7261211985859587338, 11439672689354862964, 16789708072300570627, 4607056528866348430, 3202978990421512997, 2024899620433984146, 17666950207239811774, 4233228489390288200, 9137580478688460738, 4060411066587388546, 11119949806060600124, 867715462473090103, 14382394941384869610, 4856042377419278489, 8265605599571137921, 538981667666252469, 4270263388700786523, 3281140600308898503, 4121392524544394174, 2077884106245940229, 9773041957329767574, 7550623316597646685, 8611033926449791714, 18137922955420802793, 2796546741236224013, 15477096484628446761, 9517540128113714010, 9471917970500821378, 15938570248662483124, 5228016831978462619, 15720991252586974501, 7662829825220776698, 17328310068068434348, 3371736428170309730, 3803724952191098855, 13115926536504376719, 16752571196153442257, 16540185467776259880, 3432518182450051120, 5880364967211798870, 12355748840305392783, 14196090758536469575, 7370123524686686319, 6819740424617592686, 13037938013537368753, 15029273671291927100, 3671312928327205696, 7473228676544792780, 17234079691312938123, 14164740848093544419, 13169904779481875902, 7179036968465894054, 8244653688947194445, 17179797746073799490, 5591970751047577674, 17530550506268329742, 5965746721852312330, 1604149463243472865, 7734199791463116918, 11305790396015856714, 4441196105025505137, 13046431581185664762, 124776524294606713, 1134521334706523966, 11671728093344476434, 14103440020972933148, 3966727403013869059, 9828094508409132821, 4355682486381147287, 10261407143988481234, 3800455155249557199, 12700901937937547500, 18184475466894579360, 13267691151779895412, 4714157123477697445, 10770360171308585263, 9083344917597998040, 12078649873810212155, 18218989082046199377, 4454285072780637351, 5287307245618354742, 16042289702059031730, 4131926574212754010, 217692071448455473, 3624845916216282093, 2901203491797614218, 6679177724033967080, 44561358851332790, 9094639944041587162, 13690915012276084311, 1408896670826320686, 5359130319612337580, 6148412925099835601, 5211368532286409612, 11386360825549027374, 16895182466965795071, 3392940493846427241, 438089879085393580, 4783928372776399972, 6278117363595909959, 12569481049412674733, 15648622492570893902, 1966316336235305115, 1603775390515993547, 13576113010204316709, 10821754650102840474, 18198222517222903152, 6966163076615302988, 1373932372410129684, 3285839581819684990, 30177575069719475, 16447047871247307061, 11618654126674833808, 990072222556306872, 1260682336135768017, 13862055046689532489, 15668483092844698432, 1879572630092764264, 13912027797058626108, 6231679788219816920, 13857858054844167403, 18101470072534728857, 4144579812461609229, 7048589655616599284, 9946956499532694630, 9771303850109874038, 6477823708780339765, 17526247621747041971, 13525995675852669549, 3928768291901239810, 8094153383078124544, 11214278667728965552, 11251547162596832610, 5964946855123292381, 3622548288590237903, 13469765967150053587, 17798986288523466082, 14684592818807932259, 16724077276802963921, 7119877993753121290, 1864571304902781632, 12871984921385213812, 9065447042604670298, 3987130777300360550, 6890545752116901685, 17275341711601865750, 6296474927799264658, 1257436973037243463, 13854281781965301421, 1657132483318662716, 17309399540017292849, 12808111630089217242, 1098489625264462071, 14010458905686364135, 16134414519481621220, 14288255900328821475, 3469093466388187882, 15982710881468295872, 4056765540058056052, 15945176389096104089, 8625339365793505375, 12316179968863788913, 15334123773538054321, 9536238824220581765, 16080825720106203271, 6235695225418121745, 12035192956458019349, 3235835166714703698, 5348960676912581218, 15315062772709464647, 17335089708021308662, 16855855317958414409, 2369751139431140406, 3693542588628609043, 7350405893393987577, 17402072586341663801, 7007897690013647122, 15671767872059304758, 9259490518292347915, 14836045474406130394, 4654005815464502513, 6487825998330548401, 7013356660323385022, 7136200343936679946, 15341236858676437716, 3657357368867197449, 12621075530054608378, 5603868621997066972, 7683447656788439942, 450883379216880060, 14291494350184945047, 5466258454997635048, 14206933098432772126, 4775870327277641692, 1864430798867181939, 13748978265070608793, 12250822864261576589, 12561896977498605296, 16060949594257359328, 17775189113543311529, 11835965177892927035, 4218664174878121437, 3499000902478111683, 15169853304359126294, 7076121963053575143, 832652347668916805, 1292148207755194737, 7556838978364207852, 5904021986723518500, 4610244652288570024, 4526508363195533871, 746120481022614726, 737965197247830486, 4006266184415762653, 9272188239892688050, 15346235246415709678, 11850675997347533184, 11181059668610842701, 6687857983250662774, 2908718488661492818, 4828337780126983225, 18071738646453002184, 12790187227727197880, 17602483480871623153, 12523532189621855977, 10598805712727696716, 2179787555896149376, 2242193929457337594, 14908923241136742532, 8369182018012550027, 13385381554043022324, 3332327430110633913, 16138090784046208492, 16172324607469047339, 8279089815915615244, 12872906602736235247, 10894545290539475621, 15428756545851905023, 4155747980686992922, 4074479178894544043, 66083965608603584, 13873786284662268377, 8861183628277687555, 12119497911296021430, 2154012318305274287, 15490706314503067312, 13643145488710608367, 672340241093017103, 6039493278284091973, 9679797700977436461, 18070795828318171174, 2188146431134935377, 5247392385741514952, 1852539214842869734, 12235621681634112739, 8812930319623534062, 5585597406294108629, 11312989214475901864, 1547377291787797995, 8641748937186208205, 12518148659168623694, 6611379197521520985, 18096591571068008576, 15087021227100112139, 13058454842015958418, 1473584652966833794, 4387660670140018168, 8452836916843525402, 14376083294443363955, 13998026203969090659, 611968444648172645, 990232438801273845, 18001186324715561929, 13470591857250177501, 14881554140239420091, 16696367836720124495, 6328076032778459673, 17027497695968504616, 10192245646262428833, 8282482589527318647, 4319014353374321425, 14134087271041670980, 5060230880114618599, 13179509240430058600, 3903514232614801894, 17774749744702165255, 15448635507030969726, 15983775238358480209, 14542832143965487887, 9385618098039514666, 14431419612662304843, 730863073501675978, 16750118380379734815, 9640]; pub(super) const POW5: [&'static [u64]; 14] = [ &POW5_1, &POW5_2, &POW5_3, &POW5_4, &POW5_5, &POW5_6, &POW5_7, &POW5_8, &POW5_9, &POW5_10, &POW5_11, &POW5_12, &POW5_13, &POW5_14, ]; cfg_if! { if #[cfg(feature = "radix")] { /// Large powers (&[u64]) for base3 operations. const POW3_1: [u64; 1] = [3]; const POW3_2: [u64; 1] = [9]; const POW3_3: [u64; 1] = [81]; const POW3_4: [u64; 1] = [6561]; const POW3_5: [u64; 1] = [43046721]; const POW3_6: [u64; 1] = [1853020188851841]; const POW3_7: [u64; 2] = [8733086111712066817, 186140372879]; const POW3_8: [u64; 4] = [9241971931925084673, 16454059005556024164, 5253045282866540271, 1878]; const POW3_9: [u64; 7] = [15136703003180987393, 8476343899828878673, 18361811754143825027, 14388418858783342465, 5401376488135036380, 12364567666609403030, 3527953]; const POW3_10: [u64; 13] = [2118395047680534529, 8537117469025143052, 3872259360504933309, 10701526949532696147, 17998776526579280936, 6666182382162752224, 2298937609138591600, 10431735398056406321, 16375030035869515722, 3789847405179292381, 16253248952895454123, 5013447294207740028, 12446457099674]; const POW3_11: [u64; 26] = [11359380750133874689, 5276606518746106582, 8074516225493162415, 44091562328298894, 3624566612640262530, 1648712055576603746, 570015793462054116, 4997922052233515184, 11461456262225743338, 3703749129909374618, 1032298853854876563, 5055703740018389007, 12165799951080916707, 7876242724076368176, 11382490680713659023, 8012668037354425323, 6455631446982530500, 11518146109761638553, 14211686304453726670, 14638327231082858575, 212706140070406144, 18114182620365251442, 16255881380360420802, 17396653870711483704, 13342545167648199825, 8397920]; const POW3_12: [u64; 51] = [6615629770586038273, 14589289854081549156, 16033283353414803848, 4072670504909965136, 9285202060411609801, 3844375208352343783, 14457341458236460110, 11113571593891798513, 6897806051678254736, 13754726319538359186, 6705168383790534776, 18424255276769215806, 9125568036581672334, 17950439800261239652, 3360019889600789048, 8736970908230253200, 5862837180794632907, 4685996133977145346, 7012924617285143305, 6946857363647229985, 17278143000252629097, 8632720555983218073, 448178319842208351, 13359710428804700555, 13363983887301643254, 13693315286110143380, 3073162922650220325, 14844710205972612777, 10236141098283186080, 15546300905171289287, 14991733718586000242, 12916696994748984595, 1335788671178492970, 8288858105892413588, 531597803005806362, 1424346394172629150, 8721143616286912970, 14331896312442271549, 3043145014208270918, 8340447499879054696, 11359259714499294398, 8644862996062775644, 9484939289239162819, 13589880770603801564, 15411917558929121981, 4327480870720673885, 1325470906085940108, 1949446308450023420, 15707488697789413385, 7670729805623044772, 70525072474845]; const POW3_13: [u64; 102] = [17686697579142660097, 6835527964327392632, 519141719648339438, 10915724132684181418, 10525094883897927730, 12931691278819523731, 13609994346461817211, 7792013918408689767, 12616283906737735258, 6152585453049961975, 18093218868158061242, 4597585598518975727, 4540690555621276154, 5146752950888563072, 17078008680493976306, 4940054416148051507, 13292642740797593673, 11433236470183933650, 1893271136554408208, 5395175136028342217, 3377431049116564971, 16414233592433497551, 660190863912874689, 10191500464313104710, 5296767785184324219, 7017570247774576725, 11906963227774686324, 11523256495834484144, 17718039332649552444, 18203074682319783749, 13063547705319384019, 2689214593055349782, 8872984591015716038, 13295405780899799222, 17955349892186737306, 18377333322072047388, 10009321763381733263, 10740619310679053173, 3678366978495582488, 5386006412549914107, 2939999530005680313, 864350463957430877, 7134876155463612350, 12859539885231597000, 14622204113412710377, 8487354967518133412, 16893752681799589394, 1861455355759609366, 2215078177635153677, 12328081781789258814, 13512115210914444970, 12467125683110614132, 10809819066795130489, 10302065192562501784, 6333142106738947567, 12227363843828271581, 4911642960325424181, 4922686570288394259, 2904259931365432466, 15017412742290626787, 18050457076260269306, 7789034218973547683, 10100531119715750776, 6151136088165477097, 13496448062567072853, 11179514145292123821, 6834256416281897152, 6315963086107973635, 7916218311420134351, 4058636906137698771, 612677900085674499, 740390706776619056, 15913061541915060609, 5625318012611030298, 5492469315252333142, 1787499506659871564, 13130972346797301907, 17139036276093329309, 3129806882433428008, 11801555561087648421, 1337437552933432854, 14393715939936689772, 5075982616701483039, 14146728107994341104, 2009717676181581254, 6499370409273010652, 1614287946020752558, 543465737531163540, 9981569900494582018, 14819783240964814582, 3413474580476079436, 10254490513920293241, 15716828194058191719, 4496048105227602492, 9117771791529929093, 8598172845056620230, 10788533399188821370, 6549281897122335588, 13437155476602347060, 2738314500086357436, 1315507096324862908, 269629471]; const POW3_14: [u64; 203] = [3014151301029068801, 3368717210500941014, 16526655043858351280, 1570922329624414208, 1659387501763276584, 14746156693680335077, 12991990277270429286, 819557268048782528, 13315632618164850296, 13715274206880838717, 17320008985571678455, 5772178420050611091, 2836253575397763676, 7717380670411115663, 2099659576414294503, 15238056155431820065, 12367761437621511661, 10877305759783841876, 1225050232812614950, 4132971589311606454, 3487827946854483167, 8858594377116303592, 13014169932326731571, 6586799248091633642, 2908467343916459689, 17130644458472461229, 11990926378323331396, 7443957075454662896, 11344079546287445306, 6894950762728195350, 1686251346332844224, 6646110915587688968, 6238314137953262194, 4464909969120699941, 14286719114913530972, 2734304957036558979, 773565632958560255, 14242527207621083408, 14447328157991647975, 4816462262218287249, 14117383283175832350, 14908821434818589176, 6568674307664296350, 678284794617743431, 8334193628813726431, 9581059312036536760, 3383333089665701405, 2303925959357643449, 9136900775437373797, 11516055338615503912, 13559451120619030647, 17025355858086313952, 1910167349182142859, 16525896153568708881, 17714211194627560821, 10810197653235829756, 7452461128358501030, 17844611896374050395, 333578009178998475, 4628333967402862148, 10057732281097955560, 15569406586116356914, 4118001685045222295, 6935172110078815123, 12967793877761791179, 8817769094107007808, 1747043335436027338, 15653102610442392714, 4502857681038835401, 6487866587498327385, 18379297231463588590, 11533941842543278284, 13172688588106291155, 8469492863154015196, 6805786336069511037, 9261430062346425502, 9474322044812704055, 6999972495444113671, 7013474345268902220, 714098888039517700, 9579110838306604082, 18056640044808390108, 1403980188111742434, 17430545075496543804, 3391229225121147510, 11581960744638707540, 5557076712965167319, 14374646898589421993, 3074971570627478236, 7522848267109877585, 4851002149225660252, 1149011036220677837, 10860077460801552088, 10030117995774642746, 9800251505364265802, 12263726642788040500, 8880913180594270442, 15211874648317416291, 7160134456849478774, 11477475544166228321, 257207889078646990, 3305183774411918594, 13048234133003633760, 18097110596628986519, 12591826257500422975, 15148251536720461410, 16843770751005933355, 11253961878990923156, 593780973732575744, 10457383791702173304, 11986258352615194256, 11413384508803902693, 12753714256533469971, 18436679404309801714, 726019101611306918, 7258345777840499664, 5032958293947934815, 12227080935754030974, 13887924239651958077, 1400265616991034855, 7085864794210057777, 1240279560360509664, 14067798200534308237, 9797298435194605689, 7723185714118383600, 4745023082819817852, 8367408728769205959, 14068664393588123867, 7743596177843306725, 13881494215404370022, 5857917740184736707, 11774638389823353270, 13335039482811683472, 5448496090214748403, 8169443631504709398, 8923963461059690757, 1420236601460646338, 17175265161397714, 9419779367266532198, 13740545339430881939, 149551661811372044, 2134178529555318188, 11862173939403040776, 134962647208871982, 15812412501213249693, 15500965737260495409, 9091597338111703767, 1402601351158315376, 9678477204323131251, 7123714578778314639, 13419443329419867216, 1626139390311403400, 10670527174588355677, 15613942385335190283, 14866028981683790327, 2875412637795392250, 5545700603057473186, 3901369409833122233, 5041841700261093720, 10236452968877155790, 3361723130076326542, 14087286044445658952, 4897068441082356069, 2618207670852915413, 2604225553110898515, 14226665567951584750, 12441492392956774230, 11464430628227911604, 9999109980159956095, 7322975638809513305, 13948967581531822327, 16002355077850659557, 8999432336483894258, 8650590966026907421, 9182164374843588426, 13872899150185224091, 2685796546452147997, 14968944803847985245, 1671197773218265345, 17072901215829183054, 11825035869843291884, 7589981082857893534, 1366317217152210935, 18341163110247053099, 17449546387829746903, 11088612001571320736, 13674344207423319935, 2545851539157564305, 454005134127827820, 11490672491862242506, 17374998876632719106, 728817640684130820, 7986346026335789287, 18271071587538933317, 17636118140819937104, 18108284073799426945, 8364244323095764194, 13281114514187980951, 10491295715437014665, 1310444496377544831, 13888191830922343152, 17586897146784604748, 72700051670196435]; const POW3_15: [u64; 406] = [2857149036689686529, 14175379900903675190, 1401520348671872501, 16234776120238177371, 2962701845019208792, 10297908473583313655, 18066235025537403509, 1985963752685589805, 15624639389973621271, 9833928866606755125, 17745402233238635630, 78130099366186161, 12083669796004842145, 15173692294343262744, 9518028755097555228, 10655057306492369587, 10897270467574297527, 11548904126095768962, 16262733627336844205, 18151767593952348763, 950464694189644815, 6291554747973611516, 412611759298967463, 5131078896100319781, 11813629186150778579, 4930929854592610956, 9762646238078359535, 14151100457737951354, 9708371858765635341, 6206831854096772214, 11595187312349610475, 6063894554553047360, 5433806591902421653, 15615131202940708890, 5805566002014644475, 4620768948367927720, 9055048231872307321, 14794281338878642100, 14491705029677010203, 7725284928432884786, 5045913831328676711, 15521729565232894446, 3262592488400695957, 5860761651758622952, 15030937622342206574, 7453984232973937363, 6285625393700329290, 2465144476302674710, 8540406565562185120, 2124606755425251207, 15813845962394172633, 2477333097123117589, 8683731013287375651, 15551597013896998911, 13605714123740057270, 14643891956139000479, 16971916378338524615, 15119653078633321114, 7493370147962291677, 2678804130241001593, 13413059027227613678, 6036771203292121206, 216244970876952160, 17611436704967980222, 3304742578256495637, 6927085775538733664, 13315658962419865452, 16461637478880332520, 9159263971826645462, 3913462873965369515, 17857254079665575825, 3797276440638589676, 9647428625542802123, 5854328892645482296, 2742441761432302421, 11225733082991098542, 4731412809753060685, 17545245222905168693, 15240998744534217754, 17088932600994765882, 10442808830797594267, 11981042725675971866, 644023621331554282, 2253594321603903465, 13252024675441680346, 1124873775965929306, 3874314155656849983, 13892797440651273602, 9163903989027282919, 5017350417091981181, 11170456011312851663, 2813559808584014328, 4116812115518818307, 13702742319649213141, 9775591519475943926, 17735958355304760612, 3093666990666573256, 8423586328399094843, 14152162489874533060, 17134035917593418065, 11958464969389092154, 18193330560469652293, 15521397355562956835, 10283106949839764045, 18334295958623800517, 14145932412602810213, 1816204165436187296, 16755091554444271862, 13461743902646297942, 17785198157821483501, 999714903368483550, 4677242625481985221, 9910022434578132564, 12025413185432583859, 16127703755272276818, 7453627110909065543, 15703566422987747137, 7272822243903333886, 1972484455033885611, 5509585683682809340, 12514075252383283443, 11015910612262455107, 8794620302298645693, 15766428415367493519, 1711834399970520693, 15301284329794636575, 15049625973964155655, 15900259345481470201, 14664694545501816077, 3248323624137027632, 16327026424974928165, 17676983136848424128, 17594845293034422036, 3598462360111237297, 6164837332473491363, 12557690121307106283, 10109939069437709652, 12800775096878587589, 2264928308272583125, 13933925261096421472, 12872763176208350745, 17787668368194830187, 8570604642865953441, 7048709692658599440, 6754336151043341637, 2767582648225916208, 17089211422130615505, 7566542657417605506, 554454622829143337, 13636006234823920274, 10978927532226055445, 13620824993125744831, 15598312988352584692, 11333363185755496030, 10691411377887685123, 9093362498010697430, 7394222032753075205, 12497667692881492128, 17276437181405535039, 1967499791420895192, 13091300736258632381, 1931999432125026959, 18101845663395832750, 10737028481523317251, 12073559789498238872, 11600927278876301021, 15394915644183372245, 43690149765302700, 14536830506341517937, 16343918510091159741, 8885672906893606987, 13181764654802828998, 10684690211700734804, 11732832770256274611, 8091692846200747000, 11734231950782980792, 11641113657779633319, 6987987564428180688, 6088231683739768666, 16987580781422859898, 16746734300109643009, 17453062775533821932, 17841203839200805944, 12973269137781883020, 6739230905854879202, 4867603677078590158, 17071942355573399551, 16746958632169604933, 8042500730691203793, 1396863806740074599, 6353513291046703412, 17389378324433898655, 15224528156400861908, 14940329842914752037, 8087738209487611514, 9396976871403877261, 14675994089300772146, 8819403867934322505, 13266609157024508919, 587689721215471106, 1703005196134536966, 2562787762183549728, 2313037854415173833, 7657340139746646222, 11564317508629152862, 5177906634388746083, 13192072273283457007, 2386777937402525559, 5375420682092016494, 9601947856602884550, 12680741746175106873, 2647294323878177901, 16035270017585634300, 12640401596289815949, 914437713487483877, 5090403726355275456, 15014595474028671514, 2867550296812809867, 2226773502982296943, 11459138565640924262, 8011532628562544869, 10500265492658359708, 15678123494779554117, 8506283525418128192, 11555992027763787680, 16095828519246415965, 1780456502835650762, 14603503648175969311, 1023585434351191123, 7484428532864560132, 18418291991478309713, 15357998610942194121, 3327605184344835340, 10435521103325521382, 1462713553537928150, 17423946492822110088, 145809024559853829, 6485054502148338297, 17099341458460775434, 965188172493604392, 5942702139314563916, 18106401177866486041, 14227718483166825836, 16035001229177166090, 15848711243740451176, 8774453998296083694, 11450427090259705369, 15573232951905096870, 6377903469683679142, 4261188984466607964, 11623123875989409090, 14415088741163804951, 1599813716942485968, 10604599897062500857, 2841830536040670623, 17828418933022515783, 6008046665831459714, 1978729563784647133, 5039099535650143903, 1599933062843895915, 737781630230469889, 11776024369682400535, 959346849988973980, 1671320449241372282, 9374282794778072195, 5383646033852945261, 4082887125286827160, 7536093557609062578, 3037527067803905260, 17427494077634156108, 12901475821374563281, 12032057534999621592, 7153754414806200017, 11521738428893480789, 16840132959828552310, 4951031368936021383, 10312972927109338281, 12434164894986795920, 16556791237464647839, 16220041076205579133, 18066959170754826181, 16064639237569846742, 1869073155250041058, 2420881339938507528, 4916480328379338711, 7578061351847790663, 13718055631926778314, 8732707385537350434, 17405133998566250365, 10371421237885974483, 6574583501129588316, 11300582933137231603, 282635628756722916, 10023070438431334382, 14272941146175213443, 16447365197670601414, 16041672552242935265, 17831407565973892034, 4182576405085205587, 11489328974408614647, 5035552335907170388, 3828974546045291137, 391913277838204438, 2817165455206460849, 11037533297049178580, 17170762779897421063, 2017484446390904666, 9021271920363221672, 11472693518105623921, 9501309554691385430, 16285283824493093188, 1703905920124801556, 11903037454242217696, 15395241027612287187, 307954930251028486, 11285734998298085507, 4846482603857718635, 2932055447754077719, 8481968243191684346, 11872001756632486481, 15833458741916767589, 5344561634374332691, 11307041361145532568, 18098034837345724832, 9473471699261927345, 12738480131881003004, 9318308383069160161, 14437880034370135329, 13965001776697565794, 17220068391430406293, 9769002565592045026, 14598113333382548931, 54463427733913003, 9653310437927051461, 18160027269831575495, 18079344490948425895, 15649431771668008954, 7638725635058075543, 360487819896943426, 18025371643700939561, 131193844645282412, 665347044270411237, 6051870096576101338, 2265594749826975374, 8499902357104734534, 11652571364819076154, 14239292171532033618, 13665821847127328442, 8018875021737294176, 4362889439394542905, 4780760689801532038, 685326272505554135, 852503507998133134, 237435172021779198, 5647410246788877101, 14902909516438526300, 11561729043595838984, 6580075114648231917, 3157148098482255540, 6292052703844876456, 4748907769001459290, 2759798991985961249, 15886889339845481809, 14517196801294293542, 15634118355276978734, 7602021282687142333, 16412875441962451500, 859131100574205952, 13679947396837903063, 18007510132633611780, 10281782328503563318, 16806051588047700661, 1764784474925535298, 5132268748786976403, 14007269090915984241, 16228556843064665646, 6786619220176084699, 8781872344617115798, 14818695140861444492, 3803689984658392692, 8867348272163989449, 4445582801996948090, 1814340225932887761, 7442302284644936579, 8934573719166517466, 16663117729942253798, 1945493944851571756, 6242849097309870753, 3003858696070588705, 5554724178452783697, 5784523079423192636, 16351163808549131589, 13851169259806597257, 10400584659272711720, 13517990180283491305, 5411389055160485541, 16458469570767121525, 13029575019242449083, 3390421090671316916, 11145730665637945625, 12769842855787723120, 856643283237865802, 3377708198364687594, 11148540603251120001, 9392475753388252485, 286516552283168]; pub(super) const POW3: [&'static [u64]; 15] = [ &POW3_1, &POW3_2, &POW3_3, &POW3_4, &POW3_5, &POW3_6, &POW3_7, &POW3_8, &POW3_9, &POW3_10, &POW3_11, &POW3_12, &POW3_13, &POW3_14, &POW3_15, ]; /// Large powers (&[u64]) for base7 operations. const POW7_1: [u64; 1] = [7]; const POW7_2: [u64; 1] = [49]; const POW7_3: [u64; 1] = [2401]; const POW7_4: [u64; 1] = [5764801]; const POW7_5: [u64; 1] = [33232930569601]; const POW7_6: [u64; 2] = [3475709467328330497, 59871144]; const POW7_7: [u64; 3] = [1843124298495784449, 15437065083437528094, 3584553906430408]; const POW7_8: [u64; 6] = [603000588348353537, 6625227153381996056, 14457317603578335302, 17567483729823316726, 11305168499310630393, 696547133562]; const POW7_9: [u64; 12] = [582341683539466241, 935252957464965720, 7598000487062652093, 4625010431675930147, 9224048018587399532, 13680868751916767356, 8922574898880355762, 10713662064272255971, 7311846544833571521, 7849590305058879299, 10093391657513723873, 26301]; const POW7_10: [u64; 23] = [17388776497041092609, 16457160058211406920, 2033260851521277314, 388183302058992872, 11702388862916293188, 15587415680696876522, 17031101678673454097, 13546772628478348863, 1318818236829654072, 13546125121584063508, 15808600474458000559, 12340053761285050049, 11573725793723298554, 6718505878150856626, 13954243453614827806, 16457462685960267285, 4074042241940842542, 2459465861860456148, 11372976075770768963, 12438879223211243738, 10907291956159364375, 3922778149643709348, 691771383]; const POW7_11: [u64; 45] = [17893919801682124801, 3206805966542412074, 991339494089278143, 13206340436150790646, 18033625394386074124, 16458343404181418861, 17068682823623086914, 17404038974574216090, 962547594831857602, 3798503919189056778, 10868579965491865695, 16037596885066557690, 15650701519890368734, 5316858967346585573, 1294049556640001754, 4351899201987763235, 17272889925200789554, 11628357220856409746, 8183184337517765892, 5628381843664522578, 7035887794254973747, 14841513942105928626, 14335113033987904456, 4216971858414870684, 10046451271544515515, 13714559003201406195, 5538475528829426789, 13395992984114831599, 5775212483408605146, 476243820514366277, 7043979434395428305, 1123299295821096769, 13048743086067956097, 17408198213811270998, 14736127160480877037, 9928220036139807386, 16675345951754369649, 18412518348195034899, 6406425587547789027, 4882575999668915206, 578900299059747925, 13250083076538589099, 2094116887459461474, 1275645183894667687, 478547646631948910]; const POW7_12: [u64; 90] = [14704542522817822721, 1908239702443586382, 611332695634661034, 16935085395232124524, 17736127977087465434, 11574241301399055267, 5823027105340961300, 17867009488740981351, 16348656808471078139, 16998423839097420228, 10609591466688569109, 9321504974414050525, 5278480101560703961, 14020203188500303776, 11864162492233692889, 17199512118478259021, 11362092576628354485, 3847370898204590091, 17126288518479724521, 10795558634415719516, 18062350854860133613, 17815499380630351463, 2397880943408320835, 11957809306317262075, 4223055476074955396, 16895069142623741217, 1458414023731884738, 14478520812823555327, 4291320715420414322, 8514090496211945321, 17901716023666967076, 14778482251275665363, 14165811673627054156, 9738219091708628549, 17670530737779529126, 18441890196349229021, 1430517926851965919, 4257604772280009255, 18025184073054564469, 9432558672249582826, 9643577683709596315, 10555481450221114804, 13124478177775831576, 11646845666206872949, 14548406571586152881, 141151896422981225, 11467171836679354650, 17545012642488291046, 14398743913477952771, 2888950879284581693, 13666904399237409328, 621695337355461794, 14166552457800910289, 10954834507641183898, 9677730810104475487, 14676264575249719435, 13008246759944130819, 2030706501610114848, 4897055351795194734, 3524240815322299211, 15993729733810538377, 8348875806346627098, 3621970447188199522, 1936527222884678993, 11992365621207994256, 8378409427045537486, 8371521441088447597, 6461957056912354693, 7577499642046353006, 17758468389980924503, 3665053575154184649, 17632504112159264165, 10287638585991044463, 13453018864877752149, 4986048915235721371, 8010577477677231093, 2566753874256716720, 13671175792596478465, 17399823534959146233, 657911218850639068, 18403822336734148495, 12555610471455063660, 14201739888607579522, 17742516903898228154, 6520371116357715524, 8544760306369341395, 1180972524889679931, 11918607129691019839, 12571893800880669715, 12414540429568840]; const POW7_13: [u64; 180] = [12366296415387615233, 11730370143930056766, 13967732971866448579, 2925064822323435284, 2785615026663960457, 9074767406787476511, 3387713669152756978, 16330772840749905029, 5004347987740918145, 1315322498776660068, 7136573792949781095, 6596511490066652934, 15328400376800820701, 4151285918184437031, 2722109124645525931, 12584201001210098571, 4801451632388026870, 1248764704649326431, 12119364074365100011, 5640226822887893893, 2466082534073732294, 9376326909146947249, 12674214251527350139, 16419525458752860311, 13141399977808101994, 16781245260594999187, 4673558965977830587, 1543269790139155142, 655848619610515825, 4380368131434905185, 17202266790808975771, 9897556520474296144, 186158812369995444, 10839347090923799085, 12422346061322264189, 12643626675592297011, 8939459572447991756, 16206167192025569135, 10652787480640468501, 6293507708854356553, 10008288180717595541, 16701596280546434665, 2182825862847259332, 2628366503764667985, 15959170117175880303, 15836457939481202981, 11143212174727211038, 11639730631195478348, 8604656216563733850, 290257727157156575, 10867525394732332731, 1400886510665911332, 6854704422327140956, 3741927266393244853, 12592994994270249287, 439863710787067670, 16239578794168605549, 9640756285361877479, 9561104718740555478, 10986531952367003721, 5612089266456309932, 5109766922818154132, 520998779395183753, 4810560545866637631, 7274850324832478242, 17740465167031001500, 13265097944367707437, 5648511910982105361, 1926944453539713356, 12405754124125155830, 8383831105158128438, 13034264539550437049, 6918089257970591536, 8857928391173216388, 12676875348889552368, 13731113671766870607, 6771449918166076052, 8756654551140551959, 13379197087459041336, 6347547918949812401, 3387083920238887242, 14306112307048422287, 11912069810554218385, 14551104752625294311, 13417676994193582072, 14897938903565105236, 17289003445441078886, 15935491860024724266, 10923257555407950154, 5770216580172492402, 6250010055206710577, 7113183740182564188, 16387949281660169088, 17091421695475875959, 2131077906426403330, 13839116851521344304, 8864920085113370983, 6149852328935262932, 15032054729326966345, 4079272632542779879, 18150912544137753996, 492094719586834357, 17582232315280964994, 17578774863963670026, 12416216660796818289, 302631016537865551, 7277572050364799567, 18318206792198604499, 8336737834969626066, 11235435284257084219, 13892783786080704129, 7289453266695394602, 6929315969304750655, 12953596354343027301, 14472672948577913927, 15139745008459803490, 1690846238072387883, 4955216932099385961, 16619071707385308450, 9480481535671607273, 12515534283932537347, 10261619361996609982, 5697090213210413990, 16942391088215900432, 3390999434243588207, 10353114664674932485, 12517229326878383040, 9850781917386990418, 14517298494686528889, 7573739014936709067, 9491858137805457174, 8611651487447140948, 3780787470485496576, 1469333660036523473, 15295174784873008984, 12194577480964034719, 15876198610592501565, 18166331529585637952, 14741475852802803613, 12569037466157958916, 3196162541872941938, 7948233786967345628, 8512552754069301546, 15113573103827111254, 11941684798565771194, 18265093358547574369, 4518669510372598251, 6791752066809298136, 16474333814242830926, 13472661237575196439, 16203356457439450423, 9015295329483684690, 7515397403580994501, 9717515703166204916, 12803427964745774746, 9813636653104481782, 12164929818934127602, 6797386733521120119, 7357244105545916498, 6517689230155891753, 4494756087209765099, 12574450216721428114, 18229699776525499919, 16540416958523241979, 16954357825433621959, 4441764790640151967, 7692257063480708500, 14819052434666854628, 16539482058519341923, 2489420457360669726, 10401109589692597340, 6501853965608688459, 6084336442276895198, 7104159518497231396, 5906434163082579893, 6565487219660143921, 12514992069438829377, 8382345892383208722, 9989560017558404363, 8354906072397]; const POW7_14: [u64; 360] = [16097952260272357377, 13130180796874004926, 6337999946274631917, 7806454005154593237, 3964779689212281839, 12067020790687221530, 993348543337434128, 456722304578047521, 6384489518616540919, 13656542509554516712, 7615813412761653167, 1522890313695650550, 6769281955844232350, 9000627954716615290, 17654875012081329198, 15585242463663518376, 2540047272071862908, 18010502217122882397, 2469241273316584143, 14522992147677403371, 3181323347248219209, 7412171862387734501, 15605977390940193644, 13732110206561584648, 6841310912708667139, 16772078603097906642, 3932701771162534294, 935552481945584886, 8928472931851695208, 439487408254902253, 3742108558531046361, 7467399779969413506, 6927800424520470433, 12319531680218572262, 2207523306292819613, 9058935655454630050, 8955262245124164257, 1695674628383954123, 12816266506087942372, 7642227795136877890, 5713091426437903432, 12455780974352151992, 9028911734769248426, 2629919507522055962, 6568953920878807825, 6441922329987167714, 1380860427454155323, 5162485348867390068, 18120478809550583585, 3557167691094160707, 9585556561423086347, 11140377260415831834, 17643371617081948346, 8803088719882987190, 15962382442107137458, 17063152676566552748, 10725484034242195865, 15709290609547120918, 9776802977956060171, 9641939324093396328, 8372300427360498714, 16896521492553339514, 1605503625113386766, 6596970146048364117, 5436155145821996359, 6773372136735004873, 2628016400388274989, 6462447048395462393, 15868096675813489674, 12969626573711253525, 12950483435176918975, 2262901692170033777, 7884963415598533440, 11514901661896874795, 5535814518946402213, 16351010394775660849, 4484876175662512236, 12156236651679611400, 15913616290364867544, 6253994434725726243, 1772728943040970532, 804279014012107613, 10394176623936067837, 17767737320216335381, 13651623913537429051, 2760832717800206867, 353270184060837729, 7447587540669411115, 11497513406571887865, 13223393344293563948, 2247898226096490615, 9953276799822295558, 12096075571540599291, 1817771230343237672, 18102535593989929269, 6414926188696218205, 10016339272007016725, 16879061665801594136, 10460900921895064914, 11085671488685598859, 7889552591773559932, 3021854743891978983, 4085994113907715761, 10466379589806669773, 16349849026994454109, 17352762078141175596, 601419915748930655, 6447353073228970401, 17995486874886165147, 6929880376298793509, 3669860551090646591, 3398341264769132809, 2301312788782735293, 14326873820728993112, 6519275883693387909, 5473548873407647590, 3920167345898264370, 10811801410884101002, 52970438849003295, 18128409130392095377, 10129863895205347314, 8320617748635348408, 15230404138270709575, 10425352779147164501, 8552070433977403941, 519705666637954232, 8524877583558787805, 8793834798035604499, 16167575759687524270, 547353747635705358, 2262756621184939719, 5991353929532280027, 10912415421229507949, 16483292131039576327, 9884619350958591014, 10734315355375469644, 11800424964188469136, 12058456212947390452, 7155400162305206791, 16135411518688007462, 6634167420807032090, 18063622714683533688, 2507242405996740310, 8259021275432108422, 12945670728782439874, 7172905444644909244, 15489103791052285055, 10418690523421072793, 9204769224238674854, 2878886988929159927, 14478321813784184602, 6580438489841406930, 17945679376420501907, 16001168065175441422, 10474823731535765832, 6505883723032583832, 7017424349503470247, 10427343442585095117, 7439465121266744247, 16183858348895227045, 6358193713503525814, 12702498643321358765, 7249764850445241116, 5299649406322709021, 481501828002012261, 16048956593771133686, 18238268908149352689, 2277566368866221405, 2801572749363642207, 15845862264899617200, 9806493542549254185, 13171331383548694257, 17811024629638326500, 237728575869603137, 1584918033186942575, 3458405115991025486, 14927829336143853235, 12029979567201885941, 11399400825819059492, 358387370090724492, 14249854791490390116, 14532916569974861129, 1093408639155183134, 6783598018720378728, 14819699618307406559, 6367909722180635812, 14209671311977258244, 9896579481722863617, 2097705012534014475, 17121704697625244445, 3622230343497336042, 17774622213911132212, 6645830483858889425, 15059793628035953495, 14525066567216672413, 7768417859699468843, 9442783756696131154, 10120202076259726556, 7383621149031122703, 6307316201761002780, 7381462566569701037, 12682904768029991916, 10325096036426052320, 12053931381819278360, 16852137193270511631, 17828141154092460989, 15472958372898633112, 10685946623044136176, 7058161217185270446, 15506112215314992523, 2603405286327598150, 14984285679998610515, 13308782686743905479, 13572243438993310066, 496660177568319435, 11998217866928295752, 15399372022516591533, 7172311566126579964, 4293481005014510635, 12973099906887367644, 14248415487123492423, 932891384243788852, 3467436302278130377, 1247673930042538006, 15377855697395121362, 3784510218690412199, 8104799035987075210, 12519062381270051133, 5495005024645947637, 2351932853904283156, 6703998543967833340, 3216210641055977203, 13199727672684370757, 10456834212923237043, 1800869797916367448, 9936934404567432636, 7024904587990317101, 17661047131642535339, 9058291675122015538, 667783409113178925, 5083781129445930221, 3556923738989951503, 10613572322633589647, 4350359409101468309, 1457548242871789739, 8885342167524640344, 10316845847952729828, 3477511179397303409, 16925069634451263094, 15834976524338260586, 15659523818281901996, 7434857577782550946, 12147746899654987715, 5668413592721689665, 8032830936493279200, 13617876313652185522, 5055982689745543607, 2058351167232943793, 2384018411882861673, 18393412178309349217, 3595687859588011938, 4724338838262503762, 88487996285581379, 12419469004964354847, 15029405122247879091, 10453100248404664303, 11815875067107019163, 13318783922657172641, 17063328775103766210, 15995177957727858631, 3337113625236935402, 12011245583154484308, 5612520138869104301, 14552133026880633198, 1836785609036632505, 1675725092902144711, 6557967504238413980, 18157671856133242743, 13015066162180778194, 4821635839614725011, 14901336225477334385, 18051437442300357744, 4018581868209046319, 11380431028641919395, 15494488453762803593, 2234206949114687498, 10814654735415792321, 11032514027152029919, 12840164818300226149, 12632990531852126959, 14542578197457741239, 5574572814530813269, 9039317489618929225, 6638367824881589965, 15204500812328294053, 8449286298854092036, 5629551307743247026, 14315632672578784243, 9863340608758860590, 14498396372357538980, 17230627093216409991, 2126190059759121396, 7282436405282076555, 16334215958199140859, 9821866104444108236, 14166990661167317903, 17954587786171925389, 8053187639906305959, 5818126477269297937, 16703671127253274435, 3325631217918823977, 11257142347483193312, 8493323319788741582, 6769867770236249770, 8075904957237992496, 18333240141647668885, 9489810858494556395, 1268788742819741070, 8183052026303658119, 1119184389843976056, 15756092335594419499, 7294561540061076746, 11472189890655343279, 17991578536803490058, 11257374986136473726, 15978035697189493595, 16754225317773630993, 13330871253108412337, 11006252491451403411, 7818512327252827085, 7606858841874053276, 7072722004561541599, 7738478710728317399, 9037822280667238374, 3681607021635297595, 12842201535468213346, 11539966054165267631, 10371391190118416727, 13484800967140291487, 11638839644475346673, 17502514434053797501, 16599166471406440654, 11166751072013296017, 12143045417492076966, 17258176312463112896, 16619606322400939605, 6748801852988009064, 7995536363981500580, 16541527472806327001, 5174785509933619616, 12207954298427456142, 8409687532898307371, 12212456215883038873, 9096953697076456401, 10927914225841440029, 10425878390961569497, 17598390738945121969, 2285822102408734494, 2102052483318711971, 3784107]; pub(super) const POW7: [&'static [u64]; 14] = [ &POW7_1, &POW7_2, &POW7_3, &POW7_4, &POW7_5, &POW7_6, &POW7_7, &POW7_8, &POW7_9, &POW7_10, &POW7_11, &POW7_12, &POW7_13, &POW7_14, ]; /// Large powers (&[u64]) for base11 operations. const POW11_1: [u64; 1] = [11]; const POW11_2: [u64; 1] = [121]; const POW11_3: [u64; 1] = [14641]; const POW11_4: [u64; 1] = [214358881]; const POW11_5: [u64; 1] = [45949729863572161]; const POW11_6: [u64; 2] = [14844108096902645121, 114458013083425]; const POW11_7: [u64; 4] = [8905530187360357121, 14477147077736378572, 13888007700250411872, 710186941]; const POW11_8: [u64; 7] = [4224151863064040961, 6237037915502622116, 15440260407910408871, 16124569072210476883, 12861392671514593715, 14527596912204933308, 504365492236294942]; const POW11_9: [u64; 14] = [14683225950600899585, 11312468005203390341, 9315594959014972904, 10842970136224308225, 1914369411386100363, 2491852204082726000, 12175660300580967766, 9414158174000630540, 12609863281556590504, 6489400440241531664, 117114288086471509, 1456781387136959649, 15696568929021680207, 13790214074759729]; const POW11_10: [u64; 28] = [17600486957711513601, 8022606290278406200, 8640958398179583395, 17727316401753491127, 9575607270622255189, 2072190441612624931, 14325854535236213783, 497551600749624034, 17635779223843169228, 11641721939423750382, 4105266644234922105, 801313456423024184, 16053736676906551679, 11243631360283463029, 7169921231119155227, 6535002338168290033, 1778184524698444140, 12167119020684722171, 6902101552327136471, 6183212344232315579, 16617944419037185325, 10187537814409491043, 3362267959182336422, 9478890853856662177, 9803115284869262977, 16725423551793776493, 10485792092922498104, 10309136586262]; const POW11_11: [u64; 56] = [8731580401360089089, 7641087749022849047, 7459296236447692961, 9800873921581906937, 6192826691154354975, 9444147789066284785, 14210506877018498301, 3094172356842321099, 668845366480580725, 3492266118122964796, 96529364629869745, 9893346702623899520, 6456488582816735915, 8976637586268446582, 4302897655204158962, 12526727947551740113, 17609142381680809349, 15544966799867548700, 1677652516887693103, 7438076216237633450, 8863297770664404100, 733574942719088888, 6432836854270260969, 18134376405202473969, 10804596744936031921, 17290005223842274743, 10127841390384582073, 13369091202704950404, 6045733069692757935, 5722147506200683549, 13713918444041994071, 9823962477355305112, 2537590973225324990, 17042268964188673424, 16176615291475221624, 16581342866083396318, 14707859061892150060, 14591066112765904256, 7871331706807351047, 5347059669077259657, 4619379623562433285, 3503843082012409561, 10443929285777752234, 397701103738382164, 3313093769655934608, 17836661706065908393, 1889144565928840696, 13914569287880052538, 14298154024944976168, 12924825459066648959, 948817799025216192, 8692209791762933875, 13408375962285646739, 8887158042233942949, 611198328255130303, 5761358]; const POW11_12: [u64; 111] = [12258111188078518273, 8688564386083985456, 2156380122306077916, 17836377793484015006, 18361442090419275253, 7263790696386055570, 1670049922837400519, 5718650195652683092, 8163040196717364521, 11363341172428738431, 4064482683668480453, 11565560735215538501, 2528171839334464225, 15361436207937868827, 7465080434366412227, 7717867788307812880, 2823048072521719884, 13528041730992648969, 9430876728602908162, 3885208255168570863, 6535820119850281185, 4461599089176575727, 18041982256587994410, 7471905082286866712, 17020017326155742614, 4938075662850608137, 4035468853066340626, 13821921610284215834, 13862027701123527138, 9154509599241848282, 16850885539955883538, 12575377137436317217, 8571268533459053559, 13898318040337272130, 810664620423602705, 7969335010597002616, 4286298881463138912, 14997259924918624976, 8264946895082660957, 15789931679311731657, 1185140025365085931, 16660324801169803431, 2556207960654942928, 8388838178441726101, 17971511442791836722, 1518280446620680356, 14933763998487830416, 15420564015868786103, 15035815882331303650, 3724518200777626298, 16798103199834126210, 8974893138557648076, 730818289427918383, 8722780918440509067, 17929755918867537992, 1146683209954232014, 17785212432311993598, 16613266046652518135, 9037649691952539401, 6627873182884077622, 333349853771469713, 15362796262717486532, 13172781257678513446, 15673083917296920826, 9067497080000291947, 1713297178691202910, 17708109588198440330, 3651774645063594416, 10886905812677462691, 2482233135585461860, 12616350414084702971, 1579459710720933490, 14708964334113467430, 51472236753600047, 1907397188939632778, 276838364253098806, 18166561361752499284, 9673362683923931093, 7282286593732476230, 11482488857388653014, 110116388352099354, 11985755127714364622, 11919464636612160213, 4471064793063388034, 9010412767207345704, 16783755977228655765, 16705665948206142403, 11178584287994817796, 8461284996706700993, 12105618960209776400, 16759015816474315541, 14855883815494135571, 11403006415320021080, 17030720119736277607, 7322697049602247758, 8785621568590627019, 1275438746651414403, 2735203210542683179, 6038898933195588170, 1829254170735016380, 4959340518011265405, 12942229586997440418, 14265112482871021343, 16789129922601896684, 5932357378257598349, 7466966399014766989, 11895041829419269547, 336661255594001888, 6380615258116690617, 11483716500585653909, 33193246385947]; const POW11_13: [u64; 222] = [3808821441094402049, 13950047456451507757, 9798258156629946174, 15394771717186026371, 8402385358364424036, 10643620587084864841, 770025935782707926, 12646401765719380359, 12902529371099697499, 4713071912651158781, 12808907975759538373, 3611787448482999847, 10792949668135085247, 9819656912719149606, 10402648732215573615, 3099634234087648418, 1303996289514071597, 17202252306428860401, 11799438143501747880, 5290182064440021858, 6787598363645614998, 15524626330776708844, 17793027940762140310, 17004880507537385137, 12841080511592520550, 17802074978586652087, 8690205948794188170, 17021225369825206887, 12214371232481703209, 1944672684319471300, 12379112297018720671, 7908417186977849250, 2987701410501237081, 2038965172598895439, 6761749950944809115, 8931536425641523590, 7739113602339379737, 10276676859270825864, 4439920731860331975, 13587872298826297188, 10580582791203023976, 3378600784962670077, 11537395749888529099, 16813363578673814635, 7891172225344211285, 9350831321289342668, 5510229781758539814, 11084856245604590009, 12529226724027785473, 2772826409583854511, 11608215440244732894, 10561403027736810526, 9440496731290372475, 11187592866459075264, 18112121354970375753, 9439832470996749136, 12469261181704230522, 14584009432264737017, 192113371429651489, 6754460669087876465, 4530800811863053914, 463470628453220004, 6297950986641494811, 125594562797689320, 11035677947788700700, 17623708510179728580, 15775324055817623665, 14674109028438731929, 1209923272414374235, 15577884694090340636, 12570728211257605898, 11561061063357213891, 4651057686655763411, 7322712693448232647, 11809200609224415423, 2420420028580938070, 17006922394396159292, 9184515882701633204, 5031231983598943171, 3111072846816492517, 13024060130177495813, 8355932088208869510, 3321002394274404753, 6300461667657000714, 17747131805136614222, 2747653135256732076, 3505709525949287103, 3538610109129548423, 5420162045976326785, 15554801802738338250, 14489399518018827597, 4850011043856499047, 14310910444184822761, 9292252647602881874, 11707256297859066238, 11303830017912707039, 9094658840273999067, 10586581944556291517, 17960495918206643218, 8670610157246630259, 8653439255149520818, 7568788909374460033, 13873931190982173941, 15819535526777069096, 15029981376872693308, 13847545477117570871, 18220433945128351138, 8622564884841603318, 10831197658512299419, 3482858466220293205, 7738391096419399681, 2388165370073725310, 4358050862883070385, 7507790034085095805, 89269209394697250, 13562217700279342344, 16454409421097177328, 16005524809376482876, 15667251180569804396, 5575611494182542501, 10430834717129143495, 11659407253092098863, 4895499822409996600, 6091211079131464965, 17808419333800129021, 9570998286801415179, 5887752729029264648, 4894808089110649255, 264445405266933451, 12074768974351470228, 5985747285239971975, 8930452312045511767, 581799560152189317, 17941120742042728911, 15817196956092701708, 2343261090808633691, 408906981660082567, 4350888852889124580, 16977906164174597996, 3989397226896384133, 11797852548640146128, 2578312619770412510, 7917095819269751495, 4230379070581724230, 13126041898733797169, 16968484606411437981, 11317889594303192129, 12648840019394002233, 3111186006688328723, 10706649976093419159, 14466617554838031936, 17470352306889372501, 18411469382383403573, 3153962946118390326, 1014317017884139082, 9067463626083157937, 9196385543164920811, 18341966026070632878, 2053546991595525844, 15511571668352276553, 12964932464667812226, 4608057668984183759, 17979015922850588491, 15888006382316848065, 6191253953762183056, 17159783485185120772, 17513047285830409019, 10417270127383690995, 18067596632167697078, 6209418964215319558, 6733592007390738336, 4568126052283103779, 11355338046799267184, 15425201093814830598, 16990348514482983138, 9671568810535511308, 13106810235011387032, 10809291324792942232, 2571942032983045376, 12245280439867659807, 16489897181110719710, 411658004810086058, 1868460854412176896, 11032950235885186844, 6344640398962141871, 760808458165149881, 3306488977670562423, 6839411434812535694, 16468028338001386174, 2112092371815785823, 12646741262445324147, 9993358993287357353, 15017076939767283590, 1499021541653222206, 12262422680303055865, 1052978976587305768, 2525637906577367832, 9375682883492818340, 2656458953615313602, 5575528468780549633, 2205334098316854237, 4036086244823022446, 15332220321466312298, 15262584590254458024, 12408741965943962, 2169913035744765570, 5194058381386770850, 18399971040889575890, 146441422052474806, 5815392231184153485, 16047228440717103626, 17392719586815490099, 14470688503267233324, 3774976851959202265, 17522274784675477951, 1352849022052684252, 12432653384097243620, 5555774420231729718, 140146492729849120, 5751821307726361580, 11491634968064100927, 59728242]; const POW11_14: [u64; 443] = [4861448979329941505, 14234964374014750949, 12324565570828414774, 1324814589202696928, 607244302112676228, 1468893317251208529, 11822532846329079123, 1772747872098596721, 4408320304397308991, 179895444459060586, 17377293528146141760, 1714298375615180651, 13727398619163416501, 15410259826864896954, 7039628146162027211, 13698063942247679856, 9196351222540173809, 4207522375895023624, 7653694298972214729, 7081904518120937303, 18126762283091340173, 1302148257619410361, 2278020359663609313, 17275960804927763932, 17646698674846864050, 1061665203398398749, 6021343083513264083, 10292895744609000652, 13506325232783503285, 824481431162821605, 7919324098292802678, 1985884143083030766, 6027199192564773665, 5488984059843063194, 6401554277696298326, 16250265188100062086, 15461151778850686767, 2152095348062875365, 8568875091076248658, 11535118345773079746, 5457225141428596749, 18105156839686949851, 1446204699134367047, 5940200217327425024, 4723404657175721957, 11332495094309303050, 11210916865656261972, 16263615410279778249, 6583355182287363108, 3474139183894197613, 1175721547224620583, 10014270463271451313, 482451149736938829, 12654754310346753670, 12060907194253820784, 16371222874844907434, 13724874157976399003, 9122955285147480236, 2424368639689405019, 7087904929142059907, 14595747643997040906, 15968581825605881645, 17256763206331601495, 17481768017051479863, 4084534300439740145, 17098776779575199687, 8515782993518578340, 2288291991277446116, 16299830825136238124, 8561362796615308257, 11274137098972488891, 7192165600378860146, 8978728286869674427, 13923828547777691987, 5832039018973580482, 9837821197135420015, 18051373213910634026, 4637098454786810426, 6240800240028283280, 7380213381432486022, 10638615442398485648, 9542889592286395713, 533439917619070920, 15976474426279470150, 13617284272561781679, 10276288751212140441, 15218655173862339787, 6727164750656390926, 2230801314483879028, 10021252070973934913, 1612778788739111084, 7041336484812664137, 5291567855310821299, 10626676180760950806, 3659645323342341666, 1545507752301941771, 14519585472656231099, 1280387026359760607, 16199734190462799358, 8572516678011533267, 17081096972675348465, 18297685214062940363, 14723211966654587245, 8767349579514427244, 12568842691268661877, 10504581466359364874, 17983973018406970412, 328705068174436706, 2174559131771944018, 2855491391269045818, 9009166862880166991, 10878402612077551096, 17264107070611546538, 223351840959114071, 5747868541617443987, 16012440336833037029, 4274888826175210215, 5698113987508239659, 2810339290159470120, 2010651586206732346, 9076087548247923863, 17009418387669523776, 16557728273782932974, 18384489959436541655, 15752294227131384690, 6195553920678090298, 13838306873320407029, 3997543181277782696, 13632792040016317818, 10571440041344215283, 14876573291975049851, 3879865230527161572, 18236798115142797478, 13052196600916404619, 9251700438782427988, 10407452028375711369, 4538634364832492797, 8910999848840304863, 10343596653804926032, 15132844029119797390, 7864786558078627424, 4854202622679318856, 14490496116897594330, 1922939018516173744, 12791865105402661392, 4920230059241940123, 2446522703407379623, 2719058737904468525, 9999578869275587172, 4836000489857180559, 5994605752061867846, 15083412007297361974, 17908574010793699948, 8603146064853266860, 13282523391143325229, 7479701421185277336, 2826652990638591311, 9442860486471380906, 13694763927822677330, 4070864902063801545, 13509688881300716966, 3995509851884739921, 15500907961429706360, 9795626114514347062, 1571980437087492045, 13142893915917944686, 9646309683012187316, 8777629042773692026, 9881264653716081071, 8508104196538675869, 15117475129918140690, 16475891468886709943, 9503794508304165687, 14161558219184310438, 10022403343962581244, 774772164966805214, 362976409323838940, 2715006944996371750, 17694596407445297762, 1213888929410517115, 12040552348230620694, 10058036256970099697, 2256146506417247640, 18164569340587724858, 12721263982171681707, 15380531655246048023, 9194447864364357124, 1395189177546037021, 8859131669854344798, 7692997617889865194, 17678217856577248805, 5051283006520813772, 11882900795697794617, 5447764509551475534, 3261307948022048285, 7015933502359776047, 12399112476339008598, 16628161813791920281, 4466609504385759042, 11527239354824549320, 14896865012286473085, 7446357960840887736, 615295693915679010, 15420865078772261891, 15914776189073358434, 10427386017406062370, 443797358218834337, 5596975675103798631, 6338038437211252377, 13233769772475152622, 17775197412637834205, 9102894931534069061, 13353703773597231356, 944019229681291505, 8977246688627596603, 3748124351709709960, 3298771011254639, 8435566979418350674, 11851644920285863541, 16324834267757928361, 6016362057210517043, 11654330633207158652, 1370135402791183063, 14777157798210096039, 10776086879308252035, 4433322625034727973, 14836526024633985271, 4685352809016622820, 7408166577780936829, 15199466109466461354, 2211473805549433243, 10171842521951063980, 12827586232103031433, 10952407668210671654, 4933370584920750452, 7319841716061281131, 17603020551770387193, 4427023795533149004, 5760431258666948947, 2628001461433152159, 14147963620160221164, 16099616627752170074, 3327193394265296968, 5368283717218509624, 9241571475776324157, 15640746428336985715, 9487035580372452084, 17632705763587892565, 12736713781685959613, 9971589274082832845, 17168262626685135304, 414500848950060554, 5827338905593107639, 8612815215356362343, 668474300455630914, 4491005903555927409, 18378927420991026827, 10011565531712440040, 14065786654535912965, 15958324543393833014, 12112865839706180370, 1348635633866503714, 18426905119685767107, 594668133275684728, 9061562651652632498, 16967293170698280657, 7468586466608959052, 457321426013996781, 14671934119177120539, 1665947187370340545, 17062037043693347693, 1454458100651286104, 9177597526745466448, 2182055382421138739, 12758433655523518006, 11620001244104019106, 9036694130892191599, 13166526811205530424, 7969601211618561908, 10556629472960027668, 3038682221177727183, 11625506627928375388, 506754098530257881, 10840704320944236093, 14587935551799268659, 388433678147809197, 3043986931365819006, 9795384084862995819, 8687753689379869237, 10535103462454142818, 8396429594174113569, 18119088061758192698, 16481009488626485359, 12663196266720378655, 6119147888683342287, 2161357170291219501, 10311153247653876270, 14620598843548926965, 9239718912375357587, 12103480311318159322, 11635590630179821901, 6497644388597848233, 14536941038281688274, 17370698524274983270, 4054446082565130877, 12359766469096244508, 3084254287251620162, 11510691519238341312, 14048480973982759344, 3550446225178059644, 7086785931913740434, 11677224635326405715, 6131139509691824952, 3681904041476043764, 14346955711384546565, 17310238062338563531, 9260860885029083495, 16623084050272570307, 10937240502080722425, 15439315697216607631, 13475090244496674402, 18190235497085877663, 5274480102891558646, 4983822368450167335, 7000097594073865571, 2483077929630858635, 2813775331710572682, 816911581587374000, 1732149738726002827, 16039777340190112897, 139765720276307849, 17733651201482295497, 4609725426879943425, 13913572179659651504, 3059450630507556352, 14807014575446128996, 5569394288100667931, 14375498051354007605, 7807598407780865484, 569701784442343756, 51797670586037983, 9504686786967003450, 9217951525504177336, 10879341428667564507, 8843201496576441510, 6249217303036338976, 2464461876712416813, 10963802434450345807, 5156833682864126006, 5467966583136449663, 2176539270699150252, 7008785551069887799, 6632700210090622936, 18144174610076905244, 8104595025195641764, 8971441915667154511, 6011391662547105818, 3983263972883013952, 3886620564818691950, 16925909445790200563, 16003748304083263684, 1453919995355324282, 4260654273475685913, 18138606151029898826, 16699456612278458717, 7446480364777014672, 10958728156983022753, 5139828146590601075, 17653479006349068371, 7536076115681831906, 7607716607870617503, 14560876409314381480, 13158870719256372693, 12393118114934470163, 7771763481698298794, 6134690783315422671, 4024072529465038927, 13806427607287721571, 11252219171378906111, 6594350577506956860, 14743085644471785042, 2975981301153091444, 11808661777650285210, 17608508176248613454, 6115964025237033355, 17110450100769106313, 1462488821698087209, 3710454816741289037, 11109359605802440170, 9388771030799246581, 6092804038621777855, 14553243641565391062, 2571790254273754999, 13291052400737486800, 10642591906992584111, 1039612743225989315, 2516005090382757510, 5308033042682329050, 5364406318072353263, 9571296697887995083, 4342141404806216855, 13824528048124185762, 13124734456838244282, 6543442858705932039, 15653401468778309577, 1274442923177363099, 5127571593148750493, 14406107908112660827, 13330511805319483230, 10395540962184514938, 6947918551182283208, 8459432705439102169, 14124047457577169823, 8592300886547817212, 17271922302251148279, 10015402479770037483, 18049226981662995844, 14922839348994532248, 16771406244013390849, 12917722840054563317, 18368817445375692029, 16168933425046355196, 2047740251628425144, 1315137751888759163, 14138764838763486325, 825695092163721671, 3055436360940615263, 1492572876028562170, 17854804685161712323, 13963312285969121334, 1022428655137937057, 17304775861198439126, 14488691714775008885, 3559022074931400028, 9803967563486540149, 5840733631497687280, 17464660925899346648, 760781807011823055, 11138978771366153564, 4500147140213882775, 16894960700949132870, 13586419147412383825, 3567462966827507]; pub(super) const POW11: [&'static [u64]; 14] = [ &POW11_1, &POW11_2, &POW11_3, &POW11_4, &POW11_5, &POW11_6, &POW11_7, &POW11_8, &POW11_9, &POW11_10, &POW11_11, &POW11_12, &POW11_13, &POW11_14, ]; /// Large powers (&[u64]) for base13 operations. const POW13_1: [u64; 1] = [13]; const POW13_2: [u64; 1] = [169]; const POW13_3: [u64; 1] = [28561]; const POW13_4: [u64; 1] = [815730721]; const POW13_5: [u64; 1] = [665416609183179841]; const POW13_6: [u64; 2] = [3919697708568696961, 24003111985919145]; const POW13_7: [u64; 4] = [10962733054231376129, 4577472700600565796, 4329209982584479332, 31233120745124]; const POW13_8: [u64; 8] = [7163256066462638593, 7700051585458762681, 9519551227927472482, 7477692841487206870, 584696450287827424, 4658499684880148153, 9377132942246373073, 52882385]; const POW13_9: [u64; 15] = [5365041021046080513, 8568544766453320380, 7748416443152478440, 5769290248959972646, 10008377727041243801, 13198018498029413189, 18212266078933409250, 11009380506711076718, 5042359334083314982, 16169575357398556542, 5013820542687223037, 13258554444064024165, 10433479404760757721, 8005776949133303266, 2796546697052201]; const POW13_10: [u64; 30] = [15836836905661728769, 5552771274265787082, 8658814385343096072, 17318436243571826118, 3795751027676562654, 5758095269786646185, 2230268814104946217, 5649141262329647785, 9634371443283913081, 8399134031292750081, 16632839205091735321, 12189472608495961105, 16123638117585320649, 13018883090882067163, 13128986057192585034, 6769301628408492628, 474275071893529293, 8353132743960307191, 9424925663763685936, 5941010392587702928, 16609754696905747741, 469146692787701129, 14215249896965005555, 3399572096990812063, 17120890880503935024, 12388356583333619404, 15914200145625827530, 16104732014018090148, 16284305993513564551, 423959556089]; const POW13_11: [u64; 60] = [10825245909596966913, 5227565081833453221, 5437827865970514660, 2634626693930470638, 7791313698235985478, 9849032823460265468, 8279658923777232819, 2060596865702984494, 10239800468899970474, 12389871316412402834, 12015992134249231999, 15591767937777349731, 8968525305486241990, 15957056669959365974, 17622202978596432688, 2850992533279334848, 13911194238700387305, 7313624275157161214, 7248853985706563409, 6592847550342527558, 14803786781037723221, 15705891050791155715, 8133622017774493950, 3696503260788519228, 11404213207295227541, 7921238562279668647, 6561067286176262477, 12116294961236065547, 2266430190702116676, 4730219264323966605, 16311559478903934441, 15455930101545448941, 3852886984154041603, 1776228360455975018, 10515676917103608918, 769509830092784164, 169766357296013836, 9287163347439286595, 15898564984627198140, 8447546082614091560, 13343187541130294681, 13239159875550645207, 5342398021613563965, 11665491069175159155, 1225305497339060403, 13879701978218296081, 15305333355503561197, 8456975261344400641, 7180678784195069454, 5067906964941909849, 566505528766750768, 13475675598626116704, 14181860841192586270, 18312773713633166526, 10688355960935327997, 13023469697192509680, 11097116550631752656, 13159483348597556730, 15077689778296524836, 9743]; const POW13_12: [u64; 119] = [11058438542103289857, 9247248103457281029, 17336009740870029295, 10323468375289993187, 1504781354816836272, 9554730237366408854, 8587566550324569666, 5183476223015141948, 3643122171939706098, 18400384628963318263, 3572669864495390762, 4229421147935839893, 3552241799096742830, 1854807433957978561, 14028317535707552152, 14877222599659598821, 10945729493178143222, 1448781112948823933, 7767106363490107135, 16804445247893060870, 226424419111212600, 15283830687743071085, 1487797500753650062, 10333864616775077672, 2737584982632672862, 12625267193455441790, 12281734660947652817, 17217123806808760645, 10929681892618839227, 10865969385290900850, 3332334426668184000, 4883636421309900493, 17621565163257567649, 888697704683033409, 6000007989952325470, 8694648489794675891, 6439324098338385100, 5055535558537034701, 17439774471630192755, 1890751051615471174, 8519817437827345306, 12812135280042016222, 11756388140614318382, 12847173998629383540, 3195426038228239005, 5408495899086602028, 6922648616092793742, 5190932152595381165, 13719540325198346554, 10629959409267319255, 8884268677394635427, 6247623128442836769, 3486276745613410200, 9922470857167696268, 14050590494518967213, 8995719668655130556, 14390840361596141419, 8805291080328413490, 1566519057385031214, 14936709980149037189, 7843407261302448200, 7362780728948899723, 8946431151602397981, 12379705824411818733, 10625136469958786891, 14809497030327428493, 9600038407435655136, 9837775683877496167, 8314234294629785773, 7534662661788740755, 17545591642159119367, 5386108291396711743, 10314959419729647004, 9921350920794026186, 5258567043271810200, 16619824962820676808, 13220627530497654811, 16290250367911457974, 8006465541051436115, 5091829719940545572, 10072085677397640377, 14112092657396804275, 330584062778878076, 15840181077086384365, 9433048095385237868, 17547222939187629580, 9003900423094679394, 13034539377777557986, 15200986616921766375, 5647363409336713681, 13477915035055474650, 10108372618673363661, 9646104442597003613, 15344302009281875206, 7483449034533484580, 8795188594332056720, 17885112742810008270, 6548243381935151424, 6302172644111584420, 12757561721076687245, 13247607995431226792, 2189822730261058939, 11438243578619214144, 14096253582179708483, 8235642739441819693, 17931433398519450539, 9927801953719909330, 9995825800685970424, 9124542719873359665, 17993527059507412774, 9728704891460674569, 17044025698547768405, 17484244453920345875, 6521328358485104519, 12029066764909652028, 8464592765225463263, 12597892885514076315, 14894106690171984976, 94941976]; const POW13_13: [u64; 237] = [1203553390770798593, 1609911557065216166, 1088829841559431321, 16845364770249289016, 13845306940320367243, 11279257715767435083, 4184517647422671463, 13618233420395390883, 11087029362168150996, 12824044226510429646, 15049709674611256955, 9950066500331292447, 14590365862096941747, 8420372193425272733, 13105392963450672485, 2225554786167414869, 13130811412339158477, 14373309974282704312, 1363934382124367093, 3493249700550808246, 198113603689650440, 17724195032260904529, 15510671998166755903, 9412112796161208987, 13107146209093962052, 14325694777197506385, 17290985315933150591, 12912300155233688889, 11888988617301666335, 16824020535296757095, 6656469285892451070, 10712076583117571968, 13585126715300435862, 5505357760921272323, 932014371801169344, 17265099438162165715, 9217420426919580929, 7386758858448837773, 15881425290995742661, 8589320880104585762, 12250041853446393684, 14402642887289062137, 15186226884070560626, 13685794765897176244, 17149732232508516893, 16958080657013900036, 446281904813871080, 487180674618228103, 11297619110741084464, 6872665199954788963, 8212455334907092516, 3332955197913213157, 6913996779383831253, 9143487460784907028, 16797670345194284720, 323102373846704555, 13352688140753214724, 12806526486837460652, 18268241912985161776, 4382411597157882469, 847659914389185987, 921514402521550321, 3413578678807403563, 5299255870322462778, 16593630186495530209, 681978374293965158, 17224675749288852530, 13657040160381442415, 15934597417946057970, 5968355591754377009, 10937621785845023795, 16336645948308360494, 12405912972336456603, 10056632425406120927, 9545350830397964915, 6230724639162649640, 1723225072254664691, 3264119010427044824, 12061938998424201052, 15793623536384650589, 2770434678443391736, 8742840120100988883, 12550260951863227963, 5656722295253371501, 15088774378750634990, 10962679145980624525, 10979536132202984393, 13795001474202318651, 4448006730336918867, 38671531538996222, 6160062839598287682, 1257541840742917296, 3178541894065862841, 12893034833167956877, 1545292770228628058, 14868485339772606169, 12433131052169805902, 1047624445068450958, 12830444186848242028, 16967079682316239583, 15300022305344409644, 2748688994970373146, 14437881100213368756, 5136001432521644414, 11557874420159275359, 9951604686169636949, 9105441558159706958, 12641802768889824602, 14749264964144337284, 7817863904982045617, 3274708901909362741, 9216091375878036934, 2785095739303537655, 7946462064155218917, 9880642893921977390, 7312919982913531673, 6798900350867994681, 5200771958630779037, 5461481497323024249, 6667251605971833578, 10862966560696237413, 4981305851286696344, 18405303816635774252, 2626422208612979467, 2524010639745371494, 9424627984561097090, 9388677451104336995, 2582058352296334392, 3461496597965765778, 6903709418194893235, 14168445877626931980, 11962515729592987925, 18225813165060703921, 12244528200070559824, 17676522228037342234, 15700092181859214166, 3977481182383385443, 17776841864312704000, 14166018271826904702, 12649693585479702092, 14565403646859767953, 18322287800489296404, 10322559522303048577, 17758462006476576260, 5032958958915733924, 12927847438191977469, 5419434607677467828, 10527444260142380542, 3401503835092434125, 17614130616565316930, 4810516414309631958, 3507848254831682488, 15634605763662377822, 9388453154499759721, 18065763110862168232, 15388918126425569691, 461692384970678664, 15850564788257762644, 14111430541734206603, 4994954389344485847, 10805375757737593723, 3961054096977611587, 10318887131642571288, 5743184960545772523, 10189117180961746330, 5622362617669878188, 15746304441183604634, 14078139847955519633, 1794138234269283797, 16546868410017152004, 4720044912811418814, 11715077310973639211, 15826706810046401131, 7575219333327213432, 3565823395965375601, 12590663819287174106, 484808767868101781, 15408998376957354637, 6415573641749871077, 17152492909023801467, 7980131495021249563, 10327931235324087527, 12249230950224323531, 10416259948363286175, 17501767217562082331, 10989307086053754589, 5241272896345779004, 2465467701083299706, 10074938103029299899, 17129430888733603970, 10855614832124598988, 14919221415520823623, 15256533446239181458, 9174981353474693807, 2174936122263534850, 3154260097308379950, 10106874050564863329, 1505468923052395092, 13425512187246481099, 14284746803028228819, 8441005310956645818, 5073973329263230999, 6010673567795215036, 8524322481505644754, 13229211917795335472, 3650375234546436406, 6742299890377516527, 17241811097427073487, 13687187275544022283, 1106925317233923510, 17938270309567737480, 919882561984985194, 10318700069693997193, 15867660097971050053, 7928187184457814201, 8746125163467766185, 8766735466984942365, 4349224684163839110, 9117893002779338032, 8425226445855708951, 12570045176103670012, 14523052880893323756, 16571364823704058491, 11810450155391964648, 220457475584251241, 11466805777400920749, 7189923430699012936, 10523264242029311260, 1942629354778206703, 14287715025778465138, 17271531035582072914, 9257960542134080107, 15668680892476791439, 3220052894238631189, 11648831345971031687, 1762690671166907766, 9013978960098995]; const POW13_14: [u64; 474] = [11001221296112041985, 13826034922266770651, 13489083541915362882, 9373283467586653811, 1574296081529153194, 8207827534493453592, 16099869660317043525, 8401454024036860842, 5202873459370842377, 6508035404547889168, 10590408588648330578, 13599124082937212823, 9434321195352883064, 10155515984415152651, 4051416326546982, 6681481629395179557, 14231271695377702163, 12307270831191947198, 14256025792262662724, 7001983270372916679, 17105157001211452178, 17527560855128134638, 14998745783366241801, 17190927521760669498, 5007035647203439458, 8853466165539928102, 16983632653169162652, 2037074113710105517, 30417155902682448, 8035056124599177390, 6042168278089742406, 15878770400820717005, 9722934369610784553, 15287047448505517637, 2820968948861209497, 9975818641012472740, 7182985748273685520, 1364562377225132628, 18296360144709817, 576848656767306379, 5955230672257124560, 7379015716094514221, 5718216123111898794, 15142142519635291591, 11106867854158898911, 16790919704601646679, 257926260294187969, 12448066541968444986, 1415233908419532352, 17902761823566127020, 2731664248199999171, 6237029798739583092, 6467722435243876522, 1299039604882059493, 398976867616281671, 7553870406036065786, 16934670912782359126, 1289086765772745842, 2613897624044659519, 12849575202457487093, 330113016788704466, 5757502493281968984, 7559306778079978960, 5542934425745706224, 1533151162646650219, 7421850702646697978, 16594798993445426776, 17897324178914914957, 9087172952624010028, 9066556304319215325, 7840945401977096023, 16922738906269128645, 4861129228358429263, 3295150432511268970, 10997859628130123416, 15343396175772034760, 1317816914573838479, 14759039390472615987, 1281922616905457063, 5162401323428780856, 9758372827512559901, 13619943009676615370, 4902989325629769882, 14949250806229852955, 2137627133258871847, 3709905021608383901, 1154230757852321644, 2959555194364826825, 2897568030266647527, 10875744904860113415, 11966155686055175906, 3702953058348919818, 2073451823964344281, 16085408681594082929, 10552977438191271711, 12514675473966984872, 15762256019488987366, 9071568391198829544, 10510779715864700534, 17587637550002829721, 15995901679724167395, 649433175885093709, 3126365131652797316, 3745803722635257275, 2740293817418522285, 2463647550353539666, 13911370545147095490, 10947209519617321806, 10026214067430552082, 3740391652626600960, 14726472218128771969, 7810795638644566032, 15550857298608943406, 3607017316420688105, 18121379695941633959, 16641977675136006855, 1049371298479392969, 6328311637329283350, 15114018247966121758, 14757563084213719233, 17935953705758344969, 13945851098450867085, 3301120041836373770, 3726731014553693929, 16919795808353174542, 15191793168421742042, 10179892033259062458, 14032663474246125256, 6962785128823785316, 5423606119058457628, 6691408130986499730, 9794856483701825466, 13304871226024279347, 6480974202663029808, 6184600061405054561, 15442528502365176705, 12005067980263272267, 5371579747120466179, 18232208518232842609, 16444904199311614000, 9190740480149943570, 5314651193942028542, 13629915964829916970, 10094255490430702491, 4315579360341753242, 7687187928622058395, 16633182809672350619, 15201840602062472548, 815169498973750913, 11465779781025816541, 13846214078933346557, 8203008060395181666, 13072818940317752720, 2094326092261982095, 1606992515386423987, 834319476160655119, 15826955984133679204, 17864292461931537762, 16315617099703841285, 10994678332850258678, 8182109064250625378, 5733101953484631105, 1701622557818523975, 8678005748388319746, 12559138384279305724, 2149920055961087342, 4679156372840331208, 4890945313952747490, 12341079351983382907, 16996522479932293853, 7167693384214142369, 64564806202024973, 13018947479033271512, 807572127061928419, 13169707104144669064, 1301780138563365402, 11171679016440668017, 10930338792860354388, 7503827134764867545, 3710148376837961313, 7346453468431038544, 17746186879842678411, 5420383338443940395, 4546493977089636385, 7541571235635047232, 5923299374354259028, 7467965462087563843, 8695020258660585006, 11830360506652846144, 8050617092956085340, 4951161648616577377, 7462209926343763823, 10469006123121960375, 6148873142691968891, 9391262262729762674, 11872107003184134291, 5508694767999789443, 18143120487909803859, 15524922245663613461, 4833182803128976775, 8244678688694015487, 5057226443534091947, 3030120199463773862, 13784827470316886596, 18238937241437302856, 13368902651824757590, 13315981508335635710, 15966818832176274537, 3085539072629787937, 9363905682672589140, 16157039694340711928, 9559531996628716787, 3150261223189782519, 8856439592903901949, 3091470400550228612, 9040155639517394379, 1371353811560573927, 12889247891890590187, 17049235564690384092, 16757584821310313034, 11758625002648909337, 7759573695080814361, 10097096795860409844, 16589854659233622964, 11934746433485305957, 12333524935205720205, 3955817633335153034, 4125327313510146580, 4568297301310197968, 18119174710384717893, 5345869971982942857, 494470270414093801, 7997948628033282961, 942666202323743512, 16437958288915398268, 1283200097456786113, 15332211832576291157, 17410164318065492694, 11928883664083256784, 9850658024400890166, 1733793683783473816, 12344212916256620557, 2819203097851441342, 7982443306230804850, 4160454682175014431, 13842251928901083007, 7808640267378970699, 13600668417738025882, 2594746220954726072, 15816048106874640762, 2987812975317503152, 12543491042227346886, 3826802535651268272, 15850960931252961241, 10017176066894286196, 6762101883533445749, 5307989341262880556, 4157978587800144642, 6777863180208783660, 17022038493314532091, 7273401959974654348, 2004648355965154788, 6047272893593882362, 1913493044036973221, 978875274625428970, 17120070580062738323, 7209978581865436701, 7221034171459879768, 8855079812911202908, 8138230977246452031, 15129746512467684403, 18239795630873686579, 14218049206967094751, 1741356195072171132, 1250348196747565897, 4844413968011903569, 3243911763561264075, 2270507046888594328, 1745972380732774692, 11611949605661118884, 16815810824338229786, 13149366465235705917, 12772769592611338268, 18127644775168346314, 11627350941001380640, 13085395823307950354, 8163261920636206817, 6668735979905409851, 8786125210795383444, 11923422846774113428, 9155009889104890040, 5305284880382256866, 14316398359199834891, 10541498030296982923, 14943515792680830022, 7917825939785758284, 15631466534941108133, 12920335454558214696, 10959813717540086952, 15729862033964173328, 13286222593245553847, 13004657081351788118, 2626602932514888710, 3065039904467636347, 12026579291253778633, 10563241431200478218, 2349397445393051973, 18038315903885496324, 14629828402248920882, 16509748883247899556, 17448613528315110931, 6572809837694703460, 18259089056305221691, 7345479003112781147, 3670992425516768002, 7394406571262240786, 1282899707141302414, 10361574807864457268, 8432084522712399019, 9712523964169320490, 3222983355808575244, 1532899133358693843, 17095626576899797785, 4716860293526059400, 6063867918555490264, 8746071046293822259, 1152651058829808534, 11648519557365373839, 15418969224994841052, 6940179054540262900, 8364720200192476037, 11673043597161346328, 8686616599861651722, 13356248813490536770, 11819966142617113834, 12603069758178319602, 1815243887937208353, 12760687437624258217, 12561294096896395018, 8012967678291210914, 8176121075751724519, 9435407884199829361, 16805827493862195416, 5129173037979284942, 7293708894884142616, 9864549789479883882, 7637483112799067924, 10579080446112035552, 9543557324069537796, 16314213310017096676, 10031098292690718712, 10164031712634739722, 3267823673232592820, 3136193050632781907, 3706101864669700413, 9460086010135946756, 10916100565297338071, 7173053772854990367, 2503009763637123653, 8217140079509149715, 2810622735802506167, 14280999559109874227, 1650648906925277119, 11045199590068177714, 10728518634165757251, 202850395640093662, 191152309499110130, 7571404669107300800, 3575303671359809366, 16004841872492895335, 2622669442037194783, 9163035080063833785, 964368337670138517, 13390118242819651871, 10448930796967671907, 17974688233878842982, 8159271893993050695, 7677697874118781395, 6794934973509989802, 2613774578300155016, 292694226148776518, 699325260027102137, 6009081017233518841, 4808972936998712736, 2623499327102215274, 14910930447682807849, 5154480565623165511, 4596781419765526739, 9164821477431395490, 12128029734657776850, 13627460724662533268, 11708733599451343812, 75964617081117142, 7751072208351631823, 1810436372569480281, 10593526490340800088, 2928831967240972121, 11430913332203388860, 3457200823898512150, 10207567760803673904, 1653252314220274777, 7888064959285737145, 4661569017137482286, 4419268922763370533, 9193738542267727654, 643779550123355219, 7526113752480014803, 17180488012839069744, 2271943469414029100, 9454167928806399491, 17263275688221850543, 3618575948507292930, 16875459308840290795, 919514450176394764, 16881770684872090106, 6500076494866963562, 8152684853826958593, 14423244243871580034, 10078630153364349209, 1657197671101659193, 16159257563350574568, 11738586755435346341, 12002324055030490736, 8776944205051025557, 16688420418636467722, 18149554999083539289, 13691303795704853731, 6963984469531699303, 8037230931167529001, 585854776801936318, 13296836435828448841, 9587336969956966916, 16672576742326658947, 1561024513249204507, 8757421682897192967, 12562341706736520009, 2676213381522479443, 16551135642207408305, 1381302543289772132, 13052332861289439793, 8931178299453276459, 17413406719003837278, 8660924170765933191, 5102370430756705633, 7670466310574234812, 4270146355458001205, 11500515934090134119, 364081632367892515, 1424227298276949770, 8173368021493932022, 4804288675503958208, 18124903500673088296, 5083514154075546120, 17409090338743953366, 14715725901254457899, 11902426688450673479, 10555493577098859529, 6930497058318651918, 16042130515736346985, 1716882303854684150, 11660820427629564676, 9737372309838229215, 13568955813836938774, 304757648521303857, 7833621986519686371, 3508169234872570781, 4668927750426144566, 6798315679163870904, 10649911868726982934, 2582989167030406133, 17973120471981440931, 15781752425946823773, 899757886429656950, 4404669808853]; pub(super) const POW13: [&'static [u64]; 14] = [ &POW13_1, &POW13_2, &POW13_3, &POW13_4, &POW13_5, &POW13_6, &POW13_7, &POW13_8, &POW13_9, &POW13_10, &POW13_11, &POW13_12, &POW13_13, &POW13_14, ]; /// Large powers (&[u64]) for base17 operations. const POW17_1: [u64; 1] = [17]; const POW17_2: [u64; 1] = [289]; const POW17_3: [u64; 1] = [83521]; const POW17_4: [u64; 1] = [6975757441]; const POW17_5: [u64; 2] = [11767703728247765249, 2]; const POW17_6: [u64; 3] = [11901479856962007553, 17684280322388389617, 6]; const POW17_7: [u64; 5] = [14949628490430014465, 4334809184308303144, 17832375909946066926, 7803766654558500058, 48]; const POW17_8: [u64; 9] = [8009457700659775489, 5864744823687262438, 11288212946149035610, 15666403803208012848, 545151480090474179, 4471958383658311826, 6377793695101289317, 14593165042794031210, 2344]; const POW17_9: [u64; 17] = [6230562379196764161, 3405124145050529442, 6672549857659104409, 8045576461241663187, 12485001784417160192, 11038644820189654219, 429283131511802281, 17946514039288555881, 16665292417367021928, 8217113687992683468, 9233390645811130670, 6282302448753559949, 10686294792075548010, 8286724651875629291, 705476786323852570, 5328561222396733028, 5498045]; const POW17_10: [u64; 33] = [4227612726968393729, 4761126626777682748, 11568710771682007766, 5571113179633199579, 5851565854403606477, 10308635839098688885, 16798960391526040672, 7869857980563782065, 18423256546778402415, 14203547828869553692, 12791369416689782508, 12876291981408895064, 15307555864783909491, 9137356882703048504, 3517233437621529783, 15111927952764162774, 16961664718059510463, 14099718551820868393, 16099826150732442218, 11196000002599581151, 3989192399412465526, 3152094919306852295, 8526189504144703959, 16230267771132803500, 14683900195084541313, 6568030588913947551, 16721463581699432323, 17147904814754118545, 16686796696251874433, 2966231010345418546, 2819956962494148691, 6325931310759637711, 30228501998376]; const POW17_11: [u64; 66] = [15846384477333766145, 17721259160332568959, 15268217993063608275, 3369257428568507113, 6849076422060632174, 1559939278665064961, 15149163351107375334, 14454902370960405567, 6797223075258887305, 1909847963587451314, 14199165546850971259, 15511683067408627876, 5805409519841271969, 7815958194823638455, 14713740033966179139, 719153356046425635, 15139191507293081965, 16203450164456674122, 4081196284567714938, 14758364217129439883, 9702794971545023221, 12711153795347319, 1201936732137814958, 3257934889304808719, 12342561217742503707, 2516924444893373492, 16911910252687000253, 17642443087981298450, 6171037733903123784, 8711207953117949856, 9491615688477157367, 6888778246783500957, 3846072893649681856, 11581388360545359451, 6615391846425574639, 8307688205333072650, 5082992663755394103, 10006915555520507839, 13748929870033738122, 13822220226590713782, 16155676614061297595, 14591432047590794740, 16180155903817834722, 1768962406949444296, 12415132256614504782, 8001327676754234197, 16938389339776157999, 13933254066233238025, 622533281476191193, 3284230806252073576, 7582164516679533000, 6954285079702638317, 2137851930352740555, 3838440653317478891, 17588564846903944152, 7450046277947452385, 17486325056255996844, 7770323824051307195, 12761289505732553996, 14760668822500286956, 864042941828465833, 7063455544966285626, 10470935038940623311, 4298754747365446251, 6129308493713104401, 49535155]; const POW17_12: [u64; 131] = [8959163060392329217, 191675492520161846, 9861768627217535660, 15373541761327164473, 4711124327161180762, 9148574511009427361, 6256124510954776780, 16092166725978353288, 18302892885771588550, 5554041675132576311, 6701058617620120256, 17741092924367331446, 17591967636758680126, 4424715011316294039, 13880932752311819576, 7314018719979239563, 2116064787992819024, 16117403803089837852, 4655954531271169387, 6834141459358892299, 3655460684868413951, 11462338205905151735, 10077406444200357956, 13130230130748888616, 5889899626778796386, 6132699084648918276, 9726807360252753060, 5247171256046325894, 8536133978436943399, 748382039249661328, 868011800140048627, 2772320414349939948, 15362211012728597267, 3382951323352826994, 8125886995900784397, 4017158398871576676, 7893480193554175008, 5573935412896544204, 8123912607352453095, 15714075234884286912, 16469474643299192237, 9241777800732816496, 6176630977917232021, 10797511347607665837, 15022344948172738195, 14428212684778821630, 6734324888653914439, 10575506900324831475, 16553245213985120509, 1257284041236233123, 3908192413356462543, 4564527608827375259, 12151764111397135943, 458175833548946244, 4096151054727360058, 7402916187011778388, 3229234406745339345, 4132007059461908897, 9663290448559559546, 9234229907084195896, 3986539845594665168, 8583252218130488663, 16269932014543485379, 5582927709185863709, 4156224254070092169, 10228700068637145318, 15289134047528690598, 12947151334886938785, 6341666219823015281, 15251353559696302105, 11243855513904347971, 911152298063356736, 5591652336349208176, 5924560756866900721, 16140991744705182053, 125421795282426929, 1732882485300281289, 566444319590466275, 13799487113002678358, 702306079806215844, 12074151907789264562, 3318353663331306078, 12354859459090774515, 17620576393983662297, 1780495445327301352, 13281235673007693735, 4616082378180806908, 17901748227341567272, 2255419658270086281, 5124911507572099852, 11178096695446382543, 10870988045866950024, 13317277910799673260, 1643374315321976420, 9604922605134795741, 8774236625624226892, 3140444146600578725, 13538194915004718302, 6829493612567060204, 18311602663646564982, 17830822296778723208, 6865079510397734800, 11402190682638191329, 4572060998450752551, 6421143019301485022, 1918017823683976379, 3115348749764798203, 11961373941157925564, 13683530668200002252, 4550096309857206893, 749653413096125507, 7130884266445741772, 6909992711640903849, 3823563730409373012, 15296311858043646555, 2274049411665268452, 6013473541626923118, 6919079438080853997, 7448520711576428686, 17407348002788668254, 5722106574277061894, 2073438185679237707, 5960334185761856144, 15386035660141607389, 14462253340111213632, 4103115605173323406, 7271379120963975286, 4817823530239772404, 9462154710072633015, 9078581308959962399, 2453731613792164]; const POW17_13: [u64; 262] = [3453493696249004033, 14526017207175330164, 5273243693336234366, 14341733444399718434, 11415496706593102501, 13876706249671608639, 321363226988254866, 308962417931214708, 15911336303095720984, 996824685256301228, 15677982801565030214, 6203109012714328248, 3577016848774547852, 13751276889057797017, 2249578892878439932, 11649554284292177446, 10765186448076743818, 5028446022824535899, 13333281916584181132, 10600832506166696241, 374609586480556231, 8837817030667441504, 12522209874183140446, 14887407680095266206, 7878449496481078588, 9979151851659884035, 3944321834529564998, 13033175757373656028, 17034680569138281182, 15337183806926405103, 14234796339765425125, 3659046019752366622, 12319550462837266669, 17372995233808427154, 3220981660259398548, 13600683337207885152, 1240229990393705526, 2464512451689236607, 6090545387749947476, 4759164737740380158, 13567236852469529802, 2223785365877143535, 7731405295463554874, 13327676158848262579, 9927763461166706695, 16371137271828264195, 9390760318458771698, 13825879733085872998, 6108142823395892079, 15000480047604873784, 8138808737293537674, 795303861000927288, 3431326080676545410, 4094275192551237205, 13807846055260267478, 11022809290223582560, 560783138310981946, 13540845070229582961, 5857694737960376790, 327355669609233992, 4238227645838412351, 7646313024116194751, 7285406168992098213, 3897249497123239660, 1073602066689072866, 10857882633873024923, 3362934076454294000, 5212916866602033072, 1725307266225281544, 11955500225774178853, 9633806680133782119, 9861276272964407887, 10436361308193547820, 13840240434718659608, 414167629521649992, 11345570322302018903, 5390463353510226820, 12795318804701548501, 16202145356757001200, 2812273960567726268, 655049091438802107, 17231723169691259728, 11082101123986442539, 18443629319620178059, 8309590386389515990, 1939372487602583775, 2669920229543028106, 9556943150854048846, 3800461242298202654, 11832491830257986646, 15816312406128203594, 10153636748224629883, 5594191127080816557, 10269374132501948068, 3794848301519526269, 10057158154152845822, 12748032332747561749, 10647428812306673632, 12741110773301132710, 9155522279676869496, 5313772790584689660, 7936007289057905531, 12052079759835667301, 4632728627205541802, 17383578792221334953, 10038814202371690444, 9003685037805387593, 12038898373841603014, 13499198510584174522, 12140117105448917631, 16941108449964135680, 483272408134465939, 12464071335974555547, 2020642769228549477, 2264497751077711576, 448403399328266180, 12744589264497159584, 6370660673588569542, 14314471902760634029, 15996423551881056631, 1036073191813529138, 11230341400851904256, 13774244195239257712, 17877112685551479552, 2141857429346143824, 13804636919441295933, 7714753020686541958, 5541153521060002318, 13696369674662283266, 15986267858624178941, 5770580672437871734, 5544198272223268859, 3166932195878070274, 18244824934193415238, 8263359853692574304, 9896504794358422619, 3154076072347406873, 13356341923311833639, 4311531226105996129, 15827733439051006549, 5628573781578495108, 17183082566167736388, 9020640082123933088, 10068398142802300110, 4211884241116479941, 17530527679573489043, 11376944817997087233, 9255151802627062249, 8057850084867608822, 6983268662492669940, 11504853929838981371, 15678682304000836697, 14442617427776347788, 9688392016774030261, 13586354197343885967, 12909584926447299726, 14603220715827301809, 283206376923126647, 10296102240185384275, 4944543490257020180, 7146538787918427487, 15164292249373632032, 6431532434800671082, 2449416194845629415, 4432030625828233840, 6139962560278119501, 5250431025208417075, 5548467511879587586, 10715590260985086579, 3338041801736609361, 17438055901318356005, 6853670436702292494, 16372824264222855267, 14686430409410397439, 6868381658089998765, 18292642808321975035, 7274352449373431955, 14983250044603241917, 1635779988451042236, 2678323226758805561, 351774090608032895, 6392639507683575772, 8324642828346497619, 9320673411977431015, 6260021926778537127, 6348556698199682350, 9195546093760306927, 16769138414957877603, 961827998071396233, 9156524616979475039, 15673386381176476794, 5442214397100570582, 8876830942353946570, 7311172727612586526, 8234482784752016105, 15306778849167016468, 7502009653802519812, 4712059500290642977, 14423360925915259766, 1448744954666221572, 6078860174888560856, 2720672009072674462, 10318145048288136827, 18113229674157472565, 6404256905911555919, 9257257400021527557, 17686983671329440628, 10106377461913198073, 7618967566971511927, 3760397855961663847, 16813439320983284451, 11493293337594424887, 13179725129734599832, 13849366199944841585, 15065993544969198538, 3120683522238678144, 13763881560037094390, 2829296345720252421, 10712566716559778109, 9875922995273184600, 17632913709150245841, 1202466900984995006, 8056344660482507190, 3674707261944432957, 17295864791525018378, 14560273084621476982, 13048445087642742990, 16218257899308673711, 5655471326288357633, 7328683466588010193, 13941334933370497582, 552563626146860996, 12709870039432658426, 1239512640748675355, 17778787651186157106, 5866197565252347000, 6122417430865487137, 15964656896633902952, 7128470856815954433, 1848204601345607694, 4778259156713161407, 11116574780375752896, 9849797082728023937, 5763971865884449624, 4801386319788717349, 9057809257185363799, 13940990906848311768, 6808284956768501841, 12321634604151815934, 16051364341293277744, 6531003425874712870, 12157585571810326251, 4608359961445944066, 17636826458037430263, 13336478188061285051, 12567967923923968803, 18226023352920088899, 10910669443286149977, 8614888343058296948, 5237316467097514822, 18201092146435758479, 326388158715]; pub(super) const POW17: [&'static [u64]; 13] = [ &POW17_1, &POW17_2, &POW17_3, &POW17_4, &POW17_5, &POW17_6, &POW17_7, &POW17_8, &POW17_9, &POW17_10, &POW17_11, &POW17_12, &POW17_13, ]; /// Large powers (&[u64]) for base19 operations. const POW19_1: [u64; 1] = [19]; const POW19_2: [u64; 1] = [361]; const POW19_3: [u64; 1] = [130321]; const POW19_4: [u64; 1] = [16983563041]; const POW19_5: [u64; 2] = [11740252461977893441, 15]; const POW19_6: [u64; 3] = [9107004542504076417, 9191406976808105505, 244]; const POW19_7: [u64; 5] = [4093619427583084801, 13957234897430346681, 1664550439794844065, 7427571119310257990, 59779]; const POW19_8: [u64; 9] = [817529151526638081, 11061274887526630745, 13854936344412371742, 2590959186039059915, 15775445760697030947, 16331670318820695493, 2071048169989844021, 2278881448906328646, 3573576981]; const POW19_9: [u64; 17] = [18416236736923247617, 2843296379787837318, 6729620708251823400, 12798876267615021754, 2660717132428076544, 10628885389055499043, 11044503519330130687, 7985224598569237787, 1457616077719484039, 4253722459635196846, 15778909568102640, 9133037468603004244, 10607875013481456916, 10405573357077323564, 16201176834369868626, 15603744466688166633, 12770452440016022403]; const POW19_10: [u64; 34] = [5633069569090144257, 15290206512922886739, 9707218376940875875, 1709039808364038994, 14035865001343459164, 14752003658582921822, 5082969893951651856, 16272852641206412796, 730258252848516821, 5788390706397880364, 7242425681721975223, 6952174348889624452, 6454810008803646456, 13619454667360554822, 658364721192818459, 13614738124954350725, 7590796877500647051, 15054213496588806398, 18128202672247203937, 1539858474300290951, 6852435336274526825, 13905822336907188274, 13057368655456895800, 4908899325321147633, 701112620434091845, 13513741133915280885, 4125718765320579123, 1751062884599762549, 14570551700183118526, 12097441747169335093, 13483771739387388768, 657201670406363667, 14630950795039046978, 8840826048816954163]; const POW19_11: [u64; 68] = [3868274050427817985, 9609965785064554795, 6362446737853125643, 6140304471677215738, 5944960630607158193, 14401685563426760224, 4560905396542113511, 2548913289596743873, 2195836196340464609, 584474905622497817, 9585394224313248505, 11836011876247902363, 15213425438825380920, 3815573032503586985, 9803347371716257639, 9461035088993310619, 5300156522097191451, 5918635114962373973, 12218486070363149403, 6449965452583488968, 15408535376151636739, 12466181625097255803, 10825828646380741420, 4121435683046602366, 2741973219018491560, 10715518326862115396, 15231389696256960893, 8350402888314404759, 11938803783207849103, 7726173741642165137, 9772085543297372800, 17846120431012455121, 15969961948968637780, 3682485160058388355, 10414744953778694019, 11287979426725105581, 301389775852099638, 8153105316773946755, 13425390638242950873, 6732727068684316942, 6570701204518578902, 1033209613870478974, 12613463344053582811, 9498960377609318279, 9420473608029820334, 8904730387087749961, 15951318581146735401, 5998702251292236994, 14539934067862285112, 9259413545972995298, 15565615665290070497, 11891825817077140304, 5906020157881929016, 2164104905828351276, 356616233133185022, 17409004541213955531, 5307453371472689621, 15573363977388344584, 4191162759449342083, 11493628618944877076, 17119550843961342139, 4803917594058321191, 8997719434483579480, 13271118517769149072, 17284093494109674951, 9909172166325359010, 2022791723112558206, 4237073215366767747]; const POW19_12: [u64; 136] = [1960352136792973313, 12915306719042846755, 9549721850741165947, 1794818986843879764, 10215019418910247731, 4426669725966792242, 5383828992808606577, 2001777283720954158, 15250541989612595041, 15876462925156345934, 4444313350329650360, 7926624381155763340, 14296416638539564181, 404793363532558309, 1200481957272550884, 15907747927139955519, 14671662520317250615, 1507208032879759849, 6851799916100325063, 8565727275049804590, 4689600023823228041, 756029801721980048, 15329091841300896412, 10566542626694407745, 13533481494481050317, 12874804700045844122, 1991448365425740129, 17353422221748742514, 13313092773583902835, 11497473115430563823, 13702285198855437096, 247010935149247943, 12549987517324888135, 17375207470734806265, 15821763063034448617, 12536204144939836520, 2357214310561288419, 647449256512126995, 3325003721186089419, 17452175399978474856, 5524709823518690895, 10175805100915607438, 12164264439256393019, 1182031409207463077, 11482720052668503858, 5809954311598707966, 1458642029465885496, 6652359116980107346, 17309444824431055511, 12050041769952339412, 16720975861473443227, 957554924186800091, 859228806681068266, 10225722239085408727, 10959642869928201712, 1447446427562697235, 16607278679201454416, 17474996716956937081, 6539898828930260607, 8647993941424130124, 11076258879161498058, 510342348592251553, 16269428316411042956, 8555392314223380320, 11535418644057428613, 12051908495099828664, 2776204980897946502, 13126542370903926866, 15738254011086029526, 18379785119021048064, 11739425220439312073, 2854925554475372758, 17669770314744446061, 1437039477200178015, 18392564141500484039, 11145666968277950017, 8796226633411283692, 16023130302112197966, 10686203817595327958, 7557808848364814361, 14885152611388665789, 9900024034053821768, 1824284327392229733, 4209142342116784665, 13654828572915005029, 15907904975061311313, 8737388517806224363, 11363958266183929021, 10498302627208387178, 2754551711826034827, 2124138861016386537, 4335915466825829320, 18352003110361531619, 5269970246625732076, 12023298798400671021, 18385236477689900799, 8722836570358853256, 11267513616534803384, 6679741229755568887, 503544455235210957, 2391128621808331307, 3448315061963389445, 17136462553840291457, 1740673100858724456, 4392582926876629883, 12394647519023928247, 13865729469863724620, 416651680067900905, 10330898263527971675, 10645324120294157721, 6793220771642939284, 11760621930141429944, 5546468040327333541, 5022544873554114077, 16574061157558710524, 15088079029515873596, 2472930629014111443, 13728522472745411853, 814942555029735474, 9921434599477829181, 16710970458645597244, 9705337344771396803, 12085441819327374209, 16935579946984688668, 14477999081276262966, 9663727961641594069, 18361964884341760000, 2155295036902588563, 1243782721433810458, 9716419136897822080, 15251463038903931903, 14357519492630616122, 1719450790954065508, 15226663363792079469, 17581785284757192445, 973222665237977690]; const POW19_13: [u64; 272] = [10087636017330929665, 117629036420060348, 2257288031963526354, 2697080650104114613, 7317222843606800402, 17233645136066997926, 15215182557830513151, 4409679207039632416, 5551303152772086392, 10445654504756146421, 15631589513374389381, 16740210980841856961, 12206455894870582408, 10514915510066191703, 9798591746919096135, 9113014456766034048, 1915311464989266308, 5175862425342707440, 1127360680493692391, 10057398955950352231, 6891411935195458871, 12832839332288736446, 17524506411926026100, 14080098086345178452, 3038109464521314257, 10013456124587865885, 13142012752886403448, 4060193906554278791, 11170398590472031536, 9410248415261768441, 3755575703495444750, 1087894592984391669, 4751912188462049770, 4632624366515210386, 4457129870110852870, 17868371918426695046, 15491749089632868398, 3903129746649350010, 11730329157482703963, 13362676418965584486, 6226315336624364369, 12940628154440446020, 5995730625702226605, 17080500880567388476, 17034166135852711986, 12615388967880237964, 16607446377225295242, 18120411465172808420, 15787446299618211950, 9620043234196185226, 9126458288620594261, 1060614255342882962, 9239977131371698978, 12617828668535245979, 11181865063178680417, 15582511285421893496, 5987843678629960553, 17386244475857748072, 9888528612616582462, 3595464981086127320, 9367439919957030621, 8550549043264059628, 18085192502605262261, 15407796931651607761, 298328856447100096, 17421750770842790234, 7872501740568656664, 10448096615740815737, 14188815967734612068, 16693009861392493023, 17789600806338082050, 8336869697002343684, 2654789055729331141, 2555141400888163156, 16517047579880288931, 13273651777149305664, 4389952680784057449, 12975614287925853036, 240304697575882478, 6279305865397923522, 583873442935862603, 14813213709621671969, 7518402263083839071, 7699243630994338007, 776675925129320514, 3161721386993647464, 17252271088371083361, 9042895028327730598, 17863118534771035424, 2610310289260073738, 3068384401569065116, 18117743184408431768, 10425084636492659263, 3202757335665379157, 1876980547904382981, 4461954182467642278, 7532602544065039437, 17563076800501299785, 16143257408892335352, 6295024592838238576, 10008317046802168803, 14724124565313108034, 17299868711699727533, 4895465631912272518, 17770579402527327428, 2830029028298029644, 10615879134485394366, 987571403500865241, 9762544400969694173, 16653514993868016982, 1624757165807484573, 204841906801488337, 15777934803209092178, 15414314932377081282, 3650194213562170847, 11376615561640372874, 4557464199802833195, 3324722857207389612, 10111951260843269854, 9569735001807245738, 3059295715511503958, 17685235258966059049, 10517342237401591825, 354103831077768891, 10947529916789799264, 9338838995601614704, 11063908090907358752, 5723362756156006336, 14617726084547208238, 7886038541673275570, 13563265626626102222, 10034675999158421059, 14492040540975587359, 4398047127547358009, 14009874952125454284, 16164064201877844513, 12793855159126477819, 7950190962625024443, 13134601873605010989, 1026250608253301715, 2324027021264506877, 3119872640450254566, 16891471480735182549, 925759926631512499, 11506481750981778838, 17165776305519574102, 6814319562472641991, 13079239135144701609, 13141241223890729352, 5513306421473738820, 3582378349717660269, 5730906620900438167, 5394537897260238331, 16297735367783243747, 18080087427118476356, 17599083483868974872, 15129459250026816827, 17475111262689115571, 13344954397330229420, 8420637573042348903, 6046669001445359623, 16319645399226821858, 7074786781366394509, 15634023809706170499, 4898837957007600689, 15844744975808700817, 390847525575164812, 18085692917222692170, 3214633710999277789, 5716739820665318296, 63348494580365313, 3020400304882660879, 607738189972524142, 3443940450944203675, 15881503064634772098, 5552098941850988078, 9290710216213469310, 296915641757819365, 7070434908109555948, 1790837242415017211, 14625333403779272734, 725994173179639547, 14482331486641754517, 9528949187291341636, 18024708427413949800, 17288887229748136390, 8899435903106243746, 17988248052919925310, 6947402444577155041, 6102401349327815535, 918032569817073273, 14091169229233872799, 11678332896348850445, 16667100324871710602, 18115288876096386167, 13321458589949243965, 1376780814704062680, 11226929164225688342, 1125421141839018337, 12521336644420774669, 3682001341451127051, 15900803215858589266, 1303755909781032328, 12097295241808717981, 13453712991233606943, 7026470544640004522, 10100797219731824718, 975024424540019315, 5056532385317840595, 17368627541712270955, 16035680985794411722, 5191685044041583197, 16235840560737586136, 2515620382857515504, 12335718154665377412, 9544737571567727217, 4957028513530967975, 15302002767586093347, 9620354081560709444, 3374303816262012102, 17037564459266931463, 17870173137731539879, 16515953066203089454, 15562674195074515656, 8935015972508533182, 8875739945546909864, 7333409272073094393, 6788020331206760892, 11319443782736110523, 4138122615952700192, 18070206751546527386, 2940188139423456884, 11736344620252426560, 3955689805771896586, 12904996292254923461, 14498489684711778472, 7465801477785039214, 476293544341988621, 15863251123627035814, 13619655021727337536, 17848938041797888676, 3547454720950500944, 4020413785537927524, 13936795933949041379, 5075641280008027370, 15618965771410566540, 4101472574574017389, 9212270156760100154, 8555337216799006376, 9145279087076965275, 1199695991452739777, 2713922159954688000, 10606067813488973233, 10972936715516040283, 6899706460023528980, 17491134457648128203, 10151760599490889167, 5374984912989270420, 13366347060282661666, 14999762991372500216, 663520553837103658, 7911434487847740217, 1335775454177731075, 6970149221482062030, 13820800718039914087, 9335839211241611714, 17931193805554364485, 6936941694454344305, 3154923838389543411, 3660932139853271008, 10616240878179739562, 51345774210789654]; pub(super) const POW19: [&'static [u64]; 13] = [ &POW19_1, &POW19_2, &POW19_3, &POW19_4, &POW19_5, &POW19_6, &POW19_7, &POW19_8, &POW19_9, &POW19_10, &POW19_11, &POW19_12, &POW19_13, ]; /// Large powers (&[u64]) for base23 operations. const POW23_1: [u64; 1] = [23]; const POW23_2: [u64; 1] = [529]; const POW23_3: [u64; 1] = [279841]; const POW23_4: [u64; 1] = [78310985281]; const POW23_5: [u64; 2] = [8291383209427512449, 332]; const POW23_6: [u64; 3] = [10963214168556935425, 12075501357860292979, 110522]; const POW23_7: [u64; 5] = [6169747395525227009, 18278596701859697445, 10143526335361400012, 18052964393545421928, 12215257182]; const POW23_8: [u64; 10] = [2314350813275137, 2115025458154065526, 13012907653031611278, 3246851852016756117, 11806541200520375937, 9084306458261185492, 12980781886615526130, 7070004871468253888, 1638555456635168298, 8]; const POW23_9: [u64; 19] = [13383179381829584897, 4986775222005391822, 16749980212696255657, 4061598081123432621, 768049018947466739, 6592967522174005057, 8903351024578555393, 5486204967384814563, 6120273838388396482, 13554115592753033289, 298252933424703083, 5550726760273253541, 10004568017234232307, 10100413347317564558, 5353328459616604482, 12441875649480567710, 4272456035716489785, 7915690000692603790, 65]; const POW23_10: [u64; 37] = [5457725428155387905, 3409833822158792114, 3566505380784054462, 2655768856853172843, 13248675731579966520, 16540455438375496078, 15949305013218048451, 7541623142077085031, 4152324958281516936, 684303725534263216, 15539784438307811164, 17104371202110529069, 4199610698829860400, 126822483240641232, 12825510680015966874, 17554055574591513199, 12420795136445382810, 2909397580955509369, 16532645984425360835, 8048795052905159307, 6713679763399778455, 8784718149221564753, 8638710942521937363, 13517696909744801057, 10460807820795012520, 8671609146121531134, 5519177235896658455, 11507164353531136392, 10536607744046307518, 4355128376509778204, 14502975696374556792, 3603174206751281377, 11214401716978930513, 13457942323576995558, 4669213468679131443, 17865481055429874212, 4280]; const POW23_11: [u64; 73] = [11846125655129530369, 4808347477151537698, 4984465170536406021, 17773229190307726871, 9475540574276464039, 7490002630238673270, 12829219606569497605, 1855490239264020182, 18196368192375820573, 16807403573600054938, 169585650986432335, 1845707536133458874, 13880561038756938083, 15243237806662982418, 17942748340492775874, 16207312265816437904, 11750147279302913858, 9049742493468517337, 5322923673175149077, 12242456034673219367, 11097550052789754831, 15650059140797413691, 17451696301993982208, 1724791760067987189, 8425470383802962159, 445880095952832449, 12779890271826700983, 11510117651182442642, 811221383614412327, 11252917946439608025, 1966070912675922366, 9276698529902483041, 10006374879804156549, 12910054506401765901, 10935255376046483643, 17542193306785054322, 2799013365688525807, 7547447332198403221, 9611560566708938589, 18053657461852001840, 12739768537000605532, 15560568499051768847, 402026060965106606, 3813214866015313496, 13855420058731889817, 423347996799679577, 11974719557522547716, 12457578402889776404, 15177833050588247673, 17014151973003054641, 7069613605995695685, 14924754741116128615, 2833285700561124132, 14488631686198386586, 10053937439451005014, 3747724373394791044, 9081924864020352751, 3006643698446027200, 5686022571631760529, 6303984184389542219, 16918272220940077886, 522813575954678783, 3394026677636394373, 17739110856692301776, 9009777335823375089, 8767502255116089843, 5811942416715429553, 10946884817876382206, 15547247254446397106, 11379149715474961117, 3415855189674114476, 3865253181294437007, 18326691]; const POW23_12: [u64; 145] = [11622517936107175937, 7033721139220014975, 17462596640339821761, 13443677624106482132, 13859025874579068688, 7280878587045926646, 5383064232978901626, 14665433874378760711, 7894817074399567738, 2041528587491127549, 11289859072721806396, 15722851455311617147, 17458663791908953193, 11373112974961266550, 17352366949201397809, 13694086727170229938, 15463470048916970364, 10570279842741120227, 6648193649700737751, 8601822496984129799, 18372388903764790934, 6554882423490887366, 13042954592236188882, 3808659751122712337, 13864998361267667814, 4936550449154763745, 1828997440316703799, 14178484846094336273, 8300160226004005939, 10650947050425965462, 11583438941158443082, 8522319677650037649, 1151356073008628140, 1868932738148428389, 14506340656346284949, 11817243760415981359, 17232585953382863483, 4753502805182177217, 12140144073638385110, 6047777126866781305, 8813512867009582516, 16214160100477068190, 11804216147256631092, 16758964429489891496, 817329583528750285, 10447211405305514968, 18187526514453193878, 15053852564892683104, 8972529117610110924, 10074677660977770203, 2060932658913772713, 1231641879598153894, 149117274952849823, 8839750144015468931, 13870849855808267005, 8497006295516812096, 12073998247659205592, 5227293461699406659, 12456857656474561288, 8071942982843138162, 17759584873234692073, 12408149989685761605, 966007088006790208, 15511204086555671740, 2111665739818137977, 10118791289794325443, 3239481064035042212, 4492850046702593696, 13966441049549479584, 8189105420526375921, 13025230708727756685, 1193466212743701307, 10414023183316180801, 15671669769341094794, 11459894969881142504, 9285576284817450377, 12794423314985937539, 1582486651183691040, 1233523445429108177, 15381656572259224358, 5839925333982045254, 1160227998025674076, 14621523935478174951, 11529055784409423191, 12535556463298536878, 11436518289385212637, 14678182288623217538, 1552974345701158423, 4147998753782449281, 1927652060510564509, 15088149282793322569, 14255865993427576407, 1023125521444459005, 3970740624906031112, 6047967177082775951, 2339662716940436578, 14355512922095874245, 4822772729108678019, 17320001634075024793, 14809631814461679339, 5210330158728763310, 4884444728559559679, 7018200998928663501, 4298433382992520523, 17042941735629279971, 10927395923749774306, 2302500185014965096, 9771934668912536138, 3884184797462724965, 2168628345276262561, 7005561876375487250, 9886177363664049122, 6514828189616609185, 7449477772310456349, 15522543591036378582, 7825624973021338899, 1410365973364396176, 14168293017624070645, 1640393222821385990, 10010974317741386045, 3623106050347539560, 12167346593779104567, 14151984978845758374, 2484940957914386867, 14114413731052178462, 12818973764128383727, 5194198120907027631, 4770998095731015738, 15004991160144901317, 12053912103781953592, 15326435702098550204, 3772177951370317322, 8517749116120725318, 17878047395783878861, 2238926480500866659, 17793138211716196325, 10628224830211866604, 56513344983428023, 17124432907531586525, 10482976782550925537, 14366608740333918588, 9778100743842486673, 9759653953317335926, 10589425421842329905, 335867610689676]; const POW23_13: [u64; 290] = [8394090400973619201, 11964303563521419425, 6680726081226746407, 10953973454617762836, 8204153382229311332, 16254041314256517652, 5382403309283490189, 10294598562963672778, 6611673214344934182, 3108252571142423500, 591264897553799654, 10077880485074314447, 3324111534544969485, 9312594108209533062, 17640948814700965781, 6012379191488054550, 18444371524971204512, 132618783111387324, 5019449967207124897, 3549205104136494386, 10235095930753063619, 11320997397158549987, 10742490818317644895, 3187751223385388430, 352423585976925038, 8780916933321333442, 11561688232024544532, 4202008599615167561, 4487691813656735111, 15134695176258169105, 6690960709403211122, 12918310920993471271, 11635100276931512145, 17857812523909118347, 5686500615257112446, 494865271069226148, 14150027739975964006, 8995172384109705470, 15431220502214132213, 3591973263550772996, 16271017589500618733, 17711203169741269068, 12892034546770696203, 5900598767950539192, 14193592364934362760, 14901999759013903579, 7732732328927894272, 16475560904594101226, 8078965955741398752, 977645218519838711, 15832342418236883999, 10072025098841136643, 1358419459364144280, 797847689283391326, 14659537555179771844, 9896675821218330168, 15415516967802058517, 7968045175669056426, 7424233202721636956, 17848094697634144248, 288525173312435345, 15810972518254383115, 9299311067109640492, 13667629587352480006, 10303757103824097738, 6600213728598220514, 6218622672662595799, 3670031549674590187, 9716451342226392591, 13877815784478946249, 3113816061294914377, 12653023432091871432, 4481451666031891832, 17212931850927052728, 1308733032955890568, 12132175452048556703, 11965835958759012878, 16435282950624677626, 4886753010812848853, 4623306558254786620, 13328724565787069334, 10052593477402542792, 1287374823782162814, 13719253410664960848, 13940737455354227577, 16156794396241594726, 9406872663445041426, 14460695329812970433, 8147602052595626465, 9759086079357316460, 10770202697768734650, 12141428714491122492, 3479738801678607218, 4116552336811862093, 4664785535989027905, 6781810929589108561, 1453495303439479551, 15755570378614253759, 960995512121360650, 1320078744371634240, 14071283408344620583, 15873589170615939567, 11844318309681113006, 18209960901656184091, 5509787699837863735, 16057237111836286318, 12144799626465867039, 11301164228354554871, 15538809017861144326, 3881789278651060396, 2083726758011249379, 7242075601495698008, 16929003188024569952, 2637582047221593007, 6164192295857524759, 4324715935100466646, 3442312090445348770, 5482847019968621410, 14416139992674855236, 13766108847076098732, 17515176161144990062, 1472195265852816965, 9558656307272696327, 8860336721938319348, 10424050158232995985, 17735942241223068755, 11554220001439961201, 704483198669109564, 2932341443912568886, 2824738056487663018, 4281496866134446893, 17265437450258721953, 3681879345413845992, 11515194834409798593, 985765253142548197, 2984023863142018257, 4834135584147244310, 10515176357474522511, 7861156381474504930, 15513420229788668624, 5820797276345237369, 11750855905078856569, 12777784995909442228, 16086254035200170068, 16636829547693408883, 4302160437312317603, 7894749045828366333, 1529440129469432054, 16283118102972817572, 13551968615829143045, 14141755494036163869, 10202408444107256095, 16162673438713215156, 16480653606869029657, 12896873037878662327, 15675140110468513855, 14886915089358542684, 774257548144727721, 3121297763916484210, 11244674068351451742, 6136457775661368394, 8276608028813063005, 4328806852273184293, 10725793814173142373, 8713207349328170016, 3314496893276770994, 6467297917521019219, 10832668641628016315, 890510633050784875, 13522061147310988258, 9295062529110389908, 940274273173921624, 17713793344650807607, 2144115015919032862, 1515271528422120562, 11617268519367395431, 10225339851466026999, 18356608905542242762, 15747650718811748381, 14361136259390419567, 9521043180435682096, 7032180939671307649, 4766943856803433589, 1788903151609336531, 3067111554243386815, 15396974384403506303, 17635357051125839211, 18410171674236714111, 13006404946048489254, 10175048494319231069, 13695997532684394127, 15701030627417961230, 15625543174530632057, 11047121066749531892, 17248796765549407344, 14686939862573595225, 14467382368559107625, 9735007144341017943, 14300551919264430841, 12199685552486464333, 7976771866390972828, 11019782864537458767, 12325239107485025410, 7336145268816036435, 10317789320724881313, 6268969282673032717, 11187057720524651362, 10412317757966782720, 9957223876294202238, 14797474393797369649, 12707890408232218246, 17954169933651423542, 16261922616103793114, 4333510071491197126, 9148091121522839756, 12080381731581946005, 6771848631704086130, 1804305449358901527, 12855875845526226822, 18335367474036144797, 14793893678735463667, 10645700488999161160, 1895996504247616045, 2382164017483054973, 10552216344087268433, 9021719584181091192, 3380188034160414725, 6249703865004425795, 64414635892261407, 12377384963568233814, 7307438968304536980, 8966232128834474186, 6786257565852201597, 10068981359548525447, 12985487761061821347, 15250068204821929612, 17796166089646982811, 15383811979808576214, 5387278521333793444, 14111476944260561375, 6563576519556684180, 13695943457067318209, 6918562023235029062, 14754075890773412567, 858163115551518614, 12023362342021158858, 3730097749382796530, 15782336360183107402, 11828711242459787363, 6771555216470897935, 7119406591441040624, 11698872050004396496, 4286498256299825297, 14024971287426850410, 12627222004472030216, 10526038749734500455, 15799257125352115074, 16543575070263732648, 5360930992960858150, 5480478235630490088, 10740957876631647568, 10856615013881049128, 6337895592574874879, 10548351078802045249, 10770232544197542452, 17203053735917901567, 5544703280273301876, 473028986463327892, 1992348869891386479, 18106593888504158793, 14963463231368059529, 16888696108434515023, 3701215063285536555, 10706766752220176757, 6658893699890277224, 11422230761371528275, 13455493321187216777, 2936016201779625065, 10645596013106226786, 16327988970334155784, 14017806230973566932, 5319754173859118381, 6276196983172202503, 9141821856366243840, 7861511871015121036, 2669567714201173617, 16996968587538889159, 2361484064688056998, 11927883869173258618, 6115282537]; pub(super) const POW23: [&'static [u64]; 13] = [ &POW23_1, &POW23_2, &POW23_3, &POW23_4, &POW23_5, &POW23_6, &POW23_7, &POW23_8, &POW23_9, &POW23_10, &POW23_11, &POW23_12, &POW23_13, ]; /// Large powers (&[u64]) for base29 operations. const POW29_1: [u64; 1] = [29]; const POW29_2: [u64; 1] = [841]; const POW29_3: [u64; 1] = [707281]; const POW29_4: [u64; 1] = [500246412961]; const POW29_5: [u64; 2] = [16390320477281116481, 13565]; const POW29_6: [u64; 3] = [9728714693370925697, 6745052611261206813, 184033331]; const POW29_7: [u64; 5] = [5757371679635727617, 453419600393655919, 7471178055056504086, 16196800870886799471, 33868267053539148]; const POW29_8: [u64; 10] = [15498448609686505985, 1479573139064493249, 1836875582269835795, 1814411116202214481, 16009278822815034249, 3793936265448736901, 7182808813944114636, 17021911425577363478, 18016738525341173714, 62182220809613]; const POW29_9: [u64; 20] = [16095552165416375297, 6065906482531612469, 15846163999557365237, 8013973177636272531, 9907319438467333809, 1691774050185876939, 1506028245701941645, 4265451072064456439, 3529530588555872352, 1638853873174462591, 6883747855773278130, 11889568804655462422, 8456300052243942764, 16223290542744403653, 2762925283991841243, 253267985127962974, 14089073124764984418, 12127786193190370253, 10931184201498586925, 209610355]; const POW29_10: [u64; 39] = [7418542219833059329, 958377938827997701, 12488373186104909143, 12529661491707363005, 2460871112196890430, 13301540322674214688, 2373733691634663140, 11423959455316010393, 18281459953449138674, 13513136808894472708, 3823417341457510714, 1658370468200076063, 97467081071724554, 7848891007640526021, 17045665495969248851, 12096572349860687818, 2344094882925129526, 16190726499474487633, 8661974748470910973, 2574678668507283601, 3938614083820384558, 14341609184753406313, 2327685548231144915, 13092203624281047501, 5927048675101651312, 11029220976556497723, 16060534061541073881, 12814669207404065063, 16627810676372102119, 9026340843146512580, 15159190325393838446, 4023118401698046761, 11640539626749296523, 1550915222204822306, 16884085217527839713, 11861828186682004783, 3690204447908116734, 18297612114356149756, 43936501171648119]; const POW29_11: [u64; 78] = [2994516997653811201, 12691238007485188813, 6425373631596055902, 15742770753423678927, 12204372028205694288, 5468214848723792535, 9013064258242214675, 3705670445566310522, 6816135216491761480, 7579681604803045464, 4606613900336899030, 12532494192450120462, 10977305613949161291, 2925401003903444641, 11434821894394303238, 6370559474830540587, 3613465365096045323, 8572921874219622351, 17686337502642682630, 9293099978060864798, 17797128149100621552, 16155222522427697112, 3181967258345772623, 17295243910487365923, 8334446766563669130, 9987032240221668744, 4134590021599940843, 10649547782386712269, 17907870508952217684, 7350151663967192535, 13809504305637163343, 40380992378335767, 4555217157101625376, 1657389040493062985, 2448044455405957695, 14590542673302313551, 4276642375845923056, 8771354597287485314, 17699373990153521820, 9154659546877076733, 12098470914195334408, 15510274657315649565, 2945274152627196618, 15547292285751739089, 3863178779199140492, 18239280759876840351, 8951674302212815712, 5207549104253473993, 12829105964069607756, 15630099553755898378, 18350513890796580112, 16016692600961659767, 11181977692592568416, 6673218275992797930, 3690766535465030925, 6533794652243942130, 11732497937469914712, 852954069083677346, 15781580274925636218, 7313857007886670976, 16710172042874726789, 11335644921839334192, 17642364469799383421, 8287572863569889806, 16034458160023464806, 15733292827351475864, 7974299796479031730, 7044659385783483718, 3797189105432088351, 14466915282265664182, 17729930178773628819, 895573073497407671, 12206919607548026764, 6507363199240370486, 14755257268128867927, 15742062737932432583, 11995317340732918802, 104648068379583]; const POW29_12: [u64; 156] = [13624873453324378113, 16385905459755676464, 1524305801788745086, 10199785704783688521, 1105651907887017695, 7899244504136605362, 18415256620208376992, 6527880665753083982, 682595803567740022, 16971614856922076940, 122533806241893053, 1353874090500713666, 7700237657957992551, 11127822942621606857, 1117749882174310955, 1258597230258737875, 7588632863614073926, 13138370241566658389, 2944598617928471419, 17686360850888548584, 10802613354916448913, 3714169153408764353, 6097871342973394581, 15861447995882643160, 10529542217748913313, 5856668093475572493, 7687895863558019677, 12605086561069481807, 7359120490786328322, 5569552760021637038, 4610304421820188056, 14547599253888017465, 11448162300671493140, 11818860935063076787, 9024368236844078846, 17611918172934723031, 629058103025294072, 16402630757077520187, 3011120034874656385, 559434539294690920, 7708404193241517444, 11475885645249324855, 7527987534261502946, 18429346260451766463, 16647774408649527759, 14994162011800902093, 1602818183595944455, 10416127526769434021, 3902238027102980241, 16221439502904488789, 12728402492485944773, 16073041623703233415, 12059726721016275106, 7545575059158739724, 2799238940044439918, 1672337105562087992, 8637211310967344193, 2407781877381905680, 11081849713304248562, 6021357575086118725, 7805169637362728481, 2625854993373891686, 16225294581782396586, 10062522529509829562, 2491408246686350605, 16868477542775958185, 5432403930965842681, 6401086498452275312, 12923560148084435631, 16773315028203435668, 8787070119132526524, 6463823535577679823, 13155598264862568438, 5435953435295016479, 14887580091845909428, 5662240093801646219, 6061361103497749674, 16748987890714927578, 8380355601067159254, 3333305983278680362, 5659126067788145105, 17749870175532152657, 16165175331899768700, 10227145147339710095, 10044125302402649256, 15178477263894883824, 10894099044530456123, 14560109165216863917, 17383533091118876692, 621825033718554903, 10839534769243474212, 1967962613229464445, 8169873286726584084, 10782901860247460926, 17093800990823904246, 11498611700774056582, 12410146132732634389, 7417803587808478058, 18297046186195412975, 1574754350240276490, 13353046326481463290, 703471129273705839, 9342410231302222619, 7177988852693229323, 731499736917740653, 13443044161710177268, 10283780089535375364, 15978203559738560802, 7963817190382519294, 5669156970634321340, 14472164925629166220, 13004679628433896001, 9604961982380928881, 16097595907957091063, 8580674506874034541, 5991654135140835361, 4486972720692276001, 14599506547892476808, 13925166205172986588, 11489825356002091398, 11118067556437148191, 11395708967825186605, 3829509361757685613, 15256482687844263043, 16220636668955199613, 9899470830714797674, 16171116048998105055, 9519063829182808481, 14866997540493315924, 16868409756818216339, 1021202624840046466, 11782253385860110106, 2818200589100936468, 12919226415367876759, 650908069644921607, 10017441333456359930, 3989108944068656321, 960976354279554772, 9757599012852014139, 18114660057832184138, 18167793868128559825, 14505503950682026051, 4506577842976861893, 3490506407674121260, 14721352082457615055, 5606132434995114951, 6758734482506628989, 1949658512938374708, 9038022040851963244, 4539935154943351555, 14491940671051821480, 13570801843566854467, 10590637167428855161, 4113671608170033059, 638731029910275814, 593666729]; const POW29_13: [u64; 311] = [13672226770128551937, 4294585427239528572, 11937131084527655176, 17121705376405822666, 7266228530481644789, 12046326213228550475, 4555057994774087724, 8142229442681275952, 14928982525547024142, 10590848912065017772, 204977530255868505, 18394854911726948882, 18072147853711708396, 12984137044024706349, 13009557613879130662, 13437977536707178674, 17194519815234671567, 17880973136611499925, 8740997228436187796, 1053992851950062740, 9457052323001348307, 12635519821631166958, 7816877192318698506, 718974763720009595, 10506931626216910574, 16677486741239744144, 3231254992931774931, 8235433747461888832, 724496508110913891, 13418937453673984204, 8909291817057944420, 14418648484529316905, 18043014680750553541, 5725476447770531156, 13071604278662220441, 10277659562569596333, 12018124774190765506, 17648076272580958966, 5779739214397276354, 16650875990066234185, 17578631890048416051, 18245706186939598453, 8860678737288244932, 2108635465551665383, 12676314908233341203, 4285804123234359081, 9277371795036436264, 10891868801908629004, 13397489614092183722, 15564677338119485008, 9665683407829948339, 5488201562995831037, 15013749743704512461, 5778162266745605791, 14886812807808528790, 168867009872405748, 7700062651581741459, 6387875535489181056, 9217246679453129609, 11592490233993784416, 17456249849289259204, 7719671028608500290, 5776354603165235091, 11902258013330924579, 16271941308134810423, 18175425490570157612, 1348150720221513076, 5588923701320423310, 14347935746438536406, 2596293928414773985, 12999246088959114720, 7853618653032698111, 7428832709538391314, 9170615543668590681, 12873617114721415899, 2287308408671855195, 15460664247921730262, 1081523048631284839, 6151194618794128608, 11273222781436349088, 13797604919627813256, 10624352073641598508, 630071154717618278, 11372236940584293328, 1075063172784885024, 5353969557588737765, 17451750398327390218, 8847663264773559928, 14748776361514840683, 18141609447845895554, 8182248027890039495, 7740296117300250315, 9983411951252605895, 8838835298932336410, 15822882019381304121, 7494054417011587712, 9900741832494288950, 1884928955842835785, 14171827897630066950, 13979799510826257080, 13513518815078312459, 5547695969646569639, 8530956960051361363, 12925328754320739957, 15636981282003148604, 12380992638017772181, 5493876552103757314, 215260643889624253, 12599522812737008379, 10618136163261717865, 865812928187561342, 18164096494692425166, 4255258782059127586, 1482350852033754088, 2695674783092434476, 612994748952243333, 5350516409712278067, 10643337985082357108, 7767606074667599560, 13335853206335095348, 17909273832462095134, 348073511241936160, 14336337316615481341, 12294498444798592895, 3468077374887439958, 14752296701514702839, 11605240111110396223, 9912105850349709991, 12222362274483646114, 5500320934311332049, 965322882796551125, 8120198151864100986, 10385638565545610254, 11099447317438769075, 18145701608326972194, 9211397194147565471, 16133140126293610187, 15479595949832460983, 8772975857916812745, 1084809613596598881, 5209298234534478403, 17558147171719107828, 143145869814217375, 10856698203553984473, 2659417222261508760, 16776485743584819636, 5302132120190972721, 4179156032527653547, 10978123522004167617, 8616903826794857138, 16682110447672369644, 17408038179970039463, 17186638068325799623, 12586354934200162415, 2233353304839136470, 4604182926246550683, 15020945466130945179, 16882044374210881607, 4338556115610530951, 2548212077346936596, 1411947313359297892, 10760208517239011678, 12093507522709487357, 13250275519469800494, 17582234765715613618, 2587511047896745958, 9212232785325628779, 18416663261885415016, 587958984336727576, 16770327872208757326, 18029866150989284266, 2155188481720710192, 12170084941625609208, 13109309650505330232, 8947648203486222025, 5888408458257150024, 14610620042876969685, 15423269234038144149, 3755865284152467362, 6346866449393971611, 1048506361728426237, 9870704850560462772, 10902661774531812828, 4199023600185360775, 6841388119581862720, 13682397273260178435, 14451847431964184851, 9525153246333444962, 17005489543042710365, 16211222296998776081, 15260265402027014562, 7763125742878812795, 13979706248482079267, 8676877617572732607, 6717568554186988777, 7451376909733293094, 12743147316357600209, 14813987449073120918, 14803395224357306623, 6217191927361854763, 15651965812852718609, 14440004895152758631, 13270702150255333623, 5389827381820702983, 3735068664526592820, 10857318640694862193, 10376694890261332559, 3933073728848971783, 697722641169826892, 16654090227270876633, 2460452273549607042, 8139664584320228460, 12550749769392292878, 14691474813019701742, 8199888084316731628, 11707952462140957816, 16114347695442949664, 4254129723503068617, 13905886209486906303, 1678761750672668626, 3225544376917705027, 4779593219040896651, 4235756478245421233, 5843573772009581114, 13665134646853522957, 8166624769996657068, 12911077716854219395, 16031871157703988923, 17416979802078865491, 8935601752687330771, 8735956307554644333, 16225905211746171707, 4197301432305286566, 8217235209443529821, 6568145665602340166, 4703736038695943549, 18166481118991346417, 9055754601443772842, 14714094804941228956, 16920404788456306665, 16524115921513210483, 641311670008165827, 15278175775893318136, 4907119125081600753, 5470711230848082435, 7100440935018849813, 13548915853787394088, 13590896704726324215, 13419458591969809595, 12770517692189405268, 1682411139436089322, 16204267049714979529, 2130875000887245762, 3898148472505848400, 14808356779381968102, 12947547547530892128, 17093910043024869675, 4525420012639340544, 13406279992640413066, 1729931621875839983, 16399898141312950768, 7129430414049908823, 17055498123847510422, 5949333034669238013, 13172939620181146406, 11403868551726675873, 6758381945319437250, 4959899602116544640, 3030437071703111193, 7620094948025377385, 17953437088637383479, 430815515899335460, 8526143794481228897, 2011335460140755665, 1673153626059617351, 16611732881434813086, 6443513401833815128, 6356927152578677596, 5197550056219683564, 15117200294690211492, 12015247322584645921, 9143591408719695076, 16336687030934349149, 553766647123672757, 2941286556052681945, 16789397649694586286, 12086132202659948792, 6535544241266924915, 10218166389643100138, 17860728039428683844, 16698865587722179966, 10428296414771730021, 2472961343093658568, 777962589860353634, 15699598097617775224, 16945956761022060145, 6034890250215295206, 16824146588235996674, 11627609953984916638, 15085182234564679451, 16046485513580920525, 5649255435865038088, 16906305800633423485, 18391011698312280946, 16404185211853238423, 4822232346815630437, 2160504333581284492, 7990377947715144481, 1965670057026283843, 11174877963137540449, 352440185162671667]; pub(super) const POW29: [&'static [u64]; 13] = [ &POW29_1, &POW29_2, &POW29_3, &POW29_4, &POW29_5, &POW29_6, &POW29_7, &POW29_8, &POW29_9, &POW29_10, &POW29_11, &POW29_12, &POW29_13, ]; /// Large powers (&[u64]) for base31 operations. const POW31_1: [u64; 1] = [31]; const POW31_2: [u64; 1] = [961]; const POW31_3: [u64; 1] = [923521]; const POW31_4: [u64; 1] = [852891037441]; const POW31_5: [u64; 2] = [12662688596514954753, 39433]; const POW31_6: [u64; 3] = [3671467063254694913, 12907182779550130112, 1555015626]; const POW31_7: [u64; 5] = [2398592399778478081, 16903472776956642306, 6096611049602248745, 16636903787979198184, 2418073599280260060]; const POW31_8: [u64; 10] = [16495141226337464321, 5497467942242379092, 739419886143237049, 15503879009878095970, 11682331906096634316, 16633417005805376854, 5372896706229367958, 9202442005912433102, 563103204607180020, 316970838223396679]; const POW31_9: [u64; 20] = [15485542806247563265, 7902121530818837975, 2174706260711399794, 8338441619710993323, 5174276498274060584, 13896057508626164711, 18375211818704524752, 3771896122404979996, 8975237466821512923, 3719531891742392080, 16278739063660681217, 4597651131527345692, 2186070395957176618, 13296270632358335916, 15407783350388521641, 5218389564425962599, 16684214730241765171, 12778720639429264303, 4999906995294690253, 5446517384454533]; const POW31_10: [u64; 40] = [9917852350074830849, 17503880052831590204, 446078003314555885, 8290200544094315544, 4545662562678721248, 4773755696042207422, 11638197421469811125, 5583541543002688187, 2928843055633941976, 958885388170378936, 3769648711024405821, 5876476779803596179, 11002952954355201516, 13871000240735738927, 17280625944737162989, 14126363476369511686, 15540015784356269088, 16121873610546913654, 12315657342730701215, 6625239742322092255, 7267729338210329014, 7304834554893687532, 7448184685073964747, 13915799753354305463, 15532808105003034689, 15560148693948667263, 6702446356212876218, 13874950973356027931, 2487265240908372712, 7423364546851580592, 16542076444295774186, 6667557158368925022, 1662731694557479534, 9710460046131384926, 2132134259642658908, 5536099200409622432, 7079630905631896838, 15765425182381143449, 6981407756766447719, 1608118565565]; const POW31_11: [u64; 80] = [2096357348270899201, 16522211005267270321, 7477919505160117322, 8806055114386868960, 3103435049531657831, 3379991644164106799, 4737739374697149255, 9945960765085644629, 7776246301742102048, 17399545307872502909, 3336726592735577432, 3519304755566256320, 5275788180193374204, 12928214378342167617, 15534345485858271159, 9401077179437188119, 7195141385339960711, 7142093030883132565, 14543884843609752529, 1217720379423662081, 12850287365802214228, 17344347135107428951, 12599061754132488689, 8259746063225165422, 339910009266162020, 17918745758552077552, 6268582040783762747, 5426821636267775363, 4395733309604733570, 6358602157561990726, 11221739565428542155, 2749886157802053331, 3189270605149490673, 4790389046718542725, 1175431124796898032, 5749001033556578690, 6912856700960811479, 4968629094888695034, 5837635138599290090, 3776654629561458848, 11336701517692035987, 1984651411556410646, 6931043715203064840, 6837691805643163316, 14367990737348130710, 17276342136548545114, 3105185803291383662, 12596699258178437907, 6470695596657158731, 3602704307378790153, 11572324985684752652, 11114547972589521268, 1092394893621389626, 10841797182274992700, 1040880730761485215, 16711988749278589650, 5975456085549041101, 14905526063676943009, 13367279695703674516, 6835338110419533612, 18343405583925227682, 126856704539218164, 4654555027808343551, 5185799915572738127, 15883434376460367703, 10459236391563286876, 9723337164163736994, 8768112576670327395, 2997638480561109889, 14755828647425496405, 1773069327573470181, 7247206901800033682, 11330645768649999049, 5069820474999096624, 5080077807929860435, 2674467631168657459, 5381001373866890151, 5389434896896673945, 14715966782098618198, 140189]; const POW31_12: [u64; 159] = [1801767598626373633, 11369215895344178997, 10557430481523398302, 14729514228510065525, 16360921955454372649, 16474683228536923574, 17648663066377562214, 4616891103789060010, 11068143261721723115, 1986645887088002957, 13290878115429655256, 3688668928960070024, 12512281909781684531, 7202283709776267072, 3967537723985850955, 12079529339314160258, 5789930103522033008, 6446685030039335642, 17807119147724672441, 3657430757286952433, 4399435073983627112, 18080853932637710552, 4422312687427527790, 7041879709312349878, 4779369405315517716, 17761075356942561993, 6886785584079733145, 6856167696222472649, 6677149285262446585, 14128635321123954901, 2647749906943380861, 4947686821001308616, 5044767174651025699, 2000890117376226065, 7696974985933478928, 13698435522203632260, 12508923657400466359, 15708418517218618222, 17674087902574982192, 2599698632235115523, 2009487300431793372, 9152382659123644566, 8381623589094130620, 9360768865282788157, 7841634244523839263, 5142811084696223554, 10567527345171480010, 16587773482736315677, 2641488119964491057, 11283016081783311237, 10720423912347695400, 5033579150548247328, 13355273399754189136, 51107983476714371, 16767129091656895127, 13287727447102009689, 17540684169108840875, 16056898477225800826, 15452534119249468253, 1584338096418635712, 17835157847873868573, 15761939049259095748, 17731276659510811437, 15878595503172808064, 13541637914930966895, 13453653161442836461, 18167456091839538328, 18255511530115413898, 4918856903308235200, 149229284494812489, 2557715426008933344, 6329903885342108338, 7318037208799124842, 2088260064299365610, 2541296462169285780, 381201140083506486, 16076846840076350151, 8462873072785783617, 660968055866686239, 2714493904717207769, 12375607733044388010, 5072867669619256914, 423086081630114977, 14280478669225037932, 17938032817920806759, 18247594851371119991, 16179063841019022056, 13021457957149068932, 8911307390539096499, 11363387932840668312, 10741435924015807141, 10029008094449397314, 16074918609567735355, 3769485278193873309, 9755372283020856168, 14717290698284082587, 7570733972839733749, 4298417382024000897, 13903774150610302172, 15293354607334066454, 528520764411840191, 15390551811956009819, 3379881677203840025, 13637932214547525934, 17660189041724368123, 11806060371417074758, 15647766708173899796, 7670709915778958063, 14579010623960808134, 3115030890575484558, 6390827240047220130, 3093427188698038429, 18400204352832039125, 13284388778413708181, 15266311760490059065, 12555628412866282735, 7422734806867121800, 9917331904149950467, 7716622572140393442, 4308002630539149169, 4299292758073020141, 11078221702723102710, 7192518176606606762, 14435348804115821404, 13062353273716910458, 13994439988643223997, 78194093488871065, 16673842407064744836, 2523733938373131892, 17363625493235470610, 12985783305889285413, 5814006926820796127, 14725299958835250512, 9524704170138330948, 2092960985130703422, 373732450919540444, 8163480067992673786, 14148234157378013578, 3255522486897147875, 12881327932855308105, 6404382367598296653, 8614596466670346051, 12047324956663877009, 4172218920524389996, 4699362730392253186, 8713226888015588849, 3933801823730961601, 9823349397494488408, 4982238783101836982, 11481357151755968809, 4766978584604408965, 18106032764723837673, 15784602917188118646, 13418700349702360957, 77586404521456507, 14219791363337228746, 4890203053901953780, 6486956095841198351, 19653179394]; const POW31_13: [u64; 318] = [11650932410935017473, 17308825409233552681, 15496923541467448409, 1777718871702572849, 9922250554759274416, 12138026234393869648, 17452061592037372959, 8941120299606061452, 14366819422178367459, 12093141130691423854, 6120245025799833153, 4040279058952228412, 16148669873983246463, 11638143459508968866, 7154962979814798744, 7446144282266149209, 14174761033366019694, 11005543689910023371, 4128945788305534352, 7916440503096344475, 17070759717638194282, 8317155700235419964, 16931165184121652232, 6107946258706111077, 17731633154006971892, 9975717563530952164, 17543341719370900445, 9068983835221482709, 11415618862125602468, 13941086487558922704, 9635074152356732409, 8609049941205301246, 5471271126836396598, 2529439458376343483, 5604462733361525308, 5071787135380346645, 9909017897886427767, 15318475760261214863, 15316661691465834839, 7269371500803889962, 18032035088825185820, 9351894071296179180, 7343963840109365284, 5474046747747064192, 17481971361736150682, 5824250518798481785, 16255331231101793892, 11457017040634759339, 4426275110417427081, 1672002347120187444, 1975148498547535928, 11542057410017607813, 1220219139718878911, 3572598416877263916, 17006271185639766323, 462877625934666647, 5946847649902211805, 10990578101662644446, 7321273047908499993, 11548771999759168406, 4552759373643571249, 6618206790756389, 13316001433771606947, 75035747373599413, 10537200199427443702, 840767934414474190, 2777096646401916111, 17012900311823701232, 7015161044925147448, 6556613106909146969, 3157487824339572799, 11834930013965627207, 4150587971056738845, 4060390407706833438, 3984973614331228862, 9699637788294727825, 7098321630753042945, 250364221365032952, 12893847110117037419, 11924286071111309505, 8393083471154342881, 5603413628441508744, 4312581983296816308, 17817980376780588471, 7428707413480964562, 13790918846651350003, 16839134508576563808, 15143176246629895881, 26735050067619462, 5603585605129569706, 1750160737609386776, 13568704574413602334, 3781635003327098853, 12897395712756630425, 2729856571522370295, 2992033563406299606, 14195997516689513778, 7401541414450269, 3031650221770855130, 12559199617131004638, 8885318091262764443, 7265380638052772864, 1962471378061357844, 3684153597631553019, 10238664161660321918, 12783244908359269213, 12391242514324497954, 1023711264845355161, 12452432713654839765, 13284783342897209511, 16557260712252730343, 5308303541438704709, 2796444403386340288, 15964531828291706736, 17988431333681334980, 14050372967446057331, 2909153184171088974, 18271130663105232364, 17469865582643271403, 9235655978445445898, 15404258371539441145, 5414561797197130298, 12710970338328138283, 11348287294622669205, 13279912660231133205, 10006247474864908844, 387503936696045632, 11946706255639811710, 11557870632698008761, 17437329406201043082, 16453976559258974555, 18392521437799244418, 5518103827549465462, 3974014970850441837, 15906277221207084410, 12801233926930718584, 4858365996896405222, 9322063613169093288, 14295953691080547753, 9592792123651163696, 2307344178546710630, 3386463638913702994, 9746093064647197259, 17360792881978099646, 2331390749971078807, 67001271839132128, 15325146603819551287, 2212628260682394667, 3686351591055346926, 18444798459840663871, 3754055313895642917, 3111892272160209815, 15016905147277324996, 15249576022718612023, 9687562159637011466, 13620931157765942584, 6190446801315715564, 10199083049527776302, 18141268778130065839, 9194745994890263134, 7235857422137094771, 3039910200489081515, 5415376942362531145, 16313633954549303183, 16461609570472238153, 9135277678097989755, 4294200396551742961, 13873006430789283232, 3023341343724205072, 16180504954216000185, 16609282451833813517, 16147311299516906931, 3865431442196887781, 12056989559936082473, 5047870703145606460, 1325407901341138823, 3862762561046689086, 12154167808814600764, 13559820430591455007, 16360437559998671104, 7527717115571819358, 10716582562115872527, 11456000201504763720, 10701796272554334104, 10721370524245846060, 12741499625978911616, 14421778075231438768, 11779380118632710772, 5424719334131978781, 5139480536351736997, 17661687414527592806, 11683842095404036105, 8502752269926502292, 11859733037943709207, 12494735198665940265, 8407405997702413068, 4768364384316304380, 18319322834390557454, 8429150892580430029, 9956937433087180707, 15428189518856272765, 4992651218965591961, 10432854511240697207, 18332416995451783647, 3108194795607589285, 10895053723708853661, 2479127734352181541, 3680448758879590275, 7893151660183717273, 13698422782505760429, 9058264674841042271, 8173577806118979126, 15059606718923206684, 6303849893315995452, 9663435245565856532, 10386953918449659613, 8365072188147552061, 5909105025045825689, 7505410059121943936, 14835187236522959824, 7178542398798756721, 3244101273793333014, 7478293355884534482, 9936708530048724800, 7214296726988684118, 11442302058569190230, 9285606747893989774, 9168915157885784775, 16961770236320521450, 10874898498687269396, 16592277389624644429, 3007013275672248960, 16211270761002642645, 8955452119018187856, 1991548249560329806, 16983391470441275738, 156816301123428631, 16056306118076063989, 3636726870096591928, 8947421734000646900, 11102942016938080406, 6119525769550479573, 96726746357708986, 12936505540798421749, 9178050386743348451, 5620134833181442437, 11762276505007076755, 12761772344156536488, 3679038526545223637, 13345584437885106473, 16425398117968312468, 15232164270082349060, 9367625489982087631, 15526319758859232235, 226839740591401608, 243271890237418965, 6068791731053606502, 9016003892101302373, 16144441092544578465, 1664847353881709656, 17029558723917215874, 6610972717941396232, 17795795228359356713, 15173020102679721202, 16500332964522840314, 13262352098506638269, 5415683019436064276, 9845938604751972372, 15011664267083886298, 9302815697041392426, 10134461814529250912, 13782101968955909012, 2357979049692918364, 6720070569549937826, 9714100880431638078, 14744526615439393795, 13157593180412954939, 13358340127501549181, 7202587685441141744, 3998092887006896176, 12440695122666175631, 6060298862568659312, 1778062782693401036, 3101316331066515899, 15959362652679781172, 3812580654417274552, 3179751990173014075, 4800884105328080242, 4555909187188415655, 10019168566451086821, 10203906477086999803, 9709465268035298374, 8222943895049045865, 13975784716964627816, 14156811051863448914, 5613088360083362056, 6658023700600195151, 10260390177620906511, 7253822460209371436, 2005358072289035384, 10384255809604537396, 10612173669347199378, 17872559304263195172, 12918681865001345859, 11169532485848227142, 18410164066596640797, 7557387013661437005, 8074018520354688200, 1695402573163373447, 2388608657305224726, 3851803170527561236, 8478879889311201066, 883591599761019226, 267303269300772726, 14564461833813888409, 3980592300144013488, 17312578832377593806, 20]; pub(super) const POW31: [&'static [u64]; 13] = [ &POW31_1, &POW31_2, &POW31_3, &POW31_4, &POW31_5, &POW31_6, &POW31_7, &POW31_8, &POW31_9, &POW31_10, &POW31_11, &POW31_12, &POW31_13, ]; }} // cfg_if lexical-core-0.7.6/src/atof/algorithm/math.rs000075500000000000000000003101070000000000000171740ustar 00000000000000//! Building-blocks for arbitrary-precision math. //! //! These algorithms assume little-endian order for the large integer //! buffers, so for a `vec![0, 1, 2, 3]`, `3` is the most significant limb, //! and `0` is the least significant limb. // We have a lot of higher-order, efficient math routines that may // come in handy later. These aren't trivial to implement, so keep them. #![allow(dead_code)] use crate::util::*; // ALIASES // ------- // Type for a single limb of the big integer. // // A limb is analogous to a digit in base10, except, it stores 32-bit // or 64-bit numbers instead. // // This should be all-known 64-bit platforms supported by Rust. // https://forge.rust-lang.org/platform-support.html // // Platforms where native 128-bit multiplication is explicitly supported: // - x86_64 (Supported via `MUL`). // - mips64 (Supported via `DMULTU`, which `HI` and `LO` can be read-from). // // Platforms where native 64-bit multiplication is supported and // you can extract hi-lo for 64-bit multiplications. // aarch64 (Requires `UMULH` and `MUL` to capture high and low bits). // powerpc64 (Requires `MULHDU` and `MULLD` to capture high and low bits). // // Platforms where native 128-bit multiplication is not supported, // requiring software emulation. // sparc64 (`UMUL` only supported double-word arguments). cfg_if! { if #[cfg(limb_width_64)] { pub type Limb = u64; type Wide = u128; type SignedWide = i128; } else { pub type Limb = u32; type Wide = u64; type SignedWide = i64; }} // cfg_if perftools_inline!{ /// Cast to limb type. pub(super) fn as_limb(t: T) -> Limb { as_cast(t) }} perftools_inline!{ /// Cast to wide type. fn as_wide(t: T) -> Wide { as_cast(t) }} perftools_inline!{ /// Cast tosigned wide type. fn as_signed_wide(t: T) -> SignedWide { as_cast(t) }} // SPLIT // ----- perftools_inline!{ /// Split u16 into limbs, in little-endian order. fn split_u16(x: u16) -> [Limb; 1] { [as_limb(x)] }} perftools_inline!{ /// Split u32 into limbs, in little-endian order. fn split_u32(x: u32) -> [Limb; 1] { [as_limb(x)] }} perftools_inline!{ /// Split u64 into limbs, in little-endian order. #[cfg(limb_width_32)] fn split_u64(x: u64) -> [Limb; 2] { [as_limb(x), as_limb(x >> 32)] }} perftools_inline!{ /// Split u64 into limbs, in little-endian order. #[cfg(limb_width_64)] fn split_u64(x: u64) -> [Limb; 1] { [as_limb(x)] }} perftools_inline!{ /// Split u128 into limbs, in little-endian order. #[cfg(limb_width_32)] fn split_u128(x: u128) -> [Limb; 4] { [as_limb(x), as_limb(x >> 32), as_limb(x >> 64), as_limb(x >> 96)] }} perftools_inline!{ /// Split u128 into limbs, in little-endian order. #[cfg(limb_width_64)] fn split_u128(x: u128) -> [Limb; 2] { [as_limb(x), as_limb(x >> 64)] }} // HI BITS // ------- // NONZERO perftools_inline!{ /// Check if any of the remaining bits are non-zero. pub fn nonzero(x: &[T], rindex: usize) -> bool { let len = x.len(); let slc = &x[..len-rindex]; slc.iter().rev().any(|&x| x != T::ZERO) }} // HI16 perftools_inline!{ /// Shift 16-bit integer to high 16-bits. fn u16_to_hi16_1(r0: u16) -> (u16, bool) { debug_assert!(r0 != 0); let ls = r0.leading_zeros(); (r0 << ls, false) }} perftools_inline!{ /// Shift 2 16-bit integers to high 16-bits. fn u16_to_hi16_2(r0: u16, r1: u16) -> (u16, bool) { debug_assert!(r0 != 0); let ls = r0.leading_zeros(); let rs = 16 - ls; let v = match ls { 0 => r0, _ => (r0 << ls) | (r1 >> rs), }; let n = r1 << ls != 0; (v, n) }} perftools_inline!{ /// Shift 32-bit integer to high 16-bits. fn u32_to_hi16_1(r0: u32) -> (u16, bool) { let r0 = u32_to_hi32_1(r0).0; ((r0 >> 16).as_u16(), r0.as_u16() != 0) }} perftools_inline!{ /// Shift 2 32-bit integers to high 16-bits. fn u32_to_hi16_2(r0: u32, r1: u32) -> (u16, bool) { let (r0, n) = u32_to_hi32_2(r0, r1); ((r0 >> 16).as_u16(), n || r0.as_u16() != 0) }} perftools_inline!{ /// Shift 64-bit integer to high 16-bits. fn u64_to_hi16_1(r0: u64) -> (u16, bool) { let r0 = u64_to_hi64_1(r0).0; ((r0 >> 48).as_u16(), r0.as_u16() != 0) }} perftools_inline!{ /// Shift 2 64-bit integers to high 16-bits. fn u64_to_hi16_2(r0: u64, r1: u64) -> (u16, bool) { let (r0, n) = u64_to_hi64_2(r0, r1); ((r0 >> 48).as_u16(), n || r0.as_u16() != 0) }} /// Trait to export the high 16-bits from a little-endian slice. trait Hi16: SliceLike { /// Get the hi16 bits from a 1-limb slice. fn hi16_1(&self) -> (u16, bool); /// Get the hi16 bits from a 2-limb slice. fn hi16_2(&self) -> (u16, bool); perftools_inline!{ /// High-level exporter to extract the high 16 bits from a little-endian slice. fn hi16(&self) -> (u16, bool) { match self.len() { 0 => (0, false), 1 => self.hi16_1(), _ => self.hi16_2(), } }} } impl Hi16 for [u16] { perftools_inline!{ fn hi16_1(&self) -> (u16, bool) { debug_assert!(self.len() == 1); let rview = self.rview(); let r0 = rview[0]; u16_to_hi16_1(r0) }} perftools_inline!{ fn hi16_2(&self) -> (u16, bool) { debug_assert!(self.len() == 2); let rview = self.rview(); let r0 = rview[0]; let r1 = rview[1]; let (v, n) = u16_to_hi16_2(r0, r1); (v, n || nonzero(self, 2)) }} } impl Hi16 for [u32] { perftools_inline!{ fn hi16_1(&self) -> (u16, bool) { debug_assert!(self.len() == 1); let rview = self.rview(); let r0 = rview[0]; u32_to_hi16_1(r0) }} perftools_inline!{ fn hi16_2(&self) -> (u16, bool) { debug_assert!(self.len() == 2); let rview = self.rview(); let r0 = rview[0]; let r1 = rview[1]; let (v, n) = u32_to_hi16_2(r0, r1); (v, n || nonzero(self, 2)) }} } impl Hi16 for [u64] { perftools_inline!{ fn hi16_1(&self) -> (u16, bool) { debug_assert!(self.len() == 1); let rview = self.rview(); let r0 = rview[0]; u64_to_hi16_1(r0) }} perftools_inline!{ fn hi16_2(&self) -> (u16, bool) { debug_assert!(self.len() == 2); let rview = self.rview(); let r0 = rview[0]; let r1 = rview[1]; let (v, n) = u64_to_hi16_2(r0, r1); (v, n || nonzero(self, 2)) }} } // HI32 perftools_inline!{ /// Shift 32-bit integer to high 32-bits. fn u32_to_hi32_1(r0: u32) -> (u32, bool) { debug_assert!(r0 != 0); let ls = r0.leading_zeros(); (r0 << ls, false) }} perftools_inline!{ /// Shift 2 32-bit integers to high 32-bits. fn u32_to_hi32_2(r0: u32, r1: u32) -> (u32, bool) { debug_assert!(r0 != 0); let ls = r0.leading_zeros(); let rs = 32 - ls; let v = match ls { 0 => r0, _ => (r0 << ls) | (r1 >> rs), }; let n = r1 << ls != 0; (v, n) }} perftools_inline!{ /// Shift 64-bit integer to high 32-bits. fn u64_to_hi32_1(r0: u64) -> (u32, bool) { let r0 = u64_to_hi64_1(r0).0; ((r0 >> 32).as_u32(), r0.as_u32() != 0) }} perftools_inline!{ /// Shift 2 64-bit integers to high 32-bits. fn u64_to_hi32_2(r0: u64, r1: u64) -> (u32, bool) { let (r0, n) = u64_to_hi64_2(r0, r1); ((r0 >> 32).as_u32(), n || r0.as_u32() != 0) }} /// Trait to export the high 32-bits from a little-endian slice. trait Hi32: SliceLike { /// Get the hi32 bits from a 1-limb slice. fn hi32_1(&self) -> (u32, bool); /// Get the hi32 bits from a 2-limb slice. fn hi32_2(&self) -> (u32, bool); /// Get the hi32 bits from a 3-limb slice. fn hi32_3(&self) -> (u32, bool); perftools_inline!{ /// High-level exporter to extract the high 32 bits from a little-endian slice. fn hi32(&self) -> (u32, bool) { match self.len() { 0 => (0, false), 1 => self.hi32_1(), 2 => self.hi32_2(), _ => self.hi32_3(), } }} } impl Hi32 for [u16] { perftools_inline!{ fn hi32_1(&self) -> (u32, bool) { debug_assert!(self.len() == 1); let rview = self.rview(); u32_to_hi32_1(rview[0].as_u32()) }} perftools_inline!{ fn hi32_2(&self) -> (u32, bool) { debug_assert!(self.len() == 2); let rview = self.rview(); let r0 = rview[0].as_u32() << 16; let r1 = rview[1].as_u32(); u32_to_hi32_1(r0 | r1) }} perftools_inline!{ fn hi32_3(&self) -> (u32, bool) { debug_assert!(self.len() >= 3); let rview = self.rview(); let r0 = rview[0].as_u32(); let r1 = rview[1].as_u32() << 16; let r2 = rview[2].as_u32(); let (v, n) = u32_to_hi32_2( r0, r1 | r2); (v, n || nonzero(self, 3)) }} } impl Hi32 for [u32] { perftools_inline!{ fn hi32_1(&self) -> (u32, bool) { debug_assert!(self.len() == 1); let rview = self.rview(); let r0 = rview[0]; u32_to_hi32_1(r0) }} perftools_inline!{ fn hi32_2(&self) -> (u32, bool) { debug_assert!(self.len() >= 2); let rview = self.rview(); let r0 = rview[0]; let r1 = rview[1]; let (v, n) = u32_to_hi32_2(r0, r1); (v, n || nonzero(self, 2)) }} perftools_inline!{ fn hi32_3(&self) -> (u32, bool) { self.hi32_2() }} } impl Hi32 for [u64] { perftools_inline!{ fn hi32_1(&self) -> (u32, bool) { debug_assert!(self.len() == 1); let rview = self.rview(); let r0 = rview[0]; u64_to_hi32_1(r0) }} perftools_inline!{ fn hi32_2(&self) -> (u32, bool) { debug_assert!(self.len() >= 2); let rview = self.rview(); let r0 = rview[0]; let r1 = rview[1]; let (v, n) = u64_to_hi32_2(r0, r1); (v, n || nonzero(self, 2)) }} perftools_inline!{ fn hi32_3(&self) -> (u32, bool) { self.hi32_2() }} } // HI64 perftools_inline!{ /// Shift 64-bit integer to high 64-bits. fn u64_to_hi64_1(r0: u64) -> (u64, bool) { debug_assert!(r0 != 0); let ls = r0.leading_zeros(); (r0 << ls, false) }} perftools_inline!{ /// Shift 2 64-bit integers to high 64-bits. fn u64_to_hi64_2(r0: u64, r1: u64) -> (u64, bool) { debug_assert!(r0 != 0); let ls = r0.leading_zeros(); let rs = 64 - ls; let v = match ls { 0 => r0, _ => (r0 << ls) | (r1 >> rs), }; let n = r1 << ls != 0; (v, n) }} /// Trait to export the high 64-bits from a little-endian slice. trait Hi64: SliceLike { /// Get the hi64 bits from a 1-limb slice. fn hi64_1(&self) -> (u64, bool); /// Get the hi64 bits from a 2-limb slice. fn hi64_2(&self) -> (u64, bool); /// Get the hi64 bits from a 3-limb slice. fn hi64_3(&self) -> (u64, bool); /// Get the hi64 bits from a 4-limb slice. fn hi64_4(&self) -> (u64, bool); /// Get the hi64 bits from a 5-limb slice. fn hi64_5(&self) -> (u64, bool); perftools_inline!{ /// High-level exporter to extract the high 64 bits from a little-endian slice. fn hi64(&self) -> (u64, bool) { match self.len() { 0 => (0, false), 1 => self.hi64_1(), 2 => self.hi64_2(), 3 => self.hi64_3(), 4 => self.hi64_4(), _ => self.hi64_5(), } }} } impl Hi64 for [u16] { perftools_inline!{ fn hi64_1(&self) -> (u64, bool) { debug_assert!(self.len() == 1); let rview = self.rview(); let r0 = rview[0].as_u64(); u64_to_hi64_1(r0) }} perftools_inline!{ fn hi64_2(&self) -> (u64, bool) { debug_assert!(self.len() == 2); let rview = self.rview(); let r0 = rview[0].as_u64() << 16; let r1 = rview[1].as_u64(); u64_to_hi64_1(r0 | r1) }} perftools_inline!{ fn hi64_3(&self) -> (u64, bool) { debug_assert!(self.len() == 3); let rview = self.rview(); let r0 = rview[0].as_u64() << 32; let r1 = rview[1].as_u64() << 16; let r2 = rview[2].as_u64(); u64_to_hi64_1(r0 | r1 | r2) }} perftools_inline!{ fn hi64_4(&self) -> (u64, bool) { debug_assert!(self.len() == 4); let rview = self.rview(); let r0 = rview[0].as_u64() << 48; let r1 = rview[1].as_u64() << 32; let r2 = rview[2].as_u64() << 16; let r3 = rview[3].as_u64(); u64_to_hi64_1(r0 | r1 | r2 | r3) }} perftools_inline!{ fn hi64_5(&self) -> (u64, bool) { debug_assert!(self.len() >= 5); let rview = self.rview(); let r0 = rview[0].as_u64(); let r1 = rview[1].as_u64() << 48; let r2 = rview[2].as_u64() << 32; let r3 = rview[3].as_u64() << 16; let r4 = rview[4].as_u64(); let (v, n) = u64_to_hi64_2(r0, r1 | r2 | r3 | r4); (v, n || nonzero(self, 5)) }} } impl Hi64 for [u32] { perftools_inline!{ fn hi64_1(&self) -> (u64, bool) { debug_assert!(self.len() == 1); let rview = self.rview(); let r0 = rview[0].as_u64(); u64_to_hi64_1(r0) }} perftools_inline!{ fn hi64_2(&self) -> (u64, bool) { debug_assert!(self.len() == 2); let rview = self.rview(); let r0 = rview[0].as_u64() << 32; let r1 = rview[1].as_u64(); u64_to_hi64_1(r0 | r1) }} perftools_inline!{ fn hi64_3(&self) -> (u64, bool) { debug_assert!(self.len() >= 3); let rview = self.rview(); let r0 = rview[0].as_u64(); let r1 = rview[1].as_u64() << 32; let r2 = rview[2].as_u64(); let (v, n) = u64_to_hi64_2(r0, r1 | r2); (v, n || nonzero(self, 3)) }} perftools_inline!{ fn hi64_4(&self) -> (u64, bool) { self.hi64_3() }} perftools_inline!{ fn hi64_5(&self) -> (u64, bool) { self.hi64_3() }} } impl Hi64 for [u64] { perftools_inline!{ fn hi64_1(&self) -> (u64, bool) { debug_assert!(self.len() == 1); let rview = self.rview(); let r0 = rview[0]; u64_to_hi64_1(r0) }} perftools_inline!{ fn hi64_2(&self) -> (u64, bool) { debug_assert!(self.len() >= 2); let rview = self.rview(); let r0 = rview[0]; let r1 = rview[1]; let (v, n) = u64_to_hi64_2(r0, r1); (v, n || nonzero(self, 2)) }} perftools_inline!{ fn hi64_3(&self) -> (u64, bool) { self.hi64_2() }} perftools_inline!{ fn hi64_4(&self) -> (u64, bool) { self.hi64_2() }} perftools_inline!{ fn hi64_5(&self) -> (u64, bool) { self.hi64_2() }} } // HI128 perftools_inline!{ /// Shift 128-bit integer to high 128-bits. fn u128_to_hi128_1(r0: u128) -> (u128, bool) { let ls = r0.leading_zeros(); (r0 << ls, false) }} perftools_inline!{ /// Shift 2 128-bit integers to high 128-bits. fn u128_to_hi128_2(r0: u128, r1: u128) -> (u128, bool) { let ls = r0.leading_zeros(); let rs = 128 - ls; let v = (r0 << ls) | (r1 >> rs); let n = r1 << ls != 0; (v, n) }} /// Trait to export the high 128-bits from a little-endian slice. trait Hi128: SliceLike { /// Get the hi128 bits from a 1-limb slice. fn hi128_1(&self) -> (u128, bool); /// Get the hi128 bits from a 2-limb slice. fn hi128_2(&self) -> (u128, bool); /// Get the hi128 bits from a 3-limb slice. fn hi128_3(&self) -> (u128, bool); /// Get the hi128 bits from a 4-limb slice. fn hi128_4(&self) -> (u128, bool); /// Get the hi128 bits from a 5-limb slice. fn hi128_5(&self) -> (u128, bool); /// Get the hi128 bits from a 5-limb slice. fn hi128_6(&self) -> (u128, bool); /// Get the hi128 bits from a 5-limb slice. fn hi128_7(&self) -> (u128, bool); /// Get the hi128 bits from a 5-limb slice. fn hi128_8(&self) -> (u128, bool); /// Get the hi128 bits from a 5-limb slice. fn hi128_9(&self) -> (u128, bool); perftools_inline!{ /// High-level exporter to extract the high 128 bits from a little-endian slice. fn hi128(&self) -> (u128, bool) { match self.len() { 0 => (0, false), 1 => self.hi128_1(), 2 => self.hi128_2(), 3 => self.hi128_3(), 4 => self.hi128_4(), 6 => self.hi128_6(), 7 => self.hi128_7(), 8 => self.hi128_8(), _ => self.hi128_9(), } }} } impl Hi128 for [u16] { perftools_inline!{ fn hi128_1(&self) -> (u128, bool) { debug_assert!(self.len() == 1); let rview = self.rview(); let r0 = rview[0].as_u128(); u128_to_hi128_1(r0) }} perftools_inline!{ fn hi128_2(&self) -> (u128, bool) { debug_assert!(self.len() == 2); let rview = self.rview(); let r0 = rview[0].as_u128() << 16; let r1 = rview[1].as_u128(); u128_to_hi128_1(r0 | r1) }} perftools_inline!{ fn hi128_3(&self) -> (u128, bool) { debug_assert!(self.len() == 3); let rview = self.rview(); let r0 = rview[0].as_u128() << 32; let r1 = rview[1].as_u128() << 16; let r2 = rview[2].as_u128(); u128_to_hi128_1(r0 | r1 | r2) }} perftools_inline!{ fn hi128_4(&self) -> (u128, bool) { debug_assert!(self.len() == 4); let rview = self.rview(); let r0 = rview[0].as_u128() << 48; let r1 = rview[1].as_u128() << 32; let r2 = rview[2].as_u128() << 16; let r3 = rview[3].as_u128(); u128_to_hi128_1(r0 | r1 | r2 | r3) }} perftools_inline!{ fn hi128_5(&self) -> (u128, bool) { debug_assert!(self.len() == 5); let rview = self.rview(); let r0 = rview[0].as_u128() << 64; let r1 = rview[1].as_u128() << 48; let r2 = rview[2].as_u128() << 32; let r3 = rview[3].as_u128() << 16; let r4 = rview[4].as_u128(); u128_to_hi128_1(r0 | r1 | r2 | r3 | r4) }} perftools_inline!{ fn hi128_6(&self) -> (u128, bool) { debug_assert!(self.len() == 6); let rview = self.rview(); let r0 = rview[0].as_u128() << 80; let r1 = rview[1].as_u128() << 64; let r2 = rview[2].as_u128() << 48; let r3 = rview[3].as_u128() << 32; let r4 = rview[4].as_u128() << 16; let r5 = rview[5].as_u128(); u128_to_hi128_1(r0 | r1 | r2 | r3 | r4 | r5) }} perftools_inline!{ fn hi128_7(&self) -> (u128, bool) { debug_assert!(self.len() == 7); let rview = self.rview(); let r0 = rview[0].as_u128() << 96; let r1 = rview[1].as_u128() << 80; let r2 = rview[2].as_u128() << 64; let r3 = rview[3].as_u128() << 48; let r4 = rview[4].as_u128() << 32; let r5 = rview[5].as_u128() << 16; let r6 = rview[6].as_u128(); u128_to_hi128_1(r0 | r1 | r2 | r3 | r4 | r5 | r6) }} perftools_inline!{ fn hi128_8(&self) -> (u128, bool) { debug_assert!(self.len() == 8); let rview = self.rview(); let r0 = rview[0].as_u128() << 112; let r1 = rview[1].as_u128() << 96; let r2 = rview[2].as_u128() << 80; let r3 = rview[3].as_u128() << 64; let r4 = rview[4].as_u128() << 48; let r5 = rview[5].as_u128() << 32; let r6 = rview[6].as_u128() << 16; let r7 = rview[7].as_u128(); u128_to_hi128_1(r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7) }} perftools_inline!{ fn hi128_9(&self) -> (u128, bool) { debug_assert!(self.len() >= 9); let rview = self.rview(); let r0 = rview[0].as_u128(); let r1 = rview[1].as_u128() << 112; let r2 = rview[2].as_u128() << 96; let r3 = rview[3].as_u128() << 80; let r4 = rview[4].as_u128() << 64; let r5 = rview[5].as_u128() << 48; let r6 = rview[6].as_u128() << 32; let r7 = rview[7].as_u128() << 16; let r8 = rview[8].as_u128(); let (v, n) = u128_to_hi128_2(r0, r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8); (v, n || nonzero(self, 9)) }} } impl Hi128 for [u32] { perftools_inline!{ fn hi128_1(&self) -> (u128, bool) { debug_assert!(self.len() == 1); let rview = self.rview(); let r0 = rview[0].as_u128(); u128_to_hi128_1(r0) }} perftools_inline!{ fn hi128_2(&self) -> (u128, bool) { debug_assert!(self.len() == 2); let rview = self.rview(); let r0 = rview[0].as_u128() << 32; let r1 = rview[1].as_u128(); u128_to_hi128_1(r0 | r1) }} perftools_inline!{ fn hi128_3(&self) -> (u128, bool) { debug_assert!(self.len() == 3); let rview = self.rview(); let r0 = rview[0].as_u128() << 64; let r1 = rview[1].as_u128() << 32; let r2 = rview[2].as_u128(); u128_to_hi128_1(r0 | r1 | r2) }} perftools_inline!{ fn hi128_4(&self) -> (u128, bool) { debug_assert!(self.len() == 4); let rview = self.rview(); let r0 = rview[0].as_u128() << 96; let r1 = rview[1].as_u128() << 64; let r2 = rview[2].as_u128() << 32; let r3 = rview[3].as_u128(); u128_to_hi128_1(r0 | r1 | r2 | r3) }} perftools_inline!{ fn hi128_5(&self) -> (u128, bool) { debug_assert!(self.len() >= 5); let rview = self.rview(); let r0 = rview[0].as_u128(); let r1 = rview[1].as_u128() << 96; let r2 = rview[2].as_u128() << 64; let r3 = rview[3].as_u128() << 32; let r4 = rview[4].as_u128(); let (v, n) = u128_to_hi128_2(r0, r1 | r2 | r3 | r4); (v, n || nonzero(self, 5)) }} perftools_inline!{ fn hi128_6(&self) -> (u128, bool) { self.hi128_5() }} perftools_inline!{ fn hi128_7(&self) -> (u128, bool) { self.hi128_5() }} perftools_inline!{ fn hi128_8(&self) -> (u128, bool) { self.hi128_5() }} perftools_inline!{ fn hi128_9(&self) -> (u128, bool) { self.hi128_5() }} } impl Hi128 for [u64] { perftools_inline!{ fn hi128_1(&self) -> (u128, bool) { debug_assert!(self.len() == 1); let rview = self.rview(); let r0 = rview[0].as_u128(); u128_to_hi128_1(r0) }} perftools_inline!{ fn hi128_2(&self) -> (u128, bool) { debug_assert!(self.len() == 2); let rview = self.rview(); let r0 = rview[0].as_u128() << 64; let r1 = rview[1].as_u128(); u128_to_hi128_1(r0 | r1) }} perftools_inline!{ fn hi128_3(&self) -> (u128, bool) { debug_assert!(self.len() >= 3); let rview = self.rview(); let r0 = rview[0].as_u128(); let r1 = rview[1].as_u128() << 64; let r2 = rview[2].as_u128(); let (v, n) = u128_to_hi128_2(r0, r1 | r2); (v, n || nonzero(self, 3)) }} perftools_inline!{ fn hi128_4(&self) -> (u128, bool) { self.hi128_3() }} perftools_inline!{ fn hi128_5(&self) -> (u128, bool) { self.hi128_3() }} perftools_inline!{ fn hi128_6(&self) -> (u128, bool) { self.hi128_3() }} perftools_inline!{ fn hi128_7(&self) -> (u128, bool) { self.hi128_3() }} perftools_inline!{ fn hi128_8(&self) -> (u128, bool) { self.hi128_3() }} perftools_inline!{ fn hi128_9(&self) -> (u128, bool) { self.hi128_3() }} } // SCALAR // ------ // Scalar-to-scalar operations, for building-blocks for arbitrary-precision // operations. pub(in crate::atof::algorithm) mod scalar { use super::*; // ADDITION perftools_inline!{ /// Add two small integers and return the resulting value and if overflow happens. pub fn add(x: Limb, y: Limb) -> (Limb, bool) { x.overflowing_add(y) }} perftools_inline!{ /// AddAssign two small integers and return if overflow happens. pub fn iadd(x: &mut Limb, y: Limb) -> bool { let t = add(*x, y); *x = t.0; t.1 }} // SUBTRACTION perftools_inline!{ /// Subtract two small integers and return the resulting value and if overflow happens. pub fn sub(x: Limb, y: Limb) -> (Limb, bool) { x.overflowing_sub(y) }} perftools_inline!{ /// SubAssign two small integers and return if overflow happens. pub fn isub(x: &mut Limb, y: Limb) -> bool { let t = sub(*x, y); *x = t.0; t.1 }} // MULTIPLICATION perftools_inline!{ /// Multiply two small integers (with carry) (and return the overflow contribution). /// /// Returns the (low, high) components. pub fn mul(x: Limb, y: Limb, carry: Limb) -> (Limb, Limb) { // Cannot overflow, as long as wide is 2x as wide. This is because // the following is always true: // `Wide::max_value() - (Narrow::max_value() * Narrow::max_value()) >= Narrow::max_value()` let z: Wide = as_wide(x) * as_wide(y) + as_wide(carry); (as_limb(z), as_limb(z >> ::BITS)) }} perftools_inline!{ /// Multiply two small integers (with carry) (and return if overflow happens). pub fn imul(x: &mut Limb, y: Limb, carry: Limb) -> Limb { let t = mul(*x, y, carry); *x = t.0; t.1 }} // DIVISION perftools_inline!{ /// Divide two small integers (with remainder) (and return the remainder contribution). /// /// Returns the (value, remainder) components. pub fn div(x: Limb, y: Limb, rem: Limb) -> (Limb, Limb) { // Cannot overflow, as long as wide is 2x as wide. let x = as_wide(x) | (as_wide(rem) << ::BITS); let y = as_wide(y); (as_limb(x / y), as_limb(x % y)) }} perftools_inline!{ /// DivAssign two small integers and return the remainder. pub fn idiv(x: &mut Limb, y: Limb, rem: Limb) -> Limb { let t = div(*x, y, rem); *x = t.0; t.1 }} } // scalar // SMALL // ----- // Large-to-small operations, to modify a big integer from a native scalar. pub(in crate::atof::algorithm) mod small { use crate::lib::iter; use super::*; use super::super::small_powers::*; use super::super::large_powers::*; // PROPERTIES perftools_inline!{ /// Get the number of leading zero values in the storage. /// Assumes the value is normalized. pub fn leading_zero_limbs(_: &[Limb]) -> usize { 0 }} perftools_inline!{ /// Get the number of trailing zero values in the storage. /// Assumes the value is normalized. pub fn trailing_zero_limbs(x: &[Limb]) -> usize { let mut iter = x.iter().enumerate(); let opt = iter.find(|&tup| !tup.1.is_zero()); let value = opt .map(|t| t.0) .unwrap_or(x.len()); value }} perftools_inline!{ /// Get number of leading zero bits in the storage. pub fn leading_zeros(x: &[Limb]) -> usize { if x.is_empty() { 0 } else { x.rindex(0).leading_zeros().as_usize() } }} perftools_inline!{ /// Get number of trailing zero bits in the storage. /// Assumes the value is normalized. pub fn trailing_zeros(x: &[Limb]) -> usize { // Get the index of the last non-zero value let index = trailing_zero_limbs(x); let mut count = index.saturating_mul(::BITS); if let Some(value) = x.get(index) { count = count.saturating_add(value.trailing_zeros().as_usize()); } count }} // BIT LENGTH perftools_inline!{ /// Calculate the bit-length of the big-integer. pub fn bit_length(x: &[Limb]) -> usize { // Avoid overflowing, calculate via total number of bits // minus leading zero bits. let nlz = leading_zeros(x); ::BITS.checked_mul(x.len()) .map(|v| v - nlz) .unwrap_or(usize::max_value()) }} // BIT LENGTH perftools_inline!{ /// Calculate the limb-length of the big-integer. pub fn limb_length(x: &[Limb]) -> usize { x.len() }} // SHR perftools_inline!{ /// Shift-right bits inside a buffer and returns the truncated bits. /// /// Returns the truncated bits. /// /// Assumes `n < ::BITS`, IE, internally shifting bits. pub fn ishr_bits(x: &mut T, n: usize) -> Limb where T: CloneableVecLike { // Need to shift by the number of `bits % ::BITS`. let bits = ::BITS; debug_assert!(n < bits && n != 0); // Internally, for each item, we shift left by n, and add the previous // right shifted limb-bits. // For example, we transform (for u8) shifted right 2, to: // b10100100 b01000010 // b101001 b00010000 let lshift = bits - n; let rshift = n; let mut prev: Limb = 0; for xi in x.iter_mut().rev() { let tmp = *xi; *xi >>= rshift; *xi |= prev << lshift; prev = tmp; } prev & lower_n_mask(as_limb(rshift)) }} perftools_inline!{ /// Shift-right `n` limbs inside a buffer and returns if all the truncated limbs are zero. /// /// Assumes `n` is not 0. pub fn ishr_limbs(x: &mut T, n: usize) -> bool where T: CloneableVecLike { debug_assert!(n != 0); if n >= x.len() { x.clear(); false } else { let is_zero = (&x[..n]).iter().all(|v| v.is_zero()); x.remove_many(0..n); is_zero } }} perftools_inline!{ /// Shift-left buffer by n bits and return if we should round-up. pub fn ishr(x: &mut T, n: usize) -> bool where T: CloneableVecLike { let bits = ::BITS; // Need to pad with zeros for the number of `bits / ::BITS`, // and shift-left with carry for `bits % ::BITS`. let rem = n % bits; let div = n / bits; let is_zero = match div.is_zero() { true => true, false => ishr_limbs(x, div), }; let truncated = match rem.is_zero() { true => 0, false => ishr_bits(x, rem), }; // Calculate if we need to roundup. let roundup = { let halfway = lower_n_halfway(as_limb(rem)); if truncated > halfway { // Above halfway true } else if truncated == halfway { // Exactly halfway, if !is_zero, we have a tie-breaker, // otherwise, we follow round-to-nearest, tie-even rules. // Cannot be empty, since truncated is non-zero. !is_zero || x[0].is_odd() } else { // Below halfway false } }; // Normalize the data normalize(x); roundup }} perftools_inline!{ /// Shift-left buffer by n bits. pub fn shr(x: &[Limb], n: usize) -> (T, bool) where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); let roundup = ishr(&mut z, n); (z, roundup) }} // SHL perftools_inline!{ /// Shift-left bits inside a buffer. /// /// Assumes `n < ::BITS`, IE, internally shifting bits. pub fn ishl_bits(x: &mut T, n: usize) where T: CloneableVecLike { // Need to shift by the number of `bits % ::BITS)`. let bits = ::BITS; debug_assert!(n < bits); if n.is_zero() { return; } // Internally, for each item, we shift left by n, and add the previous // right shifted limb-bits. // For example, we transform (for u8) shifted left 2, to: // b10100100 b01000010 // b10 b10010001 b00001000 let rshift = bits - n; let lshift = n; let mut prev: Limb = 0; for xi in x.iter_mut() { let tmp = *xi; *xi <<= lshift; *xi |= prev >> rshift; prev = tmp; } // Always push the carry, even if it creates a non-normal result. let carry = prev >> rshift; if carry != 0 { x.push(carry); } }} perftools_inline!{ /// Shift-left bits inside a buffer. /// /// Assumes `n < ::BITS`, IE, internally shifting bits. pub fn shl_bits(x: &[Limb], n: usize) -> T where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); ishl_bits(&mut z, n); z }} perftools_inline!{ /// Shift-left `n` digits inside a buffer. /// /// Assumes `n` is not 0. pub fn ishl_limbs(x: &mut T, n: usize) where T: CloneableVecLike { debug_assert!(n != 0); if !x.is_empty() { x.insert_many(0, iter::repeat(0).take(n)); } }} perftools_inline!{ /// Shift-left buffer by n bits. pub fn ishl(x: &mut T, n: usize) where T: CloneableVecLike { let bits = ::BITS; // Need to pad with zeros for the number of `bits / ::BITS`, // and shift-left with carry for `bits % ::BITS`. let rem = n % bits; let div = n / bits; ishl_bits(x, rem); if !div.is_zero() { ishl_limbs(x, div); } }} perftools_inline!{ /// Shift-left buffer by n bits. pub fn shl(x: &[Limb], n: usize) -> T where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); ishl(&mut z, n); z }} // NORMALIZE perftools_inline!{ /// Normalize the container by popping any leading zeros. pub fn normalize(x: &mut T) where T: CloneableVecLike { // Remove leading zero if we cause underflow. Since we're dividing // by a small power, we have at max 1 int removed. while !x.is_empty() && x.rindex(0).is_zero() { x.pop(); } }} // ADDITION perftools_inline!{ /// Implied AddAssign implementation for adding a small integer to bigint. /// /// Allows us to choose a start-index in x to store, to allow incrementing /// from a non-zero start. pub fn iadd_impl(x: &mut T, y: Limb, xstart: usize) where T: CloneableVecLike { if x.len() <= xstart { x.push(y); } else { // Initial add let mut carry = scalar::iadd(&mut x[xstart], y); // Increment until overflow stops occurring. let mut size = xstart + 1; while carry && size < x.len() { carry = scalar::iadd(&mut x[size], 1); size += 1; } // If we overflowed the buffer entirely, need to add 1 to the end // of the buffer. if carry { x.push(1); } } }} perftools_inline!{ /// AddAssign small integer to bigint. pub fn iadd(x: &mut T, y: Limb) where T: CloneableVecLike { iadd_impl(x, y, 0); }} perftools_inline!{ /// Add small integer to bigint. pub fn add(x: &[Limb], y: Limb) -> T where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); iadd(&mut z, y); z }} // SUBTRACTION perftools_inline!{ /// SubAssign small integer to bigint. /// Does not do overflowing subtraction. pub fn isub_impl(x: &mut T, y: Limb, xstart: usize) where T: CloneableVecLike { debug_assert!(x.len() > xstart && (x[xstart] >= y || x.len() > xstart+1)); // Initial subtraction let mut carry = scalar::isub(&mut x[xstart], y); // Increment until overflow stops occurring. let mut size = xstart + 1; while carry && size < x.len() { carry = scalar::isub(&mut x[size], 1); size += 1; } normalize(x); }} perftools_inline!{ /// SubAssign small integer to bigint. /// Does not do overflowing subtraction. pub fn isub(x: &mut T, y: Limb) where T: CloneableVecLike { isub_impl(x, y, 0); }} perftools_inline!{ /// Sub small integer to bigint. pub fn sub(x: &[Limb], y: Limb) -> T where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); isub(&mut z, y); z }} // MULTIPLICATION perftools_inline!{ /// MulAssign small integer to bigint. pub fn imul(x: &mut T, y: Limb) where T: CloneableVecLike { // Multiply iteratively over all elements, adding the carry each time. let mut carry: Limb = 0; for xi in x.iter_mut() { carry = scalar::imul(xi, y, carry); } // Overflow of value, add to end. if carry != 0 { x.push(carry); } }} perftools_inline!{ /// Mul small integer to bigint. pub fn mul(x: &[Limb], y: Limb) -> T where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); imul(&mut z, y); z }} /// MulAssign by a power. /// /// Theoretically... /// /// Use an exponentiation by squaring method, since it reduces the time /// complexity of the multiplication to ~`O(log(n))` for the squaring, /// and `O(n*m)` for the result. Since `m` is typically a lower-order /// factor, this significantly reduces the number of multiplications /// we need to do. Iteratively multiplying by small powers follows /// the nth triangular number series, which scales as `O(p^2)`, but /// where `p` is `n+m`. In short, it scales very poorly. /// /// Practically.... /// /// Exponentiation by Squaring: /// running 2 tests /// test bigcomp_f32_lexical ... bench: 1,018 ns/iter (+/- 78) /// test bigcomp_f64_lexical ... bench: 3,639 ns/iter (+/- 1,007) /// /// Exponentiation by Iterative Small Powers: /// running 2 tests /// test bigcomp_f32_lexical ... bench: 518 ns/iter (+/- 31) /// test bigcomp_f64_lexical ... bench: 583 ns/iter (+/- 47) /// /// Exponentiation by Iterative Large Powers (of 2): /// running 2 tests /// test bigcomp_f32_lexical ... bench: 671 ns/iter (+/- 31) /// test bigcomp_f64_lexical ... bench: 1,394 ns/iter (+/- 47) /// /// Even using worst-case scenarios, exponentiation by squaring is /// significantly slower for our workloads. Just multiply by small powers, /// in simple cases, and use precalculated large powers in other cases. pub fn imul_power(x: &mut T, radix: u32, n: u32) where T: CloneableVecLike { use super::large::KARATSUBA_CUTOFF; let small_powers = get_small_powers(radix); let large_powers = get_large_powers(radix); if n == 0 { // No exponent, just return. // The 0-index of the large powers is `2^0`, which is 1, so we want // to make sure we don't take that path with a literal 0. return; } // We want to use the asymptotically faster algorithm if we're going // to be using Karabatsu multiplication sometime during the result, // otherwise, just use exponentiation by squaring. let bit_length = 32 - n.leading_zeros().as_usize(); debug_assert!(bit_length != 0 && bit_length <= large_powers.len()); if x.len() + large_powers[bit_length-1].len() < 2*KARATSUBA_CUTOFF { // We can use iterative small powers to make this faster for the // easy cases. // Multiply by the largest small power until n < step. let step = small_powers.len() - 1; let power = small_powers[step]; let mut n = n.as_usize(); while n >= step { imul(x, power); n -= step; } // Multiply by the remainder. imul(x, small_powers[n]); } else { // In theory, this code should be asymptotically a lot faster, // in practice, our small::imul seems to be the limiting step, // and large imul is slow as well. // Multiply by higher order powers. let mut idx: usize = 0; let mut bit: usize = 1; let mut n = n.as_usize(); while n != 0 { if n & bit != 0 { debug_assert!(idx < large_powers.len()); large::imul(x, large_powers[idx]); n ^= bit; } idx += 1; bit <<= 1; } } } perftools_inline!{ /// Mul by a power. pub fn mul_power(x: &[Limb], radix: u32, n: u32) -> T where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); imul_power(&mut z, radix, n); z }} // DIVISION perftools_inline!{ /// DivAssign small integer to bigint and get the remainder. pub fn idiv(x: &mut T, y: Limb) -> Limb where T: CloneableVecLike { // Divide iteratively over all elements, adding the carry each time. let mut rem: Limb = 0; for xi in x.iter_mut().rev() { rem = scalar::idiv(xi, y, rem); } normalize(x); rem }} perftools_inline!{ /// Div small integer to bigint and get the remainder. pub fn div(x: &[Limb], y: Limb) -> (T, Limb) where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); let rem = idiv(&mut z, y); (z, rem) }} // POWER perftools_inline!{ /// Calculate x^n, using exponentiation by squaring. /// /// This algorithm is slow, using `mul_power` should generally be preferred, /// as although it's not asymptotically faster, it precalculates a lot /// of results. pub fn ipow(x: &mut T, mut n: Limb) where T: CloneableVecLike { // Store `x` as 1, and switch `base` to `x`. let mut base = T::default(); base.push(1); mem::swap(x, &mut base); // Do main algorithm. loop { if n.is_odd() { large::imul(x, &base); } n /= 2; // We need to break as a post-condition, since the real work // is in the `imul` and `mul` algorithms. if n.is_zero() { break; } else { base = large::mul(&base, &base); } } }} perftools_inline!{ /// Calculate x^n, using exponentiation by squaring. pub fn pow(x: &[Limb], n: Limb) -> T where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); ipow(&mut z, n); z }} } // small // LARGE // ----- // Large-to-large operations, to modify a big integer from a native scalar. pub(in crate::atof::algorithm) mod large { use crate::lib::cmp; use super::*; // RELATIVE OPERATORS perftools_inline!{ /// Compare `x` to `y`, in little-endian order. pub fn compare(x: &[Limb], y: &[Limb]) -> cmp::Ordering { if x.len() > y.len() { return cmp::Ordering::Greater; } else if x.len() < y.len() { return cmp::Ordering::Less; } else { let iter = x.iter().rev().zip(y.iter().rev()); for (&xi, &yi) in iter { if xi > yi { return cmp::Ordering::Greater; } else if xi < yi { return cmp::Ordering::Less; } } // Equal case. return cmp::Ordering::Equal; } }} perftools_inline!{ /// Check if x is greater than y. pub fn greater(x: &[Limb], y: &[Limb]) -> bool { compare(x, y) == cmp::Ordering::Greater }} perftools_inline!{ /// Check if x is greater than or equal to y. pub fn greater_equal(x: &[Limb], y: &[Limb]) -> bool { !less(x, y) }} perftools_inline!{ /// Check if x is less than y. pub fn less(x: &[Limb], y: &[Limb]) -> bool { compare(x, y) == cmp::Ordering::Less }} perftools_inline!{ /// Check if x is less than or equal to y. pub fn less_equal(x: &[Limb], y: &[Limb]) -> bool { !greater(x, y) }} perftools_inline!{ /// Check if x is equal to y. /// Slightly optimized for equality comparisons, since it reduces the number /// of comparisons relative to `compare`. pub fn equal(x: &[Limb], y: &[Limb]) -> bool { let mut iter = x.iter().rev().zip(y.iter().rev()); x.len() == y.len() && iter.all(|(&xi, &yi)| xi == yi) }} /// ADDITION /// Implied AddAssign implementation for bigints. /// /// Allows us to choose a start-index in x to store, so we can avoid /// padding the buffer with zeros when not needed, optimized for vectors. pub fn iadd_impl(x: &mut T, y: &[Limb], xstart: usize) where T: CloneableVecLike { // The effective x buffer is from `xstart..x.len()`, so we need to treat // that as the current range. If the effective y buffer is longer, need // to resize to that, + the start index. if y.len() > x.len() - xstart { x.resize(y.len() + xstart, 0); } // Iteratively add elements from y to x. let mut carry = false; for (xi, yi) in (&mut x[xstart..]).iter_mut().zip(y.iter()) { // Only one op of the two can overflow, since we added at max // Limb::max_value() + Limb::max_value(). Add the previous carry, // and store the current carry for the next. let mut tmp = scalar::iadd(xi, *yi); if carry { tmp |= scalar::iadd(xi, 1); } carry = tmp; } // Overflow from the previous bit. if carry { small::iadd_impl(x, 1, y.len()+xstart); } } perftools_inline!{ /// AddAssign bigint to bigint. pub fn iadd(x: &mut T, y: &[Limb]) where T: CloneableVecLike { iadd_impl(x, y, 0) }} perftools_inline!{ /// Add bigint to bigint. pub fn add(x: &[Limb], y: &[Limb]) -> T where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); iadd(&mut z, y); z }} // SUBTRACTION /// SubAssign bigint to bigint. pub fn isub(x: &mut T, y: &[Limb]) where T: CloneableVecLike { // Basic underflow checks. debug_assert!(greater_equal(x, y)); // Iteratively add elements from y to x. let mut carry = false; for (xi, yi) in x.iter_mut().zip(y.iter()) { // Only one op of the two can overflow, since we added at max // Limb::max_value() + Limb::max_value(). Add the previous carry, // and store the current carry for the next. let mut tmp = scalar::isub(xi, *yi); if carry { tmp |= scalar::isub(xi, 1); } carry = tmp; } if carry { small::isub_impl(x, 1, y.len()); } else { small::normalize(x); } } perftools_inline!{ /// Sub bigint to bigint. pub fn sub(x: &[Limb], y: &[Limb]) -> T where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); isub(&mut z, y); z }} // MULTIPLICATIION /// Number of digits to bottom-out to asymptotically slow algorithms. /// /// Karatsuba tends to out-perform long-multiplication at ~320-640 bits, /// so we go halfway, while Newton division tends to out-perform /// Algorithm D at ~1024 bits. We can toggle this for optimal performance. pub const KARATSUBA_CUTOFF: usize = 32; /// Grade-school multiplication algorithm. /// /// Slow, naive algorithm, using limb-bit bases and just shifting left for /// each iteration. This could be optimized with numerous other algorithms, /// but it's extremely simple, and works in O(n*m) time, which is fine /// by me. Each iteration, of which there are `m` iterations, requires /// `n` multiplications, and `n` additions, or grade-school multiplication. fn long_mul(x: &[Limb], y: &[Limb]) -> T where T: CloneableVecLike { // Using the immutable value, multiply by all the scalars in y, using // the algorithm defined above. Use a single buffer to avoid // frequent reallocations. Handle the first case to avoid a redundant // addition, since we know y.len() >= 1. let mut z: T = small::mul(x, y[0]); z.resize(x.len() + y.len(), 0); // Handle the iterative cases. for (i, &yi) in y[1..].iter().enumerate() { let zi: T = small::mul(x, yi); iadd_impl(&mut z, &zi, i+1); } small::normalize(&mut z); z } perftools_inline!{ /// Split two buffers into halfway, into (lo, hi). pub fn karatsuba_split<'a>(z: &'a [Limb], m: usize) -> (&'a [Limb], &'a [Limb]) { (&z[..m], &z[m..]) }} /// Karatsuba multiplication algorithm with roughly equal input sizes. /// /// Assumes `y.len() >= x.len()`. fn karatsuba_mul(x: &[Limb], y: &[Limb]) -> T where T: CloneableVecLike { if y.len() <= KARATSUBA_CUTOFF { // Bottom-out to long division for small cases. long_mul(x, y) } else if x.len() < y.len() / 2 { karatsuba_uneven_mul(x, y) } else { // Do our 3 multiplications. let m = y.len() / 2; let (xl, xh) = karatsuba_split(x, m); let (yl, yh) = karatsuba_split(y, m); let sumx: T = add(xl, xh); let sumy: T = add(yl, yh); let z0: T = karatsuba_mul(xl, yl); let mut z1: T = karatsuba_mul(&sumx, &sumy); let z2: T = karatsuba_mul(xh, yh); // Properly scale z1, which is `z1 - z2 - zo`. isub(&mut z1, &z2); isub(&mut z1, &z0); // Create our result, which is equal to, in little-endian order: // [z0, z1 - z2 - z0, z2] // z1 must be shifted m digits (2^(32m)) over. // z2 must be shifted 2*m digits (2^(64m)) over. let mut result = T::default(); let len = z0.len().max(m + z1.len()).max(2*m + z2.len()); result.reserve_exact(len); result.extend_from_slice(&z0); iadd_impl(&mut result, &z1, m); iadd_impl(&mut result, &z2, 2*m); result } } /// Karatsuba multiplication algorithm where y is substantially larger than x. /// /// Assumes `y.len() >= x.len()`. fn karatsuba_uneven_mul(x: &[Limb], mut y: &[Limb]) -> T where T: CloneableVecLike { let mut result = T::default(); result.resize(x.len() + y.len(), 0); // This effectively is like grade-school multiplication between // two numbers, except we're using splits on `y`, and the intermediate // step is a Karatsuba multiplication. let mut start = 0; while y.len() != 0 { let m = x.len().min(y.len()); let (yl, yh) = karatsuba_split(y, m); let prod: T = karatsuba_mul(x, yl); iadd_impl(&mut result, &prod, start); y = yh; start += m; } small::normalize(&mut result); result } perftools_inline!{ /// Forwarder to the proper Karatsuba algorithm. fn karatsuba_mul_fwd(x: &[Limb], y: &[Limb]) -> T where T: CloneableVecLike { if x.len() < y.len() { karatsuba_mul(x, y) } else { karatsuba_mul(y, x) } }} perftools_inline!{ /// MulAssign bigint to bigint. pub fn imul(x: &mut T, y: &[Limb]) where T: CloneableVecLike { if y.len() == 1 { small::imul(x, y[0]); } else { // We're not really in a condition where using Karatsuba // multiplication makes sense, so we're just going to use long // division. ~20% speedup compared to: // *x = karatsuba_mul_fwd(x, y); *x = karatsuba_mul_fwd(x, y); } }} perftools_inline!{ /// Mul bigint to bigint. pub fn mul(x: &[Limb], y: &[Limb]) -> T where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); imul(&mut z, y); z }} // DIVISION /// Constants for algorithm D. const ALGORITHM_D_B: Wide = 1 << ::BITS; const ALGORITHM_D_M: Wide = ALGORITHM_D_B - 1; /// Calculate qhat (an estimate for the quotient). /// /// This is step D3 in Algorithm D in "The Art of Computer Programming". /// Assumes `x.len() > y.len()` and `y.len() >= 2`. /// /// * `j` - Current index on the iteration of the loop. fn calculate_qhat(x: &[Limb], y: &[Limb], j: usize) -> Wide { let n = y.len(); // Estimate qhat of q[j] // Original Code: // qhat = (x[j+n]*B + x[j+n-1])/y[n-1]; // rhat = (x[j+n]*B + x[j+n-1]) - qhat*y[n-1]; let x_jn = as_wide(x[j+n]); let x_jn1 = as_wide(x[j+n-1]); let num = (x_jn << ::BITS) + x_jn1; let den = as_wide(y[n-1]); let mut qhat = num / den; let mut rhat = num - qhat * den; // Scale qhat and rhat // Original Code: // again: // if (qhat >= B || qhat*y[n-2] > B*rhat + x[j+n-2]) // { qhat = qhat - 1; // rhat = rhat + y[n-1]; // if (rhat < B) goto again; // } let x_jn2 = as_wide(x[j+n-2]); let y_n2 = as_wide(y[n-2]); let y_n1 = as_wide(y[n-1]); // This only happens when the leading bit of qhat is set. while qhat >= ALGORITHM_D_B || qhat * y_n2 > (rhat << ::BITS) + x_jn2 { qhat -= 1; rhat += y_n1; if rhat >= ALGORITHM_D_B { break; } } qhat } /// Multiply and subtract. /// /// This is step D4 in Algorithm D in "The Art of Computer Programming", /// and returns the remainder. fn multiply_and_subtract(x: &mut T, y: &T, qhat: Wide, j: usize) -> SignedWide where T: CloneableVecLike { let n = y.len(); // Multiply and subtract // Original Code: // k = 0; // for (i = 0; i < n; i++) { // p = qhat*y[i]; // t = x[i+j] - k - (p & 0xFFFFFFFFLL); // x[i+j] = t; // k = (p >> 32) - (t >> 32); // } // t = x[j+n] - k; // x[j+n] = t; let mut k: SignedWide = 0; let mut t: SignedWide; for i in 0..n { let x_ij = as_signed_wide(x[i+j]); let y_i = as_wide(y[i]); let p = qhat * y_i; t = x_ij.wrapping_sub(k).wrapping_sub(as_signed_wide(p & ALGORITHM_D_M)); x[i+j] = as_limb(t); k = as_signed_wide(p >> ::BITS) - (t >> ::BITS); } t = as_signed_wide(x[j+n]) - k; x[j+n] = as_limb(t); t } perftools_inline!{ /// Calculate the quotient from the estimate and the test. /// /// This is a mix of step D5 and D6 in Algorithm D, so the algorithm /// may work for single passes, without a quotient buffer. fn test_quotient(qhat: Wide, t: SignedWide) -> Wide { if t < 0 { qhat - 1 } else { qhat } }} /// Add back. /// /// This is step D6 in Algorithm D in "The Art of Computer Programming", /// and adds back the remainder on the very unlikely scenario we overestimated /// the quotient by 1. Subtract 1 from the quotient, and add back the /// remainder. /// /// This step should be specifically debugged, due to its low likelihood, /// since the probability is ~2/b, where b in this case is 2^32 or 2^64. fn add_back(x: &mut T, y: &T, mut t: SignedWide, j: usize) where T: CloneableVecLike { let n = y.len(); // Store quotient digits // If we subtracted too much, add back. // Original Code: // q[j] = qhat; // Store quotient digit. // if (t < 0) { // If we subtracted too // q[j] = q[j] - 1; // much, add back. // k = 0; // for (i = 0; i < n; i++) { // t = (unsigned long long)x[i+j] + y[i] + k; // x[i+j] = t; // k = t >> 32; // } // x[j+n] = x[j+n] + k; // } if t < 0 { let mut k: SignedWide = 0; for i in 0..n { t = as_signed_wide(as_wide(x[i+j]) + as_wide(y[i])) + k; x[i+j] = as_limb(t); k = t >> ::BITS; } let x_jn = as_signed_wide(x[j+n]) + k; x[j+n] = as_limb(x_jn); } } /// Calculate the remainder from the quotient. /// /// This is step D8 in Algorithm D in "The Art of Computer Programming", /// and "unnormalizes" to calculate the remainder from the quotient. fn calculate_remainder(x: &[Limb], y: &[Limb], s: usize) -> T where T: CloneableVecLike { // Calculate the remainder. // Original Code: // for (i = 0; i < n-1; i++) // r[i] = (x[i] >> s) | ((unsigned long long)x[i+1] << (32-s)); // r[n-1] = x[n-1] >> s; let n = y.len(); let mut r = T::default(); r.reserve_exact(n); let rs = ::BITS - s; for i in 0..n-1 { let xi = as_wide(x[i]) >> s; let xi1 = as_wide(x[i+1]) << rs; let ri = xi | xi1; r.push(as_limb(ri)); } let x_n1 = x[n-1] >> s; r.push(as_limb(x_n1)); r } /// Implementation of Knuth's Algorithm D, and return the quotient and remainder. /// /// `x` is the dividend, and `y` is the divisor. /// Assumes `x.len() > y.len()` and `y.len() >= 2`. /// /// Based off the Hacker's Delight implementation of Knuth's Algorithm D /// in "The Art of Computer Programming". /// http://www.hackersdelight.org/hdcodetxt/divmnu64.c.txt /// /// All Hacker's Delight code is public domain, so this routine shall /// also be placed in the public domain. See: /// https://www.hackersdelight.org/permissions.htm fn algorithm_d_div(x: &[Limb], y: &[Limb]) -> (T, T) where T: CloneableVecLike { // Normalize the divisor so the leading-bit is set to 1. // x is the dividend, y is the divisor. // Need a leading zero on the numerator. let s = y.rindex(0).leading_zeros().as_usize(); let m = x.len(); let n = y.len(); let mut xn: T = small::shl_bits(x, s); let yn: T = small::shl_bits(y, s); xn.push(0); // Store certain variables for the algorithm. let mut q = T::default(); q.resize(m-n+1, 0); for j in (0..m-n+1).rev() { // Estimate the quotient let mut qhat = calculate_qhat(&xn, &yn, j); if qhat != 0 { let t = multiply_and_subtract(&mut xn, &yn, qhat, j); qhat = test_quotient(qhat, t); add_back(&mut xn, &yn, t, j); } q[j] = as_limb(qhat); } let mut r = calculate_remainder(&xn, &yn, s); // Normalize our results small::normalize(&mut q); small::normalize(&mut r); (q, r) } perftools_inline!{ /// DivAssign bigint to bigint. pub fn idiv(x: &mut T, y: &[Limb]) -> T where T: CloneableVecLike { debug_assert!(y.len() != 0); if x.len() < y.len() { // Can optimize easily, since the quotient is 0, // and the remainder is x. Put before `y.len() == 1`, since // it optimizes when `x.len() == 0` nicely. let mut r = T::default(); mem::swap(x, &mut r); r } else if y.len() == 1 { // Can optimize for division by a small value. let mut r = T::default(); r.push(small::idiv(x, y[0])); r } else { let (q, r) = algorithm_d_div(x, y); *x = q; r } }} perftools_inline!{ /// Div bigint to bigint. pub fn div(x: &[Limb], y: &[Limb]) -> (T, T) where T: CloneableVecLike { let mut z = T::default(); z.extend_from_slice(x); let rem = idiv(&mut z, y); (z, rem) }} /// Emit a single digit for the quotient and store the remainder in-place. /// /// An extremely efficient division algorithm for small quotients, requiring /// you to know the full range of the quotient prior to use. For example, /// with a quotient that can range from [0, 10), you must have 4 leading /// zeros in the divisor, so we can use a single-limb division to get /// an accurate estimate of the quotient. Since we always underestimate /// the quotient, we can add 1 and then emit the digit. /// /// Requires a non-normalized denominator, with at least [1-6] leading /// zeros, depending on the base (for example, 1 for base2, 6 for base36). /// /// Adapted from David M. Gay's dtoa, and therefore under an MIT license: /// www.netlib.org/fp/dtoa.c pub fn quorem(x: &mut T, y: &T) -> Limb where T: CloneableVecLike { debug_assert!(y.len() > 0); let mask = as_wide(Limb::max_value()); // Numerator is smaller the denominator, quotient always 0. let m = x.len(); let n = y.len(); if m < n { return 0; } // Calculate our initial estimate for q let mut q = x[m-1] / (y[n-1] + 1); // Need to calculate the remainder if we don't have a 0 quotient. if q != 0 { let mut borrow: Wide = 0; let mut carry: Wide = 0; for j in 0..m { let p = as_wide(y[j]) * as_wide(q) + carry; carry = p >> ::BITS; let t = as_wide(x[j]).wrapping_sub(p & mask).wrapping_sub(borrow); borrow = (t >> ::BITS) & 1; x[j] = as_limb(t); } small::normalize(x); } // Check if we under-estimated x. if greater_equal(x, y) { q += 1; let mut borrow: Wide = 0; let mut carry: Wide = 0; for j in 0..m { let p = as_wide(y[j]) + carry; carry = p >> ::BITS; let t = as_wide(x[j]).wrapping_sub(p & mask).wrapping_sub(borrow); borrow = (t >> ::BITS) & 1; x[j] = as_limb(t); } small::normalize(x); } q } } // large use crate::lib::cmp; use super::small_powers::*; use super::large_powers::*; /// Generate the imul_pown wrappers. macro_rules! imul_power { ($name:ident, $base:expr) => ( perftools_inline!{ /// Multiply by a power of $base. fn $name(&mut self, n: u32) { self.imul_power_impl($base, n) }} ); } // TRAITS // ------ /// Traits for shared operations for big integers. /// /// None of these are implemented using normal traits, since these /// are very expensive operations, and we want to deliberately /// and explicitly use these functions. pub(in crate::atof::algorithm) trait SharedOps: Clone + Sized + Default { /// Underlying storage type for a SmallOps. type StorageType: CloneableVecLike; // DATA /// Get access to the underlying data fn data<'a>(&'a self) -> &'a Self::StorageType; /// Get access to the underlying data fn data_mut<'a>(&'a mut self) -> &'a mut Self::StorageType; // ZERO perftools_inline!{ /// Check if the value is a normalized 0. fn is_zero(&self) -> bool { self.limb_length() == 0 }} // RELATIVE OPERATIONS perftools_inline!{ /// Compare self to y. fn compare(&self, y: &Self) -> cmp::Ordering { large::compare(self.data(), y.data()) }} perftools_inline!{ /// Check if self is greater than y. fn greater(&self, y: &Self) -> bool { large::greater(self.data(), y.data()) }} perftools_inline!{ /// Check if self is greater than or equal to y. fn greater_equal(&self, y: &Self) -> bool { large::greater_equal(self.data(), y.data()) }} perftools_inline!{ /// Check if self is less than y. fn less(&self, y: &Self) -> bool { large::less(self.data(), y.data()) }} perftools_inline!{ /// Check if self is less than or equal to y. fn less_equal(&self, y: &Self) -> bool { large::less_equal(self.data(), y.data()) }} perftools_inline!{ /// Check if self is equal to y. fn equal(&self, y: &Self) -> bool { large::equal(self.data(), y.data()) }} // PROPERTIES perftools_inline!{ /// Get the number of leading zero digits in the storage. /// Assumes the value is normalized. fn leading_zero_limbs(&self) -> usize { small::leading_zero_limbs(self.data()) }} perftools_inline!{ /// Get the number of trailing zero digits in the storage. /// Assumes the value is normalized. fn trailing_zero_limbs(&self) -> usize { small::trailing_zero_limbs(self.data()) }} perftools_inline!{ /// Get number of leading zero bits in the storage. /// Assumes the value is normalized. fn leading_zeros(&self) -> usize { small::leading_zeros(self.data()) }} perftools_inline!{ /// Get number of trailing zero bits in the storage. /// Assumes the value is normalized. fn trailing_zeros(&self) -> usize { small::trailing_zeros(self.data()) }} perftools_inline!{ /// Calculate the bit-length of the big-integer. /// Returns usize::max_value() if the value overflows, /// IE, if `self.data().len() > usize::max_value() / 8`. fn bit_length(&self) -> usize { small::bit_length(self.data()) }} perftools_inline!{ /// Calculate the digit-length of the big-integer. fn limb_length(&self) -> usize { small::limb_length(self.data()) }} perftools_inline!{ /// Get the high 16-bits from the bigint and if there are remaining bits. fn hi16(&self) -> (u16, bool) { self.data().as_slice().hi16() }} perftools_inline!{ /// Get the high 32-bits from the bigint and if there are remaining bits. fn hi32(&self) -> (u32, bool) { self.data().as_slice().hi32() }} perftools_inline!{ /// Get the high 64-bits from the bigint and if there are remaining bits. fn hi64(&self) -> (u64, bool) { self.data().as_slice().hi64() }} perftools_inline!{ /// Get the high 128-bits from the bigint and if there are remaining bits. fn hi128(&self) -> (u128, bool) { self.data().as_slice().hi128() }} perftools_inline!{ /// Pad the buffer with zeros to the least-significant bits. fn pad_zero_digits(&mut self, n: usize) -> usize { small::ishl_limbs(self.data_mut(), n); n }} // INTEGER CONVERSIONS // CREATION perftools_inline!{ /// Create new big integer from u16. fn from_u16(x: u16) -> Self { let mut v = Self::default(); let slc = split_u16(x); v.data_mut().extend_from_slice(&slc); v.normalize(); v }} perftools_inline!{ /// Create new big integer from u32. fn from_u32(x: u32) -> Self { let mut v = Self::default(); let slc = split_u32(x); v.data_mut().extend_from_slice(&slc); v.normalize(); v }} perftools_inline!{ /// Create new big integer from u64. fn from_u64(x: u64) -> Self { let mut v = Self::default(); let slc = split_u64(x); v.data_mut().extend_from_slice(&slc); v.normalize(); v }} perftools_inline!{ /// Create new big integer from u128. fn from_u128(x: u128) -> Self { let mut v = Self::default(); let slc = split_u128(x); v.data_mut().extend_from_slice(&slc); v.normalize(); v }} // NORMALIZE perftools_inline!{ /// Normalize the integer, so any leading zero values are removed. fn normalize(&mut self) { small::normalize(self.data_mut()); }} perftools_inline!{ /// Get if the big integer is normalized. fn is_normalized(&self) -> bool { self.data().is_empty() || !self.data().rindex(0).is_zero() }} // SHIFTS perftools_inline!{ /// Shift-left the entire buffer n bits. fn ishl(&mut self, n: usize) { small::ishl(self.data_mut(), n); }} perftools_inline!{ /// Shift-left the entire buffer n bits. fn shl(&self, n: usize) -> Self { let mut x = self.clone(); x.ishl(n); x }} perftools_inline!{ /// Shift-right the entire buffer n bits. fn ishr(&mut self, n: usize, mut roundup: bool) { roundup &= small::ishr(self.data_mut(), n); // Round-up the least significant bit. if roundup { if self.data().is_empty() { self.data_mut().push(1); } else { self.data_mut()[0] += 1; } } }} perftools_inline!{ /// Shift-right the entire buffer n bits. fn shr(&self, n: usize, roundup: bool) -> Self { let mut x = self.clone(); x.ishr(n, roundup); x }} } /// Trait for small operations for arbitrary-precision numbers. pub(in crate::atof::algorithm) trait SmallOps: SharedOps { // SMALL POWERS perftools_inline!{ /// Get the small powers from the radix. fn small_powers(radix: u32) -> &'static [Limb] { get_small_powers(radix) }} perftools_inline!{ /// Get the large powers from the radix. fn large_powers(radix: u32) -> &'static [&'static [Limb]] { get_large_powers(radix) }} // ADDITION perftools_inline!{ /// AddAssign small integer. fn iadd_small(&mut self, y: Limb) { small::iadd(self.data_mut(), y); }} perftools_inline!{ /// Add small integer to a copy of self. fn add_small(&self, y: Limb) -> Self { let mut x = self.clone(); x.iadd_small(y); x }} // SUBTRACTION perftools_inline!{ /// SubAssign small integer. /// Warning: Does no overflow checking, x must be >= y. fn isub_small(&mut self, y: Limb) { small::isub(self.data_mut(), y); }} perftools_inline!{ /// Sub small integer to a copy of self. /// Warning: Does no overflow checking, x must be >= y. fn sub_small(&mut self, y: Limb) -> Self { let mut x = self.clone(); x.isub_small(y); x }} // MULTIPLICATION perftools_inline!{ /// MulAssign small integer. fn imul_small(&mut self, y: Limb) { small::imul(self.data_mut(), y); }} perftools_inline!{ /// Mul small integer to a copy of self. fn mul_small(&self, y: Limb) -> Self { let mut x = self.clone(); x.imul_small(y); x }} perftools_inline!{ /// MulAssign by a power. fn imul_power_impl(&mut self, radix: u32, n: u32) { small::imul_power(self.data_mut(), radix, n); }} perftools_inline!{ fn imul_power(&mut self, radix: u32, n: u32) { match radix { 2 => self.imul_pow2(n), 3 => self.imul_pow3(n), 4 => self.imul_pow4(n), 5 => self.imul_pow5(n), 6 => self.imul_pow6(n), 7 => self.imul_pow7(n), 8 => self.imul_pow8(n), 9 => self.imul_pow9(n), 10 => self.imul_pow10(n), 11 => self.imul_pow11(n), 12 => self.imul_pow12(n), 13 => self.imul_pow13(n), 14 => self.imul_pow14(n), 15 => self.imul_pow15(n), 16 => self.imul_pow16(n), 17 => self.imul_pow17(n), 18 => self.imul_pow18(n), 19 => self.imul_pow19(n), 20 => self.imul_pow20(n), 21 => self.imul_pow21(n), 22 => self.imul_pow22(n), 23 => self.imul_pow23(n), 24 => self.imul_pow24(n), 25 => self.imul_pow25(n), 26 => self.imul_pow26(n), 27 => self.imul_pow27(n), 28 => self.imul_pow28(n), 29 => self.imul_pow29(n), 30 => self.imul_pow30(n), 31 => self.imul_pow31(n), 32 => self.imul_pow32(n), 33 => self.imul_pow33(n), 34 => self.imul_pow34(n), 35 => self.imul_pow35(n), 36 => self.imul_pow36(n), _ => unreachable!() } }} perftools_inline!{ /// Multiply by a power of 2. fn imul_pow2(&mut self, n: u32) { self.ishl(n.as_usize()) }} imul_power!(imul_pow3, 3); perftools_inline!{ /// Multiply by a power of 4. fn imul_pow4(&mut self, n: u32) { self.imul_pow2(2*n); }} imul_power!(imul_pow5, 5); perftools_inline!{ /// Multiply by a power of 6. fn imul_pow6(&mut self, n: u32) { self.imul_pow3(n); self.imul_pow2(n); }} imul_power!(imul_pow7, 7); perftools_inline!{ /// Multiply by a power of 8. fn imul_pow8(&mut self, n: u32) { self.imul_pow2(3*n); }} perftools_inline!{ /// Multiply by a power of 9. fn imul_pow9(&mut self, n: u32) { self.imul_pow3(n); self.imul_pow3(n); }} perftools_inline!{ /// Multiply by a power of 10. fn imul_pow10(&mut self, n: u32) { self.imul_pow5(n); self.imul_pow2(n); }} imul_power!(imul_pow11, 11); perftools_inline!{ /// Multiply by a power of 12. fn imul_pow12(&mut self, n: u32) { self.imul_pow3(n); self.imul_pow4(n); }} imul_power!(imul_pow13, 13); perftools_inline!{ /// Multiply by a power of 14. fn imul_pow14(&mut self, n: u32) { self.imul_pow7(n); self.imul_pow2(n); }} perftools_inline!{ /// Multiply by a power of 15. fn imul_pow15(&mut self, n: u32) { self.imul_pow3(n); self.imul_pow5(n); }} perftools_inline!{ /// Multiply by a power of 16. fn imul_pow16(&mut self, n: u32) { self.imul_pow2(4*n); }} imul_power!(imul_pow17, 17); perftools_inline!{ /// Multiply by a power of 18. fn imul_pow18(&mut self, n: u32) { self.imul_pow9(n); self.imul_pow2(n); }} imul_power!(imul_pow19, 19); perftools_inline!{ /// Multiply by a power of 20. fn imul_pow20(&mut self, n: u32) { self.imul_pow5(n); self.imul_pow4(n); }} perftools_inline!{ /// Multiply by a power of 21. fn imul_pow21(&mut self, n: u32) { self.imul_pow3(n); self.imul_pow7(n); }} perftools_inline!{ /// Multiply by a power of 22. fn imul_pow22(&mut self, n: u32) { self.imul_pow11(n); self.imul_pow2(n); }} imul_power!(imul_pow23, 23); perftools_inline!{ /// Multiply by a power of 24. fn imul_pow24(&mut self, n: u32) { self.imul_pow3(n); self.imul_pow8(n); }} perftools_inline!{ /// Multiply by a power of 25. fn imul_pow25(&mut self, n: u32) { self.imul_pow5(n); self.imul_pow5(n); }} perftools_inline!{ /// Multiply by a power of 26. fn imul_pow26(&mut self, n: u32) { self.imul_pow13(n); self.imul_pow2(n); }} perftools_inline!{ /// Multiply by a power of 27. fn imul_pow27(&mut self, n: u32) { self.imul_pow9(n); self.imul_pow3(n); }} perftools_inline!{ /// Multiply by a power of 28. fn imul_pow28(&mut self, n: u32) { self.imul_pow7(n); self.imul_pow4(n); }} imul_power!(imul_pow29, 29); perftools_inline!{ /// Multiply by a power of 30. fn imul_pow30(&mut self, n: u32) { self.imul_pow15(n); self.imul_pow2(n); }} imul_power!(imul_pow31, 31); perftools_inline!{ /// Multiply by a power of 32. fn imul_pow32(&mut self, n: u32) { self.imul_pow2(5*n); }} perftools_inline!{ /// Multiply by a power of 33. fn imul_pow33(&mut self, n: u32) { self.imul_pow3(n); self.imul_pow11(n); }} perftools_inline!{ /// Multiply by a power of 34. fn imul_pow34(&mut self, n: u32) { self.imul_pow17(n); self.imul_pow2(n); }} perftools_inline!{ /// Multiply by a power of 35. fn imul_pow35(&mut self, n: u32) { self.imul_pow5(n); self.imul_pow7(n); }} perftools_inline!{ /// Multiply by a power of 36. fn imul_pow36(&mut self, n: u32) { self.imul_pow9(n); self.imul_pow4(n); }} // DIVISION perftools_inline!{ /// DivAssign small integer, and return the remainder. fn idiv_small(&mut self, y: Limb) -> Limb { small::idiv(self.data_mut(), y) }} perftools_inline!{ /// Div small integer to a copy of self, and return the remainder. fn div_small(&self, y: Limb) -> (Self, Limb) { let mut x = self.clone(); let rem = x.idiv_small(y); (x, rem) }} // POWER perftools_inline!{ /// Calculate self^n fn ipow(&mut self, n: Limb) { small::ipow(self.data_mut(), n); }} perftools_inline!{ /// Calculate self^n fn pow(&self, n: Limb) -> Self { let mut x = self.clone(); x.ipow(n); x }} } /// Trait for large operations for arbitrary-precision numbers. pub(in crate::atof::algorithm) trait LargeOps: SmallOps { // ADDITION perftools_inline!{ /// AddAssign large integer. fn iadd_large(&mut self, y: &Self) { large::iadd(self.data_mut(), y.data()); }} perftools_inline!{ /// Add large integer to a copy of self. fn add_large(&mut self, y: &Self) -> Self { let mut x = self.clone(); x.iadd_large(y); x }} // SUBTRACTION perftools_inline!{ /// SubAssign large integer. /// Warning: Does no overflow checking, x must be >= y. fn isub_large(&mut self, y: &Self) { large::isub(self.data_mut(), y.data()); }} perftools_inline!{ /// Sub large integer to a copy of self. /// Warning: Does no overflow checking, x must be >= y. fn sub_large(&mut self, y: &Self) -> Self { let mut x = self.clone(); x.isub_large(y); x }} // MULTIPLICATION perftools_inline!{ /// MulAssign large integer. fn imul_large(&mut self, y: &Self) { large::imul(self.data_mut(), y.data()); }} perftools_inline!{ /// Mul large integer to a copy of self. fn mul_large(&mut self, y: &Self) -> Self { let mut x = self.clone(); x.imul_large(y); x }} // DIVISION perftools_inline!{ /// DivAssign large integer and get remainder. fn idiv_large(&mut self, y: &Self) -> Self { let mut rem = Self::default(); *rem.data_mut() = large::idiv(self.data_mut(), y.data()); rem }} perftools_inline!{ /// Div large integer to a copy of self and get quotient and remainder. fn div_large(&mut self, y: &Self) -> (Self, Self) { let mut x = self.clone(); let rem = x.idiv_large(y); (x, rem) }} perftools_inline!{ /// Calculate the fast quotient for a single limb-bit quotient. /// /// This requires a non-normalized divisor, where there at least /// `integral_binary_factor` 0 bits set, to ensure at maximum a single /// digit will be produced for a single base. /// /// Warning: This is not a general-purpose division algorithm, /// it is highly specialized for peeling off singular digits. fn quorem(&mut self, y: &Self) -> Limb { large::quorem(self.data_mut(), y.data()) }} } #[cfg(test)] mod tests { use crate::util::test::*; use super::*; #[derive(Clone, Default)] struct Bigint { data: DataType, } impl Bigint { #[inline] pub fn new() -> Bigint { Bigint { data: arrvec![] } } } impl SharedOps for Bigint { type StorageType = DataType; #[inline] fn data<'a>(&'a self) -> &'a Self::StorageType { &self.data } #[inline] fn data_mut<'a>(&'a mut self) -> &'a mut Self::StorageType { &mut self.data } } impl SmallOps for Bigint { } impl LargeOps for Bigint { } // SHARED OPS #[test] fn greater_test() { // Simple let x = Bigint { data: from_u32(&[1]) }; let y = Bigint { data: from_u32(&[2]) }; assert!(!x.greater(&y)); assert!(!x.greater(&x)); assert!(y.greater(&x)); // Check asymmetric let x = Bigint { data: from_u32(&[5, 1]) }; let y = Bigint { data: from_u32(&[2]) }; assert!(x.greater(&y)); assert!(!x.greater(&x)); assert!(!y.greater(&x)); // Check when we use reverse ordering properly. let x = Bigint { data: from_u32(&[5, 1, 9]) }; let y = Bigint { data: from_u32(&[6, 2, 8]) }; assert!(x.greater(&y)); assert!(!x.greater(&x)); assert!(!y.greater(&x)); // Complex scenario, check it properly uses reverse ordering. let x = Bigint { data: from_u32(&[0, 1, 9]) }; let y = Bigint { data: from_u32(&[4294967295, 0, 9]) }; assert!(x.greater(&y)); assert!(!x.greater(&x)); assert!(!y.greater(&x)); } #[test] fn greater_equal_test() { // Simple let x = Bigint { data: from_u32(&[1]) }; let y = Bigint { data: from_u32(&[2]) }; assert!(!x.greater_equal(&y)); assert!(x.greater_equal(&x)); assert!(y.greater_equal(&x)); // Check asymmetric let x = Bigint { data: from_u32(&[5, 1]) }; let y = Bigint { data: from_u32(&[2]) }; assert!(x.greater_equal(&y)); assert!(x.greater_equal(&x)); assert!(!y.greater_equal(&x)); // Check when we use reverse ordering properly. let x = Bigint { data: from_u32(&[5, 1, 9]) }; let y = Bigint { data: from_u32(&[6, 2, 8]) }; assert!(x.greater_equal(&y)); assert!(x.greater_equal(&x)); assert!(!y.greater_equal(&x)); // Complex scenario, check it properly uses reverse ordering. let x = Bigint { data: from_u32(&[0, 1, 9]) }; let y = Bigint { data: from_u32(&[4294967295, 0, 9]) }; assert!(x.greater_equal(&y)); assert!(x.greater_equal(&x)); assert!(!y.greater_equal(&x)); } #[test] fn equal_test() { // Simple let x = Bigint { data: from_u32(&[1]) }; let y = Bigint { data: from_u32(&[2]) }; assert!(!x.equal(&y)); assert!(x.equal(&x)); assert!(!y.equal(&x)); // Check asymmetric let x = Bigint { data: from_u32(&[5, 1]) }; let y = Bigint { data: from_u32(&[2]) }; assert!(!x.equal(&y)); assert!(x.equal(&x)); assert!(!y.equal(&x)); // Check when we use reverse ordering properly. let x = Bigint { data: from_u32(&[5, 1, 9]) }; let y = Bigint { data: from_u32(&[6, 2, 8]) }; assert!(!x.equal(&y)); assert!(x.equal(&x)); assert!(!y.equal(&x)); // Complex scenario, check it properly uses reverse ordering. let x = Bigint { data: from_u32(&[0, 1, 9]) }; let y = Bigint { data: from_u32(&[4294967295, 0, 9]) }; assert!(!x.equal(&y)); assert!(x.equal(&x)); assert!(!y.equal(&x)); } #[test] fn less_test() { // Simple let x = Bigint { data: from_u32(&[1]) }; let y = Bigint { data: from_u32(&[2]) }; assert!(x.less(&y)); assert!(!x.less(&x)); assert!(!y.less(&x)); // Check asymmetric let x = Bigint { data: from_u32(&[5, 1]) }; let y = Bigint { data: from_u32(&[2]) }; assert!(!x.less(&y)); assert!(!x.less(&x)); assert!(y.less(&x)); // Check when we use reverse ordering properly. let x = Bigint { data: from_u32(&[5, 1, 9]) }; let y = Bigint { data: from_u32(&[6, 2, 8]) }; assert!(!x.less(&y)); assert!(!x.less(&x)); assert!(y.less(&x)); // Complex scenario, check it properly uses reverse ordering. let x = Bigint { data: from_u32(&[0, 1, 9]) }; let y = Bigint { data: from_u32(&[4294967295, 0, 9]) }; assert!(!x.less(&y)); assert!(!x.less(&x)); assert!(y.less(&x)); } #[test] fn less_equal_test() { // Simple let x = Bigint { data: from_u32(&[1]) }; let y = Bigint { data: from_u32(&[2]) }; assert!(x.less_equal(&y)); assert!(x.less_equal(&x)); assert!(!y.less_equal(&x)); // Check asymmetric let x = Bigint { data: from_u32(&[5, 1]) }; let y = Bigint { data: from_u32(&[2]) }; assert!(!x.less_equal(&y)); assert!(x.less_equal(&x)); assert!(y.less_equal(&x)); // Check when we use reverse ordering properly. let x = Bigint { data: from_u32(&[5, 1, 9]) }; let y = Bigint { data: from_u32(&[6, 2, 8]) }; assert!(!x.less_equal(&y)); assert!(x.less_equal(&x)); assert!(y.less_equal(&x)); // Complex scenario, check it properly uses reverse ordering. let x = Bigint { data: from_u32(&[0, 1, 9]) }; let y = Bigint { data: from_u32(&[4294967295, 0, 9]) }; assert!(!x.less_equal(&y)); assert!(x.less_equal(&x)); assert!(y.less_equal(&x)); } #[test] fn leading_zero_limbs_test() { assert_eq!(Bigint::new().leading_zero_limbs(), 0); assert_eq!(Bigint::from_u16(0xF).leading_zero_limbs(), 0); assert_eq!(Bigint::from_u32(0xFF).leading_zero_limbs(), 0); assert_eq!(Bigint::from_u64(0xFF00000000).leading_zero_limbs(), 0); assert_eq!(Bigint::from_u128(0xFF000000000000000000000000).leading_zero_limbs(), 0); assert_eq!(Bigint::from_u16(0xF).leading_zero_limbs(), 0); assert_eq!(Bigint::from_u32(0xF).leading_zero_limbs(), 0); assert_eq!(Bigint::from_u64(0xF00000000).leading_zero_limbs(), 0); assert_eq!(Bigint::from_u128(0xF000000000000000000000000).leading_zero_limbs(), 0); assert_eq!(Bigint::from_u16(0xF0).leading_zero_limbs(), 0); assert_eq!(Bigint::from_u32(0xF0).leading_zero_limbs(), 0); assert_eq!(Bigint::from_u64(0xF000000000).leading_zero_limbs(), 0); assert_eq!(Bigint::from_u128(0xF0000000000000000000000000).leading_zero_limbs(), 0); } #[test] fn trailing_zero_limbs_test() { assert_eq!(Bigint::new().trailing_zero_limbs(), 0); assert_eq!(Bigint { data: arrvec![0xFF] }.trailing_zero_limbs(), 0); assert_eq!(Bigint { data: arrvec![0, 0xFF000] }.trailing_zero_limbs(), 1); assert_eq!(Bigint { data: arrvec![0, 0, 0, 0xFF000] }.trailing_zero_limbs(), 3); } #[test] fn leading_zeros_test() { assert_eq!(Bigint::new().leading_zeros(), 0); assert_eq!(Bigint::from_u16(0xFF).leading_zeros(), ::BITS-8); assert_eq!(Bigint::from_u32(0xFF).leading_zeros(), ::BITS-8); assert_eq!(Bigint::from_u64(0xFF00000000).leading_zeros(), 24); assert_eq!(Bigint::from_u128(0xFF000000000000000000000000).leading_zeros(), 24); assert_eq!(Bigint::from_u16(0xF).leading_zeros(), ::BITS-4); assert_eq!(Bigint::from_u32(0xF).leading_zeros(), ::BITS-4); assert_eq!(Bigint::from_u64(0xF00000000).leading_zeros(), 28); assert_eq!(Bigint::from_u128(0xF000000000000000000000000).leading_zeros(), 28); assert_eq!(Bigint::from_u16(0xF0).leading_zeros(), ::BITS-8); assert_eq!(Bigint::from_u32(0xF0).leading_zeros(), ::BITS-8); assert_eq!(Bigint::from_u64(0xF000000000).leading_zeros(), 24); assert_eq!(Bigint::from_u128(0xF0000000000000000000000000).leading_zeros(), 24); } #[test] fn trailing_zeros_test() { assert_eq!(Bigint::new().trailing_zeros(), 0); assert_eq!(Bigint::from_u16(0xFF).trailing_zeros(), 0); assert_eq!(Bigint::from_u32(0xFF).trailing_zeros(), 0); assert_eq!(Bigint::from_u64(0xFF00000000).trailing_zeros(), 32); assert_eq!(Bigint::from_u128(0xFF000000000000000000000000).trailing_zeros(), 96); assert_eq!(Bigint::from_u16(0xF).trailing_zeros(), 0); assert_eq!(Bigint::from_u32(0xF).trailing_zeros(), 0); assert_eq!(Bigint::from_u64(0xF00000000).trailing_zeros(), 32); assert_eq!(Bigint::from_u128(0xF000000000000000000000000).trailing_zeros(), 96); assert_eq!(Bigint::from_u16(0xF0).trailing_zeros(), 4); assert_eq!(Bigint::from_u32(0xF0).trailing_zeros(), 4); assert_eq!(Bigint::from_u64(0xF000000000).trailing_zeros(), 36); assert_eq!(Bigint::from_u128(0xF0000000000000000000000000).trailing_zeros(), 100); } #[test] fn hi32_test() { assert_eq!(Bigint::from_u16(0xA).hi32(), (0xA0000000, false)); assert_eq!(Bigint::from_u32(0xAB).hi32(), (0xAB000000, false)); assert_eq!(Bigint::from_u64(0xAB00000000).hi32(), (0xAB000000, false)); assert_eq!(Bigint::from_u64(0xA23456789A).hi32(), (0xA2345678, true)); } #[test] fn hi64_test() { assert_eq!(Bigint::from_u16(0xA).hi64(), (0xA000000000000000, false)); assert_eq!(Bigint::from_u32(0xAB).hi64(), (0xAB00000000000000, false)); assert_eq!(Bigint::from_u64(0xAB00000000).hi64(), (0xAB00000000000000, false)); assert_eq!(Bigint::from_u64(0xA23456789A).hi64(), (0xA23456789A000000, false)); assert_eq!(Bigint::from_u128(0xABCDEF0123456789ABCDEF0123).hi64(), (0xABCDEF0123456789, true)); } #[test] fn hi128_test() { assert_eq!(Bigint::from_u128(0xABCDEF0123456789ABCDEF0123).hi128(), (0xABCDEF0123456789ABCDEF0123000000, false)); assert_eq!(Bigint::from_u128(0xABCDEF0123456789ABCDEF0123456789).hi128(), (0xABCDEF0123456789ABCDEF0123456789, false)); assert_eq!(Bigint { data: from_u32(&[0x34567890, 0xBCDEF012, 0x3456789A, 0xBCDEF012, 0xA]) }.hi128(), (0xABCDEF0123456789ABCDEF0123456789, false)); assert_eq!(Bigint { data: from_u32(&[0x34567891, 0xBCDEF012, 0x3456789A, 0xBCDEF012, 0xA]) }.hi128(), (0xABCDEF0123456789ABCDEF0123456789, true)); } #[test] fn pad_zero_digits_test() { let mut x = Bigint { data: arrvec![0, 0, 0, 1] }; x.pad_zero_digits(3); assert_eq!(x.data.as_slice(), &[0, 0, 0, 0, 0, 0, 1]); let mut x = Bigint { data: arrvec![1] }; x.pad_zero_digits(1); assert_eq!(x.data.as_slice(), &[0, 1]); } #[test] fn shl_test() { // Pattern generated via `''.join(["1" +"0"*i for i in range(20)])` let mut big = Bigint { data: from_u32(&[0xD2210408]) }; big.ishl(5); assert_eq!(big.data, from_u32(&[0x44208100, 0x1A])); big.ishl(32); assert_eq!(big.data, from_u32(&[0, 0x44208100, 0x1A])); big.ishl(27); assert_eq!(big.data, from_u32(&[0, 0, 0xD2210408])); // 96-bits of previous pattern let mut big = Bigint { data: from_u32(&[0x20020010, 0x8040100, 0xD2210408]) }; big.ishl(5); assert_eq!(big.data, from_u32(&[0x400200, 0x802004, 0x44208101, 0x1A])); big.ishl(32); assert_eq!(big.data, from_u32(&[0, 0x400200, 0x802004, 0x44208101, 0x1A])); big.ishl(27); assert_eq!(big.data, from_u32(&[0, 0, 0x20020010, 0x8040100, 0xD2210408])); } #[test] fn shr_test() { // Simple case. let mut big = Bigint { data: from_u32(&[0xD2210408]) }; big.ishr(5, false); assert_eq!(big.data, from_u32(&[0x6910820])); big.ishr(27, false); assert_eq!(big.data, from_u32(&[])); // Pattern generated via `''.join(["1" +"0"*i for i in range(20)])` let mut big = Bigint { data: from_u32(&[0x20020010, 0x8040100, 0xD2210408]) }; big.ishr(5, false); assert_eq!(big.data, from_u32(&[0x1001000, 0x40402008, 0x6910820])); big.ishr(32, false); assert_eq!(big.data, from_u32(&[0x40402008, 0x6910820])); big.ishr(27, false); assert_eq!(big.data, from_u32(&[0xD2210408])); // Check no-roundup with halfway and even let mut big = Bigint { data: from_u32(&[0xD2210408]) }; big.ishr(3, true); assert_eq!(big.data, from_u32(&[0x1A442081])); big.ishr(1, true); assert_eq!(big.data, from_u32(&[0xD221040])); let mut big = Bigint { data: from_u32(&[0xD2210408]) }; big.ishr(4, true); assert_eq!(big.data, from_u32(&[0xD221040])); // Check roundup with halfway and odd let mut big = Bigint { data: from_u32(&[0xD2210438]) }; big.ishr(3, true); assert_eq!(big.data, from_u32(&[0x1A442087])); big.ishr(1, true); assert_eq!(big.data, from_u32(&[0xD221044])); let mut big = Bigint { data: from_u32(&[0xD2210438]) }; big.ishr(5, true); assert_eq!(big.data, from_u32(&[0x6910822])); } #[test] fn bit_length_test() { let x = Bigint { data: from_u32(&[0, 0, 0, 1]) }; assert_eq!(x.bit_length(), 97); let x = Bigint { data: from_u32(&[0, 0, 0, 3]) }; assert_eq!(x.bit_length(), 98); let x = Bigint { data: from_u32(&[1<<31]) }; assert_eq!(x.bit_length(), 32); } // SMALL OPS #[test] fn iadd_small_test() { // Overflow check (single) // This should set all the internal data values to 0, the top // value to (1<<31), and the bottom value to (4>>1). // This is because the max_value + 1 leads to all 0s, we set the // topmost bit to 1. let mut x = Bigint { data: from_u32(&[4294967295]) }; x.iadd_small(5); assert_eq!(x.data, from_u32(&[4, 1])); // No overflow, single value let mut x = Bigint { data: from_u32(&[5]) }; x.iadd_small(7); assert_eq!(x.data, from_u32(&[12])); // Single carry, internal overflow let mut x = Bigint::from_u64(0x80000000FFFFFFFF); x.iadd_small(7); assert_eq!(x.data, from_u32(&[6, 0x80000001])); // Double carry, overflow let mut x = Bigint::from_u64(0xFFFFFFFFFFFFFFFF); x.iadd_small(7); assert_eq!(x.data, from_u32(&[6, 0, 1])); } #[test] fn isub_small_test() { // Overflow check (single) let mut x = Bigint { data: from_u32(&[4, 1]) }; x.isub_small(5); assert_eq!(x.data, from_u32(&[4294967295])); // No overflow, single value let mut x = Bigint { data: from_u32(&[12]) }; x.isub_small(7); assert_eq!(x.data, from_u32(&[5])); // Single carry, internal overflow let mut x = Bigint { data: from_u32(&[6, 0x80000001]) }; x.isub_small(7); assert_eq!(x.data, from_u32(&[0xFFFFFFFF, 0x80000000])); // Double carry, overflow let mut x = Bigint { data: from_u32(&[6, 0, 1]) }; x.isub_small(7); assert_eq!(x.data, from_u32(&[0xFFFFFFFF, 0xFFFFFFFF])); } #[test] fn imul_small_test() { // No overflow check, 1-int. let mut x = Bigint { data: from_u32(&[5]) }; x.imul_small(7); assert_eq!(x.data, from_u32(&[35])); // No overflow check, 2-ints. let mut x = Bigint::from_u64(0x4000000040000); x.imul_small(5); assert_eq!(x.data, from_u32(&[0x00140000, 0x140000])); // Overflow, 1 carry. let mut x = Bigint { data: from_u32(&[0x33333334]) }; x.imul_small(5); assert_eq!(x.data, from_u32(&[4, 1])); // Overflow, 1 carry, internal. let mut x = Bigint::from_u64(0x133333334); x.imul_small(5); assert_eq!(x.data, from_u32(&[4, 6])); // Overflow, 2 carries. let mut x = Bigint::from_u64(0x3333333333333334); x.imul_small(5); assert_eq!(x.data, from_u32(&[4, 0, 1])); } #[test] fn idiv_small_test() { let mut x = Bigint { data: from_u32(&[4]) }; assert_eq!(x.idiv_small(7), 4); assert_eq!(x.data, from_u32(&[])); let mut x = Bigint { data: from_u32(&[3]) }; assert_eq!(x.idiv_small(7), 3); assert_eq!(x.data, from_u32(&[])); // Check roundup, odd, halfway let mut x = Bigint { data: from_u32(&[15]) }; assert_eq!(x.idiv_small(10), 5); assert_eq!(x.data, from_u32(&[1])); // Check 1 carry. let mut x = Bigint::from_u64(0x133333334); assert_eq!(x.idiv_small(5), 1); assert_eq!(x.data, from_u32(&[0x3D70A3D7])); // Check 2 carries. let mut x = Bigint::from_u64(0x3333333333333334); assert_eq!(x.idiv_small(5), 4); assert_eq!(x.data, from_u32(&[0xD70A3D70, 0xA3D70A3])); } #[test] fn ipow_test() { let x = Bigint { data: from_u32(&[5]) }; assert_eq!(x.pow(2).data, from_u32(&[25])); assert_eq!(x.pow(15).data, from_u32(&[452807053, 7])); assert_eq!(x.pow(16).data, from_u32(&[2264035265, 35])); assert_eq!(x.pow(17).data, from_u32(&[2730241733, 177])); assert_eq!(x.pow(302).data, from_u32(&[2443090281, 2149694430, 2297493928, 1584384001, 1279504719, 1930002239, 3312868939, 3735173465, 3523274756, 2025818732, 1641675015, 2431239749, 4292780461, 3719612855, 4174476133, 3296847770, 2677357556, 638848153, 2198928114, 3285049351, 2159526706, 626302612])); } // LARGE OPS #[test] fn iadd_large_test() { // Overflow, both single values let mut x = Bigint { data: from_u32(&[4294967295]) }; let y = Bigint { data: from_u32(&[5]) }; x.iadd_large(&y); assert_eq!(x.data, from_u32(&[4, 1])); // No overflow, single value let mut x = Bigint { data: from_u32(&[5]) }; let y = Bigint { data: from_u32(&[7]) }; x.iadd_large(&y); assert_eq!(x.data, from_u32(&[12])); // Single carry, internal overflow let mut x = Bigint::from_u64(0x80000000FFFFFFFF); let y = Bigint { data: from_u32(&[7]) }; x.iadd_large(&y); assert_eq!(x.data, from_u32(&[6, 0x80000001])); // 1st overflows, 2nd doesn't. let mut x = Bigint::from_u64(0x7FFFFFFFFFFFFFFF); let y = Bigint::from_u64(0x7FFFFFFFFFFFFFFF); x.iadd_large(&y); assert_eq!(x.data, from_u32(&[0xFFFFFFFE, 0xFFFFFFFF])); // Both overflow. let mut x = Bigint::from_u64(0x8FFFFFFFFFFFFFFF); let y = Bigint::from_u64(0x7FFFFFFFFFFFFFFF); x.iadd_large(&y); assert_eq!(x.data, from_u32(&[0xFFFFFFFE, 0x0FFFFFFF, 1])); } #[test] fn isub_large_test() { // Overflow, both single values let mut x = Bigint { data: from_u32(&[4, 1]) }; let y = Bigint { data: from_u32(&[5]) }; x.isub_large(&y); assert_eq!(x.data, from_u32(&[4294967295])); // No overflow, single value let mut x = Bigint { data: from_u32(&[12]) }; let y = Bigint { data: from_u32(&[7]) }; x.isub_large(&y); assert_eq!(x.data, from_u32(&[5])); // Single carry, internal overflow let mut x = Bigint { data: from_u32(&[6, 0x80000001]) }; let y = Bigint { data: from_u32(&[7]) }; x.isub_large(&y); assert_eq!(x.data, from_u32(&[0xFFFFFFFF, 0x80000000])); // Zeros out. let mut x = Bigint { data: from_u32(&[0xFFFFFFFF, 0x7FFFFFFF]) }; let y = Bigint { data: from_u32(&[0xFFFFFFFF, 0x7FFFFFFF]) }; x.isub_large(&y); assert_eq!(x.data, from_u32(&[])); // 1st overflows, 2nd doesn't. let mut x = Bigint { data: from_u32(&[0xFFFFFFFE, 0x80000000]) }; let y = Bigint { data: from_u32(&[0xFFFFFFFF, 0x7FFFFFFF]) }; x.isub_large(&y); assert_eq!(x.data, from_u32(&[0xFFFFFFFF])); } #[test] fn imul_large_test() { // Test by empty let mut x = Bigint { data: from_u32(&[0xFFFFFFFF]) }; let y = Bigint { data: from_u32(&[]) }; x.imul_large(&y); assert_eq!(x.data, from_u32(&[])); // Simple case let mut x = Bigint { data: from_u32(&[0xFFFFFFFF]) }; let y = Bigint { data: from_u32(&[5]) }; x.imul_large(&y); assert_eq!(x.data, from_u32(&[0xFFFFFFFB, 0x4])); // Large u32, but still just as easy. let mut x = Bigint { data: from_u32(&[0xFFFFFFFF]) }; let y = Bigint { data: from_u32(&[0xFFFFFFFE]) }; x.imul_large(&y); assert_eq!(x.data, from_u32(&[0x2, 0xFFFFFFFD])); // Let's multiply two large values together let mut x = Bigint { data: from_u32(&[0xFFFFFFFE, 0x0FFFFFFF, 1]) }; let y = Bigint { data: from_u32(&[0x99999999, 0x99999999, 0xCCCD9999, 0xCCCC]) }; x.imul_large(&y); assert_eq!(x.data, from_u32(&[0xCCCCCCCE, 0x5CCCCCCC, 0x9997FFFF, 0x33319999, 0x999A7333, 0xD999])); } #[test] fn imul_karatsuba_mul_test() { // Test cases triggered to use `karatsuba_mul`. let mut x = Bigint { data: from_u32(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) }; let y = Bigint { data: from_u32(&[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) }; x.imul_large(&y); assert_eq!(x.data, from_u32(&[4, 13, 28, 50, 80, 119, 168, 228, 300, 385, 484, 598, 728, 875, 1040, 1224, 1340, 1435, 1508, 1558, 1584, 1585, 1560, 1508, 1428, 1319, 1180, 1010, 808, 573, 304])); // Test cases to use karatsuba_uneven_mul let mut x = Bigint { data: from_u32(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) }; let y = Bigint { data: from_u32(&[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37]) }; x.imul_large(&y); assert_eq!(x.data, from_u32(&[4, 13, 28, 50, 80, 119, 168, 228, 300, 385, 484, 598, 728, 875, 1040, 1224, 1360, 1496, 1632, 1768, 1904, 2040, 2176, 2312, 2448, 2584, 2720, 2856, 2992, 3128, 3264, 3400, 3536, 3672, 3770, 3829, 3848, 3826, 3762, 3655, 3504, 3308, 3066, 2777, 2440, 2054, 1618, 1131, 592])); } #[test] fn idiv_large_test() { // Simple case. let mut x = Bigint { data: from_u32(&[0xFFFFFFFF]) }; let y = Bigint { data: from_u32(&[5]) }; let rem = x.idiv_large(&y); assert_eq!(x.data, from_u32(&[0x33333333])); assert_eq!(rem.data, from_u32(&[0])); // Two integer case let mut x = Bigint { data: from_u32(&[0x2, 0xFFFFFFFF]) }; let y = Bigint { data: from_u32(&[0xFFFFFFFE]) }; let rem = x.idiv_large(&y); assert_eq!(x.data, from_u32(&[1, 1])); assert_eq!(rem.data, from_u32(&[4])); // Larger large case let mut x = Bigint { data: from_u32(&[0xCCCCCCCF, 0x5CCCCCCC, 0x9997FFFF, 0x33319999, 0x999A7333, 0xD999]) }; let y = Bigint { data: from_u32(&[0x99999999, 0x99999999, 0xCCCD9999, 0xCCCC]) }; let rem = x.idiv_large(&y); assert_eq!(x.data, from_u32(&[0xFFFFFFFE, 0x0FFFFFFF, 1])); assert_eq!(rem.data, from_u32(&[1])); // Extremely large cases, examples from Karatsuba multiplication. let mut x = Bigint { data: from_u32(&[4, 13, 29, 50, 80, 119, 168, 228, 300, 385, 484, 598, 728, 875, 1040, 1224, 1340, 1435, 1508, 1558, 1584, 1585, 1560, 1508, 1428, 1319, 1180, 1010, 808, 573, 304]) }; let y = Bigint { data: from_u32(&[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) }; let rem = x.idiv_large(&y); assert_eq!(x.data, from_u32(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])); assert_eq!(rem.data, from_u32(&[0, 0, 1])); } #[test] fn quorem_test() { let mut x = Bigint::from_u128(42535295865117307932921825928971026432); let y = Bigint::from_u128(17218479456385750618067377696052635483); assert_eq!(x.quorem(&y), 2); assert_eq!(x.data, from_u32(&[1873752394, 3049207402, 3024501058, 102215382])); } } lexical-core-0.7.6/src/atof/algorithm/mod.rs000075500000000000000000000012250000000000000170200ustar 00000000000000//! Algorithms for parsing strings to floats. // Hide implementation details. #[macro_use] mod format; cfg_if! { if #[cfg(feature = "correct")] { mod bhcomp; mod bigcomp; mod alias; mod bignum; mod cached; mod cached_float80; mod cached_float160; mod errors; mod large_powers; mod math; mod small_powers; #[cfg(limb_width_32)] mod large_powers_32; #[cfg(limb_width_32)] mod small_powers_32; #[cfg(limb_width_64)] mod large_powers_64; // Required for fast-path, keep on all platforms. mod small_powers_64; }} // cfg_if // Export algorithms. #[cfg(feature = "correct")] pub(crate) mod correct; #[cfg(not(feature = "correct"))] pub(crate) mod incorrect; lexical-core-0.7.6/src/atof/algorithm/small_powers.rs000075500000000000000000000120360000000000000207520ustar 00000000000000//! Precalculated small powers. #[cfg(any(feature = "correct", feature = "format"))] use static_assertions::const_assert; use super::math::Limb; use super::small_powers_64; #[cfg(limb_width_32)] use super::small_powers_32::*; #[cfg(limb_width_64)] use super::small_powers_64::*; // ASSERTIONS const_assert!(POW5[1] / POW5[0] == 5); const_assert!(POW10[1] / POW10[0] == 10); cfg_if! { if #[cfg(feature = "radix")] { // Ensure our small powers are valid. const_assert!(POW2[1] / POW2[0] == 2); const_assert!(POW3[1] / POW3[0] == 3); const_assert!(POW4[1] / POW4[0] == 4); const_assert!(POW6[1] / POW6[0] == 6); const_assert!(POW7[1] / POW7[0] == 7); const_assert!(POW8[1] / POW8[0] == 8); const_assert!(POW9[1] / POW9[0] == 9); const_assert!(POW11[1] / POW11[0] == 11); const_assert!(POW12[1] / POW12[0] == 12); const_assert!(POW13[1] / POW13[0] == 13); const_assert!(POW14[1] / POW14[0] == 14); const_assert!(POW15[1] / POW15[0] == 15); const_assert!(POW16[1] / POW16[0] == 16); const_assert!(POW17[1] / POW17[0] == 17); const_assert!(POW18[1] / POW18[0] == 18); const_assert!(POW19[1] / POW19[0] == 19); const_assert!(POW20[1] / POW20[0] == 20); const_assert!(POW21[1] / POW21[0] == 21); const_assert!(POW22[1] / POW22[0] == 22); const_assert!(POW23[1] / POW23[0] == 23); const_assert!(POW24[1] / POW24[0] == 24); const_assert!(POW25[1] / POW25[0] == 25); const_assert!(POW26[1] / POW26[0] == 26); const_assert!(POW27[1] / POW27[0] == 27); const_assert!(POW28[1] / POW28[0] == 28); const_assert!(POW29[1] / POW29[0] == 29); const_assert!(POW30[1] / POW30[0] == 30); const_assert!(POW31[1] / POW31[0] == 31); const_assert!(POW32[1] / POW32[0] == 32); const_assert!(POW33[1] / POW33[0] == 33); const_assert!(POW34[1] / POW34[0] == 34); const_assert!(POW35[1] / POW35[0] == 35); const_assert!(POW36[1] / POW36[0] == 36); }} //cfg_if // HELPER /// Get the correct small power from the radix. pub(in crate::atof::algorithm) fn get_small_powers(radix: u32) -> &'static [Limb] { #[cfg(not(feature = "radix"))] { match radix { 5 => &POW5, 10 => &POW10, _ => unreachable!() } } #[cfg(feature = "radix")] { match radix { 2 => &POW2, 3 => &POW3, 4 => &POW4, 5 => &POW5, 6 => &POW6, 7 => &POW7, 8 => &POW8, 9 => &POW9, 10 => &POW10, 11 => &POW11, 12 => &POW12, 13 => &POW13, 14 => &POW14, 15 => &POW15, 16 => &POW16, 17 => &POW17, 18 => &POW18, 19 => &POW19, 20 => &POW20, 21 => &POW21, 22 => &POW22, 23 => &POW23, 24 => &POW24, 25 => &POW25, 26 => &POW26, 27 => &POW27, 28 => &POW28, 29 => &POW29, 30 => &POW30, 31 => &POW31, 32 => &POW32, 33 => &POW33, 34 => &POW34, 35 => &POW35, 36 => &POW36, _ => unreachable!(), } } } /// Get the correct 64-bit small power from the radix. pub(in crate::atof::algorithm) fn get_small_powers_64(radix: u32) -> &'static [u64] { #[cfg(not(feature = "radix"))] { match radix { 5 => &small_powers_64::POW5, 10 => &small_powers_64::POW10, _ => unreachable!() } } #[cfg(feature = "radix")] { match radix { 2 => &small_powers_64::POW2, 3 => &small_powers_64::POW3, 4 => &small_powers_64::POW4, 5 => &small_powers_64::POW5, 6 => &small_powers_64::POW6, 7 => &small_powers_64::POW7, 8 => &small_powers_64::POW8, 9 => &small_powers_64::POW9, 10 => &small_powers_64::POW10, 11 => &small_powers_64::POW11, 12 => &small_powers_64::POW12, 13 => &small_powers_64::POW13, 14 => &small_powers_64::POW14, 15 => &small_powers_64::POW15, 16 => &small_powers_64::POW16, 17 => &small_powers_64::POW17, 18 => &small_powers_64::POW18, 19 => &small_powers_64::POW19, 20 => &small_powers_64::POW20, 21 => &small_powers_64::POW21, 22 => &small_powers_64::POW22, 23 => &small_powers_64::POW23, 24 => &small_powers_64::POW24, 25 => &small_powers_64::POW25, 26 => &small_powers_64::POW26, 27 => &small_powers_64::POW27, 28 => &small_powers_64::POW28, 29 => &small_powers_64::POW29, 30 => &small_powers_64::POW30, 31 => &small_powers_64::POW31, 32 => &small_powers_64::POW32, 33 => &small_powers_64::POW33, 34 => &small_powers_64::POW34, 35 => &small_powers_64::POW35, 36 => &small_powers_64::POW36, _ => unreachable!(), } } } lexical-core-0.7.6/src/atof/algorithm/small_powers_32.rs000075500000000000000000000074640000000000000212670ustar 00000000000000//! Precalculated small powers for 32-bit limbs. // DECIMAL pub(super) const POW5: [u32; 14] = [1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125]; pub(super) const POW10: [u32; 10] = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000]; cfg_if! { if #[cfg(feature = "radix")] { // PRIME (EXCEPT 2) pub(super) const POW3: [u32; 21] = [1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721, 129140163, 387420489, 1162261467, 3486784401]; pub(super) const POW7: [u32; 12] = [1, 7, 49, 343, 2401, 16807, 117649, 823543, 5764801, 40353607, 282475249, 1977326743]; pub(super) const POW11: [u32; 10] = [1, 11, 121, 1331, 14641, 161051, 1771561, 19487171, 214358881, 2357947691]; pub(super) const POW13: [u32; 9] = [1, 13, 169, 2197, 28561, 371293, 4826809, 62748517, 815730721]; pub(super) const POW17: [u32; 8] = [1, 17, 289, 4913, 83521, 1419857, 24137569, 410338673]; pub(super) const POW19: [u32; 8] = [1, 19, 361, 6859, 130321, 2476099, 47045881, 893871739]; pub(super) const POW23: [u32; 8] = [1, 23, 529, 12167, 279841, 6436343, 148035889, 3404825447]; pub(super) const POW29: [u32; 7] = [1, 29, 841, 24389, 707281, 20511149, 594823321]; pub(super) const POW31: [u32; 7] = [1, 31, 961, 29791, 923521, 28629151, 887503681]; // NON-PRIME (AND 2) pub(super) const POW2: [u32; 32] = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648]; pub(super) const POW4: [u32; 16] = [1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864, 268435456, 1073741824]; pub(super) const POW6: [u32; 13] = [1, 6, 36, 216, 1296, 7776, 46656, 279936, 1679616, 10077696, 60466176, 362797056, 2176782336]; pub(super) const POW8: [u32; 11] = [1, 8, 64, 512, 4096, 32768, 262144, 2097152, 16777216, 134217728, 1073741824]; pub(super) const POW9: [u32; 11] = [1, 9, 81, 729, 6561, 59049, 531441, 4782969, 43046721, 387420489, 3486784401]; pub(super) const POW12: [u32; 9] = [1, 12, 144, 1728, 20736, 248832, 2985984, 35831808, 429981696]; pub(super) const POW14: [u32; 9] = [1, 14, 196, 2744, 38416, 537824, 7529536, 105413504, 1475789056]; pub(super) const POW15: [u32; 9] = [1, 15, 225, 3375, 50625, 759375, 11390625, 170859375, 2562890625]; pub(super) const POW16: [u32; 8] = [1, 16, 256, 4096, 65536, 1048576, 16777216, 268435456]; pub(super) const POW18: [u32; 8] = [1, 18, 324, 5832, 104976, 1889568, 34012224, 612220032]; pub(super) const POW20: [u32; 8] = [1, 20, 400, 8000, 160000, 3200000, 64000000, 1280000000]; pub(super) const POW21: [u32; 8] = [1, 21, 441, 9261, 194481, 4084101, 85766121, 1801088541]; pub(super) const POW22: [u32; 8] = [1, 22, 484, 10648, 234256, 5153632, 113379904, 2494357888]; pub(super) const POW24: [u32; 7] = [1, 24, 576, 13824, 331776, 7962624, 191102976]; pub(super) const POW25: [u32; 7] = [1, 25, 625, 15625, 390625, 9765625, 244140625]; pub(super) const POW26: [u32; 7] = [1, 26, 676, 17576, 456976, 11881376, 308915776]; pub(super) const POW27: [u32; 7] = [1, 27, 729, 19683, 531441, 14348907, 387420489]; pub(super) const POW28: [u32; 7] = [1, 28, 784, 21952, 614656, 17210368, 481890304]; pub(super) const POW30: [u32; 7] = [1, 30, 900, 27000, 810000, 24300000, 729000000]; pub(super) const POW32: [u32; 7] = [1, 32, 1024, 32768, 1048576, 33554432, 1073741824]; pub(super) const POW33: [u32; 7] = [1, 33, 1089, 35937, 1185921, 39135393, 1291467969]; pub(super) const POW34: [u32; 7] = [1, 34, 1156, 39304, 1336336, 45435424, 1544804416]; pub(super) const POW35: [u32; 7] = [1, 35, 1225, 42875, 1500625, 52521875, 1838265625]; pub(super) const POW36: [u32; 7] = [1, 36, 1296, 46656, 1679616, 60466176, 2176782336]; }} // cfg_if lexical-core-0.7.6/src/atof/algorithm/small_powers_64.rs000075500000000000000000000222640000000000000212670ustar 00000000000000//! Precalculated small powers for 64-bit limbs. // DECIMAL pub(super) const POW5: [u64; 28] = [1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125, 6103515625, 30517578125, 152587890625, 762939453125, 3814697265625, 19073486328125, 95367431640625, 476837158203125, 2384185791015625, 11920928955078125, 59604644775390625, 298023223876953125, 1490116119384765625, 7450580596923828125]; pub(super) const POW10: [u64; 20] = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000, 10000000000000000000]; cfg_if! { if #[cfg(feature = "radix")] { // PRIME (EXCEPT 2) pub(super) const POW3: [u64; 41] = [1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721, 129140163, 387420489, 1162261467, 3486784401, 10460353203, 31381059609, 94143178827, 282429536481, 847288609443, 2541865828329, 7625597484987, 22876792454961, 68630377364883, 205891132094649, 617673396283947, 1853020188851841, 5559060566555523, 16677181699666569, 50031545098999707, 150094635296999121, 450283905890997363, 1350851717672992089, 4052555153018976267, 12157665459056928801]; pub(super) const POW7: [u64; 23] = [1, 7, 49, 343, 2401, 16807, 117649, 823543, 5764801, 40353607, 282475249, 1977326743, 13841287201, 96889010407, 678223072849, 4747561509943, 33232930569601, 232630513987207, 1628413597910449, 11398895185373143, 79792266297612001, 558545864083284007, 3909821048582988049]; pub(super) const POW11: [u64; 19] = [1, 11, 121, 1331, 14641, 161051, 1771561, 19487171, 214358881, 2357947691, 25937424601, 285311670611, 3138428376721, 34522712143931, 379749833583241, 4177248169415651, 45949729863572161, 505447028499293771, 5559917313492231481]; pub(super) const POW13: [u64; 18] = [1, 13, 169, 2197, 28561, 371293, 4826809, 62748517, 815730721, 10604499373, 137858491849, 1792160394037, 23298085122481, 302875106592253, 3937376385699289, 51185893014090757, 665416609183179841, 8650415919381337933]; pub(super) const POW17: [u64; 16] = [1, 17, 289, 4913, 83521, 1419857, 24137569, 410338673, 6975757441, 118587876497, 2015993900449, 34271896307633, 582622237229761, 9904578032905937, 168377826559400929, 2862423051509815793]; pub(super) const POW19: [u64; 16] = [1, 19, 361, 6859, 130321, 2476099, 47045881, 893871739, 16983563041, 322687697779, 6131066257801, 116490258898219, 2213314919066161, 42052983462257059, 799006685782884121, 15181127029874798299]; pub(super) const POW23: [u64; 15] = [1, 23, 529, 12167, 279841, 6436343, 148035889, 3404825447, 78310985281, 1801152661463, 41426511213649, 952809757913927, 21914624432020321, 504036361936467383, 11592836324538749809]; pub(super) const POW29: [u64; 14] = [1, 29, 841, 24389, 707281, 20511149, 594823321, 17249876309, 500246412961, 14507145975869, 420707233300201, 12200509765705829, 353814783205469041, 10260628712958602189]; pub(super) const POW31: [u64; 13] = [1, 31, 961, 29791, 923521, 28629151, 887503681, 27512614111, 852891037441, 26439622160671, 819628286980801, 25408476896404831, 787662783788549761]; // NON-PRIME (AND 2) pub(super) const POW2: [u64; 64] = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648, 4294967296, 8589934592, 17179869184, 34359738368, 68719476736, 137438953472, 274877906944, 549755813888, 1099511627776, 2199023255552, 4398046511104, 8796093022208, 17592186044416, 35184372088832, 70368744177664, 140737488355328, 281474976710656, 562949953421312, 1125899906842624, 2251799813685248, 4503599627370496, 9007199254740992, 18014398509481984, 36028797018963968, 72057594037927936, 144115188075855872, 288230376151711744, 576460752303423488, 1152921504606846976, 2305843009213693952, 4611686018427387904, 9223372036854775808]; pub(super) const POW4: [u64; 32] = [1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864, 268435456, 1073741824, 4294967296, 17179869184, 68719476736, 274877906944, 1099511627776, 4398046511104, 17592186044416, 70368744177664, 281474976710656, 1125899906842624, 4503599627370496, 18014398509481984, 72057594037927936, 288230376151711744, 1152921504606846976, 4611686018427387904]; pub(super) const POW6: [u64; 25] = [1, 6, 36, 216, 1296, 7776, 46656, 279936, 1679616, 10077696, 60466176, 362797056, 2176782336, 13060694016, 78364164096, 470184984576, 2821109907456, 16926659444736, 101559956668416, 609359740010496, 3656158440062976, 21936950640377856, 131621703842267136, 789730223053602816, 4738381338321616896]; pub(super) const POW8: [u64; 22] = [1, 8, 64, 512, 4096, 32768, 262144, 2097152, 16777216, 134217728, 1073741824, 8589934592, 68719476736, 549755813888, 4398046511104, 35184372088832, 281474976710656, 2251799813685248, 18014398509481984, 144115188075855872, 1152921504606846976, 9223372036854775808]; pub(super) const POW9: [u64; 21] = [1, 9, 81, 729, 6561, 59049, 531441, 4782969, 43046721, 387420489, 3486784401, 31381059609, 282429536481, 2541865828329, 22876792454961, 205891132094649, 1853020188851841, 16677181699666569, 150094635296999121, 1350851717672992089, 12157665459056928801]; pub(super) const POW12: [u64; 18] = [1, 12, 144, 1728, 20736, 248832, 2985984, 35831808, 429981696, 5159780352, 61917364224, 743008370688, 8916100448256, 106993205379072, 1283918464548864, 15407021574586368, 184884258895036416, 2218611106740436992]; pub(super) const POW14: [u64; 17] = [1, 14, 196, 2744, 38416, 537824, 7529536, 105413504, 1475789056, 20661046784, 289254654976, 4049565169664, 56693912375296, 793714773254144, 11112006825558016, 155568095557812224, 2177953337809371136]; pub(super) const POW15: [u64; 17] = [1, 15, 225, 3375, 50625, 759375, 11390625, 170859375, 2562890625, 38443359375, 576650390625, 8649755859375, 129746337890625, 1946195068359375, 29192926025390625, 437893890380859375, 6568408355712890625]; pub(super) const POW16: [u64; 16] = [1, 16, 256, 4096, 65536, 1048576, 16777216, 268435456, 4294967296, 68719476736, 1099511627776, 17592186044416, 281474976710656, 4503599627370496, 72057594037927936, 1152921504606846976]; pub(super) const POW18: [u64; 16] = [1, 18, 324, 5832, 104976, 1889568, 34012224, 612220032, 11019960576, 198359290368, 3570467226624, 64268410079232, 1156831381426176, 20822964865671168, 374813367582081024, 6746640616477458432]; pub(super) const POW20: [u64; 15] = [1, 20, 400, 8000, 160000, 3200000, 64000000, 1280000000, 25600000000, 512000000000, 10240000000000, 204800000000000, 4096000000000000, 81920000000000000, 1638400000000000000]; pub(super) const POW21: [u64; 15] = [1, 21, 441, 9261, 194481, 4084101, 85766121, 1801088541, 37822859361, 794280046581, 16679880978201, 350277500542221, 7355827511386641, 154472377739119461, 3243919932521508681]; pub(super) const POW22: [u64; 15] = [1, 22, 484, 10648, 234256, 5153632, 113379904, 2494357888, 54875873536, 1207269217792, 26559922791424, 584318301411328, 12855002631049216, 282810057883082752, 6221821273427820544]; pub(super) const POW24: [u64; 14] = [1, 24, 576, 13824, 331776, 7962624, 191102976, 4586471424, 110075314176, 2641807540224, 63403380965376, 1521681143169024, 36520347436056576, 876488338465357824]; pub(super) const POW25: [u64; 14] = [1, 25, 625, 15625, 390625, 9765625, 244140625, 6103515625, 152587890625, 3814697265625, 95367431640625, 2384185791015625, 59604644775390625, 1490116119384765625]; pub(super) const POW26: [u64; 14] = [1, 26, 676, 17576, 456976, 11881376, 308915776, 8031810176, 208827064576, 5429503678976, 141167095653376, 3670344486987776, 95428956661682176, 2481152873203736576]; pub(super) const POW27: [u64; 14] = [1, 27, 729, 19683, 531441, 14348907, 387420489, 10460353203, 282429536481, 7625597484987, 205891132094649, 5559060566555523, 150094635296999121, 4052555153018976267]; pub(super) const POW28: [u64; 14] = [1, 28, 784, 21952, 614656, 17210368, 481890304, 13492928512, 377801998336, 10578455953408, 296196766695424, 8293509467471872, 232218265089212416, 6502111422497947648]; pub(super) const POW30: [u64; 14] = [1, 30, 900, 27000, 810000, 24300000, 729000000, 21870000000, 656100000000, 19683000000000, 590490000000000, 17714700000000000, 531441000000000000, 15943230000000000000]; pub(super) const POW32: [u64; 13] = [1, 32, 1024, 32768, 1048576, 33554432, 1073741824, 34359738368, 1099511627776, 35184372088832, 1125899906842624, 36028797018963968, 1152921504606846976]; pub(super) const POW33: [u64; 13] = [1, 33, 1089, 35937, 1185921, 39135393, 1291467969, 42618442977, 1406408618241, 46411484401953, 1531578985264449, 50542106513726817, 1667889514952984961]; pub(super) const POW34: [u64; 13] = [1, 34, 1156, 39304, 1336336, 45435424, 1544804416, 52523350144, 1785793904896, 60716992766464, 2064377754059776, 70188843638032384, 2386420683693101056]; pub(super) const POW35: [u64; 13] = [1, 35, 1225, 42875, 1500625, 52521875, 1838265625, 64339296875, 2251875390625, 78815638671875, 2758547353515625, 96549157373046875, 3379220508056640625]; pub(super) const POW36: [u64; 13] = [1, 36, 1296, 46656, 1679616, 60466176, 2176782336, 78364164096, 2821109907456, 101559956668416, 3656158440062976, 131621703842267136, 4738381338321616896]; }} //cfg_if lexical-core-0.7.6/src/atof/api.rs000075500000000000000000001371470000000000000150410ustar 00000000000000//! Low-level API generator. //! //! Uses either the imprecise or the precise algorithm. use crate::lib::slice; use crate::util::*; // Select the back-end cfg_if! { if #[cfg(feature = "correct")] { use super::algorithm::correct as algorithm; } else { use super::algorithm::incorrect as algorithm; }} // cfg_if // TRAITS /// Trait to define parsing of a string to float. trait StringToFloat: Float { /// Serialize string to float, favoring correctness. fn default(bytes: &[u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(Self, *const u8)>; } impl StringToFloat for f32 { perftools_inline_always!{ fn default(bytes: &[u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(f32, *const u8)> { algorithm::atof(bytes, radix, lossy, sign, format) }} } impl StringToFloat for f64 { perftools_inline_always!{ fn default(bytes: &[u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(f64, *const u8)> { algorithm::atod(bytes, radix, lossy, sign, format) }} } // SPECIAL // Utilities to filter special values. // Convert slice to iterator without digit separators. perftools_inline!{ fn to_iter<'a>(bytes: &'a [u8], _: u8) -> slice::Iter<'a, u8> { bytes.iter() }} // Convert slice to iterator with digit separators. perftools_inline!{ #[cfg(feature = "format")] fn to_iter_s<'a>(bytes: &'a [u8], digit_separator: u8) -> SkipValueIterator<'a, u8> { SkipValueIterator::new(bytes, digit_separator) }} // PARSER // Parse infinity from string. perftools_inline!{ fn parse_infinity<'a, ToIter, StartsWith, Iter, F>( bytes: &'a [u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat, to_iter: ToIter, starts_with: StartsWith ) -> ParseResult<(F, *const u8)> where F: StringToFloat, ToIter: Fn(&'a [u8], u8) -> Iter, Iter: AsPtrIterator<'a, u8>, StartsWith: Fn(Iter, slice::Iter<'a, u8>) -> (bool, Iter) { let infinity = get_infinity_string(); let inf = get_inf_string(); if let (true, iter) = starts_with(to_iter(bytes, format.digit_separator()), infinity.iter()) { Ok((F::INFINITY, iter.as_ptr())) } else if let (true, iter) = starts_with(to_iter(bytes, format.digit_separator()), inf.iter()) { Ok((F::INFINITY, iter.as_ptr())) } else { // Not infinity, may be valid with a different radix. if cfg!(feature = "radix"){ F::default(bytes, radix, lossy, sign, format) } else { Err((ErrorCode::InvalidDigit, bytes.as_ptr())) } } }} // Parse NaN from string. perftools_inline!{ fn parse_nan<'a, ToIter, StartsWith, Iter, F>( bytes: &'a [u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat, to_iter: ToIter, starts_with: StartsWith ) -> ParseResult<(F, *const u8)> where F: StringToFloat, ToIter: Fn(&'a [u8], u8) -> Iter, Iter: AsPtrIterator<'a, u8>, StartsWith: Fn(Iter, slice::Iter<'a, u8>) -> (bool, Iter) { let nan = get_nan_string(); if let (true, iter) = starts_with(to_iter(bytes, format.digit_separator()), nan.iter()) { Ok((F::NAN, iter.as_ptr())) } else { // Not NaN, may be valid with a different radix. if cfg!(feature = "radix"){ F::default(bytes, radix, lossy, sign, format) } else { Err((ErrorCode::InvalidDigit, bytes.as_ptr())) } } }} // ATOF/ATOD // Parse special or float values with the standard format. // Special values are allowed, the match is case-insensitive, // and no digit separators are allowed. perftools_inline!{ fn parse_float_standard(bytes: &[u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(F, *const u8)> { // Use predictive parsing to filter special cases. This leads to // dramatic performance gains. let starts_with = case_insensitive_starts_with_iter; match index!(bytes[0]) { b'i' | b'I' => parse_infinity(bytes, radix, lossy, sign, format, to_iter, starts_with), b'N' | b'n' => parse_nan(bytes, radix, lossy, sign, format, to_iter, starts_with), _ => F::default(bytes, radix, lossy, sign, format), } }} // Parse special or float values. // Special values are allowed, the match is case-sensitive, // and digit separators are allowed. perftools_inline!{ #[cfg(feature = "format")] fn parse_float_cs(bytes: &[u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(F, *const u8)> { let digit_separator = format.digit_separator(); let starts_with = starts_with_iter; match SkipValueIterator::new(bytes, digit_separator).next() { Some(&b'i') | Some(&b'I') => parse_infinity(bytes, radix, lossy, sign, format, to_iter_s, starts_with), Some(&b'n') | Some(&b'N') => parse_nan(bytes, radix, lossy, sign, format, to_iter_s, starts_with), _ => F::default(bytes, radix, lossy, sign, format), } }} // Parse special or float values. // Special values are allowed, the match is case-sensitive, // and no digit separators are allowed. perftools_inline!{ #[cfg(feature = "format")] fn parse_float_c(bytes: &[u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(F, *const u8)> { // Use predictive parsing to filter special cases. This leads to // dramatic performance gains. let starts_with = starts_with_iter; match index!(bytes[0]) { b'i' | b'I' => parse_infinity(bytes, radix, lossy, sign, format, to_iter, starts_with), b'N' | b'n' => parse_nan(bytes, radix, lossy, sign, format, to_iter, starts_with), _ => F::default(bytes, radix, lossy, sign, format), } }} // Parse special or float values. // Special values are allowed, the match is case-insensitive, // and digit separators are allowed. perftools_inline!{ #[cfg(feature = "format")] fn parse_float_s(bytes: &[u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(F, *const u8)> { let digit_separator = format.digit_separator(); let starts_with = case_insensitive_starts_with_iter; match SkipValueIterator::new(bytes, digit_separator).next() { Some(&b'i') | Some(&b'I') => parse_infinity(bytes, radix, lossy, sign, format, to_iter_s, starts_with), Some(&b'n') | Some(&b'N') => parse_nan(bytes, radix, lossy, sign, format, to_iter_s, starts_with), _ => F::default(bytes, radix, lossy, sign, format), } }} // Parse special or float values with the default formatter. perftools_inline!{ #[cfg(not(feature = "format"))] fn parse_float(bytes: &[u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(F, *const u8)> { parse_float_standard(bytes, radix, lossy, sign, format) }} // Parse special or float values with the default formatter. perftools_inline!{ #[cfg(feature = "format")] fn parse_float(bytes: &[u8], radix: u32, lossy: bool, sign: Sign, format: NumberFormat) -> ParseResult<(F, *const u8)> { // Need to consider 3 possibilities: // 1). No special values are allowed. // 2). Special values are case-sensitive. // 3). Digit separators are allowed in the special. let no_special = format.no_special(); let case = format.case_sensitive_special(); let has_sep = format.special_digit_separator(); match (no_special, case, has_sep) { (true, _, _) => F::default(bytes, radix, lossy, sign, format), (false, true, true) => parse_float_cs(bytes, radix, lossy, sign, format), (false, false, true) => parse_float_s(bytes, radix, lossy, sign, format), (false, true, false) => parse_float_c(bytes, radix, lossy, sign, format), (false, false, false) => parse_float_standard(bytes, radix, lossy, sign, format), } }} // Validate sign byte is valid. perftools_inline!{ #[cfg(not(feature = "format"))] fn validate_sign(_: &[u8], _: &[u8], _: Sign, _: NumberFormat) -> ParseResult<()> { Ok(()) }} // Validate sign byte is valid. perftools_inline!{ #[cfg(feature = "format")] fn validate_sign(bytes: &[u8], digits: &[u8], sign: Sign, format: NumberFormat) -> ParseResult<()> { let has_sign = bytes.as_ptr() != digits.as_ptr(); if format.no_positive_mantissa_sign() && has_sign && sign == Sign::Positive { Err((ErrorCode::InvalidPositiveMantissaSign, bytes.as_ptr())) } else if format.required_mantissa_sign() && !has_sign { Err((ErrorCode::MissingMantissaSign, bytes.as_ptr())) } else { Ok(()) } }} // Convert float to signed representation. perftools_inline!{ fn to_signed(float: F, sign: Sign) -> F { match sign { Sign::Positive => float, Sign::Negative => -float } }} // Standalone atof processor. perftools_inline!{ fn atof(bytes: &[u8], radix: u32, lossy: bool, format: NumberFormat) -> ParseResult<(F, *const u8)> { let (sign, digits) = parse_sign::(bytes, format); if digits.is_empty() { return Err((ErrorCode::Empty, digits.as_ptr())); } let (float, ptr): (F, *const u8) = parse_float(digits, radix, lossy, sign, format)?; validate_sign(bytes, digits, sign, format)?; Ok((to_signed(float, sign), ptr)) }} perftools_inline!{ fn atof_lossy(bytes: &[u8], radix: u32) -> Result<(F, usize)> { let index = | ptr | distance(bytes.as_ptr(), ptr); match atof::(bytes, radix, true, NumberFormat::standard().unwrap()) { Ok((value, ptr)) => Ok((value, index(ptr))), Err((code, ptr)) => Err((code, index(ptr)).into()), } }} perftools_inline!{ fn atof_nonlossy(bytes: &[u8], radix: u32) -> Result<(F, usize)> { let index = | ptr | distance(bytes.as_ptr(), ptr); match atof::(bytes, radix, false, NumberFormat::standard().unwrap()) { Ok((value, ptr)) => Ok((value, index(ptr))), Err((code, ptr)) => Err((code, index(ptr)).into()), } }} perftools_inline!{ #[cfg(feature = "format")] fn atof_format(bytes: &[u8], radix: u32, format: NumberFormat) -> Result<(F, usize)> { let index = | ptr | distance(bytes.as_ptr(), ptr); match atof::(bytes, radix, false, format) { Ok((value, ptr)) => Ok((value, index(ptr))), Err((code, ptr)) => Err((code, index(ptr)).into()), } }} perftools_inline!{ #[cfg(feature = "format")] fn atof_lossy_format(bytes: &[u8], radix: u32, format: NumberFormat) -> Result<(F, usize)> { let index = | ptr | distance(bytes.as_ptr(), ptr); match atof::(bytes, radix, true, format) { Ok((value, ptr)) => Ok((value, index(ptr))), Err((code, ptr)) => Err((code, index(ptr)).into()), } }} // FROM LEXICAL // ------------ from_lexical!(atof_nonlossy, f32); from_lexical!(atof_nonlossy, f64); from_lexical_lossy!(atof_lossy, f32); from_lexical_lossy!(atof_lossy, f64); cfg_if!{ if #[cfg(feature = "format")] { from_lexical_format!(atof_format, f32); from_lexical_format!(atof_format, f64); from_lexical_lossy_format!(atof_lossy_format, f32); from_lexical_lossy_format!(atof_lossy_format, f64); }} // TESTS // ----- #[cfg(test)] mod tests { use crate::util::*; use approx::assert_relative_eq; #[cfg(all(feature = "std", feature = "property_tests"))] use proptest::{proptest, prop_assert_eq, prop_assert}; #[test] fn f32_decimal_test() { // integer test assert_f32_eq!(0.0, f32::from_lexical(b"0").unwrap()); assert_f32_eq!(1.0, f32::from_lexical(b"1").unwrap()); assert_f32_eq!(12.0, f32::from_lexical(b"12").unwrap()); assert_f32_eq!(123.0, f32::from_lexical(b"123").unwrap()); assert_f32_eq!(1234.0, f32::from_lexical(b"1234").unwrap()); assert_f32_eq!(12345.0, f32::from_lexical(b"12345").unwrap()); assert_f32_eq!(123456.0, f32::from_lexical(b"123456").unwrap()); assert_f32_eq!(1234567.0, f32::from_lexical(b"1234567").unwrap()); assert_f32_eq!(12345678.0, f32::from_lexical(b"12345678").unwrap()); // No fraction after decimal point test assert_f32_eq!(1.0, f32::from_lexical(b"1.").unwrap()); assert_f32_eq!(12.0, f32::from_lexical(b"12.").unwrap()); assert_f32_eq!(1234567.0, f32::from_lexical(b"1234567.").unwrap()); // No integer before decimal point test assert_f32_eq!(0.1, f32::from_lexical(b".1").unwrap()); assert_f32_eq!(0.12, f32::from_lexical(b".12").unwrap()); assert_f32_eq!(0.1234567, f32::from_lexical(b".1234567").unwrap()); // decimal test assert_f32_eq!(123.1, f32::from_lexical(b"123.1").unwrap()); assert_f32_eq!(123.12, f32::from_lexical(b"123.12").unwrap()); assert_f32_eq!(123.123, f32::from_lexical(b"123.123").unwrap()); assert_f32_eq!(123.1234, f32::from_lexical(b"123.1234").unwrap()); assert_f32_eq!(123.12345, f32::from_lexical(b"123.12345").unwrap()); // rounding test assert_f32_eq!(123456790.0, f32::from_lexical(b"123456789").unwrap()); assert_f32_eq!(123456790.0, f32::from_lexical(b"123456789.1").unwrap()); assert_f32_eq!(123456790.0, f32::from_lexical(b"123456789.12").unwrap()); assert_f32_eq!(123456790.0, f32::from_lexical(b"123456789.123").unwrap()); assert_f32_eq!(123456790.0, f32::from_lexical(b"123456789.1234").unwrap()); assert_f32_eq!(123456790.0, f32::from_lexical(b"123456789.12345").unwrap()); // exponent test assert_f32_eq!(123456789.12345, f32::from_lexical(b"1.2345678912345e8").unwrap()); assert_f32_eq!(123450000.0, f32::from_lexical(b"1.2345e+8").unwrap()); assert_f32_eq!(1.2345e+11, f32::from_lexical(b"1.2345e+11").unwrap()); assert_f32_eq!(1.2345e+11, f32::from_lexical(b"123450000000").unwrap()); assert_f32_eq!(1.2345e+38, f32::from_lexical(b"1.2345e+38").unwrap()); assert_f32_eq!(1.2345e+38, f32::from_lexical(b"123450000000000000000000000000000000000").unwrap()); assert_f32_eq!(1.2345e-8, f32::from_lexical(b"1.2345e-8").unwrap()); assert_f32_eq!(1.2345e-8, f32::from_lexical(b"0.000000012345").unwrap()); assert_f32_eq!(1.2345e-38, f32::from_lexical(b"1.2345e-38").unwrap()); assert_f32_eq!(1.2345e-38, f32::from_lexical(b"0.000000000000000000000000000000000000012345").unwrap()); assert!(f32::from_lexical(b"NaN").unwrap().is_nan()); assert!(f32::from_lexical(b"nan").unwrap().is_nan()); assert!(f32::from_lexical(b"NAN").unwrap().is_nan()); assert!(f32::from_lexical(b"inf").unwrap().is_infinite()); assert!(f32::from_lexical(b"INF").unwrap().is_infinite()); assert!(f32::from_lexical(b"+inf").unwrap().is_infinite()); assert!(f32::from_lexical(b"-inf").unwrap().is_infinite()); // Check various expected failures. assert_eq!(Err(ErrorCode::Empty.into()), f32::from_lexical(b"")); assert_eq!(Err((ErrorCode::EmptyMantissa, 0).into()), f32::from_lexical(b"e")); assert_eq!(Err((ErrorCode::EmptyMantissa, 0).into()), f32::from_lexical(b"E")); assert_eq!(Err(ErrorCode::EmptyMantissa.into()), f32::from_lexical(b".e1")); assert_eq!(Err(ErrorCode::EmptyMantissa.into()), f32::from_lexical(b".e-1")); assert_eq!(Err((ErrorCode::EmptyMantissa, 0).into()), f32::from_lexical(b"e1")); assert_eq!(Err((ErrorCode::EmptyMantissa, 0).into()), f32::from_lexical(b"e-1")); assert_eq!(Err((ErrorCode::Empty, 1).into()), f32::from_lexical(b"+")); assert_eq!(Err((ErrorCode::Empty, 1).into()), f32::from_lexical(b"-")); // Bug fix for Issue #8 assert_eq!(Ok(5.002868148396374), f32::from_lexical(b"5.002868148396374")); } #[cfg(feature = "radix")] #[test] fn f32_radix_test() { assert_f32_eq!(1234.0, f32::from_lexical_radix(b"YA", 36).unwrap()); assert_f32_eq!(1234.0, f32::from_lexical_lossy_radix(b"YA", 36).unwrap()); } #[test] fn f64_decimal_test() { // integer test assert_f64_eq!(0.0, f64::from_lexical(b"0").unwrap()); assert_f64_eq!(1.0, f64::from_lexical(b"1").unwrap()); assert_f64_eq!(12.0, f64::from_lexical(b"12").unwrap()); assert_f64_eq!(123.0, f64::from_lexical(b"123").unwrap()); assert_f64_eq!(1234.0, f64::from_lexical(b"1234").unwrap()); assert_f64_eq!(12345.0, f64::from_lexical(b"12345").unwrap()); assert_f64_eq!(123456.0, f64::from_lexical(b"123456").unwrap()); assert_f64_eq!(1234567.0, f64::from_lexical(b"1234567").unwrap()); assert_f64_eq!(12345678.0, f64::from_lexical(b"12345678").unwrap()); // No fraction after decimal point test assert_f64_eq!(1.0, f64::from_lexical(b"1.").unwrap()); assert_f64_eq!(12.0, f64::from_lexical(b"12.").unwrap()); assert_f64_eq!(1234567.0, f64::from_lexical(b"1234567.").unwrap()); // No integer before decimal point test assert_f64_eq!(0.1, f64::from_lexical(b".1").unwrap()); assert_f64_eq!(0.12, f64::from_lexical(b".12").unwrap()); assert_f64_eq!(0.1234567, f64::from_lexical(b".1234567").unwrap()); // decimal test assert_f64_eq!(123456789.0, f64::from_lexical(b"123456789").unwrap()); assert_f64_eq!(123456789.1, f64::from_lexical(b"123456789.1").unwrap()); assert_f64_eq!(123456789.12, f64::from_lexical(b"123456789.12").unwrap()); assert_f64_eq!(123456789.123, f64::from_lexical(b"123456789.123").unwrap()); assert_f64_eq!(123456789.1234, f64::from_lexical(b"123456789.1234").unwrap()); assert_f64_eq!(123456789.12345, f64::from_lexical(b"123456789.12345").unwrap()); assert_f64_eq!(123456789.123456, f64::from_lexical(b"123456789.123456").unwrap()); assert_f64_eq!(123456789.1234567, f64::from_lexical(b"123456789.1234567").unwrap()); assert_f64_eq!(123456789.12345678, f64::from_lexical(b"123456789.12345678").unwrap()); // rounding test assert_f64_eq!(123456789.12345679, f64::from_lexical(b"123456789.123456789").unwrap()); assert_f64_eq!(123456789.12345679, f64::from_lexical(b"123456789.1234567890").unwrap()); assert_f64_eq!(123456789.12345679, f64::from_lexical(b"123456789.123456789012").unwrap()); assert_f64_eq!(123456789.12345679, f64::from_lexical(b"123456789.1234567890123").unwrap()); assert_f64_eq!(123456789.12345679, f64::from_lexical(b"123456789.12345678901234").unwrap()); // exponent test assert_f64_eq!(123456789.12345, f64::from_lexical(b"1.2345678912345e8").unwrap()); assert_f64_eq!(123450000.0, f64::from_lexical(b"1.2345e+8").unwrap()); assert_f64_eq!(1.2345e+11, f64::from_lexical(b"123450000000").unwrap()); assert_f64_eq!(1.2345e+11, f64::from_lexical(b"1.2345e+11").unwrap()); assert_f64_eq!(1.2345e+38, f64::from_lexical(b"1.2345e+38").unwrap()); assert_f64_eq!(1.2345e+38, f64::from_lexical(b"123450000000000000000000000000000000000").unwrap()); assert_f64_eq!(1.2345e+308, f64::from_lexical(b"1.2345e+308").unwrap()); assert_f64_eq!(1.2345e+308, f64::from_lexical(b"123450000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()); assert_f64_eq!(0.000000012345, f64::from_lexical(b"1.2345e-8").unwrap()); assert_f64_eq!(1.2345e-8, f64::from_lexical(b"0.000000012345").unwrap()); assert_f64_eq!(1.2345e-38, f64::from_lexical(b"1.2345e-38").unwrap()); assert_f64_eq!(1.2345e-38, f64::from_lexical(b"0.000000000000000000000000000000000000012345").unwrap()); // denormalized (try extremely low values) assert_f64_eq!(1.2345e-308, f64::from_lexical(b"1.2345e-308").unwrap()); // These next 3 tests fail on arm-unknown-linux-gnueabi with the // incorrect parser. #[cfg(all(not(feature = "correct"), not(target_arch = "arm")))] assert_eq!(Ok(5e-322), f64::from_lexical(b"5e-322")); #[cfg(all(not(feature = "correct"), not(target_arch = "arm")))] assert_eq!(Ok(5e-323), f64::from_lexical(b"5e-323")); #[cfg(all(not(feature = "correct"), not(target_arch = "arm")))] assert_eq!(Ok(5e-324), f64::from_lexical(b"5e-324")); // due to issues in how the data is parsed, manually extracting // non-exponents of 1. ParseResult<(Self, *const u8)>; // Parse integer from string with format. #[cfg(feature = "format")] fn atoi_format(bytes: &[u8], radix: u32, format: NumberFormat) -> ParseResult<(Self, *const u8)>; } // Implement atoi for type. macro_rules! atoi_impl { ($($t:ty)*) => ($( impl Atoi for $t { perftools_inline_always!{ fn atoi(bytes: &[u8], radix: u32) -> ParseResult<($t, *const u8)> { standalone_no_separator(bytes, radix) }} perftools_inline_always!{ #[cfg(feature = "format")] fn atoi_format(bytes: &[u8], radix: u32, format: NumberFormat) -> ParseResult<($t, *const u8)> { standalone_separator(bytes, radix, format) }} } )*); } atoi_impl! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } impl Atoi for u128 { perftools_inline_always!{ fn atoi(bytes: &[u8], radix: u32) -> ParseResult<(u128, *const u8)> { standalone_128_no_separator::(bytes, radix) }} perftools_inline_always!{ #[cfg(feature = "format")] fn atoi_format(bytes: &[u8], radix: u32, format: NumberFormat) -> ParseResult<(u128, *const u8)> { standalone_128_separator::(bytes, radix, format) }} } impl Atoi for i128 { perftools_inline_always!{ fn atoi(bytes: &[u8], radix: u32) -> ParseResult<(i128, *const u8)> { standalone_128_no_separator::(bytes, radix) }} perftools_inline_always!{ #[cfg(feature = "format")] fn atoi_format(bytes: &[u8], radix: u32, format: NumberFormat) -> ParseResult<(i128, *const u8)> { standalone_128_separator::(bytes, radix, format) }} } // ATOI // ---- perftools_inline!{ pub(crate) fn atoi<'a, T>(bytes: &'a [u8], radix: u32) -> Result<(T, usize)> where T: Atoi { let index = | ptr | distance(bytes.as_ptr(), ptr); match T::atoi(bytes, radix) { Ok((value, ptr)) => Ok((value, index(ptr))), Err((code, ptr)) => Err((code, index(ptr)).into()), } }} perftools_inline!{ #[cfg(feature = "format")] pub(crate) fn atoi_format<'a, T>(bytes: &'a [u8], radix: u32, format: NumberFormat) -> Result<(T, usize)> where T: Atoi { let index = | ptr | distance(bytes.as_ptr(), ptr); match T::atoi_format(bytes, radix, format) { Ok((value, ptr)) => Ok((value, index(ptr))), Err((code, ptr)) => Err((code, index(ptr)).into()), } }} // FROM LEXICAL // ------------ from_lexical!(atoi, u8); from_lexical!(atoi, u16); from_lexical!(atoi, u32); from_lexical!(atoi, u64); from_lexical!(atoi, usize); from_lexical!(atoi, u128); from_lexical!(atoi, i8); from_lexical!(atoi, i16); from_lexical!(atoi, i32); from_lexical!(atoi, i64); from_lexical!(atoi, isize); from_lexical!(atoi, i128); cfg_if!{ if #[cfg(feature = "format")] { from_lexical_format!(atoi_format, u8); from_lexical_format!(atoi_format, u16); from_lexical_format!(atoi_format, u32); from_lexical_format!(atoi_format, u64); from_lexical_format!(atoi_format, usize); from_lexical_format!(atoi_format, u128); from_lexical_format!(atoi_format, i8); from_lexical_format!(atoi_format, i16); from_lexical_format!(atoi_format, i32); from_lexical_format!(atoi_format, i64); from_lexical_format!(atoi_format, isize); from_lexical_format!(atoi_format, i128); }} // TESTS // ----- #[cfg(test)] mod tests { use crate::util::*; #[cfg(all(feature = "std", feature = "property_tests"))] use proptest::{proptest, prop_assert_eq, prop_assert}; #[cfg(feature = "radix")] const DATA: [(u8, &'static str); 35] = [ (2, "100101"), (3, "1101"), (4, "211"), (5, "122"), (6, "101"), (7, "52"), (8, "45"), (9, "41"), (10, "37"), (11, "34"), (12, "31"), (13, "2B"), (14, "29"), (15, "27"), (16, "25"), (17, "23"), (18, "21"), (19, "1I"), (20, "1H"), (21, "1G"), (22, "1F"), (23, "1E"), (24, "1D"), (25, "1C"), (26, "1B"), (27, "1A"), (28, "19"), (29, "18"), (30, "17"), (31, "16"), (32, "15"), (33, "14"), (34, "13"), (35, "12"), (36, "11"), ]; #[test] fn u8_decimal_test() { assert_eq!(Ok(0), u8::from_lexical(b"0")); assert_eq!(Ok(127), u8::from_lexical(b"127")); assert_eq!(Ok(128), u8::from_lexical(b"128")); assert_eq!(Ok(255), u8::from_lexical(b"255")); assert_eq!(Err((ErrorCode::InvalidDigit, 0).into()), u8::from_lexical(b"-1")); assert_eq!(Err((ErrorCode::InvalidDigit, 1).into()), u8::from_lexical(b"1a")); } #[cfg(feature = "radix")] #[test] fn u8_radix_test() { for (b, s) in DATA.iter() { assert_eq!(u8::from_lexical_radix(s.as_bytes(), *b), Ok(37)); } } #[test] fn i8_decimal_test() { assert_eq!(Ok(0), i8::from_lexical(b"0")); assert_eq!(Ok(127), i8::from_lexical(b"127")); assert_eq!(Err((ErrorCode::Overflow, 2).into()), i8::from_lexical(b"128")); assert_eq!(Err((ErrorCode::Overflow, 2).into()), i8::from_lexical(b"255")); assert_eq!(Ok(-1), i8::from_lexical(b"-1")); assert_eq!(Err((ErrorCode::InvalidDigit, 1).into()), i8::from_lexical(b"1a")); } #[cfg(feature = "radix")] #[test] fn i8_radix_test() { for (b, s) in DATA.iter() { assert_eq!(i8::from_lexical_radix(s.as_bytes(), *b), Ok(37)); } } #[test] fn u16_decimal_test() { assert_eq!(Ok(0), u16::from_lexical(b"0")); assert_eq!(Ok(32767), u16::from_lexical(b"32767")); assert_eq!(Ok(32768), u16::from_lexical(b"32768")); assert_eq!(Ok(65535), u16::from_lexical(b"65535")); assert_eq!(Err((ErrorCode::InvalidDigit, 0).into()), u16::from_lexical(b"-1")); assert_eq!(Err((ErrorCode::InvalidDigit, 1).into()), u16::from_lexical(b"1a")); } #[test] fn i16_decimal_test() { assert_eq!(Ok(0), i16::from_lexical(b"0")); assert_eq!(Ok(32767), i16::from_lexical(b"32767")); assert_eq!(Err((ErrorCode::Overflow, 4).into()), i16::from_lexical(b"32768")); assert_eq!(Err((ErrorCode::Overflow, 4).into()), i16::from_lexical(b"65535")); assert_eq!(Ok(-1), i16::from_lexical(b"-1")); assert_eq!(Err((ErrorCode::InvalidDigit, 1).into()), i16::from_lexical(b"1a")); } #[cfg(feature = "radix")] #[test] fn i16_radix_test() { for (b, s) in DATA.iter() { assert_eq!(i16::from_lexical_radix(s.as_bytes(), *b), Ok(37)); } assert_eq!(i16::from_lexical_radix(b"YA", 36), Ok(1234)); } #[test] fn u32_decimal_test() { assert_eq!(Ok(0), u32::from_lexical(b"0")); assert_eq!(Ok(2147483647), u32::from_lexical(b"2147483647")); assert_eq!(Ok(2147483648), u32::from_lexical(b"2147483648")); assert_eq!(Ok(4294967295), u32::from_lexical(b"4294967295")); assert_eq!(Err((ErrorCode::InvalidDigit, 0).into()), u32::from_lexical(b"-1")); assert_eq!(Err((ErrorCode::InvalidDigit, 1).into()), u32::from_lexical(b"1a")); } #[test] fn i32_decimal_test() { assert_eq!(Ok(0), i32::from_lexical(b"0")); assert_eq!(Ok(2147483647), i32::from_lexical(b"2147483647")); assert_eq!(Err((ErrorCode::Overflow, 9).into()), i32::from_lexical(b"2147483648")); assert_eq!(Err((ErrorCode::Overflow, 9).into()), i32::from_lexical(b"4294967295")); assert_eq!(Ok(-1), i32::from_lexical(b"-1")); assert_eq!(Err((ErrorCode::InvalidDigit, 1).into()), i32::from_lexical(b"1a")); } #[test] fn u64_decimal_test() { assert_eq!(Ok(0), u64::from_lexical(b"0")); assert_eq!(Ok(9223372036854775807), u64::from_lexical(b"9223372036854775807")); assert_eq!(Ok(9223372036854775808), u64::from_lexical(b"9223372036854775808")); assert_eq!(Ok(18446744073709551615), u64::from_lexical(b"18446744073709551615")); assert_eq!(Err((ErrorCode::InvalidDigit, 0).into()), u64::from_lexical(b"-1")); assert_eq!(Err((ErrorCode::InvalidDigit, 1).into()), u64::from_lexical(b"1a")); } #[test] fn i64_decimal_test() { assert_eq!(Ok(0), i64::from_lexical(b"0")); assert_eq!(Ok(9223372036854775807), i64::from_lexical(b"9223372036854775807")); assert_eq!(Err((ErrorCode::Overflow, 18).into()), i64::from_lexical(b"9223372036854775808")); assert_eq!(Err((ErrorCode::Overflow, 19).into()), i64::from_lexical(b"18446744073709551615")); assert_eq!(Ok(-1), i64::from_lexical(b"-1")); assert_eq!(Err((ErrorCode::InvalidDigit, 1).into()), i64::from_lexical(b"1a")); // Add tests discovered via fuzzing. assert_eq!(Err((ErrorCode::Overflow, 19).into()), i64::from_lexical(b"406260572150672006000066000000060060007667760000000000000000000+00000006766767766666767665670000000000000000000000666")); } #[test] fn u128_decimal_test() { assert_eq!(Ok(0), u128::from_lexical(b"0")); assert_eq!(Ok(170141183460469231731687303715884105727), u128::from_lexical(b"170141183460469231731687303715884105727")); assert_eq!(Ok(170141183460469231731687303715884105728), u128::from_lexical(b"170141183460469231731687303715884105728")); assert_eq!(Ok(340282366920938463463374607431768211455), u128::from_lexical(b"340282366920938463463374607431768211455")); assert_eq!(Err((ErrorCode::InvalidDigit, 0).into()), u128::from_lexical(b"-1")); assert_eq!(Err((ErrorCode::InvalidDigit, 1).into()), u128::from_lexical(b"1a")); } #[test] fn i128_decimal_test() { assert_eq!(Ok(0), i128::from_lexical(b"0")); assert_eq!(Ok(170141183460469231731687303715884105727), i128::from_lexical(b"170141183460469231731687303715884105727")); assert_eq!(Err((ErrorCode::Overflow, 39).into()), i128::from_lexical(b"170141183460469231731687303715884105728")); assert_eq!(Err((ErrorCode::Overflow, 39).into()), i128::from_lexical(b"340282366920938463463374607431768211455")); assert_eq!(Ok(-1), i128::from_lexical(b"-1")); assert_eq!(Err((ErrorCode::InvalidDigit, 1).into()), i128::from_lexical(b"1a")); } #[test] #[cfg(feature = "format")] fn i32_no_leading_zeros_test() { let format = NumberFormat::NO_INTEGER_LEADING_ZEROS; assert!(i32::from_lexical_format(b"1", format).is_ok()); assert!(i32::from_lexical_format(b"0", format).is_ok()); assert!(i32::from_lexical_format(b"01", format).is_err()); assert!(i32::from_lexical_format(b"10", format).is_ok()); assert!(i32::from_lexical_format(b"010", format).is_err()); } #[test] #[cfg(feature = "format")] fn i32_integer_internal_digit_separator_test() { let format = NumberFormat::from_separator(b'_') | NumberFormat::INTEGER_INTERNAL_DIGIT_SEPARATOR; assert!(i32::from_lexical_format(b"3_1", format).is_ok()); assert!(i32::from_lexical_format(b"_31", format).is_err()); assert!(i32::from_lexical_format(b"31_", format).is_err()); } #[test] #[cfg(feature = "format")] fn i32_integer_leading_digit_separator_test() { let format = NumberFormat::from_separator(b'_') | NumberFormat::INTEGER_LEADING_DIGIT_SEPARATOR; assert!(i32::from_lexical_format(b"3_1", format).is_err()); assert!(i32::from_lexical_format(b"_31", format).is_ok()); assert!(i32::from_lexical_format(b"31_", format).is_err()); } #[test] #[cfg(feature = "format")] fn i32_integer_trailing_digit_separator_test() { let format = NumberFormat::from_separator(b'_') | NumberFormat::INTEGER_TRAILING_DIGIT_SEPARATOR; assert!(i32::from_lexical_format(b"3_1", format).is_err()); assert!(i32::from_lexical_format(b"_31", format).is_err()); assert!(i32::from_lexical_format(b"31_", format).is_ok()); } #[test] #[cfg(feature = "format")] fn i32_integer_consecutive_digit_separator_test() { let format = NumberFormat::from_separator(b'_') | NumberFormat::INTEGER_INTERNAL_DIGIT_SEPARATOR | NumberFormat::INTEGER_CONSECUTIVE_DIGIT_SEPARATOR; assert!(i32::from_lexical_format(b"3_1", format).is_ok()); assert!(i32::from_lexical_format(b"3__1", format).is_ok()); assert!(i32::from_lexical_format(b"_31", format).is_err()); assert!(i32::from_lexical_format(b"31_", format).is_err()); } #[test] #[cfg(feature = "format")] fn i32_json_no_leading_zero() { let format = NumberFormat::JSON; assert!(i32::from_lexical_format(b"12", format).is_ok()); assert!(i32::from_lexical_format(b"-12", format).is_ok()); assert!(i32::from_lexical_format(b"012", format).is_err()); assert!(i32::from_lexical_format(b"-012", format).is_err()); } #[cfg(all(feature = "std", feature = "property_tests"))] proptest! { #[test] fn u8_invalid_proptest(i in r"[+]?[0-9]{2}\D") { let result = u8::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let index = result.err().unwrap().index; prop_assert!(index == 2 || index == 3); } #[test] fn u8_overflow_proptest(i in r"[+]?[1-9][0-9]{3}") { let result = u8::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Overflow); } #[test] fn u8_negative_proptest(i in r"[-][1-9][0-9]{2}") { let result = u8::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::InvalidDigit); } #[test] fn u8_double_sign_proptest(i in r"[+]{2}[0-9]{2}") { let result = u8::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 1); } #[test] fn u8_sign_only_proptest(i in r"[+]") { let result = u8::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Empty); } #[test] fn u8_trailing_digits_proptest(i in r"[+]?[0-9]{2}\D[0-9]{2}") { let result = u8::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 2 || error.index == 3); } #[test] fn i8_invalid_proptest(i in r"[+-]?[0-9]{2}\D") { let result = i8::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 2 || error.index == 3); } #[test] fn i8_overflow_proptest(i in r"[+]?[1-9][0-9]{3}\D") { let result = i8::from_lexical(i.as_bytes()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Overflow); } #[test] fn i8_underflow_proptest(i in r"[-][1-9][0-9]{3}\D") { let result = i8::from_lexical(i.as_bytes()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Underflow); } #[test] fn i8_double_sign_proptest(i in r"[+-]{2}[0-9]{2}") { let result = i8::from_lexical(i.as_bytes()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 1); } #[test] fn i8_sign_only_proptest(i in r"[+-]") { let result = i8::from_lexical(i.as_bytes()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::Empty); } #[test] fn i8_trailing_digits_proptest(i in r"[+-]?[0-9]{2}\D[0-9]{2}") { let result = i8::from_lexical(i.as_bytes()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 2 || error.index == 3); } #[test] fn u16_invalid_proptest(i in r"[+]?[0-9]{4}\D") { let result = u16::from_lexical(i.as_bytes()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 4 || error.index == 5); } #[test] fn u16_overflow_proptest(i in r"[+]?[1-9][0-9]{5}\D") { let result = u16::from_lexical(i.as_bytes()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Overflow); } #[test] fn u16_negative_proptest(i in r"[-][1-9][0-9]{4}") { let result = u16::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::InvalidDigit); } #[test] fn u16_double_sign_proptest(i in r"[+]{2}[0-9]{4}") { let result = u16::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 1); } #[test] fn u16_sign_only_proptest(i in r"[+]") { let result = u16::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Empty); } #[test] fn u16_trailing_digits_proptest(i in r"[+]?[0-9]{4}\D[0-9]{2}") { let result = u16::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 4 || error.index == 5); } #[test] fn i16_invalid_proptest(i in r"[+-]?[0-9]{4}\D") { let result = i16::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 4 || error.index == 5); } #[test] fn i16_overflow_proptest(i in r"[+]?[1-9][0-9]{5}\D") { let result = i16::from_lexical(i.as_bytes()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Overflow); } #[test] fn i16_underflow_proptest(i in r"[-][1-9][0-9]{5}\DD") { let result = i16::from_lexical(i.as_bytes()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Underflow); } #[test] fn i16_double_sign_proptest(i in r"[+-]{2}[0-9]{4}") { let result = i16::from_lexical(i.as_bytes()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 1); } #[test] fn i16_sign_only_proptest(i in r"[+-]") { let result = i16::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Empty); } #[test] fn i16_trailing_digits_proptest(i in r"[+-]?[0-9]{4}\D[0-9]{2}") { let result = i16::from_lexical(i.as_bytes()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 4 || error.index == 5); } #[test] fn u32_invalid_proptest(i in r"[+]?[0-9]{9}\D") { let result = u32::from_lexical(i.as_bytes()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 9 || error.index == 10); } #[test] fn u32_overflow_proptest(i in r"[+]?[1-9][0-9]{10}\D") { let result = u32::from_lexical(i.as_bytes()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Overflow); } #[test] fn u32_negative_proptest(i in r"[-][1-9][0-9]{9}") { let result = u32::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::InvalidDigit); } #[test] fn u32_double_sign_proptest(i in r"[+]{2}[0-9]{9}") { let result = u32::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 1); } #[test] fn u32_sign_only_proptest(i in r"[+]") { let result = u32::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Empty); } #[test] fn u32_trailing_digits_proptest(i in r"[+]?[0-9]{9}\D[0-9]{2}") { let result = u32::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 9 || error.index == 10); } #[test] fn i32_invalid_proptest(i in r"[+-]?[0-9]{9}\D") { let result = i32::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 9 || error.index == 10); } #[test] fn i32_overflow_proptest(i in r"[+]?[1-9][0-9]{10}\D") { let result = i32::from_lexical(i.as_bytes()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Overflow); } #[test] fn i32_underflow_proptest(i in r"-[1-9][0-9]{10}\D") { let result = i32::from_lexical(i.as_bytes()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Underflow); } #[test] fn i32_double_sign_proptest(i in r"[+-]{2}[0-9]{9}") { let result = i32::from_lexical(i.as_bytes()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 1); } #[test] fn i32_sign_only_proptest(i in r"[+-]") { let result = i32::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Empty); } #[test] fn i32_trailing_digits_proptest(i in r"[+-]?[0-9]{9}\D[0-9]{2}") { let result = i32::from_lexical(i.as_bytes()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 9 || error.index == 10); } #[test] fn u64_invalid_proptest(i in r"[+]?[0-9]{19}\D") { let result = u64::from_lexical(i.as_bytes()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 19 || error.index == 20); } #[test] fn u64_overflow_proptest(i in r"[+]?[1-9][0-9]{21}\D") { let result = u64::from_lexical(i.as_bytes()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Overflow); } #[test] fn u64_negative_proptest(i in r"[-][1-9][0-9]{21}") { let result = u64::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::InvalidDigit); } #[test] fn u64_double_sign_proptest(i in r"[+]{2}[0-9]{19}") { let result = u64::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 1); } #[test] fn u64_sign_only_proptest(i in r"[+]") { let result = u64::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Empty); } #[test] fn u64_trailing_digits_proptest(i in r"[+]?[0-9]{19}\D[0-9]{2}") { let result = u64::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 19 || error.index == 20); } #[test] fn i64_invalid_proptest(i in r"[+-]?[0-9]{18}\D") { let result = i64::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 18 || error.index == 19); } #[test] fn i64_overflow_proptest(i in r"[+]?[1-9][0-9]{19}\D") { let result = i64::from_lexical(i.as_bytes()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Overflow); } #[test] fn i64_underflow_proptest(i in r"-[1-9][0-9]{19}\D") { let result = i64::from_lexical(i.as_bytes()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Underflow); } #[test] fn i64_double_sign_proptest(i in r"[+-]{2}[0-9]{18}") { let result = i64::from_lexical(i.as_bytes()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 1); } #[test] fn i64_sign_only_proptest(i in r"[+-]") { let result = i32::from_lexical(i.as_bytes()); prop_assert!(result.is_err()); let code = result.err().unwrap().code; prop_assert_eq!(code, ErrorCode::Empty); } #[test] fn i64_trailing_digits_proptest(i in r"[+-]?[0-9]{18}\D[0-9]{2}") { let result = i64::from_lexical(i.as_bytes()); let error = result.err().unwrap(); prop_assert_eq!(error.code, ErrorCode::InvalidDigit); prop_assert!(error.index == 18 || error.index == 19); } } } lexical-core-0.7.6/src/atoi/exponent.rs000075500000000000000000000043050000000000000161200ustar 00000000000000//! String-to-integer routines specialized to parse the exponent of a float. use crate::util::*; use super::shared::*; // STANDALONE EXPONENT // ------------------- // These routines are a specialized parser for the exponent of a floating- // point number, from an unvalidated buffer with a potential sign bit. // On numeric overflow or underflow, we want to return the max or min // value possible, respectively. On overflow, find the first non-digit // char (if applicable), and return the max/min value and the number // of digits parsed. // Add digit to mantissa. macro_rules! add_digit { ($value:ident, $radix:ident, $op:ident, $digit:ident) => { match $value.checked_mul(as_cast($radix)) { Some(v) => v.$op(as_cast($digit)), None => None, } }; } // Iterate over the digits and iteratively process them. macro_rules! parse_digits_exponent { ($value:ident, $iter:ident, $radix:ident, $op:ident, $default:expr) => ( while let Some(c) = $iter.next() { let digit = match to_digit(c, $radix) { Ok(v) => v, Err(c) => return ($value, c), }; $value = match add_digit!($value, $radix, $op, digit) { Some(v) => v, None => { // Consume the rest of the iterator to validate // the remaining data. if let Some(c) = $iter.find(|&c| is_not_digit_char(*c, $radix)) { return ($default, c); } $default }, }; } ); } // Specialized parser for the exponent, which validates digits and // returns a default min or max value on overflow. perftools_inline!{ pub(crate) fn standalone_exponent<'a, Iter>(mut iter: Iter, radix: u32, sign: Sign) -> (i32, *const u8) where Iter: AsPtrIterator<'a, u8> { // Parse the sign bit or current data. let mut value = 0; match sign { Sign::Positive => parse_digits_exponent!(value, iter, radix, checked_add, i32::max_value()), Sign::Negative => parse_digits_exponent!(value, iter, radix, checked_sub, i32::min_value()) } (value, iter.as_ptr()) }} lexical-core-0.7.6/src/atoi/generic.rs000075500000000000000000000615730000000000000157060ustar 00000000000000//! Fast, generic, lexical string-to-integer conversion routines. // The following benchmarks were run on an "Intel(R) Core(TM) i7-6560U // CPU @ 2.20GHz" CPU, on Fedora 28, Linux kernel version 4.18.16-200 // (x86-64), using the lexical formatter or `x.parse()`, // avoiding any inefficiencies in Rust string parsing. The code was // compiled with LTO and at an optimization level of 3. // // The benchmarks with `std` were compiled using "rustc 1.32.0 // (9fda7c223 2019-01-16)". // // The benchmark code may be found `benches/atoi.rs`. // // # Benchmarks // // | Type | lexical (ns/iter) | parse (ns/iter) | Relative Increase | // |:-----:|:------------------:|:---------------------:|:-----------------:| // | u8 | 75,622 | 80,021 | 1.06x | // | u16 | 80,926 | 82,185 | 1.02x | // | u32 | 131,221 | 148,231 | 1.13x | // | u64 | 243,315 | 296,713 | 1.22x | // | u128 | 512,552 | 1,175,946 | 2.29x | // | i8 | 112,152 | 115,147 | 1.03x | // | i16 | 153,670 | 150,231 | 0.98x | // | i32 | 202,512 | 204,880 | 1.01x | // | i64 | 309,731 | 309,584 | 1.00x | // | i128 | 4,362,672 | 149,418,085 | 34.3x | // // # Raw Benchmarks // // ```text // test atoi_i128_lexical ... bench: 4,305,621 ns/iter (+/- 132,707) // test atoi_i128_parse ... bench: 146,893,478 ns/iter (+/- 2,822,002) // test atoi_i16_lexical ... bench: 132,255 ns/iter (+/- 5,503) // test atoi_i16_parse ... bench: 137,965 ns/iter (+/- 5,906) // test atoi_i32_lexical ... bench: 207,101 ns/iter (+/- 79,541) // test atoi_i32_parse ... bench: 194,225 ns/iter (+/- 9,065) // test atoi_i64_lexical ... bench: 271,538 ns/iter (+/- 9,137) // test atoi_i64_parse ... bench: 293,542 ns/iter (+/- 9,706) // test atoi_i8_lexical ... bench: 106,368 ns/iter (+/- 5,919) // test atoi_i8_parse ... bench: 108,316 ns/iter (+/- 3,418) // test atoi_u128_lexical ... bench: 496,426 ns/iter (+/- 40,197) // test atoi_u128_parse ... bench: 1,119,213 ns/iter (+/- 54,945) // test atoi_u128_simple_lexical ... bench: 121,121 ns/iter (+/- 4,858) // test atoi_u128_simple_parse ... bench: 97,518 ns/iter (+/- 2,739) // test atoi_u16_lexical ... bench: 80,886 ns/iter (+/- 2,366) // test atoi_u16_parse ... bench: 81,881 ns/iter (+/- 1,708) // test atoi_u16_simple_lexical ... bench: 62,819 ns/iter (+/- 1,707) // test atoi_u16_simple_parse ... bench: 60,916 ns/iter (+/- 8,340) // test atoi_u32_lexical ... bench: 139,264 ns/iter (+/- 3,945) // test atoi_u32_parse ... bench: 139,649 ns/iter (+/- 5,735) // test atoi_u32_simple_lexical ... bench: 61,398 ns/iter (+/- 1,248) // test atoi_u32_simple_parse ... bench: 59,560 ns/iter (+/- 3,388) // test atoi_u64_lexical ... bench: 257,116 ns/iter (+/- 6,810) // test atoi_u64_parse ... bench: 273,811 ns/iter (+/- 6,871) // test atoi_u64_simple_lexical ... bench: 59,674 ns/iter (+/- 4,852) // test atoi_u64_simple_parse ... bench: 55,982 ns/iter (+/- 2,288) // test atoi_u8_lexical ... bench: 70,637 ns/iter (+/- 1,889) // test atoi_u8_parse ... bench: 67,606 ns/iter (+/- 1,924) // test atoi_u8_simple_lexical ... bench: 41,190 ns/iter (+/- 6,948) // test atoi_u8_simple_parse ... bench: 36,836 ns/iter (+/- 2,958) // ``` // // Code the generate the benchmark plot: // import numpy as np // import pandas as pd // import matplotlib.pyplot as plt // plt.style.use('ggplot') // lexical = np.array([75622, 80926, 131221, 243315, 512552, 112152, 153670, 202512, 309731, 4362672]) / 1e6 // rustcore = np.array([80021, 82185, 148231, 296713, 1175946, 115147, 150231, 204880, 309584, 149418085]) / 1e6 // index = ["u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", "i64", "i128"] // df = pd.DataFrame({'lexical': lexical, 'rustcore': rustcore}, index = index, columns=['lexical', 'rustcore']) // ax = df.plot.bar(rot=0, figsize=(16, 8), fontsize=14, color=['#E24A33', '#348ABD']) // ax.set_ylabel("ms/iter") // ax.set_yscale('log') // ax.figure.tight_layout() // ax.legend(loc=2, prop={'size': 14}) // plt.show() use crate::util::*; use super::shared::*; // SHARED // ------ // Validate the extracted integer has no leading zeros. perftools_inline!{ #[cfg(feature = "format")] fn validate_no_leading_zeros<'a>(digits: &[u8], digit_separator: u8, ptr: *const u8) -> ParseResult<()> { // Check if the next character is a sign symbol. let index = distance(digits.as_ptr(), ptr); let digits = &index!(digits[..index]); let mut iter = iterate_digits_ignore_separator(digits, digit_separator); let is_zero = match iter.next() { Some(&b'+') | Some(&b'-') => false, Some(&b'0') => true, _ => return Ok(()) }; // Only here if we have a leading 0 or sign symbol. match iter.next() { Some(_) if is_zero => return Err((ErrorCode::InvalidLeadingZeros, digits.as_ptr())), Some(&b'0') => (), _ => return Ok(()) } // Only here if we have a leading 0 symbol. match iter.next() { Some(_) => Err((ErrorCode::InvalidLeadingZeros, digits.as_ptr())), _ => Ok(()) } }} // STANDALONE // ---------- /// Iterate over the digits and iteratively process them. macro_rules! parse_digits { ($value:ident, $iter:ident, $radix:ident, $op:ident, $code:ident) => ( while let Some(c) = $iter.next() { let digit = match to_digit!(*c, $radix) { Some(v) => v, None => return Ok(($value, c)), }; $value = match $value.checked_mul(as_cast($radix)) { Some(v) => v, None => return Err((ErrorCode::$code, c)), }; $value = match $value.$op(as_cast(digit)) { Some(v) => v, None => return Err((ErrorCode::$code, c)), }; } ); } // Parse the digits for the atoi processor. perftools_inline_always!{ fn parse_digits<'a, T, Iter>(digits: &[u8], mut iter: Iter, radix: u32, sign: Sign) -> ParseResult<(T, *const u8)> where T: Integer, Iter: AsPtrIterator<'a, u8> { let mut value = T::ZERO; if sign == Sign::Positive { parse_digits!(value, iter, radix, checked_add, Overflow); } else { parse_digits!(value, iter, radix, checked_sub, Underflow); } Ok((value, last_ptr(digits))) }} // PARSE THEN EXTRACT // Standalone atoi processor without a digit separator. perftools_inline_always!{ fn standalone(bytes: &[u8], radix: u32) -> ParseResult<(T, *const u8)> where T: Integer { let (sign, digits) = parse_sign!(bytes, T::IS_SIGNED, Empty); let iter = iterate_digits_no_separator(digits, b'\x00'); parse_digits(digits, iter, radix, sign) }} // Standalone atoi processor with digit separators. // Consumes leading, internal, trailing, and consecutive digit separators. perftools_inline_always!{ #[cfg(feature = "format")] fn standalone_iltc(bytes: &[u8], radix: u32, digit_separator: u8) -> ParseResult<(T, *const u8)> where T: Integer { let (sign, digits) = parse_sign_lc_separator::(bytes, digit_separator); if digits.is_empty() { return Err((ErrorCode::Empty, digits.as_ptr())); } let iter = iterate_digits_ignore_separator(digits, digit_separator); parse_digits(digits, iter, radix, sign) }} // EXTRACT THEN PARSE // Generate function definition to extract then parse an integer with digit separators. macro_rules! standalone_atoi_separator { ( fn $name:ident, sign => $sign:ident, consume => $consume:ident ) => ( perftools_inline_always!{ #[cfg(feature = "format")] fn $name( bytes: &[u8], radix: u32, digit_separator: u8 ) -> ParseResult<(T, *const u8)> where T: Integer { // Parse the sign, and error if we have no more digits. let (sign, digits) = $sign::(bytes, digit_separator); if digits.is_empty() { return Err((ErrorCode::Empty, digits.as_ptr())); } // Extract the integer subslice, then parse. let leading = $consume(digits, radix, digit_separator).0; let iter = iterate_digits_ignore_separator(leading, digit_separator); parse_digits(leading, iter, radix, sign) }} ); } standalone_atoi_separator!( fn standalone_i, sign => parse_sign_no_separator, consume => consume_digits_i ); standalone_atoi_separator!( fn standalone_ic, sign => parse_sign_no_separator, consume => consume_digits_ic ); standalone_atoi_separator!( fn standalone_l, sign => parse_sign_l_separator, consume => consume_digits_l ); standalone_atoi_separator!( fn standalone_lc, sign => parse_sign_lc_separator, consume => consume_digits_lc ); standalone_atoi_separator!( fn standalone_t, sign => parse_sign_no_separator, consume => consume_digits_t ); standalone_atoi_separator!( fn standalone_tc, sign => parse_sign_no_separator, consume => consume_digits_tc ); standalone_atoi_separator!( fn standalone_il, sign => parse_sign_l_separator, consume => consume_digits_il ); standalone_atoi_separator!( fn standalone_ilc, sign => parse_sign_lc_separator, consume => consume_digits_ilc ); standalone_atoi_separator!( fn standalone_it, sign => parse_sign_no_separator, consume => consume_digits_it ); standalone_atoi_separator!( fn standalone_itc, sign => parse_sign_no_separator, consume => consume_digits_itc ); standalone_atoi_separator!( fn standalone_lt, sign => parse_sign_l_separator, consume => consume_digits_lt ); standalone_atoi_separator!( fn standalone_ltc, sign => parse_sign_lc_separator, consume => consume_digits_ltc ); standalone_atoi_separator!( fn standalone_ilt, sign => parse_sign_l_separator, consume => consume_digits_ilt ); // API // Standalone atoi processor without a digit separator. perftools_inline_always!{ pub(crate) fn standalone_no_separator(bytes: &[u8], radix: u32) -> ParseResult<(T, *const u8)> where T: Integer { standalone(bytes, radix) }} // Extract exponent with a digit separator in the exponent component. perftools_inline_always!{ #[cfg(feature = "format")] pub(crate) fn standalone_separator(bytes: &[u8], radix: u32, format: NumberFormat) -> ParseResult<(V, *const u8)> where V: Integer { const I: NumberFormat = NumberFormat::INTEGER_INTERNAL_DIGIT_SEPARATOR; const L: NumberFormat = NumberFormat::INTEGER_LEADING_DIGIT_SEPARATOR; const T: NumberFormat = NumberFormat::INTEGER_TRAILING_DIGIT_SEPARATOR; const C: NumberFormat = NumberFormat::INTEGER_CONSECUTIVE_DIGIT_SEPARATOR; const IL: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | L.bits()); const IT: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | T.bits()); const LT: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | T.bits()); const ILT: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | T.bits()); const IC: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | C.bits()); const LC: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | C.bits()); const TC: NumberFormat = NumberFormat::from_bits_truncate(T.bits() | C.bits()); const ILC: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | C.bits()); const ITC: NumberFormat = NumberFormat::from_bits_truncate(IT.bits() | C.bits()); const LTC: NumberFormat = NumberFormat::from_bits_truncate(LT.bits() | C.bits()); const ILTC: NumberFormat = NumberFormat::from_bits_truncate(ILT.bits() | C.bits()); let digit_separator = format.digit_separator(); let (value, ptr) = match format & NumberFormat::INTEGER_DIGIT_SEPARATOR_FLAG_MASK { I => standalone_i(bytes, radix, digit_separator), IC => standalone_ic(bytes, radix, digit_separator), L => standalone_l(bytes, radix, digit_separator), LC => standalone_lc(bytes, radix, digit_separator), T => standalone_t(bytes, radix, digit_separator), TC => standalone_tc(bytes, radix, digit_separator), IL => standalone_il(bytes, radix, digit_separator), ILC => standalone_ilc(bytes, radix, digit_separator), IT => standalone_it(bytes, radix, digit_separator), ITC => standalone_itc(bytes, radix, digit_separator), LT => standalone_lt(bytes, radix, digit_separator), LTC => standalone_ltc(bytes, radix, digit_separator), ILT => standalone_ilt(bytes, radix, digit_separator), ILTC => standalone_iltc(bytes, radix, digit_separator), // No digit separator match. _ => standalone(bytes, radix) }?; // Check if we have any leading zeros. if format.no_integer_leading_zeros() { validate_no_leading_zeros(bytes, digit_separator, ptr)?; } Ok((value, ptr)) }} // STANDALONE U128 // --------------- // Grab the step size and power for step_u64. // This is the same as the u128 divisor, so don't duplicate the values // there. perftools_inline_always!{ fn step_u64(radix: u32) -> usize { u128_divisor(radix).1 }} // Add 64-bit temporary to the 128-bit value. macro_rules! add_temporary_128 { ($value:ident, $tmp:ident, $step_power:ident, $ptr:expr, $op:ident, $code:ident) => ( if !$value.is_zero() { $value = match $value.checked_mul(as_cast($step_power)) { Some(v) => v, None => return Err((ErrorCode::$code, $ptr)), }; } $value = match $value.$op(as_cast($tmp)) { Some(v) => v, None => return Err((ErrorCode::$code, $ptr)), }; ); } /// Iterate over the digits and iteratively process them. macro_rules! parse_digits_u128 { ($value:ident, $iter:ident, $radix:ident, $step:ident, $op:ident, $code:ident) => ({ // Break the input into chunks of len `step`, which can be parsed // as a 64-bit integer. while !$iter.consumed() { let mut value: u64 = 0; let mut index = 0; while index < $step { if let Some(c) = $iter.next() { index += 1; let digit = match to_digit!(*c, $radix) { Some(v) => v, None => { // Add temporary to value and return early. let radix_pow = $radix.as_u64().pow(index.as_u32()); add_temporary_128!($value, value, radix_pow, c, $op, $code); return Ok(($value, c)); }, }; // Don't have to worry about overflows. value *= $radix.as_u64(); value += digit.as_u64(); } else { break; } } // Add the temporary value to the total value. let radix_pow = $radix.as_u64().pow(index.as_u32()); add_temporary_128!($value, value, radix_pow, $iter.as_ptr(), $op, $code); } }); } // Quickly parse digits using a 64-bit intermediate for the 128-bit atoi processor. perftools_inline_always!{ fn parse_digits_128_fast<'a, W, N, Iter>(digits: &[u8], iter: Iter, radix: u32, sign: Sign) -> ParseResult<(W, *const u8)> where W: Integer, N: Integer, Iter: ConsumedIterator + AsPtrIterator<'a, u8> { let (value, ptr) = parse_digits::(digits, iter, radix, sign)?; Ok((as_cast(value), ptr)) }} // Slowly parse digits for the 128-bit atoi processor. perftools_inline_always!{ fn parse_digits_128_slow<'a, T, Iter>(digits: &[u8], mut iter: Iter, radix: u32, step: usize, sign: Sign) -> ParseResult<(T, *const u8)> where T: Integer, Iter: ConsumedIterator + AsPtrIterator<'a, u8> { let mut value = T::ZERO; if sign == Sign::Positive { parse_digits_u128!(value, iter, radix, step, checked_add, Overflow) } else { parse_digits_u128!(value, iter, radix, step, checked_sub, Underflow) } Ok((value, last_ptr(digits))) }} // Parse digits for the 128-bit atoi processor. // // This algorithm may overestimate the number of digits to overflow // on numeric overflow or underflow, otherwise, it will be accurate. // This is because we break costly u128 addition/multiplications into // temporary steps using u64, allowing much better performance. // This is a similar approach to what we take in the arbitrary-precision // arithmetic. perftools_inline_always!{ fn parse_digits_128<'a, W, N, Iter>(digits: &[u8], iter: Iter, radix: u32, sign: Sign) -> ParseResult<(W, *const u8)> where W: Integer, N: Integer, Iter: ConsumedIterator + AsPtrIterator<'a, u8> { // This is guaranteed to be safe, since if the length is // 1 less than step, and the min radix is 2, the value must be // less than 2x u64::MAX, which means it must fit in an i64. let step = step_u64(radix); if digits.len() < step { parse_digits_128_fast::(digits, iter, radix, sign) } else { parse_digits_128_slow(digits, iter, radix, step, sign) } }} // PARSE THEN EXTRACT // Standalone atoi processor for 128-bit integers without a digit separator. perftools_inline_always!{ fn standalone_128(bytes: &[u8], radix: u32) -> ParseResult<(W, *const u8)> where W: Integer, N: Integer { let (sign, digits) = parse_sign!(bytes, W::IS_SIGNED, Empty); let iter = iterate_digits_no_separator(digits, b'\x00'); parse_digits_128::(digits, iter, radix, sign) }} // Standalone atoi processor for 128-bit integers with digit separators. // Consumes leading, internal, trailing, and consecutive digit separators. perftools_inline_always!{ #[cfg(feature = "format")] fn standalone_128_iltc(bytes: &[u8], radix: u32, digit_separator: u8) -> ParseResult<(W, *const u8)> where W: Integer, N: Integer { let (sign, digits) = parse_sign_lc_separator::(bytes, digit_separator); if digits.is_empty() { return Err((ErrorCode::Empty, digits.as_ptr())); } let iter = iterate_digits_ignore_separator(digits, digit_separator); parse_digits_128::(digits, iter, radix, sign) }} // EXTRACT THEN PARSE // Generate function definition to extract then parse an 128-bit integer with digit separators. macro_rules! standalone_atoi_128_separator { ( fn $name:ident, sign => $sign:ident, consume => $consume:ident ) => ( perftools_inline!{ #[cfg(feature = "format")] fn $name( bytes: &[u8], radix: u32, digit_separator: u8 ) -> ParseResult<(W, *const u8)> where W: Integer, N: Integer { // Parse the sign, and error if we have no more digits. let (sign, digits) = $sign::(bytes, digit_separator); if digits.is_empty() { return Err((ErrorCode::Empty, digits.as_ptr())); } // Extract the integer subslice, then parse. let leading = $consume(digits, radix, digit_separator).0; let iter = iterate_digits_ignore_separator(leading, digit_separator); parse_digits_128::(leading, iter, radix, sign) }} ); } standalone_atoi_128_separator!( fn standalone_128_i, sign => parse_sign_no_separator, consume => consume_digits_i ); standalone_atoi_128_separator!( fn standalone_128_ic, sign => parse_sign_no_separator, consume => consume_digits_ic ); standalone_atoi_128_separator!( fn standalone_128_l, sign => parse_sign_l_separator, consume => consume_digits_l ); standalone_atoi_128_separator!( fn standalone_128_lc, sign => parse_sign_lc_separator, consume => consume_digits_lc ); standalone_atoi_128_separator!( fn standalone_128_t, sign => parse_sign_no_separator, consume => consume_digits_t ); standalone_atoi_128_separator!( fn standalone_128_tc, sign => parse_sign_no_separator, consume => consume_digits_tc ); standalone_atoi_128_separator!( fn standalone_128_il, sign => parse_sign_l_separator, consume => consume_digits_il ); standalone_atoi_128_separator!( fn standalone_128_ilc, sign => parse_sign_lc_separator, consume => consume_digits_ilc ); standalone_atoi_128_separator!( fn standalone_128_it, sign => parse_sign_no_separator, consume => consume_digits_it ); standalone_atoi_128_separator!( fn standalone_128_itc, sign => parse_sign_no_separator, consume => consume_digits_itc ); standalone_atoi_128_separator!( fn standalone_128_lt, sign => parse_sign_l_separator, consume => consume_digits_lt ); standalone_atoi_128_separator!( fn standalone_128_ltc, sign => parse_sign_lc_separator, consume => consume_digits_ltc ); standalone_atoi_128_separator!( fn standalone_128_ilt, sign => parse_sign_l_separator, consume => consume_digits_ilt ); // API // Standalone atoi processor for u128 without a digit separator. perftools_inline_always!{ pub(crate) fn standalone_128_no_separator(bytes: &[u8], radix: u32) -> ParseResult<(W, *const u8)> where W: Integer, N: Integer { standalone_128::(bytes, radix) }} // Extract exponent with a digit separator in the exponent component. perftools_inline_always!{ #[cfg(feature = "format")] pub(crate) fn standalone_128_separator(bytes: &[u8], radix: u32, format: NumberFormat) -> ParseResult<(W, *const u8)> where W: Integer, N: Integer { const I: NumberFormat = NumberFormat::INTEGER_INTERNAL_DIGIT_SEPARATOR; const L: NumberFormat = NumberFormat::INTEGER_LEADING_DIGIT_SEPARATOR; const T: NumberFormat = NumberFormat::INTEGER_TRAILING_DIGIT_SEPARATOR; const C: NumberFormat = NumberFormat::INTEGER_CONSECUTIVE_DIGIT_SEPARATOR; const IL: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | L.bits()); const IT: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | T.bits()); const LT: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | T.bits()); const ILT: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | T.bits()); const IC: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | C.bits()); const LC: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | C.bits()); const TC: NumberFormat = NumberFormat::from_bits_truncate(T.bits() | C.bits()); const ILC: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | C.bits()); const ITC: NumberFormat = NumberFormat::from_bits_truncate(IT.bits() | C.bits()); const LTC: NumberFormat = NumberFormat::from_bits_truncate(LT.bits() | C.bits()); const ILTC: NumberFormat = NumberFormat::from_bits_truncate(ILT.bits() | C.bits()); let digit_separator = format.digit_separator(); let (value, ptr) = match format & NumberFormat::INTEGER_DIGIT_SEPARATOR_FLAG_MASK { I => standalone_128_i::(bytes, radix, digit_separator), IC => standalone_128_ic::(bytes, radix, digit_separator), L => standalone_128_l::(bytes, radix, digit_separator), LC => standalone_128_lc::(bytes, radix, digit_separator), T => standalone_128_t::(bytes, radix, digit_separator), TC => standalone_128_tc::(bytes, radix, digit_separator), IL => standalone_128_il::(bytes, radix, digit_separator), ILC => standalone_128_ilc::(bytes, radix, digit_separator), IT => standalone_128_it::(bytes, radix, digit_separator), ITC => standalone_128_itc::(bytes, radix, digit_separator), LT => standalone_128_lt::(bytes, radix, digit_separator), LTC => standalone_128_ltc::(bytes, radix, digit_separator), ILT => standalone_128_ilt::(bytes, radix, digit_separator), ILTC => standalone_128_iltc::(bytes, radix, digit_separator), // No digit separator match. _ => standalone_128::(bytes, radix) }?; // Check if we have any leading zeros. if format.no_integer_leading_zeros() { validate_no_leading_zeros(bytes, digit_separator, ptr)?; } Ok((value, ptr)) }} lexical-core-0.7.6/src/atoi/mantissa.rs000075500000000000000000000061660000000000000161060ustar 00000000000000//! String-to-integer routines specialized to parse the mantissa of a float. use crate::util::*; #[cfg(feature = "correct")] use super::shared::*; // STANDALONE MANTISSA // ------------------- // These routines are a specialized parser for the mantissa of a floating- // point number, from two buffers containing valid digits. We want to // exit early on numeric overflow, returning the value parsed up until // that point. // Calculate the mantissa and the number of truncated digits from a digits iterator. // Will stop once the iterators produce a non-valid digit character. perftools_inline!{ #[cfg(feature = "correct")] pub(crate) fn standalone_mantissa<'a, T, Iter1, Iter2>(mut integer: Iter1, mut fraction: Iter2, radix: u32) -> (T, usize) where T: UnsignedInteger, Iter1: Iterator, Iter2: Iterator { // Mote: // Do not use iter.chain(), since it is enormously slow. // Since we need to maintain backwards compatibility, even if // iter.chain() is patched, for older Rustc versions, it's nor // worth the performance penalty. let mut value: T = T::ZERO; // On overflow, validate that all the remaining characters are valid // digits, if not, return the first invalid digit. Otherwise, // calculate the number of truncated digits. while let Some(c) = integer.next() { value = match add_digit(value, to_digit!(*c, radix).unwrap(), radix) { Some(v) => v, None => { let truncated = 1 + integer.count() + fraction.count(); return (value, truncated); }, }; } while let Some(c) = fraction.next() { value = match add_digit(value, to_digit!(*c, radix).unwrap(), radix) { Some(v) => v, None => { let truncated = 1 + fraction.count(); return (value, truncated); }, }; } (value, 0) }} // Calculate the mantissa when it cannot have sign or other invalid digits. perftools_inline!{ #[cfg(not(feature = "correct"))] pub(crate) fn standalone_mantissa<'a, T, Iter>(mut iter: Iter, radix: u32) -> T where T: Integer, Iter: Iterator { // Parse the integer. let mut value = T::ZERO; while let Some(c) = iter.next() { // Cannot overflow, since using a wrapped float. value = (value * as_cast(radix)) + as_cast(to_digit!(*c, radix).unwrap()); } value }} // Calculate mantissa and only take first N digits. perftools_inline!{ #[cfg(not(feature = "correct"))] pub(crate) fn standalone_mantissa_n<'a, T, Iter>(iter: &mut Iter, radix: u32, max: usize) -> (T, usize) where T: Integer, Iter: Iterator { // Parse the integer. let mut value = T::ZERO; let mut index = 0; while index < max { if let Some(c) = iter.next() { // Cannot overflow, since we're limiting it to non-overflowing digit counts. index += 1; value = (value * as_cast(radix)) + as_cast(to_digit!(*c, radix).unwrap()); } else { break; } } (value, index) }} lexical-core-0.7.6/src/atoi/mod.rs000075500000000000000000000003700000000000000150350ustar 00000000000000//! Fast lexical string-to-integer conversion routines. // Hide implementation details. #[macro_use] mod shared; mod api; mod exponent; mod generic; mod mantissa; // Re-exports pub(crate) use self::mantissa::*; pub(crate) use self::exponent::*; lexical-core-0.7.6/src/atoi/shared.rs000075500000000000000000000037760000000000000155410ustar 00000000000000//! Shared definitions for string-to-integer conversions. use crate::lib::result::Result as StdResult; #[cfg(feature = "correct")] use crate::util::*; // SHARED // ------ // Convert u8 to digit. macro_rules! to_digit { ($c:expr, $radix:expr) => (($c as char).to_digit($radix)); } // Parse the sign bit and filter empty inputs from the atoi data. macro_rules! parse_sign { ($bytes:ident, $is_signed:expr, $code:ident) => ({ // Filter out empty inputs. if $bytes.is_empty() { return Err((ErrorCode::$code, $bytes.as_ptr())); } let (sign, digits) = match index!($bytes[0]) { b'+' => (Sign::Positive, &index!($bytes[1..])), b'-' if $is_signed => (Sign::Negative, &index!($bytes[1..])), _ => (Sign::Positive, $bytes), }; // Filter out empty inputs. if digits.is_empty() { return Err((ErrorCode::$code, digits.as_ptr())); } (sign, digits) }); } // Get pointer to 1-past-end of slice. // Performance note: Use slice, as `iter.as_ptr()` turns out to // quite slow performance wise, likely since it needs to calculate // the end ptr, while for a slice this is effectively a no-op. perftools_inline_always!{ pub(super) fn last_ptr(slc: &[T]) -> *const T { index!(slc[slc.len()..]).as_ptr() }} // Convert character to digit. perftools_inline_always!{ pub(super) fn to_digit<'a>(c: &'a u8, radix: u32) -> StdResult { match to_digit!(*c, radix) { Some(v) => Ok(v), None => Err(c), } }} // Convert character to digit. perftools_inline_always!{ pub(super) fn is_not_digit_char(c: u8, radix: u32) -> bool { to_digit!(c, radix).is_none() }} // Add digit to mantissa. perftools_inline_always!{ #[cfg(feature = "correct")] pub(super) fn add_digit(value: T, digit: u32, radix: u32) -> Option where T: UnsignedInteger { return value .checked_mul(as_cast(radix))? .checked_add(as_cast(digit)) }} lexical-core-0.7.6/src/float/convert.rs000075500000000000000000000056510000000000000161160ustar 00000000000000//! Convert between extended-precision and native floats/integers. use crate::lib::convert::From; use crate::lib::mem; use crate::util::*; use super::float::ExtendedFloat; use super::mantissa::Mantissa; // FROM INT // Import ExtendedFloat from integer. // // This works because we call normalize before any operation, which // allows us to convert the integer representation to the float one. perftools_inline!{ pub(crate) fn from_int(t: T) -> ExtendedFloat where T: Integer, M: Mantissa { debug_assert!(mem::size_of::() <= mem::size_of::(), "Possible truncation in ExtendedFloat::from_int."); ExtendedFloat { mant: as_cast(t), exp: 0, } }} // FROM FLOAT // Import ExtendedFloat from native float. perftools_inline!{ pub(crate) fn from_float(t: T) -> ExtendedFloat where T: Float, M: Mantissa { ExtendedFloat { mant: as_cast(t.mantissa()), exp: t.exponent(), } }} // AS FLOAT // Export extended-precision float to native float. // // The extended-precision float must be in native float representation, // with overflow/underflow appropriately handled. perftools_inline!{ pub(crate) fn into_float(fp: ExtendedFloat) -> T where T: Float, M: Mantissa { // Export floating-point number. if fp.mant.is_zero() || fp.exp < T::DENORMAL_EXPONENT { // sub-denormal, underflow T::ZERO } else if fp.exp >= T::MAX_EXPONENT { // overflow T::from_bits(T::INFINITY_BITS) } else { // calculate the exp and fraction bits, and return a float from bits. let exp: M; if (fp.exp == T::DENORMAL_EXPONENT) && (fp.mant & as_cast::(T::HIDDEN_BIT_MASK)).is_zero() { exp = M::ZERO; } else { exp = as_cast::(fp.exp + T::EXPONENT_BIAS); } let exp = exp << T::MANTISSA_SIZE; let mant = fp.mant & as_cast::(T::MANTISSA_MASK); T::from_bits(as_cast(mant | exp)) } }} // FROM CONVERSIONS /// Conversion from a float to an extended float of the same size. impl From for ExtendedFloat where F::Unsigned: Mantissa { perftools_inline!{ fn from(f: F) -> Self { from_float(f) }} } /// Conversion from a (mant, exp) tuple to an extended float of the same size. impl From<(M, i32)> for ExtendedFloat { perftools_inline!{ fn from(t: (M, i32)) -> Self { ExtendedFloat { mant: t.0, exp: t.1 } }} } // TESTS // ----- #[cfg(test)] mod tests { use super::*; #[test] fn convert_float_test() { let f: f32 = 1e-45; let fp: ExtendedFloat = f.into(); assert_eq!(fp, ExtendedFloat { mant: 1u32, exp: -149 }); } #[test] fn convert_tuple_test() { let t = (1u64, 0i32); let fp: ExtendedFloat = t.into(); assert_eq!(fp, ExtendedFloat { mant: 1u64, exp: 0 }); } } lexical-core-0.7.6/src/float/float.rs000075500000000000000000001202210000000000000155320ustar 00000000000000//! Extended precision floating-point types. //! //! Also contains helpers to convert to and from native rust floats. //! This representation stores the mantissa as a 64-bit unsigned integer, //! and the exponent as a 32-bit unsigned integer, allowed ~80 bits of //! precision (only 16 bits of the 32-bit integer are used, u32 is used //! for performance). Since there is no storage for the sign bit, //! this only works for positive floats. // Lot of useful algorithms in here, and helper utilities. // We want to make sure this code is not accidentally deleted. #![allow(dead_code)] use crate::util::*; use super::convert::*; use super::mantissa::Mantissa; use super::rounding::*; use super::shift::*; // FLOAT TYPE /// Extended precision floating-point type. /// /// Private implementation, exposed only for testing purposes. #[doc(hidden)] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct ExtendedFloat { /// Mantissa for the extended-precision float. pub mant: M, /// Binary exponent for the extended-precision float. pub exp: i32, } impl ExtendedFloat { // PROPERTIES perftools_inline!{ /// Get the mantissa component. pub fn mantissa(&self) -> M { self.mant }} perftools_inline!{ /// Get the exponent component. pub fn exponent(&self) -> i32 { self.exp }} // OPERATIONS perftools_inline!{ /// Multiply two normalized extended-precision floats, as if by `a*b`. /// /// The precision is maximal when the numbers are normalized, however, /// decent precision will occur as long as both values have high bits /// set. The result is not normalized. /// /// Algorithm: /// 1. Non-signed multiplication of mantissas (requires 2x as many bits as input). /// 2. Normalization of the result (not done here). /// 3. Addition of exponents. pub fn mul(&self, b: &ExtendedFloat) -> ExtendedFloat { // Logic check, values must be decently normalized prior to multiplication. debug_assert!((self.mant & M::HIMASK != M::ZERO) && (b.mant & M::HIMASK != M::ZERO)); // Extract high-and-low masks. let ah = self.mant >> M::HALF; let al = self.mant & M::LOMASK; let bh = b.mant >> M::HALF; let bl = b.mant & M::LOMASK; // Get our products let ah_bl = ah * bl; let al_bh = al * bh; let al_bl = al * bl; let ah_bh = ah * bh; let mut tmp = (ah_bl & M::LOMASK) + (al_bh & M::LOMASK) + (al_bl >> M::HALF); // round up tmp += M::ONE << (M::HALF-1); ExtendedFloat { mant: ah_bh + (ah_bl >> M::HALF) + (al_bh >> M::HALF) + (tmp >> M::HALF), exp: self.exp + b.exp + M::FULL } }} perftools_inline!{ /// Multiply in-place, as if by `a*b`. /// /// The result is not normalized. pub fn imul(&mut self, b: &ExtendedFloat) { *self = self.mul(b); }} // NORMALIZE perftools_inline!{ /// Get if extended-float is normalized, MSB is set. pub fn is_normalized(&self) -> bool { self.mant & M::NORMALIZED_MASK == M::NORMALIZED_MASK }} perftools_inline!{ /// Normalize float-point number. /// /// Shift the mantissa so the number of leading zeros is 0, or the value /// itself is 0. /// /// Get the number of bytes shifted. pub fn normalize(&mut self) -> u32 { // Note: // Using the cltz intrinsic via leading_zeros is way faster (~10x) // than shifting 1-bit at a time, via while loop, and also way // faster (~2x) than an unrolled loop that checks at 32, 16, 4, // 2, and 1 bit. // // Using a modulus of pow2 (which will get optimized to a bitwise // and with 0x3F or faster) is slightly slower than an if/then, // however, removing the if/then will likely optimize more branched // code as it removes conditional logic. // Calculate the number of leading zeros, and then zero-out // any overflowing bits, to avoid shl overflow when self.mant == 0. let shift = if self.mant.is_zero() { 0 } else { self.mant.leading_zeros() }; shl(self, shift); shift }} perftools_inline!{ /// Normalize floating-point number to n-bits away from the MSB. /// /// This may lead to lossy rounding, and will not use custom rounding /// rules to accommodate for this. pub fn normalize_to(&mut self, n: u32) -> i32 { debug_assert!(n <= M::BITS.as_u32(), "ExtendedFloat::normalize_to() attempting to shift beyond type size."); // Get the shift, with any of the higher bits removed. // This way, we can guarantee that we will not overflow // with the shl/shr. let leading = if self.mant.is_zero() { n } else { self.mant.leading_zeros() }; let shift = leading.as_i32() - n.as_i32(); if shift > 0 { // Need to shift left shl(self, shift); } else if shift < 0 { // Need to shift right. shr(self, -shift); } shift }} perftools_inline!{ /// Get normalized boundaries for float. pub fn normalized_boundaries(&self) -> (ExtendedFloat, ExtendedFloat) { let mut upper = ExtendedFloat { mant: (self.mant << 1) + M::ONE, exp: self.exp - 1, }; upper.normalize(); // Use a boolean hack to get 2 if they're equal, else 1, without // any branching. let is_hidden = self.mant == as_cast::(f64::HIDDEN_BIT_MASK); let l_shift: i32 = is_hidden as i32 + 1; let mut lower = ExtendedFloat { mant: (self.mant << l_shift) - M::ONE, exp: self.exp - l_shift, }; lower.mant <<= lower.exp - upper.exp; lower.exp = upper.exp; (lower, upper) }} // ROUND perftools_inline!{ /// Lossy round float-point number to native mantissa boundaries. pub(crate) fn round_to_native(&mut self, cb: Cb) where F: FloatRounding, Cb: FnOnce(&mut ExtendedFloat, i32) { round_to_native::(self, cb) }} perftools_inline!{ /// Lossy round float-point number to f32 mantissa boundaries. pub(crate) fn round_to_f32(&mut self, cb: Cb) where f32: FloatRounding, Cb: FnOnce(&mut ExtendedFloat, i32) { self.round_to_native::(cb) }} perftools_inline!{ /// Lossy round float-point number to f64 mantissa boundaries. pub(crate) fn round_to_f64(&mut self, cb: Cb) where f64: FloatRounding, Cb: FnOnce(&mut ExtendedFloat, i32) { self.round_to_native::(cb) }} // FROM perftools_inline!{ /// Create extended float from 8-bit unsigned integer. pub fn from_int(i: T) -> ExtendedFloat { from_int(i) }} perftools_inline!{ /// Create extended float from 8-bit unsigned integer. pub fn from_u8(i: u8) -> ExtendedFloat { Self::from_int(i) }} perftools_inline!{ /// Create extended float from 16-bit unsigned integer. pub fn from_u16(i: u16) -> ExtendedFloat { Self::from_int(i) }} perftools_inline!{ /// Create extended float from 32-bit unsigned integer. pub fn from_u32(i: u32) -> ExtendedFloat { Self::from_int(i) }} perftools_inline!{ /// Create extended float from 64-bit unsigned integer. pub fn from_u64(i: u64) -> ExtendedFloat { Self::from_int(i) }} perftools_inline!{ /// Create extended float from native float. pub fn from_float(f: F) -> ExtendedFloat { from_float(f) }} perftools_inline!{ /// Create extended float from 32-bit float. pub fn from_f32(f: f32) -> ExtendedFloat { Self::from_float(f) }} perftools_inline!{ /// Create extended float from 64-bit float. pub fn from_f64(f: f64) -> ExtendedFloat { Self::from_float(f) }} // INTO perftools_inline!{ /// Convert into lower-precision native float. pub fn into_float>(self) -> F { #[cfg(not(feature = "rounding"))] { self.into_rounded_float::(RoundingKind::NearestTieEven, Sign::Positive) } #[cfg(feature = "rounding")] { self.into_rounded_float::(get_float_rounding(), Sign::Positive) } }} perftools_inline!{ /// Convert into lower-precision 32-bit float. pub fn into_f32(self) -> f32 where f32: FloatRounding { self.into_float() }} perftools_inline!{ /// Convert into lower-precision 64-bit float. pub fn into_f64(self) -> f64 where f64: FloatRounding { self.into_float() }} // INTO ROUNDED perftools_inline!{ /// Into rounded float where the rounding kind has been converted. pub(crate) fn into_rounded_float_impl(mut self, kind: RoundingKind) -> F where F: FloatRounding { // Normalize the actual float rounding here. let cb = match kind { RoundingKind::NearestTieEven => round_nearest_tie_even, RoundingKind::NearestTieAwayZero => round_nearest_tie_away_zero, RoundingKind::Upward => round_upward, RoundingKind::Downward => round_downward, _ => unreachable!() }; self.round_to_native::(cb); into_float(self) }} perftools_inline!{ /// Convert into lower-precision native float with custom rounding rules. pub fn into_rounded_float(self, kind: RoundingKind, sign: Sign) -> F where F: FloatRounding { self.into_rounded_float_impl(internal_rounding(kind, sign)) }} perftools_inline!{ /// Convert into lower-precision 32-bit float with custom rounding rules. pub fn into_rounded_f32(self, kind: RoundingKind, sign: Sign) -> f32 where f32: FloatRounding { self.into_rounded_float(kind, sign) }} perftools_inline!{ /// Convert into lower-precision 64-bit float with custom rounding rules. pub fn into_rounded_f64(self, kind: RoundingKind, sign: Sign) -> f64 where f64: FloatRounding { self.into_rounded_float(kind, sign) }} // AS perftools_inline!{ /// Convert to lower-precision native float. pub fn as_float>(&self) -> F { self.clone().into_float::() }} perftools_inline!{ /// Convert to lower-precision 32-bit float. pub fn as_f32(&self) -> f32 where f32: FloatRounding { self.as_float() }} perftools_inline!{ /// Convert to lower-precision 64-bit float. pub fn as_f64(&self) -> f64 where f64: FloatRounding { self.as_float() }} // AS ROUNDED perftools_inline!{ /// Convert to lower-precision native float with custom rounding rules. pub fn as_rounded_float(&self, kind: RoundingKind, sign: Sign) -> F where F: FloatRounding { self.clone().into_rounded_float::(kind, sign) }} perftools_inline!{ /// Convert to lower-precision 32-bit float with custom rounding rules. pub fn as_rounded_f32(&self, kind: RoundingKind, sign: Sign) -> f32 where f32: FloatRounding { self.as_rounded_float(kind, sign) }} perftools_inline!{ /// Convert to lower-precision 64-bit float with custom rounding rules. pub fn as_rounded_f64(&self, kind: RoundingKind, sign: Sign) -> f64 where f64: FloatRounding { self.as_rounded_float(kind, sign) }} } impl ExtendedFloat { perftools_inline!{ /// Create extended float from 64-bit unsigned integer. pub fn from_u128(i: u128) -> ExtendedFloat { Self::from_int(i) }} } // ALIASES /// Alias with ~80 bits of precision, 64 for the mantissa and 16 for exponent. pub type ExtendedFloat80 = ExtendedFloat; /// Alias with ~160 bits of precision, 128 for the mantissa and 32 for exponent. pub type ExtendedFloat160 = ExtendedFloat; // TESTS // ----- #[cfg(test)] mod tests { use super::*; use approx::assert_relative_eq; // NORMALIZE fn check_normalize(mant: u64, exp: i32, shift: u32, r_mant: u64, r_exp: i32) { let mut x = ExtendedFloat {mant: mant, exp: exp}; assert!(!x.is_normalized()); assert_eq!(x.normalize(), shift); assert_eq!(x, ExtendedFloat {mant: r_mant, exp: r_exp}); assert!(x.is_normalized() || x.mant.is_zero()); let mut x = ExtendedFloat {mant: mant as u128, exp: exp}; let shift = if shift == 0 { 0 } else { shift+64 }; let r_exp = if r_exp == 0 { 0 } else { r_exp-64 }; assert!(!x.is_normalized()); assert_eq!(x.normalize(), shift); assert_eq!(x, ExtendedFloat {mant: (r_mant as u128) << 64, exp: r_exp}); assert!(x.is_normalized() || x.mant.is_zero()); } #[test] fn normalize_test() { // F32 // 0 check_normalize(0, 0, 0, 0, 0); // min value check_normalize(1, -149, 63, 9223372036854775808, -212); // 1.0e-40 check_normalize(71362, -149, 47, 10043308644012916736, -196); // 1.0e-20 check_normalize(12379400, -90, 40, 13611294244890214400, -130); // 1.0 check_normalize(8388608, -23, 40, 9223372036854775808, -63); // 1e20 check_normalize(11368684, 43, 40, 12500000250510966784, 3); // max value check_normalize(16777213, 104, 40, 18446740775174668288, 64); // F64 // min value check_normalize(1, -1074, 63, 9223372036854775808, -1137); // 1.0e-250 check_normalize(6448907850777164, -883, 11, 13207363278391631872, -894); // 1.0e-150 check_normalize(7371020360979573, -551, 11, 15095849699286165504, -562); // 1.0e-45 check_normalize(6427752177035961, -202, 11, 13164036458569648128, -213); // 1.0e-40 check_normalize(4903985730770844, -185, 11, 10043362776618688512, -196); // 1.0e-20 check_normalize(6646139978924579, -119, 11, 13611294676837537792, -130); // 1.0 check_normalize(4503599627370496, -52, 11, 9223372036854775808, -63); // 1e20 check_normalize(6103515625000000, 14, 11, 12500000000000000000, 3); // 1e40 check_normalize(8271806125530277, 80, 11, 16940658945086007296, 69); // 1e150 check_normalize(5503284107318959, 446, 11, 11270725851789228032, 435); // 1e250 check_normalize(6290184345309700, 778, 11, 12882297539194265600, 767); // max value check_normalize(9007199254740991, 971, 11, 18446744073709549568, 960); } fn check_normalize_to(mant: u64, exp: i32, n: u32, shift: i32, r_mant: u64, r_exp: i32) { let mut x = ExtendedFloat {mant: mant, exp: exp}; assert_eq!(x.normalize_to(n), shift); assert_eq!(x, ExtendedFloat {mant: r_mant, exp: r_exp}); let mut x = ExtendedFloat {mant: mant as u128, exp: exp}; let shift = if shift == 0 { 0 } else { shift+64 }; let r_exp = if r_exp == 0 { 0 } else { r_exp-64 }; assert_eq!(x.normalize_to(n), shift); assert_eq!(x, ExtendedFloat {mant: (r_mant as u128) << 64, exp: r_exp}); } #[test] fn normalize_to_test() { // F32 // 0 check_normalize_to(0, 0, 0, 0, 0, 0); check_normalize_to(0, 0, 2, 0, 0, 0); // min value check_normalize_to(1, -149, 0, 63, 9223372036854775808, -212); check_normalize_to(1, -149, 2, 61, 2305843009213693952, -210); // 1.0e-40 check_normalize_to(71362, -149, 0, 47, 10043308644012916736, -196); check_normalize_to(71362, -149, 2, 45, 2510827161003229184, -194); // 1.0e-20 check_normalize_to(12379400, -90, 0, 40, 13611294244890214400, -130); check_normalize_to(12379400, -90, 2, 38, 3402823561222553600, -128); // 1.0 check_normalize_to(8388608, -23, 0, 40, 9223372036854775808, -63); check_normalize_to(8388608, -23, 2, 38, 2305843009213693952, -61); // 1e20 check_normalize_to(11368684, 43, 0, 40, 12500000250510966784, 3); check_normalize_to(11368684, 43, 2, 38, 3125000062627741696, 5); // max value check_normalize_to(16777213, 104, 0, 40, 18446740775174668288, 64); check_normalize_to(16777213, 104, 2, 38, 4611685193793667072, 66); // F64 // min value check_normalize_to(1, -1074, 0, 63, 9223372036854775808, -1137); check_normalize_to(1, -1074, 2, 61, 2305843009213693952, -1135); // 1.0e-250 check_normalize_to(6448907850777164, -883, 0, 11, 13207363278391631872, -894); check_normalize_to(6448907850777164, -883, 2, 9, 3301840819597907968, -892); // 1.0e-150 check_normalize_to(7371020360979573, -551, 0, 11, 15095849699286165504, -562); check_normalize_to(7371020360979573, -551, 2, 9, 3773962424821541376, -560); // 1.0e-45 check_normalize_to(6427752177035961, -202, 0, 11, 13164036458569648128, -213); check_normalize_to(6427752177035961, -202, 2, 9, 3291009114642412032, -211); // 1.0e-40 check_normalize_to(4903985730770844, -185, 0, 11, 10043362776618688512, -196); check_normalize_to(4903985730770844, -185, 2, 9, 2510840694154672128, -194); // 1.0e-20 check_normalize_to(6646139978924579, -119, 0, 11, 13611294676837537792, -130); check_normalize_to(6646139978924579, -119, 2, 9, 3402823669209384448, -128); // 1.0 check_normalize_to(4503599627370496, -52, 0, 11, 9223372036854775808, -63); check_normalize_to(4503599627370496, -52, 2, 9, 2305843009213693952, -61); // 1e20 check_normalize_to(6103515625000000, 14, 0 ,11, 12500000000000000000, 3); check_normalize_to(6103515625000000, 14, 2, 9, 3125000000000000000, 5); // 1e40 check_normalize_to(8271806125530277, 80, 0, 11, 16940658945086007296, 69); check_normalize_to(8271806125530277, 80, 2, 9, 4235164736271501824, 71); // 1e150 check_normalize_to(5503284107318959, 446, 0, 11, 11270725851789228032, 435); check_normalize_to(5503284107318959, 446, 2, 9, 2817681462947307008, 437); // 1e250 check_normalize_to(6290184345309700, 778, 0, 11, 12882297539194265600, 767); check_normalize_to(6290184345309700, 778, 2, 9, 3220574384798566400, 769); // max value check_normalize_to(9007199254740991, 971, 0, 11, 18446744073709549568, 960); check_normalize_to(9007199254740991, 971, 2, 9, 4611686018427387392, 962); } #[test] fn normalized_boundaries_test() { let fp = ExtendedFloat80 {mant: 4503599627370496, exp: -50}; let u = ExtendedFloat80 {mant: 9223372036854775296, exp: -61}; let l = ExtendedFloat80 {mant: 9223372036854776832, exp: -61}; let (upper, lower) = fp.normalized_boundaries(); assert_eq!(upper, u); assert_eq!(lower, l); } // ROUND fn check_round_to_f32(mant: u64, exp: i32, r_mant: u64, r_exp: i32) { let mut x = ExtendedFloat {mant: mant, exp: exp}; x.round_to_f32(round_nearest_tie_even); assert_eq!(x, ExtendedFloat {mant: r_mant, exp: r_exp}); let mut x = ExtendedFloat {mant: (mant as u128) << 64, exp: exp-64}; x.round_to_f32(round_nearest_tie_even); assert_eq!(x, ExtendedFloat {mant: r_mant as u128, exp: r_exp}); } #[test] fn round_to_f32_test() { // This is lossy, so some of these values are **slightly** rounded. // underflow check_round_to_f32(9223372036854775808, -213, 0, -149); // min value check_round_to_f32(9223372036854775808, -212, 1, -149); // 1.0e-40 check_round_to_f32(10043308644012916736, -196, 71362, -149); // 1.0e-20 check_round_to_f32(13611294244890214400, -130, 12379400, -90); // 1.0 check_round_to_f32(9223372036854775808, -63, 8388608, -23); // 1e20 check_round_to_f32(12500000250510966784, 3, 11368684, 43); // max value check_round_to_f32(18446740775174668288, 64, 16777213, 104); // overflow check_round_to_f32(18446740775174668288, 65, 16777213, 105); } fn check_round_to_f64(mant: u64, exp: i32, r_mant: u64, r_exp: i32) { let mut x = ExtendedFloat {mant: mant, exp: exp}; x.round_to_f64(round_nearest_tie_even); assert_eq!(x, ExtendedFloat {mant: r_mant, exp: r_exp}); let mut x = ExtendedFloat {mant: (mant as u128) << 64, exp: exp-64}; x.round_to_f64(round_nearest_tie_even); assert_eq!(x, ExtendedFloat {mant: r_mant as u128, exp: r_exp}); } #[test] fn round_to_f64_test() { // This is lossy, so some of these values are **slightly** rounded. // underflow check_round_to_f64(9223372036854775808, -1138, 0, -1074); // min value check_round_to_f64(9223372036854775808, -1137, 1, -1074); // 1.0e-250 check_round_to_f64(15095849699286165504, -562, 7371020360979573, -551); // 1.0e-150 check_round_to_f64(15095849699286165504, -562, 7371020360979573, -551); // 1.0e-45 check_round_to_f64(13164036458569648128, -213, 6427752177035961, -202); // 1.0e-40 check_round_to_f64(10043362776618688512, -196, 4903985730770844, -185); // 1.0e-20 check_round_to_f64(13611294676837537792, -130, 6646139978924579, -119); // 1.0 check_round_to_f64(9223372036854775808, -63, 4503599627370496, -52); // 1e20 check_round_to_f64(12500000000000000000, 3, 6103515625000000, 14); // 1e40 check_round_to_f64(16940658945086007296, 69, 8271806125530277, 80); // 1e150 check_round_to_f64(11270725851789228032, 435, 5503284107318959, 446); // 1e250 check_round_to_f64(12882297539194265600, 767, 6290184345309700, 778); // max value check_round_to_f64(18446744073709549568, 960, 9007199254740991, 971); // Bug fixes // 1.2345e-308 check_round_to_f64(10234494226754558294, -1086, 2498655817078750, -1074) } // FROM #[test] fn from_int_test() { // 0 assert_eq!(ExtendedFloat80::from_u8(0), (0, 0).into()); assert_eq!(ExtendedFloat80::from_u16(0), (0, 0).into()); assert_eq!(ExtendedFloat80::from_u32(0), (0, 0).into()); assert_eq!(ExtendedFloat80::from_u64(0), (0, 0).into()); assert_eq!(ExtendedFloat160::from_u128(0), (0, 0).into()); // 1 assert_eq!(ExtendedFloat80::from_u8(1), (1, 0).into()); assert_eq!(ExtendedFloat80::from_u16(1), (1, 0).into()); assert_eq!(ExtendedFloat80::from_u32(1), (1, 0).into()); assert_eq!(ExtendedFloat80::from_u64(1), (1, 0).into()); assert_eq!(ExtendedFloat160::from_u128(1), (1, 0).into()); // (2^8-1) 255 assert_eq!(ExtendedFloat80::from_u8(255), (255, 0).into()); assert_eq!(ExtendedFloat80::from_u16(255), (255, 0).into()); assert_eq!(ExtendedFloat80::from_u32(255), (255, 0).into()); assert_eq!(ExtendedFloat80::from_u64(255), (255, 0).into()); assert_eq!(ExtendedFloat160::from_u128(255), (255, 0).into()); // (2^16-1) 65535 assert_eq!(ExtendedFloat80::from_u16(65535), (65535, 0).into()); assert_eq!(ExtendedFloat80::from_u32(65535), (65535, 0).into()); assert_eq!(ExtendedFloat80::from_u64(65535), (65535, 0).into()); assert_eq!(ExtendedFloat160::from_u128(65535), (65535, 0).into()); // (2^32-1) 4294967295 assert_eq!(ExtendedFloat80::from_u32(4294967295), (4294967295, 0).into()); assert_eq!(ExtendedFloat80::from_u64(4294967295), (4294967295, 0).into()); assert_eq!(ExtendedFloat160::from_u128(4294967295), (4294967295, 0).into()); // (2^64-1) 18446744073709551615 assert_eq!(ExtendedFloat80::from_u64(18446744073709551615), (18446744073709551615, 0).into()); assert_eq!(ExtendedFloat160::from_u128(18446744073709551615), (18446744073709551615, 0).into()); // (2^128-1) 340282366920938463463374607431768211455 assert_eq!(ExtendedFloat160::from_u128(340282366920938463463374607431768211455), (340282366920938463463374607431768211455, 0).into()); } #[test] fn from_f32_test() { assert_eq!(ExtendedFloat80::from_f32(0.), (0, -149).into()); assert_eq!(ExtendedFloat80::from_f32(-0.), (0, -149).into()); assert_eq!(ExtendedFloat80::from_f32(1e-45), (1, -149).into()); assert_eq!(ExtendedFloat80::from_f32(1e-40), (71362, -149).into()); assert_eq!(ExtendedFloat80::from_f32(2e-40), (142725, -149).into()); assert_eq!(ExtendedFloat80::from_f32(1e-20), (12379400, -90).into()); assert_eq!(ExtendedFloat80::from_f32(2e-20), (12379400, -89).into()); assert_eq!(ExtendedFloat80::from_f32(1.0), (8388608, -23).into()); assert_eq!(ExtendedFloat80::from_f32(2.0), (8388608, -22).into()); assert_eq!(ExtendedFloat80::from_f32(1e20), (11368684, 43).into()); assert_eq!(ExtendedFloat80::from_f32(2e20), (11368684, 44).into()); assert_eq!(ExtendedFloat80::from_f32(3.402823e38), (16777213, 104).into()); } #[test] fn from_f64_test() { assert_eq!(ExtendedFloat80::from_f64(0.), (0, -1074).into()); assert_eq!(ExtendedFloat80::from_f64(-0.), (0, -1074).into()); assert_eq!(ExtendedFloat80::from_f64(5e-324), (1, -1074).into()); assert_eq!(ExtendedFloat80::from_f64(1e-250), (6448907850777164, -883).into()); assert_eq!(ExtendedFloat80::from_f64(1e-150), (7371020360979573, -551).into()); assert_eq!(ExtendedFloat80::from_f64(1e-45), (6427752177035961, -202).into()); assert_eq!(ExtendedFloat80::from_f64(1e-40), (4903985730770844, -185).into()); assert_eq!(ExtendedFloat80::from_f64(2e-40), (4903985730770844, -184).into()); assert_eq!(ExtendedFloat80::from_f64(1e-20), (6646139978924579, -119).into()); assert_eq!(ExtendedFloat80::from_f64(2e-20), (6646139978924579, -118).into()); assert_eq!(ExtendedFloat80::from_f64(1.0), (4503599627370496, -52).into()); assert_eq!(ExtendedFloat80::from_f64(2.0), (4503599627370496, -51).into()); assert_eq!(ExtendedFloat80::from_f64(1e20), (6103515625000000, 14).into()); assert_eq!(ExtendedFloat80::from_f64(2e20), (6103515625000000, 15).into()); assert_eq!(ExtendedFloat80::from_f64(1e40), (8271806125530277, 80).into()); assert_eq!(ExtendedFloat80::from_f64(2e40), (8271806125530277, 81).into()); assert_eq!(ExtendedFloat80::from_f64(1e150), (5503284107318959, 446).into()); assert_eq!(ExtendedFloat80::from_f64(1e250), (6290184345309700, 778).into()); assert_eq!(ExtendedFloat80::from_f64(1.7976931348623157e308), (9007199254740991, 971).into()); } fn assert_normalized_eq(mut x: ExtendedFloat, mut y: ExtendedFloat) { x.normalize(); y.normalize(); assert_eq!(x, y); } #[test] fn from_float() { let values: [f32; 26] = [ 1e-40, 2e-40, 1e-35, 2e-35, 1e-30, 2e-30, 1e-25, 2e-25, 1e-20, 2e-20, 1e-15, 2e-15, 1e-10, 2e-10, 1e-5, 2e-5, 1.0, 2.0, 1e5, 2e5, 1e10, 2e10, 1e15, 2e15, 1e20, 2e20, ]; for value in values.iter() { assert_normalized_eq(ExtendedFloat80::from_f32(*value), ExtendedFloat80::from_f64(*value as f64)); assert_normalized_eq(ExtendedFloat160::from_f32(*value), ExtendedFloat160::from_f64(*value as f64)); } } // TO // Sample of interesting numbers to check during standard test builds. const INTEGERS: [u64; 32] = [ 0, // 0x0 1, // 0x1 7, // 0x7 15, // 0xF 112, // 0x70 119, // 0x77 127, // 0x7F 240, // 0xF0 247, // 0xF7 255, // 0xFF 2032, // 0x7F0 2039, // 0x7F7 2047, // 0x7FF 4080, // 0xFF0 4087, // 0xFF7 4095, // 0xFFF 65520, // 0xFFF0 65527, // 0xFFF7 65535, // 0xFFFF 1048560, // 0xFFFF0 1048567, // 0xFFFF7 1048575, // 0xFFFFF 16777200, // 0xFFFFF0 16777207, // 0xFFFFF7 16777215, // 0xFFFFFF 268435440, // 0xFFFFFF0 268435447, // 0xFFFFFF7 268435455, // 0xFFFFFFF 4294967280, // 0xFFFFFFF0 4294967287, // 0xFFFFFFF7 4294967295, // 0xFFFFFFFF 18446744073709551615, // 0xFFFFFFFFFFFFFFFF ]; #[test] fn to_f32_test() { // underflow let x = ExtendedFloat80 {mant: 9223372036854775808, exp: -213}; assert_eq!(x.into_f32(), 0.0); // min value let x = ExtendedFloat80 {mant: 9223372036854775808, exp: -212}; assert_eq!(x.into_f32(), 1e-45); // 1.0e-40 let x = ExtendedFloat80 {mant: 10043308644012916736, exp: -196}; assert_eq!(x.into_f32(), 1e-40); // 1.0e-20 let x = ExtendedFloat80 {mant: 13611294244890214400, exp: -130}; assert_eq!(x.into_f32(), 1e-20); // 1.0 let x = ExtendedFloat80 {mant: 9223372036854775808, exp: -63}; assert_eq!(x.into_f32(), 1.0); // 1e20 let x = ExtendedFloat80 {mant: 12500000250510966784, exp: 3}; assert_eq!(x.into_f32(), 1e20); // max value let x = ExtendedFloat80 {mant: 18446740775174668288, exp: 64}; assert_eq!(x.into_f32(), 3.402823e38); // almost max, high exp let x = ExtendedFloat80 {mant: 1048575, exp: 108}; assert_eq!(x.into_f32(), 3.4028204e38); // max value + 1 let x = ExtendedFloat80 {mant: 16777216, exp: 104}; assert_eq!(x.into_f32(), f32::INFINITY); // max value + 1 let x = ExtendedFloat80 {mant: 1048576, exp: 108}; assert_eq!(x.into_f32(), f32::INFINITY); // 1e40 let x = ExtendedFloat80 {mant: 16940658945086007296, exp: 69}; assert_eq!(x.into_f32(), f32::INFINITY); // Integers. for int in INTEGERS.iter() { let fp = ExtendedFloat80 {mant: *int, exp: 0}; assert_eq!(fp.into_f32(), *int as f32, "{:?} as f32", *int); } } #[test] fn to_f64_test() { // underflow let x = ExtendedFloat80 {mant: 9223372036854775808, exp: -1138}; assert_relative_eq!(x.into_f64(), 0.0); // min value let x = ExtendedFloat80 {mant: 9223372036854775808, exp: -1137}; assert_relative_eq!(x.into_f64(), 5e-324); // 1.0e-250 let x = ExtendedFloat80 {mant: 13207363278391631872, exp: -894}; assert_relative_eq!(x.into_f64(), 1e-250); // 1.0e-150 let x = ExtendedFloat80 {mant: 15095849699286165504, exp: -562}; assert_relative_eq!(x.into_f64(), 1e-150); // 1.0e-45 let x = ExtendedFloat80 {mant: 13164036458569648128, exp: -213}; assert_relative_eq!(x.into_f64(), 1e-45); // 1.0e-40 let x = ExtendedFloat80 {mant: 10043362776618688512, exp: -196}; assert_relative_eq!(x.into_f64(), 1e-40); // 1.0e-20 let x = ExtendedFloat80 {mant: 13611294676837537792, exp: -130}; assert_relative_eq!(x.into_f64(), 1e-20); // 1.0 let x = ExtendedFloat80 {mant: 9223372036854775808, exp: -63}; assert_relative_eq!(x.into_f64(), 1.0); // 1e20 let x = ExtendedFloat80 {mant: 12500000000000000000, exp: 3}; assert_relative_eq!(x.into_f64(), 1e20); // 1e40 let x = ExtendedFloat80 {mant: 16940658945086007296, exp: 69}; assert_relative_eq!(x.into_f64(), 1e40); // 1e150 let x = ExtendedFloat80 {mant: 11270725851789228032, exp: 435}; assert_relative_eq!(x.into_f64(), 1e150); // 1e250 let x = ExtendedFloat80 {mant: 12882297539194265600, exp: 767}; assert_relative_eq!(x.into_f64(), 1e250); // max value let x = ExtendedFloat80 {mant: 9007199254740991, exp: 971}; assert_relative_eq!(x.into_f64(), 1.7976931348623157e308); // max value let x = ExtendedFloat80 {mant: 18446744073709549568, exp: 960}; assert_relative_eq!(x.into_f64(), 1.7976931348623157e308); // overflow let x = ExtendedFloat80 {mant: 9007199254740992, exp: 971}; assert_relative_eq!(x.into_f64(), f64::INFINITY); // overflow let x = ExtendedFloat80 {mant: 18446744073709549568, exp: 961}; assert_relative_eq!(x.into_f64(), f64::INFINITY); // Underflow // Adapted from failures in strtod. let x = ExtendedFloat80 { exp: -1139, mant: 18446744073709550712 }; assert_relative_eq!(x.into_f64(), 0.0); let x = ExtendedFloat80 { exp: -1139, mant: 18446744073709551460 }; assert_relative_eq!(x.into_f64(), 0.0); let x = ExtendedFloat80 { exp: -1138, mant: 9223372036854776103 }; assert_relative_eq!(x.into_f64(), 5e-324); // Integers. for int in INTEGERS.iter() { let fp = ExtendedFloat80 {mant: *int, exp: 0}; assert_eq!(fp.into_f64(), *int as f64, "{:?} as f64", *int); } } #[test] fn to_rounded_f32_test() { // Just check it compiles, we already check the underlying algorithms. let x = ExtendedFloat80 {mant: 9223372036854775808, exp: -63}; assert_eq!(x.as_rounded_f32(RoundingKind::NearestTieEven, Sign::Positive), 1.0); assert_eq!(x.as_rounded_f32(RoundingKind::NearestTieAwayZero, Sign::Positive), 1.0); assert_eq!(x.as_rounded_f32(RoundingKind::TowardPositiveInfinity, Sign::Positive), 1.0); assert_eq!(x.as_rounded_f32(RoundingKind::TowardNegativeInfinity, Sign::Positive), 1.0); assert_eq!(x.as_rounded_f32(RoundingKind::TowardZero, Sign::Positive), 1.0); } #[test] fn to_rounded_f64_test() { // Just check it compiles, we already check the underlying algorithms. let x = ExtendedFloat80 {mant: 9223372036854775808, exp: -63}; assert_eq!(x.as_rounded_f64(RoundingKind::NearestTieEven, Sign::Positive), 1.0); assert_eq!(x.as_rounded_f64(RoundingKind::NearestTieAwayZero, Sign::Positive), 1.0); assert_eq!(x.as_rounded_f64(RoundingKind::TowardPositiveInfinity, Sign::Positive), 1.0); assert_eq!(x.as_rounded_f64(RoundingKind::TowardNegativeInfinity, Sign::Positive), 1.0); assert_eq!(x.as_rounded_f64(RoundingKind::TowardZero, Sign::Positive), 1.0); } #[test] #[ignore] fn to_f32_full_test() { // Use exhaustive search to ensure both lossy and unlossy items are checked. // 23-bits of precision, so go from 0-32. for int in 0..u32::max_value() { let fp = ExtendedFloat80 {mant: int as u64, exp: 0}; assert_eq!(fp.into_f32(), int as f32, "ExtendedFloat80 {:?} as f32", int); let fp = ExtendedFloat160 {mant: int as u128, exp: 0}; assert_eq!(fp.into_f32(), int as f32, "ExtendedFloat160 {:?} as f64", int); } } #[test] #[ignore] fn to_f64_full_test() { // Use exhaustive search to ensure both lossy and unlossy items are checked. const U32_MAX: u64 = u32::max_value() as u64; const POW2_52: u64 = 4503599627370496; const START: u64 = POW2_52 - U32_MAX / 2; const END: u64 = START + U32_MAX; for int in START..END { let fp = ExtendedFloat80 {mant: int, exp: 0}; assert_eq!(fp.into_f64(), int as f64, "ExtendedFloat80 {:?} as f64", int); let fp = ExtendedFloat160 {mant: int as u128, exp: 0}; assert_eq!(fp.into_f64(), int as f64, "ExtendedFloat160 {:?} as f64", int); } } // OPERATIONS fn check_mul(a: ExtendedFloat, b: ExtendedFloat, c: ExtendedFloat) { let r = a.mul(&b); assert_eq!(r, c); } #[test] fn mul_test() { // Normalized (64-bit mantissa) let a = ExtendedFloat80 {mant: 13164036458569648128, exp: -213}; let b = ExtendedFloat80 {mant: 9223372036854775808, exp: -62}; let c = ExtendedFloat80 {mant: 6582018229284824064, exp: -211}; check_mul(a, b, c); // Normalized (128-bit mantissa) let a = ExtendedFloat160 {mant: 242833611528216130005140556221773774848, exp: -277}; let b = ExtendedFloat160 {mant: 170141183460469231731687303715884105728, exp: -126}; let c = ExtendedFloat160 {mant: 121416805764108065002570278110886887424, exp: -275}; check_mul(a, b, c); // Check with integers // 64-bit mantissa let mut a = ExtendedFloat80::from_u8(10); let mut b = ExtendedFloat80::from_u8(10); a.normalize(); b.normalize(); assert_eq!(a.mul(&b).into_f64(), 100.0); // 128-bit mantissa let mut a = ExtendedFloat160::from_u8(10); let mut b = ExtendedFloat160::from_u8(10); a.normalize(); b.normalize(); assert_eq!(a.mul(&b).into_f64(), 100.0); // Check both values need high bits set. let a = ExtendedFloat80 { mant: 1 << 32, exp: -31 }; let b = ExtendedFloat80 { mant: 1 << 32, exp: -31 }; assert_eq!(a.mul(&b).into_f64(), 4.0); // Check both values need high bits set. let a = ExtendedFloat80 { mant: 10 << 31, exp: -31 }; let b = ExtendedFloat80 { mant: 10 << 31, exp: -31 }; assert_eq!(a.mul(&b).into_f64(), 100.0); } fn check_imul(mut a: ExtendedFloat, b: ExtendedFloat, c: ExtendedFloat) { a.imul(&b); assert_eq!(a, c); } #[test] fn imul_test() { // Normalized (64-bit mantissa) let a = ExtendedFloat80 {mant: 13164036458569648128, exp: -213}; let b = ExtendedFloat80 {mant: 9223372036854775808, exp: -62}; let c = ExtendedFloat80 {mant: 6582018229284824064, exp: -211}; check_imul(a, b, c); // Normalized (128-bit mantissa) let a = ExtendedFloat160 {mant: 242833611528216130005140556221773774848, exp: -277}; let b = ExtendedFloat160 {mant: 170141183460469231731687303715884105728, exp: -126}; let c = ExtendedFloat160 {mant: 121416805764108065002570278110886887424, exp: -275}; check_imul(a, b, c); // Check with integers // 64-bit mantissa let mut a = ExtendedFloat80::from_u8(10); let mut b = ExtendedFloat80::from_u8(10); a.normalize(); b.normalize(); a.imul(&b); assert_eq!(a.into_f64(), 100.0); // 128-bit mantissa let mut a = ExtendedFloat160::from_u8(10); let mut b = ExtendedFloat160::from_u8(10); a.normalize(); b.normalize(); a.imul(&b); assert_eq!(a.into_f64(), 100.0); // Check both values need high bits set. let mut a = ExtendedFloat80 { mant: 1 << 32, exp: -31 }; let b = ExtendedFloat80 { mant: 1 << 32, exp: -31 }; a.imul(&b); assert_eq!(a.into_f64(), 4.0); // Check both values need high bits set. let mut a = ExtendedFloat80 { mant: 10 << 31, exp: -31 }; let b = ExtendedFloat80 { mant: 10 << 31, exp: -31 }; a.imul(&b); assert_eq!(a.into_f64(), 100.0); } } lexical-core-0.7.6/src/float/mantissa.rs000075500000000000000000000027000000000000000162450ustar 00000000000000//! Type trait for the mantissa of an extended float. use crate::util::*; /// Type trait for the mantissa type. pub trait Mantissa: UnsignedInteger { /// Mask for the left-most bit, to check if the value is normalized. const NORMALIZED_MASK: Self; /// Mask to extract the high bits from the integer. const HIMASK: Self; /// Mask to extract the low bits from the integer. const LOMASK: Self; /// Full size of the integer, in bits. const FULL: i32 = Self::BITS as i32; /// Half size of the integer, in bits. const HALF: i32 = Self::FULL / 2; } impl Mantissa for u8 { const NORMALIZED_MASK: u8 = 0x80; const HIMASK: u8 = 0xF0; const LOMASK: u8 = 0x0F; } impl Mantissa for u16 { const NORMALIZED_MASK: u16 = 0x8000; const HIMASK: u16 = 0xFF00; const LOMASK: u16 = 0x00FF; } impl Mantissa for u32 { const NORMALIZED_MASK: u32 = 0x80000000; const HIMASK: u32 = 0xFFFF0000; const LOMASK: u32 = 0x0000FFFF; } impl Mantissa for u64 { const NORMALIZED_MASK: u64 = 0x8000000000000000; const HIMASK: u64 = 0xFFFFFFFF00000000; const LOMASK: u64 = 0x00000000FFFFFFFF; } impl Mantissa for u128 { const NORMALIZED_MASK: u128 = 0x80000000000000000000000000000000; const HIMASK: u128 = 0xFFFFFFFFFFFFFFFF0000000000000000; const LOMASK: u128 = 0x0000000000000000FFFFFFFFFFFFFFFF; } lexical-core-0.7.6/src/float/mod.rs000075500000000000000000000007360000000000000152140ustar 00000000000000//! Extended-precision floating-point type. // Hide implementation details. pub(crate) mod convert; pub(crate) mod float; pub(crate) mod mantissa; pub(crate) mod rounding; pub(crate) mod shift; // Re-export the extended-precision floating-point type. pub use self::float::{ExtendedFloat, ExtendedFloat80, ExtendedFloat160}; pub use self::mantissa::Mantissa; pub use self::rounding::{FloatRounding}; #[cfg(feature = "correct")] pub(crate) use self::rounding::global_rounding; lexical-core-0.7.6/src/float/rounding.rs000075500000000000000000000475000000000000000162620ustar 00000000000000//! Defines rounding schemes for floating-point numbers. use crate::util::*; use super::float::ExtendedFloat; use super::mantissa::Mantissa; use super::shift::*; // GENERIC // ------- // NEAREST ROUNDING // Shift right N-bytes and round to the nearest. // // Return if we are above halfway and if we are halfway. perftools_inline!{ pub(crate) fn round_nearest(fp: &mut ExtendedFloat, shift: i32) -> (bool, bool) where M: Mantissa { // Extract the truncated bits using mask. // Calculate if the value of the truncated bits are either above // the mid-way point, or equal to it. // // For example, for 4 truncated bytes, the mask would be b1111 // and the midway point would be b1000. let mask: M = lower_n_mask(as_cast(shift)); let halfway: M = lower_n_halfway(as_cast(shift)); let truncated_bits = fp.mant & mask; let is_above = truncated_bits > halfway; let is_halfway = truncated_bits == halfway; // Bit shift so the leading bit is in the hidden bit. overflowing_shr(fp, shift); (is_above, is_halfway) }} // Tie rounded floating point to event. perftools_inline!{ pub(crate) fn tie_even(fp: &mut ExtendedFloat, is_above: bool, is_halfway: bool) where M: Mantissa { // Extract the last bit after shifting (and determine if it is odd). let is_odd = fp.mant & M::ONE == M::ONE; // Calculate if we need to roundup. // We need to roundup if we are above halfway, or if we are odd // and at half-way (need to tie-to-even). if is_above || (is_odd && is_halfway) { fp.mant += M::ONE; } }} // Shift right N-bytes and round nearest, tie-to-even. // // Floating-point arithmetic uses round to nearest, ties to even, // which rounds to the nearest value, if the value is halfway in between, // round to an even value. perftools_inline!{ pub(crate) fn round_nearest_tie_even(fp: &mut ExtendedFloat, shift: i32) where M: Mantissa { let (is_above, is_halfway) = round_nearest(fp, shift); tie_even(fp, is_above, is_halfway); }} // Tie rounded floating point away from zero. perftools_inline!{ pub(crate) fn tie_away_zero(fp: &mut ExtendedFloat, is_above: bool, is_halfway: bool) where M: Mantissa { // Calculate if we need to roundup. // We need to roundup if we are halfway or above halfway, // since the value is always positive and we need to round away // from zero. if is_above || is_halfway { fp.mant += M::ONE; } }} // Shift right N-bytes and round nearest, tie-away-zero. // // Floating-point arithmetic defines round to nearest, ties away from zero, // which rounds to the nearest value, if the value is halfway in between, // ties away from zero. perftools_inline!{ pub(crate) fn round_nearest_tie_away_zero(fp: &mut ExtendedFloat, shift: i32) where M: Mantissa { let (is_above, is_halfway) = round_nearest(fp, shift); tie_away_zero(fp, is_above, is_halfway); }} // DIRECTED ROUNDING // Shift right N-bytes and round towards a direction. // // Return if we have any truncated bytes. perftools_inline!{ pub(crate) fn round_toward(fp: &mut ExtendedFloat, shift: i32) -> bool where M: Mantissa { let mask: M = lower_n_mask(as_cast(shift)); let truncated_bits = fp.mant & mask; // Bit shift so the leading bit is in the hidden bit. overflowing_shr(fp, shift); truncated_bits != M::ZERO }} // Round up. perftools_inline!{ pub(crate) fn upward(fp: &mut ExtendedFloat, is_truncated: bool) where M: Mantissa { if is_truncated { fp.mant += M::ONE; } }} // Shift right N-bytes and round toward infinity. // // Floating-point arithmetic defines round toward infinity, which rounds // towards positive infinity. perftools_inline!{ pub(crate) fn round_upward(fp: &mut ExtendedFloat, shift: i32) where M: Mantissa { // If the truncated bits are non-zero, that is, any rounding error occurred, // round-up. let is_truncated = round_toward(fp, shift); upward(fp, is_truncated); }} // Round down. perftools_inline!{ pub(crate) fn downard(_: &mut ExtendedFloat, _: bool) where M: Mantissa {}} // Shift right N-bytes and round toward zero. // // Floating-point arithmetic defines round toward zero, which rounds // towards positive zero. perftools_inline!{ pub(crate) fn round_downward(fp: &mut ExtendedFloat, shift: i32) where M: Mantissa { // Bit shift so the leading bit is in the hidden bit. // No rounding schemes, so we just ignore everything else. let is_truncated = round_toward(fp, shift); downard(fp, is_truncated); }} // NATIVE FLOAT // ------------ // FLOAT ROUNDING /// Trait to round extended-precision floats to native representations. pub trait FloatRounding: Float { /// Default number of bits to shift (or 64 - mantissa size - 1). const DEFAULT_SHIFT: i32; /// Mask to determine if a full-carry occurred (1 in bit above hidden bit). const CARRY_MASK: M; } // Literals don't work for generic types, we need to use this as a hack. macro_rules! float_rounding_f32 { ($($t:tt)*) => ($( impl FloatRounding<$t> for f32 { const DEFAULT_SHIFT: i32 = $t::FULL - f32::MANTISSA_SIZE - 1; const CARRY_MASK: $t = 0x1000000; } )*) } float_rounding_f32! { u64 u128 } // Literals don't work for generic types, we need to use this as a hack. macro_rules! float_rounding_f64 { ($($t:tt)*) => ($( impl FloatRounding<$t> for f64 { const DEFAULT_SHIFT: i32 = $t::FULL - f64::MANTISSA_SIZE - 1; const CARRY_MASK: $t = 0x20000000000000; } )*) } float_rounding_f64! { u64 u128 } // ROUND TO FLOAT // Shift the ExtendedFloat fraction to the fraction bits in a native float. // // Floating-point arithmetic uses round to nearest, ties to even, // which rounds to the nearest value, if the value is halfway in between, // round to an even value. perftools_inline!{ pub(crate) fn round_to_float(fp: &mut ExtendedFloat, cb: Cb) where T: FloatRounding, M: Mantissa, Cb: FnOnce(&mut ExtendedFloat, i32) { // Calculate the difference to allow a single calculation // rather than a loop, to minimize the number of ops required. // This does underflow detection. let final_exp = fp.exp + T::DEFAULT_SHIFT; if final_exp < T::DENORMAL_EXPONENT { // We would end up with a denormal exponent, try to round to more // digits. Only shift right if we can avoid zeroing out the value, // which requires the exponent diff to be < M::BITS. The value // is already normalized, so we shouldn't have any issue zeroing // out the value. let diff = T::DENORMAL_EXPONENT - fp.exp; if diff <= M::FULL { // We can avoid underflow, can get a valid representation. cb(fp, diff); } else { // Certain underflow, assign literal 0s. fp.mant = M::ZERO; fp.exp = 0; } } else { cb(fp, T::DEFAULT_SHIFT); } if fp.mant & T::CARRY_MASK == T::CARRY_MASK { // Roundup carried over to 1 past the hidden bit. shr(fp, 1); } }} // AVOID OVERFLOW/UNDERFLOW // Avoid overflow for large values, shift left as needed. // // Shift until a 1-bit is in the hidden bit, if the mantissa is not 0. perftools_inline!{ pub(crate) fn avoid_overflow(fp: &mut ExtendedFloat) where T: FloatRounding, M: Mantissa { // Calculate the difference to allow a single calculation // rather than a loop, minimizing the number of ops required. if fp.exp >= T::MAX_EXPONENT { let diff = fp.exp - T::MAX_EXPONENT; if diff <= T::MANTISSA_SIZE { // Our overflow mask needs to start at the hidden bit, or at // `T::MANTISSA_SIZE+1`, and needs to have `diff+1` bits set, // to see if our value overflows. let bit = as_cast(T::MANTISSA_SIZE+1); let n = as_cast(diff+1); let mask: M = internal_n_mask(bit, n); if (fp.mant & mask).is_zero() { // If we have no 1-bit in the hidden-bit position, // which is index 0, we need to shift 1. let shift = diff + 1; shl(fp, shift); } } } }} // ROUND TO NATIVE // Round an extended-precision float to a native float representation. perftools_inline!{ pub(crate) fn round_to_native(fp: &mut ExtendedFloat, cb: Cb) where T: FloatRounding, M: Mantissa, Cb: FnOnce(&mut ExtendedFloat, i32) { // Shift all the way left, to ensure a consistent representation. // The following right-shifts do not work for a non-normalized number. fp.normalize(); // Round so the fraction is in a native mantissa representation, // and avoid overflow/underflow. round_to_float::(fp, cb); avoid_overflow::(fp); }} // Get the rounding scheme to determine if we should go up or down. perftools_inline!{ #[allow(unused_variables)] pub(crate) fn internal_rounding(kind: RoundingKind, sign: Sign) -> RoundingKind { #[cfg(not(feature = "rounding"))] { RoundingKind::NearestTieEven } #[cfg(feature = "rounding")] { match sign { Sign::Positive => { match kind { RoundingKind::TowardPositiveInfinity => RoundingKind::Upward, RoundingKind::TowardNegativeInfinity => RoundingKind::Downward, RoundingKind::TowardZero => RoundingKind::Downward, _ => kind, } }, Sign::Negative => { match kind { RoundingKind::TowardPositiveInfinity => RoundingKind::Downward, RoundingKind::TowardNegativeInfinity => RoundingKind::Upward, RoundingKind::TowardZero => RoundingKind::Downward, _ => kind, } }, } } }} // Get the global, default rounding scheme. perftools_inline!{ #[cfg(feature = "correct")] #[allow(unused_variables)] pub(crate) fn global_rounding(sign: Sign) -> RoundingKind { #[cfg(not(feature = "rounding"))] { RoundingKind::NearestTieEven } #[cfg(feature = "rounding")] { internal_rounding(get_float_rounding(), sign) } }} // TESTS // ----- #[cfg(test)] mod tests { use crate::float::ExtendedFloat80; use super::*; // NEAREST ROUNDING #[test] fn round_nearest_test() { // Check exactly halfway (b'1100000') let mut fp = ExtendedFloat80 { mant: 0x60, exp: 0 }; let (above, halfway) = round_nearest(&mut fp, 6); assert!(!above); assert!(halfway); assert_eq!(fp.mant, 1); // Check above halfway (b'1100001') let mut fp = ExtendedFloat80 { mant: 0x61, exp: 0 }; let (above, halfway) = round_nearest(&mut fp, 6); assert!(above); assert!(!halfway); assert_eq!(fp.mant, 1); // Check below halfway (b'1011111') let mut fp = ExtendedFloat80 { mant: 0x5F, exp: 0 }; let (above, halfway) = round_nearest(&mut fp, 6); assert!(!above); assert!(!halfway); assert_eq!(fp.mant, 1); } #[test] fn round_nearest_tie_even_test() { // Check round-up, halfway let mut fp = ExtendedFloat80 { mant: 0x60, exp: 0 }; round_nearest_tie_even(&mut fp, 6); assert_eq!(fp.mant, 2); // Check round-down, halfway let mut fp = ExtendedFloat80 { mant: 0x20, exp: 0 }; round_nearest_tie_even(&mut fp, 6); assert_eq!(fp.mant, 0); // Check round-up, above halfway let mut fp = ExtendedFloat80 { mant: 0x61, exp: 0 }; round_nearest_tie_even(&mut fp, 6); assert_eq!(fp.mant, 2); let mut fp = ExtendedFloat80 { mant: 0x21, exp: 0 }; round_nearest_tie_even(&mut fp, 6); assert_eq!(fp.mant, 1); // Check round-down, below halfway let mut fp = ExtendedFloat80 { mant: 0x5F, exp: 0 }; round_nearest_tie_even(&mut fp, 6); assert_eq!(fp.mant, 1); let mut fp = ExtendedFloat80 { mant: 0x1F, exp: 0 }; round_nearest_tie_even(&mut fp, 6); assert_eq!(fp.mant, 0); } #[test] fn round_nearest_tie_away_zero_test() { // Check round-up, halfway let mut fp = ExtendedFloat80 { mant: 0x60, exp: 0 }; round_nearest_tie_away_zero(&mut fp, 6); assert_eq!(fp.mant, 2); let mut fp = ExtendedFloat80 { mant: 0x20, exp: 0 }; round_nearest_tie_away_zero(&mut fp, 6); assert_eq!(fp.mant, 1); // Check round-up, above halfway let mut fp = ExtendedFloat80 { mant: 0x61, exp: 0 }; round_nearest_tie_away_zero(&mut fp, 6); assert_eq!(fp.mant, 2); let mut fp = ExtendedFloat80 { mant: 0x21, exp: 0 }; round_nearest_tie_away_zero(&mut fp, 6); assert_eq!(fp.mant, 1); // Check round-down, below halfway let mut fp = ExtendedFloat80 { mant: 0x5F, exp: 0 }; round_nearest_tie_away_zero(&mut fp, 6); assert_eq!(fp.mant, 1); let mut fp = ExtendedFloat80 { mant: 0x1F, exp: 0 }; round_nearest_tie_away_zero(&mut fp, 6); assert_eq!(fp.mant, 0); } // DIRECTED ROUNDING #[test] fn round_upward_test() { // b0000000 let mut fp = ExtendedFloat80 { mant: 0x00, exp: 0 }; round_upward(&mut fp, 6); assert_eq!(fp.mant, 0); // b1000000 let mut fp = ExtendedFloat80 { mant: 0x40, exp: 0 }; round_upward(&mut fp, 6); assert_eq!(fp.mant, 1); // b1100000 let mut fp = ExtendedFloat80 { mant: 0x60, exp: 0 }; round_upward(&mut fp, 6); assert_eq!(fp.mant, 2); // b1110000 let mut fp = ExtendedFloat80 { mant: 0x70, exp: 0 }; round_upward(&mut fp, 6); assert_eq!(fp.mant, 2); } #[test] fn round_downward_test() { // b0000000 let mut fp = ExtendedFloat80 { mant: 0x00, exp: 0 }; round_downward(&mut fp, 6); assert_eq!(fp.mant, 0); // b1000000 let mut fp = ExtendedFloat80 { mant: 0x40, exp: 0 }; round_downward(&mut fp, 6); assert_eq!(fp.mant, 1); // b1100000 let mut fp = ExtendedFloat80 { mant: 0x60, exp: 0 }; round_downward(&mut fp, 6); assert_eq!(fp.mant, 1); // b1110000 let mut fp = ExtendedFloat80 { mant: 0x70, exp: 0 }; round_downward(&mut fp, 6); assert_eq!(fp.mant, 1); } // HIGH-LEVEL #[test] fn round_to_float_test() { // Denormal let mut fp = ExtendedFloat80 { mant: 1<<63, exp: f64::DENORMAL_EXPONENT - 15 }; round_to_float::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, 1<<48); assert_eq!(fp.exp, f64::DENORMAL_EXPONENT); // Halfway, round-down (b'1000000000000000000000000000000000000000000000000000010000000000') let mut fp = ExtendedFloat80 { mant: 0x8000000000000400, exp: -63 }; round_to_float::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, 1<<52); assert_eq!(fp.exp, -52); // Halfway, round-up (b'1000000000000000000000000000000000000000000000000000110000000000') let mut fp = ExtendedFloat80 { mant: 0x8000000000000C00, exp: -63 }; round_to_float::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, (1<<52) + 2); assert_eq!(fp.exp, -52); // Above halfway let mut fp = ExtendedFloat80 { mant: 0x8000000000000401, exp: -63 }; round_to_float::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, (1<<52)+1); assert_eq!(fp.exp, -52); let mut fp = ExtendedFloat80 { mant: 0x8000000000000C01, exp: -63 }; round_to_float::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, (1<<52) + 2); assert_eq!(fp.exp, -52); // Below halfway let mut fp = ExtendedFloat80 { mant: 0x80000000000003FF, exp: -63 }; round_to_float::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, 1<<52); assert_eq!(fp.exp, -52); let mut fp = ExtendedFloat80 { mant: 0x8000000000000BFF, exp: -63 }; round_to_float::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, (1<<52) + 1); assert_eq!(fp.exp, -52); } #[test] fn avoid_overflow_test() { // Avoid overflow, fails by 1 let mut fp = ExtendedFloat80 { mant: 0xFFFFFFFFFFFF, exp: f64::MAX_EXPONENT + 5 }; avoid_overflow::(&mut fp); assert_eq!(fp.mant, 0xFFFFFFFFFFFF); assert_eq!(fp.exp, f64::MAX_EXPONENT+5); // Avoid overflow, succeeds let mut fp = ExtendedFloat80 { mant: 0xFFFFFFFFFFFF, exp: f64::MAX_EXPONENT + 4 }; avoid_overflow::(&mut fp); assert_eq!(fp.mant, 0x1FFFFFFFFFFFE0); assert_eq!(fp.exp, f64::MAX_EXPONENT-1); } #[test] fn round_to_native_test() { // Overflow let mut fp = ExtendedFloat80 { mant: 0xFFFFFFFFFFFF, exp: f64::MAX_EXPONENT + 4 }; round_to_native::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, 0x1FFFFFFFFFFFE0); assert_eq!(fp.exp, f64::MAX_EXPONENT-1); // Need denormal let mut fp = ExtendedFloat80 { mant: 1, exp: f64::DENORMAL_EXPONENT +48 }; round_to_native::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, 1<<48); assert_eq!(fp.exp, f64::DENORMAL_EXPONENT); // Halfway, round-down (b'10000000000000000000000000000000000000000000000000000100000') let mut fp = ExtendedFloat80 { mant: 0x400000000000020, exp: -58 }; round_to_native::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, 1<<52); assert_eq!(fp.exp, -52); // Halfway, round-up (b'10000000000000000000000000000000000000000000000000001100000') let mut fp = ExtendedFloat80 { mant: 0x400000000000060, exp: -58 }; round_to_native::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, (1<<52) + 2); assert_eq!(fp.exp, -52); // Above halfway let mut fp = ExtendedFloat80 { mant: 0x400000000000021, exp: -58 }; round_to_native::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, (1<<52)+1); assert_eq!(fp.exp, -52); let mut fp = ExtendedFloat80 { mant: 0x400000000000061, exp: -58 }; round_to_native::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, (1<<52) + 2); assert_eq!(fp.exp, -52); // Below halfway let mut fp = ExtendedFloat80 { mant: 0x40000000000001F, exp: -58 }; round_to_native::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, 1<<52); assert_eq!(fp.exp, -52); let mut fp = ExtendedFloat80 { mant: 0x40000000000005F, exp: -58 }; round_to_native::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, (1<<52) + 1); assert_eq!(fp.exp, -52); // Underflow // Adapted from failures in strtod. let mut fp = ExtendedFloat80 { exp: -1139, mant: 18446744073709550712 }; round_to_native::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, 0); assert_eq!(fp.exp, 0); let mut fp = ExtendedFloat80 { exp: -1139, mant: 18446744073709551460 }; round_to_native::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, 0); assert_eq!(fp.exp, 0); let mut fp = ExtendedFloat80 { exp: -1138, mant: 9223372036854776103 }; round_to_native::(&mut fp, round_nearest_tie_even); assert_eq!(fp.mant, 1); assert_eq!(fp.exp, -1074); } } lexical-core-0.7.6/src/float/shift.rs000075500000000000000000000025630000000000000155520ustar 00000000000000//! Macros for bit-wise shifts. use crate::lib::mem; use crate::util::*; use super::float::ExtendedFloat; use super::mantissa::Mantissa; // SHIFT RIGHT // Shift extended-precision float right `shift` bytes. perftools_inline!{ pub(super) fn shr(fp: &mut ExtendedFloat, shift: T) { let bits: T = as_cast(mem::size_of::() * 8); debug_assert!(shift < bits, "shr() overflow in shift right."); fp.mant >>= as_cast::(shift); fp.exp += shift.as_i32(); }} // Shift extended-precision float right `shift` bytes. // // Accepts when the shift is the same as the type size, and // sets the value to 0. perftools_inline!{ pub(super) fn overflowing_shr(fp: &mut ExtendedFloat, shift: T) { let bits: T = as_cast(mem::size_of::() * 8); debug_assert!(shift <= bits, "overflowing_shr() overflow in shift right."); fp.mant = match shift == bits { true => M::ZERO, false => fp.mant >> as_cast::(shift), }; fp.exp += shift.as_i32(); }} // Shift extended-precision float left `shift` bytes. perftools_inline!{ pub(super) fn shl(fp: &mut ExtendedFloat, shift: T) { let bits: T = as_cast(mem::size_of::() * 8); debug_assert!(shift < bits, "shl() overflow in shift left."); fp.mant <<= as_cast::(shift); fp.exp -= shift.as_i32(); }} lexical-core-0.7.6/src/ftoa/api.rs000075500000000000000000000456560000000000000150440ustar 00000000000000//! Low-level API generator. //! //! Uses either the internal "Grisu2", or the external "Grisu3" or "Ryu" //! algorithms provided by `https://github.com/dtolnay`. // The following benchmarks were run on an "Intel(R) Core(TM) i7-6560U // CPU @ 2.20GHz" CPU, on Fedora 28, Linux kernel version 4.18.16-200 // (x86-64), using the lexical formatter or `x.parse()`, // avoiding any inefficiencies in Rust string parsing. The code was // compiled with LTO and at an optimization level of 3. // // The benchmarks with `std` were compiled using "rustc 1.29.2 (17a9dc751 // 2018-10-05", and the `no_std` benchmarks were compiled using "rustc // 1.31.0-nightly (46880f41b 2018-10-15)". // // The benchmark code may be found `benches/atof.rs`. // // # Benchmarks // // | Type | lexical (ns/iter) | libcore (ns/iter) | Relative Increase | // |:-----:|:------------------:|:---------------------:|:-----------------:| // | f32 | 465,584 | 1,884,646 | 4.04x | // | f64 | 539,904 | 2,276,839 | 4.22x | // // # Raw Benchmarks // // ```text // test ftoa_f32_dtoa ... bench: 917,561 ns/iter (+/- 45,458) // test ftoa_f32_lexical ... bench: 465,584 ns/iter (+/- 76,158) // test ftoa_f32_std ... bench: 1,884,646 ns/iter (+/- 130,721) // test ftoa_f64_dtoa ... bench: 1,092,687 ns/iter (+/- 125,136) // test ftoa_f64_lexical ... bench: 539,904 ns/iter (+/- 29,626) // test ftoa_f64_std ... bench: 2,276,839 ns/iter (+/- 64,515) // ``` // Code the generate the benchmark plot: // import numpy as np // import pandas as pd // import matplotlib.pyplot as plt // plt.style.use('ggplot') // lexical = np.array([465584, 539904]) / 1e6 // rustcore = np.array([1884646, 2276839]) / 1e6 // dtoa = np.array([917561, 1092687]) / 1e6 // ryu = np.array([432878, 522515]) / 1e6 // index = ["f32", "f64"] // df = pd.DataFrame({'lexical': lexical, 'rustcore': rustcore, 'dtoa': dtoa, 'ryu': ryu}, index = index, columns=['lexical', 'dtoa', 'ryu', 'rustcore']) // ax = df.plot.bar(rot=0, figsize=(16, 8), fontsize=14) // ax.set_ylabel("ms/iter") // ax.figure.tight_layout() // ax.legend(loc=2, prop={'size': 14}) // plt.show() use crate::util::*; #[cfg(feature = "radix")] use super::radix::{double_radix, float_radix}; // Select the back-end cfg_if! { if #[cfg(feature = "grisu3")] { use super::grisu3::{double_decimal, float_decimal}; } else if #[cfg(feature = "ryu")] { use super::ryu::{double_decimal, float_decimal}; } else { use super::grisu2::{double_decimal, float_decimal}; }} //cfg_if // TRAITS /// Trait to define serialization of a float to string. pub(crate) trait FloatToString: Float { /// Export float to decimal string with optimized algorithm. fn decimal<'a>(self, bytes: &'a mut [u8]) -> usize; /// Export float to radix string with slow algorithm. #[cfg(feature = "radix")] fn radix<'a>(self, radix: u32, bytes: &'a mut [u8]) -> usize; } impl FloatToString for f32 { perftools_inline!{ fn decimal<'a>(self, bytes: &'a mut [u8]) -> usize { float_decimal(self, bytes) }} perftools_inline!{ #[cfg(feature = "radix")] fn radix<'a>(self, radix: u32, bytes: &'a mut [u8]) -> usize { float_radix(self, radix, bytes) }} } impl FloatToString for f64 { perftools_inline!{ fn decimal<'a>(self, bytes: &'a mut [u8]) -> usize { double_decimal(self, bytes) }} perftools_inline!{ #[cfg(feature = "radix")] fn radix<'a>(self, radix: u32, bytes: &'a mut [u8]) -> usize { double_radix(self, radix, bytes) }} } // FTOA // Forward the correct arguments the ideal encoder. perftools_inline!{ fn forward<'a, F: FloatToString>(value: F, radix: u32, bytes: &'a mut [u8]) -> usize { debug_assert_radix!(radix); #[cfg(not(feature = "radix"))] { value.decimal(bytes) } #[cfg(feature = "radix")] { match radix { 10 => value.decimal(bytes), _ => value.radix(radix, bytes), } } }} // Convert float-to-string and handle special (positive) floats. perftools_inline!{ fn filter_special<'a, F: FloatToString>(value: F, radix: u32, bytes: &'a mut [u8]) -> usize { // Logic errors, disable in release builds. debug_assert!(value.is_sign_positive(), "Value cannot be negative."); debug_assert_radix!(radix); // We already check for 0 in `filter_sign` if value.is_zero(). #[cfg(not(feature = "trim_floats"))] { if value.is_zero() { // This is safe, because we confirmed the buffer is >= 4 // in total (since we also handled the sign by here). return copy_to_dst(bytes, b"0.0"); } } if value.is_nan() { // This is safe, because we confirmed the buffer is >= F::FORMATTED_SIZE. // We have up to `F::FORMATTED_SIZE - 1` bytes from `get_nan_string()`, // and up to 1 byte from the sign. copy_to_dst(bytes, get_nan_string()) } else if value.is_special() { // This is safe, because we confirmed the buffer is >= F::FORMATTED_SIZE. // We have up to `F::FORMATTED_SIZE - 1` bytes from `get_inf_string()`, // and up to 1 byte from the sign. copy_to_dst(bytes, get_inf_string()) } else { forward(value, radix, bytes) } }} // Handle +/- values. perftools_inline!{ fn filter_sign<'a, F: FloatToString>(value: F, radix: u32, bytes: &'a mut [u8]) -> usize { debug_assert_radix!(radix); // Export "-0.0" and "0.0" as "0" with trimmed floats. #[cfg(feature = "trim_floats")] { if value.is_zero() { // We know this is safe, because we confirmed the buffer is >= 1. index_mut!(bytes[0] = b'0'); return 1; } } // If the sign bit is set, invert it and just set the first // value to "-". if value.is_sign_negative() { let value = -value; // We know this is safe, because we confirmed the buffer is >= 1. index_mut!(bytes[0] = b'-'); let bytes = &mut index_mut!(bytes[1..]); filter_special(value, radix, bytes) + 1 } else { filter_special(value, radix, bytes) } }} // Write float to string.. perftools_inline!{ fn ftoa(value: F, radix: u32, bytes: &mut [u8]) -> usize { let len = filter_sign(value, radix, bytes); let bytes = &mut index_mut!(bytes[..len]); trim(bytes) }} // Trim a trailing ".0" from a float. perftools_inline!{ fn trim<'a>(bytes: &'a mut [u8]) -> usize { // Trim a trailing ".0" from a float. if cfg!(feature = "trim_floats") && ends_with_slice(bytes, b".0") { bytes.len() - 2 } else { bytes.len() } }} // TO LEXICAL to_lexical!(ftoa, f32); to_lexical!(ftoa, f64); // TESTS // ----- #[cfg(test)] mod tests { use crate::util::*; use crate::util::test::*; #[cfg(all(feature = "correct", feature = "property_tests"))] use quickcheck::quickcheck; #[cfg(all(feature = "correct", feature = "std", feature = "property_tests"))] use proptest::{proptest, prop_assert_eq}; use approx::assert_relative_eq; // Test data for roundtrips. const F32_DATA : [f32; 31] = [0., 0.1, 1., 1.1, 12., 12.1, 123., 123.1, 1234., 1234.1, 12345., 12345.1, 123456., 123456.1, 1234567., 1234567.1, 12345678., 12345678.1, 123456789., 123456789.1, 123456789.12, 123456789.123, 123456789.1234, 123456789.12345, 1.2345678912345e8, 1.2345e+8, 1.2345e+11, 1.2345e+38, 1.2345e-8, 1.2345e-11, 1.2345e-38]; const F64_DATA: [f64; 33] = [0., 0.1, 1., 1.1, 12., 12.1, 123., 123.1, 1234., 1234.1, 12345., 12345.1, 123456., 123456.1, 1234567., 1234567.1, 12345678., 12345678.1, 123456789., 123456789.1, 123456789.12, 123456789.123, 123456789.1234, 123456789.12345, 1.2345678912345e8, 1.2345e+8, 1.2345e+11, 1.2345e+38, 1.2345e+308, 1.2345e-8, 1.2345e-11, 1.2345e-38, 1.2345e-299]; #[cfg(feature = "radix")] #[test] fn f32_binary_test() { let mut buffer = new_buffer(); // positive #[cfg(feature = "trim_floats")] { assert_eq!(as_slice(b"0"), 0.0f32.to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"0"), (-0.0f32).to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"1"), 1.0f32.to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"10"), 2.0f32.to_lexical_radix(2, &mut buffer)); } #[cfg(not(feature = "trim_floats"))] { assert_eq!(as_slice(b"0.0"), 0.0f32.to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"-0.0"), (-0.0f32).to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"1.0"), 1.0f32.to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"10.0"), 2.0f32.to_lexical_radix(2, &mut buffer)); } assert_eq!(as_slice(b"1.1"), 1.5f32.to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"1.01"), 1.25f32.to_lexical_radix(2, &mut buffer)); assert_eq!(b"1.001111000000110010", &1.2345678901234567890e0f32.to_lexical_radix(2, &mut buffer)[..20]); assert_eq!(b"1100.010110000111111", &1.2345678901234567890e1f32.to_lexical_radix(2, &mut buffer)[..20]); assert_eq!(b"1111011.011101001111", &1.2345678901234567890e2f32.to_lexical_radix(2, &mut buffer)[..20]); assert_eq!(b"10011010010.10010001", &1.2345678901234567890e3f32.to_lexical_radix(2, &mut buffer)[..20]); // negative assert_eq!(b"-1.001111000000110010", &(-1.2345678901234567890e0f32).to_lexical_radix(2, &mut buffer)[..21]); assert_eq!(b"-1100.010110000111111", &(-1.2345678901234567890e1f32).to_lexical_radix(2, &mut buffer)[..21]); assert_eq!(b"-1111011.011101001111", &(-1.2345678901234567890e2f32).to_lexical_radix(2, &mut buffer)[..21]); assert_eq!(b"-10011010010.10010001", &(-1.2345678901234567890e3f32).to_lexical_radix(2, &mut buffer)[..21]); // special assert_eq!(as_slice(b"NaN"), f32::NAN.to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"inf"), f32::INFINITY.to_lexical_radix(2, &mut buffer)); // bugfixes assert_eq!(as_slice(b"1.1010100000101011110001e-11011"), 0.000000012345f32.to_lexical_radix(2, &mut buffer)); } #[test] fn f32_decimal_test() { let mut buffer = new_buffer(); // positive #[cfg(feature = "trim_floats")] { assert_eq!(as_slice(b"0"), 0.0f32.to_lexical(&mut buffer)); assert_eq!(as_slice(b"0"), (-0.0f32).to_lexical(&mut buffer)); assert_eq!(as_slice(b"1"), 1.0f32.to_lexical(&mut buffer)); assert_eq!(as_slice(b"10"), 10.0f32.to_lexical(&mut buffer)); } #[cfg(not(feature = "trim_floats"))] { assert_eq!(as_slice(b"0.0"), 0.0f32.to_lexical(&mut buffer)); assert_eq!(as_slice(b"-0.0"), (-0.0f32).to_lexical(&mut buffer)); assert_eq!(as_slice(b"1.0"), 1.0f32.to_lexical(&mut buffer)); assert_eq!(as_slice(b"10.0"), 10.0f32.to_lexical(&mut buffer)); } assert_eq!(as_slice(b"1.234567"), &1.2345678901234567890e0f32.to_lexical(&mut buffer)[..8]); assert_eq!(as_slice(b"12.34567"), &1.2345678901234567890e1f32.to_lexical(&mut buffer)[..8]); assert_eq!(as_slice(b"123.4567"), &1.2345678901234567890e2f32.to_lexical(&mut buffer)[..8]); assert_eq!(as_slice(b"1234.567"), &1.2345678901234567890e3f32.to_lexical(&mut buffer)[..8]); // negative assert_eq!(as_slice(b"-1.234567"), &(-1.2345678901234567890e0f32).to_lexical(&mut buffer)[..9]); assert_eq!(as_slice(b"-12.34567"), &(-1.2345678901234567890e1f32).to_lexical(&mut buffer)[..9]); assert_eq!(as_slice(b"-123.4567"), &(-1.2345678901234567890e2f32).to_lexical(&mut buffer)[..9]); assert_eq!(as_slice(b"-1234.567"), &(-1.2345678901234567890e3f32).to_lexical(&mut buffer)[..9]); // special assert_eq!(as_slice(b"NaN"), f32::NAN.to_lexical(&mut buffer)); assert_eq!(as_slice(b"inf"), f32::INFINITY.to_lexical(&mut buffer)); } #[test] fn f32_decimal_roundtrip_test() { let mut buffer = new_buffer(); for &f in F32_DATA.iter() { let s = f.to_lexical(&mut buffer); assert_relative_eq!(f32::from_lexical(s).unwrap(), f, epsilon=1e-6, max_relative=1e-6); } } #[cfg(feature = "radix")] #[test] fn f32_radix_roundtrip_test() { let mut buffer = new_buffer(); for &f in F32_DATA.iter() { for radix in 2..37 { // The lower accuracy is due to slight rounding errors of // ftoa for the Grisu method with non-10 bases. let s = f.to_lexical_radix(radix, &mut buffer); assert_relative_eq!(f32::from_lexical_radix(s, radix).unwrap(), f, max_relative=2e-5); } } } #[cfg(feature = "radix")] #[test] fn f64_binary_test() { let mut buffer = new_buffer(); // positive #[cfg(feature = "trim_floats")] { assert_eq!(as_slice(b"0"), 0.0f64.to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"0"), (-0.0f64).to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"1"), 1.0f64.to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"10"), 2.0f64.to_lexical_radix(2, &mut buffer)); } #[cfg(not(feature = "trim_floats"))] { assert_eq!(as_slice(b"0.0"), 0.0f64.to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"-0.0"), (-0.0f64).to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"1.0"), 1.0f64.to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"10.0"), 2.0f64.to_lexical_radix(2, &mut buffer)); } assert_eq!(as_slice(b"1.00111100000011001010010000101000110001"), &1.2345678901234567890e0f64.to_lexical_radix(2, &mut buffer)[..40]); assert_eq!(as_slice(b"1100.01011000011111100110100110010111101"), &1.2345678901234567890e1f64.to_lexical_radix(2, &mut buffer)[..40]); assert_eq!(as_slice(b"1111011.01110100111100000001111111101101"), &1.2345678901234567890e2f64.to_lexical_radix(2, &mut buffer)[..40]); assert_eq!(as_slice(b"10011010010.1001000101100001001111110100"), &1.2345678901234567890e3f64.to_lexical_radix(2, &mut buffer)[..40]); // negative assert_eq!(as_slice(b"-1.00111100000011001010010000101000110001"), &(-1.2345678901234567890e0f64).to_lexical_radix(2, &mut buffer)[..41]); assert_eq!(as_slice(b"-1100.01011000011111100110100110010111101"), &(-1.2345678901234567890e1f64).to_lexical_radix(2, &mut buffer)[..41]); assert_eq!(as_slice(b"-1111011.01110100111100000001111111101101"), &(-1.2345678901234567890e2f64).to_lexical_radix(2, &mut buffer)[..41]); assert_eq!(as_slice(b"-10011010010.1001000101100001001111110100"), &(-1.2345678901234567890e3f64).to_lexical_radix(2, &mut buffer)[..41]); // special assert_eq!(as_slice(b"NaN"), f64::NAN.to_lexical_radix(2, &mut buffer)); assert_eq!(as_slice(b"inf"), f64::INFINITY.to_lexical_radix(2, &mut buffer)); } #[test] fn f64_decimal_test() { let mut buffer = new_buffer(); // positive #[cfg(feature = "trim_floats")] { assert_eq!(as_slice(b"0"), 0.0.to_lexical(&mut buffer)); assert_eq!(as_slice(b"0"), (-0.0).to_lexical(&mut buffer)); assert_eq!(as_slice(b"1"), 1.0.to_lexical(&mut buffer)); assert_eq!(as_slice(b"10"), 10.0.to_lexical(&mut buffer)); } #[cfg(not(feature = "trim_floats"))] { assert_eq!(as_slice(b"0.0"), 0.0.to_lexical(&mut buffer)); assert_eq!(as_slice(b"-0.0"), (-0.0).to_lexical(&mut buffer)); assert_eq!(as_slice(b"1.0"), 1.0.to_lexical(&mut buffer)); assert_eq!(as_slice(b"10.0"), 10.0.to_lexical(&mut buffer)); } assert_eq!(as_slice(b"1.234567"), &1.2345678901234567890e0.to_lexical(&mut buffer)[..8]); assert_eq!(as_slice(b"12.34567"), &1.2345678901234567890e1.to_lexical(&mut buffer)[..8]); assert_eq!(as_slice(b"123.4567"), &1.2345678901234567890e2.to_lexical(&mut buffer)[..8]); assert_eq!(as_slice(b"1234.567"), &1.2345678901234567890e3.to_lexical(&mut buffer)[..8]); // negative assert_eq!(as_slice(b"-1.234567"), &(-1.2345678901234567890e0).to_lexical(&mut buffer)[..9]); assert_eq!(as_slice(b"-12.34567"), &(-1.2345678901234567890e1).to_lexical(&mut buffer)[..9]); assert_eq!(as_slice(b"-123.4567"), &(-1.2345678901234567890e2).to_lexical(&mut buffer)[..9]); assert_eq!(as_slice(b"-1234.567"), &(-1.2345678901234567890e3).to_lexical(&mut buffer)[..9]); // special assert_eq!(b"NaN".to_vec(), f64::NAN.to_lexical(&mut buffer)); assert_eq!(b"inf".to_vec(), f64::INFINITY.to_lexical(&mut buffer)); } #[test] fn f64_decimal_roundtrip_test() { let mut buffer = new_buffer(); for &f in F64_DATA.iter() { let s = f.to_lexical(&mut buffer); assert_relative_eq!(f64::from_lexical(s).unwrap(), f, epsilon=1e-12, max_relative=1e-12); } } #[cfg(feature = "radix")] #[test] fn f64_radix_roundtrip_test() { let mut buffer = new_buffer(); for &f in F64_DATA.iter() { for radix in 2..37 { // The lower accuracy is due to slight rounding errors of // ftoa for the Grisu method with non-10 bases. let s = f.to_lexical_radix(radix, &mut buffer); assert_relative_eq!(f64::from_lexical_radix(s, radix).unwrap(), f, max_relative=3e-5); } } } #[cfg(all(feature = "correct", feature = "property_tests"))] quickcheck! { fn f32_quickcheck(f: f32) -> bool { let mut buffer = new_buffer(); let parsed = f32::from_lexical(f.to_lexical(&mut buffer)).unwrap(); if f.is_nan() { parsed.is_nan() } else { f == parsed } } fn f64_quickcheck(f: f64) -> bool { let mut buffer = new_buffer(); let parsed = f64::from_lexical(f.to_lexical(&mut buffer)).unwrap(); if f.is_nan() { parsed.is_nan() } else { f == parsed } } } #[cfg(all(feature = "correct", feature = "std", feature = "property_tests"))] proptest! { #[test] fn f32_proptest(i in f32::MIN..f32::MAX) { let mut buffer = new_buffer(); prop_assert_eq!(i, f32::from_lexical(i.to_lexical(&mut buffer)).unwrap()); } #[test] fn f64_proptest(i in f64::MIN..f64::MAX) { let mut buffer = new_buffer(); prop_assert_eq!(i, f64::from_lexical(i.to_lexical(&mut buffer)).unwrap()); } } #[test] #[should_panic] fn f32_buffer_test() { let mut buffer = [b'0'; f32::FORMATTED_SIZE_DECIMAL-1]; 1.2345f32.to_lexical(&mut buffer); } #[test] #[should_panic] fn f64_buffer_test() { let mut buffer = [b'0'; f64::FORMATTED_SIZE_DECIMAL-1]; 1.2345f64.to_lexical(&mut buffer); } } lexical-core-0.7.6/src/ftoa/grisu2.rs000075500000000000000000000400310000000000000154640ustar 00000000000000//! Internal implementation of the Grisu2 algorithm. //! //! The optimized routines are adapted from Andrea Samoljuk's `fpconv` library, //! which is available [here](https://github.com/night-shift/fpconv). //! //! The following benchmarks were run on an "Intel(R) Core(TM) i7-6560U //! CPU @ 2.20GHz" CPU, on Fedora 28, Linux kernel version 4.18.16-200 //! (x86-64), using the lexical formatter, `dtoa::write()` or `x.to_string()`, //! avoiding any inefficiencies in Rust string parsing for `format!(...)` //! or `write!()` macros. The code was compiled with LTO and at an optimization //! level of 3. //! //! The benchmarks with `std` were compiled using "rustc 1.29.2 (17a9dc751 //! 2018-10-05", and the `no_std` benchmarks were compiled using "rustc //! 1.31.0-nightly (46880f41b 2018-10-15)". //! //! The benchmark code may be found `benches/ftoa.rs`. //! //! # Benchmarks //! //! | Type | lexical (ns/iter) | to_string (ns/iter) | Relative Increase | //! |:-----:|:------------------:|:---------------------:|:-----------------:| //! | f32 | 1,221,025 | 2,711,290 | 2.22x | //! | f64 | 1,248,397 | 3,558,305 | 2.85x | //! //! # Raw Benchmarks //! //! ```text //! test f32_dtoa ... bench: 1,174,070 ns/iter (+/- 442,501) //! test f32_lexical ... bench: 1,433,234 ns/iter (+/- 633,261) //! test f32_ryu ... bench: 669,828 ns/iter (+/- 192,291) //! test f32_to_string ... bench: 3,341,733 ns/iter (+/- 1,346,744) //! test f64_dtoa ... bench: 1,302,522 ns/iter (+/- 364,655) //! test f64_lexical ... bench: 1,375,384 ns/iter (+/- 596,860) //! test f64_ryu ... bench: 1,015,171 ns/iter (+/- 187,552) //! test f64_to_string ... bench: 3,900,299 ns/iter (+/- 521,956) //! ``` // Code the generate the benchmark plot: // import numpy as np // import pandas as pd // import matplotlib.pyplot as plt // plt.style.use('ggplot') // lexical = np.array([1221025, 1375384]) / 1e6 // dtoa = np.array([1174070, 1302522]) / 1e6 // ryu = np.array([669828, 1015171]) / 1e6 // rustcore = np.array([2711290, 3558305]) / 1e6 // index = ["f32", "f64"] // df = pd.DataFrame({'lexical': lexical, 'lexical (dtoa)': dtoa, 'lexical (ryu)': ryu, 'rustcore': rustcore}, index = index, columns=['lexical', 'lexical (dtoa)', 'lexical (ryu)', 'rustcore']) // ax = df.plot.bar(rot=0, figsize=(16, 8), fontsize=14, color=['#E24A33', '#988ED5', '#8EBA42', '#348ABD']) // ax.set_ylabel("ms/iter") // ax.figure.tight_layout() // ax.legend(loc=2, prop={'size': 14}) // plt.show() use crate::float::ExtendedFloat80; use crate::util::*; // CACHED POWERS perftools_inline!{ /// Find cached power of 10 from the exponent. fn cached_grisu_power(exp: i32, k: &mut i32) -> &'static ExtendedFloat80 { // FLOATING POINT CONSTANTS const ONE_LOG_TEN: f64 = 0.30102999566398114; const NPOWERS: i32 = 87; const FIRSTPOWER: i32 = -348; // 10 ^ -348 const STEPPOWERS: i32 = 8; const EXPMAX: i32 = -32; const EXPMIN: i32 = -60; let approx = -((exp + NPOWERS).as_f64()) * ONE_LOG_TEN; let approx = approx.as_i32(); let mut idx = ((approx - FIRSTPOWER) / STEPPOWERS).as_usize(); loop { // Use `arr.get(idx)`, which explicitly provides a reference, // instead of `arr[idx]`, which provides a value. // We have a bug in versions <= 1.27.0 where it creates // a local copy, which we then get the reference to and return. // This allows use-after-free, without any warning, so we're // using unidiomatic code to avoid any issue. let power = GRISU_POWERS_OF_TEN.get(idx).unwrap(); let current = exp + power.exp + 64; if current < EXPMIN { idx += 1; continue; } if current > EXPMAX { idx -= 1; continue; } *k = FIRSTPOWER + idx.as_i32() * STEPPOWERS; return power; } }} /// Cached powers of ten as specified by the Grisu algorithm. /// /// Cached powers of 10^k, calculated as if by: /// `ceil((alpha-e+63) * ONE_LOG_TEN);` const GRISU_POWERS_OF_TEN: [ExtendedFloat80; 87] = [ ExtendedFloat80 { mant: 18054884314459144840, exp: -1220 }, ExtendedFloat80 { mant: 13451937075301367670, exp: -1193 }, ExtendedFloat80 { mant: 10022474136428063862, exp: -1166 }, ExtendedFloat80 { mant: 14934650266808366570, exp: -1140 }, ExtendedFloat80 { mant: 11127181549972568877, exp: -1113 }, ExtendedFloat80 { mant: 16580792590934885855, exp: -1087 }, ExtendedFloat80 { mant: 12353653155963782858, exp: -1060 }, ExtendedFloat80 { mant: 18408377700990114895, exp: -1034 }, ExtendedFloat80 { mant: 13715310171984221708, exp: -1007 }, ExtendedFloat80 { mant: 10218702384817765436, exp: -980 }, ExtendedFloat80 { mant: 15227053142812498563, exp: -954 }, ExtendedFloat80 { mant: 11345038669416679861, exp: -927 }, ExtendedFloat80 { mant: 16905424996341287883, exp: -901 }, ExtendedFloat80 { mant: 12595523146049147757, exp: -874 }, ExtendedFloat80 { mant: 9384396036005875287, exp: -847 }, ExtendedFloat80 { mant: 13983839803942852151, exp: -821 }, ExtendedFloat80 { mant: 10418772551374772303, exp: -794 }, ExtendedFloat80 { mant: 15525180923007089351, exp: -768 }, ExtendedFloat80 { mant: 11567161174868858868, exp: -741 }, ExtendedFloat80 { mant: 17236413322193710309, exp: -715 }, ExtendedFloat80 { mant: 12842128665889583758, exp: -688 }, ExtendedFloat80 { mant: 9568131466127621947, exp: -661 }, ExtendedFloat80 { mant: 14257626930069360058, exp: -635 }, ExtendedFloat80 { mant: 10622759856335341974, exp: -608 }, ExtendedFloat80 { mant: 15829145694278690180, exp: -582 }, ExtendedFloat80 { mant: 11793632577567316726, exp: -555 }, ExtendedFloat80 { mant: 17573882009934360870, exp: -529 }, ExtendedFloat80 { mant: 13093562431584567480, exp: -502 }, ExtendedFloat80 { mant: 9755464219737475723, exp: -475 }, ExtendedFloat80 { mant: 14536774485912137811, exp: -449 }, ExtendedFloat80 { mant: 10830740992659433045, exp: -422 }, ExtendedFloat80 { mant: 16139061738043178685, exp: -396 }, ExtendedFloat80 { mant: 12024538023802026127, exp: -369 }, ExtendedFloat80 { mant: 17917957937422433684, exp: -343 }, ExtendedFloat80 { mant: 13349918974505688015, exp: -316 }, ExtendedFloat80 { mant: 9946464728195732843, exp: -289 }, ExtendedFloat80 { mant: 14821387422376473014, exp: -263 }, ExtendedFloat80 { mant: 11042794154864902060, exp: -236 }, ExtendedFloat80 { mant: 16455045573212060422, exp: -210 }, ExtendedFloat80 { mant: 12259964326927110867, exp: -183 }, ExtendedFloat80 { mant: 18268770466636286478, exp: -157 }, ExtendedFloat80 { mant: 13611294676837538539, exp: -130 }, ExtendedFloat80 { mant: 10141204801825835212, exp: -103 }, ExtendedFloat80 { mant: 15111572745182864684, exp: -77 }, ExtendedFloat80 { mant: 11258999068426240000, exp: -50 }, ExtendedFloat80 { mant: 16777216000000000000, exp: -24 }, ExtendedFloat80 { mant: 12500000000000000000, exp: 3 }, ExtendedFloat80 { mant: 9313225746154785156, exp: 30 }, ExtendedFloat80 { mant: 13877787807814456755, exp: 56 }, ExtendedFloat80 { mant: 10339757656912845936, exp: 83 }, ExtendedFloat80 { mant: 15407439555097886824, exp: 109 }, ExtendedFloat80 { mant: 11479437019748901445, exp: 136 }, ExtendedFloat80 { mant: 17105694144590052135, exp: 162 }, ExtendedFloat80 { mant: 12744735289059618216, exp: 189 }, ExtendedFloat80 { mant: 9495567745759798747, exp: 216 }, ExtendedFloat80 { mant: 14149498560666738074, exp: 242 }, ExtendedFloat80 { mant: 10542197943230523224, exp: 269 }, ExtendedFloat80 { mant: 15709099088952724970, exp: 295 }, ExtendedFloat80 { mant: 11704190886730495818, exp: 322 }, ExtendedFloat80 { mant: 17440603504673385349, exp: 348 }, ExtendedFloat80 { mant: 12994262207056124023, exp: 375 }, ExtendedFloat80 { mant: 9681479787123295682, exp: 402 }, ExtendedFloat80 { mant: 14426529090290212157, exp: 428 }, ExtendedFloat80 { mant: 10748601772107342003, exp: 455 }, ExtendedFloat80 { mant: 16016664761464807395, exp: 481 }, ExtendedFloat80 { mant: 11933345169920330789, exp: 508 }, ExtendedFloat80 { mant: 17782069995880619868, exp: 534 }, ExtendedFloat80 { mant: 13248674568444952270, exp: 561 }, ExtendedFloat80 { mant: 9871031767461413346, exp: 588 }, ExtendedFloat80 { mant: 14708983551653345445, exp: 614 }, ExtendedFloat80 { mant: 10959046745042015199, exp: 641 }, ExtendedFloat80 { mant: 16330252207878254650, exp: 667 }, ExtendedFloat80 { mant: 12166986024289022870, exp: 694 }, ExtendedFloat80 { mant: 18130221999122236476, exp: 720 }, ExtendedFloat80 { mant: 13508068024458167312, exp: 747 }, ExtendedFloat80 { mant: 10064294952495520794, exp: 774 }, ExtendedFloat80 { mant: 14996968138956309548, exp: 800 }, ExtendedFloat80 { mant: 11173611982879273257, exp: 827 }, ExtendedFloat80 { mant: 16649979327439178909, exp: 853 }, ExtendedFloat80 { mant: 12405201291620119593, exp: 880 }, ExtendedFloat80 { mant: 9242595204427927429, exp: 907 }, ExtendedFloat80 { mant: 13772540099066387757, exp: 933 }, ExtendedFloat80 { mant: 10261342003245940623, exp: 960 }, ExtendedFloat80 { mant: 15290591125556738113, exp: 986 }, ExtendedFloat80 { mant: 11392378155556871081, exp: 1013 }, ExtendedFloat80 { mant: 16975966327722178521, exp: 1039 }, ExtendedFloat80 { mant: 12648080533535911531, exp: 1066 } ]; // FTOA DECIMAL // LOOKUPS const TENS: [u64; 20] = [ 10000000000000000000, 1000000000000000000, 100000000000000000, 10000000000000000, 1000000000000000, 100000000000000, 10000000000000, 1000000000000, 100000000000, 10000000000, 1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 ]; // FPCONV GRISU perftools_inline!{ /// Round digit to sane approximation. fn round_digit(digits: &mut [u8], ndigits: usize, delta: u64, mut rem: u64, kappa: u64, mant: u64) { while rem < mant && delta - rem >= kappa && (rem + kappa < mant || mant - rem > rem + kappa - mant) { digits[ndigits - 1] -= 1; rem += kappa; } }} /// Generate digits from upper and lower range on rounding of number. fn generate_digits(fp: &ExtendedFloat80, upper: &ExtendedFloat80, lower: &ExtendedFloat80, digits: &mut [u8], k: &mut i32) -> usize { let wmant = upper.mant - fp.mant; let mut delta = upper.mant - lower.mant; let one = ExtendedFloat80 { mant: 1 << -upper.exp, exp: upper.exp, }; let mut part1 = upper.mant >> -one.exp; let mut part2 = upper.mant & (one.mant - 1); let mut idx: usize = 0; let mut kappa: i32 = 10; // 1000000000 // Guaranteed to be safe, TENS has 20 elements. let mut divp = index!(TENS[10..]).iter(); while kappa > 0 { // Remember not to continue! This loop has an increment condition. let div = divp.next().unwrap(); let digit = part1 / div; if digit != 0 || idx != 0 { digits[idx] = digit.as_u8() + b'0'; idx += 1; } part1 -= digit.as_u64() * div; kappa -= 1; let tmp = (part1 <<-one.exp) + part2; if tmp <= delta { *k += kappa; round_digit(digits, idx, delta, tmp, div << -one.exp, wmant); return idx; } } /* 10 */ // Guaranteed to be safe, TENS has 20 elements. let mut unit = index!(TENS[..=18]).iter().rev(); loop { part2 *= 10; delta *= 10; kappa -= 1; let digit = part2 >> -one.exp; if digit != 0 || idx != 0 { digits[idx] = digit.as_u8() + b'0'; idx += 1; } part2 &= one.mant - 1; let ten = unit.next().unwrap(); if part2 < delta { *k += kappa; round_digit(digits, idx, delta, part2, one.mant, wmant * ten); return idx; } } } /// Core Grisu2 algorithm for the float formatter. fn grisu2(d: f64, digits: &mut [u8], k: &mut i32) -> usize { let mut w = ExtendedFloat80::from_f64(d); let (mut lower, mut upper) = w.normalized_boundaries(); w.normalize(); let mut ki: i32 = 0; let cp = cached_grisu_power(upper.exp, &mut ki); w = w.mul(cp); upper = upper.mul(cp); lower = lower.mul(cp); lower.mant += 1; upper.mant -= 1; *k = -ki; generate_digits(&w, &upper, &lower, digits, k) } /// Write the produced digits to string. /// /// Adds formatting for exponents, and other types of information. fn emit_digits(digits: &mut [u8], mut ndigits: usize, dest: &mut [u8], k: i32) -> usize { let exp = k + ndigits.as_i32() - 1; let mut exp = exp.abs().as_usize(); // write plain integer (with ".0" suffix). if k >= 0 && exp < (ndigits + 7) { let idx = ndigits; let count = k.as_usize(); // These are all safe, since digits.len() >= idx, and // dest.len() >= idx+count+2, so the range must be valid. copy_to_dst(dest, &index!(digits[..idx])); write_bytes(&mut index_mut!(dest[idx..idx+count]), b'0'); copy_to_dst(&mut index_mut!(dest[idx+count..]), b".0"); return ndigits + k.as_usize() + 2; } // write decimal w/o scientific notation if k < 0 && (k > -7 || exp < 4) { let offset = ndigits.as_isize() - k.abs().as_isize(); // fp < 1.0 -> write leading zero if offset <= 0 { let offset = (-offset).as_usize(); // These are all safe, since digits.len() >= ndigits, and // dest.len() >= ndigits+offset+2, so the range must be valid. index_mut!(dest[0] = b'0'); index_mut!(dest[1] = b'.'); write_bytes(&mut index_mut!(dest[2..offset+2]), b'0'); copy_to_dst(&mut index_mut!(dest[offset+2..]), &index!(digits[..ndigits])); return ndigits + 2 + offset; } else { // fp > 1.0 let offset = offset.as_usize(); // These are all safe, since digits.len() >= ndigits, and // dest.len() >= ndigits+1, so the range must be valid. copy_to_dst(dest, &index!(digits[..offset])); index_mut!(dest[offset] = b'.'); copy_to_dst(&mut index_mut!(dest[offset+1..]), &index!(digits[offset..ndigits])); return ndigits + 1; } } // write decimal w/ scientific notation ndigits = ndigits.min(18); let dst_len = dest.len(); let mut dst_iter = dest.iter_mut(); let mut src_iter = digits.iter().take(ndigits); *dst_iter.next().unwrap() = *src_iter.next().unwrap(); if ndigits > 1 { *dst_iter.next().unwrap() = b'.'; for &src in src_iter { *dst_iter.next().unwrap() = src; } } *dst_iter.next().unwrap() = exponent_notation_char(10); *dst_iter.next().unwrap() = match k + ndigits.as_i32() - 1 < 0 { true => b'-', false => b'+', }; let mut cent: usize = 0; if exp > 99 { cent = exp / 100; *dst_iter.next().unwrap() = cent.as_u8() + b'0'; exp -= cent * 100; } if exp > 9 { let dec = exp / 10; *dst_iter.next().unwrap() = dec.as_u8() + b'0'; exp -= dec * 10; } else if cent != 0 { *dst_iter.next().unwrap() = b'0'; } let shift = (exp % 10).as_u8(); *dst_iter.next().unwrap() = shift + b'0'; dst_len - dst_iter.count() } perftools_inline!{ fn fpconv_dtoa(d: f64, dest: &mut [u8]) -> usize { let mut digits: [u8; 18] = [0; 18]; let mut k: i32 = 0; let ndigits = grisu2(d, &mut digits, &mut k); emit_digits(&mut digits, ndigits, dest, k) }} // DECIMAL perftools_inline!{ /// Forward to double_decimal. /// /// `f` must be non-special (NaN or infinite), non-negative, /// and non-zero. pub(crate) fn float_decimal<'a>(f: f32, bytes: &'a mut [u8]) -> usize { double_decimal(f.as_f64(), bytes) }} // F64 perftools_inline!{ /// Optimized algorithm for decimal numbers. /// /// `d` must be non-special (NaN or infinite), non-negative, /// and non-zero. pub(crate) fn double_decimal<'a>(d: f64, bytes: &'a mut [u8]) -> usize { fpconv_dtoa(d, bytes) }} lexical-core-0.7.6/src/ftoa/grisu3.rs000075500000000000000000000011560000000000000154720ustar 00000000000000//! Wrapper around David Tolnay's dtoa. use dtoa; use crate::util::*; // F32 perftools_inline!{ /// Wrapper for dtoa. /// /// `f` must be non-special (NaN or infinite), non-negative, /// and non-zero. pub(crate) fn float_decimal<'a>(f: f32, bytes: &'a mut [u8]) -> usize { dtoa::write(bytes, f).expect("Write to in-memory buffer.") }} // F64 perftools_inline!{ /// Wrapper for dtoa. /// /// `d` must be non-special (NaN or infinite), non-negative, /// and non-zero. pub(crate) fn double_decimal<'a>(d: f64, bytes: &'a mut [u8]) -> usize { dtoa::write(bytes, d).expect("Write to in-memory buffer.") }} lexical-core-0.7.6/src/ftoa/mod.rs000075500000000000000000000004310000000000000150300ustar 00000000000000//! Fast lexical float-to-string conversion routines. // Hide implementation details. #[cfg(feature = "radix")] mod radix; cfg_if! { if #[cfg(feature = "grisu3")] { mod grisu3; } else if #[cfg(feature = "ryu")] { mod ryu; } else { mod grisu2; }} // cfg_if mod api; lexical-core-0.7.6/src/ftoa/radix.rs000075500000000000000000000201460000000000000153650ustar 00000000000000//! Adaptation of the V8 ftoa algorithm with a custom radix. //! //! This algorithm is adapted from the V8 codebase, //! and may be found [here](https://github.com/v8/v8). use crate::itoa; use crate::util::*; // FTOA BASEN // ---------- // Export a character to digit. macro_rules! to_digit { ($c:expr, $radix:ident) => (($c as char).to_digit($radix)); } // Calculate the naive exponent from a minimal value. // // Don't export this for float, since it's specialized for radix. perftools_inline!{ pub(crate) fn naive_exponent(d: f64, radix: u32) -> i32 { // floor returns the minimal value, which is our // desired exponent // ln(1.1e-5) -> -4.95 -> -5 // ln(1.1e5) -> -5.04 -> 5 (d.ln() / (radix as f64).ln()).floor() as i32 }} /// Naive algorithm for converting a floating point to a custom radix. /// /// `d` must be non-special (NaN or infinite), non-negative, /// and non-zero. /// /// Adapted from the V8 implementation. fn ftoa_naive<'a>(value: f64, radix: u32, bytes: &'a mut [u8]) -> usize { debug_assert_radix!(radix); // Assert no special cases remain, no non-zero values, // and no negative numbers. debug_assert!(!value.is_special()); debug_assert!(value != 0.0); debug_assert!(value > 0.0); // Store the first digit and up to `BUFFER_SIZE - 20` digits // that occur from left-to-right in the decimal representation. // For example, for the number 123.45, store the first digit `1` // and `2345` as the remaining values. Then, decide on-the-fly // if we need scientific or regular formatting. // // BUFFER_SIZE // - 1 # first digit // - 1 # period // - 1 # +/- sign // - 2 # e and +/- sign // - 9 # max exp is 308, in radix2 is 9 // - 1 # null terminator // = 15 characters of formatting required // Just pad it a bit, we don't want memory corruption. const MAX_NONDIGIT_LENGTH: usize = 25; const MAX_DIGIT_LENGTH: usize = BUFFER_SIZE - MAX_NONDIGIT_LENGTH; // Temporary buffer for the result. We start with the decimal point in the // middle and write to the left for the integer part and to the right for the // fractional part. 1024 characters for the exponent and 52 for the mantissa // either way, with additional space for sign, decimal point and string // termination should be sufficient. const SIZE: usize = 2200; let mut buffer: [u8; SIZE] = [b'\0'; SIZE]; //let buffer = buffer.as_mut_ptr(); let initial_position: usize = SIZE / 2; let mut integer_cursor = initial_position; let mut fraction_cursor = initial_position; let base = radix as f64; // Split the value into an integer part and a fractional part. let mut integer = value.floor(); let mut fraction = value - integer; // We only compute fractional digits up to the input double's precision. let mut delta = 0.5 * (value.next_positive() - value); delta = 0.0.next_positive().max_finite(delta); debug_assert!(delta > 0.0); // Don't remove bounds checks, for a few reasons. // 1. Difficult to determine statically. // 2. Algorithm is fairly slow, in general, so performance isn't a major deal. if fraction > delta { loop { // Shift up by one digit. fraction *= base; delta *= base; // Write digit. let digit = fraction as i32; buffer[fraction_cursor] = digit_to_char(digit); fraction_cursor += 1; // Calculate remainder. fraction -= digit as f64; // Round to even. if fraction > 0.5 || (fraction == 0.5 && (digit & 1) != 0) { if fraction + delta > 1.0 { // We need to back trace already written digits in case of carry-over. loop { fraction_cursor -= 1; if fraction_cursor == initial_position-1 { // Carry over to the integer part. integer += 1.0; break; } // Reconstruct digit. let c = buffer[fraction_cursor]; if let Some(digit) = to_digit!(c, radix) { let idx = (digit + 1) as usize; buffer[fraction_cursor] = digit_to_char(idx); fraction_cursor += 1; break; } } break; } } if delta >= fraction { break; } } } // Compute integer digits. Fill unrepresented digits with zero. while (integer / base).exponent() > 0 { integer /= base; integer_cursor -= 1; buffer[integer_cursor] = b'0'; } loop { let remainder = integer % base; integer_cursor -= 1; let idx = remainder as usize; buffer[integer_cursor] = digit_to_char(idx); integer = (integer - remainder) / base; if integer <= 0.0 { break; } }; if value <= 1e-5 || value >= 1e9 { // write scientific notation with negative exponent let exponent = naive_exponent(value, radix); // Non-exponent portion. // 1. Get as many digits as possible, up to `MAX_DIGIT_LENGTH+1` // (since we are ignoring the digit for the first digit), // or the number of written digits let start: usize; let end: usize; if value <= 1e-5 { start = ((initial_position as i32) - exponent - 1) as usize; end = fraction_cursor.min(start + MAX_DIGIT_LENGTH + 1); } else { start = integer_cursor; end = fraction_cursor.min(start + MAX_DIGIT_LENGTH + 1); } let buffer = &buffer[start..end]; // 2. Remove any trailing 0s in the selected range. let buffer = rtrim_char_slice(buffer, b'0').0; // 3. Write the fraction component bytes[0] = buffer[0]; bytes[1] = b'.'; let count = copy_to_dst(&mut bytes[2..], &buffer[1..]); let bytes = &mut bytes[count+2..]; // write the exponent component bytes[0] = exponent_notation_char(radix); // Handle negative exponents. let exp: u32; if exponent < 0 { bytes[1] = b'-'; exp = exponent.wrapping_neg() as u32; itoa::itoa_positive(exp, radix, &mut bytes[2..]) + count + 4 } else { exp = exponent as u32; itoa::itoa_positive(exp, radix, &mut bytes[1..]) + count + 3 } } else { // get component lengths let integer_length = initial_position - integer_cursor; let fraction_length = (fraction_cursor - initial_position).min(MAX_DIGIT_LENGTH - integer_length); // write integer component let start = integer_cursor; let end = integer_cursor + integer_length; let count = copy_to_dst(bytes, &buffer[start..end]); let bytes = &mut bytes[count..]; // write fraction component if fraction_length > 0 { // fraction exists, write it bytes[0] = b'.'; let start = initial_position; let end = initial_position + fraction_length; copy_to_dst(&mut bytes[1..], &buffer[start..end]); integer_length + fraction_length + 1 } else { // no fraction, write decimal place copy_to_dst(bytes, ".0"); integer_length + 2 } } } // F32 // Forward to double_radix. // // `f` must be non-special (NaN or infinite), non-negative, // and non-zero. perftools_inline!{ pub(crate) fn float_radix<'a>(f: f32, radix: u32, bytes: &'a mut [u8]) -> usize { double_radix(f as f64, radix, bytes) }} // F64 // Algorithm for non-decimal string representations. // // `d` must be non-special (NaN or infinite), non-negative, // and non-zero. perftools_inline!{ pub(crate) fn double_radix<'a>(value: f64, radix: u32, bytes: &'a mut [u8]) -> usize { ftoa_naive(value, radix, bytes) }} lexical-core-0.7.6/src/ftoa/ryu.rs000075500000000000000000000011610000000000000150710ustar 00000000000000//! Wrapper around David Tolnay's ryu. use ryu::raw; use crate::util::*; // F32 perftools_inline!{ /// Wrapper for ryu. /// /// `f` must be non-special (NaN or infinite), non-negative, /// and non-zero. pub(crate) fn float_decimal<'a>(f: f32, bytes: &'a mut [u8]) -> usize { unsafe { raw::format32(f, bytes.as_mut_ptr()) } }} // F64 perftools_inline!{ /// Wrapper for ryu. /// /// `d` must be non-special (NaN or infinite), non-negative, /// and non-zero. pub(crate) fn double_decimal<'a>(d: f64, bytes: &'a mut [u8]) -> usize { unsafe { raw::format64(d, bytes.as_mut_ptr()) } }} lexical-core-0.7.6/src/itoa/api.rs000075500000000000000000001116770000000000000150440ustar 00000000000000//! Low-level API generator. //! //! Uses either the optimized decimal algorithm, the optimized generic //! algorithm, or the naive algorithm. use crate::util::*; /// Select the back-end. #[cfg(feature = "table")] use super::decimal::Decimal; #[cfg(all(feature = "table", feature = "radix"))] use super::generic::Generic; #[cfg(not(feature = "table"))] use super::naive::Naive; // HELPERS // Wrapper to facilitate calling a backend that writes iteratively to // the end of the buffer. #[cfg(any(not(feature = "table"), feature = "radix"))] macro_rules! write_backwards { ($value:ident, $radix:expr, $buffer:ident, $t:tt, $cb:ident) => ({ // Create a temporary buffer, and copy into it. // Way faster than reversing a buffer in-place. // Need to ensure the buffer size is adequate for any radix, but // small for the optimized decimal formatters. debug_assert_radix!($radix); let mut buffer: [u8; BUFFER_SIZE] = [b'0'; BUFFER_SIZE]; let digits; if cfg!(not(feature = "radix")) || $radix == 10 { digits = &mut buffer[..$t::FORMATTED_SIZE_DECIMAL]; } else { digits = &mut buffer[..$t::FORMATTED_SIZE]; } // Write backwards to buffer and copy output to slice. let offset = $value.$cb($radix, digits); debug_assert!(offset <= digits.len()); copy_to_dst($buffer, &unchecked_index!(digits[offset..])) }); } #[cfg(all(feature = "table", not(feature = "radix")))] pub(crate) trait Itoa: Decimal + UnsignedInteger {} #[cfg(all(feature = "table", feature = "radix"))] pub(crate) trait Itoa: Decimal + Generic + UnsignedInteger {} #[cfg(not(feature = "table"))] pub(crate) trait Itoa: Naive + UnsignedInteger {} macro_rules! itoa_impl { ($($t:ty)*) => ($( impl Itoa for $t {} )*) } itoa_impl! { u8 u16 u32 u64 u128 usize } // FORWARD // Forward itoa arguments to an optimized backend. // Preconditions: `value` must be non-negative and unsigned. perftools_inline!{ #[cfg(all(feature = "table", not(feature = "radix")))] pub(crate) fn itoa_positive(value: T, _: u32, buffer: &mut [u8]) -> usize where T: Itoa { value.decimal(buffer) }} // Forward itoa arguments to an optimized backend. // Preconditions: `value` must be non-negative and unsigned. perftools_inline!{ #[cfg(all(feature = "table", feature = "radix"))] pub(crate) fn itoa_positive(value: T, radix: u32, buffer: &mut [u8]) -> usize where T: Itoa { if radix == 10 { value.decimal(buffer) } else { write_backwards!(value, radix, buffer, T, generic) } }} // Forward itoa arguments to a naive backend. // Preconditions: `value` must be non-negative and unsigned. perftools_inline!{ #[cfg(not(feature = "table"))] pub(crate) fn itoa_positive(value: T, radix: u32, buffer: &mut [u8]) -> usize where T: Itoa { write_backwards!(value, radix, buffer, T, naive) }} // TO LEXICAL // Callback for unsigned integer formatter. perftools_inline!{ fn unsigned(value: Narrow, radix: u32, buffer: &mut [u8]) -> usize where Narrow: UnsignedInteger, Wide: Itoa { let value: Wide = as_cast(value); itoa_positive(value, radix, buffer) }} macro_rules! unsigned_to_lexical { ($narrow:ty, $wide:ty) => ( to_lexical!(unsigned::<$narrow, $wide>, $narrow); ); } unsigned_to_lexical!(u8, u32); unsigned_to_lexical!(u16, u32); unsigned_to_lexical!(u32, u32); unsigned_to_lexical!(u64, u64); unsigned_to_lexical!(u128, u128); #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))] unsigned_to_lexical!(usize, u32); #[cfg(target_pointer_width = "64")] unsigned_to_lexical!(usize, u64); // Callback for signed integer formatter. perftools_inline!{ fn signed(value: Narrow, radix: u32, buffer: &mut [u8]) -> usize where Narrow: SignedInteger, Wide: SignedInteger, Unsigned: Itoa { if value < Narrow::ZERO { unchecked_index_mut!(buffer[0] = b'-'); let value: Wide = as_cast(value); let value: Unsigned = as_cast(value.wrapping_neg()); itoa_positive(value, radix, &mut unchecked_index_mut!(buffer[1..])) + 1 } else { let value: Unsigned = as_cast(value); itoa_positive(value, radix, buffer) } }} macro_rules! signed_to_lexical { ($narrow:ty, $wide:ty, $unsigned:ty) => ( to_lexical!(signed::<$narrow, $wide, $unsigned>, $narrow); ); } signed_to_lexical!(i8, i32, u32); signed_to_lexical!(i16, i32, u32); signed_to_lexical!(i32, i32, u32); signed_to_lexical!(i64, i64, u64); signed_to_lexical!(i128, i128, u128); #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))] signed_to_lexical!(isize, i32, u32); #[cfg(target_pointer_width = "64")] signed_to_lexical!(isize, i64, u64); // TESTS // ----- #[cfg(test)] mod tests { // Shouldn't need to include atoi, should be fine with ToLexical in scope. use crate::util::*; use crate::util::test::*; #[cfg(feature = "property_tests")] use quickcheck::quickcheck; #[cfg(all(feature = "std", feature = "property_tests"))] use proptest::proptest; // GENERIC #[test] fn u8_test() { let mut buffer = new_buffer(); assert_eq!(b"0", 0u8.to_lexical(&mut buffer)); assert_eq!(b"1", 1u8.to_lexical(&mut buffer)); assert_eq!(b"5", 5u8.to_lexical(&mut buffer)); assert_eq!(b"127", 127u8.to_lexical(&mut buffer)); assert_eq!(b"128", 128u8.to_lexical(&mut buffer)); assert_eq!(b"255", 255u8.to_lexical(&mut buffer)); assert_eq!(b"255", (-1i8 as u8).to_lexical(&mut buffer)); } #[test] fn i8_test() { let mut buffer = new_buffer(); assert_eq!(b"0", 0i8.to_lexical(&mut buffer)); assert_eq!(b"1", 1i8.to_lexical(&mut buffer)); assert_eq!(b"5", 5i8.to_lexical(&mut buffer)); assert_eq!(b"127", 127i8.to_lexical(&mut buffer)); assert_eq!(b"-128", (128u8 as i8).to_lexical(&mut buffer)); assert_eq!(b"-1", (255u8 as i8).to_lexical(&mut buffer)); assert_eq!(b"-1", (-1i8).to_lexical(&mut buffer)); } #[test] fn u16_test() { let mut buffer = new_buffer(); assert_eq!(b"0", 0u16.to_lexical(&mut buffer)); assert_eq!(b"1", 1u16.to_lexical(&mut buffer)); assert_eq!(b"5", 5u16.to_lexical(&mut buffer)); assert_eq!(b"32767", 32767u16.to_lexical(&mut buffer)); assert_eq!(b"32768", 32768u16.to_lexical(&mut buffer)); assert_eq!(b"65535", 65535u16.to_lexical(&mut buffer)); assert_eq!(b"65535", (-1i16 as u16).to_lexical(&mut buffer)); } #[test] fn i16_test() { let mut buffer = new_buffer(); assert_eq!(b"0", 0i16.to_lexical(&mut buffer)); assert_eq!(b"1", 1i16.to_lexical(&mut buffer)); assert_eq!(b"5", 5i16.to_lexical(&mut buffer)); assert_eq!(b"32767", 32767i16.to_lexical(&mut buffer)); assert_eq!(b"-32768", (32768u16 as i16).to_lexical(&mut buffer)); assert_eq!(b"-1", (65535u16 as i16).to_lexical(&mut buffer)); assert_eq!(b"-1", (-1i16).to_lexical(&mut buffer)); } #[test] fn u32_test() { let mut buffer = new_buffer(); assert_eq!(b"0", 0u32.to_lexical(&mut buffer)); assert_eq!(b"1", 1u32.to_lexical(&mut buffer)); assert_eq!(b"5", 5u32.to_lexical(&mut buffer)); assert_eq!(b"2147483647", 2147483647u32.to_lexical(&mut buffer)); assert_eq!(b"2147483648", 2147483648u32.to_lexical(&mut buffer)); assert_eq!(b"4294967295", 4294967295u32.to_lexical(&mut buffer)); assert_eq!(b"4294967295", (-1i32 as u32).to_lexical(&mut buffer)); } #[test] fn i32_test() { let mut buffer = new_buffer(); assert_eq!(b"0", 0i32.to_lexical(&mut buffer)); assert_eq!(b"1", 1i32.to_lexical(&mut buffer)); assert_eq!(b"5", 5i32.to_lexical(&mut buffer)); assert_eq!(b"2147483647", 2147483647i32.to_lexical(&mut buffer)); assert_eq!(b"-2147483648", (2147483648u32 as i32).to_lexical(&mut buffer)); assert_eq!(b"-1", (4294967295u32 as i32).to_lexical(&mut buffer)); assert_eq!(b"-1", (-1i32).to_lexical(&mut buffer)); } #[test] fn u64_test() { let mut buffer = new_buffer(); assert_eq!(b"0", 0u64.to_lexical(&mut buffer)); assert_eq!(b"1", 1u64.to_lexical(&mut buffer)); assert_eq!(b"5", 5u64.to_lexical(&mut buffer)); assert_eq!(b"9223372036854775807", 9223372036854775807u64.to_lexical(&mut buffer)); assert_eq!(b"9223372036854775808", 9223372036854775808u64.to_lexical(&mut buffer)); assert_eq!(b"18446744073709551615", 18446744073709551615u64.to_lexical(&mut buffer)); assert_eq!(b"18446744073709551615", (-1i64 as u64).to_lexical(&mut buffer)); } #[test] fn i64_test() { let mut buffer = new_buffer(); assert_eq!(b"0", 0i64.to_lexical(&mut buffer)); assert_eq!(b"1", 1i64.to_lexical(&mut buffer)); assert_eq!(b"5", 5i64.to_lexical(&mut buffer)); assert_eq!(b"9223372036854775807", 9223372036854775807i64.to_lexical(&mut buffer)); assert_eq!(b"-9223372036854775808", (9223372036854775808u64 as i64).to_lexical(&mut buffer)); assert_eq!(b"-1", (18446744073709551615u64 as i64).to_lexical(&mut buffer)); assert_eq!(b"-1", (-1i64).to_lexical(&mut buffer)); } #[test] fn u128_test() { let mut buffer = new_buffer(); assert_eq!(b"0", 0u128.to_lexical(&mut buffer)); assert_eq!(b"1", 1u128.to_lexical(&mut buffer)); assert_eq!(b"5", 5u128.to_lexical(&mut buffer)); assert_eq!(&b"170141183460469231731687303715884105727"[..], 170141183460469231731687303715884105727u128.to_lexical(&mut buffer)); assert_eq!(&b"170141183460469231731687303715884105728"[..], 170141183460469231731687303715884105728u128.to_lexical(&mut buffer)); assert_eq!(&b"340282366920938463463374607431768211455"[..], 340282366920938463463374607431768211455u128.to_lexical(&mut buffer)); assert_eq!(&b"340282366920938463463374607431768211455"[..], (-1i128 as u128).to_lexical(&mut buffer)); } #[test] fn i128_test() { let mut buffer = new_buffer(); assert_eq!(b"0", 0i128.to_lexical(&mut buffer)); assert_eq!(b"1", 1i128.to_lexical(&mut buffer)); assert_eq!(b"5", 5i128.to_lexical(&mut buffer)); assert_eq!(&b"170141183460469231731687303715884105727"[..], 170141183460469231731687303715884105727i128.to_lexical(&mut buffer)); assert_eq!(&b"-170141183460469231731687303715884105728"[..], (170141183460469231731687303715884105728u128 as i128).to_lexical(&mut buffer)); assert_eq!(b"-1", (340282366920938463463374607431768211455u128 as i128).to_lexical(&mut buffer)); assert_eq!(b"-1", (-1i128).to_lexical(&mut buffer)); } #[cfg(feature = "radix")] #[test] fn radix_test() { let data = [ (2, "100101"), (3, "1101"), (4, "211"), (5, "122"), (6, "101"), (7, "52"), (8, "45"), (9, "41"), (10, "37"), (11, "34"), (12, "31"), (13, "2B"), (14, "29"), (15, "27"), (16, "25"), (17, "23"), (18, "21"), (19, "1I"), (20, "1H"), (21, "1G"), (22, "1F"), (23, "1E"), (24, "1D"), (25, "1C"), (26, "1B"), (27, "1A"), (28, "19"), (29, "18"), (30, "17"), (31, "16"), (32, "15"), (33, "14"), (34, "13"), (35, "12"), (36, "11"), ]; let mut buffer = new_buffer(); for (base, expected) in data.iter() { assert_eq!(expected.as_bytes(), 37.to_lexical_radix(*base, &mut buffer)); } } // Extensive tests #[test] fn u8_pow2_test() { let mut buffer = new_buffer(); let values: &[u8] = &[0, 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255]; for &i in values.iter() { assert_eq!(i, u8::from_lexical(i.to_lexical(&mut buffer)).unwrap()); } } #[test] fn u8_pow10_test() { let mut buffer = new_buffer(); let values: &[u8] = &[0, 1, 5, 9, 10, 11, 15, 99, 100, 101, 105]; for &i in values.iter() { assert_eq!(i, u8::from_lexical(i.to_lexical(&mut buffer)).unwrap()); } } #[test] fn u16_pow2_test() { let mut buffer = new_buffer(); let values: &[u16] = &[0, 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255, 256, 257, 511, 512, 513, 1023, 1024, 1025, 2047, 2048, 2049, 4095, 4096, 4097, 8191, 8192, 8193, 16383, 16384, 16385, 32767, 32768, 32769, 65535]; for &i in values.iter() { assert_eq!(i, u16::from_lexical(i.to_lexical(&mut buffer)).unwrap()); } } #[test] fn u16_pow10_test() { let mut buffer = new_buffer(); let values: &[u16] = &[0, 1, 5, 9, 10, 11, 15, 99, 100, 101, 105, 999, 1000, 1001, 1005, 9999, 10000, 10001, 10005]; for &i in values.iter() { assert_eq!(i, u16::from_lexical(i.to_lexical(&mut buffer)).unwrap()); } } #[test] fn u32_pow2_test() { let mut buffer = new_buffer(); let values: &[u32] = &[0, 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255, 256, 257, 511, 512, 513, 1023, 1024, 1025, 2047, 2048, 2049, 4095, 4096, 4097, 8191, 8192, 8193, 16383, 16384, 16385, 32767, 32768, 32769, 65535, 65536, 65537, 131071, 131072, 131073, 262143, 262144, 262145, 524287, 524288, 524289, 1048575, 1048576, 1048577, 2097151, 2097152, 2097153, 4194303, 4194304, 4194305, 8388607, 8388608, 8388609, 16777215, 16777216, 16777217, 33554431, 33554432, 33554433, 67108863, 67108864, 67108865, 134217727, 134217728, 134217729, 268435455, 268435456, 268435457, 536870911, 536870912, 536870913, 1073741823, 1073741824, 1073741825, 2147483647, 2147483648, 2147483649, 4294967295]; for &i in values.iter() { assert_eq!(i, u32::from_lexical(i.to_lexical(&mut buffer)).unwrap()); } } #[test] fn u32_pow10_test() { let mut buffer = new_buffer(); let values: &[u32] = &[0, 1, 5, 9, 10, 11, 15, 99, 100, 101, 105, 999, 1000, 1001, 1005, 9999, 10000, 10001, 10005, 99999, 100000, 100001, 100005, 999999, 1000000, 1000001, 1000005, 9999999, 10000000, 10000001, 10000005, 99999999, 100000000, 100000001, 100000005, 999999999, 1000000000, 1000000001, 1000000005]; for &i in values.iter() { assert_eq!(i, u32::from_lexical(i.to_lexical(&mut buffer)).unwrap()); } } #[test] fn u64_pow2_test() { let mut buffer = new_buffer(); let values: &[u64] = &[0, 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255, 256, 257, 511, 512, 513, 1023, 1024, 1025, 2047, 2048, 2049, 4095, 4096, 4097, 8191, 8192, 8193, 16383, 16384, 16385, 32767, 32768, 32769, 65535, 65536, 65537, 131071, 131072, 131073, 262143, 262144, 262145, 524287, 524288, 524289, 1048575, 1048576, 1048577, 2097151, 2097152, 2097153, 4194303, 4194304, 4194305, 8388607, 8388608, 8388609, 16777215, 16777216, 16777217, 33554431, 33554432, 33554433, 67108863, 67108864, 67108865, 134217727, 134217728, 134217729, 268435455, 268435456, 268435457, 536870911, 536870912, 536870913, 1073741823, 1073741824, 1073741825, 2147483647, 2147483648, 2147483649, 4294967295, 4294967296, 4294967297, 8589934591, 8589934592, 8589934593, 17179869183, 17179869184, 17179869185, 34359738367, 34359738368, 34359738369, 68719476735, 68719476736, 68719476737, 137438953471, 137438953472, 137438953473, 274877906943, 274877906944, 274877906945, 549755813887, 549755813888, 549755813889, 1099511627775, 1099511627776, 1099511627777, 2199023255551, 2199023255552, 2199023255553, 4398046511103, 4398046511104, 4398046511105, 8796093022207, 8796093022208, 8796093022209, 17592186044415, 17592186044416, 17592186044417, 35184372088831, 35184372088832, 35184372088833, 70368744177663, 70368744177664, 70368744177665, 140737488355327, 140737488355328, 140737488355329, 281474976710655, 281474976710656, 281474976710657, 562949953421311, 562949953421312, 562949953421313, 1125899906842623, 1125899906842624, 1125899906842625, 2251799813685247, 2251799813685248, 2251799813685249, 4503599627370495, 4503599627370496, 4503599627370497, 9007199254740991, 9007199254740992, 9007199254740993, 18014398509481983, 18014398509481984, 18014398509481985, 36028797018963967, 36028797018963968, 36028797018963969, 72057594037927935, 72057594037927936, 72057594037927937, 144115188075855871, 144115188075855872, 144115188075855873, 288230376151711743, 288230376151711744, 288230376151711745, 576460752303423487, 576460752303423488, 576460752303423489, 1152921504606846975, 1152921504606846976, 1152921504606846977, 2305843009213693951, 2305843009213693952, 2305843009213693953, 4611686018427387903, 4611686018427387904, 4611686018427387905, 9223372036854775807, 9223372036854775808, 9223372036854775809, 18446744073709551615]; for &i in values.iter() { assert_eq!(i, u64::from_lexical(i.to_lexical(&mut buffer)).unwrap()); } } #[test] fn u64_pow10_test() { let mut buffer = new_buffer(); let values: &[u64] = &[0, 1, 5, 9, 10, 11, 15, 99, 100, 101, 105, 999, 1000, 1001, 1005, 9999, 10000, 10001, 10005, 99999, 100000, 100001, 100005, 999999, 1000000, 1000001, 1000005, 9999999, 10000000, 10000001, 10000005, 99999999, 100000000, 100000001, 100000005, 999999999, 1000000000, 1000000001, 1000000005, 9999999999, 10000000000, 10000000001, 10000000005, 99999999999, 100000000000, 100000000001, 100000000005, 999999999999, 1000000000000, 1000000000001, 1000000000005, 9999999999999, 10000000000000, 10000000000001, 10000000000005, 99999999999999, 100000000000000, 100000000000001, 100000000000005, 999999999999999, 1000000000000000, 1000000000000001, 1000000000000005, 9999999999999999, 10000000000000000, 10000000000000001, 10000000000000005, 99999999999999999, 100000000000000000, 100000000000000001, 100000000000000005, 999999999999999999, 1000000000000000000, 1000000000000000001, 1000000000000000005]; for &i in values.iter() { assert_eq!(i, u64::from_lexical(i.to_lexical(&mut buffer)).unwrap()); } } #[test] fn u128_pow2_test() { let mut buffer = new_buffer(); let values: &[u128] = &[0, 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255, 256, 257, 511, 512, 513, 1023, 1024, 1025, 2047, 2048, 2049, 4095, 4096, 4097, 8191, 8192, 8193, 16383, 16384, 16385, 32767, 32768, 32769, 65535, 65536, 65537, 131071, 131072, 131073, 262143, 262144, 262145, 524287, 524288, 524289, 1048575, 1048576, 1048577, 2097151, 2097152, 2097153, 4194303, 4194304, 4194305, 8388607, 8388608, 8388609, 16777215, 16777216, 16777217, 33554431, 33554432, 33554433, 67108863, 67108864, 67108865, 134217727, 134217728, 134217729, 268435455, 268435456, 268435457, 536870911, 536870912, 536870913, 1073741823, 1073741824, 1073741825, 2147483647, 2147483648, 2147483649, 4294967295, 4294967296, 4294967297, 8589934591, 8589934592, 8589934593, 17179869183, 17179869184, 17179869185, 34359738367, 34359738368, 34359738369, 68719476735, 68719476736, 68719476737, 137438953471, 137438953472, 137438953473, 274877906943, 274877906944, 274877906945, 549755813887, 549755813888, 549755813889, 1099511627775, 1099511627776, 1099511627777, 2199023255551, 2199023255552, 2199023255553, 4398046511103, 4398046511104, 4398046511105, 8796093022207, 8796093022208, 8796093022209, 17592186044415, 17592186044416, 17592186044417, 35184372088831, 35184372088832, 35184372088833, 70368744177663, 70368744177664, 70368744177665, 140737488355327, 140737488355328, 140737488355329, 281474976710655, 281474976710656, 281474976710657, 562949953421311, 562949953421312, 562949953421313, 1125899906842623, 1125899906842624, 1125899906842625, 2251799813685247, 2251799813685248, 2251799813685249, 4503599627370495, 4503599627370496, 4503599627370497, 9007199254740991, 9007199254740992, 9007199254740993, 18014398509481983, 18014398509481984, 18014398509481985, 36028797018963967, 36028797018963968, 36028797018963969, 72057594037927935, 72057594037927936, 72057594037927937, 144115188075855871, 144115188075855872, 144115188075855873, 288230376151711743, 288230376151711744, 288230376151711745, 576460752303423487, 576460752303423488, 576460752303423489, 1152921504606846975, 1152921504606846976, 1152921504606846977, 2305843009213693951, 2305843009213693952, 2305843009213693953, 4611686018427387903, 4611686018427387904, 4611686018427387905, 9223372036854775807, 9223372036854775808, 9223372036854775809, 18446744073709551615, 18446744073709551616, 18446744073709551617, 36893488147419103231, 36893488147419103232, 36893488147419103233, 73786976294838206463, 73786976294838206464, 73786976294838206465, 147573952589676412927, 147573952589676412928, 147573952589676412929, 295147905179352825855, 295147905179352825856, 295147905179352825857, 590295810358705651711, 590295810358705651712, 590295810358705651713, 1180591620717411303423, 1180591620717411303424, 1180591620717411303425, 2361183241434822606847, 2361183241434822606848, 2361183241434822606849, 4722366482869645213695, 4722366482869645213696, 4722366482869645213697, 9444732965739290427391, 9444732965739290427392, 9444732965739290427393, 18889465931478580854783, 18889465931478580854784, 18889465931478580854785, 37778931862957161709567, 37778931862957161709568, 37778931862957161709569, 75557863725914323419135, 75557863725914323419136, 75557863725914323419137, 151115727451828646838271, 151115727451828646838272, 151115727451828646838273, 302231454903657293676543, 302231454903657293676544, 302231454903657293676545, 604462909807314587353087, 604462909807314587353088, 604462909807314587353089, 1208925819614629174706175, 1208925819614629174706176, 1208925819614629174706177, 2417851639229258349412351, 2417851639229258349412352, 2417851639229258349412353, 4835703278458516698824703, 4835703278458516698824704, 4835703278458516698824705, 9671406556917033397649407, 9671406556917033397649408, 9671406556917033397649409, 19342813113834066795298815, 19342813113834066795298816, 19342813113834066795298817, 38685626227668133590597631, 38685626227668133590597632, 38685626227668133590597633, 77371252455336267181195263, 77371252455336267181195264, 77371252455336267181195265, 154742504910672534362390527, 154742504910672534362390528, 154742504910672534362390529, 309485009821345068724781055, 309485009821345068724781056, 309485009821345068724781057, 618970019642690137449562111, 618970019642690137449562112, 618970019642690137449562113, 1237940039285380274899124223, 1237940039285380274899124224, 1237940039285380274899124225, 2475880078570760549798248447, 2475880078570760549798248448, 2475880078570760549798248449, 4951760157141521099596496895, 4951760157141521099596496896, 4951760157141521099596496897, 9903520314283042199192993791, 9903520314283042199192993792, 9903520314283042199192993793, 19807040628566084398385987583, 19807040628566084398385987584, 19807040628566084398385987585, 39614081257132168796771975167, 39614081257132168796771975168, 39614081257132168796771975169, 79228162514264337593543950335, 79228162514264337593543950336, 79228162514264337593543950337, 158456325028528675187087900671, 158456325028528675187087900672, 158456325028528675187087900673, 316912650057057350374175801343, 316912650057057350374175801344, 316912650057057350374175801345, 633825300114114700748351602687, 633825300114114700748351602688, 633825300114114700748351602689, 1267650600228229401496703205375, 1267650600228229401496703205376, 1267650600228229401496703205377, 2535301200456458802993406410751, 2535301200456458802993406410752, 2535301200456458802993406410753, 5070602400912917605986812821503, 5070602400912917605986812821504, 5070602400912917605986812821505, 10141204801825835211973625643007, 10141204801825835211973625643008, 10141204801825835211973625643009, 20282409603651670423947251286015, 20282409603651670423947251286016, 20282409603651670423947251286017, 40564819207303340847894502572031, 40564819207303340847894502572032, 40564819207303340847894502572033, 81129638414606681695789005144063, 81129638414606681695789005144064, 81129638414606681695789005144065, 162259276829213363391578010288127, 162259276829213363391578010288128, 162259276829213363391578010288129, 324518553658426726783156020576255, 324518553658426726783156020576256, 324518553658426726783156020576257, 649037107316853453566312041152511, 649037107316853453566312041152512, 649037107316853453566312041152513, 1298074214633706907132624082305023, 1298074214633706907132624082305024, 1298074214633706907132624082305025, 2596148429267413814265248164610047, 2596148429267413814265248164610048, 2596148429267413814265248164610049, 5192296858534827628530496329220095, 5192296858534827628530496329220096, 5192296858534827628530496329220097, 10384593717069655257060992658440191, 10384593717069655257060992658440192, 10384593717069655257060992658440193, 20769187434139310514121985316880383, 20769187434139310514121985316880384, 20769187434139310514121985316880385, 41538374868278621028243970633760767, 41538374868278621028243970633760768, 41538374868278621028243970633760769, 83076749736557242056487941267521535, 83076749736557242056487941267521536, 83076749736557242056487941267521537, 166153499473114484112975882535043071, 166153499473114484112975882535043072, 166153499473114484112975882535043073, 332306998946228968225951765070086143, 332306998946228968225951765070086144, 332306998946228968225951765070086145, 664613997892457936451903530140172287, 664613997892457936451903530140172288, 664613997892457936451903530140172289, 1329227995784915872903807060280344575, 1329227995784915872903807060280344576, 1329227995784915872903807060280344577, 2658455991569831745807614120560689151, 2658455991569831745807614120560689152, 2658455991569831745807614120560689153, 5316911983139663491615228241121378303, 5316911983139663491615228241121378304, 5316911983139663491615228241121378305, 10633823966279326983230456482242756607, 10633823966279326983230456482242756608, 10633823966279326983230456482242756609, 21267647932558653966460912964485513215, 21267647932558653966460912964485513216, 21267647932558653966460912964485513217, 42535295865117307932921825928971026431, 42535295865117307932921825928971026432, 42535295865117307932921825928971026433, 85070591730234615865843651857942052863, 85070591730234615865843651857942052864, 85070591730234615865843651857942052865, 170141183460469231731687303715884105727, 170141183460469231731687303715884105728, 170141183460469231731687303715884105729, 340282366920938463463374607431768211455]; for &i in values.iter() { assert_eq!(i, u128::from_lexical(i.to_lexical(&mut buffer)).unwrap()); } } #[test] fn u128_pow10_test() { let mut buffer = new_buffer(); let values: &[u128] = &[0, 1, 5, 9, 10, 11, 15, 99, 100, 101, 105, 999, 1000, 1001, 1005, 9999, 10000, 10001, 10005, 99999, 100000, 100001, 100005, 999999, 1000000, 1000001, 1000005, 9999999, 10000000, 10000001, 10000005, 99999999, 100000000, 100000001, 100000005, 999999999, 1000000000, 1000000001, 1000000005, 9999999999, 10000000000, 10000000001, 10000000005, 99999999999, 100000000000, 100000000001, 100000000005, 999999999999, 1000000000000, 1000000000001, 1000000000005, 9999999999999, 10000000000000, 10000000000001, 10000000000005, 99999999999999, 100000000000000, 100000000000001, 100000000000005, 999999999999999, 1000000000000000, 1000000000000001, 1000000000000005, 9999999999999999, 10000000000000000, 10000000000000001, 10000000000000005, 99999999999999999, 100000000000000000, 100000000000000001, 100000000000000005, 999999999999999999, 1000000000000000000, 1000000000000000001, 1000000000000000005, 9999999999999999999, 10000000000000000000, 10000000000000000001, 10000000000000000005, 99999999999999999999, 100000000000000000000, 100000000000000000001, 100000000000000000005, 999999999999999999999, 1000000000000000000000, 1000000000000000000001, 1000000000000000000005, 9999999999999999999999, 10000000000000000000000, 10000000000000000000001, 10000000000000000000005, 99999999999999999999999, 100000000000000000000000, 100000000000000000000001, 100000000000000000000005, 999999999999999999999999, 1000000000000000000000000, 1000000000000000000000001, 1000000000000000000000005, 9999999999999999999999999, 10000000000000000000000000, 10000000000000000000000001, 10000000000000000000000005, 99999999999999999999999999, 100000000000000000000000000, 100000000000000000000000001, 100000000000000000000000005, 999999999999999999999999999, 1000000000000000000000000000, 1000000000000000000000000001, 1000000000000000000000000005, 9999999999999999999999999999, 10000000000000000000000000000, 10000000000000000000000000001, 10000000000000000000000000005, 99999999999999999999999999999, 100000000000000000000000000000, 100000000000000000000000000001, 100000000000000000000000000005, 999999999999999999999999999999, 1000000000000000000000000000000, 1000000000000000000000000000001, 1000000000000000000000000000005, 9999999999999999999999999999999, 10000000000000000000000000000000, 10000000000000000000000000000001, 10000000000000000000000000000005, 99999999999999999999999999999999, 100000000000000000000000000000000, 100000000000000000000000000000001, 100000000000000000000000000000005, 999999999999999999999999999999999, 1000000000000000000000000000000000, 1000000000000000000000000000000001, 1000000000000000000000000000000005, 9999999999999999999999999999999999, 10000000000000000000000000000000000, 10000000000000000000000000000000001, 10000000000000000000000000000000005, 99999999999999999999999999999999999, 100000000000000000000000000000000000, 100000000000000000000000000000000001, 100000000000000000000000000000000005, 999999999999999999999999999999999999, 1000000000000000000000000000000000000, 1000000000000000000000000000000000001, 1000000000000000000000000000000000005, 9999999999999999999999999999999999999, 10000000000000000000000000000000000000, 10000000000000000000000000000000000001, 10000000000000000000000000000000000005, 99999999999999999999999999999999999999, 100000000000000000000000000000000000000, 100000000000000000000000000000000000001, 100000000000000000000000000000000000005]; for &i in values.iter() { assert_eq!(i, u128::from_lexical(i.to_lexical(&mut buffer)).unwrap()); } } // Quickcheck #[cfg(feature = "property_tests")] quickcheck! { fn u8_quickcheck(i: u8) -> bool { let mut buffer = new_buffer(); i == u8::from_lexical(i.to_lexical(&mut buffer)).unwrap() } fn u16_quickcheck(i: u16) -> bool { let mut buffer = new_buffer(); i == u16::from_lexical(i.to_lexical(&mut buffer)).unwrap() } fn u32_quickcheck(i: u32) -> bool { let mut buffer = new_buffer(); i == u32::from_lexical(i.to_lexical(&mut buffer)).unwrap() } fn u64_quickcheck(i: u64) -> bool { let mut buffer = new_buffer(); i == u64::from_lexical(i.to_lexical(&mut buffer)).unwrap() } fn u128_quickcheck(i: u128) -> bool { let mut buffer = new_buffer(); i == u128::from_lexical(i.to_lexical(&mut buffer)).unwrap() } fn usize_quickcheck(i: usize) -> bool { let mut buffer = new_buffer(); i == usize::from_lexical(i.to_lexical(&mut buffer)).unwrap() } fn i8_quickcheck(i: i8) -> bool { let mut buffer = new_buffer(); i == i8::from_lexical(i.to_lexical(&mut buffer)).unwrap() } fn i16_quickcheck(i: i16) -> bool { let mut buffer = new_buffer(); i == i16::from_lexical(i.to_lexical(&mut buffer)).unwrap() } fn i32_quickcheck(i: i32) -> bool { let mut buffer = new_buffer(); i == i32::from_lexical(i.to_lexical(&mut buffer)).unwrap() } fn i64_quickcheck(i: i64) -> bool { let mut buffer = new_buffer(); i == i64::from_lexical(i.to_lexical(&mut buffer)).unwrap() } fn i128_quickcheck(i: i128) -> bool { let mut buffer = new_buffer(); i == i128::from_lexical(i.to_lexical(&mut buffer)).unwrap() } fn isize_quickcheck(i: isize) -> bool { let mut buffer = new_buffer(); i == isize::from_lexical(i.to_lexical(&mut buffer)).unwrap() } } // Proptest #[cfg(all(feature = "std", feature = "property_tests"))] proptest! { #[test] fn u8_proptest(i in u8::min_value()..u8::max_value()) { let mut buffer = new_buffer(); assert_eq!(i, u8::from_lexical(i.to_lexical(&mut buffer)).unwrap()) } #[test] fn i8_proptest(i in i8::min_value()..i8::max_value()) { let mut buffer = new_buffer(); assert_eq!(i, i8::from_lexical(i.to_lexical(&mut buffer)).unwrap()) } #[test] fn u16_proptest(i in u16::min_value()..u16::max_value()) { let mut buffer = new_buffer(); assert_eq!(i, u16::from_lexical(i.to_lexical(&mut buffer)).unwrap()) } #[test] fn i16_proptest(i in i16::min_value()..i16::max_value()) { let mut buffer = new_buffer(); assert_eq!(i, i16::from_lexical(i.to_lexical(&mut buffer)).unwrap()) } #[test] fn u32_proptest(i in u32::min_value()..u32::max_value()) { let mut buffer = new_buffer(); assert_eq!(i, u32::from_lexical(i.to_lexical(&mut buffer)).unwrap()) } #[test] fn i32_proptest(i in i32::min_value()..i32::max_value()) { let mut buffer = new_buffer(); assert_eq!(i, i32::from_lexical(i.to_lexical(&mut buffer)).unwrap()) } #[test] fn u64_proptest(i in u64::min_value()..u64::max_value()) { let mut buffer = new_buffer(); assert_eq!(i, u64::from_lexical(i.to_lexical(&mut buffer)).unwrap()) } #[test] fn i64_proptest(i in i64::min_value()..i64::max_value()) { let mut buffer = new_buffer(); assert_eq!(i, i64::from_lexical(i.to_lexical(&mut buffer)).unwrap()) } #[test] fn u128_proptest(i in u128::min_value()..u128::max_value()) { let mut buffer = new_buffer(); assert_eq!(i, u128::from_lexical(i.to_lexical(&mut buffer)).unwrap()) } #[test] fn i128_proptest(i in i128::min_value()..i128::max_value()) { let mut buffer = new_buffer(); assert_eq!(i, i128::from_lexical(i.to_lexical(&mut buffer)).unwrap()) } #[test] fn usize_proptest(i in usize::min_value()..usize::max_value()) { let mut buffer = new_buffer(); assert_eq!(i, usize::from_lexical(i.to_lexical(&mut buffer)).unwrap()) } #[test] fn isize_proptest(i in isize::min_value()..isize::max_value()) { let mut buffer = new_buffer(); assert_eq!(i, isize::from_lexical(i.to_lexical(&mut buffer)).unwrap()) } } // Panic tests #[test] #[should_panic] fn i8_buffer_test() { let mut buffer = [b'0'; i8::FORMATTED_SIZE_DECIMAL-1]; 12i8.to_lexical(&mut buffer); } #[test] #[should_panic] fn i16_buffer_test() { let mut buffer = [b'0'; i16::FORMATTED_SIZE_DECIMAL-1]; 12i16.to_lexical(&mut buffer); } #[test] #[should_panic] fn i32_buffer_test() { let mut buffer = [b'0'; i32::FORMATTED_SIZE_DECIMAL-1]; 12i32.to_lexical(&mut buffer); } #[test] #[should_panic] fn i64_buffer_test() { let mut buffer = [b'0'; i64::FORMATTED_SIZE_DECIMAL-1]; 12i64.to_lexical(&mut buffer); } #[test] #[should_panic] fn i128_buffer_test() { let mut buffer = [b'0'; i128::FORMATTED_SIZE_DECIMAL-1]; 12i128.to_lexical(&mut buffer); } #[test] #[should_panic] fn isize_buffer_test() { let mut buffer = [b'0'; isize::FORMATTED_SIZE_DECIMAL-1]; 12isize.to_lexical(&mut buffer); } #[test] #[should_panic] fn u8_buffer_test() { let mut buffer = [b'0'; u8::FORMATTED_SIZE_DECIMAL-1]; 12i8.to_lexical(&mut buffer); } #[test] #[should_panic] fn u16_buffer_test() { let mut buffer = [b'0'; u16::FORMATTED_SIZE_DECIMAL-1]; 12i16.to_lexical(&mut buffer); } #[test] #[should_panic] fn u32_buffer_test() { let mut buffer = [b'0'; u32::FORMATTED_SIZE_DECIMAL-1]; 12i32.to_lexical(&mut buffer); } #[test] #[should_panic] fn u64_buffer_test() { let mut buffer = [b'0'; u64::FORMATTED_SIZE_DECIMAL-1]; 12i64.to_lexical(&mut buffer); } #[test] #[should_panic] fn u128_buffer_test() { let mut buffer = [b'0'; u128::FORMATTED_SIZE_DECIMAL-1]; 12i128.to_lexical(&mut buffer); } #[test] #[should_panic] fn usize_buffer_test() { let mut buffer = [b'0'; usize::FORMATTED_SIZE_DECIMAL-1]; 12usize.to_lexical(&mut buffer); } } lexical-core-0.7.6/src/itoa/decimal.rs000075500000000000000000000771700000000000000156700ustar 00000000000000//! Fast lexical integer-to-string conversion routines for decimal strings. // The following algorithms aim to minimize the number of conditional // jumps required, by requiring at most 5 linear conditions before // jumping to a condition-less set of instructions. This allows high // performance formatting for integer sizes, and scales well for // both sequential values (primarily low number of digits) and uniform // values (primarily high numbers of digits), however, it also works // well even with branch misprediction (tested using a linear congruent // generator to choose between a sequential or uniform integer). // // The performance is ~2-3x the performance of traditional integer // formatters (see, dtolnay/itoa, or the generic algorithm) for 32-bits // or less, highlighting the advantage of removing for loops with // minimal branches. It also scales well for 64 or more bit integers. // The following benchmarks were run on an "Intel(R) Core(TM) i7-6560U // CPU @ 2.20GHz" CPU, on Fedora 28, Linux kernel version 4.18.16-200 // (x86-64), using the lexical formatter, `itoa::write()` or `x.to_string()`, // avoiding any inefficiencies in Rust string parsing for `format!(...)` // or `write!()` macros. The code was compiled with LTO and at an optimization // level of 3. // // The benchmarks with `std` were compiled using "rustc 1.32.0 // (9fda7c223 2019-01-16". // // The benchmark code may be found `benches/itoa.rs`. // // # Benchmarks // // | Type | lexical (ns/iter) | libcore (ns/iter) | Relative Increase | // |:-----:|:------------------:|:---------------------:|:-----------------:| // | u8 | 55,072 | 376,625 | 6.84x | // | u16 | 51,219 | 385,722 | 7.53x | // | u32 | 120,378 | 410,117 | 3.41x | // | u64 | 187,850 | 489,783 | 2.60x | // | u128 | 2,056,008 | 14,556,649 | 7.08x | // | i8 | 81,346 | 414,715 | 5.10x | // | i16 | 102,664 | 447,581 | 5.50x | // | i32 | 149,340 | 475,189 | 3.18x | // | i64 | 230,283 | 527,589 | 2.29x | // | i128 | 2,052,915 | 14,600,861 | 7.11x | // // # Raw Benchmarks // // ```text // test itoa_i8_itoa ... bench: 126,392 ns/iter (+/- 5,778) // test itoa_i8_lexical ... bench: 81,346 ns/iter (+/- 1,476) // test itoa_i8_std ... bench: 414,715 ns/iter (+/- 5,695) // test itoa_i16_itoa ... bench: 142,794 ns/iter (+/- 8,103) // test itoa_i16_lexical ... bench: 102,664 ns/iter (+/- 2,735) // test itoa_i16_std ... bench: 447,581 ns/iter (+/- 47,814) // test itoa_i32_itoa ... bench: 173,478 ns/iter (+/- 7,305) // test itoa_i32_lexical ... bench: 149,340 ns/iter (+/- 9,998) // test itoa_i32_std ... bench: 475,189 ns/iter (+/- 32,131) // test itoa_i64_itoa ... bench: 198,176 ns/iter (+/- 16,321) // test itoa_i64_lexical ... bench: 230,283 ns/iter (+/- 5,156) // test itoa_i64_std ... bench: 527,589 ns/iter (+/- 9,557) // test itoa_i128_itoa ... bench: 2,047,257 ns/iter (+/- 73,000) // test itoa_i128_lexical ... bench: 2,052,915 ns/iter (+/- 74,725) // test itoa_i128_std ... bench: 14,600,861 ns/iter (+/- 271,447) // test itoa_u8_heterogeneous_itoa ... bench: 292,486 ns/iter (+/- 9,220) // test itoa_u8_heterogeneous_lexical ... bench: 206,873 ns/iter (+/- 2,046) // test itoa_u8_heterogeneous_std ... bench: 750,418 ns/iter (+/- 15,635) // test itoa_u8_itoa ... bench: 105,066 ns/iter (+/- 2,855) // test itoa_u8_lexical ... bench: 55,072 ns/iter (+/- 1,549) // test itoa_u8_simple_itoa ... bench: 69,004 ns/iter (+/- 1,619) // test itoa_u8_simple_lexical ... bench: 28,524 ns/iter (+/- 1,577) // test itoa_u8_simple_std ... bench: 317,812 ns/iter (+/- 14,782) // test itoa_u8_std ... bench: 376,625 ns/iter (+/- 10,076) // test itoa_u16_heterogeneous_itoa ... bench: 286,189 ns/iter (+/- 16,636) // test itoa_u16_heterogeneous_lexical ... bench: 214,915 ns/iter (+/- 7,595) // test itoa_u16_heterogeneous_std ... bench: 797,362 ns/iter (+/- 39,345) // test itoa_u16_itoa ... bench: 90,015 ns/iter (+/- 1,597) // test itoa_u16_lexical ... bench: 51,219 ns/iter (+/- 5,323) // test itoa_u16_simple_itoa ... bench: 92,558 ns/iter (+/- 2,638) // test itoa_u16_simple_lexical ... bench: 42,701 ns/iter (+/- 3,799) // test itoa_u16_simple_std ... bench: 363,527 ns/iter (+/- 20,206) // test itoa_u16_std ... bench: 385,722 ns/iter (+/- 14,945) // test itoa_u32_heterogeneous_itoa ... bench: 319,279 ns/iter (+/- 8,077) // test itoa_u32_heterogeneous_lexical ... bench: 262,614 ns/iter (+/- 10,914) // test itoa_u32_heterogeneous_std ... bench: 830,270 ns/iter (+/- 38,468) // test itoa_u32_itoa ... bench: 114,494 ns/iter (+/- 2,552) // test itoa_u32_lexical ... bench: 120,378 ns/iter (+/- 4,930) // test itoa_u32_simple_itoa ... bench: 89,981 ns/iter (+/- 4,136) // test itoa_u32_simple_lexical ... bench: 42,902 ns/iter (+/- 2,875) // test itoa_u32_simple_std ... bench: 366,203 ns/iter (+/- 14,009) // test itoa_u32_std ... bench: 410,117 ns/iter (+/- 15,781) // test itoa_u64_heterogeneous_itoa ... bench: 399,933 ns/iter (+/- 9,702) // test itoa_u64_heterogeneous_lexical ... bench: 348,971 ns/iter (+/- 5,901) // test itoa_u64_heterogeneous_std ... bench: 928,328 ns/iter (+/- 27,413) // test itoa_u64_itoa ... bench: 205,365 ns/iter (+/- 20,925) // test itoa_u64_lexical ... bench: 187,850 ns/iter (+/- 5,501) // test itoa_u64_simple_itoa ... bench: 91,360 ns/iter (+/- 3,417) // test itoa_u64_simple_lexical ... bench: 43,714 ns/iter (+/- 771) // test itoa_u64_simple_std ... bench: 373,320 ns/iter (+/- 6,293) // test itoa_u64_std ... bench: 489,783 ns/iter (+/- 27,719) // test itoa_u128_heterogeneous_itoa ... bench: 2,313,010 ns/iter (+/- 56,841) // test itoa_u128_heterogeneous_lexical ... bench: 2,219,170 ns/iter (+/- 61,161) // test itoa_u128_heterogeneous_std ... bench: 15,076,380 ns/iter (+/- 206,851) // test itoa_u128_itoa ... bench: 2,084,005 ns/iter (+/- 55,530) // test itoa_u128_lexical ... bench: 2,056,008 ns/iter (+/- 76,115) // test itoa_u128_simple_itoa ... bench: 112,675 ns/iter (+/- 6,788) // test itoa_u128_simple_lexical ... bench: 59,320 ns/iter (+/- 2,386) // test itoa_u128_simple_std ... bench: 365,819 ns/iter (+/- 17,862) // test itoa_u128_std ... bench: 14,556,649 ns/iter (+/- 238,244) // ``` // Code the generate the benchmark plot: // import numpy as np // import pandas as pd // import matplotlib.pyplot as plt // plt.style.use('ggplot') // lexical = np.array([55072, 51219, 120378, 187850, 2056008, 81346, 102664, 149340, 230283, 2052915]) / 1e3 // itoa = np.array([105066, 90015, 114494, 205365, 2084005, 126392, 142794, 173478, 198176, 2047257]) / 1e3 // rustcore = np.array([376625, 385722, 410117, 489783, 14556649, 414715, 447581, 475189, 527589, 14600861]) / 1e3 // index = ["u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", "i64", "i128"] // df = pd.DataFrame({'lexical': lexical, 'itoa': itoa, 'rustcore': rustcore}, index = index, columns=['lexical', 'itoa', 'rustcore']) // ax = df.plot.bar(rot=0, figsize=(16, 8), fontsize=14, color=['#E24A33', '#988ED5', '#348ABD']) // ax.set_ylabel("ms/iter") // ax.set_yscale('log') // ax.figure.tight_layout() // ax.legend(loc=2, prop={'size': 14}) // plt.show() use crate::util::*; // Lookup table for optimized base10 itoa. const TABLE: &[u8] = &DIGIT_TO_BASE10_SQUARED; // DIGIT COUNT // ----------- // Hyper-optimized integer formatters using bit-twiddling tricks for // base10. These are meant to be correct, however, they use bit-twiddling // tricks so they may not be very legible. // Calculate the number of leading 0s. macro_rules! cltz { ($value:ident) => { $value.leading_zeros().as_usize() }; } // Calculate the offset where the digits were first written. macro_rules! calculate_offset { ($value:ident, $digits:ident, $max_digits:expr, $size:expr) => ({ // Get the log2 of the value to estimate the log10 quickly. // log2(0) is undefined, always ensure 1 bit is set. let value = $value | 1; let log2 = $size - cltz!(value); // Estimate log10(value) to calculate number of digits. // Put in safe guards so we always have at least 1 digit. // Our magic numbers are: // 1233 / 2^12 == log10(2) // These magic numbers are valid for any value <= 2**18, // which encompasses all offsets (<= 40). let digits = (log2 * 1233) >> 12; let mut offset = $max_digits - digits - 1; debug_assert!(offset < $digits.len()); if digits != 0 && unchecked_index!($digits[offset]) == b'0' { offset += 1; } offset }); } // INDEXING // -------- // Convert sequential values to index. macro_rules! sequential_index { ($v0:ident, $v1:ident) => (($v0 * 2 - $v1 * 200).as_usize()); } // Convert singular value to index. macro_rules! last_index { ($value:ident) => ((2 * $value).as_usize()); } // WRITE // ----- // Write N digits to buffer. // Write 1 digit to buffer. perftools_inline!{ #[allow(unused_unsafe)] fn write_1(value: u32, buffer: &mut [u8]) { unchecked_index_mut!(buffer[0] = digit_to_char(value)); }} // Write 2 digits to buffer. perftools_inline!{ #[allow(unused_unsafe)] fn write_2(value: u32, buffer: &mut [u8]) { let i_0 = last_index!(value); unchecked_index_mut!(buffer[1] = unchecked_index!(TABLE[i_0+1])); unchecked_index_mut!(buffer[0] = unchecked_index!(TABLE[i_0+0])); }} // Write 3 digits to buffer. perftools_inline!{ #[allow(unused_unsafe)] fn write_3(value: u32, buffer: &mut [u8]) { let v_0 = value; let v_1 = v_0 / 100; let i_0 = sequential_index!(v_0, v_1); let i_1 = last_index!(v_1); unchecked_index_mut!(buffer[2] = unchecked_index!(TABLE[i_0+1])); unchecked_index_mut!(buffer[1] = unchecked_index!(TABLE[i_0+0])); unchecked_index_mut!(buffer[0] = unchecked_index!(TABLE[i_1+1])); }} // Write 4 digits to buffer. perftools_inline!{ #[allow(unused_unsafe)] fn write_4(value: u32, buffer: &mut [u8]) { let v_0 = value; let v_1 = v_0 / 100; let i_0 = sequential_index!(v_0, v_1); let i_1 = last_index!(v_1); unchecked_index_mut!(buffer[3] = unchecked_index!(TABLE[i_0+1])); unchecked_index_mut!(buffer[2] = unchecked_index!(TABLE[i_0+0])); unchecked_index_mut!(buffer[1] = unchecked_index!(TABLE[i_1+1])); unchecked_index_mut!(buffer[0] = unchecked_index!(TABLE[i_1+0])); }} // Write 5 digits to buffer. perftools_inline!{ #[allow(unused_unsafe)] fn write_5(value: u32, buffer: &mut [u8]) { let v_0 = value; let v_1 = v_0 / 100; let v_2 = v_1 / 100; let i_0 = sequential_index!(v_0, v_1); let i_1 = sequential_index!(v_1, v_2); let i_2 = last_index!(v_2); unchecked_index_mut!(buffer[4] = unchecked_index!(TABLE[i_0+1])); unchecked_index_mut!(buffer[3] = unchecked_index!(TABLE[i_0+0])); unchecked_index_mut!(buffer[2] = unchecked_index!(TABLE[i_1+1])); unchecked_index_mut!(buffer[1] = unchecked_index!(TABLE[i_1+0])); unchecked_index_mut!(buffer[0] = unchecked_index!(TABLE[i_2+1])); }} // Write 10 digits to buffer. perftools_inline!{ #[allow(unused_unsafe)] fn write_10(value: u32, buffer: &mut [u8]) { let t0 = value / 100000000; let v_0 = value.wrapping_sub(t0.wrapping_mul(100000000)); let v_1 = v_0 / 100; let v_2 = v_1 / 100; let v_3 = v_2 / 100; let v_4 = t0; let i_0 = sequential_index!(v_0, v_1); let i_1 = sequential_index!(v_1, v_2); let i_2 = sequential_index!(v_2, v_3); let i_3 = last_index!(v_3); let i_4 = last_index!(v_4); unchecked_index_mut!(buffer[9] = unchecked_index!(TABLE[i_0+1])); unchecked_index_mut!(buffer[8] = unchecked_index!(TABLE[i_0+0])); unchecked_index_mut!(buffer[7] = unchecked_index!(TABLE[i_1+1])); unchecked_index_mut!(buffer[6] = unchecked_index!(TABLE[i_1+0])); unchecked_index_mut!(buffer[5] = unchecked_index!(TABLE[i_2+1])); unchecked_index_mut!(buffer[4] = unchecked_index!(TABLE[i_2+0])); unchecked_index_mut!(buffer[3] = unchecked_index!(TABLE[i_3+1])); unchecked_index_mut!(buffer[2] = unchecked_index!(TABLE[i_3+0])); unchecked_index_mut!(buffer[1] = unchecked_index!(TABLE[i_4+1])); unchecked_index_mut!(buffer[0] = unchecked_index!(TABLE[i_4+0])); }} // Write 15 digits to buffer. perftools_inline!{ #[allow(unused_unsafe)] fn write_15(value: u64, buffer: &mut [u8]) { let t_0 = (value / 100000000).as_u32(); let v_0 = value.as_u32().wrapping_sub(t_0.wrapping_mul(100000000)); let v_1 = v_0 / 100; let v_2 = v_1 / 100; let v_3 = v_2 / 100; let v_4 = t_0; let v_5 = v_4 / 100; let v_6 = v_5 / 100; let v_7 = v_6 / 100; let i_0 = sequential_index!(v_0, v_1); let i_1 = sequential_index!(v_1, v_2); let i_2 = sequential_index!(v_2, v_3); let i_3 = last_index!(v_3); let i_4 = sequential_index!(v_4, v_5); let i_5 = sequential_index!(v_5, v_6); let i_6 = sequential_index!(v_6, v_7); let i_7 = last_index!(v_7); unchecked_index_mut!(buffer[14] = unchecked_index!(TABLE[i_0+1])); unchecked_index_mut!(buffer[13] = unchecked_index!(TABLE[i_0+0])); unchecked_index_mut!(buffer[12] = unchecked_index!(TABLE[i_1+1])); unchecked_index_mut!(buffer[11] = unchecked_index!(TABLE[i_1+0])); unchecked_index_mut!(buffer[10] = unchecked_index!(TABLE[i_2+1])); unchecked_index_mut!(buffer[9] = unchecked_index!(TABLE[i_2+0])); unchecked_index_mut!(buffer[8] = unchecked_index!(TABLE[i_3+1])); unchecked_index_mut!(buffer[7] = unchecked_index!(TABLE[i_3+0])); unchecked_index_mut!(buffer[6] = unchecked_index!(TABLE[i_4+1])); unchecked_index_mut!(buffer[5] = unchecked_index!(TABLE[i_4+0])); unchecked_index_mut!(buffer[4] = unchecked_index!(TABLE[i_5+1])); unchecked_index_mut!(buffer[3] = unchecked_index!(TABLE[i_5+0])); unchecked_index_mut!(buffer[2] = unchecked_index!(TABLE[i_6+1])); unchecked_index_mut!(buffer[1] = unchecked_index!(TABLE[i_6+0])); unchecked_index_mut!(buffer[0] = unchecked_index!(TABLE[i_7+1])); }} // Write 19 digits to buffer (used internally for the u128 writers). perftools_inline!{ #[allow(unused_unsafe)] fn write_19(value: u64, buffer: &mut [u8]) { let t_0 = (value / 100000000).as_u32(); let t_1 = (value / 10000000000000000).as_u32(); let v_0 = value.as_u32().wrapping_sub(t_0.wrapping_mul(100000000)); let v_1 = v_0 / 100; let v_2 = v_1 / 100; let v_3 = v_2 / 100; let v_4 = t_0.wrapping_sub(t_1.wrapping_mul(100000000)); let v_5 = v_4 / 100; let v_6 = v_5 / 100; let v_7 = v_6 / 100; let v_8 = t_1; let v_9 = v_8 / 100; let i_0 = sequential_index!(v_0, v_1); let i_1 = sequential_index!(v_1, v_2); let i_2 = sequential_index!(v_2, v_3); let i_3 = last_index!(v_3); let i_4 = sequential_index!(v_4, v_5); let i_5 = sequential_index!(v_5, v_6); let i_6 = sequential_index!(v_6, v_7); let i_7 = last_index!(v_7); let i_8 = sequential_index!(v_8, v_9); let i_9 = last_index!(v_9); unchecked_index_mut!(buffer[18] = unchecked_index!(TABLE[i_0+1])); unchecked_index_mut!(buffer[17] = unchecked_index!(TABLE[i_0+0])); unchecked_index_mut!(buffer[16] = unchecked_index!(TABLE[i_1+1])); unchecked_index_mut!(buffer[15] = unchecked_index!(TABLE[i_1+0])); unchecked_index_mut!(buffer[14] = unchecked_index!(TABLE[i_2+1])); unchecked_index_mut!(buffer[13] = unchecked_index!(TABLE[i_2+0])); unchecked_index_mut!(buffer[12] = unchecked_index!(TABLE[i_3+1])); unchecked_index_mut!(buffer[11] = unchecked_index!(TABLE[i_3+0])); unchecked_index_mut!(buffer[10] = unchecked_index!(TABLE[i_4+1])); unchecked_index_mut!(buffer[9] = unchecked_index!(TABLE[i_4+0])); unchecked_index_mut!(buffer[8] = unchecked_index!(TABLE[i_5+1])); unchecked_index_mut!(buffer[7] = unchecked_index!(TABLE[i_5+0])); unchecked_index_mut!(buffer[6] = unchecked_index!(TABLE[i_6+1])); unchecked_index_mut!(buffer[5] = unchecked_index!(TABLE[i_6+0])); unchecked_index_mut!(buffer[4] = unchecked_index!(TABLE[i_7+1])); unchecked_index_mut!(buffer[3] = unchecked_index!(TABLE[i_7+0])); unchecked_index_mut!(buffer[2] = unchecked_index!(TABLE[i_8+1])); unchecked_index_mut!(buffer[1] = unchecked_index!(TABLE[i_8+0])); unchecked_index_mut!(buffer[0] = unchecked_index!(TABLE[i_9+1])); }} // Write 20 digits to buffer. perftools_inline!{ #[allow(unused_unsafe)] fn write_20(value: u64, buffer: &mut [u8]) { let t_0 = (value / 100000000).as_u32(); let t_1 = (value / 10000000000000000).as_u32(); let v_0 = value.as_u32().wrapping_sub(t_0.wrapping_mul(100000000)); let v_1 = v_0 / 100; let v_2 = v_1 / 100; let v_3 = v_2 / 100; let v_4 = t_0.wrapping_sub(t_1.wrapping_mul(100000000)); let v_5 = v_4 / 100; let v_6 = v_5 / 100; let v_7 = v_6 / 100; let v_8 = t_1; let v_9 = v_8 / 100; let i_0 = sequential_index!(v_0, v_1); let i_1 = sequential_index!(v_1, v_2); let i_2 = sequential_index!(v_2, v_3); let i_3 = last_index!(v_3); let i_4 = sequential_index!(v_4, v_5); let i_5 = sequential_index!(v_5, v_6); let i_6 = sequential_index!(v_6, v_7); let i_7 = last_index!(v_7); let i_8 = sequential_index!(v_8, v_9); let i_9 = last_index!(v_9); unchecked_index_mut!(buffer[19] = unchecked_index!(TABLE[i_0+1])); unchecked_index_mut!(buffer[18] = unchecked_index!(TABLE[i_0+0])); unchecked_index_mut!(buffer[17] = unchecked_index!(TABLE[i_1+1])); unchecked_index_mut!(buffer[16] = unchecked_index!(TABLE[i_1+0])); unchecked_index_mut!(buffer[15] = unchecked_index!(TABLE[i_2+1])); unchecked_index_mut!(buffer[14] = unchecked_index!(TABLE[i_2+0])); unchecked_index_mut!(buffer[13] = unchecked_index!(TABLE[i_3+1])); unchecked_index_mut!(buffer[12] = unchecked_index!(TABLE[i_3+0])); unchecked_index_mut!(buffer[11] = unchecked_index!(TABLE[i_4+1])); unchecked_index_mut!(buffer[10] = unchecked_index!(TABLE[i_4+0])); unchecked_index_mut!(buffer[9] = unchecked_index!(TABLE[i_5+1])); unchecked_index_mut!(buffer[8] = unchecked_index!(TABLE[i_5+0])); unchecked_index_mut!(buffer[7] = unchecked_index!(TABLE[i_6+1])); unchecked_index_mut!(buffer[6] = unchecked_index!(TABLE[i_6+0])); unchecked_index_mut!(buffer[5] = unchecked_index!(TABLE[i_7+1])); unchecked_index_mut!(buffer[4] = unchecked_index!(TABLE[i_7+0])); unchecked_index_mut!(buffer[3] = unchecked_index!(TABLE[i_8+1])); unchecked_index_mut!(buffer[2] = unchecked_index!(TABLE[i_8+0])); unchecked_index_mut!(buffer[1] = unchecked_index!(TABLE[i_9+1])); unchecked_index_mut!(buffer[0] = unchecked_index!(TABLE[i_9+0])); }} // Write 25 digits to buffer. perftools_inline!{ #[allow(unused_unsafe)] fn write_25(value: u128, buffer: &mut [u8]) { // Split value into high 6 and low 19. let (high, low) = u128_divrem_1e19(value); // Write low 19 to the end of the buffer. write_19(low, &mut unchecked_index_mut!(buffer[6..])); // Write high 6 to the front of the buffer. let value = high.as_u64(); let v_0 = value.as_u32(); let v_1 = v_0 / 100; let v_2 = v_1 / 100; let i_0 = sequential_index!(v_0, v_1); let i_1 = sequential_index!(v_1, v_2); let i_2 = last_index!(v_2); unchecked_index_mut!(buffer[5] = unchecked_index!(TABLE[i_0+1])); unchecked_index_mut!(buffer[4] = unchecked_index!(TABLE[i_0+0])); unchecked_index_mut!(buffer[3] = unchecked_index!(TABLE[i_1+1])); unchecked_index_mut!(buffer[2] = unchecked_index!(TABLE[i_1+0])); unchecked_index_mut!(buffer[1] = unchecked_index!(TABLE[i_2+1])); unchecked_index_mut!(buffer[0] = unchecked_index!(TABLE[i_2+0])); }} // Write 29 digits to buffer. perftools_inline!{ #[allow(unused_unsafe)] fn write_29(value: u128, buffer: &mut [u8]) { // Split value into high 10 and low 19. let (high, low) = u128_divrem_1e19(value); // Write low 19 to the end of the buffer. write_19(low, &mut unchecked_index_mut!(buffer[10..])); // Write high 10 to the front of the buffer. let value = high.as_u64(); let t_0 = (value / 100000000).as_u32(); let v_0 = value.as_u32().wrapping_sub(t_0.wrapping_mul(100000000)); let v_1 = v_0 / 100; let v_2 = v_1 / 100; let v_3 = v_2 / 100; let v_4 = t_0; let i_0 = sequential_index!(v_0, v_1); let i_1 = sequential_index!(v_1, v_2); let i_2 = sequential_index!(v_2, v_3); let i_3 = last_index!(v_3); let i_4 = last_index!(v_4); unchecked_index_mut!(buffer[9] = unchecked_index!(TABLE[i_0+1])); unchecked_index_mut!(buffer[8] = unchecked_index!(TABLE[i_0+0])); unchecked_index_mut!(buffer[7] = unchecked_index!(TABLE[i_1+1])); unchecked_index_mut!(buffer[6] = unchecked_index!(TABLE[i_1+0])); unchecked_index_mut!(buffer[5] = unchecked_index!(TABLE[i_2+1])); unchecked_index_mut!(buffer[4] = unchecked_index!(TABLE[i_2+0])); unchecked_index_mut!(buffer[3] = unchecked_index!(TABLE[i_3+1])); unchecked_index_mut!(buffer[2] = unchecked_index!(TABLE[i_3+0])); unchecked_index_mut!(buffer[1] = unchecked_index!(TABLE[i_4+1])); unchecked_index_mut!(buffer[0] = unchecked_index!(TABLE[i_4+0])); }} // Write 34 digits to buffer. perftools_inline!{ #[allow(unused_unsafe)] fn write_34(value: u128, buffer: &mut [u8]) { // Split value into high 15 and low 19. let (high, low) = u128_divrem_1e19(value); // Write low 19 to the end of the buffer. write_19(low, &mut unchecked_index_mut!(buffer[15..])); // Write high 15 to the front of the buffer. let value = high.as_u64(); let t_0 = (value / 100000000).as_u32(); let v_0 = value.as_u32().wrapping_sub(t_0.wrapping_mul(100000000)); let v_1 = v_0 / 100; let v_2 = v_1 / 100; let v_3 = v_2 / 100; let v_4 = t_0; let v_5 = v_4 / 100; let v_6 = v_5 / 100; let v_7 = v_6 / 100; let i_0 = sequential_index!(v_0, v_1); let i_1 = sequential_index!(v_1, v_2); let i_2 = sequential_index!(v_2, v_3); let i_3 = last_index!(v_3); let i_4 = sequential_index!(v_4, v_5); let i_5 = sequential_index!(v_5, v_6); let i_6 = sequential_index!(v_6, v_7); let i_7 = last_index!(v_7); unchecked_index_mut!(buffer[14] = unchecked_index!(TABLE[i_0+1])); unchecked_index_mut!(buffer[13] = unchecked_index!(TABLE[i_0+0])); unchecked_index_mut!(buffer[12] = unchecked_index!(TABLE[i_1+1])); unchecked_index_mut!(buffer[11] = unchecked_index!(TABLE[i_1+0])); unchecked_index_mut!(buffer[10] = unchecked_index!(TABLE[i_2+1])); unchecked_index_mut!(buffer[9] = unchecked_index!(TABLE[i_2+0])); unchecked_index_mut!(buffer[8] = unchecked_index!(TABLE[i_3+1])); unchecked_index_mut!(buffer[7] = unchecked_index!(TABLE[i_3+0])); unchecked_index_mut!(buffer[6] = unchecked_index!(TABLE[i_4+1])); unchecked_index_mut!(buffer[5] = unchecked_index!(TABLE[i_4+0])); unchecked_index_mut!(buffer[4] = unchecked_index!(TABLE[i_5+1])); unchecked_index_mut!(buffer[3] = unchecked_index!(TABLE[i_5+0])); unchecked_index_mut!(buffer[2] = unchecked_index!(TABLE[i_6+1])); unchecked_index_mut!(buffer[1] = unchecked_index!(TABLE[i_6+0])); unchecked_index_mut!(buffer[0] = unchecked_index!(TABLE[i_7+1])); }} // Write 39 digits to buffer. perftools_inline!{ #[allow(unused_unsafe)] fn write_39(value: u128, buffer: &mut [u8]) { // Split value into high 20 and low 19. let (high, low) = u128_divrem_1e19(value); // Write low 19 to the end of the buffer. write_19(low, &mut unchecked_index_mut!(buffer[20..])); // Split the value into the high 1 and mid 19. let (high, mid) = u128_divrem_1e19(high); // Write mid 19 to the middle of the buffer. write_19(mid, &mut unchecked_index_mut!(buffer[1..])); // Write high 1 to the front of the buffer. unchecked_index_mut!(buffer[0] = digit_to_char(high)); }} // WRITE RAMGE // ----------- // Write range of digits to buffer, optionally using a temporary buffer // and copying the digits over. // Write 1-3 digits (from a u8 value). perftools_inline!{ fn write_1_3(value: u32, buffer: &mut [u8]) -> usize { if value < 10 { write_1(value, buffer); 1 } else if value < 100 { write_2(value, buffer); 2 } else { write_3(value, buffer); 3 } }} // Write 1-3 digits (from a u16 value). perftools_inline!{ fn write_1_5(value: u32, buffer: &mut [u8]) -> usize { if value < 10 { write_1(value, buffer); 1 } else if value < 100 { write_2(value, buffer); 2 } else if value < 1000 { write_3(value, buffer); 3 } else if value < 10000 { write_4(value, buffer); 4 } else { write_5(value, buffer); 5 } }} // Write 5-10 digits (from a u32 value). perftools_inline!{ fn write_5_10(value: u32, buffer: &mut [u8]) -> usize { // Use a temporary buffer so we only need a single code path. let mut tmp_buf: [u8; 16] = [b'0'; 16]; let digits = &mut tmp_buf[..10]; write_10(value, digits); let offset = calculate_offset!(value, digits, 10, 32); copy_to_dst(buffer, &unchecked_index!(digits[offset..])) }} // Write 10-15 digits (from a u64 value). perftools_inline!{ fn write_10_15(value: u64, buffer: &mut [u8]) -> usize { // Use a temporary buffer so we only need a single code path. let mut tmp_buf: [u8; 32] = [b'0'; 32]; let digits = &mut tmp_buf[..15]; write_15(value, digits); let offset = calculate_offset!(value, digits, 15, 64); copy_to_dst(buffer, &unchecked_index!(digits[offset..])) }} // Write 15-20 digits (from a u64 value). perftools_inline!{ fn write_15_20(value: u64, buffer: &mut [u8]) -> usize { // Use a temporary buffer so we only need a single code path. let mut tmp_buf: [u8; 32] = [b'0'; 32]; let digits = &mut tmp_buf[..20]; write_20(value, digits); let offset = calculate_offset!(value, digits, 20, 64); copy_to_dst(buffer, &unchecked_index!(digits[offset..])) }} // Write 20-25 digits (from a u64 value). perftools_inline!{ fn write_20_25(value: u128, buffer: &mut [u8]) -> usize { // Use a temporary buffer so we only need a single code path. let mut tmp_buf: [u8; 64] = [b'0'; 64]; let digits = &mut tmp_buf[..25]; write_25(value, digits); let offset = calculate_offset!(value, digits, 25, 128); copy_to_dst(buffer, &unchecked_index!(digits[offset..])) }} // Write 25-29 digits (from a u64 value). perftools_inline!{ fn write_25_29(value: u128, buffer: &mut [u8]) -> usize { // Use a temporary buffer so we only need a single code path. let mut tmp_buf: [u8; 64] = [b'0'; 64]; let digits = &mut tmp_buf[..29]; write_29(value, digits); let offset = calculate_offset!(value, digits, 29, 128); copy_to_dst(buffer, &unchecked_index!(digits[offset..])) }} // Write 29-34 digits (from a u64 value). perftools_inline!{ fn write_29_34(value: u128, buffer: &mut [u8]) -> usize { // Use a temporary buffer so we only need a single code path. let mut tmp_buf: [u8; 64] = [b'0'; 64]; let digits = &mut tmp_buf[..34]; write_34(value, digits); let offset = calculate_offset!(value, digits, 34, 128); copy_to_dst(buffer, &unchecked_index!(digits[offset..])) }} // Write 34-39 digits (from a u64 value). perftools_inline!{ fn write_34_39(value: u128, buffer: &mut [u8]) -> usize { // Use a temporary buffer so we only need a single code path. let mut tmp_buf: [u8; 64] = [b'0'; 64]; let digits = &mut tmp_buf[..39]; write_39(value, digits); let offset = calculate_offset!(value, digits, 39, 128); copy_to_dst(buffer, &unchecked_index!(digits[offset..])) }} // FORMATTERS // ---------- // Each flow-path should have no more than 5 comparisons, or // else we're poorly optimizing our code. // Use the number of leading zeros to minimize the number // of jumps we have possible. // Internal integer formatter for u8. perftools_inline!{ fn u8toa(value: u8, buffer: &mut [u8]) -> usize { write_1_3(value.as_u32(), buffer) }} // Internal integer formatter for u16. perftools_inline!{ fn u16toa(value: u16, buffer: &mut [u8]) -> usize { write_1_5(value.as_u32(), buffer) }} // Internal integer formatter for u32. perftools_inline!{ fn u32toa(value: u32, buffer: &mut [u8]) -> usize { if value >> 16 == 0 { // [0, 2^16 - 1] write_1_5(value, buffer) } else { // [2^16, 2^32 - 1] write_5_10(value, buffer) } }} // Internal integer formatter for u64. perftools_inline!{ fn u64toa(value: u64, buffer: &mut [u8]) -> usize { if value >> 16 == 0 { // [0, 2^16 - 1] write_1_5(value.as_u32(), buffer) } else if value >> 32 == 0 { // [2^16, 2^32 - 1] write_5_10(value.as_u32(), buffer) } else if value >> 48 == 0 { // [2^32, 2^48 - 1] write_10_15(value, buffer) } else { // [2^48, 2^64 - 1] write_15_20(value, buffer) } }} // Internal integer formatter for u128. perftools_inline!{ fn u128toa(value: u128, buffer: &mut [u8]) -> usize { if value >> 16 == 0 { // [0, 2^16 - 1] write_1_5(value.as_u32(), buffer) } else if value >> 32 == 0 { // [2^16, 2^32 - 1] write_5_10(value.as_u32(), buffer) } else if value >> 48 == 0 { // [2^32, 2^48 - 1] write_10_15(value.as_u64(), buffer) } else if value >> 64 == 0 { // [2^48, 2^64 - 1] write_15_20(value.as_u64(), buffer) } else if value >> 80 == 0 { // [2^64, 2^80 - 1] write_20_25(value, buffer) } else if value >> 96 == 0 { // [2^80, 2^96 - 1] write_25_29(value, buffer) } else if value >> 112 == 0 { // [2^96, 2^112 - 1] write_29_34(value, buffer) } else { // [2^112, 2^128 - 1] write_34_39(value, buffer) } }} cfg_if! { if #[cfg(target_pointer_width = "16")] { perftools_inline!{ fn usizetoa(value: usize, buffer: &mut [u8]) -> usize { u16toa(value.as_u16(), buffer) }} } else if #[cfg(target_pointer_width = "32")] { perftools_inline!{ fn usizetoa(value: usize, buffer: &mut [u8]) -> usize { u32toa(value.as_u32(), buffer) }} } else if #[cfg(target_pointer_width = "64")] { perftools_inline!{ fn usizetoa(value: usize, buffer: &mut [u8]) -> usize { u64toa(value.as_u64(), buffer) }} }} // cfg_if // TRAIT // ----- pub(crate) trait Decimal { // Export integer to string. fn decimal(self, buffer: &mut [u8]) -> usize; } // Implement decimal for type. macro_rules! decimal_impl { ($t:ty, $cb:ident) => ( impl Decimal for $t { perftools_inline_always!{ fn decimal(self, buffer: &mut [u8]) -> usize { $cb(self, buffer) }} } ); } decimal_impl!(u8, u8toa); decimal_impl!(u16, u16toa); decimal_impl!(u32, u32toa); decimal_impl!(u64, u64toa); decimal_impl!(u128, u128toa); decimal_impl!(usize, usizetoa); lexical-core-0.7.6/src/itoa/generic.rs000075500000000000000000000270130000000000000156750ustar 00000000000000//! Mildly fast, generic, lexical integer-to-string conversion routines. // The following benchmarks were run on an "Intel(R) Core(TM) i7-6560U // CPU @ 2.20GHz" CPU, on Fedora 28, Linux kernel version 4.18.16-200 // (x86-64), using the lexical formatter, `itoa::write()` or `x.to_string()`, // avoiding any inefficiencies in Rust string parsing for `format!(...)` // or `write!()` macros. The code was compiled with LTO and at an optimization // level of 3. // // The benchmarks with `std` were compiled using "rustc 1.32.0 // (9fda7c223 2019-01-16". // // The benchmark code may be found `benches/itoa.rs`. // // # Benchmarks // // | Type | lexical (ns/iter) | libcore (ns/iter) | Relative Increase | // |:-----:|:------------------:|:---------------------:|:-----------------:| // | u8 | 122,329 | 413,025 | 3.38x | // | u16 | 119,888 | 405,945 | 3.41x | // | u32 | 121,150 | 423,174 | 3.49x | // | u64 | 165,609 | 531,862 | 3.21x | // | i8 | 151,478 | 458,374 | 3.03x | // | i16 | 153,211 | 489,010 | 3.19x | // | i32 | 149,433 | 517,710 | 3.46x | // | i64 | 195,575 | 553,387 | 2.83x | // // # Raw Benchmarks // // ```text // test itoa_i8_itoa ... bench: 130,969 ns/iter (+/- 7,420) // test itoa_i8_lexical ... bench: 151,478 ns/iter (+/- 7,510) // test itoa_i8_std ... bench: 458,374 ns/iter (+/- 26,663) // test itoa_i16_itoa ... bench: 143,344 ns/iter (+/- 9,495) // test itoa_i16_lexical ... bench: 153,211 ns/iter (+/- 7,365) // test itoa_i16_std ... bench: 489,010 ns/iter (+/- 25,319) // test itoa_i32_itoa ... bench: 176,494 ns/iter (+/- 9,596) // test itoa_i32_lexical ... bench: 149,433 ns/iter (+/- 5,803) // test itoa_i32_std ... bench: 517,710 ns/iter (+/- 38,439) // test itoa_i64_itoa ... bench: 205,055 ns/iter (+/- 12,436) // test itoa_i64_lexical ... bench: 195,575 ns/iter (+/- 8,007) // test itoa_i64_std ... bench: 553,387 ns/iter (+/- 26,731) // test itoa_u8_itoa ... bench: 112,529 ns/iter (+/- 4,514) // test itoa_u8_lexical ... bench: 122,329 ns/iter (+/- 9,902) // test itoa_u8_std ... bench: 413,025 ns/iter (+/- 30,262) // test itoa_u16_itoa ... bench: 91,936 ns/iter (+/- 5,405) // test itoa_u16_lexical ... bench: 119,888 ns/iter (+/- 6,089) // test itoa_u16_std ... bench: 405,945 ns/iter (+/- 24,104) // test itoa_u32_itoa ... bench: 161,679 ns/iter (+/- 6,719) // test itoa_u32_lexical ... bench: 121,150 ns/iter (+/- 7,580) // test itoa_u32_std ... bench: 423,174 ns/iter (+/- 21,801) // test itoa_u64_itoa ... bench: 203,847 ns/iter (+/- 18,512) // test itoa_u64_lexical ... bench: 165,609 ns/iter (+/- 8,620) // test itoa_u64_std ... bench: 531,862 ns/iter (+/- 31,223) // ``` // Code the generate the benchmark plot: // import numpy as np // import pandas as pd // import matplotlib.pyplot as plt // plt.style.use('ggplot') // lexical = np.array([122329, 119888, 121150, 165609, 151478, 153211, 149433, 195575]) / 1e6 // itoa = np.array([112529, 91936, 161679, 203847, 130969, 143344, 176494, 205055]) / 1e6 // rustcore = np.array([413025, 405945, 423174, 531862, 458374, 489010, 517710, 553387]) / 1e6 // index = ["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64"] // df = pd.DataFrame({'lexical': lexical, 'itoa': itoa, 'rustcore': rustcore}, index = index, columns=['lexical', 'itoa', 'rustcore']) // ax = df.plot.bar(rot=0, figsize=(16, 8), fontsize=14, color=['#E24A33', '#988ED5', '#348ABD']) // ax.set_ylabel("ms/iter") // ax.figure.tight_layout() // ax.legend(loc=2, prop={'size': 14}) // plt.show() use crate::util::*; // Generic itoa algorithm. macro_rules! generic_algorithm { ($value:ident, $radix:ident, $buffer:ident, $t:tt, $table:ident, $index:ident, $radix2:ident, $radix4:ident) => ({ while $value >= $radix4 { let r = $value % $radix4; $value /= $radix4; let r1 = ($t::TWO * (r / $radix2)).as_usize(); let r2 = ($t::TWO * (r % $radix2)).as_usize(); // This is always safe, since the table is 2*radix^2, and // r1 and r2 must be in the range [0, 2*radix^2-1), since the maximum // value of r is `radix4-1`, which must have a div and r // in the range [0, radix^2-1). $index -= 1; unchecked_index_mut!($buffer[$index] = unchecked_index!($table[r2+1])); $index -= 1; unchecked_index_mut!($buffer[$index] = unchecked_index!($table[r2])); $index -= 1; unchecked_index_mut!($buffer[$index] = unchecked_index!($table[r1+1])); $index -= 1; unchecked_index_mut!($buffer[$index] = unchecked_index!($table[r1])); } // Decode 2 digits at a time. while $value >= $radix2 { let r = ($t::TWO * ($value % $radix2)).as_usize(); $value /= $radix2; // This is always safe, since the table is 2*radix^2, and // r must be in the range [0, 2*radix^2-1). $index -= 1; unchecked_index_mut!($buffer[$index] = unchecked_index!($table[r+1])); $index -= 1; unchecked_index_mut!($buffer[$index] = unchecked_index!($table[r])); } // Decode last 2 digits. if $value < $radix { // This is always safe, since value < radix, so it must be < 36. // Digit must be <= 36. $index -= 1; unchecked_index_mut!($buffer[$index] = digit_to_char($value)); //*iter.next().unwrap() = digit_to_char(value); } else { let r = ($t::TWO * $value).as_usize(); // This is always safe, since the table is 2*radix^2, and the value // must <= radix^2, so rem must be in the range [0, 2*radix^2-1). $index -= 1; unchecked_index_mut!($buffer[$index] = unchecked_index!($table[r+1])); $index -= 1; unchecked_index_mut!($buffer[$index] = unchecked_index!($table[r])); } }); } // Get lookup table for 2 digit radix conversions. perftools_inline!{ #[cfg(feature = "radix")] fn get_table(radix: u32) -> &'static [u8] { match radix { 2 => &DIGIT_TO_BASE2_SQUARED, 3 => &DIGIT_TO_BASE3_SQUARED, 4 => &DIGIT_TO_BASE4_SQUARED, 5 => &DIGIT_TO_BASE5_SQUARED, 6 => &DIGIT_TO_BASE6_SQUARED, 7 => &DIGIT_TO_BASE7_SQUARED, 8 => &DIGIT_TO_BASE8_SQUARED, 9 => &DIGIT_TO_BASE9_SQUARED, 10 => &DIGIT_TO_BASE10_SQUARED, 11 => &DIGIT_TO_BASE11_SQUARED, 12 => &DIGIT_TO_BASE12_SQUARED, 13 => &DIGIT_TO_BASE13_SQUARED, 14 => &DIGIT_TO_BASE14_SQUARED, 15 => &DIGIT_TO_BASE15_SQUARED, 16 => &DIGIT_TO_BASE16_SQUARED, 17 => &DIGIT_TO_BASE17_SQUARED, 18 => &DIGIT_TO_BASE18_SQUARED, 19 => &DIGIT_TO_BASE19_SQUARED, 20 => &DIGIT_TO_BASE20_SQUARED, 21 => &DIGIT_TO_BASE21_SQUARED, 22 => &DIGIT_TO_BASE22_SQUARED, 23 => &DIGIT_TO_BASE23_SQUARED, 24 => &DIGIT_TO_BASE24_SQUARED, 25 => &DIGIT_TO_BASE25_SQUARED, 26 => &DIGIT_TO_BASE26_SQUARED, 27 => &DIGIT_TO_BASE27_SQUARED, 28 => &DIGIT_TO_BASE28_SQUARED, 29 => &DIGIT_TO_BASE29_SQUARED, 30 => &DIGIT_TO_BASE30_SQUARED, 31 => &DIGIT_TO_BASE31_SQUARED, 32 => &DIGIT_TO_BASE32_SQUARED, 33 => &DIGIT_TO_BASE33_SQUARED, 34 => &DIGIT_TO_BASE34_SQUARED, 35 => &DIGIT_TO_BASE35_SQUARED, 36 => &DIGIT_TO_BASE36_SQUARED, _ => unreachable!(), } }} // Get lookup table for 2 digit radix conversions. perftools_inline!{ #[cfg(not(feature = "radix"))] fn get_table(_: u32) -> &'static [u8] { &DIGIT_TO_BASE10_SQUARED }} // Optimized implementation for radix-N numbers. // Precondition: `value` must be non-negative and mutable. perftools_inline!{ #[allow(unused_unsafe)] fn generic(mut value: T, radix: u32, table: &[u8], buffer: &mut [u8]) -> usize where T: UnsignedInteger { // Both forms of unchecked indexing cannot overflow. // The table always has 2*radix^2 elements, so it must be a legal index. // The buffer is ensured to have at least MAX_DIGITS or MAX_DIGITS_BASE10 // characters, which is the maximum number of digits an integer of // that size may write. // Use power-reduction to minimize the number of operations. // Idea taken from "3 Optimization Tips for C++". let radix: T = as_cast(radix); let radix2 = radix * radix; let radix4 = radix2 * radix2; // Decode 4-digits at a time let mut index = buffer.len(); generic_algorithm!(value, radix, buffer, T, table, index, radix2, radix4); index }} // Optimized implementation for radix-N numbers. // Precondition: // `value` must be non-negative and mutable. // Buffer must be 0-initialized. perftools_inline!{ #[allow(unused_unsafe)] fn generic_u128(value: u128, radix: u32, table: &[u8], buffer: &mut [u8]) -> usize { // Both forms of unchecked indexing cannot overflow. // The table always has 2*radix^2 elements, so it must be a legal index. // The buffer is ensured to have at least MAX_DIGITS or MAX_DIGITS_BASE10 // characters, which is the maximum number of digits an integer of // that size may write. // Use power-reduction to minimize the number of operations. // Idea taken from "3 Optimization Tips for C++". let (divisor, digits_per_iter, d_cltz) = u128_divisor(radix); let radix: u64 = as_cast(radix); let radix2 = radix * radix; let radix4 = radix2 * radix2; // Decode 4-digits at a time. // To deal with internal 0 values or values with internal 0 digits set, // we store the starting index, and if not all digits are written, // we just skip down `digits` digits for the next value. let mut index = buffer.len(); let mut start_index = index; let (value, mut low) = u128_divrem(value, divisor, d_cltz); generic_algorithm!(low, radix, buffer, u64, table, index, radix2, radix4); if value != 0 { start_index -= digits_per_iter; index = index.min(start_index); let (value, mut mid) = u128_divrem(value, divisor, d_cltz); generic_algorithm!(mid, radix, buffer, u64, table, index, radix2, radix4); if value != 0 { start_index -= digits_per_iter; index = index.min(start_index); let mut high = value as u64; generic_algorithm!(high, radix, buffer, u64, table, index, radix2, radix4); } } index }} pub(crate) trait Generic { // Export integer to string. fn generic(self, radix: u32, buffer: &mut [u8]) -> usize; } // Implement generic for type. macro_rules! generic_impl { ($($t:ty)*) => ($( impl Generic for $t { perftools_inline_always!{ fn generic(self, radix: u32, buffer: &mut [u8]) -> usize { let table = get_table(radix); generic(self, radix, table, buffer) }} } )*); } generic_impl! { u8 u16 u32 u64 usize } impl Generic for u128 { perftools_inline_always!{ fn generic(self, radix: u32, buffer: &mut [u8]) -> usize { let table = get_table(radix); generic_u128(self, radix, table, buffer) }} } lexical-core-0.7.6/src/itoa/mod.rs000075500000000000000000000004650000000000000150420ustar 00000000000000//! Integer-to-string formatting routines. // Hide internal implementation details. #[cfg(feature = "table")] mod decimal; #[cfg(all(feature = "table", feature = "radix"))] mod generic; #[cfg(not(feature = "table"))] mod naive; mod api; #[cfg(feature = "radix")] pub(crate) use self::api::itoa_positive; lexical-core-0.7.6/src/itoa/naive.rs000075500000000000000000000056100000000000000153620ustar 00000000000000//! Slow, simple lexical integer-to-string conversion routine. use crate::util::*; // Naive itoa algorithm. macro_rules! naive_algorithm { ($value:ident, $radix:ident, $buffer:ident, $index:ident) => ({ while $value >= $radix { let r = ($value % $radix).as_usize(); $value /= $radix; // This is always safe, since r must be [0, radix). $index -= 1; unchecked_index_mut!($buffer[$index] = digit_to_char(r)); } // Decode last digit. let r = ($value % $radix).as_usize(); // This is always safe, since r must be [0, radix). $index -= 1; unchecked_index_mut!($buffer[$index] = digit_to_char(r)); }); } // Naive implementation for radix-N numbers. // Precondition: `value` must be non-negative and mutable. perftools_inline!{ fn naive(mut value: T, radix: u32, buffer: &mut [u8]) -> usize where T: UnsignedInteger { // Decode all but last digit, 1 at a time. let mut index = buffer.len(); let radix: T = as_cast(radix); naive_algorithm!(value, radix, buffer, index); index }} pub(crate) trait Naive { // Export integer to string. fn naive(self, radix: u32, buffer: &mut [u8]) -> usize; } // Implement naive for type. macro_rules! naive_impl { ($($t:ty)*) => ($( impl Naive for $t { perftools_inline_always!{ fn naive(self, radix: u32, buffer: &mut [u8]) -> usize { naive(self, radix, buffer) }} } )*); } naive_impl! { u8 u16 u32 u64 usize } // Naive implementation for 128-bit radix-N numbers. // Precondition: `value` must be non-negative and mutable. perftools_inline!{ fn naive_u128(value: u128, radix: u32, buffer: &mut [u8]) -> usize { // Decode all but last digit, 1 at a time. let (divisor, digits_per_iter, d_cltz) = u128_divisor(radix); let radix: u64 = as_cast(radix); // To deal with internal 0 values or values with internal 0 digits set, // we store the starting index, and if not all digits are written, // we just skip down `digits` digits for the next value. let mut index = buffer.len(); let mut start_index = index; let (value, mut low) = u128_divrem(value, divisor, d_cltz); naive_algorithm!(low, radix, buffer, index); if value != 0 { start_index -= digits_per_iter; index = index.min(start_index); let (value, mut mid) = u128_divrem(value, divisor, d_cltz); naive_algorithm!(mid, radix, buffer, index); if value != 0 { start_index -= digits_per_iter; index = index.min(start_index); let mut high = value as u64; naive_algorithm!(high, radix, buffer, index); } } index }} impl Naive for u128 { perftools_inline_always!{ fn naive(self, radix: u32, buffer: &mut [u8]) -> usize { naive_u128(self, radix, buffer) }} } lexical-core-0.7.6/src/lib.rs000075500000000000000000000505110000000000000140720ustar 00000000000000//! Fast lexical conversion routines for a no_std environment. //! //! lexical-core is a low-level API for number-to-string and //! string-to-number conversions, without requiring a system //! allocator. If you would like to use a convenient, high-level //! API, please look at [lexical](https://crates.io/crates/lexical) //! instead. //! //! # Getting Started //! //! ```rust //! extern crate lexical_core; //! //! // String to number using Rust slices. //! // The argument is the byte string parsed. //! let f: f32 = lexical_core::parse(b"3.5").unwrap(); // 3.5 //! let i: i32 = lexical_core::parse(b"15").unwrap(); // 15 //! //! // All lexical_core parsers are checked, they validate the //! // input data is entirely correct, and stop parsing when invalid data //! // is found, or upon numerical overflow. //! let r = lexical_core::parse::(b"256"); // Err(ErrorCode::Overflow.into()) //! let r = lexical_core::parse::(b"1a5"); // Err(ErrorCode::InvalidDigit.into()) //! //! // In order to extract and parse a number from a substring of the input //! // data, use `parse_partial`. These functions return the parsed value and //! // the number of processed digits, allowing you to extract and parse the //! // number in a single pass. //! let r = lexical_core::parse_partial::(b"3a5"); // Ok((3, 1)) //! //! // If an insufficiently long buffer is passed, the serializer will panic. //! // PANICS //! let mut buf = [b'0'; 1]; //! //let slc = lexical_core::write::(15, &mut buf); //! //! // In order to guarantee the buffer is long enough, always ensure there //! // are at least `T::FORMATTED_SIZE` bytes, which requires the //! // `lexical_core::Number` trait to be in scope. //! use lexical_core::Number; //! let mut buf = [b'0'; f64::FORMATTED_SIZE]; //! let slc = lexical_core::write::(15.1, &mut buf); //! assert_eq!(slc, b"15.1"); //! //! // When the `radix` feature is enabled, for decimal floats, using //! // `T::FORMATTED_SIZE` may significantly overestimate the space //! // required to format the number. Therefore, the //! // `T::FORMATTED_SIZE_DECIMAL` constants allow you to get a much //! // tighter bound on the space required. //! let mut buf = [b'0'; f64::FORMATTED_SIZE_DECIMAL]; //! let slc = lexical_core::write::(15.1, &mut buf); //! assert_eq!(slc, b"15.1"); //! ``` //! //! # Conversion API //! //! **To String** //! - [`write`] #![cfg_attr(feature = "radix", doc = " - [`write_radix`]")] //! //! **From String** //! - [`parse`] #![cfg_attr(feature = "radix", doc = " - [`parse_radix`]")] #![cfg_attr(feature = "format", doc = " - [`parse_format`]")] #![cfg_attr(all(feature = "format", feature = "radix"), doc = " - [`parse_format_radix`]")] //! - [`parse_partial`] #![cfg_attr(feature = "radix", doc = " - [`parse_partial_radix`]")] #![cfg_attr(feature = "format", doc = " - [`parse_partial_format`]")] #![cfg_attr(all(feature = "format", feature = "radix"), doc = " - [`parse_partial_format_radix`]")] //! - [`parse_lossy`] #![cfg_attr(feature = "radix", doc = " - [`parse_lossy_radix`]")] #![cfg_attr(feature = "format", doc = " - [`parse_lossy_format`]")] #![cfg_attr(all(feature = "format", feature = "radix"), doc = " - [`parse_lossy_format_radix`]")] //! - [`parse_partial_lossy`] #![cfg_attr(feature = "radix", doc = " - [`parse_partial_lossy_radix`]")] #![cfg_attr(feature = "format", doc = " - [`parse_partial_lossy_format`]")] #![cfg_attr(all(feature = "format", feature = "radix"), doc = " - [`parse_partial_lossy_format_radix`]")] //! //! # Configuration Settings //! //! **Get Configuration** //! - [`get_exponent_default_char`] #![cfg_attr(feature = "radix", doc = " - [`get_exponent_backup_char`]")] #![cfg_attr(all(feature = "correct", feature = "rounding"), doc = " - [`get_float_rounding`]")] //! - [`get_nan_string`] //! - [`get_inf_string`] //! - [`get_infinity_string`] //! //! **Set Configuration** //! - [`set_exponent_default_char`] #![cfg_attr(feature = "radix", doc = " - [`set_exponent_backup_char`]")] #![cfg_attr(all(feature = "correct", feature = "rounding"), doc = " - [`set_float_rounding`]")] //! - [`set_nan_string`] //! - [`set_inf_string`] //! - [`set_infinity_string`] //! //! [`write`]: fn.write.html #![cfg_attr(feature = "radix", doc = " [`write_radix`]: fn.write_radix.html")] //! [`parse`]: fn.parse.html #![cfg_attr(feature = "radix", doc = " [`parse_radix`]: fn.parse_radix.html")] #![cfg_attr(feature = "format", doc = " [`parse_format`]: fn.parse_format.html")] #![cfg_attr(all(feature = "format", feature = "radix"), doc = " [`parse_format_radix`]: fn.parse_format_radix.html")] //! [`parse_partial`]: fn.parse_partial.html #![cfg_attr(feature = "radix", doc = " [`parse_partial_radix`]: fn.parse_partial_radix.html")] #![cfg_attr(feature = "format", doc = " [`parse_partial_format`]: fn.parse_partial_format.html")] #![cfg_attr(all(feature = "format", feature = "radix"), doc = " [`parse_partial_format_radix`]: fn.parse_partial_format_radix.html")] //! [`parse_lossy`]: fn.parse_lossy.html #![cfg_attr(feature = "radix", doc = " [`parse_lossy_radix`]: fn.parse_lossy_radix.html")] #![cfg_attr(feature = "format", doc = " [`parse_lossy_format`]: fn.parse_lossy_format.html")] #![cfg_attr(all(feature = "format", feature = "radix"), doc = " [`parse_lossy_format_radix`]: fn.parse_lossy_format_radix.html")] //! [`parse_partial_lossy`]: fn.parse_partial_lossy.html #![cfg_attr(feature = "radix", doc = " [`parse_partial_lossy_radix`]: fn.parse_partial_lossy_radix.html")] #![cfg_attr(feature = "format", doc = " [`parse_partial_lossy_format`]: fn.parse_partial_lossy_format.html")] #![cfg_attr(all(feature = "format", feature = "radix"), doc = " [`parse_partial_lossy_format_radix`]: fn.parse_partial_lossy_format_radix.html")] //! //! [`get_exponent_default_char`]: fn.get_exponent_default_char.html #![cfg_attr(feature = "radix", doc = " [`get_exponent_backup_char`]: fn.get_exponent_backup_char.html")] #![cfg_attr(all(feature = "correct", feature = "rounding"), doc = " [`get_float_rounding`]: fn.get_float_rounding.html")] //! [`get_nan_string`]: fn.get_nan_string.html //! [`get_inf_string`]: fn.get_inf_string.html //! [`get_infinity_string`]: fn.get_infinity_string.html //! //! [`set_exponent_default_char`]: fn.set_exponent_default_char.html #![cfg_attr(feature = "radix", doc = " [`set_exponent_backup_char`]: fn.set_exponent_backup_char.html")] #![cfg_attr(all(feature = "correct", feature = "rounding"), doc = " [`set_float_rounding`]: fn.set_float_rounding.html")] //! [`set_nan_string`]: fn.set_nan_string.html //! [`set_inf_string`]: fn.set_inf_string.html //! [`set_infinity_string`]: fn.set_infinity_string.html // silence warnings for unused doc comments #![allow(unused_doc_comments)] // FEATURES // Require intrinsics in a no_std context. #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(all(not(feature = "std"), not(feature = "libm")), feature(core_intrinsics))] // DEPENDENCIES #[macro_use] extern crate cfg_if; // Use vec if there is a system allocator, which we require only if // we're using the correct and radix features. #[cfg(all(not(feature = "std"), feature = "correct", feature = "radix"))] #[cfg_attr(test, macro_use)] extern crate alloc; // Use arrayvec for atof. #[cfg(feature = "correct")] extern crate arrayvec; // Ensure only one back-end is enabled. #[cfg(all(feature = "grisu3", feature = "ryu"))] compile_error!("Lexical only accepts one of the following backends: `grisu3` or `ryu`."); // Import the back-end, if applicable. cfg_if! { if #[cfg(feature = "grisu3")] { extern crate dtoa; } else if #[cfg(feature = "ryu")] { extern crate ryu; } } // cfg_if /// Facade around the core features for name mangling. pub(crate) mod lib { #[cfg(feature = "std")] pub(crate) use std::*; #[cfg(not(feature = "std"))] pub(crate) use core::*; cfg_if! { if #[cfg(all(feature = "correct", feature = "radix"))] { #[cfg(feature = "std")] pub(crate) use std::vec::Vec; #[cfg(not(feature = "std"))] pub(crate) use ::alloc::vec::Vec; } } // cfg_if } // lib // API // Hide implementation details #[macro_use] mod util; mod atof; mod atoi; mod float; mod ftoa; mod itoa; // Re-export configuration and utilities globally. pub use util::*; /// Write number to string. /// /// Returns a subslice of the input buffer containing the written bytes, /// starting from the same address in memory as the input slice. /// /// * `value` - Number to serialize. /// * `bytes` - Slice containing a numeric string. /// /// # Panics /// /// Panics if the buffer may not be large enough to hold the serialized /// number. In order to ensure the function will not panic, provide a /// buffer with at least `{integer}::FORMATTED_SIZE_DECIMAL` elements. /// /// # Example /// /// ``` /// // import `Number` trait to get the `FORMATTED_SIZE_DECIMAL` of the number. /// use lexical_core::Number; /// /// let mut buffer = [0u8; f32::FORMATTED_SIZE_DECIMAL]; /// let float = 3.14159265359_f32; /// /// lexical_core::write(float, &mut buffer); /// /// assert_eq!(&buffer[0..9], b"3.1415927"); /// ``` /// /// This will panic, because the buffer is not large enough: /// /// ```should_panic /// // note: the buffer is only one byte large /// let mut buffer = [0u8; 1]; /// let float = 3.14159265359_f32; /// /// lexical_core::write(float, &mut buffer); /// ``` #[inline] pub fn write<'a, N: ToLexical>(n: N, bytes: &'a mut [u8]) -> &'a mut [u8] { n.to_lexical(bytes) } /// Write number to string with a custom radix. /// /// Returns a subslice of the input buffer containing the written bytes, /// starting from the same address in memory as the input slice. /// /// * `value` - Number to serialize. /// * `radix` - Radix for number encoding. /// * `bytes` - Slice containing a numeric string. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. /// /// Also panics if the buffer may not be large enough to hold the /// serialized number. In order to ensure the function will not panic, /// provide a buffer with at least [`FORMATTED_SIZE`] elements. /// /// [`FORMATTED_SIZE`]: trait.Number.html#associatedconstant.FORMATTED_SIZE #[inline] #[cfg(feature = "radix")] pub fn write_radix<'a, N: ToLexical>(n: N, radix: u8, bytes: &'a mut [u8]) -> &'a mut [u8] { n.to_lexical_radix(radix, bytes) } /// Parse number from string. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. /// /// * `bytes` - Byte slice containing a numeric string. #[inline] pub fn parse(bytes: &[u8]) -> Result { N::from_lexical(bytes) } /// Parse number from string. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. /// /// * `bytes` - Byte slice containing a numeric string. #[inline] pub fn parse_partial(bytes: &[u8]) -> Result<(N, usize)> { N::from_lexical_partial(bytes) } /// Lossily parse number from string. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. This parser is /// lossy, so numerical rounding may occur during parsing. /// /// * `bytes` - Byte slice containing a numeric string. #[inline] pub fn parse_lossy(bytes: &[u8]) -> Result { N::from_lexical_lossy(bytes) } /// Lossily parse number from string. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. This parser is /// lossy, so numerical rounding may occur during parsing. /// /// * `bytes` - Byte slice containing a numeric string. #[inline] pub fn parse_partial_lossy(bytes: &[u8]) -> Result<(N, usize)> { N::from_lexical_partial_lossy(bytes) } /// Parse number from string with a custom radix. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. /// /// * `radix` - Radix for number decoding. /// * `bytes` - Byte slice containing a numeric string. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[inline] #[cfg(feature = "radix")] pub fn parse_radix(bytes: &[u8], radix: u8) -> Result { N::from_lexical_radix(bytes, radix) } /// Parse number from string with a custom radix. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. /// /// * `radix` - Radix for number decoding. /// * `bytes` - Byte slice containing a numeric string. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[inline] #[cfg(feature = "radix")] pub fn parse_partial_radix(bytes: &[u8], radix: u8) -> Result<(N, usize)> { N::from_lexical_partial_radix(bytes, radix) } /// Lossily parse number from string with a custom radix. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. This parser is /// lossy, so numerical rounding may occur during parsing. /// /// * `radix` - Radix for number decoding. /// * `bytes` - Byte slice containing a numeric string. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[inline] #[cfg(feature = "radix")] pub fn parse_lossy_radix(bytes: &[u8], radix: u8) -> Result { N::from_lexical_lossy_radix(bytes, radix) } /// Lossily parse number from string with a custom radix. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. This parser is /// lossy, so numerical rounding may occur during parsing. /// /// * `bytes` - Byte slice containing a numeric string. /// * `radix` - Radix for number decoding. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[inline] #[cfg(feature = "radix")] pub fn parse_partial_lossy_radix(bytes: &[u8], radix: u8) -> Result<(N, usize)> { N::from_lexical_partial_lossy_radix(bytes, radix) } /// Parse number from string with a custom numerical format. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. The numerical format /// is specified by the format bitflags, which customize the required /// components, digit separators, and other parameters of the number. /// /// * `bytes` - Byte slice containing a numeric string. /// * `format` - Numerical format. #[inline] #[cfg(feature = "format")] pub fn parse_format(bytes: &[u8], format: NumberFormat) -> Result { N::from_lexical_format(bytes, format) } /// Parse number from string with a custom numerical format. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. The numerical format /// is specified by the format bitflags, which customize the required /// components, digit separators, and other parameters of the number. /// /// * `bytes` - Byte slice containing a numeric string. /// * `format` - Numerical format. #[inline] #[cfg(feature = "format")] pub fn parse_partial_format(bytes: &[u8], format: NumberFormat) -> Result<(N, usize)> { N::from_lexical_partial_format(bytes, format) } /// Lossily parse number from string with a custom numerical format. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. This parser is /// lossy, so numerical rounding may occur during parsing. The /// numerical format is specified by the format bitflags, which /// customize the required components, digit separators, and other /// parameters of the number. /// /// * `bytes` - Byte slice containing a numeric string. /// * `format` - Numerical format. #[inline] #[cfg(feature = "format")] pub fn parse_lossy_format(bytes: &[u8], format: NumberFormat) -> Result { N::from_lexical_lossy_format(bytes, format) } /// Lossily parse number from string with a custom numerical format. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. This parser is /// lossy, so numerical rounding may occur during parsing. The /// numerical format is specified by the format bitflags, which /// customize the required components, digit separators, and other /// parameters of the number. /// /// * `bytes` - Byte slice containing a numeric string. /// * `format` - Numerical format. #[inline] #[cfg(feature = "format")] pub fn parse_partial_lossy_format(bytes: &[u8], format: NumberFormat) -> Result<(N, usize)> { N::from_lexical_partial_lossy_format(bytes, format) } /// Parse number from string with a custom radix and numerical format. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. The numerical format /// is specified by the format bitflags, which customize the required /// components, digit separators, and other parameters of the number. /// /// * `bytes` - Byte slice containing a numeric string. /// * `radix` - Radix for number decoding. /// * `format` - Numerical format. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[inline] #[cfg(all(feature = "radix", feature = "format"))] pub fn parse_format_radix(bytes: &[u8], radix: u8, format: NumberFormat) -> Result { N::from_lexical_format_radix(bytes, radix, format) } /// Parse number from string with a custom radix and numerical format. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. The numerical format /// is specified by the format bitflags, which customize the required /// components, digit separators, and other parameters of the number. /// /// * `bytes` - Byte slice containing a numeric string. /// * `radix` - Radix for number decoding. /// * `format` - Numerical format. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[inline] #[cfg(all(feature = "radix", feature = "format"))] pub fn parse_partial_format_radix(bytes: &[u8], radix: u8, format: NumberFormat) -> Result<(N, usize)> { N::from_lexical_partial_format_radix(bytes, radix, format) } /// Lossily parse number from string with a custom radix and numerical format. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. This parser is /// lossy, so numerical rounding may occur during parsing. The /// numerical format is specified by the format bitflags, which /// customize the required components, digit separators, and other /// parameters of the number. /// /// * `bytes` - Byte slice containing a numeric string. /// * `radix` - Radix for number decoding. /// * `format` - Numerical format. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[inline] #[cfg(all(feature = "radix", feature = "format"))] pub fn parse_lossy_format_radix(bytes: &[u8], radix: u8, format: NumberFormat) -> Result { N::from_lexical_lossy_format_radix(bytes, radix, format) } /// Lossily parse number from string with a custom radix and numerical format. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. This parser is /// lossy, so numerical rounding may occur during parsing. The /// numerical format is specified by the format bitflags, which /// customize the required components, digit separators, and other /// parameters of the number. /// /// * `bytes` - Byte slice containing a numeric string. /// * `radix` - Radix for number decoding. /// * `format` - Numerical format. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[inline] #[cfg(all(feature = "radix", feature = "format"))] pub fn parse_partial_lossy_format_radix(bytes: &[u8], radix: u8, format: NumberFormat) -> Result<(N, usize)> { N::from_lexical_partial_lossy_format_radix(bytes, radix, format) } lexical-core-0.7.6/src/util/algorithm.rs000075500000000000000000000247030000000000000162730ustar 00000000000000//! Simple, shared algorithm utilities. use crate::lib::convert::AsRef; use crate::lib::{mem, ptr, slice}; // ALGORITHMS /// Calculate the difference between two pointers. #[inline] pub fn distance(first: *const T, last: *const T) -> usize { debug_assert!(last >= first, "range must be positive."); let f = first as usize; let l = last as usize; l - f } /// Check if two slices are equal to each other. #[inline] pub fn equal_to_slice(l: &[u8], r: &[u8]) -> bool { l == r } /// Check if left iter starts with right iter. #[inline] #[cfg(feature = "format")] pub fn starts_with_iter<'a, Iter1, Iter2>(mut l: Iter1, mut r: Iter2) -> (bool, Iter1) where Iter1: Iterator, Iter2: Iterator { loop { // Only call `next()` on l if r is not None, otherwise, // we may incorrectly consume an l character. let ri = r.next(); if ri.is_none() { return (true, l); } else if l.next() != ri { return (false, l); } } } /// Check if left iter starts with right iter without case-sensitivity. #[inline] pub fn case_insensitive_starts_with_iter<'a, Iter1, Iter2>(mut l: Iter1, mut r: Iter2) -> (bool, Iter1) where Iter1: Iterator, Iter2: Iterator { loop { let ri = r.next().map(|x| x.to_ascii_lowercase()); if ri.is_none() { return (true, l); } else if l.next().map(|x| x.to_ascii_lowercase()) != ri { return (false, l); } } } /// Check if left slice ends with right slice. #[inline] pub fn ends_with_slice(l: &[u8], r: &[u8]) -> bool { // This cannot be out-of-bounds, since we check `l.len() >= r.len()` // previous to extracting the subslice, so `l.len() - r.len()` must // also be <= l.len() and >= 0. let rget = move || unsafe {l.get_unchecked(l.len()-r.len()..)}; l.len() >= r.len() && equal_to_slice(rget(), r) } /// Trim character from the left-side of a slice. #[inline] pub fn ltrim_char_slice<'a>(slc: &'a [u8], c: u8) -> (&'a [u8], usize) { let count = slc.iter().take_while(|&&si| si == c).count(); // This count cannot exceed the bounds of the slice, since it is // derived from an iterator using the standard library to generate it. debug_assert!(count <= slc.len()); let slc = unsafe {slc.get_unchecked(count..)}; (slc, count) } /// Trim characters from the left-side of a slice. #[inline] #[cfg(feature = "format")] pub fn ltrim_char2_slice<'a>(slc: &'a [u8], c1: u8, c2: u8) -> (&'a [u8], usize) { let count = slc.iter().take_while(|&&si| si == c1 || si == c2).count(); // This count cannot exceed the bounds of the slice, since it is // derived from an iterator using the standard library to generate it. debug_assert!(count <= slc.len()); let slc = unsafe {slc.get_unchecked(count..)}; (slc, count) } /// Trim character from the right-side of a slice. #[inline] pub fn rtrim_char_slice<'a>(slc: &'a [u8], c: u8) -> (&'a [u8], usize) { let count = slc.iter().rev().take_while(|&&si| si == c).count(); let index = slc.len() - count; // Count must be <= slc.len(), and therefore, slc.len() - count must // also be <= slc.len(), since this is derived from an iterator // in the standard library. debug_assert!(count <= slc.len()); debug_assert!(index <= slc.len()); let slc = unsafe {slc.get_unchecked(..index)}; (slc, count) } /// Trim character from the right-side of a slice. #[inline] #[cfg(feature = "format")] pub fn rtrim_char2_slice<'a>(slc: &'a [u8], c1: u8, c2: u8) -> (&'a [u8], usize) { let count = slc.iter().rev().take_while(|&&si| si == c1 || si == c2).count(); let index = slc.len() - count; // Count must be <= slc.len(), and therefore, slc.len() - count must // also be <= slc.len(), since this is derived from an iterator // in the standard library. debug_assert!(count <= slc.len()); debug_assert!(index <= slc.len()); let slc = unsafe {slc.get_unchecked(..index)}; (slc, count) } /// Copy from source-to-dst. #[inline] pub fn copy_to_dst<'a, Bytes: AsRef<[u8]>>(dst: &'a mut [u8], src: Bytes) -> usize { let src = src.as_ref(); let dst = &mut index_mut!(dst[..src.len()]); unsafe { ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), dst.len()); } src.len() } /// Length-check variant of ptr::write_bytes for a slice. #[cfg(not(any(feature = "grisu3", feature = "ryu")))] #[inline] pub fn write_bytes(dst: &mut [u8], byte: u8) { unsafe { ptr::write_bytes(dst.as_mut_ptr(), byte, dst.len()); } } // TEST // ---- #[cfg(test)] mod tests { use super::*; #[test] fn distance_test() { unsafe { let x: [u8; 10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; let first: *const u8 = x.as_ptr(); let last = first.add(x.len()); assert_eq!(distance(first, last), 10); } } #[test] fn equal_to_test() { let x = "Hello"; let y = "Hello"; let z = "hello"; assert!(equal_to_slice(x.as_bytes(), y.as_bytes())); assert!(!equal_to_slice(x.as_bytes(), z.as_bytes())); assert!(!equal_to_slice(y.as_bytes(), z.as_bytes())); } #[test] #[cfg(feature = "format")] fn starts_with_test() { let w = b"Hello"; let x = b"H"; let y = b"h"; let z = b"a"; // forward assert!(starts_with_iter(w.iter(), x.iter()).0); assert!(!starts_with_iter(w.iter(), y.iter()).0); assert!(!starts_with_iter(x.iter(), y.iter()).0); assert!(!starts_with_iter(w.iter(), z.iter()).0); assert!(!starts_with_iter(x.iter(), z.iter()).0); assert!(!starts_with_iter(y.iter(), z.iter()).0); // back assert!(!starts_with_iter(x.iter(), w.iter()).0); assert!(!starts_with_iter(y.iter(), w.iter()).0); assert!(!starts_with_iter(z.iter(), w.iter()).0); } #[test] fn case_insensitive_starts_with_test() { let w = b"Hello"; let x = b"H"; let y = b"h"; let z = b"a"; // forward assert!(case_insensitive_starts_with_iter(w.iter(), x.iter()).0); assert!(case_insensitive_starts_with_iter(w.iter(), y.iter()).0); assert!(case_insensitive_starts_with_iter(x.iter(), y.iter()).0); assert!(!case_insensitive_starts_with_iter(w.iter(), z.iter()).0); assert!(!case_insensitive_starts_with_iter(x.iter(), z.iter()).0); assert!(!case_insensitive_starts_with_iter(y.iter(), z.iter()).0); // back assert!(!case_insensitive_starts_with_iter(x.iter(), w.iter()).0); assert!(!case_insensitive_starts_with_iter(y.iter(), w.iter()).0); assert!(!case_insensitive_starts_with_iter(z.iter(), w.iter()).0); } #[test] fn ends_with_test() { let w = "Hello"; let x = "lO"; let y = "lo"; let z = "o"; // forward assert!(!ends_with_slice(w.as_bytes(), x.as_bytes())); assert!(ends_with_slice(w.as_bytes(), y.as_bytes())); assert!(ends_with_slice(w.as_bytes(), z.as_bytes())); assert!(!ends_with_slice(x.as_bytes(), y.as_bytes())); assert!(!ends_with_slice(x.as_bytes(), z.as_bytes())); assert!(ends_with_slice(y.as_bytes(), z.as_bytes())); // back assert!(!ends_with_slice(z.as_bytes(), y.as_bytes())); assert!(!ends_with_slice(z.as_bytes(), x.as_bytes())); assert!(!ends_with_slice(z.as_bytes(), w.as_bytes())); assert!(!ends_with_slice(y.as_bytes(), x.as_bytes())); assert!(!ends_with_slice(y.as_bytes(), w.as_bytes())); assert!(!ends_with_slice(x.as_bytes(), w.as_bytes())); } #[test] fn ltrim_char_test() { let w = "0001"; let x = "1010"; let y = "1.00"; let z = "1e05"; assert_eq!(ltrim_char_slice(w.as_bytes(), b'0').1, 3); assert_eq!(ltrim_char_slice(x.as_bytes(), b'0').1, 0); assert_eq!(ltrim_char_slice(x.as_bytes(), b'1').1, 1); assert_eq!(ltrim_char_slice(y.as_bytes(), b'0').1, 0); assert_eq!(ltrim_char_slice(y.as_bytes(), b'1').1, 1); assert_eq!(ltrim_char_slice(z.as_bytes(), b'0').1, 0); assert_eq!(ltrim_char_slice(z.as_bytes(), b'1').1, 1); } #[test] #[cfg(feature = "format")] fn ltrim_char2_test() { let w = "0001"; let x = "1010"; let y = "1.00"; let z = "1e05"; let a = "0_01"; assert_eq!(ltrim_char2_slice(w.as_bytes(), b'0', b'_').1, 3); assert_eq!(ltrim_char2_slice(x.as_bytes(), b'0', b'_').1, 0); assert_eq!(ltrim_char2_slice(x.as_bytes(), b'1', b'_').1, 1); assert_eq!(ltrim_char2_slice(y.as_bytes(), b'0', b'_').1, 0); assert_eq!(ltrim_char2_slice(y.as_bytes(), b'1', b'_').1, 1); assert_eq!(ltrim_char2_slice(z.as_bytes(), b'0', b'_').1, 0); assert_eq!(ltrim_char2_slice(z.as_bytes(), b'1', b'_').1, 1); assert_eq!(ltrim_char2_slice(a.as_bytes(), b'0', b'_').1, 3); assert_eq!(ltrim_char2_slice(a.as_bytes(), b'1', b'_').1, 0); } #[test] fn rtrim_char_test() { let w = "0001"; let x = "1010"; let y = "1.00"; let z = "1e05"; assert_eq!(rtrim_char_slice(w.as_bytes(), b'0').1, 0); assert_eq!(rtrim_char_slice(x.as_bytes(), b'0').1, 1); assert_eq!(rtrim_char_slice(x.as_bytes(), b'1').1, 0); assert_eq!(rtrim_char_slice(y.as_bytes(), b'0').1, 2); assert_eq!(rtrim_char_slice(y.as_bytes(), b'1').1, 0); assert_eq!(rtrim_char_slice(z.as_bytes(), b'0').1, 0); assert_eq!(rtrim_char_slice(z.as_bytes(), b'5').1, 1); } #[test] #[cfg(feature = "format")] fn rtrim_char2_test() { let w = "0001"; let x = "1010"; let y = "1.00"; let z = "1e05"; let a = "0_01"; assert_eq!(rtrim_char2_slice(w.as_bytes(), b'0', b'_').1, 0); assert_eq!(rtrim_char2_slice(x.as_bytes(), b'0', b'_').1, 1); assert_eq!(rtrim_char2_slice(x.as_bytes(), b'1', b'_').1, 0); assert_eq!(rtrim_char2_slice(y.as_bytes(), b'0', b'_').1, 2); assert_eq!(rtrim_char2_slice(y.as_bytes(), b'1', b'_').1, 0); assert_eq!(rtrim_char2_slice(z.as_bytes(), b'0', b'_').1, 0); assert_eq!(rtrim_char2_slice(z.as_bytes(), b'1', b'_').1, 0); assert_eq!(rtrim_char2_slice(a.as_bytes(), b'0', b'_').1, 0); assert_eq!(rtrim_char2_slice(a.as_bytes(), b'1', b'_').1, 1); } } lexical-core-0.7.6/src/util/assert.rs000075500000000000000000000022350000000000000156020ustar 00000000000000//! Macro to check if the radix is valid, in generic code. // RADIX /// Check radix is in range [2, 36] in debug builds. #[cfg(feature = "radix")] macro_rules! debug_assert_radix { ($radix:expr) => (debug_assert!($radix.as_i32() >= 2 && $radix.as_i32() <= 36, "Numerical base must be from 2-36.");) } /// Check radix is equal to 10. #[cfg(not(feature = "radix"))] macro_rules! debug_assert_radix { ($radix:expr) => (debug_assert!($radix.as_i32() == 10, "Numerical base must be 10.");) } /// Check radix is in range [2, 36] in debug and release builds. #[cfg(feature = "radix")] macro_rules! assert_radix { ($radix:expr) => (assert!($radix.as_i32() >= 2 && $radix.as_i32() <= 36, "Numerical base must be from 2-36.");) } // BUFFER /// Check the buffer has sufficient room for the output. macro_rules! assert_buffer { ($radix:expr, $slc:ident, $t:ty) => ({ #[cfg(feature = "radix")] match $radix { 10 => assert!($slc.len() >= <$t>::FORMATTED_SIZE_DECIMAL), _ => assert!($slc.len() >= <$t>::FORMATTED_SIZE), } #[cfg(not(feature = "radix"))] assert!($slc.len() >= <$t>::FORMATTED_SIZE); }); } lexical-core-0.7.6/src/util/cast.rs000075500000000000000000001060370000000000000152400ustar 00000000000000//! Rust cast utilities. // We have a lot of high-level casts that make the type-system work. // Don't delete them, fake they're being used. #![allow(dead_code)] use super::primitive::AsPrimitive; use super::num::{Integer}; // AS CAST /// Allows the high-level conversion of generic types as if `as` was used. #[inline] pub(crate) fn as_cast(t: T) -> U { AsCast::as_cast(t) } /// An interface for casting between machine scalars. pub trait AsCast: AsPrimitive { /// Creates a number from another value that can be converted into /// a primitive via the `AsPrimitive` trait. fn as_cast(n: N) -> Self; } macro_rules! as_cast { ($t:ty, $meth:ident) => { impl AsCast for $t { #[inline] fn as_cast(n: N) -> $t { n.$meth() } } }; } as_cast!(u8, as_u8); as_cast!(u16, as_u16); as_cast!(u32, as_u32); as_cast!(u64, as_u64); as_cast!(u128, as_u128); as_cast!(usize, as_usize); as_cast!(i8, as_i8); as_cast!(i16, as_i16); as_cast!(i32, as_i32); as_cast!(i64, as_i64); as_cast!(i128, as_i128); as_cast!(isize, as_isize); as_cast!(f32, as_f32); as_cast!(f64, as_f64); // TRY CAST // Analogous to TryInto. /// High-level conversion of types using TryCast. #[inline] pub(crate) fn try_cast>(t: T) -> Option { TryCast::try_cast(t) } /// Non-lossy cast between types. Returns None if new type cannot represent value. pub trait TryCast: Sized { /// Consume self and return the cast value (or None). fn try_cast(self) -> Option; } macro_rules! try_cast { // CHECK // Checked conversion (@check $v:ident, $cond:expr) => (if $cond { Some(as_cast($v)) } else { None }); // INTEGER // Widen type,so no checks required, both are signed/unsigned. (@widen $src:tt, $($dst:tt),*) => ($( impl TryCast<$dst> for $src { #[inline] fn try_cast(self) -> Option<$dst> { try_cast!(@check self, true) } } )*); // Above zero check, for a signed to unsigned conversion of same width. (@positive $src:tt, $($dst:tt),*) => ($( impl TryCast<$dst> for $src { #[inline] fn try_cast(self) -> Option<$dst> { try_cast!(@check self, self >= 0) } } )*); // Check below some upper bound (for narrowing of an unsigned value). (@below $src:tt, $($dst:tt),*) => ($( impl TryCast<$dst> for $src { #[inline] fn try_cast(self) -> Option<$dst> { const MAX: $src = $dst::max_value() as $src; try_cast!(@check self, self <= MAX) } } )*); // Check within min and max bounds (for narrowing of a signed value). (@within $src:tt, $($dst:tt),*) => ($( impl TryCast<$dst> for $src { #[inline] fn try_cast(self) -> Option<$dst> { const MIN: $src = $dst::min_value() as $src; const MAX: $src = $dst::max_value() as $src; try_cast!(@check self, self >= MIN && self <= MAX) } } )*); // FLOAT // Cannot be done without implementation defined behavior. (@into_float $src:tt, $($dst:tt),*) => ($( impl TryCast<$dst> for $src { #[inline] fn try_cast(self) -> Option<$dst> { unreachable!() } } )*); // Cannot be done without implementation defined behavior. (@from_float $src:tt, $($dst:tt),*) => ($( impl TryCast<$dst> for $src { #[inline] fn try_cast(self) -> Option<$dst> { unreachable!() } } )*); } // u8 try_cast! { @widen u8, u8, u16, u32, u64, u128 } try_cast! { @below u8, i8 } try_cast! { @widen u8, i16, i32, i64, i128 } try_cast! { @widen u8, f32, f64 } // u16 try_cast! { @below u16, u8 } try_cast! { @widen u16, u16, u32, u64, u128 } try_cast! { @below u16, i8, i16 } try_cast! { @widen u16, i32, i64, i128 } try_cast! { @widen u16, f32, f64 } // u32 try_cast! { @below u32, u8, u16 } try_cast! { @widen u32, u32, u64, u128 } try_cast! { @below u32, i8, i16, i32 } try_cast! { @widen u32, i64, i128 } try_cast! { @into_float u32, f32 } try_cast! { @widen u32, f64 } // u64 try_cast! { @below u64, u8, u16, u32 } try_cast! { @widen u64, u64, u128 } try_cast! { @below u64, i8, i16, i32, i64 } try_cast! { @widen u64, i128} try_cast! { @into_float u64, f32, f64 } // u128 try_cast! { @below u128, u8, u16, u32, u64 } try_cast! { @widen u128, u128 } try_cast! { @below u128, i8, i16, i32, i64, i128 } try_cast! { @into_float u128, f32, f64 } // i8 try_cast! { @positive i8, u8, u16, u32, u64, u128 } try_cast! { @widen i8, i8, i16, i32, i64, i128 } try_cast! { @widen i8, f32, f64 } // i16 try_cast! { @within i16, u8 } try_cast! { @positive i16, u16, u32, u64, u128 } try_cast! { @within i16, i8 } try_cast! { @widen i16, i16, i32, i64, i128 } try_cast! { @widen i16, f32, f64 } // i32 try_cast! { @within i32, u8, u16 } try_cast! { @positive i32, u32, u64, u128 } try_cast! { @within i32, i8, i16 } try_cast! { @widen i32, i32, i64, i128 } try_cast! { @into_float i32, f32 } try_cast! { @widen i32, f64 } // i64 try_cast! { @within i64, u8, u16, u32 } try_cast! { @positive i64, u64, u128 } try_cast! { @within i64, i8, i16, i32 } try_cast! { @widen i64, i64, i128 } try_cast! { @into_float i64, f32, f64 } // i128 try_cast! { @within i128, u8, u16, u32, u64 } try_cast! { @positive i128, u128 } try_cast! { @within i128, i8, i16, i32, i64 } try_cast! { @widen i128, i128 } try_cast! { @into_float i128, f32, f64 } // f32 try_cast! { @from_float f32, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64 } // f64 try_cast! { @from_float f64, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64 } // usize/isize shared try_cast! { @from_float f32, usize } try_cast! { @from_float f64, usize } try_cast! { @from_float f32, isize } try_cast! { @from_float f64, isize } cfg_if! { if #[cfg(target_pointer_width = "16")] { // 16-bit usize try_cast! { @below usize, u8 } try_cast! { @widen usize, u16, u32, u64, u128, usize } try_cast! { @below usize, i8, i16, isize } try_cast! { @widen usize, i32, i64, i128 } try_cast! { @widen usize, f32, f64 } try_cast! { @widen u8, usize } try_cast! { @widen u16, usize } try_cast! { @below u32, usize } try_cast! { @below u64, usize } try_cast! { @below u128, usize } try_cast! { @positive i8, usize } try_cast! { @positive i16, usize } try_cast! { @within i32, usize } try_cast! { @within i64, usize } try_cast! { @within i128, usize } // 16-bit isize try_cast! { @within isize, u8 } try_cast! { @positive isize, u16, u32, u64, u128, usize } try_cast! { @within isize, i8 } try_cast! { @widen isize, i16, i32, i64, i128, isize } try_cast! { @widen isize, f32, f64 } try_cast! { @widen u8, isize } try_cast! { @below u16, isize } try_cast! { @below u32, isize } try_cast! { @below u64, isize } try_cast! { @below u128, isize } try_cast! { @widen i8, isize } try_cast! { @widen i16, isize } try_cast! { @within i32, isize } try_cast! { @within i64, isize } try_cast! { @within i128, isize } } else if #[cfg(target_pointer_width = "32")] { try_cast! { @below usize, u8, u16 } try_cast! { @widen usize, u32, u64, u128, usize } try_cast! { @below usize, i8, i16, i32, isize } try_cast! { @widen usize, i64, i128 } try_cast! { @into_float usize, f32 } try_cast! { @widen usize, f64 } try_cast! { @widen u8, usize } try_cast! { @widen u16, usize } try_cast! { @widen u32, usize } try_cast! { @below u64, usize } try_cast! { @below u128, usize } try_cast! { @positive i8, usize } try_cast! { @positive i16, usize } try_cast! { @positive i32, usize } try_cast! { @within i64, usize } try_cast! { @within i128, usize } // 32-bit isize try_cast! { @within isize, u8, u16 } try_cast! { @positive isize, u32, u64, u128, usize } try_cast! { @within isize, i8, i16 } try_cast! { @widen isize, i32, i64, i128, isize } try_cast! { @into_float isize, f32 } try_cast! { @widen isize, f64 } try_cast! { @widen u8, isize } try_cast! { @widen u16, isize } try_cast! { @below u32, isize } try_cast! { @below u64, isize } try_cast! { @below u128, isize } try_cast! { @widen i8, isize } try_cast! { @widen i16, isize } try_cast! { @widen i32, isize } try_cast! { @within i64, isize } try_cast! { @within i128, isize } } else if #[cfg(target_pointer_width = "64")] { // 64-bit usize try_cast! { @below usize, u8, u16, u32 } try_cast! { @widen usize, u64, u128, usize } try_cast! { @below usize, i8, i16, i32, i64, isize } try_cast! { @widen usize, i128 } try_cast! { @into_float usize, f32, f64 } try_cast! { @widen u8, usize } try_cast! { @widen u16, usize } try_cast! { @widen u32, usize } try_cast! { @widen u64, usize } try_cast! { @below u128, usize } try_cast! { @positive i8, usize } try_cast! { @positive i16, usize } try_cast! { @positive i32, usize } try_cast! { @positive i64, usize } try_cast! { @within i128, usize } // 64-bit isize try_cast! { @within isize, u8, u16, u32 } try_cast! { @positive isize, u64, u128, usize } try_cast! { @within isize, i8, i16, i32 } try_cast! { @widen isize, i64, i128, isize } try_cast! { @into_float isize, f32, f64 } try_cast! { @widen u8, isize } try_cast! { @widen u16, isize } try_cast! { @widen u32, isize } try_cast! { @below u64, isize } try_cast! { @below u128, isize } try_cast! { @widen i8, isize } try_cast! { @widen i16, isize } try_cast! { @widen i32, isize } try_cast! { @widen i64, isize } try_cast! { @within i128, isize } }} // cfg_if // TEST // ---- #[cfg(test)] mod tests { use super::*; use super::super::num::{Integer, Float}; fn check_as_cast(t: T) { let _: i8 = as_cast(t); let _: i16 = as_cast(t); let _: i32 = as_cast(t); let _: i64 = as_cast(t); let _: i128 = as_cast(t); let _: isize = as_cast(t); let _: u8 = as_cast(t); let _: u16 = as_cast(t); let _: u32 = as_cast(t); let _: u64 = as_cast(t); let _: u128 = as_cast(t); let _: usize = as_cast(t); let _: f32 = as_cast(t); let _: f64 = as_cast(t); } #[test] fn as_cast_test() { check_as_cast(1u8); check_as_cast(1u16); check_as_cast(1u32); check_as_cast(1u64); check_as_cast(1u128); check_as_cast(1usize); check_as_cast(1i8); check_as_cast(1i16); check_as_cast(1i32); check_as_cast(1i64); check_as_cast(1i128); check_as_cast(1isize); check_as_cast(1f32); check_as_cast(1f64); } fn try_cast_u8>(t: T) -> Option { t.try_cast() } fn try_cast_u16>(t: T) -> Option { t.try_cast() } fn try_cast_u32>(t: T) -> Option { t.try_cast() } fn try_cast_u64>(t: T) -> Option { t.try_cast() } fn try_cast_u128>(t: T) -> Option { t.try_cast() } fn try_cast_usize>(t: T) -> Option { t.try_cast() } fn try_cast_i8>(t: T) -> Option { t.try_cast() } fn try_cast_i16>(t: T) -> Option { t.try_cast() } fn try_cast_i32>(t: T) -> Option { t.try_cast() } fn try_cast_i64>(t: T) -> Option { t.try_cast() } fn try_cast_i128>(t: T) -> Option { t.try_cast() } fn try_cast_isize>(t: T) -> Option { t.try_cast() } fn try_cast_f32>(t: T) -> Option { t.try_cast() } fn try_cast_f64>(t: T) -> Option { t.try_cast() } #[test] fn try_cast_test() { // u8 assert!(try_cast_u8(u8::min_value()).is_some()); assert!(try_cast_u16(u8::min_value()).is_some()); assert!(try_cast_u32(u8::min_value()).is_some()); assert!(try_cast_u64(u8::min_value()).is_some()); assert!(try_cast_u128(u8::min_value()).is_some()); assert!(try_cast_i8(u8::min_value()).is_some()); assert!(try_cast_i16(u8::min_value()).is_some()); assert!(try_cast_i32(u8::min_value()).is_some()); assert!(try_cast_i64(u8::min_value()).is_some()); assert!(try_cast_i128(u8::min_value()).is_some()); assert!(try_cast_u8(u8::max_value()).is_some()); assert!(try_cast_u16(u8::max_value()).is_some()); assert!(try_cast_u32(u8::max_value()).is_some()); assert!(try_cast_u64(u8::max_value()).is_some()); assert!(try_cast_u128(u8::max_value()).is_some()); assert!(try_cast_i8(u8::max_value()).is_none()); assert!(try_cast_i16(u8::max_value()).is_some()); assert!(try_cast_i32(u8::max_value()).is_some()); assert!(try_cast_i64(u8::max_value()).is_some()); assert!(try_cast_i128(u8::max_value()).is_some()); assert!(try_cast_usize(u8::min_value()).is_some()); assert!(try_cast_isize(u8::min_value()).is_some()); assert!(try_cast_usize(u8::max_value()).is_some()); assert!(try_cast_isize(u8::max_value()).is_some()); // u16 assert!(try_cast_u8(u16::min_value()).is_some()); assert!(try_cast_u16(u16::min_value()).is_some()); assert!(try_cast_u32(u16::min_value()).is_some()); assert!(try_cast_u64(u16::min_value()).is_some()); assert!(try_cast_u128(u16::min_value()).is_some()); assert!(try_cast_i8(u16::min_value()).is_some()); assert!(try_cast_i16(u16::min_value()).is_some()); assert!(try_cast_i32(u16::min_value()).is_some()); assert!(try_cast_i64(u16::min_value()).is_some()); assert!(try_cast_i128(u16::min_value()).is_some()); assert!(try_cast_u8(u16::max_value()).is_none()); assert!(try_cast_u16(u16::max_value()).is_some()); assert!(try_cast_u32(u16::max_value()).is_some()); assert!(try_cast_u64(u16::max_value()).is_some()); assert!(try_cast_u128(u16::max_value()).is_some()); assert!(try_cast_i8(u16::max_value()).is_none()); assert!(try_cast_i16(u16::max_value()).is_none()); assert!(try_cast_i32(u16::max_value()).is_some()); assert!(try_cast_i64(u16::max_value()).is_some()); assert!(try_cast_i128(u16::max_value()).is_some()); assert!(try_cast_usize(u16::min_value()).is_some()); assert!(try_cast_isize(u16::min_value()).is_some()); assert!(try_cast_usize(u16::max_value()).is_some()); // Discard the results, since platform dependent. Just check it compiles. try_cast_isize(u16::max_value()); // u32 assert!(try_cast_u8(u32::min_value()).is_some()); assert!(try_cast_u16(u32::min_value()).is_some()); assert!(try_cast_u32(u32::min_value()).is_some()); assert!(try_cast_u64(u32::min_value()).is_some()); assert!(try_cast_u128(u32::min_value()).is_some()); assert!(try_cast_i8(u32::min_value()).is_some()); assert!(try_cast_i16(u32::min_value()).is_some()); assert!(try_cast_i32(u32::min_value()).is_some()); assert!(try_cast_i64(u32::min_value()).is_some()); assert!(try_cast_i128(u32::min_value()).is_some()); assert!(try_cast_u8(u32::max_value()).is_none()); assert!(try_cast_u16(u32::max_value()).is_none()); assert!(try_cast_u32(u32::max_value()).is_some()); assert!(try_cast_u64(u32::max_value()).is_some()); assert!(try_cast_u128(u32::max_value()).is_some()); assert!(try_cast_i8(u32::max_value()).is_none()); assert!(try_cast_i16(u32::max_value()).is_none()); assert!(try_cast_i32(u32::max_value()).is_none()); assert!(try_cast_i64(u32::max_value()).is_some()); assert!(try_cast_i128(u32::max_value()).is_some()); assert!(try_cast_usize(u32::min_value()).is_some()); assert!(try_cast_isize(u32::min_value()).is_some()); // Discard the results, since platform dependent. Just check it compiles. try_cast_usize(u32::max_value()); try_cast_isize(u32::max_value()); // u64 assert!(try_cast_u8(u64::min_value()).is_some()); assert!(try_cast_u16(u64::min_value()).is_some()); assert!(try_cast_u32(u64::min_value()).is_some()); assert!(try_cast_u64(u64::min_value()).is_some()); assert!(try_cast_u128(u64::min_value()).is_some()); assert!(try_cast_i8(u64::min_value()).is_some()); assert!(try_cast_i16(u64::min_value()).is_some()); assert!(try_cast_i32(u64::min_value()).is_some()); assert!(try_cast_i64(u64::min_value()).is_some()); assert!(try_cast_i128(u64::min_value()).is_some()); assert!(try_cast_u8(u64::max_value()).is_none()); assert!(try_cast_u16(u64::max_value()).is_none()); assert!(try_cast_u32(u64::max_value()).is_none()); assert!(try_cast_u64(u64::max_value()).is_some()); assert!(try_cast_u128(u64::max_value()).is_some()); assert!(try_cast_i8(u64::max_value()).is_none()); assert!(try_cast_i16(u64::max_value()).is_none()); assert!(try_cast_i32(u64::max_value()).is_none()); assert!(try_cast_i64(u64::max_value()).is_none()); assert!(try_cast_i128(u64::max_value()).is_some()); assert!(try_cast_usize(u64::min_value()).is_some()); assert!(try_cast_isize(u64::min_value()).is_some()); // Discard the results, since platform dependent. Just check it compiles. try_cast_usize(u64::max_value()); try_cast_isize(u64::max_value()); // u128 assert!(try_cast_u8(u128::min_value()).is_some()); assert!(try_cast_u16(u128::min_value()).is_some()); assert!(try_cast_u32(u128::min_value()).is_some()); assert!(try_cast_u64(u128::min_value()).is_some()); assert!(try_cast_u128(u128::min_value()).is_some()); assert!(try_cast_i8(u128::min_value()).is_some()); assert!(try_cast_i16(u128::min_value()).is_some()); assert!(try_cast_i32(u128::min_value()).is_some()); assert!(try_cast_i64(u128::min_value()).is_some()); assert!(try_cast_i128(u128::min_value()).is_some()); assert!(try_cast_u8(u128::max_value()).is_none()); assert!(try_cast_u16(u128::max_value()).is_none()); assert!(try_cast_u32(u128::max_value()).is_none()); assert!(try_cast_u64(u128::max_value()).is_none()); assert!(try_cast_u128(u128::max_value()).is_some()); assert!(try_cast_i8(u128::max_value()).is_none()); assert!(try_cast_i16(u128::max_value()).is_none()); assert!(try_cast_i32(u128::max_value()).is_none()); assert!(try_cast_i64(u128::max_value()).is_none()); assert!(try_cast_i128(u128::max_value()).is_none()); assert!(try_cast_usize(u128::min_value()).is_some()); assert!(try_cast_isize(u128::min_value()).is_some()); assert!(try_cast_usize(u128::max_value()).is_none()); assert!(try_cast_isize(u128::max_value()).is_none()); // i8 assert!(try_cast_u8(i8::min_value()).is_none()); assert!(try_cast_u16(i8::min_value()).is_none()); assert!(try_cast_u32(i8::min_value()).is_none()); assert!(try_cast_u64(i8::min_value()).is_none()); assert!(try_cast_u128(i8::min_value()).is_none()); assert!(try_cast_i8(i8::min_value()).is_some()); assert!(try_cast_i16(i8::min_value()).is_some()); assert!(try_cast_i32(i8::min_value()).is_some()); assert!(try_cast_i64(i8::min_value()).is_some()); assert!(try_cast_i128(i8::min_value()).is_some()); assert!(try_cast_u8(i8::zero()).is_some()); assert!(try_cast_u16(i8::zero()).is_some()); assert!(try_cast_u32(i8::zero()).is_some()); assert!(try_cast_u64(i8::zero()).is_some()); assert!(try_cast_u128(i8::zero()).is_some()); assert!(try_cast_i8(i8::zero()).is_some()); assert!(try_cast_i16(i8::zero()).is_some()); assert!(try_cast_i32(i8::zero()).is_some()); assert!(try_cast_i64(i8::zero()).is_some()); assert!(try_cast_i128(i8::zero()).is_some()); assert!(try_cast_u8(i8::max_value()).is_some()); assert!(try_cast_u16(i8::max_value()).is_some()); assert!(try_cast_u32(i8::max_value()).is_some()); assert!(try_cast_u64(i8::max_value()).is_some()); assert!(try_cast_u128(i8::max_value()).is_some()); assert!(try_cast_i8(i8::max_value()).is_some()); assert!(try_cast_i16(i8::max_value()).is_some()); assert!(try_cast_i32(i8::max_value()).is_some()); assert!(try_cast_i64(i8::max_value()).is_some()); assert!(try_cast_i128(i8::max_value()).is_some()); assert!(try_cast_usize(i8::min_value()).is_none()); assert!(try_cast_isize(i8::min_value()).is_some()); assert!(try_cast_usize(i8::zero()).is_some()); assert!(try_cast_isize(i8::zero()).is_some()); assert!(try_cast_usize(i8::max_value()).is_some()); assert!(try_cast_isize(i8::max_value()).is_some()); // i16 assert!(try_cast_u8(i16::min_value()).is_none()); assert!(try_cast_u16(i16::min_value()).is_none()); assert!(try_cast_u32(i16::min_value()).is_none()); assert!(try_cast_u64(i16::min_value()).is_none()); assert!(try_cast_u128(i16::min_value()).is_none()); assert!(try_cast_i8(i16::min_value()).is_none()); assert!(try_cast_i16(i16::min_value()).is_some()); assert!(try_cast_i32(i16::min_value()).is_some()); assert!(try_cast_i64(i16::min_value()).is_some()); assert!(try_cast_i128(i16::min_value()).is_some()); assert!(try_cast_u8(i16::zero()).is_some()); assert!(try_cast_u16(i16::zero()).is_some()); assert!(try_cast_u32(i16::zero()).is_some()); assert!(try_cast_u64(i16::zero()).is_some()); assert!(try_cast_u128(i16::zero()).is_some()); assert!(try_cast_i8(i16::zero()).is_some()); assert!(try_cast_i16(i16::zero()).is_some()); assert!(try_cast_i32(i16::zero()).is_some()); assert!(try_cast_i64(i16::zero()).is_some()); assert!(try_cast_i128(i16::zero()).is_some()); assert!(try_cast_u8(i16::max_value()).is_none()); assert!(try_cast_u16(i16::max_value()).is_some()); assert!(try_cast_u32(i16::max_value()).is_some()); assert!(try_cast_u64(i16::max_value()).is_some()); assert!(try_cast_u128(i16::max_value()).is_some()); assert!(try_cast_i8(i16::max_value()).is_none()); assert!(try_cast_i16(i16::max_value()).is_some()); assert!(try_cast_i32(i16::max_value()).is_some()); assert!(try_cast_i64(i16::max_value()).is_some()); assert!(try_cast_i128(i16::max_value()).is_some()); assert!(try_cast_usize(i16::min_value()).is_none()); assert!(try_cast_isize(i16::min_value()).is_some()); assert!(try_cast_usize(i16::zero()).is_some()); assert!(try_cast_isize(i16::zero()).is_some()); assert!(try_cast_usize(i16::max_value()).is_some()); assert!(try_cast_isize(i16::max_value()).is_some()); // i32 assert!(try_cast_u8(i32::min_value()).is_none()); assert!(try_cast_u16(i32::min_value()).is_none()); assert!(try_cast_u32(i32::min_value()).is_none()); assert!(try_cast_u64(i32::min_value()).is_none()); assert!(try_cast_u128(i32::min_value()).is_none()); assert!(try_cast_i8(i32::min_value()).is_none()); assert!(try_cast_i16(i32::min_value()).is_none()); assert!(try_cast_i32(i32::min_value()).is_some()); assert!(try_cast_i64(i32::min_value()).is_some()); assert!(try_cast_i128(i32::min_value()).is_some()); assert!(try_cast_u8(i32::zero()).is_some()); assert!(try_cast_u16(i32::zero()).is_some()); assert!(try_cast_u32(i32::zero()).is_some()); assert!(try_cast_u64(i32::zero()).is_some()); assert!(try_cast_u128(i32::zero()).is_some()); assert!(try_cast_i8(i32::zero()).is_some()); assert!(try_cast_i16(i32::zero()).is_some()); assert!(try_cast_i32(i32::zero()).is_some()); assert!(try_cast_i64(i32::zero()).is_some()); assert!(try_cast_i128(i32::zero()).is_some()); assert!(try_cast_u8(i32::max_value()).is_none()); assert!(try_cast_u16(i32::max_value()).is_none()); assert!(try_cast_u32(i32::max_value()).is_some()); assert!(try_cast_u64(i32::max_value()).is_some()); assert!(try_cast_u128(i32::max_value()).is_some()); assert!(try_cast_i8(i32::max_value()).is_none()); assert!(try_cast_i16(i32::max_value()).is_none()); assert!(try_cast_i32(i32::max_value()).is_some()); assert!(try_cast_i64(i32::max_value()).is_some()); assert!(try_cast_i128(i32::max_value()).is_some()); assert!(try_cast_usize(i32::zero()).is_some()); assert!(try_cast_isize(i32::zero()).is_some()); // Discard the results, since platform dependent. Just check it compiles. try_cast_usize(i32::min_value()); try_cast_isize(i32::min_value()); try_cast_usize(i32::max_value()); try_cast_isize(i32::max_value()); // i64 assert!(try_cast_u8(i64::min_value()).is_none()); assert!(try_cast_u16(i64::min_value()).is_none()); assert!(try_cast_u32(i64::min_value()).is_none()); assert!(try_cast_u64(i64::min_value()).is_none()); assert!(try_cast_u128(i64::min_value()).is_none()); assert!(try_cast_i8(i64::min_value()).is_none()); assert!(try_cast_i16(i64::min_value()).is_none()); assert!(try_cast_i32(i64::min_value()).is_none()); assert!(try_cast_i64(i64::min_value()).is_some()); assert!(try_cast_i128(i64::min_value()).is_some()); assert!(try_cast_u8(i64::zero()).is_some()); assert!(try_cast_u16(i64::zero()).is_some()); assert!(try_cast_u32(i64::zero()).is_some()); assert!(try_cast_u64(i64::zero()).is_some()); assert!(try_cast_u128(i64::zero()).is_some()); assert!(try_cast_i8(i64::zero()).is_some()); assert!(try_cast_i16(i64::zero()).is_some()); assert!(try_cast_i32(i64::zero()).is_some()); assert!(try_cast_i64(i64::zero()).is_some()); assert!(try_cast_i128(i64::zero()).is_some()); assert!(try_cast_u8(i64::max_value()).is_none()); assert!(try_cast_u16(i64::max_value()).is_none()); assert!(try_cast_u32(i64::max_value()).is_none()); assert!(try_cast_u64(i64::max_value()).is_some()); assert!(try_cast_u128(i64::max_value()).is_some()); assert!(try_cast_i8(i64::max_value()).is_none()); assert!(try_cast_i16(i64::max_value()).is_none()); assert!(try_cast_i32(i64::max_value()).is_none()); assert!(try_cast_i64(i64::max_value()).is_some()); assert!(try_cast_i128(i64::max_value()).is_some()); assert!(try_cast_usize(i64::zero()).is_some()); assert!(try_cast_isize(i64::zero()).is_some()); // Discard the results, since platform dependent. Just check it compiles. try_cast_usize(i64::min_value()); try_cast_isize(i64::min_value()); try_cast_usize(i64::max_value()); try_cast_isize(i64::max_value()); // i128 assert!(try_cast_u8(i128::min_value()).is_none()); assert!(try_cast_u16(i128::min_value()).is_none()); assert!(try_cast_u32(i128::min_value()).is_none()); assert!(try_cast_u64(i128::min_value()).is_none()); assert!(try_cast_u128(i128::min_value()).is_none()); assert!(try_cast_i8(i128::min_value()).is_none()); assert!(try_cast_i16(i128::min_value()).is_none()); assert!(try_cast_i32(i128::min_value()).is_none()); assert!(try_cast_i64(i128::min_value()).is_none()); assert!(try_cast_i128(i128::min_value()).is_some()); assert!(try_cast_u8(i128::zero()).is_some()); assert!(try_cast_u16(i128::zero()).is_some()); assert!(try_cast_u32(i128::zero()).is_some()); assert!(try_cast_u64(i128::zero()).is_some()); assert!(try_cast_u128(i128::zero()).is_some()); assert!(try_cast_i8(i128::zero()).is_some()); assert!(try_cast_i16(i128::zero()).is_some()); assert!(try_cast_i32(i128::zero()).is_some()); assert!(try_cast_i64(i128::zero()).is_some()); assert!(try_cast_i128(i128::zero()).is_some()); assert!(try_cast_u8(i128::max_value()).is_none()); assert!(try_cast_u16(i128::max_value()).is_none()); assert!(try_cast_u32(i128::max_value()).is_none()); assert!(try_cast_u64(i128::max_value()).is_none()); assert!(try_cast_u128(i128::max_value()).is_some()); assert!(try_cast_i8(i128::max_value()).is_none()); assert!(try_cast_i16(i128::max_value()).is_none()); assert!(try_cast_i32(i128::max_value()).is_none()); assert!(try_cast_i64(i128::max_value()).is_none()); assert!(try_cast_i128(i128::max_value()).is_some()); assert!(try_cast_usize(i128::min_value()).is_none()); assert!(try_cast_isize(i128::min_value()).is_none()); assert!(try_cast_usize(i128::zero()).is_some()); assert!(try_cast_isize(i128::zero()).is_some()); assert!(try_cast_usize(i128::max_value()).is_none()); assert!(try_cast_isize(i128::max_value()).is_none()); // usize assert!(try_cast_u8(usize::min_value()).is_some()); assert!(try_cast_u16(usize::min_value()).is_some()); assert!(try_cast_u32(usize::min_value()).is_some()); assert!(try_cast_u64(usize::min_value()).is_some()); assert!(try_cast_u128(usize::min_value()).is_some()); assert!(try_cast_i8(usize::min_value()).is_some()); assert!(try_cast_i16(usize::min_value()).is_some()); assert!(try_cast_i32(usize::min_value()).is_some()); assert!(try_cast_i64(usize::min_value()).is_some()); assert!(try_cast_i128(usize::min_value()).is_some()); assert!(try_cast_u8(usize::max_value()).is_none()); assert!(try_cast_u64(usize::max_value()).is_some()); assert!(try_cast_u128(usize::max_value()).is_some()); assert!(try_cast_i8(usize::max_value()).is_none()); assert!(try_cast_i16(usize::max_value()).is_none()); assert!(try_cast_i128(usize::max_value()).is_some()); assert!(try_cast_usize(usize::min_value()).is_some()); assert!(try_cast_isize(usize::min_value()).is_some()); assert!(try_cast_usize(usize::max_value()).is_some()); assert!(try_cast_isize(usize::max_value()).is_none()); // Discard the results, since platform dependent. Just check it compiles. try_cast_u16(usize::max_value()); try_cast_u32(usize::max_value()); try_cast_i32(usize::max_value()); try_cast_i64(usize::max_value()); // isize assert!(try_cast_u8(isize::min_value()).is_none()); assert!(try_cast_u16(isize::min_value()).is_none()); assert!(try_cast_u32(isize::min_value()).is_none()); assert!(try_cast_u64(isize::min_value()).is_none()); assert!(try_cast_u128(isize::min_value()).is_none()); assert!(try_cast_i8(isize::min_value()).is_none()); assert!(try_cast_i64(isize::min_value()).is_some()); assert!(try_cast_i128(isize::min_value()).is_some()); assert!(try_cast_u8(isize::zero()).is_some()); assert!(try_cast_u16(isize::zero()).is_some()); assert!(try_cast_u32(isize::zero()).is_some()); assert!(try_cast_u64(isize::zero()).is_some()); assert!(try_cast_u128(isize::zero()).is_some()); assert!(try_cast_i8(isize::zero()).is_some()); assert!(try_cast_i16(isize::zero()).is_some()); assert!(try_cast_i32(isize::zero()).is_some()); assert!(try_cast_i64(isize::zero()).is_some()); assert!(try_cast_i128(isize::zero()).is_some()); assert!(try_cast_u8(isize::max_value()).is_none()); assert!(try_cast_u64(isize::max_value()).is_some()); assert!(try_cast_u128(isize::max_value()).is_some()); assert!(try_cast_i8(isize::max_value()).is_none()); assert!(try_cast_i64(isize::max_value()).is_some()); assert!(try_cast_i128(isize::max_value()).is_some()); assert!(try_cast_usize(isize::min_value()).is_none()); assert!(try_cast_isize(isize::min_value()).is_some()); assert!(try_cast_usize(isize::zero()).is_some()); assert!(try_cast_isize(isize::zero()).is_some()); assert!(try_cast_usize(isize::max_value()).is_some()); assert!(try_cast_isize(isize::max_value()).is_some()); // Discard the results, since platform dependent. Just check it compiles. try_cast_i16(isize::min_value()); try_cast_i32(isize::min_value()); try_cast_u16(isize::max_value()); try_cast_u32(isize::max_value()); try_cast_i16(isize::max_value()); try_cast_i32(isize::max_value()); } #[allow(dead_code)] // Compile-only fn try_float_cast_test() { // from f32 try_cast_u8(f32::MIN); try_cast_u16(f32::MIN); try_cast_u32(f32::MIN); try_cast_u64(f32::MIN); try_cast_u128(f32::MIN); try_cast_usize(f32::MIN); try_cast_i8(f32::MIN); try_cast_i16(f32::MIN); try_cast_i32(f32::MIN); try_cast_i64(f32::MIN); try_cast_i128(f32::MIN); try_cast_isize(f32::MIN); // from f64 try_cast_u8(f64::MIN); try_cast_u16(f64::MIN); try_cast_u32(f64::MIN); try_cast_u64(f64::MIN); try_cast_u128(f64::MIN); try_cast_usize(f64::MIN); try_cast_i8(f64::MIN); try_cast_i16(f64::MIN); try_cast_i32(f64::MIN); try_cast_i64(f64::MIN); try_cast_i128(f64::MIN); try_cast_isize(f64::MIN); // into f32 try_cast_f32(u8::min_value()); try_cast_f32(u16::min_value()); try_cast_f32(u32::min_value()); try_cast_f32(u64::min_value()); try_cast_f32(u128::min_value()); try_cast_f32(usize::min_value()); try_cast_f32(i8::min_value()); try_cast_f32(i16::min_value()); try_cast_f32(i32::min_value()); try_cast_f32(i64::min_value()); try_cast_f32(i128::min_value()); try_cast_f32(isize::min_value()); try_cast_f32(f32::MIN); try_cast_f32(f64::MIN); // into f64 try_cast_f64(u8::min_value()); try_cast_f64(u16::min_value()); try_cast_f64(u32::min_value()); try_cast_f64(u64::min_value()); try_cast_f64(u128::min_value()); try_cast_f64(usize::min_value()); try_cast_f64(i8::min_value()); try_cast_f64(i16::min_value()); try_cast_f64(i32::min_value()); try_cast_f64(i64::min_value()); try_cast_f64(i128::min_value()); try_cast_f64(isize::min_value()); try_cast_f64(f32::MIN); try_cast_f64(f64::MIN); } } lexical-core-0.7.6/src/util/config.rs000075500000000000000000000733030000000000000155520ustar 00000000000000//! Config settings for lexical-core. use crate::lib::slice; use super::algorithm::copy_to_dst; use super::rounding::RoundingKind; // HELPERS /// Determine if the character is a control character for integers or floats. /// Control characters include digits, `.`, `+`, and `-`. fn is_control_character(ch: u8, is_default: bool) -> bool { if is_default { // Default character handles radixes < 15 (where 'e'/'E' is a // a valid exponent character). match ch as char { '0' ..= '9' => true, 'a' ..= 'd' => true, 'A' ..= 'D' => true, '.' | '+' | '-' => true, _ => false, } } else { // Backup character handles radixes >= 15 (where no digit is // a valid exponent character). match ch as char { '0' ..= '9' => true, 'a' ..= 'z' => true, 'A' ..= 'Z' => true, '.' | '+' | '-' => true, _ => false, } } } // Check if byte array starts with case-insensitive N. #[inline] fn starts_with_n(bytes: &[u8]) -> bool { match bytes.get(0) { Some(&b'N') => true, Some(&b'n') => true, _ => false, } } // Check if byte array starts with case-insensitive I. #[inline] fn starts_with_i(bytes: &[u8]) -> bool { match bytes.get(0) { Some(&b'I') => true, Some(&b'i') => true, _ => false, } } /// Fixed-size string for float configurations. /// /// These values are guaranteed less than or equal to the maximum /// number of bytes after a sign byte has been written. pub(crate) struct FloatConfigString { /// Storage data for the config string. data: [u8; F32_FORMATTED_SIZE - 1], /// Actual length of the data. length: usize, } impl FloatConfigString { /// Reset data from a byte string. pub(crate) fn load_bytes(&mut self, bytes: &[u8]) { assert!(bytes.len() <= self.data.len()); copy_to_dst(&mut self.data, bytes); self.length = bytes.len(); } /// Convert to byte slice. pub(crate) fn as_bytes(&self) -> &[u8] { // Always safe, since length can only be set from `load_bytes`. unsafe { self.data.get_unchecked(..self.length) } } } // GLOBALS /// Default character for scientific notation, used when the `radix < 15`. static mut EXPONENT_DEFAULT_CHAR: u8 = b'e'; /// Backup character for scientific notation, used when the `radix >= 15`. #[cfg(feature ="radix")] static mut EXPONENT_BACKUP_CHAR: u8 = b'^'; /// The rounding scheme for float conversions. #[cfg(feature = "rounding")] static mut FLOAT_ROUNDING: RoundingKind = RoundingKind::NearestTieEven; cfg_if! { if #[cfg(feature = "radix")] { /// Not a Number literal. static mut NAN_STRING: FloatConfigString = FloatConfigString { // b"NaN" data: [b'N', b'a', b'N', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0'], length: 3 }; /// Short infinity literal. static mut INF_STRING: FloatConfigString = FloatConfigString { // b"inf" data: [b'i', b'n', b'f', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0'], length: 3 }; /// Long infinity literal. static mut INFINITY_STRING: FloatConfigString = FloatConfigString { // b"infinity" data: [b'i', b'n', b'f', b'i', b'n', b'i', b't', b'y', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0'], length: 8 }; } else { /// Not a Number literal. static mut NAN_STRING: FloatConfigString = FloatConfigString { // b"NaN" data: [b'N', b'a', b'N', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0'], length: 3 }; /// Short infinity literal. static mut INF_STRING: FloatConfigString = FloatConfigString { // b"inf" data: [b'i', b'n', b'f', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0'], length: 3 }; /// Long infinity literal. static mut INFINITY_STRING: FloatConfigString = FloatConfigString { // b"infinity" data: [b'i', b'n', b'f', b'i', b'n', b'i', b't', b'y', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0'], length: 8 }; } } // cfg_if // GETTERS/SETTERS /// Get default character for the exponent symbol. /// /// Default character for scientific notation, used when the `radix < 15`. #[inline] pub fn get_exponent_default_char() -> u8 { unsafe { EXPONENT_DEFAULT_CHAR } } /// Set the default character for the exponent symbol. /// /// Default character for scientific notation, used when the `radix < 15`. /// /// To change the expected, default character for an exponent, /// change this value before using lexical. /// /// * `ch` - Character for exponent symbol. /// /// # Safety /// /// Do not call this function in threaded-code, as it is not thread-safe. /// Do not call this function after compiling any formats. /// /// # Panics /// /// Panics if the character is in the character set `[A-Da-d.+\-]`. #[inline] pub unsafe fn set_exponent_default_char(ch: u8) { assert!(!is_control_character(ch, true)); EXPONENT_DEFAULT_CHAR = ch } /// Get backup character for the exponent symbol. /// /// For numerical strings of `radix >= 15`, 'e' or 'E' is a valid digit, /// and therefore may no longer be used as a marker for the exponent. #[inline] #[cfg(feature ="radix")] pub fn get_exponent_backup_char() -> u8 { unsafe { EXPONENT_BACKUP_CHAR } } /// Set the backup character for the exponent symbol. /// /// For numerical strings of `radix >= 15`, 'e' or 'E' is a valid digit, /// and therefore may no longer be used as a marker for the exponent. /// /// To change the expected, backup character for an exponent, /// change this value before using lexical. /// /// * `ch` - Character for exponent symbol. /// /// # Safety /// /// Do not call this function in threaded-code, as it is not thread-safe. /// Do not call this function after compiling any formats. /// /// # Panics /// /// Panics if the character is in the character set `[A-Za-z.+\-]`. #[inline] #[cfg(feature ="radix")] pub unsafe fn set_exponent_backup_char(ch: u8) { assert!(!is_control_character(ch, false)); EXPONENT_BACKUP_CHAR = ch } /// Get the default rounding scheme for float conversions. /// /// This defines the global rounding-scheme for float parsing operations. /// By default, this is set to `RoundingKind::NearestTieEven`. IEEE754 /// recommends this as the default for all for decimal and binary /// operations. #[inline] #[cfg(feature = "rounding")] pub fn get_float_rounding() -> RoundingKind { unsafe { FLOAT_ROUNDING } } /// Set the default rounding scheme for float conversions. /// /// This defines the global rounding-scheme for float parsing operations. /// By default, this is set to `RoundingKind::NearestTieEven`. IEEE754 /// recommends this as the default for all for decimal and binary /// operations. /// /// # Safety /// /// Do not modify this value in threaded-code, as it is not thread-safe. #[inline] #[cfg(feature = "rounding")] pub unsafe fn set_float_rounding(rounding: RoundingKind) { FLOAT_ROUNDING = rounding } /// Get string representation of Not a Number as a byte slice. #[inline] pub fn get_nan_string() -> &'static [u8] { unsafe { NAN_STRING.as_bytes() } } /// Set representation of Not a Number from a byte slice. /// /// * `bytes` - Slice of bytes to assign as NaN string representation. /// /// # Safety /// /// Do not call this function in threaded-code, as it is not thread-safe. /// /// # Panics /// /// Panics if: /// - `bytes.len() >= f32::FORMATTED_SIZE` /// - `bytes` is empty /// - `bytes` does not start with an `'N'` or `'n'`. #[inline] pub unsafe fn set_nan_string(bytes: &[u8]) { assert!(starts_with_n(bytes)); NAN_STRING.load_bytes(bytes); } /// Get the short representation of an Infinity literal as a byte slice. #[inline] pub fn get_inf_string() -> &'static [u8] { unsafe { INF_STRING.as_bytes() } } /// Set the short representation of Infinity from a byte slice. /// /// * `bytes` - Slice of bytes to assign as Infinity string representation. /// /// # Safety /// /// Do not call this function in threaded-code, as it is not thread-safe. /// /// # Panics /// /// Panics if: /// - `bytes.len() >= f32::FORMATTED_SIZE` /// - `bytes.len() >= get_infinity_string().len()` /// - `bytes` is empty /// - `bytes` does not start with an `'I'` or `'i'`. #[inline] pub unsafe fn set_inf_string(bytes: &[u8]) { assert!(starts_with_i(bytes) && bytes.len() <= INFINITY_STRING.length); INF_STRING.load_bytes(bytes); } /// Get the long representation of an Infinity literal as a byte slice. #[inline] pub fn get_infinity_string() -> &'static [u8] { unsafe { INFINITY_STRING.as_bytes() } } /// Set the long representation of Infinity from a byte slice. /// /// * `bytes` - Slice of bytes to assign as Infinity string representation. /// /// # Safety /// /// Do not call this function in threaded-code, as it is not thread-safe. /// /// # Panics /// /// Panics if: /// - `bytes.len() >= f32::FORMATTED_SIZE` /// - `bytes.len() < get_inf_string().len()` /// - `bytes` is empty /// - `bytes` does not start with an `'I'` or `'i'`. #[inline] pub unsafe fn set_infinity_string(bytes: &[u8]) { assert!(starts_with_i(bytes) && bytes.len() >= INF_STRING.length); INFINITY_STRING.load_bytes(bytes); } // CONSTANTS // The f64 buffer is actually a size of 60, but use 64 since it's a // power of 2. pub(crate) const I8_FORMATTED_SIZE_DECIMAL: usize = 4; pub(crate) const I16_FORMATTED_SIZE_DECIMAL: usize = 6; pub(crate) const I32_FORMATTED_SIZE_DECIMAL: usize = 11; pub(crate) const I64_FORMATTED_SIZE_DECIMAL: usize = 20; pub(crate) const U8_FORMATTED_SIZE_DECIMAL: usize = 3; pub(crate) const U16_FORMATTED_SIZE_DECIMAL: usize = 5; pub(crate) const U32_FORMATTED_SIZE_DECIMAL: usize = 10; pub(crate) const U64_FORMATTED_SIZE_DECIMAL: usize = 20; pub(crate) const F32_FORMATTED_SIZE_DECIMAL: usize = 64; pub(crate) const F64_FORMATTED_SIZE_DECIMAL: usize = 64; pub(crate) const I128_FORMATTED_SIZE_DECIMAL: usize = 40; pub(crate) const U128_FORMATTED_SIZE_DECIMAL: usize = 39; // Simple, fast optimization. // Since we're declaring a variable on the stack, and our power-of-two // alignment dramatically improved atoi performance, do it. cfg_if! { if #[cfg(feature = "radix")] { // Use 256, actually, since we seem to have memory issues with f64. // Clearly not sufficient memory allocated for non-decimal values. pub(crate) const I8_FORMATTED_SIZE: usize = 16; pub(crate) const I16_FORMATTED_SIZE: usize = 32; pub(crate) const I32_FORMATTED_SIZE: usize = 64; pub(crate) const I64_FORMATTED_SIZE: usize = 128; pub(crate) const U8_FORMATTED_SIZE: usize = 16; pub(crate) const U16_FORMATTED_SIZE: usize = 32; pub(crate) const U32_FORMATTED_SIZE: usize = 64; pub(crate) const U64_FORMATTED_SIZE: usize = 128; pub(crate) const F32_FORMATTED_SIZE: usize = 256; pub(crate) const F64_FORMATTED_SIZE: usize = 256; pub(crate) const I128_FORMATTED_SIZE: usize = 256; pub(crate) const U128_FORMATTED_SIZE: usize = 256; } else { // The f64 buffer is actually a size of 60, but use 64 since it's a // power of 2. pub(crate) const I8_FORMATTED_SIZE: usize = I8_FORMATTED_SIZE_DECIMAL; pub(crate) const I16_FORMATTED_SIZE: usize = I16_FORMATTED_SIZE_DECIMAL; pub(crate) const I32_FORMATTED_SIZE: usize = I32_FORMATTED_SIZE_DECIMAL; pub(crate) const I64_FORMATTED_SIZE: usize = I64_FORMATTED_SIZE_DECIMAL; pub(crate) const U8_FORMATTED_SIZE: usize = U8_FORMATTED_SIZE_DECIMAL; pub(crate) const U16_FORMATTED_SIZE: usize = U16_FORMATTED_SIZE_DECIMAL; pub(crate) const U32_FORMATTED_SIZE: usize = U32_FORMATTED_SIZE_DECIMAL; pub(crate) const U64_FORMATTED_SIZE: usize = U64_FORMATTED_SIZE_DECIMAL; pub(crate) const F32_FORMATTED_SIZE: usize = F32_FORMATTED_SIZE_DECIMAL; pub(crate) const F64_FORMATTED_SIZE: usize = F64_FORMATTED_SIZE_DECIMAL; pub(crate) const I128_FORMATTED_SIZE: usize = I128_FORMATTED_SIZE_DECIMAL; pub(crate) const U128_FORMATTED_SIZE: usize = U128_FORMATTED_SIZE_DECIMAL; }} // cfg_if cfg_if! { if #[cfg(target_pointer_width = "16")] { pub(crate) const ISIZE_FORMATTED_SIZE: usize = I16_FORMATTED_SIZE; pub(crate) const ISIZE_FORMATTED_SIZE_DECIMAL: usize = I16_FORMATTED_SIZE_DECIMAL; pub(crate) const USIZE_FORMATTED_SIZE: usize = U16_FORMATTED_SIZE; pub(crate) const USIZE_FORMATTED_SIZE_DECIMAL: usize = U16_FORMATTED_SIZE_DECIMAL; } else if #[cfg(target_pointer_width = "32")] { pub(crate) const ISIZE_FORMATTED_SIZE: usize = I32_FORMATTED_SIZE; pub(crate) const ISIZE_FORMATTED_SIZE_DECIMAL: usize = I32_FORMATTED_SIZE_DECIMAL; pub(crate) const USIZE_FORMATTED_SIZE: usize = U32_FORMATTED_SIZE; pub(crate) const USIZE_FORMATTED_SIZE_DECIMAL: usize = U32_FORMATTED_SIZE_DECIMAL; } else if #[cfg(target_pointer_width = "64")] { pub(crate) const ISIZE_FORMATTED_SIZE: usize = I64_FORMATTED_SIZE; pub(crate) const ISIZE_FORMATTED_SIZE_DECIMAL: usize = I64_FORMATTED_SIZE_DECIMAL; pub(crate) const USIZE_FORMATTED_SIZE: usize = U64_FORMATTED_SIZE; pub(crate) const USIZE_FORMATTED_SIZE_DECIMAL: usize = U64_FORMATTED_SIZE_DECIMAL; }} // cfg_if /// Maximum number of bytes required to serialize any number to string. pub const BUFFER_SIZE: usize = F64_FORMATTED_SIZE; // FUNCTIONS /// Get the exponent notation character. #[inline] #[allow(unused_variables)] pub(crate) fn exponent_notation_char(radix: u32) -> u8 { #[cfg(not(feature ="radix"))] { get_exponent_default_char() } #[cfg(feature ="radix")] { if radix >= 15 { get_exponent_backup_char() } else { get_exponent_default_char() } } } // TEST // ---- #[cfg(test)] mod tests { use crate::util::*; use crate::util::test::*; use super::*; #[cfg(feature ="radix")] #[test] fn exponent_notation_char_test() { let default = get_exponent_default_char(); let backup = get_exponent_backup_char(); assert_eq!(exponent_notation_char(2), default); assert_eq!(exponent_notation_char(8), default); assert_eq!(exponent_notation_char(10), default); assert_eq!(exponent_notation_char(15), backup); assert_eq!(exponent_notation_char(16), backup); assert_eq!(exponent_notation_char(32), backup); } // Only enable when no other threads touch NAN_STRING or INFINITY_STRING. #[test] #[ignore] fn special_bytes_test() { unsafe { let mut buffer = new_buffer(); // Test serializing and deserializing special strings. assert!(f32::from_lexical(b"NaN").unwrap().is_nan()); assert!(f32::from_lexical(b"nan").unwrap().is_nan()); assert!(f32::from_lexical(b"NAN").unwrap().is_nan()); assert!(f32::from_lexical(b"inf").unwrap().is_infinite()); assert!(f32::from_lexical(b"INF").unwrap().is_infinite()); assert!(f32::from_lexical(b"Infinity").unwrap().is_infinite()); assert_eq!(f64::NAN.to_lexical(&mut buffer), b"NaN"); assert_eq!(f64::INFINITY.to_lexical(&mut buffer), b"inf"); set_nan_string(b"nan"); set_inf_string(b"Infinity"); assert!(f32::from_lexical(b"inf").err().unwrap().code == ErrorCode::InvalidDigit); assert!(f32::from_lexical(b"Infinity").unwrap().is_infinite()); assert_eq!(f64::NAN.to_lexical(&mut buffer), b"nan"); assert_eq!(f64::INFINITY.to_lexical(&mut buffer), b"Infinity"); set_nan_string(b"NaN"); set_inf_string(b"inf"); } } // Only enable when no other threads touch FLOAT_ROUNDING. #[cfg(all(feature = "correct", feature = "rounding"))] #[test] #[ignore] fn special_rounding_test() { // Each one of these pairs is halfway, and we can detect the // rounding schemes from this. unsafe { // Nearest, tie-even set_float_rounding(RoundingKind::NearestTieEven); assert_eq!(f64::from_lexical(b"-9007199254740993").unwrap(), -9007199254740992.0); assert_eq!(f64::from_lexical(b"-9007199254740995").unwrap(), -9007199254740996.0); assert_eq!(f64::from_lexical(b"9007199254740993").unwrap(), 9007199254740992.0); assert_eq!(f64::from_lexical(b"9007199254740995").unwrap(), 9007199254740996.0); // Nearest, tie-away-zero set_float_rounding(RoundingKind::NearestTieAwayZero); assert_eq!(f64::from_lexical(b"-9007199254740993").unwrap(), -9007199254740994.0); assert_eq!(f64::from_lexical(b"-9007199254740995").unwrap(), -9007199254740996.0); assert_eq!(f64::from_lexical(b"9007199254740993").unwrap(), 9007199254740994.0); assert_eq!(f64::from_lexical(b"9007199254740995").unwrap(), 9007199254740996.0); // Toward positive infinity set_float_rounding(RoundingKind::TowardPositiveInfinity); assert_eq!(f64::from_lexical(b"-9007199254740993").unwrap(), -9007199254740992.0); assert_eq!(f64::from_lexical(b"-9007199254740995").unwrap(), -9007199254740994.0); assert_eq!(f64::from_lexical(b"9007199254740993").unwrap(), 9007199254740994.0); assert_eq!(f64::from_lexical(b"9007199254740995").unwrap(), 9007199254740996.0); // Toward negative infinity set_float_rounding(RoundingKind::TowardNegativeInfinity); assert_eq!(f64::from_lexical(b"-9007199254740993").unwrap(), -9007199254740994.0); assert_eq!(f64::from_lexical(b"-9007199254740995").unwrap(), -9007199254740996.0); assert_eq!(f64::from_lexical(b"9007199254740993").unwrap(), 9007199254740992.0); assert_eq!(f64::from_lexical(b"9007199254740995").unwrap(), 9007199254740994.0); // Toward zero set_float_rounding(RoundingKind::TowardZero); assert_eq!(f64::from_lexical(b"-9007199254740993").unwrap(), -9007199254740992.0); assert_eq!(f64::from_lexical(b"-9007199254740995").unwrap(), -9007199254740994.0); assert_eq!(f64::from_lexical(b"9007199254740993").unwrap(), 9007199254740992.0); assert_eq!(f64::from_lexical(b"9007199254740995").unwrap(), 9007199254740994.0); // Reset to default set_float_rounding(RoundingKind::NearestTieEven); } } // Only enable when no other threads touch FLOAT_ROUNDING. #[cfg(all(feature = "correct", feature = "radix", feature = "rounding"))] #[test] #[ignore] fn special_rounding_binary_test() { // Each one of these pairs is halfway, and we can detect the // rounding schemes from this. unsafe { // Nearest, tie-even set_float_rounding(RoundingKind::NearestTieEven); assert_eq!(f64::from_lexical_radix(b"-100000000000000000000000000000000000000000000000000001", 2).unwrap(), -9007199254740992.0); assert_eq!(f64::from_lexical_radix(b"-100000000000000000000000000000000000000000000000000011", 2).unwrap(), -9007199254740996.0); assert_eq!(f64::from_lexical_radix(b"100000000000000000000000000000000000000000000000000001", 2).unwrap(), 9007199254740992.0); assert_eq!(f64::from_lexical_radix(b"100000000000000000000000000000000000000000000000000011", 2).unwrap(), 9007199254740996.0); // Nearest, tie-away-zero set_float_rounding(RoundingKind::NearestTieAwayZero); assert_eq!(f64::from_lexical_radix(b"-100000000000000000000000000000000000000000000000000001", 2).unwrap(), -9007199254740994.0); assert_eq!(f64::from_lexical_radix(b"-100000000000000000000000000000000000000000000000000011", 2).unwrap(), -9007199254740996.0); assert_eq!(f64::from_lexical_radix(b"100000000000000000000000000000000000000000000000000001", 2).unwrap(), 9007199254740994.0); assert_eq!(f64::from_lexical_radix(b"100000000000000000000000000000000000000000000000000011", 2).unwrap(), 9007199254740996.0); // Toward positive infinity set_float_rounding(RoundingKind::TowardPositiveInfinity); assert_eq!(f64::from_lexical_radix(b"-100000000000000000000000000000000000000000000000000001", 2).unwrap(), -9007199254740992.0); assert_eq!(f64::from_lexical_radix(b"-100000000000000000000000000000000000000000000000000011", 2).unwrap(), -9007199254740994.0); assert_eq!(f64::from_lexical_radix(b"100000000000000000000000000000000000000000000000000001", 2).unwrap(), 9007199254740994.0); assert_eq!(f64::from_lexical_radix(b"100000000000000000000000000000000000000000000000000011", 2).unwrap(), 9007199254740996.0); // Toward negative infinity set_float_rounding(RoundingKind::TowardNegativeInfinity); assert_eq!(f64::from_lexical_radix(b"-100000000000000000000000000000000000000000000000000001", 2).unwrap(), -9007199254740994.0); assert_eq!(f64::from_lexical_radix(b"-100000000000000000000000000000000000000000000000000011", 2).unwrap(), -9007199254740996.0); assert_eq!(f64::from_lexical_radix(b"100000000000000000000000000000000000000000000000000001", 2).unwrap(), 9007199254740992.0); assert_eq!(f64::from_lexical_radix(b"100000000000000000000000000000000000000000000000000011", 2).unwrap(), 9007199254740994.0); // Toward zero set_float_rounding(RoundingKind::TowardZero); assert_eq!(f64::from_lexical_radix(b"-100000000000000000000000000000000000000000000000000001", 2).unwrap(), -9007199254740992.0); assert_eq!(f64::from_lexical_radix(b"-100000000000000000000000000000000000000000000000000011", 2).unwrap(), -9007199254740994.0); assert_eq!(f64::from_lexical_radix(b"100000000000000000000000000000000000000000000000000001", 2).unwrap(), 9007199254740992.0); assert_eq!(f64::from_lexical_radix(b"100000000000000000000000000000000000000000000000000011", 2).unwrap(), 9007199254740994.0); // Reset to default set_float_rounding(RoundingKind::NearestTieEven); } } #[should_panic] #[test] fn set_exponent_default_char_digit_test() { unsafe { set_exponent_default_char(b'0') } } #[should_panic] #[test] fn set_exponent_default_char_period_test() { unsafe { set_exponent_default_char(b'.') } } #[should_panic] #[test] fn set_exponent_default_char_add_test() { unsafe { set_exponent_default_char(b'+') } } #[should_panic] #[test] fn set_exponent_default_char_sub_test() { unsafe { set_exponent_default_char(b'-') } } #[cfg(all(feature = "radix"))] #[should_panic] #[test] fn set_exponent_backup_char_digit_test() { unsafe { set_exponent_backup_char(b'0') } } #[cfg(all(feature = "radix"))] #[should_panic] #[test] fn set_exponent_backup_char_period_test() { unsafe { set_exponent_backup_char(b'.') } } #[cfg(all(feature = "radix"))] #[should_panic] #[test] fn set_exponent_backup_char_add_test() { unsafe { set_exponent_backup_char(b'+') } } #[cfg(all(feature = "radix"))] #[should_panic] #[test] fn set_exponent_backup_char_sub_test() { unsafe { set_exponent_backup_char(b'-') } } #[should_panic] #[test] fn set_nan_string_empty_test() { unsafe { set_nan_string(b"") } } #[should_panic] #[test] fn set_nan_string_invalid_test() { unsafe { set_nan_string(b"i") } } #[should_panic] #[test] fn set_inf_string_empty_test() { unsafe { set_inf_string(b"") } } #[should_panic] #[test] fn set_inf_string_invalid_test() { unsafe { set_inf_string(b"n") } } #[should_panic] #[test] fn set_inf_string_long_test() { unsafe { set_inf_string(b"infinityinfinf") } } #[should_panic] #[test] fn set_infinity_string_empty_test() { unsafe { set_infinity_string(b"") } } #[should_panic] #[test] fn set_infinity_string_invalid_test() { unsafe { set_infinity_string(b"n") } } #[should_panic] #[test] fn set_infinity_string_short_test() { unsafe { set_infinity_string(b"i") } } } lexical-core-0.7.6/src/util/consume.rs000075500000000000000000001751600000000000000157620ustar 00000000000000//! Algorithms to consume digits and digit separators. //! //! # Complexity //! //! Although superficially quite simple, the level of complexity //! introduced by digit separators can be quite complex, due //! the number of permutations during parsing. //! //! We can consume any combinations of of [0,3] items from the following set: //! - [l]eading digit separators, where digit separators occur before digits. //! - [i]nternal digit separators, where digit separators occur between digits. //! - [t]railing digit separators, where digit separators occur after digits. //! //! In addition to those combinations, we can also have: //! - [c]onsecutive digit separators, which allows two digit separators to be adjacent. //! //! # Shorthand //! //! We will use the term consumer to denote a function that consumes digits, //! splitting an input buffer at an index, where the leading section contains //! valid input digits, and the trailing section contains invalid characters. //! Due to the number of combinations for consumers, we use the following //! shorthand to denote consumers: //! - `no`, does not use a digit separator. //! - `l`, consumes leading digit separators. //! - `i`, consumes internal digit separators. //! - `t`, consumes trailing digit separators. //! - `c`, consumes consecutive digit separators. //! //! Consumers are named `consume_digits_x_separator`, where `x` represents //! the shorthand name of the consumer, in sorted order. For example, //! `consume_digits_ilt` means that consumer can consume //! internal, leading, and trailing digit separators, but not //! consecutive ones. //! //! # Signature //! //! All low-level consumers have the following signature: //! //! ```text //! fn consumer<'a>( //! digits: &'a [u8], //! radix: u32, //! digit_separator: u8 //! ) -> (&'a [u8], &'a [u8]); //! ``` //! //! All high-level consumers have the following signature: //! //! ```text //! fn consumer<'a>( //! digits: &'a [u8], //! radix: u32, //! format: NumberFormat //! ) -> (&'a [u8], &'a [u8]); //! ``` //! //! If the consumer does not require a digit separator, that value is //! simply ignored. use super::format::*; // HELPERS // Convert radix to value. macro_rules! to_digit { ($c:expr, $radix:expr) => (($c as char).to_digit($radix)); } // Convert character to digit. #[inline(always)] fn is_digit(c: u8, radix: u32) -> bool { to_digit!(c, radix).is_some() } // Convert character to digit. #[cfg(feature = "format")] #[inline(always)] fn is_digit_or_separator(c: u8, radix: u32, digit_separator: u8) -> bool { return is_digit(c, radix) || c == digit_separator } // Split buffer at index. #[inline(always)] fn split_at_index<'a>(digits: &'a [u8], index: usize) -> (&'a [u8], &'a [u8]) { (&digits[..index], &digits[index..]) } // CONSUMERS // We use the following convention to denote consumers: // consume_digits_x, where `x` can be: // - , does not use a digit separator. // - l, consumes leading digit separators. // - i, consumes internal digit separators. // - t, consumes trailing digit separators. // - c, consumes consecutive digit separators. // // It then can use any permutation of [lit], with an optional [c] for // each permutation, or use `` for no permutation. // Consume until a an invalid digit is found. // Does not consume any digit separators. #[inline] fn consume_digits<'a>(digits: &'a [u8], radix: u32, _: u8) -> (&'a [u8], &'a [u8]) { // Consume all digits. let mut index = 0; while index < digits.len() && is_digit(index!(digits[index]), radix) { index += 1; } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes internal digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_i<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume all digits and internal digit separators, except for // consecutive digit separators. let mut previous = false; let mut index = 0; while index < digits.len() { let c = index!(digits[index]); if is_digit(c, radix) { index += 1; previous = false; } else if c == digit_separator && index != 0 && !previous { index += 1; previous = true; } else { break; } } // We've gone too far if: // 1). The last character was a digit separator. if previous { index -= 1; } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes internal and consecutive digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_ic<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume all characters that are digits or digit separators, except // for a leading digit separator. let mut index = 0; while index < digits.len() { let c = index!(digits[index]); if is_digit(c, radix) { index += 1; } else if c == digit_separator && index != 0 { index += 1; } else { break; } } // We've gone too far if: // 1). The trailing digits are digit separators. // Preconditions: // 1). If index > 0, we know digits[0] has to a digit. while index > 1 && index!(digits[index-1]) == digit_separator { index -= 1; } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes leading digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_l<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume leading digit separator, if applicable. let mut index = 0; if index < digits.len() && index!(digits[index]) == digit_separator { index += 1; } // Consume all interior digits. // Store the previous index to later determine if any digits // were consumed. let prev_index = index; while index < digits.len() && is_digit(index!(digits[index]), radix) { index += 1; } // We've gone too far if: // 1). We consumed no interior digits. // 2). The next character is a digit separator (cannot be a digit). if prev_index == index && index < digits.len() && index!(digits[index]) == digit_separator { index = 0; } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes leading and consecutive digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_lc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume all leading digit separators, if applicable. let mut index = 0; while index < digits.len() && index!(digits[index]) == digit_separator { index += 1; } // Consume all interior digits. while index < digits.len() && is_digit(index!(digits[index]), radix) { index += 1; } // We cannot have gone too far, because in order to be in an invalid // state, we would have to consume 0 digits and the next character // be a digit separator, which is impossible since we greedily // consume leading digit separators. split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes trailing digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_t<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume all interior digits. let mut index = 0; while index < digits.len() && is_digit(index!(digits[index]), radix) { index += 1; } // Consume a trailing digit separator, if applicable. // Store the previous index to later determine if a digit separator // was consumed. let prev_index = index; if index < digits.len() && index!(digits[index]) == digit_separator { index += 1; } // We have gone too far if: // 1). We consumed a trailing digit separator. // 2). The next character is a digit or digit separator. if index != prev_index && index < digits.len() && is_digit_or_separator(index!(digits[index]), radix, digit_separator) { index = prev_index; } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes trailing and consecutive digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_tc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume all interior digits. let mut index = 0; while index < digits.len() && is_digit(index!(digits[index]), radix) { index += 1; } // Consume all trailing digit separators, if applicable. // Store the previous index to later determine if any digit // separators were consumed. let prev_index = index; while index < digits.len() && index!(digits[index]) == digit_separator { index += 1; } // We have gone too far if: // 1). We consumed more than 1 trailing digit separators. // 2). The next character is a digit (cannot be a digit separator). if index != prev_index && index < digits.len() && is_digit(index!(digits[index]), radix) { index = prev_index; } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes leading and internal digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_il<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume digits and digit separators, until consecutive digit // separators or invalid characters. let mut previous = false; let mut index = 0; while index < digits.len() { let c = index!(digits[index]); if is_digit(c, radix) { index += 1; previous = false; } else if c == digit_separator && !previous { index += 1; previous = true; } else { break; } } // We've taken everything except consecutive digit separators. // We've gone too far if: // 1). The last index was a digit separator unless: // 1). The current index is 1 (index 0 was a digit separator). // 2). The current character is not a digit separator (cannot be a digit). if previous && !(index == 1 && index < digits.len() && index!(digits[index]) != digit_separator) { index -= 1; } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes leading and internal digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_ilc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume digits and digit separators until an invalid character. let mut index = 0; while index < digits.len() { let c = index!(digits[index]); if is_digit_or_separator(c, radix, digit_separator) { index += 1; } else { break; } } // We've taken everything except invalid characters. // We have gone too far if: // 1). We have trailing digit separators. // Remove all trailing digit separators, however, store the index in // case all are removed. let current_index = index; while index >= 1 && index!(digits[index-1]) == digit_separator { index -= 1; } // All trailing digit separators were removed (or current_index is 0). // Reset back to current index. if index == 0 { index = current_index; } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes internal and trailing digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_it<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume all characters that are digits or digit separators, except // leading and consecutive digit separators. let mut previous = false; let mut index = 0; while index < digits.len() { let c = index!(digits[index]); if is_digit(c, radix) { index += 1; previous = false; } else if c == digit_separator && index != 0 && !previous { index += 1; previous = true; } else { break; } } // We needed the check for `index != 0` to ensure we don't consume // buffers like b"_123_". However, We might not have gotten a // trailing separator if: // 1). The index was 0, something like b"_.". if index == 0 && index < digits.len() && index!(digits[index]) == digit_separator { index += 1; previous = true; } // We've taken up to 1 leading digit separator, or anything // except consecutive digit separators. We've gone too far if: // 1). We take consecutive digit separators. // 2). The next character is a digit (only occurs from special index == 9 check). if previous && index < digits.len() && is_digit_or_separator(index!(digits[index]), radix, digit_separator) { index -= 1; } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes internal, trailing, and consecutive digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_itc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume all characters that are digits or digit separators, except // for a leading digit separator. let mut index = 0; while index < digits.len() { let c = index!(digits[index]); if is_digit(c, radix) { index += 1; } else if c == digit_separator && index != 0 { index += 1; } else { break; } } // We needed to check for `index != 0` to ensure we don't consume // buffers like b"_123_". However, We might not have gotten a // trailing separator if: // 1). The index was 0, something like b"_." or b"__.". if index == 0 { // Consume all leading digit separators. while index < digits.len() && index!(digits[index]) == digit_separator { index += 1; } // Now, we might have gone too far. If the next character is a digit, // we need to rollback to 0. if index < digits.len() && is_digit(index!(digits[index]), radix) { index = 0; } } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes leading and trailing digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_lt<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume leading digit separator, if applicable. let mut index = 0; if index < digits.len() && index!(digits[index]) == digit_separator { index += 1; } // Consume all interior digits. // Store the previous index to later determine if any digits // were consumed. let prev_index = index; while index < digits.len() && is_digit(index!(digits[index]), radix) { index += 1; } // Consume a trailing digit separator. If we haven't consumed any digits, // then we have a leading b'__', so we shouldn't consume that either. let mut previous = index == prev_index; if !previous && index < digits.len() && index!(digits[index]) == digit_separator { index += 1; previous = true; } // We have gone too far if: // 1). The last character was a digit separator. // 2). The current character is a digit or digit separator. if index < digits.len() && previous && is_digit_or_separator(index!(digits[index]), radix, digit_separator) { index -= 1; } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes leading, trailing, and consecutive digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_ltc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume all leading digit separators, if applicable. let mut index = 0; while index < digits.len() && index!(digits[index]) == digit_separator { index += 1; } // Consume all interior digits. // We don't need to store the index, because if we consume no digits, // then the next character cannot possibly be a digit separator. while index < digits.len() && is_digit(index!(digits[index]), radix) { index += 1; } // Consume all trailing digit separators. let prev_index = index; while index < digits.len() && index!(digits[index]) == digit_separator { index += 1; } // We have gone too far if: // 1). We consumed trailing digit separators. // 2). The subsequent character is a digit (cannot be a digit separator). if index < digits.len() && index != prev_index && is_digit(index!(digits[index]), radix) { index = prev_index; } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes leading, internal, and trailing digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_ilt<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume digits and digit separators, until consecutive digit // separators or invalid characters. let mut previous = false; let mut index = 0; while index < digits.len() { let c = index!(digits[index]); if is_digit(c, radix) { index += 1; previous = false; } else if c == digit_separator && !previous { index += 1; previous = true; } else { break; } } // We've taken everything except consecutive digit separators. // That means we've gone too far if: // 1). The last character was a digit separator. // 2). The current character is a digit separator. if previous && index < digits.len() && index!(digits[index]) == digit_separator { index -= 1; } split_at_index(digits, index) } // Consume until a an invalid digit is found. // Consumes leading, internal, trailing, and consecutive digit separators. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_iltc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8]) { // Consume digits and digit separators, until an invalid character. // There is no post-condition since we accept any digit or // digit separator combination. let mut index = 0; while index < digits.len() { let c = index!(digits[index]); if is_digit_or_separator(c, radix, digit_separator) { index += 1; } else { break; } } split_at_index(digits, index) } // API // Consume digits without a digit separator. #[inline] pub(crate) fn consume_digits_no_separator<'a>(bytes: &'a [u8], radix: u32, format: NumberFormat) -> (&'a [u8], &'a [u8]) { consume_digits(bytes, radix, format.digit_separator()) } // Consume digits while ignoring the digit separator. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_digits_ignore_separator<'a>(bytes: &'a [u8], radix: u32, format: NumberFormat) -> (&'a [u8], &'a [u8]) { consume_digits_iltc(bytes, radix, format.digit_separator()) } // Consume digits with a digit separator in the integer component. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_integer_digits_separator<'a>(bytes: &'a [u8], radix: u32, format: NumberFormat) -> (&'a [u8], &'a [u8]) { const I: NumberFormat = NumberFormat::INTEGER_INTERNAL_DIGIT_SEPARATOR; const L: NumberFormat = NumberFormat::INTEGER_LEADING_DIGIT_SEPARATOR; const T: NumberFormat = NumberFormat::INTEGER_TRAILING_DIGIT_SEPARATOR; const C: NumberFormat = NumberFormat::INTEGER_CONSECUTIVE_DIGIT_SEPARATOR; const IL: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | L.bits()); const IT: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | T.bits()); const LT: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | T.bits()); const ILT: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | T.bits()); const IC: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | C.bits()); const LC: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | C.bits()); const TC: NumberFormat = NumberFormat::from_bits_truncate(T.bits() | C.bits()); const ILC: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | C.bits()); const ITC: NumberFormat = NumberFormat::from_bits_truncate(IT.bits() | C.bits()); const LTC: NumberFormat = NumberFormat::from_bits_truncate(LT.bits() | C.bits()); const ILTC: NumberFormat = NumberFormat::from_bits_truncate(ILT.bits() | C.bits()); let digit_separator = format.digit_separator(); match format & NumberFormat::INTEGER_DIGIT_SEPARATOR_FLAG_MASK { I => consume_digits_i(bytes, radix, digit_separator), IC => consume_digits_ic(bytes, radix, digit_separator), L => consume_digits_l(bytes, radix, digit_separator), LC => consume_digits_lc(bytes, radix, digit_separator), T => consume_digits_t(bytes, radix, digit_separator), TC => consume_digits_tc(bytes, radix, digit_separator), IL => consume_digits_il(bytes, radix, digit_separator), ILC => consume_digits_ilc(bytes, radix, digit_separator), IT => consume_digits_it(bytes, radix, digit_separator), ITC => consume_digits_itc(bytes, radix, digit_separator), LT => consume_digits_lt(bytes, radix, digit_separator), LTC => consume_digits_ltc(bytes, radix, digit_separator), ILT => consume_digits_ilt(bytes, radix, digit_separator), ILTC => consume_digits_iltc(bytes, radix, digit_separator), _ => unreachable!() } } // Consume digits with a digit separator in the fraction component. #[inline] #[cfg(feature = "format")] pub(crate) fn consume_fraction_digits_separator<'a>(bytes: &'a [u8], radix: u32, format: NumberFormat) -> (&'a [u8], &'a [u8]) { const I: NumberFormat = NumberFormat::FRACTION_INTERNAL_DIGIT_SEPARATOR; const L: NumberFormat = NumberFormat::FRACTION_LEADING_DIGIT_SEPARATOR; const T: NumberFormat = NumberFormat::FRACTION_TRAILING_DIGIT_SEPARATOR; const C: NumberFormat = NumberFormat::FRACTION_CONSECUTIVE_DIGIT_SEPARATOR; const IL: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | L.bits()); const IT: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | T.bits()); const LT: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | T.bits()); const ILT: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | T.bits()); const IC: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | C.bits()); const LC: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | C.bits()); const TC: NumberFormat = NumberFormat::from_bits_truncate(T.bits() | C.bits()); const ILC: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | C.bits()); const ITC: NumberFormat = NumberFormat::from_bits_truncate(IT.bits() | C.bits()); const LTC: NumberFormat = NumberFormat::from_bits_truncate(LT.bits() | C.bits()); const ILTC: NumberFormat = NumberFormat::from_bits_truncate(ILT.bits() | C.bits()); let digit_separator = format.digit_separator(); match format & NumberFormat::FRACTION_DIGIT_SEPARATOR_FLAG_MASK { I => consume_digits_i(bytes, radix, digit_separator), IC => consume_digits_ic(bytes, radix, digit_separator), L => consume_digits_l(bytes, radix, digit_separator), LC => consume_digits_lc(bytes, radix, digit_separator), T => consume_digits_t(bytes, radix, digit_separator), TC => consume_digits_tc(bytes, radix, digit_separator), IL => consume_digits_il(bytes, radix, digit_separator), ILC => consume_digits_ilc(bytes, radix, digit_separator), IT => consume_digits_it(bytes, radix, digit_separator), ITC => consume_digits_itc(bytes, radix, digit_separator), LT => consume_digits_lt(bytes, radix, digit_separator), LTC => consume_digits_ltc(bytes, radix, digit_separator), ILT => consume_digits_ilt(bytes, radix, digit_separator), ILTC => consume_digits_iltc(bytes, radix, digit_separator), _ => unreachable!() } } // TESTS // ----- #[cfg(test)] mod tests { use super::*; #[test] fn consume_digits_test() { assert_eq!(consume_digits(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits(b!("_45"), 10, b'_'), (b!(""), b!("_45"))); assert_eq!(consume_digits(b!("__45"), 10, b'_'), (b!(""), b!("__45"))); assert_eq!(consume_digits(b!("_.45"), 10, b'_'), (b!(""), b!("_.45"))); assert_eq!(consume_digits(b!("__.45"), 10, b'_'), (b!(""), b!("__.45"))); assert_eq!(consume_digits(b!("4_5"), 10, b'_'), (b!("4"), b!("_5"))); assert_eq!(consume_digits(b!("4__5"), 10, b'_'), (b!("4"), b!("__5"))); assert_eq!(consume_digits(b!("4_"), 10, b'_'), (b!("4"), b!("_"))); assert_eq!(consume_digits(b!("4__"), 10, b'_'), (b!("4"), b!("__"))); assert_eq!(consume_digits(b!("4_."), 10, b'_'), (b!("4"), b!("_."))); assert_eq!(consume_digits(b!("4__."), 10, b'_'), (b!("4"), b!("__."))); assert_eq!(consume_digits(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5"))); assert_eq!(consume_digits(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5"))); assert_eq!(consume_digits(b!("_.45_5"), 10, b'_'), (b!(""), b!("_.45_5"))); assert_eq!(consume_digits(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5"))); assert_eq!(consume_digits(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_"))); assert_eq!(consume_digits(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__"))); assert_eq!(consume_digits(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5"))); assert_eq!(consume_digits(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5"))); assert_eq!(consume_digits(b!("_45_"), 10, b'_'), (b!(""), b!("_45_"))); assert_eq!(consume_digits(b!("__45__"), 10, b'_'), (b!(""), b!("__45__"))); assert_eq!(consume_digits(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56"))); assert_eq!(consume_digits(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56"))); assert_eq!(consume_digits(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_"))); assert_eq!(consume_digits(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__"))); assert_eq!(consume_digits(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56"))); assert_eq!(consume_digits(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56"))); } #[cfg(feature = "format")] #[test] fn consume_digits_l_test() { assert_eq!(consume_digits_l(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_l(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_l(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_l(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_l(b!("_45"), 10, b'_'), (b!("_45"), b!(""))); assert_eq!(consume_digits_l(b!("__45"), 10, b'_'), (b!(""), b!("__45"))); assert_eq!(consume_digits_l(b!("_.45"), 10, b'_'), (b!("_"), b!(".45"))); assert_eq!(consume_digits_l(b!("__.45"), 10, b'_'), (b!(""), b!("__.45"))); assert_eq!(consume_digits_l(b!("4_5"), 10, b'_'), (b!("4"), b!("_5"))); assert_eq!(consume_digits_l(b!("4__5"), 10, b'_'), (b!("4"), b!("__5"))); assert_eq!(consume_digits_l(b!("4_"), 10, b'_'), (b!("4"), b!("_"))); assert_eq!(consume_digits_l(b!("4__"), 10, b'_'), (b!("4"), b!("__"))); assert_eq!(consume_digits_l(b!("4_."), 10, b'_'), (b!("4"), b!("_."))); assert_eq!(consume_digits_l(b!("4__."), 10, b'_'), (b!("4"), b!("__."))); assert_eq!(consume_digits_l(b!("_45_5"), 10, b'_'), (b!("_45"), b!("_5"))); assert_eq!(consume_digits_l(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5"))); assert_eq!(consume_digits_l(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5"))); assert_eq!(consume_digits_l(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5"))); assert_eq!(consume_digits_l(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_"))); assert_eq!(consume_digits_l(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__"))); assert_eq!(consume_digits_l(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5"))); assert_eq!(consume_digits_l(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5"))); assert_eq!(consume_digits_l(b!("_45_"), 10, b'_'), (b!("_45"), b!("_"))); assert_eq!(consume_digits_l(b!("__45__"), 10, b'_'), (b!(""), b!("__45__"))); assert_eq!(consume_digits_l(b!("_45_.56"), 10, b'_'), (b!("_45"), b!("_.56"))); assert_eq!(consume_digits_l(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56"))); assert_eq!(consume_digits_l(b!("_4_5_"), 10, b'_'), (b!("_4"), b!("_5_"))); assert_eq!(consume_digits_l(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__"))); assert_eq!(consume_digits_l(b!("_4_5_.56"), 10, b'_'), (b!("_4"), b!("_5_.56"))); assert_eq!(consume_digits_l(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56"))); assert_eq!(consume_digits_lc(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_lc(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_lc(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_lc(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_lc(b!("_45"), 10, b'_'), (b!("_45"), b!(""))); assert_eq!(consume_digits_lc(b!("__45"), 10, b'_'), (b!("__45"), b!(""))); assert_eq!(consume_digits_lc(b!("_.45"), 10, b'_'), (b!("_"), b!(".45"))); assert_eq!(consume_digits_lc(b!("__.45"), 10, b'_'), (b!("__"), b!(".45"))); assert_eq!(consume_digits_lc(b!("4_5"), 10, b'_'), (b!("4"), b!("_5"))); assert_eq!(consume_digits_lc(b!("4__5"), 10, b'_'), (b!("4"), b!("__5"))); assert_eq!(consume_digits_lc(b!("4_"), 10, b'_'), (b!("4"), b!("_"))); assert_eq!(consume_digits_lc(b!("4__"), 10, b'_'), (b!("4"), b!("__"))); assert_eq!(consume_digits_lc(b!("4_."), 10, b'_'), (b!("4"), b!("_."))); assert_eq!(consume_digits_lc(b!("4__."), 10, b'_'), (b!("4"), b!("__."))); assert_eq!(consume_digits_lc(b!("_45_5"), 10, b'_'), (b!("_45"), b!("_5"))); assert_eq!(consume_digits_lc(b!("__45__5"), 10, b'_'), (b!("__45"), b!("__5"))); assert_eq!(consume_digits_lc(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5"))); assert_eq!(consume_digits_lc(b!("__.45__5"), 10, b'_'), (b!("__"), b!(".45__5"))); assert_eq!(consume_digits_lc(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_"))); assert_eq!(consume_digits_lc(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__"))); assert_eq!(consume_digits_lc(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5"))); assert_eq!(consume_digits_lc(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5"))); assert_eq!(consume_digits_lc(b!("_45_"), 10, b'_'), (b!("_45"), b!("_"))); assert_eq!(consume_digits_lc(b!("__45__"), 10, b'_'), (b!("__45"), b!("__"))); assert_eq!(consume_digits_lc(b!("_45_.56"), 10, b'_'), (b!("_45"), b!("_.56"))); assert_eq!(consume_digits_lc(b!("__45__.56"), 10, b'_'), (b!("__45"), b!("__.56"))); assert_eq!(consume_digits_lc(b!("_4_5_"), 10, b'_'), (b!("_4"), b!("_5_"))); assert_eq!(consume_digits_lc(b!("__4__5__"), 10, b'_'), (b!("__4"), b!("__5__"))); assert_eq!(consume_digits_lc(b!("_4_5_.56"), 10, b'_'), (b!("_4"), b!("_5_.56"))); assert_eq!(consume_digits_lc(b!("__4__5__.56"), 10, b'_'), (b!("__4"), b!("__5__.56"))); } #[cfg(feature = "format")] #[test] fn consume_digits_i_test() { assert_eq!(consume_digits_i(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_i(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_i(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_i(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_i(b!("_45"), 10, b'_'), (b!(""), b!("_45"))); assert_eq!(consume_digits_i(b!("__45"), 10, b'_'), (b!(""), b!("__45"))); assert_eq!(consume_digits_i(b!("_.45"), 10, b'_'), (b!(""), b!("_.45"))); assert_eq!(consume_digits_i(b!("__.45"), 10, b'_'), (b!(""), b!("__.45"))); assert_eq!(consume_digits_i(b!("4_5"), 10, b'_'), (b!("4_5"), b!(""))); assert_eq!(consume_digits_i(b!("4__5"), 10, b'_'), (b!("4"), b!("__5"))); assert_eq!(consume_digits_i(b!("4_"), 10, b'_'), (b!("4"), b!("_"))); assert_eq!(consume_digits_i(b!("4__"), 10, b'_'), (b!("4"), b!("__"))); assert_eq!(consume_digits_i(b!("4_."), 10, b'_'), (b!("4"), b!("_."))); assert_eq!(consume_digits_i(b!("4__."), 10, b'_'), (b!("4"), b!("__."))); assert_eq!(consume_digits_i(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5"))); assert_eq!(consume_digits_i(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5"))); assert_eq!(consume_digits_i(b!("_.45_5"), 10, b'_'), (b!(""), b!("_.45_5"))); assert_eq!(consume_digits_i(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5"))); assert_eq!(consume_digits_i(b!("4_5_"), 10, b'_'), (b!("4_5"), b!("_"))); assert_eq!(consume_digits_i(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__"))); assert_eq!(consume_digits_i(b!("4_5_.5"), 10, b'_'), (b!("4_5"), b!("_.5"))); assert_eq!(consume_digits_i(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5"))); assert_eq!(consume_digits_i(b!("_45_"), 10, b'_'), (b!(""), b!("_45_"))); assert_eq!(consume_digits_i(b!("__45__"), 10, b'_'), (b!(""), b!("__45__"))); assert_eq!(consume_digits_i(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56"))); assert_eq!(consume_digits_i(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56"))); assert_eq!(consume_digits_i(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_"))); assert_eq!(consume_digits_i(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__"))); assert_eq!(consume_digits_i(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56"))); assert_eq!(consume_digits_i(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56"))); assert_eq!(consume_digits_ic(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_ic(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_ic(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_ic(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_ic(b!("_45"), 10, b'_'), (b!(""), b!("_45"))); assert_eq!(consume_digits_ic(b!("__45"), 10, b'_'), (b!(""), b!("__45"))); assert_eq!(consume_digits_ic(b!("_.45"), 10, b'_'), (b!(""), b!("_.45"))); assert_eq!(consume_digits_ic(b!("__.45"), 10, b'_'), (b!(""), b!("__.45"))); assert_eq!(consume_digits_ic(b!("4_5"), 10, b'_'), (b!("4_5"), b!(""))); assert_eq!(consume_digits_ic(b!("4__5"), 10, b'_'), (b!("4__5"), b!(""))); assert_eq!(consume_digits_ic(b!("4_"), 10, b'_'), (b!("4"), b!("_"))); assert_eq!(consume_digits_ic(b!("4__"), 10, b'_'), (b!("4"), b!("__"))); assert_eq!(consume_digits_ic(b!("4_."), 10, b'_'), (b!("4"), b!("_."))); assert_eq!(consume_digits_ic(b!("4__."), 10, b'_'), (b!("4"), b!("__."))); assert_eq!(consume_digits_ic(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5"))); assert_eq!(consume_digits_ic(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5"))); assert_eq!(consume_digits_ic(b!("_.45_5"), 10, b'_'), (b!(""), b!("_.45_5"))); assert_eq!(consume_digits_ic(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5"))); assert_eq!(consume_digits_ic(b!("4_5_"), 10, b'_'), (b!("4_5"), b!("_"))); assert_eq!(consume_digits_ic(b!("4__5__"), 10, b'_'), (b!("4__5"), b!("__"))); assert_eq!(consume_digits_ic(b!("4_5_.5"), 10, b'_'), (b!("4_5"), b!("_.5"))); assert_eq!(consume_digits_ic(b!("4__5__.5"), 10, b'_'), (b!("4__5"), b!("__.5"))); assert_eq!(consume_digits_ic(b!("_45_"), 10, b'_'), (b!(""), b!("_45_"))); assert_eq!(consume_digits_ic(b!("__45__"), 10, b'_'), (b!(""), b!("__45__"))); assert_eq!(consume_digits_ic(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56"))); assert_eq!(consume_digits_ic(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56"))); assert_eq!(consume_digits_ic(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_"))); assert_eq!(consume_digits_ic(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__"))); assert_eq!(consume_digits_ic(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56"))); assert_eq!(consume_digits_ic(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56"))); } #[cfg(feature = "format")] #[test] fn consume_digits_t_test() { assert_eq!(consume_digits_t(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_t(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_t(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_t(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_t(b!("_45"), 10, b'_'), (b!(""), b!("_45"))); assert_eq!(consume_digits_t(b!("__45"), 10, b'_'), (b!(""), b!("__45"))); assert_eq!(consume_digits_t(b!("_.45"), 10, b'_'), (b!("_"), b!(".45"))); assert_eq!(consume_digits_t(b!("__.45"), 10, b'_'), (b!(""), b!("__.45"))); assert_eq!(consume_digits_t(b!("4_5"), 10, b'_'), (b!("4"), b!("_5"))); assert_eq!(consume_digits_t(b!("4__5"), 10, b'_'), (b!("4"), b!("__5"))); assert_eq!(consume_digits_t(b!("4_"), 10, b'_'), (b!("4_"), b!(""))); assert_eq!(consume_digits_t(b!("4__"), 10, b'_'), (b!("4"), b!("__"))); assert_eq!(consume_digits_t(b!("4_."), 10, b'_'), (b!("4_"), b!("."))); assert_eq!(consume_digits_t(b!("4__."), 10, b'_'), (b!("4"), b!("__."))); assert_eq!(consume_digits_t(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5"))); assert_eq!(consume_digits_t(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5"))); assert_eq!(consume_digits_t(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5"))); assert_eq!(consume_digits_t(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5"))); assert_eq!(consume_digits_t(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_"))); assert_eq!(consume_digits_t(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__"))); assert_eq!(consume_digits_t(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5"))); assert_eq!(consume_digits_t(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5"))); assert_eq!(consume_digits_t(b!("_45_"), 10, b'_'), (b!(""), b!("_45_"))); assert_eq!(consume_digits_t(b!("__45__"), 10, b'_'), (b!(""), b!("__45__"))); assert_eq!(consume_digits_t(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56"))); assert_eq!(consume_digits_t(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56"))); assert_eq!(consume_digits_t(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_"))); assert_eq!(consume_digits_t(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__"))); assert_eq!(consume_digits_t(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56"))); assert_eq!(consume_digits_t(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56"))); assert_eq!(consume_digits_tc(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_tc(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_tc(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_tc(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_tc(b!("_45"), 10, b'_'), (b!(""), b!("_45"))); assert_eq!(consume_digits_tc(b!("__45"), 10, b'_'), (b!(""), b!("__45"))); assert_eq!(consume_digits_tc(b!("_.45"), 10, b'_'), (b!("_"), b!(".45"))); assert_eq!(consume_digits_tc(b!("__.45"), 10, b'_'), (b!("__"), b!(".45"))); assert_eq!(consume_digits_tc(b!("4_5"), 10, b'_'), (b!("4"), b!("_5"))); assert_eq!(consume_digits_tc(b!("4__5"), 10, b'_'), (b!("4"), b!("__5"))); assert_eq!(consume_digits_tc(b!("4_"), 10, b'_'), (b!("4_"), b!(""))); assert_eq!(consume_digits_tc(b!("4__"), 10, b'_'), (b!("4__"), b!(""))); assert_eq!(consume_digits_tc(b!("4_."), 10, b'_'), (b!("4_"), b!("."))); assert_eq!(consume_digits_tc(b!("4__."), 10, b'_'), (b!("4__"), b!("."))); assert_eq!(consume_digits_tc(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5"))); assert_eq!(consume_digits_tc(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5"))); assert_eq!(consume_digits_tc(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5"))); assert_eq!(consume_digits_tc(b!("__.45__5"), 10, b'_'), (b!("__"), b!(".45__5"))); assert_eq!(consume_digits_tc(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_"))); assert_eq!(consume_digits_tc(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__"))); assert_eq!(consume_digits_tc(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5"))); assert_eq!(consume_digits_tc(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5"))); assert_eq!(consume_digits_tc(b!("_45_"), 10, b'_'), (b!(""), b!("_45_"))); assert_eq!(consume_digits_tc(b!("__45__"), 10, b'_'), (b!(""), b!("__45__"))); assert_eq!(consume_digits_tc(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56"))); assert_eq!(consume_digits_tc(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56"))); assert_eq!(consume_digits_tc(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_"))); assert_eq!(consume_digits_tc(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__"))); assert_eq!(consume_digits_tc(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56"))); assert_eq!(consume_digits_tc(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56"))); } #[cfg(feature = "format")] #[test] fn consume_digits_il_test() { assert_eq!(consume_digits_il(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_il(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_il(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_il(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_il(b!("_45"), 10, b'_'), (b!("_45"), b!(""))); assert_eq!(consume_digits_il(b!("__45"), 10, b'_'), (b!(""), b!("__45"))); assert_eq!(consume_digits_il(b!("_.45"), 10, b'_'), (b!("_"), b!(".45"))); assert_eq!(consume_digits_il(b!("__.45"), 10, b'_'), (b!(""), b!("__.45"))); assert_eq!(consume_digits_il(b!("4_5"), 10, b'_'), (b!("4_5"), b!(""))); assert_eq!(consume_digits_il(b!("4__5"), 10, b'_'), (b!("4"), b!("__5"))); assert_eq!(consume_digits_il(b!("4_"), 10, b'_'), (b!("4"), b!("_"))); assert_eq!(consume_digits_il(b!("4__"), 10, b'_'), (b!("4"), b!("__"))); assert_eq!(consume_digits_il(b!("4_."), 10, b'_'), (b!("4"), b!("_."))); assert_eq!(consume_digits_il(b!("4__."), 10, b'_'), (b!("4"), b!("__."))); assert_eq!(consume_digits_il(b!("_45_5"), 10, b'_'), (b!("_45_5"), b!(""))); assert_eq!(consume_digits_il(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5"))); assert_eq!(consume_digits_il(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5"))); assert_eq!(consume_digits_il(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5"))); assert_eq!(consume_digits_il(b!("4_5_"), 10, b'_'), (b!("4_5"), b!("_"))); assert_eq!(consume_digits_il(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__"))); assert_eq!(consume_digits_il(b!("4_5_.5"), 10, b'_'), (b!("4_5"), b!("_.5"))); assert_eq!(consume_digits_il(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5"))); assert_eq!(consume_digits_il(b!("_45_"), 10, b'_'), (b!("_45"), b!("_"))); assert_eq!(consume_digits_il(b!("__45__"), 10, b'_'), (b!(""), b!("__45__"))); assert_eq!(consume_digits_il(b!("_45_.56"), 10, b'_'), (b!("_45"), b!("_.56"))); assert_eq!(consume_digits_il(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56"))); assert_eq!(consume_digits_il(b!("_4_5_"), 10, b'_'), (b!("_4_5"), b!("_"))); assert_eq!(consume_digits_il(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__"))); assert_eq!(consume_digits_il(b!("_4_5_.56"), 10, b'_'), (b!("_4_5"), b!("_.56"))); assert_eq!(consume_digits_il(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56"))); assert_eq!(consume_digits_ilc(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_ilc(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_ilc(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_ilc(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_ilc(b!("_45"), 10, b'_'), (b!("_45"), b!(""))); assert_eq!(consume_digits_ilc(b!("__45"), 10, b'_'), (b!("__45"), b!(""))); assert_eq!(consume_digits_ilc(b!("_.45"), 10, b'_'), (b!("_"), b!(".45"))); assert_eq!(consume_digits_ilc(b!("__.45"), 10, b'_'), (b!("__"), b!(".45"))); assert_eq!(consume_digits_ilc(b!("4_5"), 10, b'_'), (b!("4_5"), b!(""))); assert_eq!(consume_digits_ilc(b!("4__5"), 10, b'_'), (b!("4__5"), b!(""))); assert_eq!(consume_digits_ilc(b!("4_"), 10, b'_'), (b!("4"), b!("_"))); assert_eq!(consume_digits_ilc(b!("4__"), 10, b'_'), (b!("4"), b!("__"))); assert_eq!(consume_digits_ilc(b!("4_."), 10, b'_'), (b!("4"), b!("_."))); assert_eq!(consume_digits_ilc(b!("4__."), 10, b'_'), (b!("4"), b!("__."))); assert_eq!(consume_digits_ilc(b!("_45_5"), 10, b'_'), (b!("_45_5"), b!(""))); assert_eq!(consume_digits_ilc(b!("__45__5"), 10, b'_'), (b!("__45__5"), b!(""))); assert_eq!(consume_digits_ilc(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5"))); assert_eq!(consume_digits_ilc(b!("__.45__5"), 10, b'_'), (b!("__"), b!(".45__5"))); assert_eq!(consume_digits_ilc(b!("4_5_"), 10, b'_'), (b!("4_5"), b!("_"))); assert_eq!(consume_digits_ilc(b!("4__5__"), 10, b'_'), (b!("4__5"), b!("__"))); assert_eq!(consume_digits_ilc(b!("4_5_.5"), 10, b'_'), (b!("4_5"), b!("_.5"))); assert_eq!(consume_digits_ilc(b!("4__5__.5"), 10, b'_'), (b!("4__5"), b!("__.5"))); assert_eq!(consume_digits_ilc(b!("_45_"), 10, b'_'), (b!("_45"), b!("_"))); assert_eq!(consume_digits_ilc(b!("__45__"), 10, b'_'), (b!("__45"), b!("__"))); assert_eq!(consume_digits_ilc(b!("_45_.56"), 10, b'_'), (b!("_45"), b!("_.56"))); assert_eq!(consume_digits_ilc(b!("__45__.56"), 10, b'_'), (b!("__45"), b!("__.56"))); assert_eq!(consume_digits_ilc(b!("_4_5_"), 10, b'_'), (b!("_4_5"), b!("_"))); assert_eq!(consume_digits_ilc(b!("__4__5__"), 10, b'_'), (b!("__4__5"), b!("__"))); assert_eq!(consume_digits_ilc(b!("_4_5_.56"), 10, b'_'), (b!("_4_5"), b!("_.56"))); assert_eq!(consume_digits_ilc(b!("__4__5__.56"), 10, b'_'), (b!("__4__5"), b!("__.56"))); } #[cfg(feature = "format")] #[test] fn consume_digits_it_test() { assert_eq!(consume_digits_it(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_it(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_it(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_it(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_it(b!("_45"), 10, b'_'), (b!(""), b!("_45"))); assert_eq!(consume_digits_it(b!("__45"), 10, b'_'), (b!(""), b!("__45"))); assert_eq!(consume_digits_it(b!("_.45"), 10, b'_'), (b!("_"), b!(".45"))); assert_eq!(consume_digits_it(b!("__.45"), 10, b'_'), (b!(""), b!("__.45"))); assert_eq!(consume_digits_it(b!("4_5"), 10, b'_'), (b!("4_5"), b!(""))); assert_eq!(consume_digits_it(b!("4__5"), 10, b'_'), (b!("4"), b!("__5"))); assert_eq!(consume_digits_it(b!("4_"), 10, b'_'), (b!("4_"), b!(""))); assert_eq!(consume_digits_it(b!("4__"), 10, b'_'), (b!("4"), b!("__"))); assert_eq!(consume_digits_it(b!("4_."), 10, b'_'), (b!("4_"), b!("."))); assert_eq!(consume_digits_it(b!("4__."), 10, b'_'), (b!("4"), b!("__."))); assert_eq!(consume_digits_it(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5"))); assert_eq!(consume_digits_it(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5"))); assert_eq!(consume_digits_it(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5"))); assert_eq!(consume_digits_it(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5"))); assert_eq!(consume_digits_it(b!("4_5_"), 10, b'_'), (b!("4_5_"), b!(""))); assert_eq!(consume_digits_it(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__"))); assert_eq!(consume_digits_it(b!("4_5_.5"), 10, b'_'), (b!("4_5_"), b!(".5"))); assert_eq!(consume_digits_it(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5"))); assert_eq!(consume_digits_it(b!("_45_"), 10, b'_'), (b!(""), b!("_45_"))); assert_eq!(consume_digits_it(b!("__45__"), 10, b'_'), (b!(""), b!("__45__"))); assert_eq!(consume_digits_it(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56"))); assert_eq!(consume_digits_it(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56"))); assert_eq!(consume_digits_it(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_"))); assert_eq!(consume_digits_it(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__"))); assert_eq!(consume_digits_it(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56"))); assert_eq!(consume_digits_it(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56"))); assert_eq!(consume_digits_itc(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_itc(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_itc(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_itc(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_itc(b!("_45"), 10, b'_'), (b!(""), b!("_45"))); assert_eq!(consume_digits_itc(b!("__45"), 10, b'_'), (b!(""), b!("__45"))); assert_eq!(consume_digits_itc(b!("_.45"), 10, b'_'), (b!("_"), b!(".45"))); assert_eq!(consume_digits_itc(b!("__.45"), 10, b'_'), (b!("__"), b!(".45"))); assert_eq!(consume_digits_itc(b!("4_5"), 10, b'_'), (b!("4_5"), b!(""))); assert_eq!(consume_digits_itc(b!("4__5"), 10, b'_'), (b!("4__5"), b!(""))); assert_eq!(consume_digits_itc(b!("4_"), 10, b'_'), (b!("4_"), b!(""))); assert_eq!(consume_digits_itc(b!("4__"), 10, b'_'), (b!("4__"), b!(""))); assert_eq!(consume_digits_itc(b!("4_."), 10, b'_'), (b!("4_"), b!("."))); assert_eq!(consume_digits_itc(b!("4__."), 10, b'_'), (b!("4__"), b!("."))); assert_eq!(consume_digits_itc(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5"))); assert_eq!(consume_digits_itc(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5"))); assert_eq!(consume_digits_itc(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5"))); assert_eq!(consume_digits_itc(b!("__.45__5"), 10, b'_'), (b!("__"), b!(".45__5"))); assert_eq!(consume_digits_itc(b!("4_5_"), 10, b'_'), (b!("4_5_"), b!(""))); assert_eq!(consume_digits_itc(b!("4__5__"), 10, b'_'), (b!("4__5__"), b!(""))); assert_eq!(consume_digits_itc(b!("4_5_.5"), 10, b'_'), (b!("4_5_"), b!(".5"))); assert_eq!(consume_digits_itc(b!("4__5__.5"), 10, b'_'), (b!("4__5__"), b!(".5"))); assert_eq!(consume_digits_itc(b!("_45_"), 10, b'_'), (b!(""), b!("_45_"))); assert_eq!(consume_digits_itc(b!("__45__"), 10, b'_'), (b!(""), b!("__45__"))); assert_eq!(consume_digits_itc(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56"))); assert_eq!(consume_digits_itc(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56"))); assert_eq!(consume_digits_itc(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_"))); assert_eq!(consume_digits_itc(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__"))); assert_eq!(consume_digits_itc(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56"))); assert_eq!(consume_digits_itc(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56"))); } #[cfg(feature = "format")] #[test] fn consume_digits_lt_test() { assert_eq!(consume_digits_lt(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_lt(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_lt(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_lt(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_lt(b!("_45"), 10, b'_'), (b!("_45"), b!(""))); assert_eq!(consume_digits_lt(b!("__45"), 10, b'_'), (b!(""), b!("__45"))); assert_eq!(consume_digits_lt(b!("_.45"), 10, b'_'), (b!("_"), b!(".45"))); assert_eq!(consume_digits_lt(b!("__.45"), 10, b'_'), (b!(""), b!("__.45"))); assert_eq!(consume_digits_lt(b!("4_5"), 10, b'_'), (b!("4"), b!("_5"))); assert_eq!(consume_digits_lt(b!("4__5"), 10, b'_'), (b!("4"), b!("__5"))); assert_eq!(consume_digits_lt(b!("4_"), 10, b'_'), (b!("4_"), b!(""))); assert_eq!(consume_digits_lt(b!("4__"), 10, b'_'), (b!("4"), b!("__"))); assert_eq!(consume_digits_lt(b!("4_."), 10, b'_'), (b!("4_"), b!("."))); assert_eq!(consume_digits_lt(b!("4__."), 10, b'_'), (b!("4"), b!("__."))); assert_eq!(consume_digits_lt(b!("_45_5"), 10, b'_'), (b!("_45"), b!("_5"))); assert_eq!(consume_digits_lt(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5"))); assert_eq!(consume_digits_lt(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5"))); assert_eq!(consume_digits_lt(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5"))); assert_eq!(consume_digits_lt(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_"))); assert_eq!(consume_digits_lt(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__"))); assert_eq!(consume_digits_lt(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5"))); assert_eq!(consume_digits_lt(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5"))); assert_eq!(consume_digits_lt(b!("_45_"), 10, b'_'), (b!("_45_"), b!(""))); assert_eq!(consume_digits_lt(b!("__45__"), 10, b'_'), (b!(""), b!("__45__"))); assert_eq!(consume_digits_lt(b!("_45_.56"), 10, b'_'), (b!("_45_"), b!(".56"))); assert_eq!(consume_digits_lt(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56"))); assert_eq!(consume_digits_lt(b!("_4_5_"), 10, b'_'), (b!("_4"), b!("_5_"))); assert_eq!(consume_digits_lt(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__"))); assert_eq!(consume_digits_lt(b!("_4_5_.56"), 10, b'_'), (b!("_4"), b!("_5_.56"))); assert_eq!(consume_digits_lt(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56"))); assert_eq!(consume_digits_ltc(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_ltc(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_ltc(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_ltc(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_ltc(b!("_45"), 10, b'_'), (b!("_45"), b!(""))); assert_eq!(consume_digits_ltc(b!("__45"), 10, b'_'), (b!("__45"), b!(""))); assert_eq!(consume_digits_ltc(b!("_.45"), 10, b'_'), (b!("_"), b!(".45"))); assert_eq!(consume_digits_ltc(b!("__.45"), 10, b'_'), (b!("__"), b!(".45"))); assert_eq!(consume_digits_ltc(b!("4_5"), 10, b'_'), (b!("4"), b!("_5"))); assert_eq!(consume_digits_ltc(b!("4__5"), 10, b'_'), (b!("4"), b!("__5"))); assert_eq!(consume_digits_ltc(b!("4_"), 10, b'_'), (b!("4_"), b!(""))); assert_eq!(consume_digits_ltc(b!("4__"), 10, b'_'), (b!("4__"), b!(""))); assert_eq!(consume_digits_ltc(b!("4_."), 10, b'_'), (b!("4_"), b!("."))); assert_eq!(consume_digits_ltc(b!("4__."), 10, b'_'), (b!("4__"), b!("."))); assert_eq!(consume_digits_ltc(b!("_45_5"), 10, b'_'), (b!("_45"), b!("_5"))); assert_eq!(consume_digits_ltc(b!("__45__5"), 10, b'_'), (b!("__45"), b!("__5"))); assert_eq!(consume_digits_ltc(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5"))); assert_eq!(consume_digits_ltc(b!("__.45__5"), 10, b'_'), (b!("__"), b!(".45__5"))); assert_eq!(consume_digits_ltc(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_"))); assert_eq!(consume_digits_ltc(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__"))); assert_eq!(consume_digits_ltc(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5"))); assert_eq!(consume_digits_ltc(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5"))); assert_eq!(consume_digits_ltc(b!("_45_"), 10, b'_'), (b!("_45_"), b!(""))); assert_eq!(consume_digits_ltc(b!("__45__"), 10, b'_'), (b!("__45__"), b!(""))); assert_eq!(consume_digits_ltc(b!("_45_.56"), 10, b'_'), (b!("_45_"), b!(".56"))); assert_eq!(consume_digits_ltc(b!("__45__.56"), 10, b'_'), (b!("__45__"), b!(".56"))); assert_eq!(consume_digits_ltc(b!("_4_5_"), 10, b'_'), (b!("_4"), b!("_5_"))); assert_eq!(consume_digits_ltc(b!("__4__5__"), 10, b'_'), (b!("__4"), b!("__5__"))); assert_eq!(consume_digits_ltc(b!("_4_5_.56"), 10, b'_'), (b!("_4"), b!("_5_.56"))); assert_eq!(consume_digits_ltc(b!("__4__5__.56"), 10, b'_'), (b!("__4"), b!("__5__.56"))); } #[cfg(feature = "format")] #[test] fn consume_digits_ilt_test() { assert_eq!(consume_digits_ilt(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_ilt(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_ilt(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_ilt(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_ilt(b!("_45"), 10, b'_'), (b!("_45"), b!(""))); assert_eq!(consume_digits_ilt(b!("__45"), 10, b'_'), (b!(""), b!("__45"))); assert_eq!(consume_digits_ilt(b!("4_5"), 10, b'_'), (b!("4_5"), b!(""))); assert_eq!(consume_digits_ilt(b!("4__5"), 10, b'_'), (b!("4"), b!("__5"))); assert_eq!(consume_digits_ilt(b!("_.45"), 10, b'_'), (b!("_"), b!(".45"))); assert_eq!(consume_digits_ilt(b!("__.45"), 10, b'_'), (b!(""), b!("__.45"))); assert_eq!(consume_digits_ilt(b!("4_"), 10, b'_'), (b!("4_"), b!(""))); assert_eq!(consume_digits_ilt(b!("4__"), 10, b'_'), (b!("4"), b!("__"))); assert_eq!(consume_digits_ilt(b!("4_."), 10, b'_'), (b!("4_"), b!("."))); assert_eq!(consume_digits_ilt(b!("4__."), 10, b'_'), (b!("4"), b!("__."))); assert_eq!(consume_digits_ilt(b!("_45_5"), 10, b'_'), (b!("_45_5"), b!(""))); assert_eq!(consume_digits_ilt(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5"))); assert_eq!(consume_digits_ilt(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5"))); assert_eq!(consume_digits_ilt(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5"))); assert_eq!(consume_digits_ilt(b!("4_5_"), 10, b'_'), (b!("4_5_"), b!(""))); assert_eq!(consume_digits_ilt(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__"))); assert_eq!(consume_digits_ilt(b!("4_5_.5"), 10, b'_'), (b!("4_5_"), b!(".5"))); assert_eq!(consume_digits_ilt(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5"))); assert_eq!(consume_digits_ilt(b!("_45_"), 10, b'_'), (b!("_45_"), b!(""))); assert_eq!(consume_digits_ilt(b!("__45__"), 10, b'_'), (b!(""), b!("__45__"))); assert_eq!(consume_digits_ilt(b!("_45_.56"), 10, b'_'), (b!("_45_"), b!(".56"))); assert_eq!(consume_digits_ilt(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56"))); assert_eq!(consume_digits_ilt(b!("_4_5_"), 10, b'_'), (b!("_4_5_"), b!(""))); assert_eq!(consume_digits_ilt(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__"))); assert_eq!(consume_digits_ilt(b!("_4_5_.56"), 10, b'_'), (b!("_4_5_"), b!(".56"))); assert_eq!(consume_digits_ilt(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56"))); assert_eq!(consume_digits_iltc(b!("123.45"), 10, b'_'), (b!("123"), b!(".45"))); assert_eq!(consume_digits_iltc(b!("1e45"), 10, b'_'), (b!("1"), b!("e45"))); assert_eq!(consume_digits_iltc(b!("1e"), 10, b'_'), (b!("1"), b!("e"))); assert_eq!(consume_digits_iltc(b!("1"), 10, b'_'), (b!("1"), b!(""))); assert_eq!(consume_digits_iltc(b!("_45"), 10, b'_'), (b!("_45"), b!(""))); assert_eq!(consume_digits_iltc(b!("__45"), 10, b'_'), (b!("__45"), b!(""))); assert_eq!(consume_digits_iltc(b!("_.45"), 10, b'_'), (b!("_"), b!(".45"))); assert_eq!(consume_digits_iltc(b!("__.45"), 10, b'_'), (b!("__"), b!(".45"))); assert_eq!(consume_digits_iltc(b!("4_5"), 10, b'_'), (b!("4_5"), b!(""))); assert_eq!(consume_digits_iltc(b!("4__5"), 10, b'_'), (b!("4__5"), b!(""))); assert_eq!(consume_digits_iltc(b!("4_"), 10, b'_'), (b!("4_"), b!(""))); assert_eq!(consume_digits_iltc(b!("4__"), 10, b'_'), (b!("4__"), b!(""))); assert_eq!(consume_digits_iltc(b!("4_."), 10, b'_'), (b!("4_"), b!("."))); assert_eq!(consume_digits_iltc(b!("4__."), 10, b'_'), (b!("4__"), b!("."))); assert_eq!(consume_digits_iltc(b!("_45_5"), 10, b'_'), (b!("_45_5"), b!(""))); assert_eq!(consume_digits_iltc(b!("__45__5"), 10, b'_'), (b!("__45__5"), b!(""))); assert_eq!(consume_digits_iltc(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5"))); assert_eq!(consume_digits_iltc(b!("__.45__5"), 10, b'_'), (b!("__"), b!(".45__5"))); assert_eq!(consume_digits_iltc(b!("4_5_"), 10, b'_'), (b!("4_5_"), b!(""))); assert_eq!(consume_digits_iltc(b!("4__5__"), 10, b'_'), (b!("4__5__"), b!(""))); assert_eq!(consume_digits_iltc(b!("4_5_.5"), 10, b'_'), (b!("4_5_"), b!(".5"))); assert_eq!(consume_digits_iltc(b!("4__5__.5"), 10, b'_'), (b!("4__5__"), b!(".5"))); assert_eq!(consume_digits_iltc(b!("_45_"), 10, b'_'), (b!("_45_"), b!(""))); assert_eq!(consume_digits_iltc(b!("__45__"), 10, b'_'), (b!("__45__"), b!(""))); assert_eq!(consume_digits_iltc(b!("_45_.56"), 10, b'_'), (b!("_45_"), b!(".56"))); assert_eq!(consume_digits_iltc(b!("__45__.56"), 10, b'_'), (b!("__45__"), b!(".56"))); assert_eq!(consume_digits_iltc(b!("_4_5_"), 10, b'_'), (b!("_4_5_"), b!(""))); assert_eq!(consume_digits_iltc(b!("__4__5__"), 10, b'_'), (b!("__4__5__"), b!(""))); assert_eq!(consume_digits_iltc(b!("_4_5_.56"), 10, b'_'), (b!("_4_5_"), b!(".56"))); assert_eq!(consume_digits_iltc(b!("__4__5__.56"), 10, b'_'), (b!("__4__5__"), b!(".56"))); } } lexical-core-0.7.6/src/util/div128.rs000075500000000000000000000147350000000000000153260ustar 00000000000000//! Optimized division algorithms for u128. //! //! The code in this module is derived off of `dtolnay/itoa` //! and Rust's compiler-builtins crate. This copies a specific //! path of LLVM's `__udivmodti4` intrinsic, which does division/ //! modulus for u128 in a single step. Rust implements both division //! and modulus in terms of this intrinsic, but calls the intrinsic //! twice for subsequent division and modulus operations on the same //! dividend/divisor, leading to significant performance overhead. //! //! This module calculates the optimal divisors for each radix, //! and exports a general-purpose division algorithm for u128 where //! the divisor can fit in a u64. //! //! This implementation is derived from dtolnay/itoa, which can be found here: //! https://github.com/dtolnay/itoa/blob/master/src/udiv128.rs //! //! This implementation is also derived from Rust's compiler-builtins crate, //! which can be found here: //! https://github.com/rust-lang-nursery/compiler-builtins/blob/master/src/int/udiv.rs //! //! Licensing for this module may be under the MIT or Illinois license //! (a BSD-like license), and may be found here: //! https://github.com/rust-lang-nursery/compiler-builtins/blob/master/LICENSE.TXT // Get the divisor for optimized 128-bit division. // Returns the divisor, the number of digits processed, and the // number of leading zeros in the divisor. // // These values were calculated using the following script: // // ```text // import math // // u64_max = 2**64 - 1 // u128_max = 2**128-1 // // def is_valid(x): // return ( // x <= u64_max // and (u128_max / (x**2)) < x // ) // // def find_pow(radix): // start_pow = int(math.floor(math.log(u64_max, radix))) - 1 // while is_valid(radix**start_pow): // start_pow += 1 // return start_pow - 1 // // for radix in range(2, 37): // power = find_pow(radix) // print(radix, radix**power, power) // ``` #[cfg(feature = "radix")] #[inline] pub(crate) fn u128_divisor(radix: u32) -> (u64, usize, u32) { match radix { 2 => (9223372036854775808, 63, 0), // 2^63 3 => (12157665459056928801, 40, 0), // 3^40 4 => (4611686018427387904, 31, 1), // 4^31 5 => (7450580596923828125, 27, 1), // 5^27 6 => (4738381338321616896, 24, 1), // 6^24 7 => (3909821048582988049, 22, 2), // 7^22 8 => (9223372036854775808, 21, 0), // 8^21 9 => (12157665459056928801, 20, 0), // 9^20 10 => (10000000000000000000, 19, 0), // 10^19 11 => (5559917313492231481, 18, 1), // 11^18 12 => (2218611106740436992, 17, 3), // 12^17 13 => (8650415919381337933, 17, 1), // 13^17 14 => (2177953337809371136, 16, 3), // 14^16 15 => (6568408355712890625, 16, 1), // 15^16 16 => (1152921504606846976, 15, 3), // 16^15 17 => (2862423051509815793, 15, 2), // 17^15 18 => (6746640616477458432, 15, 1), // 18^15 19 => (15181127029874798299, 15, 0), // 19^15 20 => (1638400000000000000, 14, 3), // 20^14 21 => (3243919932521508681, 14, 2), // 21^14 22 => (6221821273427820544, 14, 1), // 22^14 23 => (11592836324538749809, 14, 0), // 23^14 24 => (876488338465357824, 13, 4), // 24^13 25 => (1490116119384765625, 13, 3), // 25^13 26 => (2481152873203736576, 13, 2), // 26^13 27 => (4052555153018976267, 13, 2), // 27^13 28 => (6502111422497947648, 13, 1), // 28^13 29 => (10260628712958602189, 13, 0), // 29^13 30 => (15943230000000000000, 13, 0), // 30^13 31 => (787662783788549761, 12, 4), // 31^12 32 => (1152921504606846976, 12, 3), // 32^12 33 => (1667889514952984961, 12, 3), // 33^12 34 => (2386420683693101056, 12, 2), // 34^12 35 => (3379220508056640625, 12, 2), // 35^12 36 => (4738381338321616896, 12, 1), // 36^12 _ => unreachable!(), } } // Get the divisor for optimized 128-bit division. // Returns the divisor, the number of digits processed, and the // number of leading zeros in the divisor. #[cfg(not(feature = "radix"))] #[inline] #[allow(dead_code)] pub(crate) fn u128_divisor(_: u32) -> (u64, usize, u32) { (10000000000000000000, 19, 0) // 10^19 } // Optimized division/remainder algorithm for u128. // This is because the codegen for u128 divrem is very inefficient in Rust, // calling both `__udivmodti4` twice internally, rather than a single time. #[inline] pub(crate) fn u128_divrem(n: u128, d: u64, d_cltz: u32) -> (u128, u64) { // Ensure we have the correct number of leading zeros passed. debug_assert_eq!(d_cltz, d.leading_zeros()); // Optimize if we can divide using u64 first. let high = (n >> 64) as u64; if high == 0 { let low = n as u64; return ((low / d) as u128, low % d); } // sr = 1 + u64::BITS + d.leading_zeros() - high.leading_zeros(); let sr = 65 + d_cltz - high.leading_zeros(); // 1 <= sr <= u64::BITS - 1 let mut q: u128 = n << (128 - sr); let mut r: u128 = n >> sr; let mut carry: u64 = 0; // Don't use a range because they may generate references to memcpy in unoptimized code // Loop invariants: r < d; carry is 0 or 1 let mut i = 0; while i < sr { i += 1; // r:q = ((r:q) << 1) | carry r = (r << 1) | (q >> 127); q = (q << 1) | carry as u128; // carry = 0 // if r >= d { // r -= d; // carry = 1; // } let s = (d as u128).wrapping_sub(r).wrapping_sub(1) as i128 >> 127; carry = (s & 1) as u64; r -= (d as u128) & s as u128; } ((q << 1) | carry as u128, r as u64) } // Divide by 1e19 for base10 algorithms. #[cfg(feature = "table")] pub(crate) fn u128_divrem_1e19(n: u128) -> (u128, u64) { u128_divrem(n, 10000000000000000000, 0) } // TESTS // ----- #[cfg(test)] mod tests { use super::*; #[cfg(all(feature = "std", feature = "property_tests"))] use proptest::{proptest, prop_assert_eq, prop_assert}; #[cfg(all(feature = "std", feature = "property_tests"))] proptest! { #[test] fn u128_divrem_proptest(i in u128::min_value()..u128::max_value()) { let (d, _, d_cltz) = u128_divisor(10); let expected = (i / d as u128, (i % d as u128) as u64); let actual = u128_divrem(i, d, d_cltz); prop_assert_eq!(actual, expected); } } } lexical-core-0.7.6/src/util/error.rs000075500000000000000000000062510000000000000154340ustar 00000000000000//! C-compatible error type. use crate::lib::fmt::{self, Display, Formatter}; #[cfg(feature = "std")] use std::error::Error as StdError; /// Error code, indicating failure type. /// /// Error messages are designating by an error code of less than 0. /// This is to be compatible with C conventions. This enumeration is /// FFI-compatible for interfacing with C code. /// /// # FFI /// /// For interfacing with FFI-code, this may be approximated by: /// ```text /// const int32_t OVERFLOW = -1; /// const int32_t UNDERFLOW = -2; /// const int32_t INVALID_DIGIT = -3; /// const int32_t EMPTY = -4; /// const int32_t EMPTY_FRACTION = -5; /// const int32_t EMPTY_EXPONENT = -6; /// ``` /// /// # Safety /// /// Assigning any value outside the range `[-6, -1]` to value of type /// ErrorCode may invoke undefined-behavior. #[repr(i32)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub enum ErrorCode { /// Integral overflow occurred during numeric parsing. /// /// Numeric overflow takes precedence over the presence of an invalid /// digit. Overflow = -1, /// Integral underflow occurred during numeric parsing. /// /// Numeric overflow takes precedence over the presence of an invalid /// digit. Underflow = -2, /// Invalid digit found before string termination. InvalidDigit = -3, /// Empty byte array found. Empty = -4, /// Empty mantissa found. EmptyMantissa = -5, /// Empty exponent found. EmptyExponent = -6, /// Empty integer found. EmptyInteger = -7, /// Empty fraction found. EmptyFraction = -8, /// Invalid positive mantissa sign was found. InvalidPositiveMantissaSign = -9, /// Mantissa sign was required, but not found. MissingMantissaSign = -10, /// Exponent was present but not allowed. InvalidExponent = -11, /// Invalid positive exponent sign was found. InvalidPositiveExponentSign = -12, /// Exponent sign was required, but not found. MissingExponentSign = -13, /// Exponent was present without fraction component. ExponentWithoutFraction = -14, /// Integer had invalid leading zeros. InvalidLeadingZeros = -15, // We may add additional variants later, so ensure that client matching // does not depend on exhaustive matching. #[doc(hidden)] __Nonexhaustive = -200, } /// Error type for lexical parsing. /// /// This error is FFI-compatible for interfacing with C code. #[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub struct Error { /// Error code designating the type of error occurred. pub code: ErrorCode, /// Optional position within the buffer for the error. pub index: usize, } impl From for Error { #[inline] fn from(code: ErrorCode) -> Self { Error { code: code, index: 0 } } } impl From<(ErrorCode, usize)> for Error { #[inline] fn from(error: (ErrorCode, usize)) -> Self { Error { code: error.0, index: error.1 } } } impl Display for Error { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "lexical error: {:?} at index {}.", self.code, self.index) } } #[cfg(feature = "std")] impl StdError for Error {} lexical-core-0.7.6/src/util/format/feature_format.rs000075500000000000000000002440230000000000000205770ustar 00000000000000#![cfg(feature = "format")] use super::super::config; use bitflags::bitflags; use static_assertions::const_assert; // HELPERS // Determine if character is valid ASCII. #[inline] fn is_ascii(ch: u8) -> bool { ch.is_ascii() } /// Determine if the digit separator is valid. #[inline] #[cfg(not(feature = "radix"))] fn is_valid_separator(ch: u8) -> bool { match ch { b'0' ..= b'9' => false, b'+' | b'.' | b'-' => false, _ => ( is_ascii(ch) && ch != config::get_exponent_default_char() ) } } /// Determine if the digit separator is valid. #[inline] #[cfg(feature = "radix")] fn is_valid_separator(ch: u8) -> bool { match ch { b'A' ..= b'Z' => false, b'a' ..= b'z' => false, b'0' ..= b'9' => false, b'+' | b'.' | b'-' => false, _ => ( is_ascii(ch) && ch != config::get_exponent_default_char() && ch != config::get_exponent_backup_char() ) } } /// Convert digit separator to flags. #[inline] const fn digit_separator_to_flags(ch: u8) -> u64 { (ch as u64) << 56 } /// Extract digit separator from flags. #[inline] const fn digit_separator_from_flags(flag: u64) -> u8 { (flag >> 56) as u8 } // BITFLAGS bitflags! { /// Bitflags for a serialized number format. /// /// This is used to derive the high-level bitflags.The default /// representation has no digit separators, no required integer or /// fraction digits, required exponent digits, and no digit separators. /// /// Bit Flags Layout /// ---------------- /// /// The bitflags has the lower bits designated for flags that modify /// the parsing behavior of lexical, and the upper 8 bits set for the /// digit separator, allowing any valid ASCII character as a /// separator. The first 32-bits are reserved for non-digit separator /// flags, bits 32-55 are reserved for digit separator flags, and /// the last 8 bits for the digit separator. // /// ```text /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 /// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ /// |I/R|F/R|E/R|+/M|R/M|e/e|+/E|R/E|e/F|S/S|S/C| RESERVED | /// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ /// /// 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 /// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ /// | RESERVED | /// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ /// /// 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 /// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ /// |I/I|F/I|E/I|I/L|F/L|E/L|I/T|F/T|E/T|I/C|F/C|E/C|S/D| RESERVED | /// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ /// /// 48 49 50 51 52 53 54 55 56 57 58 59 60 62 62 63 /// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ /// | RESERVED | Digit Separator | /// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ /// /// Where: /// I/R = Required integer digits. /// F/R = Required fraction digits. /// E/R = Required exponent digits. /// +/M = No mantissa positive sign. /// R/M = Required positive sign. /// e/e = No exponent notation. /// +/E = No exponent positive sign. /// R/E = Required exponent sign. /// e/F = No exponent without fraction. /// S/S = No special (non-finite) values. /// S/C = Case-sensitive special (non-finite) values. /// I/I = Integer internal digit separator. /// F/I = Fraction internal digit separator. /// E/I = Exponent internal digit separator. /// I/L = Integer leading digit separator. /// F/L = Fraction leading digit separator. /// E/L = Exponent leading digit separator. /// I/T = Integer trailing digit separator. /// F/T = Fraction trailing digit separator. /// E/T = Exponent trailing digit separator. /// I/C = Integer consecutive digit separator. /// F/C = Fraction consecutive digit separator. /// E/C = Exponent consecutive digit separator. /// S/D = Special (non-finite) digit separator. /// ``` /// /// Note: /// ----- /// /// In order to limit the format specification and avoid parsing /// non-numerical data, all number formats require some significant /// digits. Examples of always invalid numbers include: /// - `` /// - `.` /// - `e` /// - `e7` /// /// Test Cases: /// ----------- /// /// The following test-cases are used to define whether a literal or /// a string float is valid in a given language, and these tests are /// used to denote features in pre-defined formats. Only a few /// of these flags may modify the parsing behavior of integers. /// Integer parsing is assumed to be derived from float parsing, /// so if consecutive digit separators are valid in the integer /// component of a float, they are also valid in an integer. /// /// ```text /// 0: '.3' // Non-required integer. /// 1: '3.' // Non-required fraction. /// 2: '3e' // Non-required exponent. /// 3. '+3.0' // Mantissa positive sign. /// 4: '3.0e7' // Exponent notation. /// 5: '3.0e+7' // Exponent positive sign. /// 6. '3e7' // Exponent notation without fraction. /// 7: 'NaN' // Special (non-finite) values. /// 8: 'NAN' // Case-sensitive special (non-finite) values. /// 9: '3_4.01' // Integer internal digit separator. /// A: '3.0_1' // Fraction internal digit separator. /// B: '3.0e7_1' // Exponent internal digit separator. /// C: '_3.01' // Integer leading digit separator. /// D: '3._01' // Fraction leading digit separator. /// E: '3.0e_71' // Exponent leading digit separator. /// F: '3_.01' // Integer trailing digit separator. /// G: '3.01_' // Fraction trailing digit separator. /// H: '3.0e71_' // Exponent trailing digit separator. /// I: '3__4.01' // Integer consecutive digit separator. /// J: '3.0__1' // Fraction consecutive digit separator. /// K: '3.0e7__1' // Exponent consecutive digit separator. /// L: 'In_f' // Special (non-finite) digit separator. /// M: '010' // No integer leading zeros. /// N: '010.0' // No float leading zeros. /// ``` /// /// Currently Supported Programming and Data Languages: /// --------------------------------------------------- /// /// 1. Rust /// 2. Python /// 3. C++ (98, 03, 11, 14, 17) /// 4. C (89, 90, 99, 11, 18) /// 5. Ruby /// 6. Swift /// 7. Go /// 8. Haskell /// 9. Javascript /// 10. Perl /// 11. PHP /// 12. Java /// 13. R /// 14. Kotlin /// 15. Julia /// 16. C# (ISO-1, ISO-2, 3, 4, 5, 6, 7) /// 17. Kawa /// 18. Gambit-C /// 19. Guile /// 20. Clojure /// 21. Erlang /// 22. Elm /// 23. Scala /// 24. Elixir /// 25. FORTRAN /// 26. D /// 27. Coffeescript /// 28. Cobol /// 29. F# /// 30. Visual Basic /// 31. OCaml /// 32. Objective-C /// 33. ReasonML /// 34. Octave /// 35. Matlab /// 36. Zig /// 37. SageMath /// 38. JSON /// 39. TOML /// 40. XML /// 41. SQLite /// 42. PostgreSQL /// 43. MySQL /// 44. MongoDB #[derive(Default)] pub struct NumberFormat: u64 { // MASKS & FLAGS /// Mask to extract the flag bits. #[doc(hidden)] const FLAG_MASK = ( Self::REQUIRED_DIGITS.bits | Self::NO_POSITIVE_MANTISSA_SIGN.bits | Self::REQUIRED_MANTISSA_SIGN.bits | Self::NO_EXPONENT_NOTATION.bits | Self::NO_POSITIVE_EXPONENT_SIGN.bits | Self::REQUIRED_EXPONENT_SIGN.bits | Self::NO_EXPONENT_WITHOUT_FRACTION.bits | Self::NO_SPECIAL.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::NO_INTEGER_LEADING_ZEROS.bits | Self::NO_FLOAT_LEADING_ZEROS.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits | Self::SPECIAL_DIGIT_SEPARATOR.bits ); /// Mask to extract the flag bits controlling interface parsing. /// /// This mask controls all the flags handled by the interface, /// omitting those that are handled prior. This limits the /// number of match paths required to determine the correct /// interface. const INTERFACE_FLAG_MASK = ( Self::REQUIRED_DIGITS.bits | Self::NO_EXPONENT_NOTATION.bits | Self::NO_POSITIVE_EXPONENT_SIGN.bits | Self::REQUIRED_EXPONENT_SIGN.bits | Self::NO_EXPONENT_WITHOUT_FRACTION.bits | Self::NO_FLOAT_LEADING_ZEROS.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); /// Mask to extract digit separator flags. #[doc(hidden)] const DIGIT_SEPARATOR_FLAG_MASK = ( Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits | Self::SPECIAL_DIGIT_SEPARATOR.bits ); /// Mask to extract integer digit separator flags. #[doc(hidden)] const INTEGER_DIGIT_SEPARATOR_FLAG_MASK = ( Self::INTEGER_INTERNAL_DIGIT_SEPARATOR.bits | Self::INTEGER_LEADING_DIGIT_SEPARATOR.bits | Self::INTEGER_TRAILING_DIGIT_SEPARATOR.bits | Self::INTEGER_CONSECUTIVE_DIGIT_SEPARATOR.bits ); /// Mask to extract fraction digit separator flags. #[doc(hidden)] const FRACTION_DIGIT_SEPARATOR_FLAG_MASK = ( Self::FRACTION_INTERNAL_DIGIT_SEPARATOR.bits | Self::FRACTION_LEADING_DIGIT_SEPARATOR.bits | Self::FRACTION_TRAILING_DIGIT_SEPARATOR.bits | Self::FRACTION_CONSECUTIVE_DIGIT_SEPARATOR.bits ); /// Mask to extract exponent digit separator flags. #[doc(hidden)] const EXPONENT_DIGIT_SEPARATOR_FLAG_MASK = ( Self::EXPONENT_INTERNAL_DIGIT_SEPARATOR.bits | Self::EXPONENT_LEADING_DIGIT_SEPARATOR.bits | Self::EXPONENT_TRAILING_DIGIT_SEPARATOR.bits | Self::EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR.bits ); /// Mask to extract exponent flags. #[doc(hidden)] const EXPONENT_FLAG_MASK = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_POSITIVE_EXPONENT_SIGN.bits | Self::REQUIRED_EXPONENT_SIGN.bits | Self::NO_EXPONENT_WITHOUT_FRACTION.bits | Self::EXPONENT_INTERNAL_DIGIT_SEPARATOR.bits | Self::EXPONENT_LEADING_DIGIT_SEPARATOR.bits | Self::EXPONENT_TRAILING_DIGIT_SEPARATOR.bits | Self::EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR.bits ); // NON-DIGIT SEPARATOR FLAGS & MASKS /// Digits are required before the decimal point. #[doc(hidden)] const REQUIRED_INTEGER_DIGITS = 0b0000000000000000000000000000000000000000000000000000000000000001; /// Digits are required after the decimal point. /// This check will only occur if the decimal point is present. #[doc(hidden)] const REQUIRED_FRACTION_DIGITS = 0b0000000000000000000000000000000000000000000000000000000000000010; /// Digits are required after the exponent character. /// This check will only occur if the exponent character is present. #[doc(hidden)] const REQUIRED_EXPONENT_DIGITS = 0b0000000000000000000000000000000000000000000000000000000000000100; /// Digits are required before or after the control characters. #[doc(hidden)] const REQUIRED_DIGITS = ( Self::REQUIRED_INTEGER_DIGITS.bits | Self::REQUIRED_FRACTION_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits ); /// Positive sign before the mantissa is not allowed. #[doc(hidden)] const NO_POSITIVE_MANTISSA_SIGN = 0b0000000000000000000000000000000000000000000000000000000000001000; /// Positive sign before the mantissa is required. #[doc(hidden)] const REQUIRED_MANTISSA_SIGN = 0b0000000000000000000000000000000000000000000000000000000000010000; /// Exponent notation is not allowed. #[doc(hidden)] const NO_EXPONENT_NOTATION = 0b0000000000000000000000000000000000000000000000000000000000100000; /// Positive sign before the exponent is not allowed. #[doc(hidden)] const NO_POSITIVE_EXPONENT_SIGN = 0b0000000000000000000000000000000000000000000000000000000001000000; /// Positive sign before the exponent is required. #[doc(hidden)] const REQUIRED_EXPONENT_SIGN = 0b0000000000000000000000000000000000000000000000000000000010000000; /// Exponent without a fraction component is not allowed. /// /// This only checks if a decimal point precedes the exponent character. /// To require fraction digits or exponent digits with this check, /// please use the appropriate flags. #[doc(hidden)] const NO_EXPONENT_WITHOUT_FRACTION = 0b0000000000000000000000000000000000000000000000000000000100000000; /// Special (non-finite) values are not allowed. #[doc(hidden)] const NO_SPECIAL = 0b0000000000000000000000000000000000000000000000000000001000000000; /// Special (non-finite) values are case-sensitive. #[doc(hidden)] const CASE_SENSITIVE_SPECIAL = 0b0000000000000000000000000000000000000000000000000000010000000000; /// Leading zeros before an integer value are not allowed. /// /// If the value is a literal, then this distinction applies /// when the value is treated like an integer literal, typically /// when there is no decimal point. If the value is parsed, /// then this distinction applies when the value as parsed /// as an integer. /// /// # Warning /// /// This also does not mean that the value parsed will be correct, /// for example, in languages like C, this will not auto- /// deduce that the radix is 8 with leading zeros, for an octal /// literal. #[doc(hidden)] const NO_INTEGER_LEADING_ZEROS = 0b0000000000000000000000000000000000000000000000000000100000000000; /// Leading zeros before a float value are not allowed. /// /// If the value is a literal, then this distinction applies /// when the value is treated like an integer float, typically /// when there is a decimal point. If the value is parsed, /// then this distinction applies when the value as parsed /// as a float. /// /// # Warning /// /// This also does not mean that the value parsed will be correct, /// for example, in languages like C, this will not auto- /// deduce that the radix is 8 with leading zeros, for an octal /// literal. #[doc(hidden)] const NO_FLOAT_LEADING_ZEROS = 0b0000000000000000000000000000000000000000000000000001000000000000; // DIGIT SEPARATOR FLAGS & MASKS /// Digit separators are allowed between integer digits. #[doc(hidden)] const INTEGER_INTERNAL_DIGIT_SEPARATOR = 0b0000000000000000000000000000000100000000000000000000000000000000; /// A digit separator is allowed before any integer digits. #[doc(hidden)] const INTEGER_LEADING_DIGIT_SEPARATOR = 0b0000000000000000000000000000001000000000000000000000000000000000; /// A digit separator is allowed after any integer digits. #[doc(hidden)] const INTEGER_TRAILING_DIGIT_SEPARATOR = 0b0000000000000000000000000000010000000000000000000000000000000000; /// Multiple consecutive integer digit separators are allowed. #[doc(hidden)] const INTEGER_CONSECUTIVE_DIGIT_SEPARATOR = 0b0000000000000000000000000000100000000000000000000000000000000000; /// Digit separators are allowed between fraction digits. #[doc(hidden)] const FRACTION_INTERNAL_DIGIT_SEPARATOR = 0b0000000000000000000000000001000000000000000000000000000000000000; /// A digit separator is allowed before any fraction digits. #[doc(hidden)] const FRACTION_LEADING_DIGIT_SEPARATOR = 0b0000000000000000000000000010000000000000000000000000000000000000; /// A digit separator is allowed after any fraction digits. #[doc(hidden)] const FRACTION_TRAILING_DIGIT_SEPARATOR = 0b0000000000000000000000000100000000000000000000000000000000000000; /// Multiple consecutive fraction digit separators are allowed. #[doc(hidden)] const FRACTION_CONSECUTIVE_DIGIT_SEPARATOR = 0b0000000000000000000000001000000000000000000000000000000000000000; /// Digit separators are allowed between exponent digits. #[doc(hidden)] const EXPONENT_INTERNAL_DIGIT_SEPARATOR = 0b0000000000000000000000010000000000000000000000000000000000000000; /// A digit separator is allowed before any exponent digits. #[doc(hidden)] const EXPONENT_LEADING_DIGIT_SEPARATOR = 0b0000000000000000000000100000000000000000000000000000000000000000; /// A digit separator is allowed after any exponent digits. #[doc(hidden)] const EXPONENT_TRAILING_DIGIT_SEPARATOR = 0b0000000000000000000001000000000000000000000000000000000000000000; /// Multiple consecutive exponent digit separators are allowed. #[doc(hidden)] const EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR = 0b0000000000000000000010000000000000000000000000000000000000000000; /// Digit separators are allowed between digits. #[doc(hidden)] const INTERNAL_DIGIT_SEPARATOR = ( Self::INTEGER_INTERNAL_DIGIT_SEPARATOR.bits | Self::FRACTION_INTERNAL_DIGIT_SEPARATOR.bits | Self::EXPONENT_INTERNAL_DIGIT_SEPARATOR.bits ); /// A digit separator is allowed before any digits. #[doc(hidden)] const LEADING_DIGIT_SEPARATOR = ( Self::INTEGER_LEADING_DIGIT_SEPARATOR.bits | Self::FRACTION_LEADING_DIGIT_SEPARATOR.bits | Self::EXPONENT_LEADING_DIGIT_SEPARATOR.bits ); /// A digit separator is allowed after any digits. #[doc(hidden)] const TRAILING_DIGIT_SEPARATOR = ( Self::INTEGER_TRAILING_DIGIT_SEPARATOR.bits | Self::FRACTION_TRAILING_DIGIT_SEPARATOR.bits | Self::EXPONENT_TRAILING_DIGIT_SEPARATOR.bits ); /// Multiple consecutive digit separators are allowed. #[doc(hidden)] const CONSECUTIVE_DIGIT_SEPARATOR = ( Self::INTEGER_CONSECUTIVE_DIGIT_SEPARATOR.bits | Self::FRACTION_CONSECUTIVE_DIGIT_SEPARATOR.bits | Self::EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR.bits ); /// Any digit separators are allowed in special (non-finite) values. #[doc(hidden)] const SPECIAL_DIGIT_SEPARATOR = 0b0000000000000000000100000000000000000000000000000000000000000000; // PRE-DEFINED // // Sample Format Shorthand: // ------------------------ // // The format shorthand lists the test cases, and if applicable, // the digit separator character. For example, the shorthand // `[134-_]` specifies it passes tests 1, 3, and 4, and uses // `'_'` as a digit-separator character. Meanwhile, `[0]` means it // passes test 0, and has no digit separator. // RUST LITERAL [4569ABFGHIJKMN-_] /// Float format for a Rust literal floating-point number. const RUST_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_DIGITS.bits | Self::NO_POSITIVE_MANTISSA_SIGN.bits | Self::NO_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // RUST STRING [0134567MN] /// Float format to parse a Rust float from string. const RUST_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; // RUST STRING STRICT [01345678MN] /// `RUST_STRING`, but enforces strict equality for special values. const RUST_STRING_STRICT = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); /// Float format for a Python literal floating-point number. const PYTHON_LITERAL = Self::PYTHON3_LITERAL.bits; /// Float format to parse a Python float from string. const PYTHON_STRING = Self::PYTHON3_STRING.bits; // PYTHON3 LITERAL [013456N] /// Float format for a Python3 literal floating-point number. const PYTHON3_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits | Self::NO_INTEGER_LEADING_ZEROS.bits ); // PYTHON3 STRING [0134567MN] /// Float format to parse a Python3 float from string. const PYTHON3_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; // PYTHON2 LITERAL [013456MN] /// Float format for a Python2 literal floating-point number. const PYTHON2_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // PYTHON2 STRING [0134567MN] /// Float format to parse a Python2 float from string. const PYTHON2_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; /// Float format for a C++ literal floating-point number. const CXX_LITERAL = Self::CXX17_LITERAL.bits; /// Float format to parse a C++ float from string. const CXX_STRING = Self::CXX17_STRING.bits; // C++17 LITERAL [01345689ABMN-'] /// Float format for a C++17 literal floating-point number. const CXX17_LITERAL = ( digit_separator_to_flags(b'\'') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits ); // C++17 STRING [013456MN] const CXX17_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; // C++14 LITERAL [01345689ABMN-'] /// Float format for a C++14 literal floating-point number. const CXX14_LITERAL = ( digit_separator_to_flags(b'\'') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits ); // C++14 STRING [013456MN] /// Float format to parse a C++14 float from string. const CXX14_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; // C++11 LITERAL [0134568MN] /// Float format for a C++11 literal floating-point number. const CXX11_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // C++11 STRING [013456MN] /// Float format to parse a C++11 float from string. const CXX11_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; // C++03 LITERAL [0134567MN] /// Float format for a C++03 literal floating-point number. const CXX03_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // C++03 STRING [013456MN] /// Float format to parse a C++03 float from string. const CXX03_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; // C++98 LITERAL [0134567MN] /// Float format for a C++98 literal floating-point number. const CXX98_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // C++98 STRING [013456MN] /// Float format to parse a C++98 float from string. const CXX98_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; /// Float format for a C literal floating-point number. const C_LITERAL = Self::C18_LITERAL.bits; /// Float format to parse a C float from string. const C_STRING = Self::C18_STRING.bits; // C18 LITERAL [0134568MN] /// Float format for a C18 literal floating-point number. const C18_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // C18 STRING [013456MN] /// Float format to parse a C18 float from string. const C18_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; // C11 LITERAL [0134568MN] /// Float format for a C11 literal floating-point number. const C11_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // C11 STRING [013456MN] /// Float format to parse a C11 float from string. const C11_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; // C99 LITERAL [0134568MN] /// Float format for a C99 literal floating-point number. const C99_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // C99 STRING [013456MN] /// Float format to parse a C99 float from string. const C99_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; // C90 LITERAL [0134567MN] /// Float format for a C90 literal floating-point number. const C90_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // C90 STRING [013456MN] /// Float format to parse a C90 float from string. const C90_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; // C89 LITERAL [0134567MN] /// Float format for a C89 literal floating-point number. const C89_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // C89 STRING [013456MN] /// Float format to parse a C89 float from string. const C89_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; // RUBY LITERAL [345689AM-_] /// Float format for a Ruby literal floating-point number. const RUBY_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_DIGITS.bits | Self::NO_SPECIAL.bits | Self::NO_FLOAT_LEADING_ZEROS.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits ); // RUBY STRING [01234569ABMN-_] /// Float format to parse a Ruby float from string. // Note: Amazingly, Ruby 1.8+ do not allow parsing special values. const RUBY_STRING = ( digit_separator_to_flags(b'_') | Self::NO_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits ); // SWIFT LITERAL [34569ABFGHIJKMN-_] /// Float format for a Swift literal floating-point number. const SWIFT_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_DIGITS.bits | Self::NO_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // SWIFT STRING [13456MN] /// Float format to parse a Swift float from string. const SWIFT_STRING = Self::REQUIRED_FRACTION_DIGITS.bits; // GO LITERAL [0134567MN] /// Float format for a Golang literal floating-point number. const GO_LITERAL = ( Self::REQUIRED_FRACTION_DIGITS.bits | Self::NO_SPECIAL.bits ); // GO STRING [013456MN] /// Float format to parse a Golang float from string. const GO_STRING = Self::REQUIRED_FRACTION_DIGITS.bits; // HASKELL LITERAL [456MN] /// Float format for a Haskell literal floating-point number. const HASKELL_LITERAL = ( Self::REQUIRED_DIGITS.bits | Self::NO_POSITIVE_MANTISSA_SIGN.bits | Self::NO_SPECIAL.bits ); // HASKELL STRING [45678MN] /// Float format to parse a Haskell float from string. const HASKELL_STRING = ( Self::REQUIRED_DIGITS.bits | Self::NO_POSITIVE_MANTISSA_SIGN.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // JAVASCRIPT LITERAL [01345678M] /// Float format for a Javascript literal floating-point number. const JAVASCRIPT_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::NO_FLOAT_LEADING_ZEROS.bits ); // JAVASCRIPT STRING [012345678MN] /// Float format to parse a Javascript float from string. const JAVASCRIPT_STRING = Self::CASE_SENSITIVE_SPECIAL.bits; // PERL LITERAL [0134569ABDEFGHIJKMN-_] /// Float format for a Perl literal floating-point number. const PERL_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::FRACTION_LEADING_DIGIT_SEPARATOR.bits | Self::EXPONENT_LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // PERL STRING [01234567MN] /// Float format to parse a Perl float from string. const PERL_STRING = 0; // PHP LITERAL [01345678MN] /// Float format for a PHP literal floating-point number. const PHP_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // PHP STRING [0123456MN] /// Float format to parse a PHP float from string. const PHP_STRING = Self::NO_SPECIAL.bits; // JAVA LITERAL [0134569ABIJKMN-_] /// Float format for a Java literal floating-point number. const JAVA_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // JAVA STRING [01345678MN] /// Float format to parse a Java float from string. const JAVA_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // R LITERAL [01345678MN] /// Float format for a R literal floating-point number. const R_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // R STRING [01234567MN] /// Float format to parse a R float from string. const R_STRING = 0; // KOTLIN LITERAL [0134569ABIJKN-_] /// Float format for a Kotlin literal floating-point number. const KOTLIN_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits | Self::NO_INTEGER_LEADING_ZEROS.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // KOTLIN STRING [0134568MN] /// Float format to parse a Kotlin float from string. const KOTLIN_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // JULIA LITERAL [01345689AMN-_] /// Float format for a Julia literal floating-point number. const JULIA_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::INTEGER_INTERNAL_DIGIT_SEPARATOR.bits | Self::FRACTION_INTERNAL_DIGIT_SEPARATOR.bits ); // JULIA STRING [01345678MN] /// Float format to parse a Julia float from string. const JULIA_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; /// Float format for a C# literal floating-point number. const CSHARP_LITERAL = Self::CSHARP7_LITERAL.bits; /// Float format to parse a C# float from string. const CSHARP_STRING = Self::CSHARP7_STRING.bits; // CSHARP7 LITERAL [034569ABIJKMN-_] /// Float format for a C#7 literal floating-point number. const CSHARP7_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_FRACTION_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // CSHARP7 STRING [0134568MN] /// Float format to parse a C#7 float from string. const CSHARP7_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // CSHARP6 LITERAL [03456MN] /// Float format for a C#6 literal floating-point number. const CSHARP6_LITERAL = ( Self::REQUIRED_FRACTION_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // CSHARP6 STRING [0134568MN] /// Float format to parse a C#6 float from string. const CSHARP6_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // CSHARP5 LITERAL [03456MN] /// Float format for a C#5 literal floating-point number. const CSHARP5_LITERAL = ( Self::REQUIRED_FRACTION_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // CSHARP5 STRING [0134568MN] /// Float format to parse a C#5 float from string. const CSHARP5_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // CSHARP4 LITERAL [03456MN] /// Float format for a C#4 literal floating-point number. const CSHARP4_LITERAL = ( Self::REQUIRED_FRACTION_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // CSHARP4 STRING [0134568MN] /// Float format to parse a C#4 float from string. const CSHARP4_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // CSHARP3 LITERAL [03456MN] /// Float format for a C#3 literal floating-point number. const CSHARP3_LITERAL = ( Self::REQUIRED_FRACTION_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // CSHARP3 STRING [0134568MN] /// Float format to parse a C#3 float from string. const CSHARP3_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // CSHARP2 LITERAL [03456MN] /// Float format for a C#2 literal floating-point number. const CSHARP2_LITERAL = ( Self::REQUIRED_FRACTION_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // CSHARP2 STRING [0134568MN] /// Float format to parse a C#2 float from string. const CSHARP2_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // CSHARP1 LITERAL [03456MN] /// Float format for a C#1 literal floating-point number. const CSHARP1_LITERAL = ( Self::REQUIRED_FRACTION_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // CSHARP1 STRING [0134568MN] /// Float format to parse a C#1 float from string. const CSHARP1_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // KAWA LITERAL [013456MN] /// Float format for a Kawa literal floating-point number. const KAWA_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // KAWA STRING [013456MN] /// Float format to parse a Kawa float from string. const KAWA_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // GAMBITC LITERAL [013456MN] /// Float format for a Gambit-C literal floating-point number. const GAMBITC_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // GAMBITC STRING [013456MN] /// Float format to parse a Gambit-C float from string. const GAMBITC_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // GUILE LITERAL [013456MN] /// Float format for a Guile literal floating-point number. const GUILE_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // GUILE STRING [013456MN] /// Float format to parse a Guile float from string. const GUILE_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // CLOJURE LITERAL [13456MN] /// Float format for a Clojure literal floating-point number. const CLOJURE_LITERAL = ( Self::REQUIRED_INTEGER_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // CLOJURE STRING [01345678MN] /// Float format to parse a Clojure float from string. const CLOJURE_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // ERLANG LITERAL [34578MN] /// Float format for an Erlang literal floating-point number. const ERLANG_LITERAL = ( Self::REQUIRED_DIGITS.bits | Self::NO_EXPONENT_WITHOUT_FRACTION.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // ERLANG STRING [345MN] /// Float format to parse an Erlang float from string. const ERLANG_STRING = ( Self::REQUIRED_DIGITS.bits | Self::NO_EXPONENT_WITHOUT_FRACTION.bits | Self::NO_SPECIAL.bits ); // ELM LITERAL [456] /// Float format for an Elm literal floating-point number. const ELM_LITERAL = ( Self::REQUIRED_DIGITS.bits | Self::NO_POSITIVE_MANTISSA_SIGN.bits | Self::NO_INTEGER_LEADING_ZEROS.bits | Self::NO_FLOAT_LEADING_ZEROS.bits ); // ELM STRING [01345678MN] /// Float format to parse an Elm float from string. // Note: There is no valid representation of NaN, just Infinity. const ELM_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // SCALA LITERAL [3456] /// Float format for a Scala literal floating-point number. const SCALA_LITERAL = ( Self::REQUIRED_DIGITS.bits | Self::NO_SPECIAL.bits | Self::NO_INTEGER_LEADING_ZEROS.bits | Self::NO_FLOAT_LEADING_ZEROS.bits ); // SCALA STRING [01345678MN] /// Float format to parse a Scala float from string. const SCALA_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // ELIXIR LITERAL [3459ABMN-_] /// Float format for an Elixir literal floating-point number. const ELIXIR_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_DIGITS.bits | Self::NO_EXPONENT_WITHOUT_FRACTION.bits | Self::NO_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits ); // ELIXIR STRING [345MN] /// Float format to parse an Elixir float from string. const ELIXIR_STRING = ( Self::REQUIRED_DIGITS.bits | Self::NO_EXPONENT_WITHOUT_FRACTION.bits | Self::NO_SPECIAL.bits ); // FORTRAN LITERAL [013456MN] /// Float format for a FORTRAN literal floating-point number. const FORTRAN_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // FORTRAN STRING [0134567MN] /// Float format to parse a FORTRAN float from string. const FORTRAN_STRING = Self::REQUIRED_EXPONENT_DIGITS.bits; // D LITERAL [0134569ABFGHIJKN-_] /// Float format for a D literal floating-point number. const D_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits | Self::NO_INTEGER_LEADING_ZEROS.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // D STRING [01345679AFGMN-_] /// Float format to parse a D float from string. const D_STRING = ( digit_separator_to_flags(b'_') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::INTEGER_INTERNAL_DIGIT_SEPARATOR.bits | Self::FRACTION_INTERNAL_DIGIT_SEPARATOR.bits | Self::INTEGER_TRAILING_DIGIT_SEPARATOR.bits | Self::FRACTION_TRAILING_DIGIT_SEPARATOR.bits ); // COFFEESCRIPT LITERAL [01345678] /// Float format for a Coffeescript literal floating-point number. const COFFEESCRIPT_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::NO_INTEGER_LEADING_ZEROS.bits | Self::NO_FLOAT_LEADING_ZEROS.bits ); // COFFEESCRIPT STRING [012345678MN] /// Float format to parse a Coffeescript float from string. const COFFEESCRIPT_STRING = Self::CASE_SENSITIVE_SPECIAL.bits; // COBOL LITERAL [0345MN] /// Float format for a Cobol literal floating-point number. const COBOL_LITERAL = ( Self::REQUIRED_FRACTION_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_EXPONENT_WITHOUT_FRACTION.bits | Self::NO_SPECIAL.bits ); // COBOL STRING [012356MN] /// Float format to parse a Cobol float from string. const COBOL_STRING = ( Self::REQUIRED_EXPONENT_SIGN.bits | Self::NO_SPECIAL.bits ); // FSHARP LITERAL [13456789ABIJKMN-_] /// Float format for a F# literal floating-point number. const FSHARP_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_INTEGER_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // FSHARP STRING [013456789ABCDEFGHIJKLMN-_] /// Float format to parse a F# float from string. const FSHARP_STRING = ( digit_separator_to_flags(b'_') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits | Self::SPECIAL_DIGIT_SEPARATOR.bits ); // VB LITERAL [03456MN] /// Float format for a Visual Basic literal floating-point number. const VB_LITERAL = ( Self::REQUIRED_FRACTION_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // VB STRING [01345678MN] /// Float format to parse a Visual Basic float from string. // Note: To my knowledge, Visual Basic cannot parse infinity. const VB_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // OCAML LITERAL [1456789ABDFGHIJKMN-_] /// Float format for an OCaml literal floating-point number. const OCAML_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_INTEGER_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_POSITIVE_MANTISSA_SIGN.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::FRACTION_LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // OCAML STRING [01345679ABCDEFGHIJKLMN-_] /// Float format to parse an OCaml float from string. const OCAML_STRING = ( digit_separator_to_flags(b'_') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits | Self::SPECIAL_DIGIT_SEPARATOR.bits ); // OBJECTIVEC LITERAL [013456MN] /// Float format for an Objective-C literal floating-point number. const OBJECTIVEC_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // OBJECTIVEC STRING [013456MN] /// Float format to parse an Objective-C float from string. const OBJECTIVEC_STRING = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // REASONML LITERAL [13456789ABDFGHIJKMN-_] /// Float format for a ReasonML literal floating-point number. const REASONML_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_INTEGER_DIGITS.bits | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::FRACTION_LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // REASONML STRING [01345679ABCDEFGHIJKLMN-_] /// Float format to parse a ReasonML float from string. const REASONML_STRING = ( digit_separator_to_flags(b'_') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits | Self::SPECIAL_DIGIT_SEPARATOR.bits ); // OCTAVE LITERAL [013456789ABDFGHIJKMN-_] /// Float format for an Octave literal floating-point number. // Note: Octave accepts both NaN and nan, Inf and inf. const OCTAVE_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::FRACTION_LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // OCTAVE STRING [01345679ABCDEFGHIJKMN-,] /// Float format to parse an Octave float from string. const OCTAVE_STRING = ( digit_separator_to_flags(b',') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // MATLAB LITERAL [013456789ABDFGHIJKMN-_] /// Float format for an Matlab literal floating-point number. // Note: Matlab accepts both NaN and nan, Inf and inf. const MATLAB_LITERAL = ( digit_separator_to_flags(b'_') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::FRACTION_LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // MATLAB STRING [01345679ABCDEFGHIJKMN-,] /// Float format to parse an Matlab float from string. const MATLAB_STRING = ( digit_separator_to_flags(b',') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::LEADING_DIGIT_SEPARATOR.bits | Self::TRAILING_DIGIT_SEPARATOR.bits | Self::CONSECUTIVE_DIGIT_SEPARATOR.bits ); // ZIG LITERAL [1456MN] /// Float format for a Zig literal floating-point number. const ZIG_LITERAL = ( Self::REQUIRED_INTEGER_DIGITS.bits | Self::NO_POSITIVE_MANTISSA_SIGN.bits | Self::NO_SPECIAL.bits ); // ZIG STRING [01234567MN] /// Float format to parse a Zig float from string. const ZIG_STRING = 0; // SAGE LITERAL [012345678MN] /// Float format for a Sage literal floating-point number. // Note: Both Infinity and infinity are accepted. const SAGE_LITERAL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits ); // SAGE STRING [01345679ABMN-_] /// Float format to parse a Sage float from string. const SAGE_STRING = ( digit_separator_to_flags(b'_') | Self::REQUIRED_EXPONENT_DIGITS.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits ); // JSON [456] /// Float format for a JSON literal floating-point number. const JSON = ( Self::REQUIRED_DIGITS.bits | Self::NO_POSITIVE_MANTISSA_SIGN.bits | Self::NO_SPECIAL.bits | Self::NO_INTEGER_LEADING_ZEROS.bits | Self::NO_FLOAT_LEADING_ZEROS.bits ); // TOML [34569AB] /// Float format for a TOML literal floating-point number. const TOML = ( Self::REQUIRED_DIGITS.bits | Self::NO_SPECIAL.bits | Self::INTERNAL_DIGIT_SEPARATOR.bits | Self::NO_INTEGER_LEADING_ZEROS.bits | Self::NO_FLOAT_LEADING_ZEROS.bits ); // YAML (defined in-terms of JSON schema). /// Float format for a YAML literal floating-point number. const YAML = Self::JSON.bits; // XML [01234578MN] /// Float format for a XML literal floating-point number. const XML = Self::CASE_SENSITIVE_SPECIAL.bits; // SQLITE [013456MN] /// Float format for a SQLite literal floating-point number. const SQLITE = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // POSTGRESQL [013456MN] /// Float format for a PostgreSQL literal floating-point number. const POSTGRESQL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // MYSQL [013456MN] /// Float format for a MySQL literal floating-point number. const MYSQL = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::NO_SPECIAL.bits ); // MONGODB [01345678M] /// Float format for a MongoDB literal floating-point number. const MONGODB = ( Self::REQUIRED_EXPONENT_DIGITS.bits | Self::CASE_SENSITIVE_SPECIAL.bits | Self::NO_FLOAT_LEADING_ZEROS.bits ); // HIDDEN DEFAULTS /// Float format when no flags are set. #[doc(hidden)] const PERMISSIVE = 0; /// Permissive interface float format flags. #[doc(hidden)] const PERMISSIVE_INTERFACE = Self::PERMISSIVE.bits & Self::INTERFACE_FLAG_MASK.bits; /// Standard float format. #[doc(hidden)] const STANDARD = Self::RUST_STRING.bits; /// Standard interface float format flags. #[doc(hidden)] const STANDARD_INTERFACE = Self::STANDARD.bits & Self::INTERFACE_FLAG_MASK.bits; /// Float format when all digit separator flags are set. #[doc(hidden)] const IGNORE = Self::DIGIT_SEPARATOR_FLAG_MASK.bits; /// Ignore interface float format flags. #[doc(hidden)] const IGNORE_INTERFACE = Self::IGNORE.bits & Self::INTERFACE_FLAG_MASK.bits; } } // Ensure all our bit flags are valid. macro_rules! check_subsequent_flags { ($x:ident, $y:ident) => ( const_assert!(NumberFormat::$x.bits << 1 == NumberFormat::$y.bits); ); } // Non-digit separator flags. const_assert!(NumberFormat::REQUIRED_INTEGER_DIGITS.bits == 1); check_subsequent_flags!(REQUIRED_INTEGER_DIGITS, REQUIRED_FRACTION_DIGITS); check_subsequent_flags!(REQUIRED_FRACTION_DIGITS, REQUIRED_EXPONENT_DIGITS); check_subsequent_flags!(REQUIRED_EXPONENT_DIGITS, NO_POSITIVE_MANTISSA_SIGN); check_subsequent_flags!(NO_POSITIVE_MANTISSA_SIGN, REQUIRED_MANTISSA_SIGN); check_subsequent_flags!(REQUIRED_MANTISSA_SIGN, NO_EXPONENT_NOTATION); check_subsequent_flags!(NO_EXPONENT_NOTATION, NO_POSITIVE_EXPONENT_SIGN); check_subsequent_flags!(NO_POSITIVE_EXPONENT_SIGN, REQUIRED_EXPONENT_SIGN); check_subsequent_flags!(REQUIRED_EXPONENT_SIGN, NO_EXPONENT_WITHOUT_FRACTION); check_subsequent_flags!(NO_EXPONENT_WITHOUT_FRACTION, NO_SPECIAL); check_subsequent_flags!(NO_SPECIAL, CASE_SENSITIVE_SPECIAL); check_subsequent_flags!(CASE_SENSITIVE_SPECIAL, NO_INTEGER_LEADING_ZEROS); check_subsequent_flags!(NO_INTEGER_LEADING_ZEROS, NO_FLOAT_LEADING_ZEROS); // Digit separator flags. const_assert!(NumberFormat::INTEGER_INTERNAL_DIGIT_SEPARATOR.bits == 1 << 32); check_subsequent_flags!(INTEGER_INTERNAL_DIGIT_SEPARATOR, INTEGER_LEADING_DIGIT_SEPARATOR); check_subsequent_flags!(INTEGER_LEADING_DIGIT_SEPARATOR, INTEGER_TRAILING_DIGIT_SEPARATOR); check_subsequent_flags!(INTEGER_TRAILING_DIGIT_SEPARATOR, INTEGER_CONSECUTIVE_DIGIT_SEPARATOR); check_subsequent_flags!(INTEGER_CONSECUTIVE_DIGIT_SEPARATOR, FRACTION_INTERNAL_DIGIT_SEPARATOR); check_subsequent_flags!(FRACTION_INTERNAL_DIGIT_SEPARATOR, FRACTION_LEADING_DIGIT_SEPARATOR); check_subsequent_flags!(FRACTION_LEADING_DIGIT_SEPARATOR, FRACTION_TRAILING_DIGIT_SEPARATOR); check_subsequent_flags!(FRACTION_TRAILING_DIGIT_SEPARATOR, FRACTION_CONSECUTIVE_DIGIT_SEPARATOR); check_subsequent_flags!(FRACTION_CONSECUTIVE_DIGIT_SEPARATOR, EXPONENT_INTERNAL_DIGIT_SEPARATOR); check_subsequent_flags!(EXPONENT_INTERNAL_DIGIT_SEPARATOR, EXPONENT_LEADING_DIGIT_SEPARATOR); check_subsequent_flags!(EXPONENT_LEADING_DIGIT_SEPARATOR, EXPONENT_TRAILING_DIGIT_SEPARATOR); check_subsequent_flags!(EXPONENT_TRAILING_DIGIT_SEPARATOR, EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR); check_subsequent_flags!(EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR, SPECIAL_DIGIT_SEPARATOR); /// Add flag to flags macro_rules! add_flag { ($flags:ident, $bool:ident, $flag:ident) => { if $bool { $flags |= NumberFormat::$flag; } }; } impl NumberFormat { /// Compile float format value from specifications. /// /// * `digit_separator` - Character to separate digits. /// * `required_integer_digits` - If digits are required before the decimal point. /// * `required_fraction_digits` - If digits are required after the decimal point. /// * `required_exponent_digits` - If digits are required after the exponent character. /// * `no_positive_mantissa_sign` - If positive sign before the mantissa is not allowed. /// * `required_mantissa_sign` - If positive sign before the mantissa is required. /// * `no_exponent_notation` - If exponent notation is not allowed. /// * `no_positive_exponent_sign` - If positive sign before the exponent is not allowed. /// * `required_exponent_sign` - If sign before the exponent is required. /// * `no_exponent_without_fraction` - If exponent without fraction is not allowed. /// * `no_special` - If special (non-finite) values are not allowed. /// * `case_sensitive_special` - If special (non-finite) values are case-sensitive. /// * `no_integer_leading_zeros` - If leading zeros before an integer are not allowed. /// * `no_float_leading_zeros` - If leading zeros before a float are not allowed. /// * `integer_internal_digit_separator` - If digit separators are allowed between integer digits. /// * `fraction_internal_digit_separator` - If digit separators are allowed between fraction digits. /// * `exponent_internal_digit_separator` - If digit separators are allowed between exponent digits. /// * `integer_leading_digit_separator` - If a digit separator is allowed before any integer digits. /// * `fraction_leading_digit_separator` - If a digit separator is allowed before any fraction digits. /// * `exponent_leading_digit_separator` - If a digit separator is allowed before any exponent digits. /// * `integer_trailing_digit_separator` - If a digit separator is allowed after any integer digits. /// * `fraction_trailing_digit_separator` - If a digit separator is allowed after any fraction digits. /// * `exponent_trailing_digit_separator` - If a digit separator is allowed after any exponent digits. /// * `integer_consecutive_digit_separator` - If multiple consecutive integer digit separators are allowed. /// * `fraction_consecutive_digit_separator` - If multiple consecutive fraction digit separators are allowed. /// * `special_digit_separator` - If any digit separators are allowed in special (non-finite) values. /// /// Returns the value if it was able to compile the format, /// otherwise, returns None. #[cfg_attr(feature = "radix", doc = " Digit separators must not be in the character group `[A-Za-z0-9+.-]`, nor be equal to")] #[cfg_attr(feature = "radix", doc = " [`get_exponent_default_char`](fn.get_exponent_default_char.html) or")] #[cfg_attr(feature = "radix", doc = " [`get_exponent_backup_char`](fn.get_exponent_backup_char.html).")] #[cfg_attr(not(feature = "radix"), doc = " Digit separators must not be in the character group `[0-9+.-]`, nor be equal to")] #[cfg_attr(not(feature = "radix"), doc = " [get_exponent_default_char](fn.get_exponent_default_char.html).")] /// /// # Versioning /// /// Due to the potential addition of bitflags required to parse a given /// number, this function is not considered stable and will not /// be stabilized until lexical-core version 1.0. Any changes will /// ensure they introduce compile errors in existing code, and will /// not the current major/minor version. #[inline] pub fn compile( digit_separator: u8, required_integer_digits: bool, required_fraction_digits: bool, required_exponent_digits: bool, no_positive_mantissa_sign: bool, required_mantissa_sign: bool, no_exponent_notation: bool, no_positive_exponent_sign: bool, required_exponent_sign: bool, no_exponent_without_fraction: bool, no_special: bool, case_sensitive_special: bool, no_integer_leading_zeros: bool, no_float_leading_zeros: bool, integer_internal_digit_separator: bool, fraction_internal_digit_separator: bool, exponent_internal_digit_separator: bool, integer_leading_digit_separator: bool, fraction_leading_digit_separator: bool, exponent_leading_digit_separator: bool, integer_trailing_digit_separator: bool, fraction_trailing_digit_separator: bool, exponent_trailing_digit_separator: bool, integer_consecutive_digit_separator: bool, fraction_consecutive_digit_separator: bool, exponent_consecutive_digit_separator: bool, special_digit_separator: bool ) -> Option { let mut format = NumberFormat::default(); // Generic flags. add_flag!(format, required_integer_digits, REQUIRED_INTEGER_DIGITS); add_flag!(format, required_fraction_digits, REQUIRED_FRACTION_DIGITS); add_flag!(format, required_exponent_digits, REQUIRED_EXPONENT_DIGITS); add_flag!(format, no_positive_mantissa_sign, NO_POSITIVE_MANTISSA_SIGN); add_flag!(format, required_mantissa_sign, REQUIRED_MANTISSA_SIGN); add_flag!(format, no_exponent_notation, NO_EXPONENT_NOTATION); add_flag!(format, no_positive_exponent_sign, NO_POSITIVE_EXPONENT_SIGN); add_flag!(format, required_exponent_sign, REQUIRED_EXPONENT_SIGN); add_flag!(format, no_exponent_without_fraction, NO_EXPONENT_WITHOUT_FRACTION); add_flag!(format, no_special, NO_SPECIAL); add_flag!(format, case_sensitive_special, CASE_SENSITIVE_SPECIAL); add_flag!(format, no_integer_leading_zeros, NO_INTEGER_LEADING_ZEROS); add_flag!(format, no_float_leading_zeros, NO_FLOAT_LEADING_ZEROS); // Digit separator flags. add_flag!(format, integer_internal_digit_separator, INTEGER_INTERNAL_DIGIT_SEPARATOR); add_flag!(format, fraction_internal_digit_separator, FRACTION_INTERNAL_DIGIT_SEPARATOR); add_flag!(format, exponent_internal_digit_separator, EXPONENT_INTERNAL_DIGIT_SEPARATOR); add_flag!(format, integer_leading_digit_separator, INTEGER_LEADING_DIGIT_SEPARATOR); add_flag!(format, fraction_leading_digit_separator, FRACTION_LEADING_DIGIT_SEPARATOR); add_flag!(format, exponent_leading_digit_separator, EXPONENT_LEADING_DIGIT_SEPARATOR); add_flag!(format, integer_trailing_digit_separator, INTEGER_TRAILING_DIGIT_SEPARATOR); add_flag!(format, fraction_trailing_digit_separator, FRACTION_TRAILING_DIGIT_SEPARATOR); add_flag!(format, exponent_trailing_digit_separator, EXPONENT_TRAILING_DIGIT_SEPARATOR); add_flag!(format, integer_consecutive_digit_separator, INTEGER_CONSECUTIVE_DIGIT_SEPARATOR); add_flag!(format, fraction_consecutive_digit_separator, FRACTION_CONSECUTIVE_DIGIT_SEPARATOR); add_flag!(format, exponent_consecutive_digit_separator, EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR); add_flag!(format, special_digit_separator, SPECIAL_DIGIT_SEPARATOR); // Digit separator. if format.intersects(NumberFormat::DIGIT_SEPARATOR_FLAG_MASK) { format.bits |= digit_separator_to_flags(digit_separator); } // Validation. let is_invalid = !is_valid_separator(digit_separator) || format.intersects(NumberFormat::NO_EXPONENT_NOTATION) && format.intersects(NumberFormat::EXPONENT_FLAG_MASK) || no_positive_mantissa_sign && required_mantissa_sign || no_positive_exponent_sign && required_exponent_sign || no_special && (case_sensitive_special || special_digit_separator) || format & NumberFormat::INTEGER_DIGIT_SEPARATOR_FLAG_MASK == NumberFormat::INTEGER_CONSECUTIVE_DIGIT_SEPARATOR || format & NumberFormat::FRACTION_DIGIT_SEPARATOR_FLAG_MASK == NumberFormat::FRACTION_CONSECUTIVE_DIGIT_SEPARATOR || format & NumberFormat::EXPONENT_DIGIT_SEPARATOR_FLAG_MASK == NumberFormat::EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR; match is_invalid { true => None, false => Some(format) } } /// Compile permissive number format. /// /// The permissive number format does not require any control /// grammar, besides the presence of mantissa digits. /// /// This function cannot fail, but returns an option for consistency /// with other grammar compilers. pub fn permissive() -> Option { Some(NumberFormat::PERMISSIVE) } /// Compile standard number format. /// /// The standard number format is guaranteed to be identical /// to the format expected by Rust's string to number parsers. /// /// This function cannot fail, but returns an option for consistency /// with other grammar compilers. pub fn standard() -> Option { Some(NumberFormat::STANDARD) } /// Compile ignore number format. /// /// The ignore number format ignores all digit separators, /// and is permissive for all other control grammar, so /// implements a fast parser. /// /// * `digit_separator` - Character to separate digits. /// /// Returns the value if it was able to compile the format, /// otherwise, returns None. pub fn ignore(digit_separator: u8) -> Option { if !is_valid_separator(digit_separator) { return None } let mut format = NumberFormat::IGNORE; format.bits |= digit_separator_to_flags(digit_separator); Some(format) } /// Create float format directly from digit separator for unittests. #[cfg(test)] #[inline] pub(crate) fn from_separator(digit_separator: u8) -> NumberFormat { NumberFormat { bits: digit_separator_to_flags(digit_separator) } } /// Get the flag bits from the compiled float format. #[inline] pub fn flags(self) -> NumberFormat { return self & NumberFormat::FLAG_MASK } /// Get the interface flag bits from the compiled float format. #[inline] pub(crate) fn interface_flags(self) -> NumberFormat { return self & NumberFormat::INTERFACE_FLAG_MASK } /// Get the digit separator from the compiled float format. #[inline] pub fn digit_separator(self) -> u8 { digit_separator_from_flags(self.bits) } /// Get if digits are required before the decimal point. #[inline] pub fn required_integer_digits(self) -> bool { self.intersects(NumberFormat::REQUIRED_INTEGER_DIGITS) } /// Get if digits are required after the decimal point. #[inline] pub fn required_fraction_digits(self) -> bool { self.intersects(NumberFormat::REQUIRED_FRACTION_DIGITS) } /// Get if digits are required after the exponent character. #[inline] pub fn required_exponent_digits(self) -> bool { self.intersects(NumberFormat::REQUIRED_EXPONENT_DIGITS) } /// Get if digits are required before or after the decimal point. #[inline] pub fn required_digits(self) -> bool { self.intersects(NumberFormat::REQUIRED_DIGITS) } /// Get if positive sign before the mantissa is not allowed. #[inline] pub fn no_positive_mantissa_sign(self) -> bool { self.intersects(NumberFormat::NO_POSITIVE_MANTISSA_SIGN) } /// Get if positive sign before the mantissa is required. #[inline] pub fn required_mantissa_sign(self) -> bool { self.intersects(NumberFormat::REQUIRED_MANTISSA_SIGN) } /// Get if exponent notation is not allowed. #[inline] pub fn no_exponent_notation(self) -> bool { self.intersects(NumberFormat::NO_EXPONENT_NOTATION) } /// Get if positive sign before the exponent is not allowed. #[inline] pub fn no_positive_exponent_sign(self) -> bool { self.intersects(NumberFormat::NO_POSITIVE_EXPONENT_SIGN) } /// Get if sign before the exponent is required. #[inline] pub fn required_exponent_sign(self) -> bool { self.intersects(NumberFormat::REQUIRED_EXPONENT_SIGN) } /// Get if exponent without fraction is not allowed. #[inline] pub fn no_exponent_without_fraction(self) -> bool { self.intersects(NumberFormat::NO_EXPONENT_WITHOUT_FRACTION) } /// Get if special (non-finite) values are not allowed. #[inline] pub fn no_special(self) -> bool { self.intersects(NumberFormat::NO_SPECIAL) } /// Get if special (non-finite) values are case-sensitive. #[inline] pub fn case_sensitive_special(self) -> bool { self.intersects(NumberFormat::CASE_SENSITIVE_SPECIAL) } /// Get if leading zeros before an integer are not allowed. #[inline] pub fn no_integer_leading_zeros(self) -> bool { self.intersects(NumberFormat::NO_INTEGER_LEADING_ZEROS) } /// Get if leading zeros before a float are not allowed. #[inline] pub fn no_float_leading_zeros(self) -> bool { self.intersects(NumberFormat::NO_FLOAT_LEADING_ZEROS) } /// Get if digit separators are allowed between integer digits. #[inline] pub fn integer_internal_digit_separator(self) -> bool { self.intersects(NumberFormat::INTEGER_INTERNAL_DIGIT_SEPARATOR) } /// Get if digit separators are allowed between fraction digits. #[inline] pub fn fraction_internal_digit_separator(self) -> bool { self.intersects(NumberFormat::FRACTION_INTERNAL_DIGIT_SEPARATOR) } /// Get if digit separators are allowed between exponent digits. #[inline] pub fn exponent_internal_digit_separator(self) -> bool { self.intersects(NumberFormat::EXPONENT_INTERNAL_DIGIT_SEPARATOR) } /// Get if digit separators are allowed between digits. #[inline] pub fn internal_digit_separator(self) -> bool { self.intersects(NumberFormat::INTERNAL_DIGIT_SEPARATOR) } /// Get if a digit separator is allowed before any integer digits. #[inline] pub fn integer_leading_digit_separator(self) -> bool { self.intersects(NumberFormat::INTEGER_LEADING_DIGIT_SEPARATOR) } /// Get if a digit separator is allowed before any fraction digits. #[inline] pub fn fraction_leading_digit_separator(self) -> bool { self.intersects(NumberFormat::FRACTION_LEADING_DIGIT_SEPARATOR) } /// Get if a digit separator is allowed before any exponent digits. #[inline] pub fn exponent_leading_digit_separator(self) -> bool { self.intersects(NumberFormat::EXPONENT_LEADING_DIGIT_SEPARATOR) } /// Get if a digit separator is allowed before any digits. #[inline] pub fn leading_digit_separator(self) -> bool { self.intersects(NumberFormat::LEADING_DIGIT_SEPARATOR) } /// Get if a digit separator is allowed after any integer digits. #[inline] pub fn integer_trailing_digit_separator(self) -> bool { self.intersects(NumberFormat::INTEGER_TRAILING_DIGIT_SEPARATOR) } /// Get if a digit separator is allowed after any fraction digits. #[inline] pub fn fraction_trailing_digit_separator(self) -> bool { self.intersects(NumberFormat::FRACTION_TRAILING_DIGIT_SEPARATOR) } /// Get if a digit separator is allowed after any exponent digits. #[inline] pub fn exponent_trailing_digit_separator(self) -> bool { self.intersects(NumberFormat::EXPONENT_TRAILING_DIGIT_SEPARATOR) } /// Get if a digit separator is allowed after any digits. #[inline] pub fn trailing_digit_separator(self) -> bool { self.intersects(NumberFormat::TRAILING_DIGIT_SEPARATOR) } /// Get if multiple consecutive integer digit separators are allowed. #[inline] pub fn integer_consecutive_digit_separator(self) -> bool { self.intersects(NumberFormat::INTEGER_CONSECUTIVE_DIGIT_SEPARATOR) } /// Get if multiple consecutive fraction digit separators are allowed. #[inline] pub fn fraction_consecutive_digit_separator(self) -> bool { self.intersects(NumberFormat::FRACTION_CONSECUTIVE_DIGIT_SEPARATOR) } /// Get if multiple consecutive exponent digit separators are allowed. #[inline] pub fn exponent_consecutive_digit_separator(self) -> bool { self.intersects(NumberFormat::EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR) } /// Get if multiple consecutive digit separators are allowed. #[inline] pub fn consecutive_digit_separator(self) -> bool { self.intersects(NumberFormat::CONSECUTIVE_DIGIT_SEPARATOR) } /// Get if any digit separators are allowed in special (non-finite) values. #[inline] pub fn special_digit_separator(self) -> bool { self.intersects(NumberFormat::SPECIAL_DIGIT_SEPARATOR) } } // TESTS // ----- #[cfg(test)] mod tests { use super::*; #[test] fn test_is_valid_separator() { assert_eq!(is_valid_separator(b'_'), true); assert_eq!(is_valid_separator(b'\''), true); assert_eq!(is_valid_separator(b'0'), false); assert_eq!(is_valid_separator(128), false); } #[test] fn test_compile() { // Test all false let flags = NumberFormat::compile(b'_', false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false).unwrap(); assert_eq!(flags.flags(), NumberFormat::default()); assert_eq!(flags.digit_separator(), 0); } #[test] fn test_permissive() { let flags = NumberFormat::ignore(b'_').unwrap(); assert_eq!(flags.flags(), NumberFormat::DIGIT_SEPARATOR_FLAG_MASK); } #[test] fn test_ignore() { let flags = NumberFormat::ignore(b'_').unwrap(); assert_eq!(flags.flags(), NumberFormat::DIGIT_SEPARATOR_FLAG_MASK); assert_eq!(flags.digit_separator(), b'_'); assert_eq!(flags.required_integer_digits(), false); assert_eq!(flags.required_fraction_digits(), false); assert_eq!(flags.required_exponent_digits(), false); assert_eq!(flags.required_digits(), false); assert_eq!(flags.no_positive_mantissa_sign(), false); assert_eq!(flags.required_mantissa_sign(), false); assert_eq!(flags.no_exponent_notation(), false); assert_eq!(flags.no_positive_exponent_sign(), false); assert_eq!(flags.required_exponent_sign(), false); assert_eq!(flags.no_exponent_without_fraction(), false); assert_eq!(flags.no_special(), false); assert_eq!(flags.case_sensitive_special(), false); assert_eq!(flags.no_integer_leading_zeros(), false); assert_eq!(flags.no_float_leading_zeros(), false); assert_eq!(flags.integer_internal_digit_separator(), true); assert_eq!(flags.fraction_internal_digit_separator(), true); assert_eq!(flags.exponent_internal_digit_separator(), true); assert_eq!(flags.internal_digit_separator(), true); assert_eq!(flags.integer_leading_digit_separator(), true); assert_eq!(flags.fraction_leading_digit_separator(), true); assert_eq!(flags.exponent_leading_digit_separator(), true); assert_eq!(flags.leading_digit_separator(), true); assert_eq!(flags.integer_trailing_digit_separator(), true); assert_eq!(flags.fraction_trailing_digit_separator(), true); assert_eq!(flags.exponent_trailing_digit_separator(), true); assert_eq!(flags.trailing_digit_separator(), true); assert_eq!(flags.integer_consecutive_digit_separator(), true); assert_eq!(flags.fraction_consecutive_digit_separator(), true); assert_eq!(flags.exponent_consecutive_digit_separator(), true); assert_eq!(flags.consecutive_digit_separator(), true); assert_eq!(flags.special_digit_separator(), true); } #[test] fn test_flags() { let flags = [ NumberFormat::REQUIRED_INTEGER_DIGITS, NumberFormat::REQUIRED_FRACTION_DIGITS, NumberFormat::REQUIRED_EXPONENT_DIGITS, NumberFormat::NO_POSITIVE_MANTISSA_SIGN, NumberFormat::REQUIRED_MANTISSA_SIGN, NumberFormat::NO_EXPONENT_NOTATION, NumberFormat::NO_POSITIVE_EXPONENT_SIGN, NumberFormat::REQUIRED_EXPONENT_SIGN, NumberFormat::NO_EXPONENT_WITHOUT_FRACTION, NumberFormat::NO_SPECIAL, NumberFormat::CASE_SENSITIVE_SPECIAL, NumberFormat::NO_INTEGER_LEADING_ZEROS, NumberFormat::NO_FLOAT_LEADING_ZEROS, NumberFormat::INTEGER_INTERNAL_DIGIT_SEPARATOR, NumberFormat::FRACTION_INTERNAL_DIGIT_SEPARATOR, NumberFormat::EXPONENT_INTERNAL_DIGIT_SEPARATOR, NumberFormat::INTEGER_LEADING_DIGIT_SEPARATOR, NumberFormat::FRACTION_LEADING_DIGIT_SEPARATOR, NumberFormat::EXPONENT_LEADING_DIGIT_SEPARATOR, NumberFormat::INTEGER_TRAILING_DIGIT_SEPARATOR, NumberFormat::FRACTION_TRAILING_DIGIT_SEPARATOR, NumberFormat::EXPONENT_TRAILING_DIGIT_SEPARATOR, NumberFormat::INTEGER_CONSECUTIVE_DIGIT_SEPARATOR, NumberFormat::FRACTION_CONSECUTIVE_DIGIT_SEPARATOR, NumberFormat::EXPONENT_CONSECUTIVE_DIGIT_SEPARATOR, NumberFormat::SPECIAL_DIGIT_SEPARATOR ]; for &flag in flags.iter() { assert_eq!(flag.flags(), flag); assert_eq!(flag.digit_separator(), 0); } } #[test] fn test_constants() { let flags = [ NumberFormat::RUST_LITERAL, NumberFormat::RUST_STRING, NumberFormat::RUST_STRING_STRICT, NumberFormat::PYTHON_LITERAL, NumberFormat::PYTHON_STRING, NumberFormat::CXX17_LITERAL, NumberFormat::CXX17_STRING, NumberFormat::CXX14_LITERAL, NumberFormat::CXX14_STRING, NumberFormat::CXX11_LITERAL, NumberFormat::CXX11_STRING, NumberFormat::CXX03_LITERAL, NumberFormat::CXX03_STRING, NumberFormat::CXX98_LITERAL, NumberFormat::CXX98_STRING, NumberFormat::C18_LITERAL, NumberFormat::C18_STRING, NumberFormat::C11_LITERAL, NumberFormat::C11_STRING, NumberFormat::C99_LITERAL, NumberFormat::C99_STRING, NumberFormat::C90_LITERAL, NumberFormat::C90_STRING, NumberFormat::C89_LITERAL, NumberFormat::C89_STRING, NumberFormat::RUBY_LITERAL, NumberFormat::RUBY_STRING, NumberFormat::SWIFT_LITERAL, NumberFormat::SWIFT_STRING, NumberFormat::GO_LITERAL, NumberFormat::GO_STRING, NumberFormat::HASKELL_LITERAL, NumberFormat::HASKELL_STRING, NumberFormat::JAVASCRIPT_LITERAL, NumberFormat::JAVASCRIPT_STRING, NumberFormat::PERL_LITERAL, NumberFormat::PERL_STRING, NumberFormat::PHP_LITERAL, NumberFormat::PHP_STRING, NumberFormat::JAVA_LITERAL, NumberFormat::JAVA_STRING, NumberFormat::R_LITERAL, NumberFormat::R_STRING, NumberFormat::KOTLIN_LITERAL, NumberFormat::KOTLIN_STRING, NumberFormat::JULIA_LITERAL, NumberFormat::JULIA_STRING, NumberFormat::CSHARP7_LITERAL, NumberFormat::CSHARP7_STRING, NumberFormat::CSHARP6_LITERAL, NumberFormat::CSHARP6_STRING, NumberFormat::CSHARP5_LITERAL, NumberFormat::CSHARP5_STRING, NumberFormat::CSHARP4_LITERAL, NumberFormat::CSHARP4_STRING, NumberFormat::CSHARP3_LITERAL, NumberFormat::CSHARP3_STRING, NumberFormat::CSHARP2_LITERAL, NumberFormat::CSHARP2_STRING, NumberFormat::CSHARP1_LITERAL, NumberFormat::CSHARP1_STRING, NumberFormat::KAWA_LITERAL, NumberFormat::KAWA_STRING, NumberFormat::GAMBITC_LITERAL, NumberFormat::GAMBITC_STRING, NumberFormat::GUILE_LITERAL, NumberFormat::GUILE_STRING, NumberFormat::CLOJURE_LITERAL, NumberFormat::CLOJURE_STRING, NumberFormat::ERLANG_LITERAL, NumberFormat::ERLANG_STRING, NumberFormat::ELM_LITERAL, NumberFormat::ELM_STRING, NumberFormat::SCALA_LITERAL, NumberFormat::SCALA_STRING, NumberFormat::ELIXIR_LITERAL, NumberFormat::ELIXIR_STRING, NumberFormat::FORTRAN_LITERAL, NumberFormat::FORTRAN_STRING, NumberFormat::D_LITERAL, NumberFormat::D_STRING, NumberFormat::COFFEESCRIPT_LITERAL, NumberFormat::COFFEESCRIPT_STRING, NumberFormat::COBOL_LITERAL, NumberFormat::COBOL_STRING, NumberFormat::FSHARP_LITERAL, NumberFormat::FSHARP_STRING, NumberFormat::VB_LITERAL, NumberFormat::VB_STRING, NumberFormat::OCAML_LITERAL, NumberFormat::OCAML_STRING, NumberFormat::OBJECTIVEC_LITERAL, NumberFormat::OBJECTIVEC_STRING, NumberFormat::REASONML_LITERAL, NumberFormat::REASONML_STRING, NumberFormat::OCTAVE_LITERAL, NumberFormat::OCTAVE_STRING, NumberFormat::MATLAB_LITERAL, NumberFormat::MATLAB_STRING, NumberFormat::ZIG_LITERAL, NumberFormat::ZIG_STRING, NumberFormat::SAGE_LITERAL, NumberFormat::SAGE_STRING, NumberFormat::JSON, NumberFormat::TOML, NumberFormat::YAML, NumberFormat::XML, NumberFormat::SQLITE, NumberFormat::POSTGRESQL, NumberFormat::MYSQL, NumberFormat::MONGODB ]; for &flag in flags.iter() { // Just wanna check the flags are defined. assert!((flag.bits == 0) | true); assert!((flag.digit_separator() == 0) | true); } } } lexical-core-0.7.6/src/util/format/not_feature_format.rs000075500000000000000000000006670000000000000214630ustar 00000000000000#![cfg(not(feature = "format"))] use bitflags::bitflags; bitflags! { /// Dummy bitflags for the float format. #[doc(hidden)] #[derive(Default)] pub struct NumberFormat: u64 { const __NONEXHAUSTIVE = 0; } } impl NumberFormat { #[inline] pub fn standard() -> Option { Some(NumberFormat::default()) } #[inline] pub fn digit_separator(&self) -> u8 { 0 } } lexical-core-0.7.6/src/util/format.rs000075500000000000000000000313350000000000000155740ustar 00000000000000//! Number format enumerations and bit masks. // Sample test code for each language used: // // Rust // ---- // // Setup: // Save to `main.rs` and run `rustc main.rs -o main`. // // Code: // ```text // pub fn main() { // println!("{:?}", 3_.0f32); // println!("{:?}", "3_.0".parse::()); // } // ``` // // Python // ------ // // Setup: // Run `python` to enter the interpreter. // // Code: // ```text // print(3_.0) // print(float("3_.0")) // ``` // // C++ // --- // // Setup: // Save to `main.cc` and run `g++ main.cc -o main -std=c++XX`, // where XX is one of the following values: // - 98 // - 03 // - 11 // - 14 // - 17 // // Code: // ```text // #include // #include // #include // #include // #include // // double parse(const char* string) { // char* end; // double result = strtod(string, &end); // if (std::distance(string, reinterpret_cast(end)) != strlen(string)) { // throw std::invalid_argument("did not consume entire string."); // } // return result; // } // // int main() { // std::cout << 3'.0 << std::endl; // std::cout << parse("3'.0") << std::endl; // } // ``` // // C // - // // Setup: // Save to `main.c` and run `gcc main.c -o main -std=cXX`, // where XX is one of the following values: // - 89 // - 90 // - 99 // - 11 // - 18 // // Code: // ```text // #include // #include // #include // #include // // size_t distance(const char* first, const char* last) { // uintptr_t x = (uintptr_t) first; // uintptr_t y = (uintptr_t) last; // return (size_t) (y - x); // } // // double parse(const char* string) { // char* end; // double result = strtod(string, &end); // if (distance(string, (const char*) end) != strlen(string)) { // abort(); // } // return result; // } // // int main() { // printf("%f\n", 3'.); // printf("%f\n", parse("3'.")); // } // ``` // // Ruby // ---- // // Setup: // Run `irb` to enter the interpreter. // // Code: // ```text // puts 3.0_1; // puts "3.0_1".to_f; // ``` // Swift // ----- // // Setup: // Run `swift` to enter the interpreter. // // Code: // ```text // print(3.0); // print(Float("3.0")); // ``` // Golang // ------ // // Setup: // Save to `main.go` and run `go run main.go` // // Code: // ```text // package main // // import ( // "fmt" // "strconv" // ) // // func main() { // fmt.Println(3.0) // fmt.Println(strconv.ParseFloat("3.0", 64)) // } // ``` // // Haskell // ------- // // Setup: // Run `ghci` to enter the interpreter. // // Code: // ```text // :m Numeric // showFloat 3.0 "" // let x = "3.0" // read x :: Float // ``` // // Javascript // ---------- // // Setup: // Run `nodejs` (or `node`) to enter the interpreter. // // Code: // ```text // console.log(3.0) // console.log(parseFloat("3.0")) // ``` // // Perl // ---- // // Setup: // Run `perl -de1` to enter the interpret. // // Code: // ```text // print 3.01; // print '3.01' * 1; // ``` // // PHP // --- // // Setup: // Run `php -a` to enter the interpret. // // Code: // ```text // printf("%f\n", 3.0); // printf("%f\n", floatval("3.0")); // ``` // // Java // ---- // // Setup: // Save to `main.java` and run `javac main.java`, then run `java Main`. // // Code: // ```text // class Main { // public static void main(String args[]) { // System.out.println(3.0); // System.out.println(Float.parseFloat("3.0")); // } // } // ``` // // R // - // // Setup: // Run `R` to enter the interpret. // // Code: // ```text // print(3.0); // print(as.numeric("3.0")); // ``` // // Kotlin // ------ // // Setup: // Save file to `main.kt` and run `kotlinc main.kt -d main.jar`, // then run `java -jar main.jar`. // // Code: // ```text // fun main() { // println(3.0) // println("3.0".toDouble()) // } // ``` // // Julia // ----- // // Setup: // Run `julia` to enter the interpret. // // Code: // ```text // print(3.0); // print(parse(Float64, "3.0")); // ``` // // C# // -- // // Note: // Mono accepts both integer and fraction decimal separators, Mono is // just buggy, see https://github.com/dotnet/csharplang/issues/55#issuecomment-574902516. // // Setup: // Run `csharp -langversion:X` to enter the interpret, // where XX is one of the following values: // - ISO-1 // - ISO-2 // - 3 // - 4 // - 5 // - 6 // - 7 // // Code: // ```text // Console.WriteLine("{0}", 3.0); // Console.WriteLine("{0}", float.Parse("3.0")); // ``` // // Kawa // ---- // // Setup: // Run `kawa` to enter the interpreter. // // Code: // ```text // 3.0 // (string->number "3.0") // ``` // // Gambit-C // -------- // // Setup: // Run `gsc` to enter the interpreter. // // Code: // ```text // 3.0 // (string->number "3.0") // ``` // // Guile // ----- // // Setup: // Run `guile` to enter the interpreter. // // Code: // ```text // 3.0 // (string->number "3.0") // ``` // // Clojure // ------- // // Setup: // Run `clojure` to enter the interpreter. // // Code: // ```text // 3.0 // (Float/parseFloat "3.0") // ``` // // Erlang // ------ // // Setup: // Run `erl` to enter the interpreter. // // Code: // ```text // io:format("~p~n", [3.0]). // string:to_float("3.0"). // ``` // // Elm // --- // // Setup: // Run `elm repl` to enter the interpreter. // // Code: // ```text // 3.0 // String.toFloat "3.0" // ``` // // Scala // ----- // // Setup: // Run `scala` to enter the interpreter. // // Code: // ```text // 3.0 // "3.0".toFloat // ``` // // Elixir // ------ // // Setup: // Run `iex` to enter the interpreter. // // Code: // ```text // 3.0; // String.to_float("3.0"); // ``` // // FORTRAN // ------- // // Setup: // Save to `main.f90` and run `gfortran -o main main.f90` // // Code: // ```text // program main // real :: x // character (len=30) :: word // word = "3." // read(word, *) x // print *, 3. // print *, x // end program main // ``` // // D // - // // Setup: // Save to `main.d` and run `dmd -run main.d` // // Code: // ```text // import std.conv; // import std.stdio; // // void main() // { // writeln(3.0); // writeln(to!double("3.0")); // } // ``` // // Coffeescript // ------------ // // Setup: // Run `coffee` to enter the interpreter. // // Code: // ```text // 3.0; // parseFloat("3.0"); // ``` // // Cobol // ----- // // Setup: // Save to `main.cbl` and run `cobc main.cbl` then `cobcrun main`. // // Code: // ```text // IDENTIFICATION DIVISION. // PROGRAM-ID. main. // // DATA DIVISION. // WORKING-STORAGE SECTION. // 01 R PIC X(20) VALUE "3.0". // 01 TOTAL USAGE IS COMP-2. // // PROCEDURE DIVISION. // COMPUTE TOTAL = FUNCTION NUMVAL(R). // Display 3.0. // Display TOTAL. // STOP RUN. // ``` // // F# // -- // // Setup: // Run `fsharpi` to enter the interpreter. // // Code: // ```text // printfn "%f" 3.0;; // let f = float "3.0";; // printfn "%f" f;; // ``` // // Visual Basic // ------------ // // Setup: // Save to `main.vb` and run `vbnc main.vb`. // // Code: // ```text // Imports System // // Module Module1 // Sub Main() // Console.WriteLine(Format$(3.0, "0.0000000000000")) // Console.WriteLine(Format$(CDbl("3.0"), "0.0000000000000")) // End Sub // End Module // ``` // // OCaml // ----- // // Setup: // Save to `main.ml` and run `ocamlc -o main main.ml`. // // Code: // ```text // Printf.printf "%f\n" 3.0 // let () = // let f = float_of_string "3.0" in // Printf.printf "%f\n" f // ``` // // Objective-C // ----------- // // Setup: // Save to `main.m` and run `gcc -o main -lobjc -lgnustep-base main.m -fconstant-string-class=NSConstantString`. // // Code: // ```text // #import // #import // // int main(int argv, char* argc[]) // { // printf("%f\n", 3.0); // NSString *s = @"3.0"; // double f = [s doubleValue]; // printf("%f\n", f); // } // ``` // // ReasonML // -------- // // Setup: // Run `rtop` to enter the interpreter. // // Code: // ```text // Printf.printf("%f\n", 3.0); // Printf.printf("%f\n", float_of_string("3.0")); // ``` // // Zig // --- // // Setup: // Save to `main.zig` and run `zig build-exe main.zig` // // Code: // ```text // const std = @import("std"); // // pub fn main() void { // const f: f64 = 3.0; // std.debug.warn("{}\n", f); // const x: f64 = std.fmt.parseFloat(f64, "3.0") catch unreachable; // std.debug.warn("{}\n", x); // } // ``` // // // Octave (and Matlab) // ------------------- // // Setup: // Run `octave` to enter the interpreter, or // run `octave --traditional` to enter the Matlab interpret. // // Code: // ```text // 3.0 // str2double("3.0") // ``` // // Sage // ---- // // Setup: // Run `sage` to enter the interpreter. // // Code: // ```text // 3.0 // float("3.0") // ``` // // JSON // ---- // // Setup: // Run `node` (or `nodejs`) to enter the JS interpreter. // // Code: // ```text // JSON.parse("3.0") // ``` // // TOML // ---- // // Setup: // Run `python` to enter the Python interpreter. // // Code: // ```text // import tomlkit // tomlkit.parse("a = 3.0") // ``` // // XML // --- // // Setup: // Run `python` to enter the Python interpreter. // // Code: // ```text // from lxml import etree // // def validate_xml(xsd, xml): // '''Validate XML file against schema''' // // schema = etree.fromstring(xsd) // doc = etree.fromstring(xml) // xmlschema = etree.XMLSchema(schema) // // return xmlschema.validate(doc) // // // xsd = b''' // // // ''' // // xml = b''' // 3.0 // ''' // // validate_xml(xsd, xml) // ``` // // SQLite // ------ // // Setup: // Run `sqlite3 :memory:` to enter the sqlite3 interpreter // with an in-memory database. // // Code: // ```text // CREATE TABLE stocks (price real); // INSERT INTO stocks VALUES (3.0); // SELECT * FROM stocks; // ``` // // PostgreSQL // ---------- // // Setup: // Run `initdb -D db` to create a database data direction, // then run `pg_ctl -D db start` to start the server, then run // `createdb` to create a user database and `psql` to start the // interpreter. // // Code: // ```text // CREATE TABLE stocks (price real); // INSERT INTO stocks VALUES (3.0); // SELECT * FROM stocks; // ``` // // MySQL // ----- // // Setup: // Run `mysqld` to start the server, then run `mysql` to start the // interpreter. // // Code: // ```text // USE mysql; // CREATE TABLE stocks (price real); // INSERT INTO stocks VALUES (3.0); // SELECT * FROM stocks; // ``` // // MongoDB // ------- // // Setup: // Run `mongod --dbpath data/db` to start the server, then run // `mongo` to start the interpreter. // // Code: // ```text // use mydb // db.movie.insert({"name": 3.0}) // db.movie.find() // ``` cfg_if! { if #[cfg(feature = "format")] { mod feature_format; pub use self::feature_format::*; } else { mod not_feature_format; pub use self::not_feature_format::*; } } lexical-core-0.7.6/src/util/index.rs000075500000000000000000000040600000000000000154060ustar 00000000000000//! Macro to facilitate indexing for unchecked variants. /// Macro to index without bounds checking. #[allow(unused_macros)] macro_rules! unchecked_index { // Get ($container:ident[$index:expr]) => ( * unsafe { $container.get_unchecked($index) } ); // Get ($obj:ident$(.$subobj:ident)*[$index:expr]) => ( * unsafe { $obj$(.$subobj)*.get_unchecked($index) } ); } /// Macro to mutably index without bounds checking. #[allow(unused_macros)] macro_rules! unchecked_index_mut { // Get ($container:ident[$index:expr]) => { * unsafe { $container.get_unchecked_mut($index) } }; // Set ($container:ident[$index:expr] = $rhs:expr) => ( unsafe { *$container.get_unchecked_mut($index) = $rhs } ); } /// Macro to index without bounds checking. #[cfg(feature = "unchecked_index")] macro_rules! index { // Get ($container:ident[$index:expr]) => ( * unsafe { $container.get_unchecked($index) } ); // Get ($obj:ident$(.$subobj:ident)*[$index:expr]) => ( * unsafe { $obj$(.$subobj)*.get_unchecked($index) } ); } /// Macro to mutably index without bounds checking. #[cfg(feature = "unchecked_index")] macro_rules! index_mut { // Get ($container:ident[$index:expr]) => ( * unsafe { $container.get_unchecked_mut($index) } ); // Set ($container:ident[$index:expr] = $rhs:expr) => ( unsafe { *$container.get_unchecked_mut($index) = $rhs } ); } /// Macro to index with bounds checking. #[cfg(not(feature = "unchecked_index"))] macro_rules! index { // Get ($container:ident[$index:expr]) => ( $container[$index] ); // Get ($obj:ident$(.$subobj:ident)*[$index:expr]) => ( $obj$(.$subobj)*[$index] ); } /// Macro to mutably index with bounds checking. #[cfg(not(feature = "unchecked_index"))] macro_rules! index_mut { // Get ($container:ident[$index:expr]) => ( $container[$index] ); // Set ($container:ident[$index:expr] = $rhs:expr) => ( $container[$index] = $rhs ); } lexical-core-0.7.6/src/util/iterator.rs000075500000000000000000000057070000000000000161410ustar 00000000000000//! Helper traits for iterators. use crate::lib::slice; #[cfg(feature = "format")] use super::skip_value::*; /// An iterator that knows if it has been fully consumed yet. /// /// A consumed iterator will guarantee to return `None` for the next /// value. It is effectively a weak variant of `is_empty()` on /// `ExactSizeIterator`. When the length of an iterator is known, /// `ConsumedIterator` will be implemented in terms of that length.. pub(crate) trait ConsumedIterator: Iterator { /// Return if the iterator has been consumed. fn consumed(&self) -> bool; } impl ConsumedIterator for T { #[inline] fn consumed(&self) -> bool { self.len() == 0 } } /// Get access to a raw, const pointer from the underlying data. /// /// A default implementation is provided for slice iterators. /// This trait **should never** return null, or be implemented /// for non-contiguous data. pub(crate) trait AsPtrIterator<'a, T: 'a>: Iterator { /// Get raw pointer from iterator state. fn as_ptr(&self) -> *const T; } impl<'a, T> AsPtrIterator<'a, T> for slice::Iter<'a, T> { #[inline] fn as_ptr(&self) -> *const T { self.as_slice().as_ptr() } } // Type for iteration without any digit separators. pub(crate) type IteratorNoSeparator<'a> = slice::Iter<'a, u8>; // Iterate without any skipping any digit separators. #[inline(always)] pub(crate) fn iterate_digits_no_separator<'a>(bytes: &'a [u8], _: u8) -> IteratorNoSeparator<'a> { bytes.iter() } // Type for iteration with a digit separator. #[cfg(feature = "format")] pub(crate) type IteratorSeparator<'a> = SkipValueIterator<'a, u8>; // Iterate while skipping digit separators. #[cfg(feature = "format")] #[inline(always)] pub(crate) fn iterate_digits_ignore_separator<'a>(bytes: &'a [u8], digit_separator: u8) -> IteratorSeparator<'a> { IteratorSeparator::new(bytes, digit_separator) } // TESTS // ----- #[cfg(test)] mod tests { use super::*; #[test] fn consumer_iterator_test() { let mut iter = b"12345".iter(); assert_eq!(iter.consumed(), false); assert_eq!(iter.nth(4).unwrap(), &b'5'); assert_eq!(iter.consumed(), true); } #[test] fn as_ptr_iterator_test() { let digits = b"12345"; let mut iter = digits.iter(); assert_eq!(iter.as_ptr(), digits.as_ptr()); assert_eq!(iter.nth(4).unwrap(), &b'5'); assert_eq!(iter.as_ptr(), digits[digits.len()..].as_ptr()); } #[test] fn iterate_digits_no_separator_test() { assert!(iterate_digits_no_separator(b"01", b'\x00').eq(b"01".iter())); assert!(iterate_digits_no_separator(b"01_01", b'_').eq(b"01_01".iter())); } #[test] #[cfg(feature = "format")] fn iterate_digits_ignore_separator_test() { assert!(iterate_digits_ignore_separator(b"01", b'_').eq(b"01".iter())); assert!(iterate_digits_ignore_separator(b"01_01", b'_').eq(b"0101".iter())); } } lexical-core-0.7.6/src/util/mask.rs000075500000000000000000000072050000000000000152360ustar 00000000000000//! Bit masks for extracting bits. use crate::lib::mem; use super::cast::as_cast; use super::num::UnsignedInteger; /// Generate a bitwise mask for the lower `n` bits. /// /// # Examples /// /// ```text /// # use lexical::util::lower_n_mask; /// # pub fn main() { /// lower_n_mask(2u32) -> b11u32; /// # } /// ``` #[inline] pub(crate) fn lower_n_mask(n: N) -> N where N:UnsignedInteger { let bits: N = as_cast(mem::size_of::() * 8); debug_assert!(n <= bits, "lower_n_mask() overflow in shl."); match n == bits { true => N::max_value(), false => (N::ONE << n) - N::ONE, } } /// Calculate the halfway point for the lower `n` bits. /// /// # Examples /// /// ```text /// # use lexical::util::lower_n_halfway; /// # pub fn main() { /// lower_n_halfway(2u32) -> b10u32; /// # } /// ``` #[inline] pub(crate) fn lower_n_halfway(n: N) -> N where N:UnsignedInteger { let bits: N = as_cast(mem::size_of::() * 8); debug_assert!(n <= bits, "lower_n_halfway() overflow in shl."); match n.is_zero() { true => N::ZERO, false => nth_bit(n - N::ONE), } } /// Calculate a scalar factor of 2 above the halfway point. /// /// # Examples /// /// ```text /// # use lexical::util::nth_bit; /// # pub fn main() { /// nth_bit(2u32) -> b100u32; /// # } /// ``` #[inline] pub(crate) fn nth_bit(n: N) -> N where N:UnsignedInteger { let bits: N = as_cast(N::BITS); debug_assert!(n < bits, "nth_bit() overflow in shl."); N::ONE << n } /// Calculate a bitwise mask with `n` 1 bits starting at the `bit` position. /// /// # Examples /// /// ```text /// # use lexical::util::internal_n_mask; /// # pub fn main() { /// internal_n_mask(4u32, 2u32) -> b1100u32; /// internal_n_mask(10u32, 2u32) -> 0b1100000000; /// # } /// ``` #[inline] pub(crate) fn internal_n_mask(bit: N, n: N) -> N where N:UnsignedInteger { let bits: N = as_cast(mem::size_of::() * 8); debug_assert!(bit <= bits, "internal_n_halfway() overflow in shl."); debug_assert!(n <= bits, "internal_n_halfway() overflow in shl."); debug_assert!(bit >= n, "internal_n_halfway() overflow in sub."); lower_n_mask(bit) ^ lower_n_mask(bit - n) } // TESTS // ----- #[cfg(test)] mod tests { use super::*; #[test] fn lower_n_mask_test() { assert_eq!(lower_n_mask(0u32), 0b0); assert_eq!(lower_n_mask(1u32), 0b1); assert_eq!(lower_n_mask(2u32), 0b11); assert_eq!(lower_n_mask(10u32), 0b1111111111); assert_eq!(lower_n_mask(32u32), 0b11111111111111111111111111111111); } #[test] fn lower_n_halfway_test() { assert_eq!(lower_n_halfway(0u32), 0b0); assert_eq!(lower_n_halfway(1u32), 0b1); assert_eq!(lower_n_halfway(2u32), 0b10); assert_eq!(lower_n_halfway(10u32), 0b1000000000); assert_eq!(lower_n_halfway(32u32), 0b10000000000000000000000000000000); } #[test] fn nth_bit_test() { assert_eq!(nth_bit(0u32), 0b1); assert_eq!(nth_bit(1u32), 0b10); assert_eq!(nth_bit(2u32), 0b100); assert_eq!(nth_bit(10u32), 0b10000000000); assert_eq!(nth_bit(31u32), 0b10000000000000000000000000000000); } #[test] fn internal_n_mask_test() { assert_eq!(internal_n_mask(1u32, 0u32), 0b0); assert_eq!(internal_n_mask(1u32, 1u32), 0b1); assert_eq!(internal_n_mask(2u32, 1u32), 0b10); assert_eq!(internal_n_mask(4u32, 2u32), 0b1100); assert_eq!(internal_n_mask(10u32, 2u32), 0b1100000000); assert_eq!(internal_n_mask(10u32, 4u32), 0b1111000000); assert_eq!(internal_n_mask(32u32, 4u32), 0b11110000000000000000000000000000); } } lexical-core-0.7.6/src/util/mod.rs000075500000000000000000000030260000000000000150570ustar 00000000000000//! Helper utilities for low-level features. // Fix a compiler bug that thinks `pow` isn't used. #![allow(unused_imports)] // Hide implementation details. #[macro_use] mod assert; #[macro_use] mod index; #[macro_use] mod perftools; #[macro_use] mod traits; #[cfg(test)] #[macro_use] pub(crate) mod test; // Hide implementation details. mod algorithm; mod cast; mod config; mod consume; mod div128; mod error; mod format; mod iterator; mod mask; mod num; mod primitive; mod pow; mod result; mod rounding; mod sign; mod table; #[cfg(feature = "format")] mod skip_value; cfg_if! { if #[cfg(feature = "correct")] { #[macro_use] mod sequence; } else { mod wrapped; }} // cfg_if // Publicly export everything with crate-visibility. pub(crate) use self::algorithm::*; pub(crate) use self::cast::*; pub(crate) use self::consume::*; pub(crate) use self::div128::*; pub(crate) use self::iterator::*; pub(crate) use self::mask::*; pub(crate) use self::primitive::*; pub(crate) use self::pow::*; pub(crate) use self::rounding::*; pub(crate) use self::sign::*; pub(crate) use self::table::*; #[cfg(feature = "format")] pub(crate) use self::skip_value::*; cfg_if! { if #[cfg(feature = "correct")] { pub(crate) use self::sequence::*; } else { pub(crate) use self::wrapped::*; }} // cfg_if // Publicly export config globally. pub use self::config::*; pub use self::error::*; pub use self::format::*; pub use self::num::*; pub use self::result::*; pub use self::traits::*; #[cfg(feature = "rounding")] pub use self::rounding::RoundingKind; lexical-core-0.7.6/src/util/num.rs000075500000000000000000001100200000000000000150700ustar 00000000000000//! Utilities for Rust numbers. // We have a lot of high-level casts that make the type-system work. // Don't delete them, fake they're being used. #![allow(dead_code)] pub(crate) use crate::lib::{f32, f64, mem}; use crate::lib::{fmt, iter, ops}; use super::cast::{AsCast, TryCast}; use super::config::*; use super::primitive::Primitive; // NUMBER /// Numerical type trait. #[doc(hidden)] pub trait Number: Primitive + // Iteration iter::Product + iter::Sum + // Operations ops::Add + ops::AddAssign + ops::Div + ops::DivAssign + ops::Mul + ops::MulAssign + ops::Rem + ops::RemAssign + ops::Sub + ops::SubAssign { /// Maximum number of bytes required to serialize a number to string. const FORMATTED_SIZE: usize; /// Maximum number of bytes required to serialize a number to a decimal string. const FORMATTED_SIZE_DECIMAL: usize; /// If the type can hold a signed (negative) value. const IS_SIGNED: bool; } macro_rules! number_impl { ($($t:tt $radix_size:ident $decimal_size:ident $is_signed:expr ; )*) => ($( impl Number for $t { const FORMATTED_SIZE: usize = $radix_size; const FORMATTED_SIZE_DECIMAL: usize = $decimal_size; const IS_SIGNED: bool = $is_signed; } )*) } number_impl! { u8 U8_FORMATTED_SIZE U8_FORMATTED_SIZE_DECIMAL false ; u16 U16_FORMATTED_SIZE U16_FORMATTED_SIZE_DECIMAL false ; u32 U32_FORMATTED_SIZE U32_FORMATTED_SIZE_DECIMAL false ; u64 U64_FORMATTED_SIZE U64_FORMATTED_SIZE_DECIMAL false ; u128 U128_FORMATTED_SIZE U128_FORMATTED_SIZE_DECIMAL false ; usize USIZE_FORMATTED_SIZE USIZE_FORMATTED_SIZE_DECIMAL false ; i8 I8_FORMATTED_SIZE I8_FORMATTED_SIZE_DECIMAL true ; i16 I16_FORMATTED_SIZE I16_FORMATTED_SIZE_DECIMAL true ; i32 I32_FORMATTED_SIZE I32_FORMATTED_SIZE_DECIMAL true ; i64 I64_FORMATTED_SIZE I64_FORMATTED_SIZE_DECIMAL true ; i128 I128_FORMATTED_SIZE I128_FORMATTED_SIZE_DECIMAL true ; isize ISIZE_FORMATTED_SIZE ISIZE_FORMATTED_SIZE_DECIMAL true ; f32 F32_FORMATTED_SIZE F32_FORMATTED_SIZE_DECIMAL true ; f64 F64_FORMATTED_SIZE F64_FORMATTED_SIZE_DECIMAL true ; } // INTEGER /// Defines a trait that supports integral operations. #[doc(hidden)] pub trait Integer: // Basic Number + Eq + Ord + // Display fmt::Octal + fmt::LowerHex + fmt::UpperHex + //Operations ops::BitAnd + ops::BitAndAssign + ops::BitOr + ops::BitOrAssign + ops::BitXor + ops::BitXorAssign + ops::Not + ops::Shl + ops::Shl + ops::Shl + ops::Shl + ops::Shl + ops::Shl + ops::Shl + ops::Shl + ops::Shl + ops::Shl + ops::Shl + ops::ShlAssign + ops::ShlAssign + ops::ShlAssign + ops::ShlAssign + ops::ShlAssign + ops::ShlAssign + ops::ShlAssign + ops::ShlAssign + ops::ShlAssign + ops::ShlAssign + ops::ShlAssign + ops::Shr + ops::Shr + ops::Shr + ops::Shr + ops::Shr + ops::Shr + ops::Shr + ops::Shr + ops::Shr + ops::Shr + ops::Shr + ops::ShrAssign + ops::ShrAssign + ops::ShrAssign + ops::ShrAssign + ops::ShrAssign + ops::ShrAssign + ops::ShrAssign + ops::ShrAssign + ops::ShrAssign + ops::ShrAssign + ops::ShrAssign { // CONSTANTS const ZERO: Self; const ONE: Self; const TWO: Self; const MAX: Self; const MIN: Self; const BITS: usize; // FUNCTIONS (INHERITED) fn max_value() -> Self; fn min_value() -> Self; fn count_ones(self) -> u32; fn count_zeros(self) -> u32; fn leading_zeros(self) -> u32; fn trailing_zeros(self) -> u32; fn pow(self, i: u32) -> Self; fn checked_add(self, i: Self) -> Option; fn checked_sub(self, i: Self) -> Option; fn checked_mul(self, i: Self) -> Option; fn checked_div(self, i: Self) -> Option; fn checked_rem(self, i: Self) -> Option; fn checked_neg(self) -> Option; fn checked_shl(self, i: u32) -> Option; fn checked_shr(self, i: u32) -> Option; fn wrapping_add(self, i: Self) -> Self; fn wrapping_sub(self, i: Self) -> Self; fn wrapping_mul(self, i: Self) -> Self; fn wrapping_div(self, i: Self) -> Self; fn wrapping_rem(self, i: Self) -> Self; fn wrapping_neg(self) -> Self; fn wrapping_shl(self, i: u32) -> Self; fn wrapping_shr(self, i: u32) -> Self; fn overflowing_add(self, i: Self) -> (Self, bool); fn overflowing_sub(self, i: Self) -> (Self, bool); fn overflowing_mul(self, i: Self) -> (Self, bool); fn overflowing_div(self, i: Self) -> (Self, bool); fn overflowing_rem(self, i: Self) -> (Self, bool); fn overflowing_neg(self) -> (Self, bool); fn overflowing_shl(self, i: u32) -> (Self, bool); fn overflowing_shr(self, i: u32) -> (Self, bool); fn saturating_add(self, i: Self) -> Self; fn saturating_sub(self, i: Self) -> Self; fn saturating_mul(self, i: Self) -> Self; /// Create literal zero. #[inline] fn zero() -> Self { Self::ZERO } /// Create literal one. #[inline] fn one() -> Self { Self::ONE } /// Create literal two. #[inline] fn two() -> Self { Self::TWO } /// Check if value is equal to zero. #[inline] fn is_zero(self) -> bool { self == Self::ZERO } /// Check if value is equal to one. #[inline] fn is_one(self) -> bool { self == Self::ONE } // OPERATIONS /// Get the fast ceiling of the quotient from integer division. /// Not safe, since the remainder can easily overflow. #[inline] fn ceil_divmod(self, y: Self) -> (Self, i32) { let q = self / y; let r = self % y; match r.is_zero() { true => (q, r.as_i32()), false => (q + Self::ONE, r.as_i32() - y.as_i32()) } } /// Get the fast ceiling of the quotient from integer division. /// Not safe, since the remainder can easily overflow. #[inline] fn ceil_div(self, y: Self) -> Self { self.ceil_divmod(y).0 } /// Get the fast ceiling modulus from integer division. /// Not safe, since the remainder can easily overflow. #[inline] fn ceil_mod(self, y: Self) -> i32 { self.ceil_divmod(y).1 } // PROPERTIES /// Get the number of bits in a value. #[inline] fn bit_length(self) -> u32 { Self::BITS as u32 - self.leading_zeros() } // TRY CAST OR MAX #[inline] fn try_u8_or_max(self) -> u8 { try_cast_or_max(self) } #[inline] fn try_u16_or_max(self) -> u16 { try_cast_or_max(self) } #[inline] fn try_u32_or_max(self) -> u32 { try_cast_or_max(self) } #[inline] fn try_u64_or_max(self) -> u64 { try_cast_or_max(self) } #[inline] fn try_u128_or_max(self) -> u128 { try_cast_or_max(self) } #[inline] fn try_usize_or_max(self) -> usize { try_cast_or_max(self) } #[inline] fn try_i8_or_max(self) -> i8 { try_cast_or_max(self) } #[inline] fn try_i16_or_max(self) -> i16 { try_cast_or_max(self) } #[inline] fn try_i32_or_max(self) -> i32 { try_cast_or_max(self) } #[inline] fn try_i64_or_max(self) -> i64 { try_cast_or_max(self) } #[inline] fn try_i128_or_max(self) -> i128 { try_cast_or_max(self) } #[inline] fn try_isize_or_max(self) -> isize { try_cast_or_max(self) } // TRY CAST OR MIN #[inline] fn try_u8_or_min(self) -> u8 { try_cast_or_min(self) } #[inline] fn try_u16_or_min(self) -> u16 { try_cast_or_min(self) } #[inline] fn try_u32_or_min(self) -> u32 { try_cast_or_min(self) } #[inline] fn try_u64_or_min(self) -> u64 { try_cast_or_min(self) } #[inline] fn try_u128_or_min(self) -> u128 { try_cast_or_min(self) } #[inline] fn try_usize_or_min(self) -> usize { try_cast_or_min(self) } #[inline] fn try_i8_or_min(self) -> i8 { try_cast_or_min(self) } #[inline] fn try_i16_or_min(self) -> i16 { try_cast_or_min(self) } #[inline] fn try_i32_or_min(self) -> i32 { try_cast_or_min(self) } #[inline] fn try_i64_or_min(self) -> i64 { try_cast_or_min(self) } #[inline] fn try_i128_or_min(self) -> i128 { try_cast_or_min(self) } #[inline] fn try_isize_or_min(self) -> isize { try_cast_or_min(self) } } macro_rules! integer_impl { ($($t:tt)*) => ($( impl Integer for $t { const ZERO: $t = 0; const ONE: $t = 1; const TWO: $t = 2; const MAX: $t = $t::max_value(); const MIN: $t = $t::min_value(); const BITS: usize = mem::size_of::<$t>() * 8; #[inline] fn max_value() -> Self { Self::MAX } #[inline] fn min_value() -> Self { Self::MIN } #[inline] fn count_ones(self) -> u32 { $t::count_ones(self) } #[inline] fn count_zeros(self) -> u32 { $t::count_zeros(self) } #[inline] fn leading_zeros(self) -> u32 { $t::leading_zeros(self) } #[inline] fn trailing_zeros(self) -> u32 { $t::trailing_zeros(self) } #[inline] fn pow(self, i: u32) -> Self { $t::pow(self, i) } #[inline] fn checked_add(self, i: Self) -> Option { $t::checked_add(self, i) } #[inline] fn checked_sub(self, i: Self) -> Option { $t::checked_sub(self, i) } #[inline] fn checked_mul(self, i: Self) -> Option { $t::checked_mul(self, i) } #[inline] fn checked_div(self, i: Self) -> Option { $t::checked_div(self, i) } #[inline] fn checked_rem(self, i: Self) -> Option { $t::checked_rem(self, i) } #[inline] fn checked_neg(self) -> Option { $t::checked_neg(self) } #[inline] fn checked_shl(self, i: u32) -> Option { $t::checked_shl(self,i) } #[inline] fn checked_shr(self, i: u32) -> Option { $t::checked_shr(self,i) } #[inline] fn wrapping_add(self, i: Self) -> Self { $t::wrapping_add(self, i) } #[inline] fn wrapping_sub(self, i: Self) -> Self { $t::wrapping_sub(self, i) } #[inline] fn wrapping_mul(self, i: Self) -> Self { $t::wrapping_mul(self, i) } #[inline] fn wrapping_div(self, i: Self) -> Self { $t::wrapping_div(self, i) } #[inline] fn wrapping_rem(self, i: Self) -> Self { $t::wrapping_rem(self, i) } #[inline] fn wrapping_neg(self) -> Self { $t::wrapping_neg(self) } #[inline] fn wrapping_shl(self, i: u32) -> Self { $t::wrapping_shl(self,i) } #[inline] fn wrapping_shr(self, i: u32) -> Self { $t::wrapping_shr(self,i) } #[inline] fn overflowing_add(self, i: Self) -> (Self, bool) { $t::overflowing_add(self, i) } #[inline] fn overflowing_sub(self, i: Self) -> (Self, bool) { $t::overflowing_sub(self, i) } #[inline] fn overflowing_mul(self, i: Self) -> (Self, bool) { $t::overflowing_mul(self, i) } #[inline] fn overflowing_div(self, i: Self) -> (Self, bool) { $t::overflowing_div(self, i) } #[inline] fn overflowing_rem(self, i: Self) -> (Self, bool) { $t::overflowing_rem(self, i) } #[inline] fn overflowing_neg(self) -> (Self, bool) { $t::overflowing_neg(self) } #[inline] fn overflowing_shl(self, i: u32) -> (Self, bool) { $t::overflowing_shl(self,i) } #[inline] fn overflowing_shr(self, i: u32) -> (Self, bool) { $t::overflowing_shr(self,i) } #[inline] fn saturating_add(self, i: Self) -> Self { $t::saturating_add(self, i) } #[inline] fn saturating_sub(self, i: Self) -> Self { $t::saturating_sub(self, i) } #[inline] fn saturating_mul(self, i: Self) -> Self { $t::saturating_mul(self, i) } } )*) } integer_impl! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } /// Unwrap or get T::max_value(). #[inline] pub(crate) fn unwrap_or_max(t: Option) -> T { t.unwrap_or(T::max_value()) } /// Unwrap or get T::min_value(). #[inline] pub(crate) fn unwrap_or_min(t: Option) -> T { t.unwrap_or(T::min_value()) } /// Try to convert to U, if not, return U::max_value(). #[inline] pub(crate) fn try_cast_or_max>(t: T) -> U { unwrap_or_max(TryCast::try_cast(t)) } /// Try to convert to U, if not, return U::min_value(). #[inline] pub(crate) fn try_cast_or_min>(t: T) -> U { unwrap_or_min(TryCast::try_cast(t)) } // SIGNED INTEGER /// Defines a trait that supports signed integral operations. #[doc(hidden)] pub trait SignedInteger: Integer + ops::Neg { // FUNCTIONS (INHERITED) fn checked_abs(self) -> Option; fn wrapping_abs(self) -> Self; fn overflowing_abs(self) -> (Self, bool); } macro_rules! signed_integer_impl { ($($t:tt)*) => ($( impl SignedInteger for $t { fn checked_abs(self) -> Option { $t::checked_abs(self) } fn wrapping_abs(self) -> Self { $t::wrapping_abs(self) } fn overflowing_abs(self) -> (Self, bool) { $t::overflowing_abs(self) } } )*) } signed_integer_impl! { i8 i16 i32 i64 i128 isize } // UNSIGNED INTEGER /// Defines a trait that supports unsigned integral operations. #[doc(hidden)] pub trait UnsignedInteger: Integer { /// Returns true if the least-significant bit is odd. #[inline] fn is_odd(self) -> bool { self & Self::ONE == Self::ONE } /// Returns true if the least-significant bit is even. #[inline] fn is_even(self) -> bool { !self.is_odd() } } macro_rules! unsigned_integer_impl { ($($t:ty)*) => ($( impl UnsignedInteger for $t {} )*) } unsigned_integer_impl! { u8 u16 u32 u64 u128 usize } // FLOAT /// Float information for native float types. #[doc(hidden)] pub trait Float: Number + ops::Neg { /// Unsigned type of the same size. type Unsigned: UnsignedInteger; // CONSTANTS const ZERO: Self; const ONE: Self; const TWO: Self; const MAX: Self; const MIN: Self; const INFINITY: Self; const NEG_INFINITY: Self; const NAN: Self; const BITS: usize; /// Bitmask for the sign bit. const SIGN_MASK: Self::Unsigned; /// Bitmask for the exponent, including the hidden bit. const EXPONENT_MASK: Self::Unsigned; /// Bitmask for the hidden bit in exponent, which is an implicit 1 in the fraction. const HIDDEN_BIT_MASK: Self::Unsigned; /// Bitmask for the mantissa (fraction), excluding the hidden bit. const MANTISSA_MASK: Self::Unsigned; // PROPERTIES /// Positive infinity as bits. const INFINITY_BITS: Self::Unsigned; /// Positive infinity as bits. const NEGATIVE_INFINITY_BITS: Self::Unsigned; /// Size of the significand (mantissa) without hidden bit. const MANTISSA_SIZE: i32; /// Bias of the exponet const EXPONENT_BIAS: i32; /// Exponent portion of a denormal float. const DENORMAL_EXPONENT: i32; /// Maximum exponent value in float. const MAX_EXPONENT: i32; // FUNCTIONS (INHERITED) // Re-export the to and from bits methods. fn abs(self) -> Self; fn ceil(self) -> Self; fn exp(self) -> Self; fn floor(self) -> Self; fn ln(self) -> Self; fn powi(self, n: i32) -> Self; fn powf(self, f: Self) -> Self; fn round(self) -> Self; fn to_bits(self) -> Self::Unsigned; fn from_bits(u: Self::Unsigned) -> Self; fn is_sign_positive(self) -> bool; fn is_sign_negative(self) -> bool; // FUNCTIONS /// Check if value is equal to zero. #[inline] fn is_zero(self) -> bool { // IEEE754 guarantees `+0.0 == -0.0`, and Rust respects this, // unlike some other languages. self == Self::ZERO } /// Check if value is equal to one. #[inline] fn is_one(self) -> bool { self == Self::ONE } /// Returns true if the float is a denormal. #[inline] fn is_denormal(self) -> bool { self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO } /// Returns true if the float is a NaN or Infinite. #[inline] fn is_special(self) -> bool { self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK } /// Returns true if the float is NaN. #[inline] fn is_nan(self) -> bool { self.is_special() && !(self.to_bits() & Self::MANTISSA_MASK).is_zero() } /// Returns true if the float is infinite. #[inline] fn is_inf(self) -> bool { self.is_special() && (self.to_bits() & Self::MANTISSA_MASK).is_zero() } /// Returns true if the float's least-significant mantissa bit is odd. #[inline] fn is_odd(self) -> bool { self.to_bits().is_odd() } /// Returns true if the float's least-significant mantissa bit is even. #[inline] fn is_even(self) -> bool { !self.is_odd() } /// Get exponent component from the float. #[inline] fn exponent(self) -> i32 { if self.is_denormal() { return Self::DENORMAL_EXPONENT; } let bits = self.to_bits(); let biased_e: i32 = AsCast::as_cast((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE); biased_e - Self::EXPONENT_BIAS } /// Get mantissa (significand) component from float. #[inline] fn mantissa(self) -> Self::Unsigned { let bits = self.to_bits(); let s = bits & Self::MANTISSA_MASK; if !self.is_denormal() { s + Self::HIDDEN_BIT_MASK } else { s } } /// Get next greater float. #[inline] fn next(self) -> Self { let bits = self.to_bits(); if self.is_sign_negative() && self.is_zero() { // -0.0 Self::ZERO } else if bits == Self::INFINITY_BITS { Self::from_bits(Self::INFINITY_BITS) } else if self.is_sign_negative() { Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE)) } else { Self::from_bits(bits.saturating_add(Self::Unsigned::ONE)) } } /// Get next greater float for a positive float. /// Value must be >= 0.0 and < INFINITY. #[inline] fn next_positive(self) -> Self { debug_assert!(self.is_sign_positive() && !self.is_inf()); Self::from_bits(self.to_bits() + Self::Unsigned::ONE) } /// Get previous greater float, such that `self.prev().next() == self`. #[inline] fn prev(self) -> Self { let bits = self.to_bits(); if self.is_sign_positive() && self.is_zero() { // +0.0 -Self::ZERO } else if bits == Self::NEGATIVE_INFINITY_BITS { Self::from_bits(Self::NEGATIVE_INFINITY_BITS) } else if self.is_sign_negative() { Self::from_bits(bits.saturating_add(Self::Unsigned::ONE)) } else { Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE)) } } /// Get previous greater float for a positive float. /// Value must be > 0.0. #[inline] fn prev_positive(self) -> Self { debug_assert!(self.is_sign_positive() && !self.is_zero()); return Self::from_bits(self.to_bits() - Self::Unsigned::ONE); } /// Round a positive number to even. #[inline] fn round_positive_even(self) -> Self { if self.mantissa().is_odd() { self.next_positive() } else { self } } /// Get the max of two finite numbers. #[inline] fn max_finite(self, f: Self) -> Self { debug_assert!(!self.is_special() && !f.is_special(), "max_finite self={} f={}", self, f); if self < f { f } else { self } } /// Get the min of two finite numbers. #[inline] fn min_finite(self, f: Self) -> Self { debug_assert!(!self.is_special() && !f.is_special(), "min_finite self={} f={}", self, f); if self < f { self } else { f } } } /// Wrap float method for `std` and `no_std` context. macro_rules! float_method { ($f:ident, $t:tt, $meth:ident, $intr:ident, $libm:ident $(,$i:expr)*) => ({ #[cfg(feature = "std")] return $t::$meth($f $(,$i)*); #[cfg(all(not(feature = "std"), feature = "libm"))] return libm::$libm($f $(,$i)*); #[cfg(all(not(feature = "std"), not(feature = "libm")))] return unsafe { core::intrinsics::$intr($f $(,$i)*) }; }) } /// Wrap float method with special conditions for MSVC. /// /// This is because MSVC wraps these as inline functions, with no actual /// ABI for the LLVM intrinsic. macro_rules! float_method_msvc { ($f:ident, $ts:tt, $tl:tt, $meth:ident, $intr:ident, $libm:ident $(,$i:expr)*) => ({ #[cfg(feature = "std")] return $ts::$meth($f $(,$i)*); #[cfg(all(not(feature = "std"), feature = "libm"))] return libm::$libm($f $(,$i)*); #[cfg(all(not(feature = "std"), not(feature = "libm"), not(target_env = "msvc")))] return unsafe { core::intrinsics::$intr($f $(,$i)*) }; #[cfg(all(not(feature = "std"), not(feature = "libm"), target_env = "msvc"))] return $tl::$meth($f as $tl $(,$i as $tl)*) as $ts; }) } /// Wrap float log method for `no_std` context, with special conditions for Solaris. /// /// Solaris has a standard non-conforming log implementation, we need /// to wrap this cheaply. macro_rules! float_method_log_solaris { ($f:ident, $t:tt, $meth:ident, $intr:ident, $libm:ident $(,$i:expr)*) => ({ #[cfg(feature = "std")] return $t::$meth($f $(,$i)*); #[cfg(all(not(feature = "std"), feature = "libm"))] return libm::$libm($f $(,$i)*); #[cfg(all(not(feature = "std"), not(feature = "libm"), not(target_os = "solaris")))] return unsafe { core::intrinsics::$intr($f $(,$i)*) }; // Workaround for Solaris/Illumos due to log(-value) == -Inf, not NaN. #[cfg(all(not(feature = "std"), not(feature = "libm"), target_os = "solaris"))] { if $f.is_nan() { $f } else if $f.is_special() { if $f > $t::ZERO { $f } else { $t::NAN } } else if $f > $t::ZERO { unsafe { core::intrinsics::$intr($f $(,$i)*) } } else if $f.is_zero() { $t::NEG_INFINITY } else { $t::NAN } } }) } impl Float for f32 { type Unsigned = u32; const ZERO: f32 = 0.0; const ONE: f32 = 1.0; const TWO: f32 = 2.0; const MAX: f32 = f32::MAX; const MIN: f32 = f32::MIN; const INFINITY: f32 = f32::INFINITY; const NEG_INFINITY: f32 = f32::NEG_INFINITY; const NAN: f32 = f32::NAN; const BITS: usize = 32; const SIGN_MASK: u32 = 0x80000000; const EXPONENT_MASK: u32 = 0x7F800000; const HIDDEN_BIT_MASK: u32 = 0x00800000; const MANTISSA_MASK: u32 = 0x007FFFFF; const INFINITY_BITS: u32 = 0x7F800000; const NEGATIVE_INFINITY_BITS: u32 = Self::INFINITY_BITS | Self::SIGN_MASK; const MANTISSA_SIZE: i32 = 23; const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE; const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS; #[inline] fn abs(self) -> f32 { float_method!(self, f32, abs, fabsf32, fabsf) } #[inline] fn ceil(self) -> f32 { float_method_msvc!(self, f32, f64, ceil, ceilf32, ceilf) } #[inline] fn exp(self) -> f32 { float_method_msvc!(self, f32, f64, exp, expf32, expf) } #[inline] fn floor(self) -> f32 { float_method_msvc!(self, f32, f64, floor, floorf32, floorf) } #[inline] fn ln(self) -> f32 { float_method_msvc!(self, f32, f64, ln, logf32, logf) } #[inline] fn powi(self, n: i32) -> f32 { cfg_if! { if #[cfg(all(not(feature = "std"), feature = "libm"))] { self.powf(n as f32) } else { float_method!(self, f32, powi, powif32, powif, n) } } } #[inline] fn powf(self, n: f32) -> f32 { float_method_msvc!(self, f32, f64, powf, powf32, powf, n) } #[inline] fn round(self) -> f32 { float_method!(self, f32, round, roundf32, roundf) } #[inline] fn to_bits(self) -> u32 { f32::to_bits(self) } #[inline] fn from_bits(u: u32) -> f32 { f32::from_bits(u) } #[inline] fn is_sign_positive(self) -> bool { f32::is_sign_positive(self) } #[inline] fn is_sign_negative(self) -> bool { f32::is_sign_negative(self) } } impl Float for f64 { type Unsigned = u64; const ZERO: f64 = 0.0; const ONE: f64 = 1.0; const TWO: f64 = 2.0; const MAX: f64 = f64::MAX; const MIN: f64 = f64::MIN; const INFINITY: f64 = f64::INFINITY; const NEG_INFINITY: f64 = f64::NEG_INFINITY; const NAN: f64 = f64::NAN; const BITS: usize = 64; const SIGN_MASK: u64 = 0x8000000000000000; const EXPONENT_MASK: u64 = 0x7FF0000000000000; const HIDDEN_BIT_MASK: u64 = 0x0010000000000000; const MANTISSA_MASK: u64 = 0x000FFFFFFFFFFFFF; const INFINITY_BITS: u64 = 0x7FF0000000000000; const NEGATIVE_INFINITY_BITS: u64 = Self::INFINITY_BITS | Self::SIGN_MASK; const MANTISSA_SIZE: i32 = 52; const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE; const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS; #[inline] fn abs(self) -> f64 { float_method!(self, f64, abs, fabsf64, fabs) } #[inline] fn ceil(self) -> f64 { float_method!(self, f64, ceil, ceilf64, ceil) } #[inline] fn exp(self) -> f64 { float_method!(self, f64, exp, expf64, exp) } #[inline] fn floor(self) -> f64 { float_method!(self, f64, floor, floorf64, floor) } #[inline] fn ln(self) -> f64 { float_method_log_solaris!(self, f64, ln, logf64, log) } #[inline] fn powi(self, n: i32) -> f64 { cfg_if! { if #[cfg(all(not(feature = "std"), feature = "libm"))] { self.powf(n as f64) } else { float_method!(self, f64, powi, powif64, powi, n) } } } #[inline] fn powf(self, n: f64) -> f64 { float_method!(self, f64, powf, powf64, pow, n) } #[inline] fn round(self) -> f64 { float_method!(self, f64, round, roundf64, round) } #[inline] fn to_bits(self) -> u64 { f64::to_bits(self) } #[inline] fn from_bits(u: u64) -> f64 { f64::from_bits(u) } #[inline] fn is_sign_positive(self) -> bool { f64::is_sign_positive(self) } #[inline] fn is_sign_negative(self) -> bool { f64::is_sign_negative(self) } } // TEST // ---- #[cfg(test)] mod tests { use super::*; fn check_number(x: T, mut y: T) { // Copy, partialeq, partialord let _ = x; assert!(x < y); assert!(x != y); // Operations let _ = y + x; let _ = y - x; let _ = y * x; let _ = y / x; let _ = y % x; y += x; y -= x; y *= x; y /= x; y %= x; // Conversions already tested. } #[test] fn number_test() { check_number(1u8, 5); check_number(1u16, 5); check_number(1u32, 5); check_number(1u64, 5); check_number(1u128, 5); check_number(1usize, 5); check_number(1i8, 5); check_number(1i16, 5); check_number(1i32, 5); check_number(1i64, 5); check_number(1i128, 5); check_number(1isize, 5); check_number(1f32, 5.0); check_number(1f64, 5.0); } fn check_integer(mut x: T) { // Copy, partialeq, partialord, ord, eq let _ = x; assert!(x > T::ONE); assert!(x != T::ONE); assert_eq!(x.min(T::ONE), T::ONE); assert_eq!(x.max(T::ONE), x); // Operations let _ = x + T::ONE; let _ = x - T::ONE; let _ = x * T::ONE; let _ = x / T::ONE; let _ = x % T::ONE; x += T::ONE; x -= T::ONE; x *= T::ONE; x /= T::ONE; x %= T::ONE; // Bitwise operations let _ = x & T::ONE; let _ = x | T::ONE; let _ = x ^ T::ONE; let _ = !x; x &= T::ONE; x |= T::ONE; x ^= T::ONE; // Bitshifts let _ = x << 1u8; let _ = x << 1u16; let _ = x << 1u32; let _ = x << 1u64; let _ = x << 1usize; let _ = x << 1i8; let _ = x << 1i16; let _ = x << 1i32; let _ = x << 1i64; let _ = x << 1isize; let _ = x >> 1u8; let _ = x >> 1u16; let _ = x >> 1u32; let _ = x >> 1u64; let _ = x >> 1usize; let _ = x >> 1i8; let _ = x >> 1i16; let _ = x >> 1i32; let _ = x >> 1i64; let _ = x >> 1isize; x <<= 1u8; x <<= 1u16; x <<= 1u32; x <<= 1u64; x <<= 1usize; x <<= 1i8; x <<= 1i16; x <<= 1i32; x <<= 1i64; x <<= 1isize; x >>= 1u8; x >>= 1u16; x >>= 1u32; x >>= 1u64; x >>= 1usize; x >>= 1i8; x >>= 1i16; x >>= 1i32; x >>= 1i64; x >>= 1isize; // Functions assert!(T::ZERO.is_zero()); assert!(!T::ONE.is_zero()); assert!(T::ONE.is_one()); assert!(!T::ZERO.is_one()); // Conversions already tested. } #[test] fn integer_test() { check_integer(65u8); check_integer(65u16); check_integer(65u32); check_integer(65u64); check_integer(65u128); check_integer(65usize); check_integer(65i8); check_integer(65i16); check_integer(65i32); check_integer(65i64); check_integer(65i128); check_integer(65isize); } #[test] fn ceil_divmod_test() { assert_eq!(5usize.ceil_divmod(7), (1, -2)); assert_eq!(0usize.ceil_divmod(7), (0, 0)); assert_eq!(35usize.ceil_divmod(7), (5, 0)); assert_eq!(36usize.ceil_divmod(7), (6, -6)); } #[test] fn unwrap_or_max_test() { let x: Option = None; assert_eq!(unwrap_or_max(x), u8::max_value()); let x: Option = Some(1); assert_eq!(unwrap_or_max(x), 1); } #[test] fn unwrap_or_min_test() { let x: Option = None; assert_eq!(unwrap_or_min(x), u8::min_value()); let x: Option = Some(1); assert_eq!(unwrap_or_min(x), 1); } #[test] fn try_cast_or_max_test() { let x: u8 = try_cast_or_max(u16::min_value()); assert_eq!(x, u8::min_value()); let x: u8 = try_cast_or_max(u8::max_value() as u16); assert_eq!(x, u8::max_value()); let x: u8 = try_cast_or_max(u16::max_value()); assert_eq!(x, u8::max_value()); } #[test] fn try_cast_or_min_test() { let x: u8 = try_cast_or_min(u16::min_value()); assert_eq!(x, u8::min_value()); let x: u8 = try_cast_or_min(u8::max_value() as u16); assert_eq!(x, u8::max_value()); let x: u8 = try_cast_or_min(u16::max_value()); assert_eq!(x, u8::min_value()); } fn check_float(mut x: T) { // Copy, partialeq, partialord let _ = x; assert!(x > T::ONE); assert!(x != T::ONE); // Operations let _ = x + T::ONE; let _ = x - T::ONE; let _ = x * T::ONE; let _ = x / T::ONE; let _ = x % T::ONE; let _ = -x; x += T::ONE; x -= T::ONE; x *= T::ONE; x /= T::ONE; x %= T::ONE; // Check functions let _ = x.abs(); let _ = x.ceil(); let _ = x.exp(); let _ = x.floor(); let _ = x.ln(); let _ = x.powi(5); let _ = x.powf(T::ONE); let _ = x.round(); let _ = x.to_bits(); assert_eq!(T::from_bits(x.to_bits()), x); let _ = x.is_sign_positive(); let _ = x.is_sign_negative(); // Check properties let _ = x.to_bits() & T::SIGN_MASK; let _ = x.to_bits() & T::EXPONENT_MASK; let _ = x.to_bits() & T::HIDDEN_BIT_MASK; let _ = x.to_bits() & T::MANTISSA_MASK; assert!(T::from_bits(T::INFINITY_BITS).is_special()); } #[test] fn float_test() { check_float(123f32); check_float(123f64); // b00000000000000000000000000000001 let f: f32 = 1e-45; assert!(f.is_odd()); assert!(f.next().is_even()); assert!(f.next_positive().is_even()); assert!(f.prev().is_even()); assert!(f.prev_positive().is_even()); assert!(f.round_positive_even().is_even()); assert_eq!(f.prev().next(), f); assert_eq!(f.prev_positive().next_positive(), f); assert_eq!(f.round_positive_even(), f.next()); // b00111101110011001100110011001101 let f: f32 = 0.1; assert!(f.is_odd()); assert!(f.next().is_even()); assert!(f.next_positive().is_even()); assert!(f.prev().is_even()); assert!(f.prev_positive().is_even()); assert!(f.round_positive_even().is_even()); assert_eq!(f.prev().next(), f); assert_eq!(f.prev_positive().next_positive(), f); assert_eq!(f.round_positive_even(), f.next()); // b01000000000000000000000000000000 let f: f32 = 1.0; assert!(f.is_even()); assert!(f.next().is_odd()); assert!(f.next_positive().is_odd()); assert!(f.prev().is_odd()); assert!(f.prev_positive().is_odd()); assert!(f.round_positive_even().is_even()); assert_eq!(f.prev().next(), f); assert_eq!(f.prev_positive().next_positive(), f); assert_ne!(f.round_positive_even(), f.next()); } } lexical-core-0.7.6/src/util/perftools.rs000075500000000000000000000010320000000000000163100ustar 00000000000000//! Macros to simple performance profiling using perftools. /// Only inline when not profiling. macro_rules! perftools_inline { ($($item:tt)*) => ( #[cfg_attr(feature = "noinline", inline(never))] #[cfg_attr(not(feature = "noinline"), inline)] $($item)* ); } /// Only inline when not profiling. macro_rules! perftools_inline_always { ($($item:tt)*) => ( #[cfg_attr(feature = "noinline", inline(never))] #[cfg_attr(not(feature = "noinline"), inline(always))] $($item)* ) } lexical-core-0.7.6/src/util/pow.rs000075500000000000000000000305460000000000000151140ustar 00000000000000//! FLoating point power utilities. use super::cast::*; use super::num::*; use super::table::*; // STABLE POWER mod private { use super::*; #[cfg(not(feature = "correct"))] pub(crate) trait StablePowerImpl: Float + ExactExponent { } #[cfg(feature = "correct")] pub(crate) trait StablePowerImpl: Float + ExactExponent + TablePower { } impl StablePowerImpl for f32 { } impl StablePowerImpl for f64 { } } /// Stable power implementations for increased numeric stability. pub(crate) trait StablePower: private::StablePowerImpl { // /// Calculate pow2 with numeric exponent. // #[cfg(any(test, not(feature = "imprecise")))] // fn pow2(self, exponent: i32) -> Self; // // /// Calculate base^n with numeric exponent and base. // #[cfg(any(test, not(feature = "imprecise")))] // fn pow(self, base: T, exponent: i32) -> Self; // ITERATIVE /// Get max exponent for `iterative_pow`. fn iterative_max(base: T) -> i32; /// Get exponent step for `iterative_pow`. fn iterative_step(base: T) -> i32; /// Calculate base^n iteratively for better numeric stability. #[inline] fn iterative_pow(self, base: T, exponent: i32) -> Self { let max = Self::iterative_max(base); if exponent > max { // Value is impossibly large, must be infinity. Self::INFINITY } else if exponent < -max { // Value is impossibly small, must be 0. Self::ZERO } else { self.iterative_pow_finite(base, exponent) } } /// Calculate base^n iteratively for a finite result. #[inline] fn iterative_pow_finite(mut self, base: T, mut exponent: i32) -> Self { let step = Self::iterative_step(base); let base: Self = as_cast(base); if exponent < 0 { // negative exponent, use division for numeric stability while exponent <= -step { exponent += step; self /= base.powi(step) } if exponent != 0 { self /= base.powi(-exponent) } self } else { // positive exponent while exponent >= step { exponent -= step; self *= base.powi(step) } if exponent != 0 { self *= base.powi(exponent) } self } } // POW2 /// Calculate a stable powi when the value is known to be >= -2*max && <= 2*max /// /// powi is not stable, even with exact values, at high or low exponents. /// However, doing it in 2 shots for exact values is exact. #[cfg(all(feature = "radix", not(feature = "correct")))] #[inline] fn pow2(self, exponent: i32) -> Self { let step: i32 = 75; if exponent > step { self * Self::TWO.powi(step) * Self::TWO.powi(exponent - step) } else if exponent < -step { self * Self::TWO.powi(-step) * Self::TWO.powi(exponent + step) } else { self * Self::TWO.powi(exponent) } } /// Calculate power of 2 using precalculated table. #[cfg(all(feature = "radix", feature = "correct"))] #[inline] fn pow2(self, exponent: i32) -> Self { self * Self::table_pow2(exponent) } // POW /// Calculate power of n using powi. #[cfg(not(feature = "correct"))] #[inline] fn pow(self, base: T, exponent: i32) -> Self { // Check the exponent is within bounds in debug builds. debug_assert!({ let (min, max) = Self::exponent_limit(base); exponent >= min && exponent <= max }); let base: Self = as_cast(base); self * base.powi(exponent) } /// Calculate power of n using precalculated table. #[cfg(feature = "correct")] #[inline] fn pow(self, base: T, exponent: i32) -> Self { // Check the exponent is within bounds in debug builds. debug_assert!({ let (min, max) = Self::exponent_limit(base); exponent >= min && exponent <= max }); if exponent > 0 { self * Self::table_pow(base, exponent) } else { self / Self::table_pow(base, -exponent) } } } // F32 impl StablePower for f32 { fn iterative_max(radix: T) -> i32 { // Cached max exponents. // Make sure the value is >= 2*log(1e45, radix), which guarantees the // value overflows or underflows. const MAX: [i32; 35] = [ 150, 100, 80, 70, 60, 60, 50, 50, 50, 50, 50, 50, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 30, 30, 30, 30, 30 ]; debug_assert_radix!(radix); let idx: usize = as_cast(radix.as_i32() - 2); MAX[idx] } fn iterative_step(radix: T) -> i32 { // Cached powers to get the desired exponent. // Make sure all values are < 1e25. const STEP: [i32; 35] = [ 90, 60, 50, 40, 40, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 ]; debug_assert_radix!(radix); let idx: usize = as_cast(radix.as_i32() - 2); STEP[idx] } } // F64 impl StablePower for f64 { fn iterative_max(radix: T) -> i32 { // Cached max exponents. // Make sure the value is >= 2*log(5e324, radix), which guarantees the // value overflows or underflows. const MAX: [i32; 35] = [ 2200, 1400, 1200, 1000, 900, 800, 750, 700, 650, 625, 625, 600, 575, 575, 550, 550, 525, 525, 500, 500, 500, 500, 475, 475, 475, 475, 450, 450, 450, 450, 450, 450, 425, 425, 425 ]; debug_assert_radix!(radix); MAX[radix.as_usize() - 2] } fn iterative_step(radix: T) -> i32 { // Cached powers to get the desired exponent. // Make sure all values are < 1e300. const STEP: [i32; 35] = [ 512, 512, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 ]; debug_assert_radix!(radix); STEP[radix.as_usize() - 2] } } // TEST // ---- #[cfg(test)] mod tests { use crate::util::test::*; use super::*; use approx::assert_relative_eq; #[test] fn f32_iterative_pow_finite_test() { assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, 38), 1e38, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, 30), 1e30, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, 25), 1e25, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, 20), 1e20, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, 15), 1e15, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, 10), 1e10, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, 5), 1e5, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, -5), 1e-5, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, -10), 1e-10, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, -15), 1e-15, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, -20), 1e-20, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, -25), 1e-25, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, -30), 1e-30, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, -38), 1e-38, max_relative=1e-6); assert_relative_eq!(f32::iterative_pow_finite(1.0, 10, -45), 1e-45, max_relative=1e-6); // overflow assert!(f32::iterative_pow_finite(1.0, 10, 39).is_infinite()); // underflow assert_eq!(f32::iterative_pow_finite(1.0, 10, -46), 0.0); } #[test] fn f32_iterative_pow_test() { assert_relative_eq!(f32::iterative_pow(1.0, 10, 10), 1e10, max_relative=1e-15); assert!(f32::iterative_pow(1.0, 10, 1000).is_infinite()); assert_eq!(f32::iterative_pow(1.0, 10, -1000), 0.0); // overflow assert!(f32::iterative_pow(1.0, 10, 39).is_infinite()); // underflow assert_eq!(f32::iterative_pow(1.0, 10, -46), 0.0); } #[test] fn f64_iterative_pow_finite_test() { assert_relative_eq!(f64::iterative_pow_finite(1.0, 10, 308), 1e308, max_relative=1e-15); assert_relative_eq!(f64::iterative_pow_finite(1.0, 10, 300), 1e300, max_relative=1e-15); assert_relative_eq!(f64::iterative_pow_finite(1.0, 10, 200), 1e200, max_relative=1e-15); assert_relative_eq!(f64::iterative_pow_finite(1.0, 10, 100), 1e100, max_relative=1e-15); assert_relative_eq!(f64::iterative_pow_finite(1.0, 10, 50), 1e50, max_relative=1e-15); assert_relative_eq!(f64::iterative_pow_finite(1.0, 10, -50), 1e-50, epsilon=1e-15); assert_relative_eq!(f64::iterative_pow_finite(1.0, 10, -100), 1e-100, epsilon=1e-15); assert_relative_eq!(f64::iterative_pow_finite(1.0, 10, -200), 1e-200, epsilon=1e-15); assert_relative_eq!(f64::iterative_pow_finite(1.0, 10, -300), 1e-300, epsilon=1e-15); assert_relative_eq!(f64::iterative_pow_finite(1.0, 10, -308), 1e-308, epsilon=1e-15); // This only affects armv6 and not armv7, but we'll skip this test // both, since `target_arch` does not differentiate between // the two. #[cfg(not(all(target_arch = "arm", not(target_feature = "v7"))))] assert_eq!(f64::iterative_pow_finite(5.0, 10, -324), 5e-324); // overflow assert!(f64::iterative_pow_finite(1.0, 10, 309).is_infinite()); // underflow assert_eq!(f64::iterative_pow_finite(1.0, 10, -325), 0.0); } #[test] fn f64_iterative_pow_test() { assert_relative_eq!(f64::iterative_pow(1.0, 10, 50), 1e50, max_relative=1e-15); assert!(f64::iterative_pow(1.0, 10, 1000).is_infinite()); assert_eq!(f64::iterative_pow(1.0, 10, -1000), 0.0); // overflow assert!(f64::iterative_pow(1.0, 10, 309).is_infinite()); // underflow assert_eq!(f64::iterative_pow(1.0, 10, -325), 0.0); } #[cfg(feature = "radix")] #[test] fn f32_pow2_test() { let (min, max) = f32::exponent_limit(2); for i in min+1..max+1 { assert_eq!(f32::pow2(1.0, i) / f32::pow2(1.0, i-1), 2.0); } for i in 1..max+1 { let f = f32::pow2(1.0, i); if f < u64::max_value() as f32 { assert_eq!((f as u64) as f32, f); } } } #[test] fn f32_pow_test() { // Only check positive, since negative values round during division. for b in BASE_POWN.iter().cloned() { let (_, max) = f32::exponent_limit(b); for i in 1..max+1 { let f = f32::pow(1.0, b, i); let p = f32::pow(1.0, b, i-1); assert_eq!(f / p, b as f32); if f < u64::max_value() as f32 { assert_eq!((f as u64) as f32, f); } } } } #[cfg(feature = "radix")] #[test] fn f64_pow2_test() { let (min, max) = f64::exponent_limit(2); for i in min+1..max+1 { let curr = f64::pow2(1.0, i); let prev = f64::pow2(1.0, i-1); assert_eq!(curr / prev, 2.0); } for i in 1..max+1 { let f = f64::pow2(1.0, i); if f < u64::max_value() as f64 { assert_eq!((f as u64) as f64, f); } } } #[test] fn f64_pow_test() { // Only check positive, since negative values round during division. for b in BASE_POWN.iter().cloned() { let (_, max) = f64::exponent_limit(b); for i in 1..max+1 { let f = f64::pow(1.0, b, i); let p = f64::pow(1.0, b, i-1); assert_eq!(f / p, b as f64); if f < u64::max_value() as f64 { assert_eq!((f as u64) as f64, f); } } } } } lexical-core-0.7.6/src/util/primitive.rs000075500000000000000000000132340000000000000163120ustar 00000000000000//! Utilities for Rust primitives. use crate::lib::fmt; use super::cast::{AsCast, TryCast}; /// Type that can be converted to primitive with `as`. pub trait AsPrimitive: Copy + PartialEq + PartialOrd + Send + Sync { fn as_u8(self) -> u8; fn as_u16(self) -> u16; fn as_u32(self) -> u32; fn as_u64(self) -> u64; fn as_u128(self) -> u128; fn as_usize(self) -> usize; fn as_i8(self) -> i8; fn as_i16(self) -> i16; fn as_i32(self) -> i32; fn as_i64(self) -> i64; fn as_i128(self) -> i128; fn as_isize(self) -> isize; fn as_f32(self) -> f32; fn as_f64(self) -> f64; } macro_rules! as_primitive { ($($t:ty)*) => ($( impl AsPrimitive for $t { #[inline] fn as_u8(self) -> u8 { self as u8 } #[inline] fn as_u16(self) -> u16 { self as u16 } #[inline] fn as_u32(self) -> u32 { self as u32 } #[inline] fn as_u64(self) -> u64 { self as u64 } #[inline] fn as_u128(self) -> u128 { self as u128 } #[inline] fn as_usize(self) -> usize { self as usize } #[inline] fn as_i8(self) -> i8 { self as i8 } #[inline] fn as_i16(self) -> i16 { self as i16 } #[inline] fn as_i32(self) -> i32 { self as i32 } #[inline] fn as_i64(self) -> i64 { self as i64 } #[inline] fn as_i128(self) -> i128 { self as i128 } #[inline] fn as_isize(self) -> isize { self as isize } #[inline] fn as_f32(self) -> f32 { self as f32 } #[inline] fn as_f64(self) -> f64 { self as f64 } } )*) } as_primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 } macro_rules! def_try_primitive { ($($t:ty)*) => ( /// Type that can be converted to primitive with `as`. pub trait TryPrimitive: AsCast + $(TryCast<$t> +)* { #[inline] fn try_u8(self) -> Option { self.try_cast() } #[inline] fn try_u16(self) -> Option { self.try_cast() } #[inline] fn try_u32(self) -> Option { self.try_cast() } #[inline] fn try_u64(self) -> Option { self.try_cast() } #[inline] fn try_u128(self) -> Option { self.try_cast() } #[inline] fn try_usize(self) -> Option { self.try_cast() } #[inline] fn try_i8(self) -> Option { self.try_cast() } #[inline] fn try_i16(self) -> Option { self.try_cast() } #[inline] fn try_i32(self) -> Option { self.try_cast() } #[inline] fn try_i64(self) -> Option { self.try_cast() } #[inline] fn try_i128(self) -> Option { self.try_cast() } #[inline] fn try_isize(self) -> Option { self.try_cast() } #[inline] fn try_f32(self) -> Option { self.try_cast() } #[inline] fn try_f64(self) -> Option { self.try_cast() } } ); } def_try_primitive!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64); macro_rules! try_primitive { ($($t:ty)*) => ($( impl TryPrimitive for $t {} )*) } try_primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 } // PRIMITIVE /// Primitive type trait (which all have static lifetimes). pub trait Primitive: 'static + fmt::Debug + fmt::Display + TryPrimitive {} macro_rules! primitive { ($($t:ty)*) => ($( impl Primitive for $t {} )*) } primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 } // TEST // ---- #[cfg(test)] mod tests { use super::*; fn check_as_primitive(t: T) { let _: u8 = t.as_u8(); let _: u16 = t.as_u16(); let _: u32 = t.as_u32(); let _: u64 = t.as_u64(); let _: u128 = t.as_u128(); let _: usize = t.as_usize(); let _: i8 = t.as_i8(); let _: i16 = t.as_i16(); let _: i32 = t.as_i32(); let _: i64 = t.as_i64(); let _: i128 = t.as_i128(); let _: isize = t.as_isize(); let _: f32 = t.as_f32(); let _: f64 = t.as_f64(); } #[test] fn as_primitive_test() { check_as_primitive(1u8); check_as_primitive(1u16); check_as_primitive(1u32); check_as_primitive(1u64); check_as_primitive(1u128); check_as_primitive(1usize); check_as_primitive(1i8); check_as_primitive(1i16); check_as_primitive(1i32); check_as_primitive(1i64); check_as_primitive(1i128); check_as_primitive(1isize); check_as_primitive(1f32); check_as_primitive(1f64); } } lexical-core-0.7.6/src/util/result.rs000075500000000000000000000010370000000000000156160ustar 00000000000000//! Parser result type. use crate::lib::result::Result as StdResult; use super::error::{Error, ErrorCode}; /// A specialized Result type for lexical operations. pub type Result = StdResult; /// Specialized error type for format parsers. pub(crate) type ParseError = (ErrorCode, *const u8); /// Specialized result type for format parsers. pub(crate) type ParseResult = StdResult; /// Type definition for result when testing parsing. #[cfg(test)] pub(crate) type ParseTestResult = StdResult; lexical-core-0.7.6/src/util/rounding.rs000075500000000000000000000040350000000000000161260ustar 00000000000000//! Rounding-scheme identifiers. #![allow(dead_code)] /// Rounding type for float-parsing. /// /// Defines the IEEE754 rounding scheme to be used during float parsing. /// In general, this should be set to `NearestTieEven`, the default /// recommended rounding scheme by IEEE754 for binary and decimal /// operations. /// /// # FFI /// /// For interfacing with FFI-code, this may be approximated by: /// ```text /// const int32_t NEAREST_TIE_EVEN = 0; /// const int32_t NEAREST_TIE_AWAY_ZERO = 1; /// const int32_t TOWARD_POSITIVE_INFINITY = 2; /// const int32_t TOWARD_NEGATIVE_INFINITY = 3; /// const int32_t TOWARD_ZERO = 4; /// ``` /// /// # Safety /// /// Assigning any value outside the range `[1-4]` to value of type /// RoundingKind may invoke undefined-behavior. #[repr(i32)] #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum RoundingKind { /// Round to the nearest, tie to even. NearestTieEven = 0, /// Round to the nearest, tie away from zero. NearestTieAwayZero = 1, /// Round toward positive infinity. TowardPositiveInfinity = 2, /// Round toward negative infinity. TowardNegativeInfinity = 3, /// Round toward zero. TowardZero = 4, // Hide the internal implementation details, for how we implement // TowardPositiveInfinity, TowardNegativeInfinity, and TowardZero. /// Round to increase the magnitude of the float. /// For example, for a negative number, this rounds to negative infinity, /// for a positive number, to positive infinity. #[doc(hidden)] Upward = -1, /// Round to decrease the magnitude of the float. /// This always rounds toward zero. #[doc(hidden)] Downward = -2, } /// Determine if we are rounding to the nearest value, then tying away. #[inline] pub(crate) fn is_nearest(kind: RoundingKind) -> bool { kind == RoundingKind::NearestTieEven || kind == RoundingKind::NearestTieAwayZero } /// Determine if we are rounding to the nearest value, then tying away. #[inline] pub(crate) fn is_toward(kind: RoundingKind) -> bool { !is_nearest(kind) } lexical-core-0.7.6/src/util/sequence.rs000075500000000000000000001150440000000000000161140ustar 00000000000000//! Helper traits for sequences. #![allow(dead_code)] use crate::lib::{cmp, iter, marker, mem, ops, ptr, slice}; use arrayvec; #[cfg(all(feature = "correct", feature = "radix"))] use crate::lib::Vec; // ARRVEC /// Macro to automate simplify the creation of an ArrayVec. #[macro_export] macro_rules! arrvec { // This only works if the ArrayVec is the same size as the input array. ($elem:expr; $n:expr) => ({ $crate::arrayvec::ArrayVec::from([$elem; $n]) }); // This just repeatedly calls `push`. I don't believe there's a concise way to count the number of expressions. ($($x:expr),*$(,)*) => ({ // Allow an unused mut variable, since if the sequence is empty, // the vec will never be mutated. #[allow(unused_mut)] { let mut vec = $crate::arrayvec::ArrayVec::new(); $(vec.push($x);)* vec } }); } // INSERT MANY /// Insert multiple elements at position `index`. /// /// Shifts all elements before index to the back of the iterator. /// It uses size hints to try to minimize the number of moves, /// however, it does not rely on them. We cannot internally allocate, so /// if we overstep the lower_size_bound, we have to do extensive /// moves to shift each item back incrementally. /// /// This implementation is adapted from [`smallvec`], which has a battle-tested /// implementation that has been revised for at least a security advisory /// warning. Smallvec is similarly licensed under an MIT/Apache dual license. /// /// [`smallvec`]: https://github.com/servo/rust-smallvec pub fn insert_many(vec: &mut V, index: usize, iterable: I) where V: VecLike, I: iter::IntoIterator { let mut iter = iterable.into_iter(); if index == vec.len() { return vec.extend(iter); } let (lower_size_bound, _) = iter.size_hint(); assert!(lower_size_bound <= core::isize::MAX as usize); // Ensure offset is indexable assert!(index + lower_size_bound >= index); // Protect against overflow let mut num_added = 0; let old_len = vec.len(); assert!(index <= old_len); unsafe { // Reserve space for `lower_size_bound` elements. vec.reserve(lower_size_bound); let start = vec.as_mut_ptr(); let ptr = start.add(index); // Move the trailing elements. ptr::copy(ptr, ptr.add(lower_size_bound), old_len - index); // In case the iterator panics, don't double-drop the items we just copied above. vec.set_len(0); let mut guard = DropOnPanic { start, skip: index..(index + lower_size_bound), len: old_len + lower_size_bound, }; while num_added < lower_size_bound { let element = match iter.next() { Some(x) => x, None => break, }; let cur = ptr.add(num_added); ptr::write(cur, element); guard.skip.start += 1; num_added += 1; } if num_added < lower_size_bound { // Iterator provided fewer elements than the hint. Move the tail backward. ptr::copy( ptr.add(lower_size_bound), ptr.add(num_added), old_len - index, ); } // There are no more duplicate or uninitialized slots, so the guard is not needed. vec.set_len(old_len + num_added); mem::forget(guard); } // Insert any remaining elements one-by-one. for element in iter { vec.insert(index + num_added, element); num_added += 1; } struct DropOnPanic { start: *mut T, skip: ops::Range, // Space we copied-out-of, but haven't written-to yet. len: usize, } impl Drop for DropOnPanic { fn drop(&mut self) { for i in 0..self.len { if !self.skip.contains(&i) { unsafe { ptr::drop_in_place(self.start.add(i)); } } } } } } // REMOVE_MANY /// Remove many elements from a vec-like container. /// /// Does not change the size of the vector, and may leak /// if the destructor panics. **Must** call `set_len` after, /// and ideally before (to 0). fn remove_many(vec: &mut V, range: R) where V: VecLike, R: ops::RangeBounds { // Get the bounds on the items we're removing. let len = vec.len(); let start = match range.start_bound() { ops::Bound::Included(&n) => n, ops::Bound::Excluded(&n) => n + 1, ops::Bound::Unbounded => 0, }; let end = match range.end_bound() { ops::Bound::Included(&n) => n + 1, ops::Bound::Excluded(&n) => n, ops::Bound::Unbounded => len, }; assert!(start <= end); assert!(end <= len); // Drop the existing items. unsafe { // Set len temporarily to the start, in case we panic on a drop. // This means we leak memory, but we don't allow any double freeing, // or use after-free. vec.set_len(start); // Iteratively drop the range. let mut first = vec.as_mut_ptr().add(start); let last = vec.as_mut_ptr().add(end); while first < last { ptr::drop_in_place(first); first = first.add(1); } // Now we need to copy the end range into the buffer. let count = len - end; if count != 0 { let src = vec.as_ptr().add(end); let dst = vec.as_mut_ptr().add(start); ptr::copy(src, dst, count); } // Set the proper length, now that we've moved items in. vec.set_len(start + count); } } // HELPERS // ------- // RSLICE INDEX /// A trait for reversed-indexing operations. pub trait RSliceIndex { /// Output type for the index. type Output: ?Sized; /// Get reference to element or subslice. fn rget(self, slc: &T) -> Option<&Self::Output>; /// Get mutable reference to element or subslice. fn rget_mut(self, slc: &mut T) -> Option<&mut Self::Output>; /// Get reference to element or subslice without bounds checking. unsafe fn rget_unchecked(self, slc: &T) -> &Self::Output; /// Get mutable reference to element or subslice without bounds checking. unsafe fn rget_unchecked_mut(self, slc: &mut T) -> &mut Self::Output; /// Get reference to element or subslice, panic if out-of-bounds. fn rindex(self, slc: &T) -> &Self::Output; /// Get mutable reference to element or subslice, panic if out-of-bounds. fn rindex_mut(self, slc: &mut T) -> &mut Self::Output; } impl RSliceIndex<[T]> for usize { type Output = T; #[inline] fn rget(self, slc: &[T]) -> Option<&T> { let len = slc.len(); slc.get(len - self - 1) } #[inline] fn rget_mut(self, slc: &mut [T]) -> Option<&mut T> { let len = slc.len(); slc.get_mut(len - self - 1) } #[inline] unsafe fn rget_unchecked(self, slc: &[T]) -> &T { let len = slc.len(); slc.get_unchecked(len - self - 1) } #[inline] unsafe fn rget_unchecked_mut(self, slc: &mut [T]) -> &mut T { let len = slc.len(); slc.get_unchecked_mut(len - self - 1) } #[inline] fn rindex(self, slc: &[T]) -> &T { let len = slc.len(); &(*slc)[len - self - 1] } #[inline] fn rindex_mut(self, slc: &mut [T]) -> &mut T { let len = slc.len(); &mut (*slc)[len - self - 1] } } /// REVERSE VIEW /// Reverse, immutable view of a sequence. pub struct ReverseView<'a, T: 'a> { inner: &'a [T], } impl<'a, T> ops::Index for ReverseView<'a, T> { type Output = T; #[inline] fn index(&self, index: usize) -> &T { self.inner.rindex(index) } } /// REVERSE VIEW MUT /// Reverse, mutable view of a sequence. pub struct ReverseViewMut<'a, T: 'a> { inner: &'a mut [T], } impl<'a, T: 'a> ops::Index for ReverseViewMut<'a, T> { type Output = T; #[inline] fn index(&self, index: usize) -> &T { self.inner.rindex(index) } } impl<'a, T: 'a> ops::IndexMut for ReverseViewMut<'a, T> { #[inline] fn index_mut(&mut self, index: usize) -> &mut T { self.inner.rindex_mut(index) } } // SLICELIKE /// Implied base trait for slice-like types. /// /// Used to provide specializations since it requires no generic function parameters. pub trait SliceLikeImpl { // AS SLICE /// Get slice of immutable elements. fn as_slice(&self) -> &[T]; /// Get slice of mutable elements. fn as_mut_slice(&mut self) -> &mut [T]; } impl SliceLikeImpl for [T] { // AS SLICE #[inline] fn as_slice(&self) -> &[T] { self } #[inline] fn as_mut_slice(&mut self) -> &mut [T] { self } } #[cfg(all(feature = "correct", feature = "radix"))] impl SliceLikeImpl for Vec { // AS SLICE #[inline] fn as_slice(&self) -> &[T] { Vec::as_slice(self) } #[inline] fn as_mut_slice(&mut self) -> &mut [T] { Vec::as_mut_slice(self) } } impl SliceLikeImpl for arrayvec::ArrayVec { // AS SLICE #[inline] fn as_slice(&self) -> &[A::Item] { arrayvec::ArrayVec::as_slice(self) } #[inline] fn as_mut_slice(&mut self) -> &mut [A::Item] { arrayvec::ArrayVec::as_mut_slice(self) } } /// Collection that has a `contains()` method. pub trait Contains { /// Check if slice contains element. fn contains(&self, x: &T) -> bool; } impl Contains for dyn SliceLikeImpl { #[inline] fn contains(&self, x: &T) -> bool { <[T]>::contains(self.as_slice(), x) } } /// Collection that has a `starts_with()` method. pub trait StartsWith { /// Check if slice starts_with subslice. fn starts_with(&self, x: &[T]) -> bool; } impl StartsWith for dyn SliceLikeImpl { #[inline] fn starts_with(&self, x: &[T]) -> bool { <[T]>::starts_with(self.as_slice(), x) } } /// Collection that has a `ends_with()` method. pub trait EndsWith { /// Check if slice ends_with subslice. fn ends_with(&self, x: &[T]) -> bool; } impl EndsWith for dyn SliceLikeImpl { #[inline] fn ends_with(&self, x: &[T]) -> bool { <[T]>::ends_with(self.as_slice(), x) } } /// Collection that has a `binary_search()` method. pub trait BinarySearch { /// Perform binary search for value. fn binary_search(&self, x: &T) -> Result; } impl BinarySearch for dyn SliceLikeImpl { #[inline] fn binary_search(&self, x: &T) -> Result { <[T]>::binary_search(self.as_slice(), x) } } /// Collection that has a `sort()` method. pub trait Sort { // TODO(ahuszagh) Currently bugged on no_std. ///// Sort sequence. //fn sort(&mut self); } impl Sort for dyn SliceLikeImpl { // //#[inline] //fn sort(&mut self) { // <[T]>::sort(self.as_mut_slice()) //} } /// Collection that has a `sort_unstable()` method. pub trait SortUnstable { /// Sort sequence without preserving order of equal elements. fn sort_unstable(&mut self); } impl SortUnstable for dyn SliceLikeImpl { #[inline] fn sort_unstable(&mut self) { <[T]>::sort_unstable(self.as_mut_slice()) } } /// Collection that has a `clone_from_slice()` method. pub trait CloneFromSlice { /// Clone items from src into self. fn clone_from_slice(&mut self, src: &[T]); } impl CloneFromSlice for dyn SliceLikeImpl { #[inline] fn clone_from_slice(&mut self, src: &[T]) { <[T]>::clone_from_slice(self.as_mut_slice(), src) } } /// Collection that has a `copy_from_slice()` method. pub trait CopyFromSlice { /// Copy items from src into self. fn copy_from_slice(&mut self, src: &[T]); } impl CopyFromSlice for dyn SliceLikeImpl { #[inline] fn copy_from_slice(&mut self, src: &[T]) { <[T]>::copy_from_slice(self.as_mut_slice(), src) } } /// Slice-like container. pub trait SliceLike: SliceLikeImpl { // CORE // ---- // GET /// Get an immutable reference to item at index. fn get>(&self, index: I) -> Option<&I::Output>; /// Get a mutable reference to item at index. fn get_mut>(&mut self, index: I) -> Option<&mut I::Output>; /// Get an immutable reference to item at index. unsafe fn get_unchecked>(&self, index: I) -> &I::Output; /// Get a mutable reference to item at index. unsafe fn get_unchecked_mut>(&mut self, index: I) -> &mut I::Output; // INDEX /// Get immutable element(s) via indexing. fn index>(&self, index: I) -> &I::Output; /// Get mutable element(s) via indexing. fn index_mut>(&mut self, index: I) -> &mut I::Output; // RGET /// Get reference to element or subslice. fn rget>(&self, index: I) -> Option<&I::Output>; /// Get mutable reference to element or subslice. fn rget_mut>(&mut self, index: I) -> Option<&mut I::Output>; /// Get reference to element or subslice without bounds checking. unsafe fn rget_unchecked>(&self, index: I) -> &I::Output; /// Get mutable reference to element or subslice without bounds checking. unsafe fn rget_unchecked_mut>(&mut self, index: I) -> &mut I::Output; // RINDEX /// Get reference to element or subslice. fn rindex>(&self, index: I) -> &I::Output; /// Get mutable reference to element or subslice. fn rindex_mut>(&mut self, index: I) -> &mut I::Output; // DERIVATIVE // ---------- // AS PTR /// Get pointer to start of contiguous collection. #[inline] fn as_ptr(&self) -> *const T { <[T]>::as_ptr(self.as_slice()) } /// Get mutable pointer to start of contiguous collection. #[inline] fn as_mut_ptr(&mut self) -> *mut T { <[T]>::as_mut_ptr(self.as_mut_slice()) } // BINARY SEARCH BY /// Perform binary search with a predicate. #[inline] fn binary_search_by(&self, func: F) -> Result where F: FnMut(&T) -> cmp::Ordering { <[T]>::binary_search_by(self.as_slice(), func) } /// Perform binary search by key with key extractor. #[inline] fn binary_search_by_key(&self, key: &K, func: F) -> Result where K: Ord, F: FnMut(&T) -> K { <[T]>::binary_search_by_key(self.as_slice(), key, func) } // CHUNKS /// Get iterator over `size`-length immutable elements in sequence. #[inline] fn chunks(&self, size: usize) -> slice::Chunks { <[T]>::chunks(self.as_slice(), size) } /// Get iterator over `size`-length mutable elements in sequence. #[inline] fn chunks_mut(&mut self, size: usize) -> slice::ChunksMut { <[T]>::chunks_mut(self.as_mut_slice(), size) } // CHUNKS EXACT // Currently unused, restore and add default implementation if required // later. Requires rustc >= 1.31.0. // // /// Get iterator over exactly `size`-length immutable elements in sequence. // #[inline] // fn chunks_exact(&self, size: usize) -> slice::ChunksExact { // <[T]>::chunks_exact(self.as_slice(), size) // } // // /// Get iterator over exactly `size`-length mutable elements in sequence. // #[inline] // fn chunks_exact_mut(&mut self, size: usize) -> slice::ChunksExactMut { // <[T]>::chunks_exact_mut(self.as_mut_slice(), size) // } // FIRST /// Get an immutable reference to the first item. #[inline] fn first(&self) -> Option<&T> { self.as_slice().get(0) } /// Get a mutable reference to the first item. #[inline] fn first_mut(&mut self) -> Option<&mut T> { self.as_mut_slice().get_mut(0) } /// Get an immutable reference to the first item without bounds checking. #[inline] unsafe fn first_unchecked(&self) -> &T { self.as_slice().get_unchecked(0) } /// Get a mutable reference to the first item without bounds checking. #[inline] unsafe fn first_unchecked_mut(&mut self) -> &mut T { self.as_mut_slice().get_unchecked_mut(0) } // ITER /// Iterate over immutable elements in the collection. #[inline] fn iter(&self) -> slice::Iter { <[T]>::iter(self.as_slice()) } /// Iterate over mutable elements in the collection. #[inline] fn iter_mut(&mut self) -> slice::IterMut { <[T]>::iter_mut(self.as_mut_slice()) } // LAST /// Get an immutable reference to the last item. #[inline] fn last(&self) -> Option<&T> { self.rget(0) } /// Get a mutable reference to the last item. #[inline] fn last_mut(&mut self) -> Option<&mut T> { self.rget_mut(0) } /// Get an immutable reference to the last item without bounds checking. #[inline] unsafe fn last_unchecked(&self) -> &T { debug_assert!(self.len() > 0); self.rget_unchecked(0) } /// Get a mutable reference to the last item without bounds checking. #[inline] unsafe fn last_unchecked_mut(&mut self) -> &mut T { debug_assert!(self.len() > 0); self.rget_unchecked_mut(0) } // LEN /// Get if the collection is empty. #[inline] fn is_empty(&self) -> bool { <[T]>::is_empty(self.as_slice()) } /// Get the length of the collection. #[inline] fn len(&self) -> usize { <[T]>::len(self.as_slice()) } // Currently unused, restore and add default implementation if required // later. Requires rustc >= 1.31.0. // // RCHUNKS // // /// Get iterator over `size`-length immutable elements in sequence. // #[inline] // fn rchunks(&self, size: usize) -> slice::RChunks { // <[T]>::rchunks(self.as_slice(), size) // } // // /// Get iterator over `size`-length mutable elements in sequence. // #[inline] // fn rchunks_mut(&mut self, size: usize) -> slice::RChunksMut { // <[T]>::rchunks_mut(self.as_mut_slice(), size) // } // // // RCHUNKS EXACT // // /// Get iterator over exactly `size`-length immutable elements in sequence. // #[inline] // fn rchunks_exact(&self, size: usize) -> slice::RChunksExact { // <[T]>::rchunks_exact(self.as_slice(), size) // } // // /// Get iterator over exactly `size`-length mutable elements in sequence. // #[inline] // fn rchunks_exact_mut(&mut self, size: usize) -> slice::RChunksExactMut { // <[T]>::rchunks_exact_mut(self.as_mut_slice(), size) // } // REVERSE /// Reverse elements in collection. #[inline] fn reverse(&mut self) { <[T]>::reverse(self.as_mut_slice()) } // ROTATE // Currently unused, restore and add default implementation if required // later. Requires rustc >= 1.26.0. // /// Rotate elements of slice left. // #[inline] // fn rotate_left(&mut self, mid: usize) { // <[T]>::rotate_left(self.as_mut_slice(), mid) // } // // /// Rotate elements of slice right. // #[inline] // fn rotate_right(&mut self, mid: usize) { // <[T]>::rotate_right(self.as_mut_slice(), mid) // } // RSPLIT // Currently unused, restore and add default implementation if required // later. Requires rustc >= 1.27.0. // /// Split on condition into immutable subslices, start from the back of the slice. // #[inline] // fn rsplit bool>(&self, func: F) -> slice::RSplit { // <[T]>::rsplit(self.as_slice(), func) // } // // /// Split on condition into mutable subslices, start from the back of the slice. // #[inline] // fn rsplit_mut bool>(&mut self, func: F) -> slice::RSplitMut { // <[T]>::rsplit_mut(self.as_mut_slice(), func) // } // RSPLITN /// `rsplit()` with n subslices. #[inline] fn rsplitn bool>(&self, n: usize, func: F) -> slice::RSplitN { <[T]>::rsplitn(self.as_slice(), n, func) } /// `rsplit_mut()` with n subslices. #[inline] fn rsplitn_mut bool>(&mut self, n: usize, func: F) -> slice::RSplitNMut { <[T]>::rsplitn_mut(self.as_mut_slice(), n, func) } // SORT BY /// Perform sort with a predicate. #[inline] fn sort_by(&mut self, func: F) where F: FnMut(&T, &T) -> cmp::Ordering { <[T]>::sort_by(self.as_mut_slice(), func) } /// Perform sort by key with key extractor. #[inline] fn sort_by_key(&mut self, func: F) where K: Ord, F: FnMut(&T) -> K { <[T]>::sort_by_key(self.as_mut_slice(), func) } // SORT UNSTABLE BY /// Perform untable sort with a predicate. #[inline] fn sort_unstable_by(&mut self, func: F) where F: FnMut(&T, &T) -> cmp::Ordering { <[T]>::sort_unstable_by(self.as_mut_slice(), func) } /// Perform untable sort by key with key extractor. #[inline] fn sort_unstable_by_key(&mut self, func: F) where K: Ord, F: FnMut(&T) -> K { <[T]>::sort_unstable_by_key(self.as_mut_slice(), func) } // SPLIT /// Split on condition into immutable subslices, start from the front of the slice. #[inline] fn split bool>(&self, func: F) -> slice::Split { <[T]>::split(self.as_slice(), func) } /// Split on condition into mutable subslices, start from the front of the slice. #[inline] fn split_mut bool>(&mut self, func: F) -> slice::SplitMut { <[T]>::split_mut(self.as_mut_slice(), func) } // SPLIT AT /// Split at index, return immutable values for the values before and after. #[inline] fn split_at(&self, index: usize) -> (&[T], &[T]) { <[T]>::split_at(self.as_slice(), index) } /// Split at index, return immutable values for the values before and after. #[inline] fn split_at_mut(&mut self, index: usize) -> (&mut [T], &mut [T]) { <[T]>::split_at_mut(self.as_mut_slice(), index) } // SPLIT FIRST /// Split at first item, returning values or None if empty. #[inline] fn split_first(&self) -> Option<(&T, &[T])> { <[T]>::split_first(self.as_slice()) } /// Split at first item, returning values or None if empty. #[inline] fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> { <[T]>::split_first_mut(self.as_mut_slice()) } // SPLIT LAST /// Split at last item, returning values or None if empty. #[inline] fn split_last(&self) -> Option<(&T, &[T])> { <[T]>::split_last(self.as_slice()) } /// Split at last item, returning values or None if empty. #[inline] fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> { <[T]>::split_last_mut(self.as_mut_slice()) } // SPLIT N /// `split()` with n subslices. #[inline] fn splitn bool>(&self, n: usize, func: F) -> slice::SplitN { <[T]>::splitn(self.as_slice(), n, func) } /// `split_mut()` with n subslices. #[inline] fn splitn_mut bool>(&mut self, n: usize, func: F) -> slice::SplitNMut { <[T]>::splitn_mut(self.as_mut_slice(), n, func) } // SWAP /// Swap two elements in the container by index. #[inline] fn swap(&mut self, x: usize, y: usize) { <[T]>::swap(self.as_mut_slice(), x, y) } /// Swap all elements in `self` with `other`. #[inline] fn swap_with_slice(&mut self, other: &mut [T]) { <[T]>::swap_with_slice(self.as_mut_slice(), other) } // WINDOWS /// View windows of `n`-length contiguous subslices. #[inline] fn windows(&self, size: usize) -> slice::Windows { <[T]>::windows(self.as_slice(), size) } // RVIEW /// Create a reverse view of the vector for indexing. #[inline] fn rview<'a>(&'a self) -> ReverseView<'a, T> { ReverseView { inner: self.as_slice() } } /// Create a reverse, mutable view of the vector for indexing. #[inline] fn rview_mut<'a>(&'a mut self) -> ReverseViewMut<'a, T> { ReverseViewMut { inner: self.as_mut_slice() } } } impl SliceLike for [T] { // GET /// Get an immutable reference to item at index. #[inline] fn get>(&self, index: I) -> Option<&I::Output> { return <[T]>::get(self, index); } /// Get an mutable reference to item at index. #[inline] fn get_mut>(&mut self, index: I) -> Option<&mut I::Output> { return <[T]>::get_mut(self, index); } /// Get an immutable reference to item at index. #[inline] unsafe fn get_unchecked>(&self, index: I) -> &I::Output { return <[T]>::get_unchecked(self, index); } /// Get an mutable reference to item at index. #[inline] unsafe fn get_unchecked_mut>(&mut self, index: I) -> &mut I::Output { return <[T]>::get_unchecked_mut(self, index); } // INDEX #[inline] fn index>(&self, index: I) -> &I::Output { return <[T] as ops::Index>::index(self, index); } #[inline] fn index_mut>(&mut self, index: I) -> &mut I::Output { return <[T] as ops::IndexMut>::index_mut(self, index); } // RGET #[inline] fn rget>(&self, index: I) -> Option<&I::Output> { index.rget(self) } #[inline] fn rget_mut>(&mut self, index: I) -> Option<&mut I::Output> { index.rget_mut(self) } #[inline] unsafe fn rget_unchecked>(&self, index: I) -> &I::Output { index.rget_unchecked(self) } #[inline] unsafe fn rget_unchecked_mut>(&mut self, index: I) -> &mut I::Output { index.rget_unchecked_mut(self) } // RINDEX #[inline] fn rindex>(&self, index: I) -> &I::Output { index.rindex(self) } #[inline] fn rindex_mut>(&mut self, index: I) -> &mut I::Output { index.rindex_mut(self) } } #[cfg(all(feature = "correct", feature = "radix"))] impl SliceLike for Vec { // GET /// Get an immutable reference to item at index. #[inline] fn get>(&self, index: I) -> Option<&I::Output> { return self.as_slice().get(index); } /// Get an mutable reference to item at index. #[inline] fn get_mut>(&mut self, index: I) -> Option<&mut I::Output> { return self.as_mut_slice().get_mut(index); } /// Get an immutable reference to item at index. #[inline] unsafe fn get_unchecked>(&self, index: I) -> &I::Output { return self.as_slice().get_unchecked(index); } /// Get an mutable reference to item at index. #[inline] unsafe fn get_unchecked_mut>(&mut self, index: I) -> &mut I::Output { return self.as_mut_slice().get_unchecked_mut(index); } // INDEX #[inline] fn index>(&self, index: I) -> &I::Output { return self.as_slice().index(index); } #[inline] fn index_mut>(&mut self, index: I) -> &mut I::Output { return self.as_mut_slice().index_mut(index); } // RGET #[inline] fn rget>(&self, index: I) -> Option<&I::Output> { index.rget(self.as_slice()) } #[inline] fn rget_mut>(&mut self, index: I) -> Option<&mut I::Output> { index.rget_mut(self.as_mut_slice()) } #[inline] unsafe fn rget_unchecked>(&self, index: I) -> &I::Output { index.rget_unchecked(self.as_slice()) } #[inline] unsafe fn rget_unchecked_mut>(&mut self, index: I) -> &mut I::Output { index.rget_unchecked_mut(self.as_mut_slice()) } // RINDEX #[inline] fn rindex>(&self, index: I) -> &I::Output { index.rindex(self.as_slice()) } #[inline] fn rindex_mut>(&mut self, index: I) -> &mut I::Output { index.rindex_mut(self.as_mut_slice()) } } impl SliceLike for arrayvec::ArrayVec { // GET /// Get an immutable reference to item at index. #[inline] fn get>(&self, index: I) -> Option<&I::Output> { return self.as_slice().get(index); } /// Get an mutable reference to item at index. #[inline] fn get_mut>(&mut self, index: I) -> Option<&mut I::Output> { return self.as_mut_slice().get_mut(index); } /// Get an immutable reference to item at index. #[inline] unsafe fn get_unchecked>(&self, index: I) -> &I::Output { return self.as_slice().get_unchecked(index); } /// Get an mutable reference to item at index. #[inline] unsafe fn get_unchecked_mut>(&mut self, index: I) -> &mut I::Output { return self.as_mut_slice().get_unchecked_mut(index); } // INDEX #[inline] fn index>(&self, index: I) -> &I::Output { return self.as_slice().index(index); } #[inline] fn index_mut>(&mut self, index: I) -> &mut I::Output { return self.as_mut_slice().index_mut(index); } // RGET #[inline] fn rget>(&self, index: I) -> Option<&I::Output> { index.rget(self.as_slice()) } #[inline] fn rget_mut>(&mut self, index: I) -> Option<&mut I::Output> { index.rget_mut(self.as_mut_slice()) } #[inline] unsafe fn rget_unchecked>(&self, index: I) -> &I::Output { index.rget_unchecked(self.as_slice()) } #[inline] unsafe fn rget_unchecked_mut>(&mut self, index: I) -> &mut I::Output { index.rget_unchecked_mut(self.as_mut_slice()) } // RINDEX #[inline] fn rindex>(&self, index: I) -> &I::Output { index.rindex(self.as_slice()) } #[inline] fn rindex_mut>(&mut self, index: I) -> &mut I::Output { index.rindex_mut(self.as_mut_slice()) } } // VECTOR // ------ // VECLIKE /// Vector-like container. pub trait VecLike: Default + iter::FromIterator + iter::IntoIterator + ops::DerefMut + Extend + SliceLike { /// Create new, empty vector. fn new() -> Self; /// Create new, empty vector with preallocated, uninitialized storage. fn with_capacity(capacity: usize) -> Self; /// Get the capacity of the underlying storage. fn capacity(&self) -> usize; /// Reserve additional capacity for the collection. fn reserve(&mut self, capacity: usize); /// Reserve minimal additional capacity for the collection. fn reserve_exact(&mut self, additional: usize); /// Shrink capacity to fit data size. fn shrink_to_fit(&mut self); /// Truncate vector to new length, dropping any items after `len`. fn truncate(&mut self, len: usize); /// Set the buffer length (unsafe). unsafe fn set_len(&mut self, new_len: usize); /// Remove element from vector and return it, replacing it with the last item in the vector. fn swap_remove(&mut self, index: usize) -> T; /// Insert element at index, shifting all elements after. fn insert(&mut self, index: usize, element: T); /// Remove element from vector at index, shifting all elements after. fn remove(&mut self, index: usize) -> T; /// Append an element to the vector. fn push(&mut self, value: T); /// Pop an element from the end of the vector. fn pop(&mut self) -> Option; /// Clear the buffer fn clear(&mut self); /// Insert many elements at index, pushing everything else to the back. fn insert_many>(&mut self, index: usize, iterable: I); /// Remove many elements from range. fn remove_many>(&mut self, range: R); } #[cfg(all(feature = "correct", feature = "radix"))] impl VecLike for Vec { #[inline] fn new() -> Vec { Vec::new() } #[inline] fn with_capacity(capacity: usize) -> Vec { Vec::with_capacity(capacity) } #[inline] fn capacity(&self) -> usize { Vec::capacity(self) } #[inline] fn reserve(&mut self, capacity: usize) { Vec::reserve(self, capacity) } #[inline] fn reserve_exact(&mut self, capacity: usize) { Vec::reserve_exact(self, capacity) } #[inline] fn shrink_to_fit(&mut self) { Vec::shrink_to_fit(self) } #[inline] fn truncate(&mut self, len: usize) { Vec::truncate(self, len) } #[inline] unsafe fn set_len(&mut self, new_len: usize) { Vec::set_len(self, new_len); } #[inline] fn swap_remove(&mut self, index: usize) -> T { Vec::swap_remove(self, index) } #[inline] fn insert(&mut self, index: usize, element: T) { Vec::insert(self, index, element) } #[inline] fn remove(&mut self, index: usize) -> T { Vec::remove(self, index) } #[inline] fn push(&mut self, value: T) { Vec::push(self, value); } #[inline] fn pop(&mut self) -> Option { Vec::pop(self) } #[inline] fn clear(&mut self) { Vec::clear(self); } #[inline] fn insert_many>(&mut self, index: usize, iterable: I) { self.splice(index..index, iterable); } #[inline] fn remove_many>(&mut self, range: R) { remove_many(self, range) } } impl VecLike for arrayvec::ArrayVec { #[inline] fn new() -> arrayvec::ArrayVec { arrayvec::ArrayVec::new() } #[inline] fn with_capacity(capacity: usize) -> arrayvec::ArrayVec { let mut v = arrayvec::ArrayVec::new(); v.reserve(capacity); v } #[inline] fn capacity(&self) -> usize { arrayvec::ArrayVec::capacity(self) } #[inline] fn reserve(&mut self, capacity: usize) { assert!(self.len() + capacity <= self.capacity()); } #[inline] fn reserve_exact(&mut self, capacity: usize) { assert!(self.len() + capacity <= self.capacity()); } #[inline] fn shrink_to_fit(&mut self) { } #[inline] fn truncate(&mut self, len: usize) { arrayvec::ArrayVec::truncate(self, len) } #[inline] unsafe fn set_len(&mut self, new_len: usize) { arrayvec::ArrayVec::set_len(self, new_len); } #[inline] fn swap_remove(&mut self, index: usize) -> A::Item { arrayvec::ArrayVec::swap_remove(self, index) } #[inline] fn insert(&mut self, index: usize, element: A::Item) { arrayvec::ArrayVec::insert(self, index, element) } #[inline] fn remove(&mut self, index: usize) -> A::Item { arrayvec::ArrayVec::remove(self, index) } #[inline] fn push(&mut self, value: A::Item) { arrayvec::ArrayVec::push(self, value); } #[inline] fn pop(&mut self) -> Option { arrayvec::ArrayVec::pop(self) } #[inline] fn clear(&mut self) { arrayvec::ArrayVec::clear(self); } #[inline] fn insert_many>(&mut self, index: usize, iterable: I) { insert_many(self, index, iterable) } #[inline] fn remove_many>(&mut self, range: R) { remove_many(self, range) } } // CLONEABLE VECLIKE /// Vector-like container with cloneable values. /// /// Implemented for Vec, SmallVec, and StackVec. pub trait CloneableVecLike: Send + VecLike { /// Extend collection from slice. fn extend_from_slice(&mut self, other: &[T]); /// Resize container to new length, with a default value if adding elements. fn resize(&mut self, len: usize, value: T); } #[cfg(all(feature = "correct", feature = "radix"))] impl CloneableVecLike for Vec where T: Clone + Copy + Send { #[inline] fn extend_from_slice(&mut self, other: &[T]) { Vec::extend_from_slice(self, other) } #[inline] fn resize(&mut self, len: usize, value: T) { Vec::resize(self, len, value) } } impl CloneableVecLike for arrayvec::ArrayVec where A: Send, A::Index: Send, A::Item: Clone + Copy + Send { #[inline] fn extend_from_slice(&mut self, other: &[A::Item]) { self.extend(other.iter().cloned()) } #[inline] fn resize(&mut self, len: usize, value: A::Item) { assert!(len <= self.capacity()); let old_len = self.len(); if len > old_len { self.extend(iter::repeat(value).take(len - old_len)); } else { self.truncate(len); } } } // TESTS // ----- #[cfg(test)] mod tests { use super::*; #[test] fn test_insert_many() { type V = arrayvec::ArrayVec<[u8; 8]>; let mut v: V = V::new(); for x in 0..4 { v.push(x); } assert_eq!(v.len(), 4); v.insert_many(1, [5, 6].iter().cloned()); assert_eq!(&v[..], &[0, 5, 6, 1, 2, 3]); } #[cfg(all(feature = "correct", feature = "radix"))] #[test] fn remove_many_test() { let mut x = vec![0, 1, 2, 3, 4, 5]; x.remove_many(0..3); assert_eq!(x, vec![3, 4, 5]); assert_eq!(x.len(), 3); let mut x = vec![0, 1, 2, 3, 4, 5]; x.remove_many(..); assert_eq!(x, vec![]); let mut x = vec![0, 1, 2, 3, 4, 5]; x.remove_many(3..); assert_eq!(x, vec![0, 1, 2]); let mut x = vec![0, 1, 2, 3, 4, 5]; x.remove_many(..3); assert_eq!(x, vec![3, 4, 5]); } } lexical-core-0.7.6/src/util/sign.rs000075500000000000000000000206310000000000000152410ustar 00000000000000//! Enumerations for the sign-bit of a number. use super::format::NumberFormat; use super::num::Number; // ENUMERATION /// Enumeration for the sign of a a number. #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub enum Sign { /// Negative value. Negative, /// Positive value. Positive, } // HELPERS // Get if an option contains a digit separator. #[inline(always)] #[cfg(feature = "format")] fn is_digit_separator(option: Option<&u8>, digit_separator: u8) -> bool { option == Some(&digit_separator) } // Convert option of byte to option of sign. #[inline(always)] #[cfg(feature = "format")] fn to_sign(option: Option<&u8>) -> Option where T: Number { match option { Some(&b'+') => Some(Sign::Positive), Some(&b'-') if T::IS_SIGNED => Some(Sign::Negative), _ => None } } // PARSE /// Find and parse sign without any possible digit separators. #[inline(always)] pub(crate) fn parse_sign_no_separator<'a, T>(bytes: &'a [u8], _: u8) -> (Sign, &'a [u8]) where T: Number { match bytes.get(0) { Some(&b'+') => (Sign::Positive, &index!(bytes[1..])), Some(&b'-') if T::IS_SIGNED => (Sign::Negative, &index!(bytes[1..])), _ => (Sign::Positive, bytes) } } /// Find and parse sign with leading and consecutive digit separators. /// /// We need to consider the following possibilities: /// 1). _*[+-]\d+ #[inline(always)] #[cfg(feature = "format")] pub(crate) fn parse_sign_lc_separator<'a, T>(bytes: &'a [u8], digit_separator: u8) -> (Sign, &'a [u8]) where T: Number { let mut index = 0; while is_digit_separator(bytes.get(index), digit_separator) { index += 1; } if let Some(sign) = to_sign::(bytes.get(index)) { (sign, &index!(bytes[index+1..])) } else { (Sign::Positive, bytes) } } /// Find and parse sign with leading digit separators. /// /// We need to consider the following possibilities: /// 1). [+-]\d+ /// 2). _[+-]\d+ #[inline(always)] #[cfg(feature = "format")] pub(crate) fn parse_sign_l_separator<'a, T>(bytes: &'a [u8], digit_separator: u8) -> (Sign, &'a [u8]) where T: Number { let b0 = bytes.get(0); if let Some(sign) = to_sign::(b0) { (sign, &index!(bytes[1..])) } else if is_digit_separator(b0, digit_separator) { if let Some(sign) = to_sign::(bytes.get(1)) { (sign, &index!(bytes[2..])) } else { (Sign::Positive, bytes) } } else { (Sign::Positive, bytes) } } /// Find and parse sign with digit separators. #[inline(always)] #[cfg(feature = "format")] pub(crate) fn parse_sign_separator<'a, T>(bytes: &'a [u8], format: NumberFormat) -> (Sign, &'a [u8]) where T: Number { // If the integer cannot have leading digit separators, we know the sign // byte must by the first byte. Otherwise, we must consider digit separators // before the sign byte. let leading = format.integer_leading_digit_separator(); let consecutive = format.integer_consecutive_digit_separator(); match (leading, consecutive) { (true, true) => parse_sign_lc_separator::(bytes, format.digit_separator()), (true, false) => parse_sign_l_separator::(bytes, format.digit_separator()), (false, _) => parse_sign_no_separator::(bytes, format.digit_separator()) } } /// Find and parse sign. #[inline] pub(crate) fn parse_sign<'a, T>(bytes: &'a [u8], format: NumberFormat) -> (Sign, &'a [u8]) where T: Number { #[cfg(not(feature = "format"))] return parse_sign_no_separator::(bytes, format.digit_separator()); #[cfg(feature = "format")] return parse_sign_separator::(bytes, format); } // TESTS // ----- #[cfg(test)] mod tests { use super::*; use crate::util::test::*; #[test] fn parse_sign_no_separator_test() { // Signed assert_eq!(parse_sign_no_separator::(b"", b'_'), (Sign::Positive, b!(""))); assert_eq!(parse_sign_no_separator::(b"+", b'_'), (Sign::Positive, b!(""))); assert_eq!(parse_sign_no_separator::(b"-", b'_'), (Sign::Negative, b!(""))); assert_eq!(parse_sign_no_separator::(b"+5", b'_'), (Sign::Positive, b!("5"))); assert_eq!(parse_sign_no_separator::(b"-5", b'_'), (Sign::Negative, b!("5"))); assert_eq!(parse_sign_no_separator::(b"_-5", b'_'), (Sign::Positive, b!("_-5"))); assert_eq!(parse_sign_no_separator::(b"___-5", b'_'), (Sign::Positive, b!("___-5"))); // Unsigned assert_eq!(parse_sign_no_separator::(b"+5", b'_'), (Sign::Positive, b!("5"))); assert_eq!(parse_sign_no_separator::(b"-5", b'_'), (Sign::Positive, b!("-5"))); } #[test] #[cfg(feature = "format")] fn parse_sign_lc_separator_test() { assert_eq!(parse_sign_lc_separator::(b"", b'_'), (Sign::Positive, b!(""))); assert_eq!(parse_sign_lc_separator::(b"+", b'_'), (Sign::Positive, b!(""))); assert_eq!(parse_sign_lc_separator::(b"-", b'_'), (Sign::Negative, b!(""))); assert_eq!(parse_sign_lc_separator::(b"+5", b'_'), (Sign::Positive, b!("5"))); assert_eq!(parse_sign_lc_separator::(b"-5", b'_'), (Sign::Negative, b!("5"))); assert_eq!(parse_sign_lc_separator::(b"_-5", b'_'), (Sign::Negative, b!("5"))); assert_eq!(parse_sign_lc_separator::(b"___-5", b'_'), (Sign::Negative, b!("5"))); // Unsigned assert_eq!(parse_sign_lc_separator::(b"___+5", b'_'), (Sign::Positive, b!("5"))); assert_eq!(parse_sign_lc_separator::(b"___-5", b'_'), (Sign::Positive, b!("___-5"))); } #[test] #[cfg(feature = "format")] fn parse_sign_l_separator_test() { assert_eq!(parse_sign_l_separator::(b"", b'_'), (Sign::Positive, b!(""))); assert_eq!(parse_sign_l_separator::(b"+", b'_'), (Sign::Positive, b!(""))); assert_eq!(parse_sign_l_separator::(b"-", b'_'), (Sign::Negative, b!(""))); assert_eq!(parse_sign_l_separator::(b"+5", b'_'), (Sign::Positive, b!("5"))); assert_eq!(parse_sign_l_separator::(b"-5", b'_'), (Sign::Negative, b!("5"))); assert_eq!(parse_sign_l_separator::(b"_-5", b'_'), (Sign::Negative, b!("5"))); assert_eq!(parse_sign_l_separator::(b"___-5", b'_'), (Sign::Positive, b!("___-5"))); // Unsigned assert_eq!(parse_sign_l_separator::(b"_+5", b'_'), (Sign::Positive, b!("5"))); assert_eq!(parse_sign_l_separator::(b"_-5", b'_'), (Sign::Positive, b!("_-5"))); } #[test] #[cfg(feature = "format")] fn parse_sign_separator_test() { let format = NumberFormat::ignore(b'_').unwrap(); assert_eq!(parse_sign_separator::(b"", format), (Sign::Positive, b!(""))); assert_eq!(parse_sign_separator::(b"+", format), (Sign::Positive, b!(""))); assert_eq!(parse_sign_separator::(b"-", format), (Sign::Negative, b!(""))); assert_eq!(parse_sign_separator::(b"+5", format), (Sign::Positive, b!("5"))); assert_eq!(parse_sign_separator::(b"-5", format), (Sign::Negative, b!("5"))); assert_eq!(parse_sign_separator::(b"_-5", format), (Sign::Negative, b!("5"))); assert_eq!(parse_sign_separator::(b"___-5", format), (Sign::Negative, b!("5"))); // Unsigned assert_eq!(parse_sign_separator::(b"__+5", format), (Sign::Positive, b!("5"))); assert_eq!(parse_sign_separator::(b"__-5", format), (Sign::Positive, b!("__-5"))); } #[test] fn parse_sign_test() { let format = NumberFormat::standard().unwrap(); assert_eq!(parse_sign::(b"", format), (Sign::Positive, b!(""))); assert_eq!(parse_sign::(b"+", format), (Sign::Positive, b!(""))); assert_eq!(parse_sign::(b"-", format), (Sign::Negative, b!(""))); assert_eq!(parse_sign::(b"+5", format), (Sign::Positive, b!("5"))); assert_eq!(parse_sign::(b"-5", format), (Sign::Negative, b!("5"))); assert_eq!(parse_sign::(b"_-5", format), (Sign::Positive, b!("_-5"))); assert_eq!(parse_sign::(b"___-5", format), (Sign::Positive, b!("___-5"))); // Unsigned assert_eq!(parse_sign::(b"+5", format), (Sign::Positive, b!("5"))); assert_eq!(parse_sign::(b"-5", format), (Sign::Positive, b!("-5"))); } } lexical-core-0.7.6/src/util/skip_value.rs000075500000000000000000000051430000000000000164440ustar 00000000000000//! An iterator that skips values equal to a provided value. //! //! SkipValueIterator iterates over a slice, returning all values //! except for those matching the provided skip value. //! //! Example //! ------- //! //! ```text //! let iter = SkipValueIterator(&[1, 2, 5, 2, 6, 7], 2); //! assert!(iter.eq([1, 5, 6, 7].iter())); //! ``` use crate::lib::slice; use super::iterator::*; /// Slice iterator that skips characters matching a given value. pub(crate) struct SkipValueIterator<'a, T: 'a + PartialEq> { /// Slice iterator to wrap. iter: slice::Iter<'a, T>, /// Value to skip. skip: T } impl<'a, T: 'a + PartialEq> SkipValueIterator<'a, T> { #[inline] pub(crate) fn new(slc: &'a [T], skip: T) -> Self { SkipValueIterator { iter: slc.iter(), skip: skip } } } impl<'a, T: 'a + PartialEq + Clone> Clone for SkipValueIterator<'a, T> { #[inline] fn clone(&self) -> Self { SkipValueIterator { iter: self.iter.clone(), skip: self.skip.clone() } } } impl<'a, T: 'a + PartialEq> Iterator for SkipValueIterator<'a, T> { type Item = &'a T; #[inline] fn next(&mut self) -> Option { loop { let value = self.iter.next()?; if *value != self.skip { return Some(value); } } } } impl<'a, T: 'a + PartialEq> ConsumedIterator for SkipValueIterator<'a, T> { // Preconditions: The iterator cannot end with `skip` characters. // Use debug_assert to enforce this is removed successfully in test scenarios. #[inline] fn consumed(&self) -> bool { // This implementation is essentially a hack. // We rely on callers to ensure this is only ever called without // any trailing digit separators, otherwise, it will incorrectly // report if the iterator itself is consumed. debug_assert!(self.iter.as_slice().last() != Some(&self.skip)); self.iter.len() == 0 } } impl<'a, T: 'a + PartialEq> AsPtrIterator<'a, T> for SkipValueIterator<'a, T> { #[inline] fn as_ptr(&self) -> *const T { self.iter.as_slice().as_ptr() } } // TESTS // ----- #[cfg(test)] mod tests { use super::*; #[test] fn skip_value_test() { let slc = &[1, 2, 5, 2, 6, 7]; let iter = SkipValueIterator::new(slc, 2); assert!(iter.eq([1, 5, 6, 7].iter())); let iter = SkipValueIterator::new(slc, 5); assert!(iter.eq([1, 2, 2, 6, 7].iter())); let iter = SkipValueIterator::new(slc, 1); assert!(iter.eq([2, 5, 2, 6, 7].iter())); } } lexical-core-0.7.6/src/util/table.rs000075500000000000000000012206220000000000000153730ustar 00000000000000//! Cached tables for precalculated values. use crate::util::*; #[cfg(any(feature = "correct", feature = "format"))] use static_assertions::const_assert; /// Precalculated table for a digit to a character. /// /// Unoptimized table for radix N always, which translates a single digit to a /// character, and also useful for radix-N float encoding. const DIGIT_TO_CHAR: [u8; 36] = [b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O', b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', b'Z']; /// Get character from digit. #[inline(always)] #[allow(dead_code)] pub(crate) fn digit_to_char(digit: T) -> u8 { debug_assert!(digit.as_i32() >= 0 && digit.as_i32() < 36, "digit_to_char() invalid character."); index!(DIGIT_TO_CHAR[digit.as_usize()]) } // Conditionally compile the precompiled radix**2 tables. // These tables take `2 * (value % (radix^2))`, and return // two consecutive values corresponding to both digits. // // Total array storage: 32 KB. // Provides ~5x performance enhancement. // // These arrays are cache-friendly, for each BASE[2-36] table, // elements can be access sequentially 2-at-a-time, preventing as many // cache misses inside inner loops. For example, accessing the two elements // for a remainder of `3` for the radix^2 in radix 2 will give you `1` and `1`, // at indexes 6 and 7. cfg_if! { if #[cfg(feature = "table")] { pub(crate) const DIGIT_TO_BASE10_SQUARED: [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']; }} // cfg_if cfg_if! { if #[cfg(all(feature = "radix", feature = "table"))] { pub(crate) const DIGIT_TO_BASE2_SQUARED: [u8; 8] = [b'0', b'0', b'0', b'1', b'1', b'0', b'1', b'1']; pub(crate) const DIGIT_TO_BASE3_SQUARED: [u8; 18] = [b'0', b'0', b'0', b'1', b'0', b'2', b'1', b'0', b'1', b'1', b'1', b'2', b'2', b'0', b'2', b'1', b'2', b'2']; pub(crate) const DIGIT_TO_BASE4_SQUARED: [u8; 32] = [b'0', b'0', b'0', b'1', b'0', b'2', b'0', b'3', b'1', b'0', b'1', b'1', b'1', b'2', b'1', b'3', b'2', b'0', b'2', b'1', b'2', b'2', b'2', b'3', b'3', b'0', b'3', b'1', b'3', b'2', b'3', b'3']; pub(crate) const DIGIT_TO_BASE5_SQUARED: [u8; 50] = [b'0', b'0', b'0', b'1', b'0', b'2', b'0', b'3', b'0', b'4', b'1', b'0', b'1', b'1', b'1', b'2', b'1', b'3', b'1', b'4', b'2', b'0', b'2', b'1', b'2', b'2', b'2', b'3', b'2', b'4', b'3', b'0', b'3', b'1', b'3', b'2', b'3', b'3', b'3', b'4', b'4', b'0', b'4', b'1', b'4', b'2', b'4', b'3', b'4', b'4']; pub(crate) const DIGIT_TO_BASE6_SQUARED: [u8; 72] = [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'1', b'0', b'1', b'1', b'1', b'2', b'1', b'3', b'1', b'4', b'1', b'5', 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'3', b'0', b'3', b'1', b'3', b'2', b'3', b'3', b'3', b'4', b'3', b'5', 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'5', b'0', b'5', b'1', b'5', b'2', b'5', b'3', b'5', b'4', b'5', b'5']; pub(crate) const DIGIT_TO_BASE7_SQUARED: [u8; 98] = [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'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'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'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'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'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'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']; pub(crate) const DIGIT_TO_BASE8_SQUARED: [u8; 128] = [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'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'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'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'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'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'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'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']; pub(crate) const DIGIT_TO_BASE9_SQUARED: [u8; 162] = [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'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'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'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'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'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'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'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'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']; pub(crate) const DIGIT_TO_BASE11_SQUARED: [u8; 242] = [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'0', b'A', 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'1', b'A', 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'2', b'A', 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'3', b'A', 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'4', b'A', 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'5', b'A', 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'6', b'A', 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'7', b'A', 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'8', b'A', 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', b'9', b'A', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A']; pub(crate) const DIGIT_TO_BASE12_SQUARED: [u8; 288] = [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'0', b'A', b'0', b'B', 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'1', b'A', b'1', b'B', 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'2', b'A', b'2', b'B', 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'3', b'A', b'3', b'B', 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'4', b'A', b'4', b'B', 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'5', b'A', b'5', b'B', 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'6', b'A', b'6', b'B', 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'7', b'A', b'7', b'B', 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'8', b'A', b'8', b'B', 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', b'9', b'A', b'9', b'B', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B']; pub(crate) const DIGIT_TO_BASE13_SQUARED: [u8; 338] = [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'0', b'A', b'0', b'B', b'0', b'C', 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'1', b'A', b'1', b'B', b'1', b'C', 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'2', b'A', b'2', b'B', b'2', b'C', 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'3', b'A', b'3', b'B', b'3', b'C', 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'4', b'A', b'4', b'B', b'4', b'C', 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'5', b'A', b'5', b'B', b'5', b'C', 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'6', b'A', b'6', b'B', b'6', b'C', 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'7', b'A', b'7', b'B', b'7', b'C', 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'8', b'A', b'8', b'B', b'8', b'C', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C']; pub(crate) const DIGIT_TO_BASE14_SQUARED: [u8; 392] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D']; pub(crate) const DIGIT_TO_BASE15_SQUARED: [u8; 450] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E']; pub(crate) const DIGIT_TO_BASE16_SQUARED: [u8; 512] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F']; pub(crate) const DIGIT_TO_BASE17_SQUARED: [u8; 578] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G']; pub(crate) const DIGIT_TO_BASE18_SQUARED: [u8; 648] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H']; pub(crate) const DIGIT_TO_BASE19_SQUARED: [u8; 722] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I']; pub(crate) const DIGIT_TO_BASE20_SQUARED: [u8; 800] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J']; pub(crate) const DIGIT_TO_BASE21_SQUARED: [u8; 882] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K']; pub(crate) const DIGIT_TO_BASE22_SQUARED: [u8; 968] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L']; pub(crate) const DIGIT_TO_BASE23_SQUARED: [u8; 1058] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M']; pub(crate) const DIGIT_TO_BASE24_SQUARED: [u8; 1152] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N']; pub(crate) const DIGIT_TO_BASE25_SQUARED: [u8; 1250] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', b'0', b'O', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', b'1', b'O', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', b'2', b'O', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', b'3', b'O', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', b'4', b'O', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', b'5', b'O', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', b'6', b'O', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', b'7', b'O', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', b'8', b'O', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'9', b'O', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'A', b'O', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'B', b'O', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'C', b'O', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'D', b'O', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'E', b'O', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'F', b'O', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'G', b'O', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'H', b'O', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'I', b'O', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'J', b'O', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'K', b'O', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'L', b'O', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'M', b'O', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N', b'N', b'O', b'O', b'0', b'O', b'1', b'O', b'2', b'O', b'3', b'O', b'4', b'O', b'5', b'O', b'6', b'O', b'7', b'O', b'8', b'O', b'9', b'O', b'A', b'O', b'B', b'O', b'C', b'O', b'D', b'O', b'E', b'O', b'F', b'O', b'G', b'O', b'H', b'O', b'I', b'O', b'J', b'O', b'K', b'O', b'L', b'O', b'M', b'O', b'N', b'O', b'O']; pub(crate) const DIGIT_TO_BASE26_SQUARED: [u8; 1352] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', b'0', b'O', b'0', b'P', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', b'1', b'O', b'1', b'P', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', b'2', b'O', b'2', b'P', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', b'3', b'O', b'3', b'P', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', b'4', b'O', b'4', b'P', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', b'5', b'O', b'5', b'P', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', b'6', b'O', b'6', b'P', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', b'7', b'O', b'7', b'P', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', b'8', b'O', b'8', b'P', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'9', b'O', b'9', b'P', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'A', b'O', b'A', b'P', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'B', b'O', b'B', b'P', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'C', b'O', b'C', b'P', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'D', b'O', b'D', b'P', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'E', b'O', b'E', b'P', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'F', b'O', b'F', b'P', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'G', b'O', b'G', b'P', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'H', b'O', b'H', b'P', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'I', b'O', b'I', b'P', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'J', b'O', b'J', b'P', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'K', b'O', b'K', b'P', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'L', b'O', b'L', b'P', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'M', b'O', b'M', b'P', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N', b'N', b'O', b'N', b'P', b'O', b'0', b'O', b'1', b'O', b'2', b'O', b'3', b'O', b'4', b'O', b'5', b'O', b'6', b'O', b'7', b'O', b'8', b'O', b'9', b'O', b'A', b'O', b'B', b'O', b'C', b'O', b'D', b'O', b'E', b'O', b'F', b'O', b'G', b'O', b'H', b'O', b'I', b'O', b'J', b'O', b'K', b'O', b'L', b'O', b'M', b'O', b'N', b'O', b'O', b'O', b'P', b'P', b'0', b'P', b'1', b'P', b'2', b'P', b'3', b'P', b'4', b'P', b'5', b'P', b'6', b'P', b'7', b'P', b'8', b'P', b'9', b'P', b'A', b'P', b'B', b'P', b'C', b'P', b'D', b'P', b'E', b'P', b'F', b'P', b'G', b'P', b'H', b'P', b'I', b'P', b'J', b'P', b'K', b'P', b'L', b'P', b'M', b'P', b'N', b'P', b'O', b'P', b'P']; pub(crate) const DIGIT_TO_BASE27_SQUARED: [u8; 1458] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', b'0', b'O', b'0', b'P', b'0', b'Q', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', b'1', b'O', b'1', b'P', b'1', b'Q', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', b'2', b'O', b'2', b'P', b'2', b'Q', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', b'3', b'O', b'3', b'P', b'3', b'Q', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', b'4', b'O', b'4', b'P', b'4', b'Q', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', b'5', b'O', b'5', b'P', b'5', b'Q', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', b'6', b'O', b'6', b'P', b'6', b'Q', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', b'7', b'O', b'7', b'P', b'7', b'Q', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', b'8', b'O', b'8', b'P', b'8', b'Q', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'9', b'O', b'9', b'P', b'9', b'Q', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'A', b'O', b'A', b'P', b'A', b'Q', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'B', b'O', b'B', b'P', b'B', b'Q', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'C', b'O', b'C', b'P', b'C', b'Q', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'D', b'O', b'D', b'P', b'D', b'Q', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'E', b'O', b'E', b'P', b'E', b'Q', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'F', b'O', b'F', b'P', b'F', b'Q', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'G', b'O', b'G', b'P', b'G', b'Q', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'H', b'O', b'H', b'P', b'H', b'Q', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'I', b'O', b'I', b'P', b'I', b'Q', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'J', b'O', b'J', b'P', b'J', b'Q', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'K', b'O', b'K', b'P', b'K', b'Q', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'L', b'O', b'L', b'P', b'L', b'Q', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'M', b'O', b'M', b'P', b'M', b'Q', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N', b'N', b'O', b'N', b'P', b'N', b'Q', b'O', b'0', b'O', b'1', b'O', b'2', b'O', b'3', b'O', b'4', b'O', b'5', b'O', b'6', b'O', b'7', b'O', b'8', b'O', b'9', b'O', b'A', b'O', b'B', b'O', b'C', b'O', b'D', b'O', b'E', b'O', b'F', b'O', b'G', b'O', b'H', b'O', b'I', b'O', b'J', b'O', b'K', b'O', b'L', b'O', b'M', b'O', b'N', b'O', b'O', b'O', b'P', b'O', b'Q', b'P', b'0', b'P', b'1', b'P', b'2', b'P', b'3', b'P', b'4', b'P', b'5', b'P', b'6', b'P', b'7', b'P', b'8', b'P', b'9', b'P', b'A', b'P', b'B', b'P', b'C', b'P', b'D', b'P', b'E', b'P', b'F', b'P', b'G', b'P', b'H', b'P', b'I', b'P', b'J', b'P', b'K', b'P', b'L', b'P', b'M', b'P', b'N', b'P', b'O', b'P', b'P', b'P', b'Q', b'Q', b'0', b'Q', b'1', b'Q', b'2', b'Q', b'3', b'Q', b'4', b'Q', b'5', b'Q', b'6', b'Q', b'7', b'Q', b'8', b'Q', b'9', b'Q', b'A', b'Q', b'B', b'Q', b'C', b'Q', b'D', b'Q', b'E', b'Q', b'F', b'Q', b'G', b'Q', b'H', b'Q', b'I', b'Q', b'J', b'Q', b'K', b'Q', b'L', b'Q', b'M', b'Q', b'N', b'Q', b'O', b'Q', b'P', b'Q', b'Q']; pub(crate) const DIGIT_TO_BASE28_SQUARED: [u8; 1568] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', b'0', b'O', b'0', b'P', b'0', b'Q', b'0', b'R', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', b'1', b'O', b'1', b'P', b'1', b'Q', b'1', b'R', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', b'2', b'O', b'2', b'P', b'2', b'Q', b'2', b'R', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', b'3', b'O', b'3', b'P', b'3', b'Q', b'3', b'R', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', b'4', b'O', b'4', b'P', b'4', b'Q', b'4', b'R', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', b'5', b'O', b'5', b'P', b'5', b'Q', b'5', b'R', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', b'6', b'O', b'6', b'P', b'6', b'Q', b'6', b'R', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', b'7', b'O', b'7', b'P', b'7', b'Q', b'7', b'R', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', b'8', b'O', b'8', b'P', b'8', b'Q', b'8', b'R', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'9', b'O', b'9', b'P', b'9', b'Q', b'9', b'R', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'A', b'O', b'A', b'P', b'A', b'Q', b'A', b'R', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'B', b'O', b'B', b'P', b'B', b'Q', b'B', b'R', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'C', b'O', b'C', b'P', b'C', b'Q', b'C', b'R', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'D', b'O', b'D', b'P', b'D', b'Q', b'D', b'R', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'E', b'O', b'E', b'P', b'E', b'Q', b'E', b'R', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'F', b'O', b'F', b'P', b'F', b'Q', b'F', b'R', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'G', b'O', b'G', b'P', b'G', b'Q', b'G', b'R', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'H', b'O', b'H', b'P', b'H', b'Q', b'H', b'R', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'I', b'O', b'I', b'P', b'I', b'Q', b'I', b'R', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'J', b'O', b'J', b'P', b'J', b'Q', b'J', b'R', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'K', b'O', b'K', b'P', b'K', b'Q', b'K', b'R', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'L', b'O', b'L', b'P', b'L', b'Q', b'L', b'R', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'M', b'O', b'M', b'P', b'M', b'Q', b'M', b'R', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N', b'N', b'O', b'N', b'P', b'N', b'Q', b'N', b'R', b'O', b'0', b'O', b'1', b'O', b'2', b'O', b'3', b'O', b'4', b'O', b'5', b'O', b'6', b'O', b'7', b'O', b'8', b'O', b'9', b'O', b'A', b'O', b'B', b'O', b'C', b'O', b'D', b'O', b'E', b'O', b'F', b'O', b'G', b'O', b'H', b'O', b'I', b'O', b'J', b'O', b'K', b'O', b'L', b'O', b'M', b'O', b'N', b'O', b'O', b'O', b'P', b'O', b'Q', b'O', b'R', b'P', b'0', b'P', b'1', b'P', b'2', b'P', b'3', b'P', b'4', b'P', b'5', b'P', b'6', b'P', b'7', b'P', b'8', b'P', b'9', b'P', b'A', b'P', b'B', b'P', b'C', b'P', b'D', b'P', b'E', b'P', b'F', b'P', b'G', b'P', b'H', b'P', b'I', b'P', b'J', b'P', b'K', b'P', b'L', b'P', b'M', b'P', b'N', b'P', b'O', b'P', b'P', b'P', b'Q', b'P', b'R', b'Q', b'0', b'Q', b'1', b'Q', b'2', b'Q', b'3', b'Q', b'4', b'Q', b'5', b'Q', b'6', b'Q', b'7', b'Q', b'8', b'Q', b'9', b'Q', b'A', b'Q', b'B', b'Q', b'C', b'Q', b'D', b'Q', b'E', b'Q', b'F', b'Q', b'G', b'Q', b'H', b'Q', b'I', b'Q', b'J', b'Q', b'K', b'Q', b'L', b'Q', b'M', b'Q', b'N', b'Q', b'O', b'Q', b'P', b'Q', b'Q', b'Q', b'R', b'R', b'0', b'R', b'1', b'R', b'2', b'R', b'3', b'R', b'4', b'R', b'5', b'R', b'6', b'R', b'7', b'R', b'8', b'R', b'9', b'R', b'A', b'R', b'B', b'R', b'C', b'R', b'D', b'R', b'E', b'R', b'F', b'R', b'G', b'R', b'H', b'R', b'I', b'R', b'J', b'R', b'K', b'R', b'L', b'R', b'M', b'R', b'N', b'R', b'O', b'R', b'P', b'R', b'Q', b'R', b'R']; pub(crate) const DIGIT_TO_BASE29_SQUARED: [u8; 1682] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', b'0', b'O', b'0', b'P', b'0', b'Q', b'0', b'R', b'0', b'S', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', b'1', b'O', b'1', b'P', b'1', b'Q', b'1', b'R', b'1', b'S', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', b'2', b'O', b'2', b'P', b'2', b'Q', b'2', b'R', b'2', b'S', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', b'3', b'O', b'3', b'P', b'3', b'Q', b'3', b'R', b'3', b'S', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', b'4', b'O', b'4', b'P', b'4', b'Q', b'4', b'R', b'4', b'S', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', b'5', b'O', b'5', b'P', b'5', b'Q', b'5', b'R', b'5', b'S', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', b'6', b'O', b'6', b'P', b'6', b'Q', b'6', b'R', b'6', b'S', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', b'7', b'O', b'7', b'P', b'7', b'Q', b'7', b'R', b'7', b'S', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', b'8', b'O', b'8', b'P', b'8', b'Q', b'8', b'R', b'8', b'S', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'9', b'O', b'9', b'P', b'9', b'Q', b'9', b'R', b'9', b'S', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'A', b'O', b'A', b'P', b'A', b'Q', b'A', b'R', b'A', b'S', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'B', b'O', b'B', b'P', b'B', b'Q', b'B', b'R', b'B', b'S', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'C', b'O', b'C', b'P', b'C', b'Q', b'C', b'R', b'C', b'S', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'D', b'O', b'D', b'P', b'D', b'Q', b'D', b'R', b'D', b'S', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'E', b'O', b'E', b'P', b'E', b'Q', b'E', b'R', b'E', b'S', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'F', b'O', b'F', b'P', b'F', b'Q', b'F', b'R', b'F', b'S', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'G', b'O', b'G', b'P', b'G', b'Q', b'G', b'R', b'G', b'S', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'H', b'O', b'H', b'P', b'H', b'Q', b'H', b'R', b'H', b'S', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'I', b'O', b'I', b'P', b'I', b'Q', b'I', b'R', b'I', b'S', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'J', b'O', b'J', b'P', b'J', b'Q', b'J', b'R', b'J', b'S', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'K', b'O', b'K', b'P', b'K', b'Q', b'K', b'R', b'K', b'S', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'L', b'O', b'L', b'P', b'L', b'Q', b'L', b'R', b'L', b'S', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'M', b'O', b'M', b'P', b'M', b'Q', b'M', b'R', b'M', b'S', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N', b'N', b'O', b'N', b'P', b'N', b'Q', b'N', b'R', b'N', b'S', b'O', b'0', b'O', b'1', b'O', b'2', b'O', b'3', b'O', b'4', b'O', b'5', b'O', b'6', b'O', b'7', b'O', b'8', b'O', b'9', b'O', b'A', b'O', b'B', b'O', b'C', b'O', b'D', b'O', b'E', b'O', b'F', b'O', b'G', b'O', b'H', b'O', b'I', b'O', b'J', b'O', b'K', b'O', b'L', b'O', b'M', b'O', b'N', b'O', b'O', b'O', b'P', b'O', b'Q', b'O', b'R', b'O', b'S', b'P', b'0', b'P', b'1', b'P', b'2', b'P', b'3', b'P', b'4', b'P', b'5', b'P', b'6', b'P', b'7', b'P', b'8', b'P', b'9', b'P', b'A', b'P', b'B', b'P', b'C', b'P', b'D', b'P', b'E', b'P', b'F', b'P', b'G', b'P', b'H', b'P', b'I', b'P', b'J', b'P', b'K', b'P', b'L', b'P', b'M', b'P', b'N', b'P', b'O', b'P', b'P', b'P', b'Q', b'P', b'R', b'P', b'S', b'Q', b'0', b'Q', b'1', b'Q', b'2', b'Q', b'3', b'Q', b'4', b'Q', b'5', b'Q', b'6', b'Q', b'7', b'Q', b'8', b'Q', b'9', b'Q', b'A', b'Q', b'B', b'Q', b'C', b'Q', b'D', b'Q', b'E', b'Q', b'F', b'Q', b'G', b'Q', b'H', b'Q', b'I', b'Q', b'J', b'Q', b'K', b'Q', b'L', b'Q', b'M', b'Q', b'N', b'Q', b'O', b'Q', b'P', b'Q', b'Q', b'Q', b'R', b'Q', b'S', b'R', b'0', b'R', b'1', b'R', b'2', b'R', b'3', b'R', b'4', b'R', b'5', b'R', b'6', b'R', b'7', b'R', b'8', b'R', b'9', b'R', b'A', b'R', b'B', b'R', b'C', b'R', b'D', b'R', b'E', b'R', b'F', b'R', b'G', b'R', b'H', b'R', b'I', b'R', b'J', b'R', b'K', b'R', b'L', b'R', b'M', b'R', b'N', b'R', b'O', b'R', b'P', b'R', b'Q', b'R', b'R', b'R', b'S', b'S', b'0', b'S', b'1', b'S', b'2', b'S', b'3', b'S', b'4', b'S', b'5', b'S', b'6', b'S', b'7', b'S', b'8', b'S', b'9', b'S', b'A', b'S', b'B', b'S', b'C', b'S', b'D', b'S', b'E', b'S', b'F', b'S', b'G', b'S', b'H', b'S', b'I', b'S', b'J', b'S', b'K', b'S', b'L', b'S', b'M', b'S', b'N', b'S', b'O', b'S', b'P', b'S', b'Q', b'S', b'R', b'S', b'S']; pub(crate) const DIGIT_TO_BASE30_SQUARED: [u8; 1800] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', b'0', b'O', b'0', b'P', b'0', b'Q', b'0', b'R', b'0', b'S', b'0', b'T', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', b'1', b'O', b'1', b'P', b'1', b'Q', b'1', b'R', b'1', b'S', b'1', b'T', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', b'2', b'O', b'2', b'P', b'2', b'Q', b'2', b'R', b'2', b'S', b'2', b'T', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', b'3', b'O', b'3', b'P', b'3', b'Q', b'3', b'R', b'3', b'S', b'3', b'T', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', b'4', b'O', b'4', b'P', b'4', b'Q', b'4', b'R', b'4', b'S', b'4', b'T', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', b'5', b'O', b'5', b'P', b'5', b'Q', b'5', b'R', b'5', b'S', b'5', b'T', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', b'6', b'O', b'6', b'P', b'6', b'Q', b'6', b'R', b'6', b'S', b'6', b'T', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', b'7', b'O', b'7', b'P', b'7', b'Q', b'7', b'R', b'7', b'S', b'7', b'T', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', b'8', b'O', b'8', b'P', b'8', b'Q', b'8', b'R', b'8', b'S', b'8', b'T', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'9', b'O', b'9', b'P', b'9', b'Q', b'9', b'R', b'9', b'S', b'9', b'T', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'A', b'O', b'A', b'P', b'A', b'Q', b'A', b'R', b'A', b'S', b'A', b'T', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'B', b'O', b'B', b'P', b'B', b'Q', b'B', b'R', b'B', b'S', b'B', b'T', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'C', b'O', b'C', b'P', b'C', b'Q', b'C', b'R', b'C', b'S', b'C', b'T', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'D', b'O', b'D', b'P', b'D', b'Q', b'D', b'R', b'D', b'S', b'D', b'T', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'E', b'O', b'E', b'P', b'E', b'Q', b'E', b'R', b'E', b'S', b'E', b'T', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'F', b'O', b'F', b'P', b'F', b'Q', b'F', b'R', b'F', b'S', b'F', b'T', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'G', b'O', b'G', b'P', b'G', b'Q', b'G', b'R', b'G', b'S', b'G', b'T', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'H', b'O', b'H', b'P', b'H', b'Q', b'H', b'R', b'H', b'S', b'H', b'T', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'I', b'O', b'I', b'P', b'I', b'Q', b'I', b'R', b'I', b'S', b'I', b'T', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'J', b'O', b'J', b'P', b'J', b'Q', b'J', b'R', b'J', b'S', b'J', b'T', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'K', b'O', b'K', b'P', b'K', b'Q', b'K', b'R', b'K', b'S', b'K', b'T', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'L', b'O', b'L', b'P', b'L', b'Q', b'L', b'R', b'L', b'S', b'L', b'T', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'M', b'O', b'M', b'P', b'M', b'Q', b'M', b'R', b'M', b'S', b'M', b'T', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N', b'N', b'O', b'N', b'P', b'N', b'Q', b'N', b'R', b'N', b'S', b'N', b'T', b'O', b'0', b'O', b'1', b'O', b'2', b'O', b'3', b'O', b'4', b'O', b'5', b'O', b'6', b'O', b'7', b'O', b'8', b'O', b'9', b'O', b'A', b'O', b'B', b'O', b'C', b'O', b'D', b'O', b'E', b'O', b'F', b'O', b'G', b'O', b'H', b'O', b'I', b'O', b'J', b'O', b'K', b'O', b'L', b'O', b'M', b'O', b'N', b'O', b'O', b'O', b'P', b'O', b'Q', b'O', b'R', b'O', b'S', b'O', b'T', b'P', b'0', b'P', b'1', b'P', b'2', b'P', b'3', b'P', b'4', b'P', b'5', b'P', b'6', b'P', b'7', b'P', b'8', b'P', b'9', b'P', b'A', b'P', b'B', b'P', b'C', b'P', b'D', b'P', b'E', b'P', b'F', b'P', b'G', b'P', b'H', b'P', b'I', b'P', b'J', b'P', b'K', b'P', b'L', b'P', b'M', b'P', b'N', b'P', b'O', b'P', b'P', b'P', b'Q', b'P', b'R', b'P', b'S', b'P', b'T', b'Q', b'0', b'Q', b'1', b'Q', b'2', b'Q', b'3', b'Q', b'4', b'Q', b'5', b'Q', b'6', b'Q', b'7', b'Q', b'8', b'Q', b'9', b'Q', b'A', b'Q', b'B', b'Q', b'C', b'Q', b'D', b'Q', b'E', b'Q', b'F', b'Q', b'G', b'Q', b'H', b'Q', b'I', b'Q', b'J', b'Q', b'K', b'Q', b'L', b'Q', b'M', b'Q', b'N', b'Q', b'O', b'Q', b'P', b'Q', b'Q', b'Q', b'R', b'Q', b'S', b'Q', b'T', b'R', b'0', b'R', b'1', b'R', b'2', b'R', b'3', b'R', b'4', b'R', b'5', b'R', b'6', b'R', b'7', b'R', b'8', b'R', b'9', b'R', b'A', b'R', b'B', b'R', b'C', b'R', b'D', b'R', b'E', b'R', b'F', b'R', b'G', b'R', b'H', b'R', b'I', b'R', b'J', b'R', b'K', b'R', b'L', b'R', b'M', b'R', b'N', b'R', b'O', b'R', b'P', b'R', b'Q', b'R', b'R', b'R', b'S', b'R', b'T', b'S', b'0', b'S', b'1', b'S', b'2', b'S', b'3', b'S', b'4', b'S', b'5', b'S', b'6', b'S', b'7', b'S', b'8', b'S', b'9', b'S', b'A', b'S', b'B', b'S', b'C', b'S', b'D', b'S', b'E', b'S', b'F', b'S', b'G', b'S', b'H', b'S', b'I', b'S', b'J', b'S', b'K', b'S', b'L', b'S', b'M', b'S', b'N', b'S', b'O', b'S', b'P', b'S', b'Q', b'S', b'R', b'S', b'S', b'S', b'T', b'T', b'0', b'T', b'1', b'T', b'2', b'T', b'3', b'T', b'4', b'T', b'5', b'T', b'6', b'T', b'7', b'T', b'8', b'T', b'9', b'T', b'A', b'T', b'B', b'T', b'C', b'T', b'D', b'T', b'E', b'T', b'F', b'T', b'G', b'T', b'H', b'T', b'I', b'T', b'J', b'T', b'K', b'T', b'L', b'T', b'M', b'T', b'N', b'T', b'O', b'T', b'P', b'T', b'Q', b'T', b'R', b'T', b'S', b'T', b'T']; pub(crate) const DIGIT_TO_BASE31_SQUARED: [u8; 1922] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', b'0', b'O', b'0', b'P', b'0', b'Q', b'0', b'R', b'0', b'S', b'0', b'T', b'0', b'U', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', b'1', b'O', b'1', b'P', b'1', b'Q', b'1', b'R', b'1', b'S', b'1', b'T', b'1', b'U', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', b'2', b'O', b'2', b'P', b'2', b'Q', b'2', b'R', b'2', b'S', b'2', b'T', b'2', b'U', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', b'3', b'O', b'3', b'P', b'3', b'Q', b'3', b'R', b'3', b'S', b'3', b'T', b'3', b'U', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', b'4', b'O', b'4', b'P', b'4', b'Q', b'4', b'R', b'4', b'S', b'4', b'T', b'4', b'U', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', b'5', b'O', b'5', b'P', b'5', b'Q', b'5', b'R', b'5', b'S', b'5', b'T', b'5', b'U', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', b'6', b'O', b'6', b'P', b'6', b'Q', b'6', b'R', b'6', b'S', b'6', b'T', b'6', b'U', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', b'7', b'O', b'7', b'P', b'7', b'Q', b'7', b'R', b'7', b'S', b'7', b'T', b'7', b'U', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', b'8', b'O', b'8', b'P', b'8', b'Q', b'8', b'R', b'8', b'S', b'8', b'T', b'8', b'U', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'9', b'O', b'9', b'P', b'9', b'Q', b'9', b'R', b'9', b'S', b'9', b'T', b'9', b'U', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'A', b'O', b'A', b'P', b'A', b'Q', b'A', b'R', b'A', b'S', b'A', b'T', b'A', b'U', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'B', b'O', b'B', b'P', b'B', b'Q', b'B', b'R', b'B', b'S', b'B', b'T', b'B', b'U', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'C', b'O', b'C', b'P', b'C', b'Q', b'C', b'R', b'C', b'S', b'C', b'T', b'C', b'U', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'D', b'O', b'D', b'P', b'D', b'Q', b'D', b'R', b'D', b'S', b'D', b'T', b'D', b'U', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'E', b'O', b'E', b'P', b'E', b'Q', b'E', b'R', b'E', b'S', b'E', b'T', b'E', b'U', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'F', b'O', b'F', b'P', b'F', b'Q', b'F', b'R', b'F', b'S', b'F', b'T', b'F', b'U', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'G', b'O', b'G', b'P', b'G', b'Q', b'G', b'R', b'G', b'S', b'G', b'T', b'G', b'U', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'H', b'O', b'H', b'P', b'H', b'Q', b'H', b'R', b'H', b'S', b'H', b'T', b'H', b'U', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'I', b'O', b'I', b'P', b'I', b'Q', b'I', b'R', b'I', b'S', b'I', b'T', b'I', b'U', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'J', b'O', b'J', b'P', b'J', b'Q', b'J', b'R', b'J', b'S', b'J', b'T', b'J', b'U', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'K', b'O', b'K', b'P', b'K', b'Q', b'K', b'R', b'K', b'S', b'K', b'T', b'K', b'U', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'L', b'O', b'L', b'P', b'L', b'Q', b'L', b'R', b'L', b'S', b'L', b'T', b'L', b'U', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'M', b'O', b'M', b'P', b'M', b'Q', b'M', b'R', b'M', b'S', b'M', b'T', b'M', b'U', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N', b'N', b'O', b'N', b'P', b'N', b'Q', b'N', b'R', b'N', b'S', b'N', b'T', b'N', b'U', b'O', b'0', b'O', b'1', b'O', b'2', b'O', b'3', b'O', b'4', b'O', b'5', b'O', b'6', b'O', b'7', b'O', b'8', b'O', b'9', b'O', b'A', b'O', b'B', b'O', b'C', b'O', b'D', b'O', b'E', b'O', b'F', b'O', b'G', b'O', b'H', b'O', b'I', b'O', b'J', b'O', b'K', b'O', b'L', b'O', b'M', b'O', b'N', b'O', b'O', b'O', b'P', b'O', b'Q', b'O', b'R', b'O', b'S', b'O', b'T', b'O', b'U', b'P', b'0', b'P', b'1', b'P', b'2', b'P', b'3', b'P', b'4', b'P', b'5', b'P', b'6', b'P', b'7', b'P', b'8', b'P', b'9', b'P', b'A', b'P', b'B', b'P', b'C', b'P', b'D', b'P', b'E', b'P', b'F', b'P', b'G', b'P', b'H', b'P', b'I', b'P', b'J', b'P', b'K', b'P', b'L', b'P', b'M', b'P', b'N', b'P', b'O', b'P', b'P', b'P', b'Q', b'P', b'R', b'P', b'S', b'P', b'T', b'P', b'U', b'Q', b'0', b'Q', b'1', b'Q', b'2', b'Q', b'3', b'Q', b'4', b'Q', b'5', b'Q', b'6', b'Q', b'7', b'Q', b'8', b'Q', b'9', b'Q', b'A', b'Q', b'B', b'Q', b'C', b'Q', b'D', b'Q', b'E', b'Q', b'F', b'Q', b'G', b'Q', b'H', b'Q', b'I', b'Q', b'J', b'Q', b'K', b'Q', b'L', b'Q', b'M', b'Q', b'N', b'Q', b'O', b'Q', b'P', b'Q', b'Q', b'Q', b'R', b'Q', b'S', b'Q', b'T', b'Q', b'U', b'R', b'0', b'R', b'1', b'R', b'2', b'R', b'3', b'R', b'4', b'R', b'5', b'R', b'6', b'R', b'7', b'R', b'8', b'R', b'9', b'R', b'A', b'R', b'B', b'R', b'C', b'R', b'D', b'R', b'E', b'R', b'F', b'R', b'G', b'R', b'H', b'R', b'I', b'R', b'J', b'R', b'K', b'R', b'L', b'R', b'M', b'R', b'N', b'R', b'O', b'R', b'P', b'R', b'Q', b'R', b'R', b'R', b'S', b'R', b'T', b'R', b'U', b'S', b'0', b'S', b'1', b'S', b'2', b'S', b'3', b'S', b'4', b'S', b'5', b'S', b'6', b'S', b'7', b'S', b'8', b'S', b'9', b'S', b'A', b'S', b'B', b'S', b'C', b'S', b'D', b'S', b'E', b'S', b'F', b'S', b'G', b'S', b'H', b'S', b'I', b'S', b'J', b'S', b'K', b'S', b'L', b'S', b'M', b'S', b'N', b'S', b'O', b'S', b'P', b'S', b'Q', b'S', b'R', b'S', b'S', b'S', b'T', b'S', b'U', b'T', b'0', b'T', b'1', b'T', b'2', b'T', b'3', b'T', b'4', b'T', b'5', b'T', b'6', b'T', b'7', b'T', b'8', b'T', b'9', b'T', b'A', b'T', b'B', b'T', b'C', b'T', b'D', b'T', b'E', b'T', b'F', b'T', b'G', b'T', b'H', b'T', b'I', b'T', b'J', b'T', b'K', b'T', b'L', b'T', b'M', b'T', b'N', b'T', b'O', b'T', b'P', b'T', b'Q', b'T', b'R', b'T', b'S', b'T', b'T', b'T', b'U', b'U', b'0', b'U', b'1', b'U', b'2', b'U', b'3', b'U', b'4', b'U', b'5', b'U', b'6', b'U', b'7', b'U', b'8', b'U', b'9', b'U', b'A', b'U', b'B', b'U', b'C', b'U', b'D', b'U', b'E', b'U', b'F', b'U', b'G', b'U', b'H', b'U', b'I', b'U', b'J', b'U', b'K', b'U', b'L', b'U', b'M', b'U', b'N', b'U', b'O', b'U', b'P', b'U', b'Q', b'U', b'R', b'U', b'S', b'U', b'T', b'U', b'U']; pub(crate) const DIGIT_TO_BASE32_SQUARED: [u8; 2048] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', b'0', b'O', b'0', b'P', b'0', b'Q', b'0', b'R', b'0', b'S', b'0', b'T', b'0', b'U', b'0', b'V', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', b'1', b'O', b'1', b'P', b'1', b'Q', b'1', b'R', b'1', b'S', b'1', b'T', b'1', b'U', b'1', b'V', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', b'2', b'O', b'2', b'P', b'2', b'Q', b'2', b'R', b'2', b'S', b'2', b'T', b'2', b'U', b'2', b'V', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', b'3', b'O', b'3', b'P', b'3', b'Q', b'3', b'R', b'3', b'S', b'3', b'T', b'3', b'U', b'3', b'V', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', b'4', b'O', b'4', b'P', b'4', b'Q', b'4', b'R', b'4', b'S', b'4', b'T', b'4', b'U', b'4', b'V', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', b'5', b'O', b'5', b'P', b'5', b'Q', b'5', b'R', b'5', b'S', b'5', b'T', b'5', b'U', b'5', b'V', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', b'6', b'O', b'6', b'P', b'6', b'Q', b'6', b'R', b'6', b'S', b'6', b'T', b'6', b'U', b'6', b'V', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', b'7', b'O', b'7', b'P', b'7', b'Q', b'7', b'R', b'7', b'S', b'7', b'T', b'7', b'U', b'7', b'V', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', b'8', b'O', b'8', b'P', b'8', b'Q', b'8', b'R', b'8', b'S', b'8', b'T', b'8', b'U', b'8', b'V', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'9', b'O', b'9', b'P', b'9', b'Q', b'9', b'R', b'9', b'S', b'9', b'T', b'9', b'U', b'9', b'V', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'A', b'O', b'A', b'P', b'A', b'Q', b'A', b'R', b'A', b'S', b'A', b'T', b'A', b'U', b'A', b'V', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'B', b'O', b'B', b'P', b'B', b'Q', b'B', b'R', b'B', b'S', b'B', b'T', b'B', b'U', b'B', b'V', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'C', b'O', b'C', b'P', b'C', b'Q', b'C', b'R', b'C', b'S', b'C', b'T', b'C', b'U', b'C', b'V', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'D', b'O', b'D', b'P', b'D', b'Q', b'D', b'R', b'D', b'S', b'D', b'T', b'D', b'U', b'D', b'V', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'E', b'O', b'E', b'P', b'E', b'Q', b'E', b'R', b'E', b'S', b'E', b'T', b'E', b'U', b'E', b'V', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'F', b'O', b'F', b'P', b'F', b'Q', b'F', b'R', b'F', b'S', b'F', b'T', b'F', b'U', b'F', b'V', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'G', b'O', b'G', b'P', b'G', b'Q', b'G', b'R', b'G', b'S', b'G', b'T', b'G', b'U', b'G', b'V', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'H', b'O', b'H', b'P', b'H', b'Q', b'H', b'R', b'H', b'S', b'H', b'T', b'H', b'U', b'H', b'V', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'I', b'O', b'I', b'P', b'I', b'Q', b'I', b'R', b'I', b'S', b'I', b'T', b'I', b'U', b'I', b'V', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'J', b'O', b'J', b'P', b'J', b'Q', b'J', b'R', b'J', b'S', b'J', b'T', b'J', b'U', b'J', b'V', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'K', b'O', b'K', b'P', b'K', b'Q', b'K', b'R', b'K', b'S', b'K', b'T', b'K', b'U', b'K', b'V', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'L', b'O', b'L', b'P', b'L', b'Q', b'L', b'R', b'L', b'S', b'L', b'T', b'L', b'U', b'L', b'V', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'M', b'O', b'M', b'P', b'M', b'Q', b'M', b'R', b'M', b'S', b'M', b'T', b'M', b'U', b'M', b'V', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N', b'N', b'O', b'N', b'P', b'N', b'Q', b'N', b'R', b'N', b'S', b'N', b'T', b'N', b'U', b'N', b'V', b'O', b'0', b'O', b'1', b'O', b'2', b'O', b'3', b'O', b'4', b'O', b'5', b'O', b'6', b'O', b'7', b'O', b'8', b'O', b'9', b'O', b'A', b'O', b'B', b'O', b'C', b'O', b'D', b'O', b'E', b'O', b'F', b'O', b'G', b'O', b'H', b'O', b'I', b'O', b'J', b'O', b'K', b'O', b'L', b'O', b'M', b'O', b'N', b'O', b'O', b'O', b'P', b'O', b'Q', b'O', b'R', b'O', b'S', b'O', b'T', b'O', b'U', b'O', b'V', b'P', b'0', b'P', b'1', b'P', b'2', b'P', b'3', b'P', b'4', b'P', b'5', b'P', b'6', b'P', b'7', b'P', b'8', b'P', b'9', b'P', b'A', b'P', b'B', b'P', b'C', b'P', b'D', b'P', b'E', b'P', b'F', b'P', b'G', b'P', b'H', b'P', b'I', b'P', b'J', b'P', b'K', b'P', b'L', b'P', b'M', b'P', b'N', b'P', b'O', b'P', b'P', b'P', b'Q', b'P', b'R', b'P', b'S', b'P', b'T', b'P', b'U', b'P', b'V', b'Q', b'0', b'Q', b'1', b'Q', b'2', b'Q', b'3', b'Q', b'4', b'Q', b'5', b'Q', b'6', b'Q', b'7', b'Q', b'8', b'Q', b'9', b'Q', b'A', b'Q', b'B', b'Q', b'C', b'Q', b'D', b'Q', b'E', b'Q', b'F', b'Q', b'G', b'Q', b'H', b'Q', b'I', b'Q', b'J', b'Q', b'K', b'Q', b'L', b'Q', b'M', b'Q', b'N', b'Q', b'O', b'Q', b'P', b'Q', b'Q', b'Q', b'R', b'Q', b'S', b'Q', b'T', b'Q', b'U', b'Q', b'V', b'R', b'0', b'R', b'1', b'R', b'2', b'R', b'3', b'R', b'4', b'R', b'5', b'R', b'6', b'R', b'7', b'R', b'8', b'R', b'9', b'R', b'A', b'R', b'B', b'R', b'C', b'R', b'D', b'R', b'E', b'R', b'F', b'R', b'G', b'R', b'H', b'R', b'I', b'R', b'J', b'R', b'K', b'R', b'L', b'R', b'M', b'R', b'N', b'R', b'O', b'R', b'P', b'R', b'Q', b'R', b'R', b'R', b'S', b'R', b'T', b'R', b'U', b'R', b'V', b'S', b'0', b'S', b'1', b'S', b'2', b'S', b'3', b'S', b'4', b'S', b'5', b'S', b'6', b'S', b'7', b'S', b'8', b'S', b'9', b'S', b'A', b'S', b'B', b'S', b'C', b'S', b'D', b'S', b'E', b'S', b'F', b'S', b'G', b'S', b'H', b'S', b'I', b'S', b'J', b'S', b'K', b'S', b'L', b'S', b'M', b'S', b'N', b'S', b'O', b'S', b'P', b'S', b'Q', b'S', b'R', b'S', b'S', b'S', b'T', b'S', b'U', b'S', b'V', b'T', b'0', b'T', b'1', b'T', b'2', b'T', b'3', b'T', b'4', b'T', b'5', b'T', b'6', b'T', b'7', b'T', b'8', b'T', b'9', b'T', b'A', b'T', b'B', b'T', b'C', b'T', b'D', b'T', b'E', b'T', b'F', b'T', b'G', b'T', b'H', b'T', b'I', b'T', b'J', b'T', b'K', b'T', b'L', b'T', b'M', b'T', b'N', b'T', b'O', b'T', b'P', b'T', b'Q', b'T', b'R', b'T', b'S', b'T', b'T', b'T', b'U', b'T', b'V', b'U', b'0', b'U', b'1', b'U', b'2', b'U', b'3', b'U', b'4', b'U', b'5', b'U', b'6', b'U', b'7', b'U', b'8', b'U', b'9', b'U', b'A', b'U', b'B', b'U', b'C', b'U', b'D', b'U', b'E', b'U', b'F', b'U', b'G', b'U', b'H', b'U', b'I', b'U', b'J', b'U', b'K', b'U', b'L', b'U', b'M', b'U', b'N', b'U', b'O', b'U', b'P', b'U', b'Q', b'U', b'R', b'U', b'S', b'U', b'T', b'U', b'U', b'U', b'V', b'V', b'0', b'V', b'1', b'V', b'2', b'V', b'3', b'V', b'4', b'V', b'5', b'V', b'6', b'V', b'7', b'V', b'8', b'V', b'9', b'V', b'A', b'V', b'B', b'V', b'C', b'V', b'D', b'V', b'E', b'V', b'F', b'V', b'G', b'V', b'H', b'V', b'I', b'V', b'J', b'V', b'K', b'V', b'L', b'V', b'M', b'V', b'N', b'V', b'O', b'V', b'P', b'V', b'Q', b'V', b'R', b'V', b'S', b'V', b'T', b'V', b'U', b'V', b'V']; pub(crate) const DIGIT_TO_BASE33_SQUARED: [u8; 2178] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', b'0', b'O', b'0', b'P', b'0', b'Q', b'0', b'R', b'0', b'S', b'0', b'T', b'0', b'U', b'0', b'V', b'0', b'W', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', b'1', b'O', b'1', b'P', b'1', b'Q', b'1', b'R', b'1', b'S', b'1', b'T', b'1', b'U', b'1', b'V', b'1', b'W', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', b'2', b'O', b'2', b'P', b'2', b'Q', b'2', b'R', b'2', b'S', b'2', b'T', b'2', b'U', b'2', b'V', b'2', b'W', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', b'3', b'O', b'3', b'P', b'3', b'Q', b'3', b'R', b'3', b'S', b'3', b'T', b'3', b'U', b'3', b'V', b'3', b'W', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', b'4', b'O', b'4', b'P', b'4', b'Q', b'4', b'R', b'4', b'S', b'4', b'T', b'4', b'U', b'4', b'V', b'4', b'W', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', b'5', b'O', b'5', b'P', b'5', b'Q', b'5', b'R', b'5', b'S', b'5', b'T', b'5', b'U', b'5', b'V', b'5', b'W', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', b'6', b'O', b'6', b'P', b'6', b'Q', b'6', b'R', b'6', b'S', b'6', b'T', b'6', b'U', b'6', b'V', b'6', b'W', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', b'7', b'O', b'7', b'P', b'7', b'Q', b'7', b'R', b'7', b'S', b'7', b'T', b'7', b'U', b'7', b'V', b'7', b'W', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', b'8', b'O', b'8', b'P', b'8', b'Q', b'8', b'R', b'8', b'S', b'8', b'T', b'8', b'U', b'8', b'V', b'8', b'W', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'9', b'O', b'9', b'P', b'9', b'Q', b'9', b'R', b'9', b'S', b'9', b'T', b'9', b'U', b'9', b'V', b'9', b'W', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'A', b'O', b'A', b'P', b'A', b'Q', b'A', b'R', b'A', b'S', b'A', b'T', b'A', b'U', b'A', b'V', b'A', b'W', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'B', b'O', b'B', b'P', b'B', b'Q', b'B', b'R', b'B', b'S', b'B', b'T', b'B', b'U', b'B', b'V', b'B', b'W', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'C', b'O', b'C', b'P', b'C', b'Q', b'C', b'R', b'C', b'S', b'C', b'T', b'C', b'U', b'C', b'V', b'C', b'W', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'D', b'O', b'D', b'P', b'D', b'Q', b'D', b'R', b'D', b'S', b'D', b'T', b'D', b'U', b'D', b'V', b'D', b'W', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'E', b'O', b'E', b'P', b'E', b'Q', b'E', b'R', b'E', b'S', b'E', b'T', b'E', b'U', b'E', b'V', b'E', b'W', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'F', b'O', b'F', b'P', b'F', b'Q', b'F', b'R', b'F', b'S', b'F', b'T', b'F', b'U', b'F', b'V', b'F', b'W', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'G', b'O', b'G', b'P', b'G', b'Q', b'G', b'R', b'G', b'S', b'G', b'T', b'G', b'U', b'G', b'V', b'G', b'W', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'H', b'O', b'H', b'P', b'H', b'Q', b'H', b'R', b'H', b'S', b'H', b'T', b'H', b'U', b'H', b'V', b'H', b'W', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'I', b'O', b'I', b'P', b'I', b'Q', b'I', b'R', b'I', b'S', b'I', b'T', b'I', b'U', b'I', b'V', b'I', b'W', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'J', b'O', b'J', b'P', b'J', b'Q', b'J', b'R', b'J', b'S', b'J', b'T', b'J', b'U', b'J', b'V', b'J', b'W', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'K', b'O', b'K', b'P', b'K', b'Q', b'K', b'R', b'K', b'S', b'K', b'T', b'K', b'U', b'K', b'V', b'K', b'W', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'L', b'O', b'L', b'P', b'L', b'Q', b'L', b'R', b'L', b'S', b'L', b'T', b'L', b'U', b'L', b'V', b'L', b'W', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'M', b'O', b'M', b'P', b'M', b'Q', b'M', b'R', b'M', b'S', b'M', b'T', b'M', b'U', b'M', b'V', b'M', b'W', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N', b'N', b'O', b'N', b'P', b'N', b'Q', b'N', b'R', b'N', b'S', b'N', b'T', b'N', b'U', b'N', b'V', b'N', b'W', b'O', b'0', b'O', b'1', b'O', b'2', b'O', b'3', b'O', b'4', b'O', b'5', b'O', b'6', b'O', b'7', b'O', b'8', b'O', b'9', b'O', b'A', b'O', b'B', b'O', b'C', b'O', b'D', b'O', b'E', b'O', b'F', b'O', b'G', b'O', b'H', b'O', b'I', b'O', b'J', b'O', b'K', b'O', b'L', b'O', b'M', b'O', b'N', b'O', b'O', b'O', b'P', b'O', b'Q', b'O', b'R', b'O', b'S', b'O', b'T', b'O', b'U', b'O', b'V', b'O', b'W', b'P', b'0', b'P', b'1', b'P', b'2', b'P', b'3', b'P', b'4', b'P', b'5', b'P', b'6', b'P', b'7', b'P', b'8', b'P', b'9', b'P', b'A', b'P', b'B', b'P', b'C', b'P', b'D', b'P', b'E', b'P', b'F', b'P', b'G', b'P', b'H', b'P', b'I', b'P', b'J', b'P', b'K', b'P', b'L', b'P', b'M', b'P', b'N', b'P', b'O', b'P', b'P', b'P', b'Q', b'P', b'R', b'P', b'S', b'P', b'T', b'P', b'U', b'P', b'V', b'P', b'W', b'Q', b'0', b'Q', b'1', b'Q', b'2', b'Q', b'3', b'Q', b'4', b'Q', b'5', b'Q', b'6', b'Q', b'7', b'Q', b'8', b'Q', b'9', b'Q', b'A', b'Q', b'B', b'Q', b'C', b'Q', b'D', b'Q', b'E', b'Q', b'F', b'Q', b'G', b'Q', b'H', b'Q', b'I', b'Q', b'J', b'Q', b'K', b'Q', b'L', b'Q', b'M', b'Q', b'N', b'Q', b'O', b'Q', b'P', b'Q', b'Q', b'Q', b'R', b'Q', b'S', b'Q', b'T', b'Q', b'U', b'Q', b'V', b'Q', b'W', b'R', b'0', b'R', b'1', b'R', b'2', b'R', b'3', b'R', b'4', b'R', b'5', b'R', b'6', b'R', b'7', b'R', b'8', b'R', b'9', b'R', b'A', b'R', b'B', b'R', b'C', b'R', b'D', b'R', b'E', b'R', b'F', b'R', b'G', b'R', b'H', b'R', b'I', b'R', b'J', b'R', b'K', b'R', b'L', b'R', b'M', b'R', b'N', b'R', b'O', b'R', b'P', b'R', b'Q', b'R', b'R', b'R', b'S', b'R', b'T', b'R', b'U', b'R', b'V', b'R', b'W', b'S', b'0', b'S', b'1', b'S', b'2', b'S', b'3', b'S', b'4', b'S', b'5', b'S', b'6', b'S', b'7', b'S', b'8', b'S', b'9', b'S', b'A', b'S', b'B', b'S', b'C', b'S', b'D', b'S', b'E', b'S', b'F', b'S', b'G', b'S', b'H', b'S', b'I', b'S', b'J', b'S', b'K', b'S', b'L', b'S', b'M', b'S', b'N', b'S', b'O', b'S', b'P', b'S', b'Q', b'S', b'R', b'S', b'S', b'S', b'T', b'S', b'U', b'S', b'V', b'S', b'W', b'T', b'0', b'T', b'1', b'T', b'2', b'T', b'3', b'T', b'4', b'T', b'5', b'T', b'6', b'T', b'7', b'T', b'8', b'T', b'9', b'T', b'A', b'T', b'B', b'T', b'C', b'T', b'D', b'T', b'E', b'T', b'F', b'T', b'G', b'T', b'H', b'T', b'I', b'T', b'J', b'T', b'K', b'T', b'L', b'T', b'M', b'T', b'N', b'T', b'O', b'T', b'P', b'T', b'Q', b'T', b'R', b'T', b'S', b'T', b'T', b'T', b'U', b'T', b'V', b'T', b'W', b'U', b'0', b'U', b'1', b'U', b'2', b'U', b'3', b'U', b'4', b'U', b'5', b'U', b'6', b'U', b'7', b'U', b'8', b'U', b'9', b'U', b'A', b'U', b'B', b'U', b'C', b'U', b'D', b'U', b'E', b'U', b'F', b'U', b'G', b'U', b'H', b'U', b'I', b'U', b'J', b'U', b'K', b'U', b'L', b'U', b'M', b'U', b'N', b'U', b'O', b'U', b'P', b'U', b'Q', b'U', b'R', b'U', b'S', b'U', b'T', b'U', b'U', b'U', b'V', b'U', b'W', b'V', b'0', b'V', b'1', b'V', b'2', b'V', b'3', b'V', b'4', b'V', b'5', b'V', b'6', b'V', b'7', b'V', b'8', b'V', b'9', b'V', b'A', b'V', b'B', b'V', b'C', b'V', b'D', b'V', b'E', b'V', b'F', b'V', b'G', b'V', b'H', b'V', b'I', b'V', b'J', b'V', b'K', b'V', b'L', b'V', b'M', b'V', b'N', b'V', b'O', b'V', b'P', b'V', b'Q', b'V', b'R', b'V', b'S', b'V', b'T', b'V', b'U', b'V', b'V', b'V', b'W', b'W', b'0', b'W', b'1', b'W', b'2', b'W', b'3', b'W', b'4', b'W', b'5', b'W', b'6', b'W', b'7', b'W', b'8', b'W', b'9', b'W', b'A', b'W', b'B', b'W', b'C', b'W', b'D', b'W', b'E', b'W', b'F', b'W', b'G', b'W', b'H', b'W', b'I', b'W', b'J', b'W', b'K', b'W', b'L', b'W', b'M', b'W', b'N', b'W', b'O', b'W', b'P', b'W', b'Q', b'W', b'R', b'W', b'S', b'W', b'T', b'W', b'U', b'W', b'V', b'W', b'W']; pub(crate) const DIGIT_TO_BASE34_SQUARED: [u8; 2312] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', b'0', b'O', b'0', b'P', b'0', b'Q', b'0', b'R', b'0', b'S', b'0', b'T', b'0', b'U', b'0', b'V', b'0', b'W', b'0', b'X', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', b'1', b'O', b'1', b'P', b'1', b'Q', b'1', b'R', b'1', b'S', b'1', b'T', b'1', b'U', b'1', b'V', b'1', b'W', b'1', b'X', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', b'2', b'O', b'2', b'P', b'2', b'Q', b'2', b'R', b'2', b'S', b'2', b'T', b'2', b'U', b'2', b'V', b'2', b'W', b'2', b'X', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', b'3', b'O', b'3', b'P', b'3', b'Q', b'3', b'R', b'3', b'S', b'3', b'T', b'3', b'U', b'3', b'V', b'3', b'W', b'3', b'X', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', b'4', b'O', b'4', b'P', b'4', b'Q', b'4', b'R', b'4', b'S', b'4', b'T', b'4', b'U', b'4', b'V', b'4', b'W', b'4', b'X', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', b'5', b'O', b'5', b'P', b'5', b'Q', b'5', b'R', b'5', b'S', b'5', b'T', b'5', b'U', b'5', b'V', b'5', b'W', b'5', b'X', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', b'6', b'O', b'6', b'P', b'6', b'Q', b'6', b'R', b'6', b'S', b'6', b'T', b'6', b'U', b'6', b'V', b'6', b'W', b'6', b'X', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', b'7', b'O', b'7', b'P', b'7', b'Q', b'7', b'R', b'7', b'S', b'7', b'T', b'7', b'U', b'7', b'V', b'7', b'W', b'7', b'X', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', b'8', b'O', b'8', b'P', b'8', b'Q', b'8', b'R', b'8', b'S', b'8', b'T', b'8', b'U', b'8', b'V', b'8', b'W', b'8', b'X', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'9', b'O', b'9', b'P', b'9', b'Q', b'9', b'R', b'9', b'S', b'9', b'T', b'9', b'U', b'9', b'V', b'9', b'W', b'9', b'X', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'A', b'O', b'A', b'P', b'A', b'Q', b'A', b'R', b'A', b'S', b'A', b'T', b'A', b'U', b'A', b'V', b'A', b'W', b'A', b'X', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'B', b'O', b'B', b'P', b'B', b'Q', b'B', b'R', b'B', b'S', b'B', b'T', b'B', b'U', b'B', b'V', b'B', b'W', b'B', b'X', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'C', b'O', b'C', b'P', b'C', b'Q', b'C', b'R', b'C', b'S', b'C', b'T', b'C', b'U', b'C', b'V', b'C', b'W', b'C', b'X', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'D', b'O', b'D', b'P', b'D', b'Q', b'D', b'R', b'D', b'S', b'D', b'T', b'D', b'U', b'D', b'V', b'D', b'W', b'D', b'X', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'E', b'O', b'E', b'P', b'E', b'Q', b'E', b'R', b'E', b'S', b'E', b'T', b'E', b'U', b'E', b'V', b'E', b'W', b'E', b'X', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'F', b'O', b'F', b'P', b'F', b'Q', b'F', b'R', b'F', b'S', b'F', b'T', b'F', b'U', b'F', b'V', b'F', b'W', b'F', b'X', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'G', b'O', b'G', b'P', b'G', b'Q', b'G', b'R', b'G', b'S', b'G', b'T', b'G', b'U', b'G', b'V', b'G', b'W', b'G', b'X', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'H', b'O', b'H', b'P', b'H', b'Q', b'H', b'R', b'H', b'S', b'H', b'T', b'H', b'U', b'H', b'V', b'H', b'W', b'H', b'X', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'I', b'O', b'I', b'P', b'I', b'Q', b'I', b'R', b'I', b'S', b'I', b'T', b'I', b'U', b'I', b'V', b'I', b'W', b'I', b'X', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'J', b'O', b'J', b'P', b'J', b'Q', b'J', b'R', b'J', b'S', b'J', b'T', b'J', b'U', b'J', b'V', b'J', b'W', b'J', b'X', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'K', b'O', b'K', b'P', b'K', b'Q', b'K', b'R', b'K', b'S', b'K', b'T', b'K', b'U', b'K', b'V', b'K', b'W', b'K', b'X', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'L', b'O', b'L', b'P', b'L', b'Q', b'L', b'R', b'L', b'S', b'L', b'T', b'L', b'U', b'L', b'V', b'L', b'W', b'L', b'X', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'M', b'O', b'M', b'P', b'M', b'Q', b'M', b'R', b'M', b'S', b'M', b'T', b'M', b'U', b'M', b'V', b'M', b'W', b'M', b'X', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N', b'N', b'O', b'N', b'P', b'N', b'Q', b'N', b'R', b'N', b'S', b'N', b'T', b'N', b'U', b'N', b'V', b'N', b'W', b'N', b'X', b'O', b'0', b'O', b'1', b'O', b'2', b'O', b'3', b'O', b'4', b'O', b'5', b'O', b'6', b'O', b'7', b'O', b'8', b'O', b'9', b'O', b'A', b'O', b'B', b'O', b'C', b'O', b'D', b'O', b'E', b'O', b'F', b'O', b'G', b'O', b'H', b'O', b'I', b'O', b'J', b'O', b'K', b'O', b'L', b'O', b'M', b'O', b'N', b'O', b'O', b'O', b'P', b'O', b'Q', b'O', b'R', b'O', b'S', b'O', b'T', b'O', b'U', b'O', b'V', b'O', b'W', b'O', b'X', b'P', b'0', b'P', b'1', b'P', b'2', b'P', b'3', b'P', b'4', b'P', b'5', b'P', b'6', b'P', b'7', b'P', b'8', b'P', b'9', b'P', b'A', b'P', b'B', b'P', b'C', b'P', b'D', b'P', b'E', b'P', b'F', b'P', b'G', b'P', b'H', b'P', b'I', b'P', b'J', b'P', b'K', b'P', b'L', b'P', b'M', b'P', b'N', b'P', b'O', b'P', b'P', b'P', b'Q', b'P', b'R', b'P', b'S', b'P', b'T', b'P', b'U', b'P', b'V', b'P', b'W', b'P', b'X', b'Q', b'0', b'Q', b'1', b'Q', b'2', b'Q', b'3', b'Q', b'4', b'Q', b'5', b'Q', b'6', b'Q', b'7', b'Q', b'8', b'Q', b'9', b'Q', b'A', b'Q', b'B', b'Q', b'C', b'Q', b'D', b'Q', b'E', b'Q', b'F', b'Q', b'G', b'Q', b'H', b'Q', b'I', b'Q', b'J', b'Q', b'K', b'Q', b'L', b'Q', b'M', b'Q', b'N', b'Q', b'O', b'Q', b'P', b'Q', b'Q', b'Q', b'R', b'Q', b'S', b'Q', b'T', b'Q', b'U', b'Q', b'V', b'Q', b'W', b'Q', b'X', b'R', b'0', b'R', b'1', b'R', b'2', b'R', b'3', b'R', b'4', b'R', b'5', b'R', b'6', b'R', b'7', b'R', b'8', b'R', b'9', b'R', b'A', b'R', b'B', b'R', b'C', b'R', b'D', b'R', b'E', b'R', b'F', b'R', b'G', b'R', b'H', b'R', b'I', b'R', b'J', b'R', b'K', b'R', b'L', b'R', b'M', b'R', b'N', b'R', b'O', b'R', b'P', b'R', b'Q', b'R', b'R', b'R', b'S', b'R', b'T', b'R', b'U', b'R', b'V', b'R', b'W', b'R', b'X', b'S', b'0', b'S', b'1', b'S', b'2', b'S', b'3', b'S', b'4', b'S', b'5', b'S', b'6', b'S', b'7', b'S', b'8', b'S', b'9', b'S', b'A', b'S', b'B', b'S', b'C', b'S', b'D', b'S', b'E', b'S', b'F', b'S', b'G', b'S', b'H', b'S', b'I', b'S', b'J', b'S', b'K', b'S', b'L', b'S', b'M', b'S', b'N', b'S', b'O', b'S', b'P', b'S', b'Q', b'S', b'R', b'S', b'S', b'S', b'T', b'S', b'U', b'S', b'V', b'S', b'W', b'S', b'X', b'T', b'0', b'T', b'1', b'T', b'2', b'T', b'3', b'T', b'4', b'T', b'5', b'T', b'6', b'T', b'7', b'T', b'8', b'T', b'9', b'T', b'A', b'T', b'B', b'T', b'C', b'T', b'D', b'T', b'E', b'T', b'F', b'T', b'G', b'T', b'H', b'T', b'I', b'T', b'J', b'T', b'K', b'T', b'L', b'T', b'M', b'T', b'N', b'T', b'O', b'T', b'P', b'T', b'Q', b'T', b'R', b'T', b'S', b'T', b'T', b'T', b'U', b'T', b'V', b'T', b'W', b'T', b'X', b'U', b'0', b'U', b'1', b'U', b'2', b'U', b'3', b'U', b'4', b'U', b'5', b'U', b'6', b'U', b'7', b'U', b'8', b'U', b'9', b'U', b'A', b'U', b'B', b'U', b'C', b'U', b'D', b'U', b'E', b'U', b'F', b'U', b'G', b'U', b'H', b'U', b'I', b'U', b'J', b'U', b'K', b'U', b'L', b'U', b'M', b'U', b'N', b'U', b'O', b'U', b'P', b'U', b'Q', b'U', b'R', b'U', b'S', b'U', b'T', b'U', b'U', b'U', b'V', b'U', b'W', b'U', b'X', b'V', b'0', b'V', b'1', b'V', b'2', b'V', b'3', b'V', b'4', b'V', b'5', b'V', b'6', b'V', b'7', b'V', b'8', b'V', b'9', b'V', b'A', b'V', b'B', b'V', b'C', b'V', b'D', b'V', b'E', b'V', b'F', b'V', b'G', b'V', b'H', b'V', b'I', b'V', b'J', b'V', b'K', b'V', b'L', b'V', b'M', b'V', b'N', b'V', b'O', b'V', b'P', b'V', b'Q', b'V', b'R', b'V', b'S', b'V', b'T', b'V', b'U', b'V', b'V', b'V', b'W', b'V', b'X', b'W', b'0', b'W', b'1', b'W', b'2', b'W', b'3', b'W', b'4', b'W', b'5', b'W', b'6', b'W', b'7', b'W', b'8', b'W', b'9', b'W', b'A', b'W', b'B', b'W', b'C', b'W', b'D', b'W', b'E', b'W', b'F', b'W', b'G', b'W', b'H', b'W', b'I', b'W', b'J', b'W', b'K', b'W', b'L', b'W', b'M', b'W', b'N', b'W', b'O', b'W', b'P', b'W', b'Q', b'W', b'R', b'W', b'S', b'W', b'T', b'W', b'U', b'W', b'V', b'W', b'W', b'W', b'X', b'X', b'0', b'X', b'1', b'X', b'2', b'X', b'3', b'X', b'4', b'X', b'5', b'X', b'6', b'X', b'7', b'X', b'8', b'X', b'9', b'X', b'A', b'X', b'B', b'X', b'C', b'X', b'D', b'X', b'E', b'X', b'F', b'X', b'G', b'X', b'H', b'X', b'I', b'X', b'J', b'X', b'K', b'X', b'L', b'X', b'M', b'X', b'N', b'X', b'O', b'X', b'P', b'X', b'Q', b'X', b'R', b'X', b'S', b'X', b'T', b'X', b'U', b'X', b'V', b'X', b'W', b'X', b'X']; pub(crate) const DIGIT_TO_BASE35_SQUARED: [u8; 2450] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', b'0', b'O', b'0', b'P', b'0', b'Q', b'0', b'R', b'0', b'S', b'0', b'T', b'0', b'U', b'0', b'V', b'0', b'W', b'0', b'X', b'0', b'Y', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', b'1', b'O', b'1', b'P', b'1', b'Q', b'1', b'R', b'1', b'S', b'1', b'T', b'1', b'U', b'1', b'V', b'1', b'W', b'1', b'X', b'1', b'Y', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', b'2', b'O', b'2', b'P', b'2', b'Q', b'2', b'R', b'2', b'S', b'2', b'T', b'2', b'U', b'2', b'V', b'2', b'W', b'2', b'X', b'2', b'Y', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', b'3', b'O', b'3', b'P', b'3', b'Q', b'3', b'R', b'3', b'S', b'3', b'T', b'3', b'U', b'3', b'V', b'3', b'W', b'3', b'X', b'3', b'Y', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', b'4', b'O', b'4', b'P', b'4', b'Q', b'4', b'R', b'4', b'S', b'4', b'T', b'4', b'U', b'4', b'V', b'4', b'W', b'4', b'X', b'4', b'Y', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', b'5', b'O', b'5', b'P', b'5', b'Q', b'5', b'R', b'5', b'S', b'5', b'T', b'5', b'U', b'5', b'V', b'5', b'W', b'5', b'X', b'5', b'Y', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', b'6', b'O', b'6', b'P', b'6', b'Q', b'6', b'R', b'6', b'S', b'6', b'T', b'6', b'U', b'6', b'V', b'6', b'W', b'6', b'X', b'6', b'Y', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', b'7', b'O', b'7', b'P', b'7', b'Q', b'7', b'R', b'7', b'S', b'7', b'T', b'7', b'U', b'7', b'V', b'7', b'W', b'7', b'X', b'7', b'Y', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', b'8', b'O', b'8', b'P', b'8', b'Q', b'8', b'R', b'8', b'S', b'8', b'T', b'8', b'U', b'8', b'V', b'8', b'W', b'8', b'X', b'8', b'Y', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'9', b'O', b'9', b'P', b'9', b'Q', b'9', b'R', b'9', b'S', b'9', b'T', b'9', b'U', b'9', b'V', b'9', b'W', b'9', b'X', b'9', b'Y', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'A', b'O', b'A', b'P', b'A', b'Q', b'A', b'R', b'A', b'S', b'A', b'T', b'A', b'U', b'A', b'V', b'A', b'W', b'A', b'X', b'A', b'Y', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'B', b'O', b'B', b'P', b'B', b'Q', b'B', b'R', b'B', b'S', b'B', b'T', b'B', b'U', b'B', b'V', b'B', b'W', b'B', b'X', b'B', b'Y', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'C', b'O', b'C', b'P', b'C', b'Q', b'C', b'R', b'C', b'S', b'C', b'T', b'C', b'U', b'C', b'V', b'C', b'W', b'C', b'X', b'C', b'Y', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'D', b'O', b'D', b'P', b'D', b'Q', b'D', b'R', b'D', b'S', b'D', b'T', b'D', b'U', b'D', b'V', b'D', b'W', b'D', b'X', b'D', b'Y', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'E', b'O', b'E', b'P', b'E', b'Q', b'E', b'R', b'E', b'S', b'E', b'T', b'E', b'U', b'E', b'V', b'E', b'W', b'E', b'X', b'E', b'Y', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'F', b'O', b'F', b'P', b'F', b'Q', b'F', b'R', b'F', b'S', b'F', b'T', b'F', b'U', b'F', b'V', b'F', b'W', b'F', b'X', b'F', b'Y', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'G', b'O', b'G', b'P', b'G', b'Q', b'G', b'R', b'G', b'S', b'G', b'T', b'G', b'U', b'G', b'V', b'G', b'W', b'G', b'X', b'G', b'Y', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'H', b'O', b'H', b'P', b'H', b'Q', b'H', b'R', b'H', b'S', b'H', b'T', b'H', b'U', b'H', b'V', b'H', b'W', b'H', b'X', b'H', b'Y', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'I', b'O', b'I', b'P', b'I', b'Q', b'I', b'R', b'I', b'S', b'I', b'T', b'I', b'U', b'I', b'V', b'I', b'W', b'I', b'X', b'I', b'Y', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'J', b'O', b'J', b'P', b'J', b'Q', b'J', b'R', b'J', b'S', b'J', b'T', b'J', b'U', b'J', b'V', b'J', b'W', b'J', b'X', b'J', b'Y', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'K', b'O', b'K', b'P', b'K', b'Q', b'K', b'R', b'K', b'S', b'K', b'T', b'K', b'U', b'K', b'V', b'K', b'W', b'K', b'X', b'K', b'Y', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'L', b'O', b'L', b'P', b'L', b'Q', b'L', b'R', b'L', b'S', b'L', b'T', b'L', b'U', b'L', b'V', b'L', b'W', b'L', b'X', b'L', b'Y', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'M', b'O', b'M', b'P', b'M', b'Q', b'M', b'R', b'M', b'S', b'M', b'T', b'M', b'U', b'M', b'V', b'M', b'W', b'M', b'X', b'M', b'Y', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N', b'N', b'O', b'N', b'P', b'N', b'Q', b'N', b'R', b'N', b'S', b'N', b'T', b'N', b'U', b'N', b'V', b'N', b'W', b'N', b'X', b'N', b'Y', b'O', b'0', b'O', b'1', b'O', b'2', b'O', b'3', b'O', b'4', b'O', b'5', b'O', b'6', b'O', b'7', b'O', b'8', b'O', b'9', b'O', b'A', b'O', b'B', b'O', b'C', b'O', b'D', b'O', b'E', b'O', b'F', b'O', b'G', b'O', b'H', b'O', b'I', b'O', b'J', b'O', b'K', b'O', b'L', b'O', b'M', b'O', b'N', b'O', b'O', b'O', b'P', b'O', b'Q', b'O', b'R', b'O', b'S', b'O', b'T', b'O', b'U', b'O', b'V', b'O', b'W', b'O', b'X', b'O', b'Y', b'P', b'0', b'P', b'1', b'P', b'2', b'P', b'3', b'P', b'4', b'P', b'5', b'P', b'6', b'P', b'7', b'P', b'8', b'P', b'9', b'P', b'A', b'P', b'B', b'P', b'C', b'P', b'D', b'P', b'E', b'P', b'F', b'P', b'G', b'P', b'H', b'P', b'I', b'P', b'J', b'P', b'K', b'P', b'L', b'P', b'M', b'P', b'N', b'P', b'O', b'P', b'P', b'P', b'Q', b'P', b'R', b'P', b'S', b'P', b'T', b'P', b'U', b'P', b'V', b'P', b'W', b'P', b'X', b'P', b'Y', b'Q', b'0', b'Q', b'1', b'Q', b'2', b'Q', b'3', b'Q', b'4', b'Q', b'5', b'Q', b'6', b'Q', b'7', b'Q', b'8', b'Q', b'9', b'Q', b'A', b'Q', b'B', b'Q', b'C', b'Q', b'D', b'Q', b'E', b'Q', b'F', b'Q', b'G', b'Q', b'H', b'Q', b'I', b'Q', b'J', b'Q', b'K', b'Q', b'L', b'Q', b'M', b'Q', b'N', b'Q', b'O', b'Q', b'P', b'Q', b'Q', b'Q', b'R', b'Q', b'S', b'Q', b'T', b'Q', b'U', b'Q', b'V', b'Q', b'W', b'Q', b'X', b'Q', b'Y', b'R', b'0', b'R', b'1', b'R', b'2', b'R', b'3', b'R', b'4', b'R', b'5', b'R', b'6', b'R', b'7', b'R', b'8', b'R', b'9', b'R', b'A', b'R', b'B', b'R', b'C', b'R', b'D', b'R', b'E', b'R', b'F', b'R', b'G', b'R', b'H', b'R', b'I', b'R', b'J', b'R', b'K', b'R', b'L', b'R', b'M', b'R', b'N', b'R', b'O', b'R', b'P', b'R', b'Q', b'R', b'R', b'R', b'S', b'R', b'T', b'R', b'U', b'R', b'V', b'R', b'W', b'R', b'X', b'R', b'Y', b'S', b'0', b'S', b'1', b'S', b'2', b'S', b'3', b'S', b'4', b'S', b'5', b'S', b'6', b'S', b'7', b'S', b'8', b'S', b'9', b'S', b'A', b'S', b'B', b'S', b'C', b'S', b'D', b'S', b'E', b'S', b'F', b'S', b'G', b'S', b'H', b'S', b'I', b'S', b'J', b'S', b'K', b'S', b'L', b'S', b'M', b'S', b'N', b'S', b'O', b'S', b'P', b'S', b'Q', b'S', b'R', b'S', b'S', b'S', b'T', b'S', b'U', b'S', b'V', b'S', b'W', b'S', b'X', b'S', b'Y', b'T', b'0', b'T', b'1', b'T', b'2', b'T', b'3', b'T', b'4', b'T', b'5', b'T', b'6', b'T', b'7', b'T', b'8', b'T', b'9', b'T', b'A', b'T', b'B', b'T', b'C', b'T', b'D', b'T', b'E', b'T', b'F', b'T', b'G', b'T', b'H', b'T', b'I', b'T', b'J', b'T', b'K', b'T', b'L', b'T', b'M', b'T', b'N', b'T', b'O', b'T', b'P', b'T', b'Q', b'T', b'R', b'T', b'S', b'T', b'T', b'T', b'U', b'T', b'V', b'T', b'W', b'T', b'X', b'T', b'Y', b'U', b'0', b'U', b'1', b'U', b'2', b'U', b'3', b'U', b'4', b'U', b'5', b'U', b'6', b'U', b'7', b'U', b'8', b'U', b'9', b'U', b'A', b'U', b'B', b'U', b'C', b'U', b'D', b'U', b'E', b'U', b'F', b'U', b'G', b'U', b'H', b'U', b'I', b'U', b'J', b'U', b'K', b'U', b'L', b'U', b'M', b'U', b'N', b'U', b'O', b'U', b'P', b'U', b'Q', b'U', b'R', b'U', b'S', b'U', b'T', b'U', b'U', b'U', b'V', b'U', b'W', b'U', b'X', b'U', b'Y', b'V', b'0', b'V', b'1', b'V', b'2', b'V', b'3', b'V', b'4', b'V', b'5', b'V', b'6', b'V', b'7', b'V', b'8', b'V', b'9', b'V', b'A', b'V', b'B', b'V', b'C', b'V', b'D', b'V', b'E', b'V', b'F', b'V', b'G', b'V', b'H', b'V', b'I', b'V', b'J', b'V', b'K', b'V', b'L', b'V', b'M', b'V', b'N', b'V', b'O', b'V', b'P', b'V', b'Q', b'V', b'R', b'V', b'S', b'V', b'T', b'V', b'U', b'V', b'V', b'V', b'W', b'V', b'X', b'V', b'Y', b'W', b'0', b'W', b'1', b'W', b'2', b'W', b'3', b'W', b'4', b'W', b'5', b'W', b'6', b'W', b'7', b'W', b'8', b'W', b'9', b'W', b'A', b'W', b'B', b'W', b'C', b'W', b'D', b'W', b'E', b'W', b'F', b'W', b'G', b'W', b'H', b'W', b'I', b'W', b'J', b'W', b'K', b'W', b'L', b'W', b'M', b'W', b'N', b'W', b'O', b'W', b'P', b'W', b'Q', b'W', b'R', b'W', b'S', b'W', b'T', b'W', b'U', b'W', b'V', b'W', b'W', b'W', b'X', b'W', b'Y', b'X', b'0', b'X', b'1', b'X', b'2', b'X', b'3', b'X', b'4', b'X', b'5', b'X', b'6', b'X', b'7', b'X', b'8', b'X', b'9', b'X', b'A', b'X', b'B', b'X', b'C', b'X', b'D', b'X', b'E', b'X', b'F', b'X', b'G', b'X', b'H', b'X', b'I', b'X', b'J', b'X', b'K', b'X', b'L', b'X', b'M', b'X', b'N', b'X', b'O', b'X', b'P', b'X', b'Q', b'X', b'R', b'X', b'S', b'X', b'T', b'X', b'U', b'X', b'V', b'X', b'W', b'X', b'X', b'X', b'Y', b'Y', b'0', b'Y', b'1', b'Y', b'2', b'Y', b'3', b'Y', b'4', b'Y', b'5', b'Y', b'6', b'Y', b'7', b'Y', b'8', b'Y', b'9', b'Y', b'A', b'Y', b'B', b'Y', b'C', b'Y', b'D', b'Y', b'E', b'Y', b'F', b'Y', b'G', b'Y', b'H', b'Y', b'I', b'Y', b'J', b'Y', b'K', b'Y', b'L', b'Y', b'M', b'Y', b'N', b'Y', b'O', b'Y', b'P', b'Y', b'Q', b'Y', b'R', b'Y', b'S', b'Y', b'T', b'Y', b'U', b'Y', b'V', b'Y', b'W', b'Y', b'X', b'Y', b'Y']; pub(crate) const DIGIT_TO_BASE36_SQUARED: [u8; 2592] = [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'0', b'A', b'0', b'B', b'0', b'C', b'0', b'D', b'0', b'E', b'0', b'F', b'0', b'G', b'0', b'H', b'0', b'I', b'0', b'J', b'0', b'K', b'0', b'L', b'0', b'M', b'0', b'N', b'0', b'O', b'0', b'P', b'0', b'Q', b'0', b'R', b'0', b'S', b'0', b'T', b'0', b'U', b'0', b'V', b'0', b'W', b'0', b'X', b'0', b'Y', b'0', b'Z', 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'1', b'A', b'1', b'B', b'1', b'C', b'1', b'D', b'1', b'E', b'1', b'F', b'1', b'G', b'1', b'H', b'1', b'I', b'1', b'J', b'1', b'K', b'1', b'L', b'1', b'M', b'1', b'N', b'1', b'O', b'1', b'P', b'1', b'Q', b'1', b'R', b'1', b'S', b'1', b'T', b'1', b'U', b'1', b'V', b'1', b'W', b'1', b'X', b'1', b'Y', b'1', b'Z', 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'2', b'A', b'2', b'B', b'2', b'C', b'2', b'D', b'2', b'E', b'2', b'F', b'2', b'G', b'2', b'H', b'2', b'I', b'2', b'J', b'2', b'K', b'2', b'L', b'2', b'M', b'2', b'N', b'2', b'O', b'2', b'P', b'2', b'Q', b'2', b'R', b'2', b'S', b'2', b'T', b'2', b'U', b'2', b'V', b'2', b'W', b'2', b'X', b'2', b'Y', b'2', b'Z', 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'3', b'A', b'3', b'B', b'3', b'C', b'3', b'D', b'3', b'E', b'3', b'F', b'3', b'G', b'3', b'H', b'3', b'I', b'3', b'J', b'3', b'K', b'3', b'L', b'3', b'M', b'3', b'N', b'3', b'O', b'3', b'P', b'3', b'Q', b'3', b'R', b'3', b'S', b'3', b'T', b'3', b'U', b'3', b'V', b'3', b'W', b'3', b'X', b'3', b'Y', b'3', b'Z', 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'4', b'A', b'4', b'B', b'4', b'C', b'4', b'D', b'4', b'E', b'4', b'F', b'4', b'G', b'4', b'H', b'4', b'I', b'4', b'J', b'4', b'K', b'4', b'L', b'4', b'M', b'4', b'N', b'4', b'O', b'4', b'P', b'4', b'Q', b'4', b'R', b'4', b'S', b'4', b'T', b'4', b'U', b'4', b'V', b'4', b'W', b'4', b'X', b'4', b'Y', b'4', b'Z', 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'5', b'A', b'5', b'B', b'5', b'C', b'5', b'D', b'5', b'E', b'5', b'F', b'5', b'G', b'5', b'H', b'5', b'I', b'5', b'J', b'5', b'K', b'5', b'L', b'5', b'M', b'5', b'N', b'5', b'O', b'5', b'P', b'5', b'Q', b'5', b'R', b'5', b'S', b'5', b'T', b'5', b'U', b'5', b'V', b'5', b'W', b'5', b'X', b'5', b'Y', b'5', b'Z', 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'6', b'A', b'6', b'B', b'6', b'C', b'6', b'D', b'6', b'E', b'6', b'F', b'6', b'G', b'6', b'H', b'6', b'I', b'6', b'J', b'6', b'K', b'6', b'L', b'6', b'M', b'6', b'N', b'6', b'O', b'6', b'P', b'6', b'Q', b'6', b'R', b'6', b'S', b'6', b'T', b'6', b'U', b'6', b'V', b'6', b'W', b'6', b'X', b'6', b'Y', b'6', b'Z', 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'7', b'A', b'7', b'B', b'7', b'C', b'7', b'D', b'7', b'E', b'7', b'F', b'7', b'G', b'7', b'H', b'7', b'I', b'7', b'J', b'7', b'K', b'7', b'L', b'7', b'M', b'7', b'N', b'7', b'O', b'7', b'P', b'7', b'Q', b'7', b'R', b'7', b'S', b'7', b'T', b'7', b'U', b'7', b'V', b'7', b'W', b'7', b'X', b'7', b'Y', b'7', b'Z', 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'8', b'A', b'8', b'B', b'8', b'C', b'8', b'D', b'8', b'E', b'8', b'F', b'8', b'G', b'8', b'H', b'8', b'I', b'8', b'J', b'8', b'K', b'8', b'L', b'8', b'M', b'8', b'N', b'8', b'O', b'8', b'P', b'8', b'Q', b'8', b'R', b'8', b'S', b'8', b'T', b'8', b'U', b'8', b'V', b'8', b'W', b'8', b'X', b'8', b'Y', b'8', b'Z', 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', b'9', b'A', b'9', b'B', b'9', b'C', b'9', b'D', b'9', b'E', b'9', b'F', b'9', b'G', b'9', b'H', b'9', b'I', b'9', b'J', b'9', b'K', b'9', b'L', b'9', b'M', b'9', b'N', b'9', b'O', b'9', b'P', b'9', b'Q', b'9', b'R', b'9', b'S', b'9', b'T', b'9', b'U', b'9', b'V', b'9', b'W', b'9', b'X', b'9', b'Y', b'9', b'Z', b'A', b'0', b'A', b'1', b'A', b'2', b'A', b'3', b'A', b'4', b'A', b'5', b'A', b'6', b'A', b'7', b'A', b'8', b'A', b'9', b'A', b'A', b'A', b'B', b'A', b'C', b'A', b'D', b'A', b'E', b'A', b'F', b'A', b'G', b'A', b'H', b'A', b'I', b'A', b'J', b'A', b'K', b'A', b'L', b'A', b'M', b'A', b'N', b'A', b'O', b'A', b'P', b'A', b'Q', b'A', b'R', b'A', b'S', b'A', b'T', b'A', b'U', b'A', b'V', b'A', b'W', b'A', b'X', b'A', b'Y', b'A', b'Z', b'B', b'0', b'B', b'1', b'B', b'2', b'B', b'3', b'B', b'4', b'B', b'5', b'B', b'6', b'B', b'7', b'B', b'8', b'B', b'9', b'B', b'A', b'B', b'B', b'B', b'C', b'B', b'D', b'B', b'E', b'B', b'F', b'B', b'G', b'B', b'H', b'B', b'I', b'B', b'J', b'B', b'K', b'B', b'L', b'B', b'M', b'B', b'N', b'B', b'O', b'B', b'P', b'B', b'Q', b'B', b'R', b'B', b'S', b'B', b'T', b'B', b'U', b'B', b'V', b'B', b'W', b'B', b'X', b'B', b'Y', b'B', b'Z', b'C', b'0', b'C', b'1', b'C', b'2', b'C', b'3', b'C', b'4', b'C', b'5', b'C', b'6', b'C', b'7', b'C', b'8', b'C', b'9', b'C', b'A', b'C', b'B', b'C', b'C', b'C', b'D', b'C', b'E', b'C', b'F', b'C', b'G', b'C', b'H', b'C', b'I', b'C', b'J', b'C', b'K', b'C', b'L', b'C', b'M', b'C', b'N', b'C', b'O', b'C', b'P', b'C', b'Q', b'C', b'R', b'C', b'S', b'C', b'T', b'C', b'U', b'C', b'V', b'C', b'W', b'C', b'X', b'C', b'Y', b'C', b'Z', b'D', b'0', b'D', b'1', b'D', b'2', b'D', b'3', b'D', b'4', b'D', b'5', b'D', b'6', b'D', b'7', b'D', b'8', b'D', b'9', b'D', b'A', b'D', b'B', b'D', b'C', b'D', b'D', b'D', b'E', b'D', b'F', b'D', b'G', b'D', b'H', b'D', b'I', b'D', b'J', b'D', b'K', b'D', b'L', b'D', b'M', b'D', b'N', b'D', b'O', b'D', b'P', b'D', b'Q', b'D', b'R', b'D', b'S', b'D', b'T', b'D', b'U', b'D', b'V', b'D', b'W', b'D', b'X', b'D', b'Y', b'D', b'Z', b'E', b'0', b'E', b'1', b'E', b'2', b'E', b'3', b'E', b'4', b'E', b'5', b'E', b'6', b'E', b'7', b'E', b'8', b'E', b'9', b'E', b'A', b'E', b'B', b'E', b'C', b'E', b'D', b'E', b'E', b'E', b'F', b'E', b'G', b'E', b'H', b'E', b'I', b'E', b'J', b'E', b'K', b'E', b'L', b'E', b'M', b'E', b'N', b'E', b'O', b'E', b'P', b'E', b'Q', b'E', b'R', b'E', b'S', b'E', b'T', b'E', b'U', b'E', b'V', b'E', b'W', b'E', b'X', b'E', b'Y', b'E', b'Z', b'F', b'0', b'F', b'1', b'F', b'2', b'F', b'3', b'F', b'4', b'F', b'5', b'F', b'6', b'F', b'7', b'F', b'8', b'F', b'9', b'F', b'A', b'F', b'B', b'F', b'C', b'F', b'D', b'F', b'E', b'F', b'F', b'F', b'G', b'F', b'H', b'F', b'I', b'F', b'J', b'F', b'K', b'F', b'L', b'F', b'M', b'F', b'N', b'F', b'O', b'F', b'P', b'F', b'Q', b'F', b'R', b'F', b'S', b'F', b'T', b'F', b'U', b'F', b'V', b'F', b'W', b'F', b'X', b'F', b'Y', b'F', b'Z', b'G', b'0', b'G', b'1', b'G', b'2', b'G', b'3', b'G', b'4', b'G', b'5', b'G', b'6', b'G', b'7', b'G', b'8', b'G', b'9', b'G', b'A', b'G', b'B', b'G', b'C', b'G', b'D', b'G', b'E', b'G', b'F', b'G', b'G', b'G', b'H', b'G', b'I', b'G', b'J', b'G', b'K', b'G', b'L', b'G', b'M', b'G', b'N', b'G', b'O', b'G', b'P', b'G', b'Q', b'G', b'R', b'G', b'S', b'G', b'T', b'G', b'U', b'G', b'V', b'G', b'W', b'G', b'X', b'G', b'Y', b'G', b'Z', b'H', b'0', b'H', b'1', b'H', b'2', b'H', b'3', b'H', b'4', b'H', b'5', b'H', b'6', b'H', b'7', b'H', b'8', b'H', b'9', b'H', b'A', b'H', b'B', b'H', b'C', b'H', b'D', b'H', b'E', b'H', b'F', b'H', b'G', b'H', b'H', b'H', b'I', b'H', b'J', b'H', b'K', b'H', b'L', b'H', b'M', b'H', b'N', b'H', b'O', b'H', b'P', b'H', b'Q', b'H', b'R', b'H', b'S', b'H', b'T', b'H', b'U', b'H', b'V', b'H', b'W', b'H', b'X', b'H', b'Y', b'H', b'Z', b'I', b'0', b'I', b'1', b'I', b'2', b'I', b'3', b'I', b'4', b'I', b'5', b'I', b'6', b'I', b'7', b'I', b'8', b'I', b'9', b'I', b'A', b'I', b'B', b'I', b'C', b'I', b'D', b'I', b'E', b'I', b'F', b'I', b'G', b'I', b'H', b'I', b'I', b'I', b'J', b'I', b'K', b'I', b'L', b'I', b'M', b'I', b'N', b'I', b'O', b'I', b'P', b'I', b'Q', b'I', b'R', b'I', b'S', b'I', b'T', b'I', b'U', b'I', b'V', b'I', b'W', b'I', b'X', b'I', b'Y', b'I', b'Z', b'J', b'0', b'J', b'1', b'J', b'2', b'J', b'3', b'J', b'4', b'J', b'5', b'J', b'6', b'J', b'7', b'J', b'8', b'J', b'9', b'J', b'A', b'J', b'B', b'J', b'C', b'J', b'D', b'J', b'E', b'J', b'F', b'J', b'G', b'J', b'H', b'J', b'I', b'J', b'J', b'J', b'K', b'J', b'L', b'J', b'M', b'J', b'N', b'J', b'O', b'J', b'P', b'J', b'Q', b'J', b'R', b'J', b'S', b'J', b'T', b'J', b'U', b'J', b'V', b'J', b'W', b'J', b'X', b'J', b'Y', b'J', b'Z', b'K', b'0', b'K', b'1', b'K', b'2', b'K', b'3', b'K', b'4', b'K', b'5', b'K', b'6', b'K', b'7', b'K', b'8', b'K', b'9', b'K', b'A', b'K', b'B', b'K', b'C', b'K', b'D', b'K', b'E', b'K', b'F', b'K', b'G', b'K', b'H', b'K', b'I', b'K', b'J', b'K', b'K', b'K', b'L', b'K', b'M', b'K', b'N', b'K', b'O', b'K', b'P', b'K', b'Q', b'K', b'R', b'K', b'S', b'K', b'T', b'K', b'U', b'K', b'V', b'K', b'W', b'K', b'X', b'K', b'Y', b'K', b'Z', b'L', b'0', b'L', b'1', b'L', b'2', b'L', b'3', b'L', b'4', b'L', b'5', b'L', b'6', b'L', b'7', b'L', b'8', b'L', b'9', b'L', b'A', b'L', b'B', b'L', b'C', b'L', b'D', b'L', b'E', b'L', b'F', b'L', b'G', b'L', b'H', b'L', b'I', b'L', b'J', b'L', b'K', b'L', b'L', b'L', b'M', b'L', b'N', b'L', b'O', b'L', b'P', b'L', b'Q', b'L', b'R', b'L', b'S', b'L', b'T', b'L', b'U', b'L', b'V', b'L', b'W', b'L', b'X', b'L', b'Y', b'L', b'Z', b'M', b'0', b'M', b'1', b'M', b'2', b'M', b'3', b'M', b'4', b'M', b'5', b'M', b'6', b'M', b'7', b'M', b'8', b'M', b'9', b'M', b'A', b'M', b'B', b'M', b'C', b'M', b'D', b'M', b'E', b'M', b'F', b'M', b'G', b'M', b'H', b'M', b'I', b'M', b'J', b'M', b'K', b'M', b'L', b'M', b'M', b'M', b'N', b'M', b'O', b'M', b'P', b'M', b'Q', b'M', b'R', b'M', b'S', b'M', b'T', b'M', b'U', b'M', b'V', b'M', b'W', b'M', b'X', b'M', b'Y', b'M', b'Z', b'N', b'0', b'N', b'1', b'N', b'2', b'N', b'3', b'N', b'4', b'N', b'5', b'N', b'6', b'N', b'7', b'N', b'8', b'N', b'9', b'N', b'A', b'N', b'B', b'N', b'C', b'N', b'D', b'N', b'E', b'N', b'F', b'N', b'G', b'N', b'H', b'N', b'I', b'N', b'J', b'N', b'K', b'N', b'L', b'N', b'M', b'N', b'N', b'N', b'O', b'N', b'P', b'N', b'Q', b'N', b'R', b'N', b'S', b'N', b'T', b'N', b'U', b'N', b'V', b'N', b'W', b'N', b'X', b'N', b'Y', b'N', b'Z', b'O', b'0', b'O', b'1', b'O', b'2', b'O', b'3', b'O', b'4', b'O', b'5', b'O', b'6', b'O', b'7', b'O', b'8', b'O', b'9', b'O', b'A', b'O', b'B', b'O', b'C', b'O', b'D', b'O', b'E', b'O', b'F', b'O', b'G', b'O', b'H', b'O', b'I', b'O', b'J', b'O', b'K', b'O', b'L', b'O', b'M', b'O', b'N', b'O', b'O', b'O', b'P', b'O', b'Q', b'O', b'R', b'O', b'S', b'O', b'T', b'O', b'U', b'O', b'V', b'O', b'W', b'O', b'X', b'O', b'Y', b'O', b'Z', b'P', b'0', b'P', b'1', b'P', b'2', b'P', b'3', b'P', b'4', b'P', b'5', b'P', b'6', b'P', b'7', b'P', b'8', b'P', b'9', b'P', b'A', b'P', b'B', b'P', b'C', b'P', b'D', b'P', b'E', b'P', b'F', b'P', b'G', b'P', b'H', b'P', b'I', b'P', b'J', b'P', b'K', b'P', b'L', b'P', b'M', b'P', b'N', b'P', b'O', b'P', b'P', b'P', b'Q', b'P', b'R', b'P', b'S', b'P', b'T', b'P', b'U', b'P', b'V', b'P', b'W', b'P', b'X', b'P', b'Y', b'P', b'Z', b'Q', b'0', b'Q', b'1', b'Q', b'2', b'Q', b'3', b'Q', b'4', b'Q', b'5', b'Q', b'6', b'Q', b'7', b'Q', b'8', b'Q', b'9', b'Q', b'A', b'Q', b'B', b'Q', b'C', b'Q', b'D', b'Q', b'E', b'Q', b'F', b'Q', b'G', b'Q', b'H', b'Q', b'I', b'Q', b'J', b'Q', b'K', b'Q', b'L', b'Q', b'M', b'Q', b'N', b'Q', b'O', b'Q', b'P', b'Q', b'Q', b'Q', b'R', b'Q', b'S', b'Q', b'T', b'Q', b'U', b'Q', b'V', b'Q', b'W', b'Q', b'X', b'Q', b'Y', b'Q', b'Z', b'R', b'0', b'R', b'1', b'R', b'2', b'R', b'3', b'R', b'4', b'R', b'5', b'R', b'6', b'R', b'7', b'R', b'8', b'R', b'9', b'R', b'A', b'R', b'B', b'R', b'C', b'R', b'D', b'R', b'E', b'R', b'F', b'R', b'G', b'R', b'H', b'R', b'I', b'R', b'J', b'R', b'K', b'R', b'L', b'R', b'M', b'R', b'N', b'R', b'O', b'R', b'P', b'R', b'Q', b'R', b'R', b'R', b'S', b'R', b'T', b'R', b'U', b'R', b'V', b'R', b'W', b'R', b'X', b'R', b'Y', b'R', b'Z', b'S', b'0', b'S', b'1', b'S', b'2', b'S', b'3', b'S', b'4', b'S', b'5', b'S', b'6', b'S', b'7', b'S', b'8', b'S', b'9', b'S', b'A', b'S', b'B', b'S', b'C', b'S', b'D', b'S', b'E', b'S', b'F', b'S', b'G', b'S', b'H', b'S', b'I', b'S', b'J', b'S', b'K', b'S', b'L', b'S', b'M', b'S', b'N', b'S', b'O', b'S', b'P', b'S', b'Q', b'S', b'R', b'S', b'S', b'S', b'T', b'S', b'U', b'S', b'V', b'S', b'W', b'S', b'X', b'S', b'Y', b'S', b'Z', b'T', b'0', b'T', b'1', b'T', b'2', b'T', b'3', b'T', b'4', b'T', b'5', b'T', b'6', b'T', b'7', b'T', b'8', b'T', b'9', b'T', b'A', b'T', b'B', b'T', b'C', b'T', b'D', b'T', b'E', b'T', b'F', b'T', b'G', b'T', b'H', b'T', b'I', b'T', b'J', b'T', b'K', b'T', b'L', b'T', b'M', b'T', b'N', b'T', b'O', b'T', b'P', b'T', b'Q', b'T', b'R', b'T', b'S', b'T', b'T', b'T', b'U', b'T', b'V', b'T', b'W', b'T', b'X', b'T', b'Y', b'T', b'Z', b'U', b'0', b'U', b'1', b'U', b'2', b'U', b'3', b'U', b'4', b'U', b'5', b'U', b'6', b'U', b'7', b'U', b'8', b'U', b'9', b'U', b'A', b'U', b'B', b'U', b'C', b'U', b'D', b'U', b'E', b'U', b'F', b'U', b'G', b'U', b'H', b'U', b'I', b'U', b'J', b'U', b'K', b'U', b'L', b'U', b'M', b'U', b'N', b'U', b'O', b'U', b'P', b'U', b'Q', b'U', b'R', b'U', b'S', b'U', b'T', b'U', b'U', b'U', b'V', b'U', b'W', b'U', b'X', b'U', b'Y', b'U', b'Z', b'V', b'0', b'V', b'1', b'V', b'2', b'V', b'3', b'V', b'4', b'V', b'5', b'V', b'6', b'V', b'7', b'V', b'8', b'V', b'9', b'V', b'A', b'V', b'B', b'V', b'C', b'V', b'D', b'V', b'E', b'V', b'F', b'V', b'G', b'V', b'H', b'V', b'I', b'V', b'J', b'V', b'K', b'V', b'L', b'V', b'M', b'V', b'N', b'V', b'O', b'V', b'P', b'V', b'Q', b'V', b'R', b'V', b'S', b'V', b'T', b'V', b'U', b'V', b'V', b'V', b'W', b'V', b'X', b'V', b'Y', b'V', b'Z', b'W', b'0', b'W', b'1', b'W', b'2', b'W', b'3', b'W', b'4', b'W', b'5', b'W', b'6', b'W', b'7', b'W', b'8', b'W', b'9', b'W', b'A', b'W', b'B', b'W', b'C', b'W', b'D', b'W', b'E', b'W', b'F', b'W', b'G', b'W', b'H', b'W', b'I', b'W', b'J', b'W', b'K', b'W', b'L', b'W', b'M', b'W', b'N', b'W', b'O', b'W', b'P', b'W', b'Q', b'W', b'R', b'W', b'S', b'W', b'T', b'W', b'U', b'W', b'V', b'W', b'W', b'W', b'X', b'W', b'Y', b'W', b'Z', b'X', b'0', b'X', b'1', b'X', b'2', b'X', b'3', b'X', b'4', b'X', b'5', b'X', b'6', b'X', b'7', b'X', b'8', b'X', b'9', b'X', b'A', b'X', b'B', b'X', b'C', b'X', b'D', b'X', b'E', b'X', b'F', b'X', b'G', b'X', b'H', b'X', b'I', b'X', b'J', b'X', b'K', b'X', b'L', b'X', b'M', b'X', b'N', b'X', b'O', b'X', b'P', b'X', b'Q', b'X', b'R', b'X', b'S', b'X', b'T', b'X', b'U', b'X', b'V', b'X', b'W', b'X', b'X', b'X', b'Y', b'X', b'Z', b'Y', b'0', b'Y', b'1', b'Y', b'2', b'Y', b'3', b'Y', b'4', b'Y', b'5', b'Y', b'6', b'Y', b'7', b'Y', b'8', b'Y', b'9', b'Y', b'A', b'Y', b'B', b'Y', b'C', b'Y', b'D', b'Y', b'E', b'Y', b'F', b'Y', b'G', b'Y', b'H', b'Y', b'I', b'Y', b'J', b'Y', b'K', b'Y', b'L', b'Y', b'M', b'Y', b'N', b'Y', b'O', b'Y', b'P', b'Y', b'Q', b'Y', b'R', b'Y', b'S', b'Y', b'T', b'Y', b'U', b'Y', b'V', b'Y', b'W', b'Y', b'X', b'Y', b'Y', b'Y', b'Z', b'Z', b'0', b'Z', b'1', b'Z', b'2', b'Z', b'3', b'Z', b'4', b'Z', b'5', b'Z', b'6', b'Z', b'7', b'Z', b'8', b'Z', b'9', b'Z', b'A', b'Z', b'B', b'Z', b'C', b'Z', b'D', b'Z', b'E', b'Z', b'F', b'Z', b'G', b'Z', b'H', b'Z', b'I', b'Z', b'J', b'Z', b'K', b'Z', b'L', b'Z', b'M', b'Z', b'N', b'Z', b'O', b'Z', b'P', b'Z', b'Q', b'Z', b'R', b'Z', b'S', b'Z', b'T', b'Z', b'U', b'Z', b'V', b'Z', b'W', b'Z', b'X', b'Z', b'Y', b'Z', b'Z']; }} // cfg_if // EXACT EXPONENT /// Get exact exponent limit for radix. pub(crate) trait ExactExponent { /// Get min and max exponent limits (exact) from radix. fn exponent_limit(radix: T) -> (i32, i32); /// Get the number of digits that can be shifted from exponent to mantissa. fn mantissa_limit(radix: T) -> i32; } impl ExactExponent for f32 { #[inline] fn exponent_limit(radix: T) -> (i32, i32) { debug_assert_radix!(radix); #[cfg(not(feature = "radix"))] { (-10, 10) } #[cfg(feature = "radix")] { match radix.as_i32() { 2 => (-149, 127), 3 => (-15, 15), 4 => (-74, 63), 5 => (-10, 10), 6 => (-15, 15), 7 => (-8, 8), 8 => (-49, 42), 9 => (-7, 7), 10 => (-10, 10), 11 => (-6, 6), 12 => (-15, 15), 13 => (-6, 6), 14 => (-8, 8), 15 => (-6, 6), 16 => (-37, 31), 17 => (-5, 5), 18 => (-7, 7), 19 => (-5, 5), 20 => (-10, 10), 21 => (-5, 5), 22 => (-6, 6), 23 => (-5, 5), 24 => (-15, 15), 25 => (-5, 5), 26 => (-6, 6), 27 => (-5, 5), 28 => (-8, 8), 29 => (-4, 4), 30 => (-6, 6), 31 => (-4, 4), 32 => (-29, 25), 33 => (-4, 4), 34 => (-5, 5), 35 => (-4, 4), 36 => (-7, 7), // Invalid radix _ => unreachable!(), } } } #[inline] fn mantissa_limit(radix: T) -> i32 { debug_assert_radix!(radix); #[cfg(not(feature = "radix"))] { 7 } #[cfg(feature = "radix")] { match radix.as_i32() { 2 => 23, 3 => 15, 4 => 11, 5 => 10, 6 => 9, 7 => 8, 8 => 7, 9 => 7, 10 => 7, 11 => 6, 12 => 6, 13 => 6, 14 => 6, 15 => 6, 16 => 5, 17 => 5, 18 => 5, 19 => 5, 20 => 5, 21 => 5, 22 => 5, 23 => 5, 24 => 5, 25 => 5, 26 => 5, 27 => 5, 28 => 4, 29 => 4, 30 => 4, 31 => 4, 32 => 4, 33 => 4, 34 => 4, 35 => 4, 36 => 4, // Invalid radix _ => unreachable!(), } } } } /// Precalculated min and max exponents for values exactly representable as f64. /// /// Table of values where `radix**min` and `radix**max` are the limits of types /// exactly representable as an f64. impl ExactExponent for f64 { #[inline] fn exponent_limit(radix: T) -> (i32, i32) { debug_assert_radix!(radix); #[cfg(not(feature = "radix"))] { (-22, 22) } #[cfg(feature = "radix")] { match radix.as_i32() { 2 => (-1074, 1023), 3 => (-33, 33), 4 => (-537, 511), 5 => (-22, 22), 6 => (-33, 33), 7 => (-18, 18), 8 => (-358, 341), 9 => (-16, 16), 10 => (-22, 22), 11 => (-15, 15), 12 => (-33, 33), 13 => (-14, 14), 14 => (-18, 18), 15 => (-13, 13), 16 => (-268, 255), 17 => (-12, 12), 18 => (-16, 16), 19 => (-12, 12), 20 => (-22, 22), 21 => (-12, 12), 22 => (-15, 15), 23 => (-11, 11), 24 => (-33, 33), 25 => (-11, 11), 26 => (-14, 14), 27 => (-11, 11), 28 => (-18, 18), 29 => (-10, 10), 30 => (-13, 13), 31 => (-10, 10), 32 => (-214, 204), 33 => (-10, 10), 34 => (-12, 12), 35 => (-10, 10), 36 => (-16, 16), // Invalid radix _ => unreachable!(), } } } #[inline] fn mantissa_limit(radix: T) -> i32 { debug_assert_radix!(radix); #[cfg(not(feature = "radix"))] { 15 } #[cfg(feature = "radix")] { match radix.as_i32() { 2 => 52, 3 => 33, 4 => 26, 5 => 22, 6 => 20, 7 => 18, 8 => 17, 9 => 16, 10 => 15, 11 => 15, 12 => 14, 13 => 14, 14 => 13, 15 => 13, 16 => 13, 17 => 12, 18 => 12, 19 => 12, 20 => 12, 21 => 12, 22 => 11, 23 => 11, 24 => 11, 25 => 11, 26 => 11, 27 => 11, 28 => 11, 29 => 10, 30 => 10, 31 => 10, 32 => 10, 33 => 10, 34 => 10, 35 => 10, 36 => 10, // Invalid radix _ => unreachable!(), } } } } // Conditionally compile the radix POWI tables. // These tables contain all the values that can be exactly represented // by a given float of a certain size. // // Total array storage: 2.1 KB (f32) + 21.5 KB (f64). // The total performance enhancements save ~350+ clock cycles (x86) or // ~100 clock cycles (x87) for the FYL2X and F2XM1 instructions, require // to compute a power. This should be a significant performance win. cfg_if! { if #[cfg(feature = "correct")] { // TRANSMUTE /// Hacky transmute for 32-bit and 64-bit floats. /// /// Remove when `f32::from_bits` and `f64::from_bits` become const /// in stable. #[cfg(feature = "radix")] union Transmute { u: U, f: F, } // TABLE POW /// Calculate powers using pre-calculated lookup tables. /// No error-checking occurs, these methods are not safe. pub(crate) trait TablePower { /// Exponent const POW2_EXPONENT_BIAS: i32; /// Get power of 2 from exponent. #[cfg(feature = "radix")] fn table_pow2(exponent: i32) -> Self; /// Get power of 2 from exponent. fn table_pow(radix: T, exponent: i32) -> Self; } // F32 /// Hacky transmute for 32-bit values. #[cfg(feature = "radix")] type F32Transmute = Transmute; /// Precalculated values of 2**i for i in range [-149, 127]. #[cfg(feature = "radix")] const F32_POW2: [f32; 277] = unsafe {[ // Denormal floats ([-149, -127]) F32Transmute { u: 0x00000001 }.f, F32Transmute { u: 0x00000002 }.f, F32Transmute { u: 0x00000004 }.f, F32Transmute { u: 0x00000008 }.f, F32Transmute { u: 0x00000010 }.f, F32Transmute { u: 0x00000020 }.f, F32Transmute { u: 0x00000040 }.f, F32Transmute { u: 0x00000080 }.f, F32Transmute { u: 0x00000100 }.f, F32Transmute { u: 0x00000200 }.f, F32Transmute { u: 0x00000400 }.f, F32Transmute { u: 0x00000800 }.f, F32Transmute { u: 0x00001000 }.f, F32Transmute { u: 0x00002000 }.f, F32Transmute { u: 0x00004000 }.f, F32Transmute { u: 0x00008000 }.f, F32Transmute { u: 0x00010000 }.f, F32Transmute { u: 0x00020000 }.f, F32Transmute { u: 0x00040000 }.f, F32Transmute { u: 0x00080000 }.f, F32Transmute { u: 0x00100000 }.f, F32Transmute { u: 0x00200000 }.f, F32Transmute { u: 0x00400000 }.f, // Regular floats (exponent only, [-126, 127]) F32Transmute { u: 0x00800000 }.f, F32Transmute { u: 0x01000000 }.f, F32Transmute { u: 0x01800000 }.f, F32Transmute { u: 0x02000000 }.f, F32Transmute { u: 0x02800000 }.f, F32Transmute { u: 0x03000000 }.f, F32Transmute { u: 0x03800000 }.f, F32Transmute { u: 0x04000000 }.f, F32Transmute { u: 0x04800000 }.f, F32Transmute { u: 0x05000000 }.f, F32Transmute { u: 0x05800000 }.f, F32Transmute { u: 0x06000000 }.f, F32Transmute { u: 0x06800000 }.f, F32Transmute { u: 0x07000000 }.f, F32Transmute { u: 0x07800000 }.f, F32Transmute { u: 0x08000000 }.f, F32Transmute { u: 0x08800000 }.f, F32Transmute { u: 0x09000000 }.f, F32Transmute { u: 0x09800000 }.f, F32Transmute { u: 0x0A000000 }.f, F32Transmute { u: 0x0A800000 }.f, F32Transmute { u: 0x0B000000 }.f, F32Transmute { u: 0x0B800000 }.f, F32Transmute { u: 0x0C000000 }.f, F32Transmute { u: 0x0C800000 }.f, F32Transmute { u: 0x0D000000 }.f, F32Transmute { u: 0x0D800000 }.f, F32Transmute { u: 0x0E000000 }.f, F32Transmute { u: 0x0E800000 }.f, F32Transmute { u: 0x0F000000 }.f, F32Transmute { u: 0x0F800000 }.f, F32Transmute { u: 0x10000000 }.f, F32Transmute { u: 0x10800000 }.f, F32Transmute { u: 0x11000000 }.f, F32Transmute { u: 0x11800000 }.f, F32Transmute { u: 0x12000000 }.f, F32Transmute { u: 0x12800000 }.f, F32Transmute { u: 0x13000000 }.f, F32Transmute { u: 0x13800000 }.f, F32Transmute { u: 0x14000000 }.f, F32Transmute { u: 0x14800000 }.f, F32Transmute { u: 0x15000000 }.f, F32Transmute { u: 0x15800000 }.f, F32Transmute { u: 0x16000000 }.f, F32Transmute { u: 0x16800000 }.f, F32Transmute { u: 0x17000000 }.f, F32Transmute { u: 0x17800000 }.f, F32Transmute { u: 0x18000000 }.f, F32Transmute { u: 0x18800000 }.f, F32Transmute { u: 0x19000000 }.f, F32Transmute { u: 0x19800000 }.f, F32Transmute { u: 0x1A000000 }.f, F32Transmute { u: 0x1A800000 }.f, F32Transmute { u: 0x1B000000 }.f, F32Transmute { u: 0x1B800000 }.f, F32Transmute { u: 0x1C000000 }.f, F32Transmute { u: 0x1C800000 }.f, F32Transmute { u: 0x1D000000 }.f, F32Transmute { u: 0x1D800000 }.f, F32Transmute { u: 0x1E000000 }.f, F32Transmute { u: 0x1E800000 }.f, F32Transmute { u: 0x1F000000 }.f, F32Transmute { u: 0x1F800000 }.f, F32Transmute { u: 0x20000000 }.f, F32Transmute { u: 0x20800000 }.f, F32Transmute { u: 0x21000000 }.f, F32Transmute { u: 0x21800000 }.f, F32Transmute { u: 0x22000000 }.f, F32Transmute { u: 0x22800000 }.f, F32Transmute { u: 0x23000000 }.f, F32Transmute { u: 0x23800000 }.f, F32Transmute { u: 0x24000000 }.f, F32Transmute { u: 0x24800000 }.f, F32Transmute { u: 0x25000000 }.f, F32Transmute { u: 0x25800000 }.f, F32Transmute { u: 0x26000000 }.f, F32Transmute { u: 0x26800000 }.f, F32Transmute { u: 0x27000000 }.f, F32Transmute { u: 0x27800000 }.f, F32Transmute { u: 0x28000000 }.f, F32Transmute { u: 0x28800000 }.f, F32Transmute { u: 0x29000000 }.f, F32Transmute { u: 0x29800000 }.f, F32Transmute { u: 0x2A000000 }.f, F32Transmute { u: 0x2A800000 }.f, F32Transmute { u: 0x2B000000 }.f, F32Transmute { u: 0x2B800000 }.f, F32Transmute { u: 0x2C000000 }.f, F32Transmute { u: 0x2C800000 }.f, F32Transmute { u: 0x2D000000 }.f, F32Transmute { u: 0x2D800000 }.f, F32Transmute { u: 0x2E000000 }.f, F32Transmute { u: 0x2E800000 }.f, F32Transmute { u: 0x2F000000 }.f, F32Transmute { u: 0x2F800000 }.f, F32Transmute { u: 0x30000000 }.f, F32Transmute { u: 0x30800000 }.f, F32Transmute { u: 0x31000000 }.f, F32Transmute { u: 0x31800000 }.f, F32Transmute { u: 0x32000000 }.f, F32Transmute { u: 0x32800000 }.f, F32Transmute { u: 0x33000000 }.f, F32Transmute { u: 0x33800000 }.f, F32Transmute { u: 0x34000000 }.f, F32Transmute { u: 0x34800000 }.f, F32Transmute { u: 0x35000000 }.f, F32Transmute { u: 0x35800000 }.f, F32Transmute { u: 0x36000000 }.f, F32Transmute { u: 0x36800000 }.f, F32Transmute { u: 0x37000000 }.f, F32Transmute { u: 0x37800000 }.f, F32Transmute { u: 0x38000000 }.f, F32Transmute { u: 0x38800000 }.f, F32Transmute { u: 0x39000000 }.f, F32Transmute { u: 0x39800000 }.f, F32Transmute { u: 0x3A000000 }.f, F32Transmute { u: 0x3A800000 }.f, F32Transmute { u: 0x3B000000 }.f, F32Transmute { u: 0x3B800000 }.f, F32Transmute { u: 0x3C000000 }.f, F32Transmute { u: 0x3C800000 }.f, F32Transmute { u: 0x3D000000 }.f, F32Transmute { u: 0x3D800000 }.f, F32Transmute { u: 0x3E000000 }.f, F32Transmute { u: 0x3E800000 }.f, F32Transmute { u: 0x3F000000 }.f, F32Transmute { u: 0x3F800000 }.f, F32Transmute { u: 0x40000000 }.f, F32Transmute { u: 0x40800000 }.f, F32Transmute { u: 0x41000000 }.f, F32Transmute { u: 0x41800000 }.f, F32Transmute { u: 0x42000000 }.f, F32Transmute { u: 0x42800000 }.f, F32Transmute { u: 0x43000000 }.f, F32Transmute { u: 0x43800000 }.f, F32Transmute { u: 0x44000000 }.f, F32Transmute { u: 0x44800000 }.f, F32Transmute { u: 0x45000000 }.f, F32Transmute { u: 0x45800000 }.f, F32Transmute { u: 0x46000000 }.f, F32Transmute { u: 0x46800000 }.f, F32Transmute { u: 0x47000000 }.f, F32Transmute { u: 0x47800000 }.f, F32Transmute { u: 0x48000000 }.f, F32Transmute { u: 0x48800000 }.f, F32Transmute { u: 0x49000000 }.f, F32Transmute { u: 0x49800000 }.f, F32Transmute { u: 0x4A000000 }.f, F32Transmute { u: 0x4A800000 }.f, F32Transmute { u: 0x4B000000 }.f, F32Transmute { u: 0x4B800000 }.f, F32Transmute { u: 0x4C000000 }.f, F32Transmute { u: 0x4C800000 }.f, F32Transmute { u: 0x4D000000 }.f, F32Transmute { u: 0x4D800000 }.f, F32Transmute { u: 0x4E000000 }.f, F32Transmute { u: 0x4E800000 }.f, F32Transmute { u: 0x4F000000 }.f, F32Transmute { u: 0x4F800000 }.f, F32Transmute { u: 0x50000000 }.f, F32Transmute { u: 0x50800000 }.f, F32Transmute { u: 0x51000000 }.f, F32Transmute { u: 0x51800000 }.f, F32Transmute { u: 0x52000000 }.f, F32Transmute { u: 0x52800000 }.f, F32Transmute { u: 0x53000000 }.f, F32Transmute { u: 0x53800000 }.f, F32Transmute { u: 0x54000000 }.f, F32Transmute { u: 0x54800000 }.f, F32Transmute { u: 0x55000000 }.f, F32Transmute { u: 0x55800000 }.f, F32Transmute { u: 0x56000000 }.f, F32Transmute { u: 0x56800000 }.f, F32Transmute { u: 0x57000000 }.f, F32Transmute { u: 0x57800000 }.f, F32Transmute { u: 0x58000000 }.f, F32Transmute { u: 0x58800000 }.f, F32Transmute { u: 0x59000000 }.f, F32Transmute { u: 0x59800000 }.f, F32Transmute { u: 0x5A000000 }.f, F32Transmute { u: 0x5A800000 }.f, F32Transmute { u: 0x5B000000 }.f, F32Transmute { u: 0x5B800000 }.f, F32Transmute { u: 0x5C000000 }.f, F32Transmute { u: 0x5C800000 }.f, F32Transmute { u: 0x5D000000 }.f, F32Transmute { u: 0x5D800000 }.f, F32Transmute { u: 0x5E000000 }.f, F32Transmute { u: 0x5E800000 }.f, F32Transmute { u: 0x5F000000 }.f, F32Transmute { u: 0x5F800000 }.f, F32Transmute { u: 0x60000000 }.f, F32Transmute { u: 0x60800000 }.f, F32Transmute { u: 0x61000000 }.f, F32Transmute { u: 0x61800000 }.f, F32Transmute { u: 0x62000000 }.f, F32Transmute { u: 0x62800000 }.f, F32Transmute { u: 0x63000000 }.f, F32Transmute { u: 0x63800000 }.f, F32Transmute { u: 0x64000000 }.f, F32Transmute { u: 0x64800000 }.f, F32Transmute { u: 0x65000000 }.f, F32Transmute { u: 0x65800000 }.f, F32Transmute { u: 0x66000000 }.f, F32Transmute { u: 0x66800000 }.f, F32Transmute { u: 0x67000000 }.f, F32Transmute { u: 0x67800000 }.f, F32Transmute { u: 0x68000000 }.f, F32Transmute { u: 0x68800000 }.f, F32Transmute { u: 0x69000000 }.f, F32Transmute { u: 0x69800000 }.f, F32Transmute { u: 0x6A000000 }.f, F32Transmute { u: 0x6A800000 }.f, F32Transmute { u: 0x6B000000 }.f, F32Transmute { u: 0x6B800000 }.f, F32Transmute { u: 0x6C000000 }.f, F32Transmute { u: 0x6C800000 }.f, F32Transmute { u: 0x6D000000 }.f, F32Transmute { u: 0x6D800000 }.f, F32Transmute { u: 0x6E000000 }.f, F32Transmute { u: 0x6E800000 }.f, F32Transmute { u: 0x6F000000 }.f, F32Transmute { u: 0x6F800000 }.f, F32Transmute { u: 0x70000000 }.f, F32Transmute { u: 0x70800000 }.f, F32Transmute { u: 0x71000000 }.f, F32Transmute { u: 0x71800000 }.f, F32Transmute { u: 0x72000000 }.f, F32Transmute { u: 0x72800000 }.f, F32Transmute { u: 0x73000000 }.f, F32Transmute { u: 0x73800000 }.f, F32Transmute { u: 0x74000000 }.f, F32Transmute { u: 0x74800000 }.f, F32Transmute { u: 0x75000000 }.f, F32Transmute { u: 0x75800000 }.f, F32Transmute { u: 0x76000000 }.f, F32Transmute { u: 0x76800000 }.f, F32Transmute { u: 0x77000000 }.f, F32Transmute { u: 0x77800000 }.f, F32Transmute { u: 0x78000000 }.f, F32Transmute { u: 0x78800000 }.f, F32Transmute { u: 0x79000000 }.f, F32Transmute { u: 0x79800000 }.f, F32Transmute { u: 0x7A000000 }.f, F32Transmute { u: 0x7A800000 }.f, F32Transmute { u: 0x7B000000 }.f, F32Transmute { u: 0x7B800000 }.f, F32Transmute { u: 0x7C000000 }.f, F32Transmute { u: 0x7C800000 }.f, F32Transmute { u: 0x7D000000 }.f, F32Transmute { u: 0x7D800000 }.f, F32Transmute { u: 0x7E000000 }.f, F32Transmute { u: 0x7E800000 }.f, F32Transmute { u: 0x7F000000 }.f, ]}; /// Precalculated values of radix**i for i in range [0, arr.len()-1]. /// Each value can be **exactly** represented as that type. const F32_POW10: [f32; 11] = [1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0, 10000000000.0]; #[cfg(feature = "radix")] const F32_POW3: [f32; 16] = [1.0, 3.0, 9.0, 27.0, 81.0, 243.0, 729.0, 2187.0, 6561.0, 19683.0, 59049.0, 177147.0, 531441.0, 1594323.0, 4782969.0, 14348907.0]; #[cfg(feature = "radix")] const F32_POW5: [f32; 11] = [1.0, 5.0, 25.0, 125.0, 625.0, 3125.0, 15625.0, 78125.0, 390625.0, 1953125.0, 9765625.0]; #[cfg(feature = "radix")] const F32_POW6: [f32; 16] = [1.0, 6.0, 36.0, 216.0, 1296.0, 7776.0, 46656.0, 279936.0, 1679616.0, 10077696.0, 60466176.0, 362797056.0, 2176782336.0, 13060694016.0, 78364164096.0, 470184984576.0]; #[cfg(feature = "radix")] const F32_POW7: [f32; 9] = [1.0, 7.0, 49.0, 343.0, 2401.0, 16807.0, 117649.0, 823543.0, 5764801.0]; #[cfg(feature = "radix")] const F32_POW9: [f32; 8] = [1.0, 9.0, 81.0, 729.0, 6561.0, 59049.0, 531441.0, 4782969.0]; #[cfg(feature = "radix")] const F32_POW11: [f32; 7] = [1.0, 11.0, 121.0, 1331.0, 14641.0, 161051.0, 1771561.0]; #[cfg(feature = "radix")] const F32_POW12: [f32; 16] = [1.0, 12.0, 144.0, 1728.0, 20736.0, 248832.0, 2985984.0, 35831808.0, 429981696.0, 5159780352.0, 61917364224.0, 743008370688.0, 8916100448256.0, 106993205379072.0, 1283918464548864.0, 15407021574586368.0]; #[cfg(feature = "radix")] const F32_POW13: [f32; 7] = [1.0, 13.0, 169.0, 2197.0, 28561.0, 371293.0, 4826809.0]; #[cfg(feature = "radix")] const F32_POW14: [f32; 9] = [1.0, 14.0, 196.0, 2744.0, 38416.0, 537824.0, 7529536.0, 105413504.0, 1475789056.0]; #[cfg(feature = "radix")] const F32_POW15: [f32; 7] = [1.0, 15.0, 225.0, 3375.0, 50625.0, 759375.0, 11390625.0]; #[cfg(feature = "radix")] const F32_POW17: [f32; 6] = [1.0, 17.0, 289.0, 4913.0, 83521.0, 1419857.0]; #[cfg(feature = "radix")] const F32_POW18: [f32; 8] = [1.0, 18.0, 324.0, 5832.0, 104976.0, 1889568.0, 34012224.0, 612220032.0]; #[cfg(feature = "radix")] const F32_POW19: [f32; 6] = [1.0, 19.0, 361.0, 6859.0, 130321.0, 2476099.0]; #[cfg(feature = "radix")] const F32_POW20: [f32; 11] = [1.0, 20.0, 400.0, 8000.0, 160000.0, 3200000.0, 64000000.0, 1280000000.0, 25600000000.0, 512000000000.0, 10240000000000.0]; #[cfg(feature = "radix")] const F32_POW21: [f32; 6] = [1.0, 21.0, 441.0, 9261.0, 194481.0, 4084101.0]; #[cfg(feature = "radix")] const F32_POW22: [f32; 7] = [1.0, 22.0, 484.0, 10648.0, 234256.0, 5153632.0, 113379904.0]; #[cfg(feature = "radix")] const F32_POW23: [f32; 6] = [1.0, 23.0, 529.0, 12167.0, 279841.0, 6436343.0]; #[cfg(feature = "radix")] const F32_POW24: [f32; 16] = [1.0, 24.0, 576.0, 13824.0, 331776.0, 7962624.0, 191102976.0, 4586471424.0, 110075314176.0, 2641807540224.0, 63403380965376.0, 1521681143169024.0, 36520347436056576.0, 876488338465357824.0, 21035720123168587776.0, 504857282956046106624.0]; #[cfg(feature = "radix")] const F32_POW25: [f32; 6] = [1.0, 25.0, 625.0, 15625.0, 390625.0, 9765625.0]; #[cfg(feature = "radix")] const F32_POW26: [f32; 7] = [1.0, 26.0, 676.0, 17576.0, 456976.0, 11881376.0, 308915776.0]; #[cfg(feature = "radix")] const F32_POW27: [f32; 6] = [1.0, 27.0, 729.0, 19683.0, 531441.0, 14348907.0]; #[cfg(feature = "radix")] const F32_POW28: [f32; 9] = [1.0, 28.0, 784.0, 21952.0, 614656.0, 17210368.0, 481890304.0, 13492928512.0, 377801998336.0]; #[cfg(feature = "radix")] const F32_POW29: [f32; 5] = [1.0, 29.0, 841.0, 24389.0, 707281.0]; #[cfg(feature = "radix")] const F32_POW30: [f32; 7] = [1.0, 30.0, 900.0, 27000.0, 810000.0, 24300000.0, 729000000.0]; #[cfg(feature = "radix")] const F32_POW31: [f32; 5] = [1.0, 31.0, 961.0, 29791.0, 923521.0]; #[cfg(feature = "radix")] const F32_POW33: [f32; 5] = [1.0, 33.0, 1089.0, 35937.0, 1185921.0]; #[cfg(feature = "radix")] const F32_POW34: [f32; 6] = [1.0, 34.0, 1156.0, 39304.0, 1336336.0, 45435424.0]; #[cfg(feature = "radix")] const F32_POW35: [f32; 5] = [1.0, 35.0, 1225.0, 42875.0, 1500625.0]; #[cfg(feature = "radix")] const F32_POW36: [f32; 8] = [1.0, 36.0, 1296.0, 46656.0, 1679616.0, 60466176.0, 2176782336.0, 78364164096.0]; // Compile-time guarantees for our tables. const_assert!(F32_POW10[1] / F32_POW10[0] == 10.0); #[cfg(feature = "radix")] const_assert!(F32_POW2[1] / F32_POW2[0] == 2.0); #[cfg(feature = "radix")] const_assert!(F32_POW3[1] / F32_POW3[0] == 3.0); #[cfg(feature = "radix")] const_assert!(F32_POW5[1] / F32_POW5[0] == 5.0); #[cfg(feature = "radix")] const_assert!(F32_POW6[1] / F32_POW6[0] == 6.0); #[cfg(feature = "radix")] const_assert!(F32_POW7[1] / F32_POW7[0] == 7.0); #[cfg(feature = "radix")] const_assert!(F32_POW9[1] / F32_POW9[0] == 9.0); #[cfg(feature = "radix")] const_assert!(F32_POW11[1] / F32_POW11[0] == 11.0); #[cfg(feature = "radix")] const_assert!(F32_POW12[1] / F32_POW12[0] == 12.0); #[cfg(feature = "radix")] const_assert!(F32_POW13[1] / F32_POW13[0] == 13.0); #[cfg(feature = "radix")] const_assert!(F32_POW14[1] / F32_POW14[0] == 14.0); #[cfg(feature = "radix")] const_assert!(F32_POW15[1] / F32_POW15[0] == 15.0); #[cfg(feature = "radix")] const_assert!(F32_POW17[1] / F32_POW17[0] == 17.0); #[cfg(feature = "radix")] const_assert!(F32_POW18[1] / F32_POW18[0] == 18.0); #[cfg(feature = "radix")] const_assert!(F32_POW19[1] / F32_POW19[0] == 19.0); #[cfg(feature = "radix")] const_assert!(F32_POW20[1] / F32_POW20[0] == 20.0); #[cfg(feature = "radix")] const_assert!(F32_POW21[1] / F32_POW21[0] == 21.0); #[cfg(feature = "radix")] const_assert!(F32_POW22[1] / F32_POW22[0] == 22.0); #[cfg(feature = "radix")] const_assert!(F32_POW23[1] / F32_POW23[0] == 23.0); #[cfg(feature = "radix")] const_assert!(F32_POW24[1] / F32_POW24[0] == 24.0); #[cfg(feature = "radix")] const_assert!(F32_POW25[1] / F32_POW25[0] == 25.0); #[cfg(feature = "radix")] const_assert!(F32_POW26[1] / F32_POW26[0] == 26.0); #[cfg(feature = "radix")] const_assert!(F32_POW27[1] / F32_POW27[0] == 27.0); #[cfg(feature = "radix")] const_assert!(F32_POW28[1] / F32_POW28[0] == 28.0); #[cfg(feature = "radix")] const_assert!(F32_POW29[1] / F32_POW29[0] == 29.0); #[cfg(feature = "radix")] const_assert!(F32_POW30[1] / F32_POW30[0] == 30.0); #[cfg(feature = "radix")] const_assert!(F32_POW31[1] / F32_POW31[0] == 31.0); #[cfg(feature = "radix")] const_assert!(F32_POW33[1] / F32_POW33[0] == 33.0); #[cfg(feature = "radix")] const_assert!(F32_POW34[1] / F32_POW34[0] == 34.0); #[cfg(feature = "radix")] const_assert!(F32_POW35[1] / F32_POW35[0] == 35.0); #[cfg(feature = "radix")] const_assert!(F32_POW36[1] / F32_POW36[0] == 36.0); impl TablePower for f32 { const POW2_EXPONENT_BIAS: i32 = 149; #[cfg(feature = "radix")] #[inline] fn table_pow2(exponent: i32) -> f32 { debug_assert!(exponent + Self::POW2_EXPONENT_BIAS >= 0, "table_pow2() have negative exponent."); F32_POW2[(exponent + Self::POW2_EXPONENT_BIAS).as_usize()] } #[inline] fn table_pow(radix: T, exponent: i32) -> f32 { debug_assert!(exponent >= 0, "table_pow() have negative exponent."); debug_assert_radix!(radix); let exponent = exponent as usize; #[cfg(not(feature = "radix"))] { F32_POW10[exponent] } #[cfg(feature = "radix")] { match radix.as_i32() { 3 => F32_POW3 [exponent], 5 => F32_POW5 [exponent], 6 => F32_POW6 [exponent], 7 => F32_POW7 [exponent], 9 => F32_POW9 [exponent], 10 => F32_POW10[exponent], 11 => F32_POW11[exponent], 12 => F32_POW12[exponent], 13 => F32_POW13[exponent], 14 => F32_POW14[exponent], 15 => F32_POW15[exponent], 17 => F32_POW17[exponent], 18 => F32_POW18[exponent], 19 => F32_POW19[exponent], 20 => F32_POW20[exponent], 21 => F32_POW21[exponent], 22 => F32_POW22[exponent], 23 => F32_POW23[exponent], 24 => F32_POW24[exponent], 25 => F32_POW25[exponent], 26 => F32_POW26[exponent], 27 => F32_POW27[exponent], 28 => F32_POW28[exponent], 29 => F32_POW29[exponent], 30 => F32_POW30[exponent], 31 => F32_POW31[exponent], 33 => F32_POW33[exponent], 34 => F32_POW34[exponent], 35 => F32_POW35[exponent], 36 => F32_POW36[exponent], // Invalid radix _ => unreachable!(), } } } } // F64 /// Hacky transmute for 64-bit values. #[cfg(feature = "radix")] type F64Transmute = Transmute; /// Precalculated values of 2**i for i in range [-1074, 1023]. #[cfg(feature = "radix")] const F64_POW2: [f64; 2098] = unsafe {[ // Denormal floats ([-1074, -1023]) F64Transmute { u: 0x0000000000000001 }.f, F64Transmute { u: 0x0000000000000002 }.f, F64Transmute { u: 0x0000000000000004 }.f, F64Transmute { u: 0x0000000000000008 }.f, F64Transmute { u: 0x0000000000000010 }.f, F64Transmute { u: 0x0000000000000020 }.f, F64Transmute { u: 0x0000000000000040 }.f, F64Transmute { u: 0x0000000000000080 }.f, F64Transmute { u: 0x0000000000000100 }.f, F64Transmute { u: 0x0000000000000200 }.f, F64Transmute { u: 0x0000000000000400 }.f, F64Transmute { u: 0x0000000000000800 }.f, F64Transmute { u: 0x0000000000001000 }.f, F64Transmute { u: 0x0000000000002000 }.f, F64Transmute { u: 0x0000000000004000 }.f, F64Transmute { u: 0x0000000000008000 }.f, F64Transmute { u: 0x0000000000010000 }.f, F64Transmute { u: 0x0000000000020000 }.f, F64Transmute { u: 0x0000000000040000 }.f, F64Transmute { u: 0x0000000000080000 }.f, F64Transmute { u: 0x0000000000100000 }.f, F64Transmute { u: 0x0000000000200000 }.f, F64Transmute { u: 0x0000000000400000 }.f, F64Transmute { u: 0x0000000000800000 }.f, F64Transmute { u: 0x0000000001000000 }.f, F64Transmute { u: 0x0000000002000000 }.f, F64Transmute { u: 0x0000000004000000 }.f, F64Transmute { u: 0x0000000008000000 }.f, F64Transmute { u: 0x0000000010000000 }.f, F64Transmute { u: 0x0000000020000000 }.f, F64Transmute { u: 0x0000000040000000 }.f, F64Transmute { u: 0x0000000080000000 }.f, F64Transmute { u: 0x0000000100000000 }.f, F64Transmute { u: 0x0000000200000000 }.f, F64Transmute { u: 0x0000000400000000 }.f, F64Transmute { u: 0x0000000800000000 }.f, F64Transmute { u: 0x0000001000000000 }.f, F64Transmute { u: 0x0000002000000000 }.f, F64Transmute { u: 0x0000004000000000 }.f, F64Transmute { u: 0x0000008000000000 }.f, F64Transmute { u: 0x0000010000000000 }.f, F64Transmute { u: 0x0000020000000000 }.f, F64Transmute { u: 0x0000040000000000 }.f, F64Transmute { u: 0x0000080000000000 }.f, F64Transmute { u: 0x0000100000000000 }.f, F64Transmute { u: 0x0000200000000000 }.f, F64Transmute { u: 0x0000400000000000 }.f, F64Transmute { u: 0x0000800000000000 }.f, F64Transmute { u: 0x0001000000000000 }.f, F64Transmute { u: 0x0002000000000000 }.f, F64Transmute { u: 0x0004000000000000 }.f, F64Transmute { u: 0x0008000000000000 }.f, // Regular floats (exponent only, [-1022, 1023]) F64Transmute { u: 0x0010000000000000 }.f, F64Transmute { u: 0x0020000000000000 }.f, F64Transmute { u: 0x0030000000000000 }.f, F64Transmute { u: 0x0040000000000000 }.f, F64Transmute { u: 0x0050000000000000 }.f, F64Transmute { u: 0x0060000000000000 }.f, F64Transmute { u: 0x0070000000000000 }.f, F64Transmute { u: 0x0080000000000000 }.f, F64Transmute { u: 0x0090000000000000 }.f, F64Transmute { u: 0x00A0000000000000 }.f, F64Transmute { u: 0x00B0000000000000 }.f, F64Transmute { u: 0x00C0000000000000 }.f, F64Transmute { u: 0x00D0000000000000 }.f, F64Transmute { u: 0x00E0000000000000 }.f, F64Transmute { u: 0x00F0000000000000 }.f, F64Transmute { u: 0x0100000000000000 }.f, F64Transmute { u: 0x0110000000000000 }.f, F64Transmute { u: 0x0120000000000000 }.f, F64Transmute { u: 0x0130000000000000 }.f, F64Transmute { u: 0x0140000000000000 }.f, F64Transmute { u: 0x0150000000000000 }.f, F64Transmute { u: 0x0160000000000000 }.f, F64Transmute { u: 0x0170000000000000 }.f, F64Transmute { u: 0x0180000000000000 }.f, F64Transmute { u: 0x0190000000000000 }.f, F64Transmute { u: 0x01A0000000000000 }.f, F64Transmute { u: 0x01B0000000000000 }.f, F64Transmute { u: 0x01C0000000000000 }.f, F64Transmute { u: 0x01D0000000000000 }.f, F64Transmute { u: 0x01E0000000000000 }.f, F64Transmute { u: 0x01F0000000000000 }.f, F64Transmute { u: 0x0200000000000000 }.f, F64Transmute { u: 0x0210000000000000 }.f, F64Transmute { u: 0x0220000000000000 }.f, F64Transmute { u: 0x0230000000000000 }.f, F64Transmute { u: 0x0240000000000000 }.f, F64Transmute { u: 0x0250000000000000 }.f, F64Transmute { u: 0x0260000000000000 }.f, F64Transmute { u: 0x0270000000000000 }.f, F64Transmute { u: 0x0280000000000000 }.f, F64Transmute { u: 0x0290000000000000 }.f, F64Transmute { u: 0x02A0000000000000 }.f, F64Transmute { u: 0x02B0000000000000 }.f, F64Transmute { u: 0x02C0000000000000 }.f, F64Transmute { u: 0x02D0000000000000 }.f, F64Transmute { u: 0x02E0000000000000 }.f, F64Transmute { u: 0x02F0000000000000 }.f, F64Transmute { u: 0x0300000000000000 }.f, F64Transmute { u: 0x0310000000000000 }.f, F64Transmute { u: 0x0320000000000000 }.f, F64Transmute { u: 0x0330000000000000 }.f, F64Transmute { u: 0x0340000000000000 }.f, F64Transmute { u: 0x0350000000000000 }.f, F64Transmute { u: 0x0360000000000000 }.f, F64Transmute { u: 0x0370000000000000 }.f, F64Transmute { u: 0x0380000000000000 }.f, F64Transmute { u: 0x0390000000000000 }.f, F64Transmute { u: 0x03A0000000000000 }.f, F64Transmute { u: 0x03B0000000000000 }.f, F64Transmute { u: 0x03C0000000000000 }.f, F64Transmute { u: 0x03D0000000000000 }.f, F64Transmute { u: 0x03E0000000000000 }.f, F64Transmute { u: 0x03F0000000000000 }.f, F64Transmute { u: 0x0400000000000000 }.f, F64Transmute { u: 0x0410000000000000 }.f, F64Transmute { u: 0x0420000000000000 }.f, F64Transmute { u: 0x0430000000000000 }.f, F64Transmute { u: 0x0440000000000000 }.f, F64Transmute { u: 0x0450000000000000 }.f, F64Transmute { u: 0x0460000000000000 }.f, F64Transmute { u: 0x0470000000000000 }.f, F64Transmute { u: 0x0480000000000000 }.f, F64Transmute { u: 0x0490000000000000 }.f, F64Transmute { u: 0x04A0000000000000 }.f, F64Transmute { u: 0x04B0000000000000 }.f, F64Transmute { u: 0x04C0000000000000 }.f, F64Transmute { u: 0x04D0000000000000 }.f, F64Transmute { u: 0x04E0000000000000 }.f, F64Transmute { u: 0x04F0000000000000 }.f, F64Transmute { u: 0x0500000000000000 }.f, F64Transmute { u: 0x0510000000000000 }.f, F64Transmute { u: 0x0520000000000000 }.f, F64Transmute { u: 0x0530000000000000 }.f, F64Transmute { u: 0x0540000000000000 }.f, F64Transmute { u: 0x0550000000000000 }.f, F64Transmute { u: 0x0560000000000000 }.f, F64Transmute { u: 0x0570000000000000 }.f, F64Transmute { u: 0x0580000000000000 }.f, F64Transmute { u: 0x0590000000000000 }.f, F64Transmute { u: 0x05A0000000000000 }.f, F64Transmute { u: 0x05B0000000000000 }.f, F64Transmute { u: 0x05C0000000000000 }.f, F64Transmute { u: 0x05D0000000000000 }.f, F64Transmute { u: 0x05E0000000000000 }.f, F64Transmute { u: 0x05F0000000000000 }.f, F64Transmute { u: 0x0600000000000000 }.f, F64Transmute { u: 0x0610000000000000 }.f, F64Transmute { u: 0x0620000000000000 }.f, F64Transmute { u: 0x0630000000000000 }.f, F64Transmute { u: 0x0640000000000000 }.f, F64Transmute { u: 0x0650000000000000 }.f, F64Transmute { u: 0x0660000000000000 }.f, F64Transmute { u: 0x0670000000000000 }.f, F64Transmute { u: 0x0680000000000000 }.f, F64Transmute { u: 0x0690000000000000 }.f, F64Transmute { u: 0x06A0000000000000 }.f, F64Transmute { u: 0x06B0000000000000 }.f, F64Transmute { u: 0x06C0000000000000 }.f, F64Transmute { u: 0x06D0000000000000 }.f, F64Transmute { u: 0x06E0000000000000 }.f, F64Transmute { u: 0x06F0000000000000 }.f, F64Transmute { u: 0x0700000000000000 }.f, F64Transmute { u: 0x0710000000000000 }.f, F64Transmute { u: 0x0720000000000000 }.f, F64Transmute { u: 0x0730000000000000 }.f, F64Transmute { u: 0x0740000000000000 }.f, F64Transmute { u: 0x0750000000000000 }.f, F64Transmute { u: 0x0760000000000000 }.f, F64Transmute { u: 0x0770000000000000 }.f, F64Transmute { u: 0x0780000000000000 }.f, F64Transmute { u: 0x0790000000000000 }.f, F64Transmute { u: 0x07A0000000000000 }.f, F64Transmute { u: 0x07B0000000000000 }.f, F64Transmute { u: 0x07C0000000000000 }.f, F64Transmute { u: 0x07D0000000000000 }.f, F64Transmute { u: 0x07E0000000000000 }.f, F64Transmute { u: 0x07F0000000000000 }.f, F64Transmute { u: 0x0800000000000000 }.f, F64Transmute { u: 0x0810000000000000 }.f, F64Transmute { u: 0x0820000000000000 }.f, F64Transmute { u: 0x0830000000000000 }.f, F64Transmute { u: 0x0840000000000000 }.f, F64Transmute { u: 0x0850000000000000 }.f, F64Transmute { u: 0x0860000000000000 }.f, F64Transmute { u: 0x0870000000000000 }.f, F64Transmute { u: 0x0880000000000000 }.f, F64Transmute { u: 0x0890000000000000 }.f, F64Transmute { u: 0x08A0000000000000 }.f, F64Transmute { u: 0x08B0000000000000 }.f, F64Transmute { u: 0x08C0000000000000 }.f, F64Transmute { u: 0x08D0000000000000 }.f, F64Transmute { u: 0x08E0000000000000 }.f, F64Transmute { u: 0x08F0000000000000 }.f, F64Transmute { u: 0x0900000000000000 }.f, F64Transmute { u: 0x0910000000000000 }.f, F64Transmute { u: 0x0920000000000000 }.f, F64Transmute { u: 0x0930000000000000 }.f, F64Transmute { u: 0x0940000000000000 }.f, F64Transmute { u: 0x0950000000000000 }.f, F64Transmute { u: 0x0960000000000000 }.f, F64Transmute { u: 0x0970000000000000 }.f, F64Transmute { u: 0x0980000000000000 }.f, F64Transmute { u: 0x0990000000000000 }.f, F64Transmute { u: 0x09A0000000000000 }.f, F64Transmute { u: 0x09B0000000000000 }.f, F64Transmute { u: 0x09C0000000000000 }.f, F64Transmute { u: 0x09D0000000000000 }.f, F64Transmute { u: 0x09E0000000000000 }.f, F64Transmute { u: 0x09F0000000000000 }.f, F64Transmute { u: 0x0A00000000000000 }.f, F64Transmute { u: 0x0A10000000000000 }.f, F64Transmute { u: 0x0A20000000000000 }.f, F64Transmute { u: 0x0A30000000000000 }.f, F64Transmute { u: 0x0A40000000000000 }.f, F64Transmute { u: 0x0A50000000000000 }.f, F64Transmute { u: 0x0A60000000000000 }.f, F64Transmute { u: 0x0A70000000000000 }.f, F64Transmute { u: 0x0A80000000000000 }.f, F64Transmute { u: 0x0A90000000000000 }.f, F64Transmute { u: 0x0AA0000000000000 }.f, F64Transmute { u: 0x0AB0000000000000 }.f, F64Transmute { u: 0x0AC0000000000000 }.f, F64Transmute { u: 0x0AD0000000000000 }.f, F64Transmute { u: 0x0AE0000000000000 }.f, F64Transmute { u: 0x0AF0000000000000 }.f, F64Transmute { u: 0x0B00000000000000 }.f, F64Transmute { u: 0x0B10000000000000 }.f, F64Transmute { u: 0x0B20000000000000 }.f, F64Transmute { u: 0x0B30000000000000 }.f, F64Transmute { u: 0x0B40000000000000 }.f, F64Transmute { u: 0x0B50000000000000 }.f, F64Transmute { u: 0x0B60000000000000 }.f, F64Transmute { u: 0x0B70000000000000 }.f, F64Transmute { u: 0x0B80000000000000 }.f, F64Transmute { u: 0x0B90000000000000 }.f, F64Transmute { u: 0x0BA0000000000000 }.f, F64Transmute { u: 0x0BB0000000000000 }.f, F64Transmute { u: 0x0BC0000000000000 }.f, F64Transmute { u: 0x0BD0000000000000 }.f, F64Transmute { u: 0x0BE0000000000000 }.f, F64Transmute { u: 0x0BF0000000000000 }.f, F64Transmute { u: 0x0C00000000000000 }.f, F64Transmute { u: 0x0C10000000000000 }.f, F64Transmute { u: 0x0C20000000000000 }.f, F64Transmute { u: 0x0C30000000000000 }.f, F64Transmute { u: 0x0C40000000000000 }.f, F64Transmute { u: 0x0C50000000000000 }.f, F64Transmute { u: 0x0C60000000000000 }.f, F64Transmute { u: 0x0C70000000000000 }.f, F64Transmute { u: 0x0C80000000000000 }.f, F64Transmute { u: 0x0C90000000000000 }.f, F64Transmute { u: 0x0CA0000000000000 }.f, F64Transmute { u: 0x0CB0000000000000 }.f, F64Transmute { u: 0x0CC0000000000000 }.f, F64Transmute { u: 0x0CD0000000000000 }.f, F64Transmute { u: 0x0CE0000000000000 }.f, F64Transmute { u: 0x0CF0000000000000 }.f, F64Transmute { u: 0x0D00000000000000 }.f, F64Transmute { u: 0x0D10000000000000 }.f, F64Transmute { u: 0x0D20000000000000 }.f, F64Transmute { u: 0x0D30000000000000 }.f, F64Transmute { u: 0x0D40000000000000 }.f, F64Transmute { u: 0x0D50000000000000 }.f, F64Transmute { u: 0x0D60000000000000 }.f, F64Transmute { u: 0x0D70000000000000 }.f, F64Transmute { u: 0x0D80000000000000 }.f, F64Transmute { u: 0x0D90000000000000 }.f, F64Transmute { u: 0x0DA0000000000000 }.f, F64Transmute { u: 0x0DB0000000000000 }.f, F64Transmute { u: 0x0DC0000000000000 }.f, F64Transmute { u: 0x0DD0000000000000 }.f, F64Transmute { u: 0x0DE0000000000000 }.f, F64Transmute { u: 0x0DF0000000000000 }.f, F64Transmute { u: 0x0E00000000000000 }.f, F64Transmute { u: 0x0E10000000000000 }.f, F64Transmute { u: 0x0E20000000000000 }.f, F64Transmute { u: 0x0E30000000000000 }.f, F64Transmute { u: 0x0E40000000000000 }.f, F64Transmute { u: 0x0E50000000000000 }.f, F64Transmute { u: 0x0E60000000000000 }.f, F64Transmute { u: 0x0E70000000000000 }.f, F64Transmute { u: 0x0E80000000000000 }.f, F64Transmute { u: 0x0E90000000000000 }.f, F64Transmute { u: 0x0EA0000000000000 }.f, F64Transmute { u: 0x0EB0000000000000 }.f, F64Transmute { u: 0x0EC0000000000000 }.f, F64Transmute { u: 0x0ED0000000000000 }.f, F64Transmute { u: 0x0EE0000000000000 }.f, F64Transmute { u: 0x0EF0000000000000 }.f, F64Transmute { u: 0x0F00000000000000 }.f, F64Transmute { u: 0x0F10000000000000 }.f, F64Transmute { u: 0x0F20000000000000 }.f, F64Transmute { u: 0x0F30000000000000 }.f, F64Transmute { u: 0x0F40000000000000 }.f, F64Transmute { u: 0x0F50000000000000 }.f, F64Transmute { u: 0x0F60000000000000 }.f, F64Transmute { u: 0x0F70000000000000 }.f, F64Transmute { u: 0x0F80000000000000 }.f, F64Transmute { u: 0x0F90000000000000 }.f, F64Transmute { u: 0x0FA0000000000000 }.f, F64Transmute { u: 0x0FB0000000000000 }.f, F64Transmute { u: 0x0FC0000000000000 }.f, F64Transmute { u: 0x0FD0000000000000 }.f, F64Transmute { u: 0x0FE0000000000000 }.f, F64Transmute { u: 0x0FF0000000000000 }.f, F64Transmute { u: 0x1000000000000000 }.f, F64Transmute { u: 0x1010000000000000 }.f, F64Transmute { u: 0x1020000000000000 }.f, F64Transmute { u: 0x1030000000000000 }.f, F64Transmute { u: 0x1040000000000000 }.f, F64Transmute { u: 0x1050000000000000 }.f, F64Transmute { u: 0x1060000000000000 }.f, F64Transmute { u: 0x1070000000000000 }.f, F64Transmute { u: 0x1080000000000000 }.f, F64Transmute { u: 0x1090000000000000 }.f, F64Transmute { u: 0x10A0000000000000 }.f, F64Transmute { u: 0x10B0000000000000 }.f, F64Transmute { u: 0x10C0000000000000 }.f, F64Transmute { u: 0x10D0000000000000 }.f, F64Transmute { u: 0x10E0000000000000 }.f, F64Transmute { u: 0x10F0000000000000 }.f, F64Transmute { u: 0x1100000000000000 }.f, F64Transmute { u: 0x1110000000000000 }.f, F64Transmute { u: 0x1120000000000000 }.f, F64Transmute { u: 0x1130000000000000 }.f, F64Transmute { u: 0x1140000000000000 }.f, F64Transmute { u: 0x1150000000000000 }.f, F64Transmute { u: 0x1160000000000000 }.f, F64Transmute { u: 0x1170000000000000 }.f, F64Transmute { u: 0x1180000000000000 }.f, F64Transmute { u: 0x1190000000000000 }.f, F64Transmute { u: 0x11A0000000000000 }.f, F64Transmute { u: 0x11B0000000000000 }.f, F64Transmute { u: 0x11C0000000000000 }.f, F64Transmute { u: 0x11D0000000000000 }.f, F64Transmute { u: 0x11E0000000000000 }.f, F64Transmute { u: 0x11F0000000000000 }.f, F64Transmute { u: 0x1200000000000000 }.f, F64Transmute { u: 0x1210000000000000 }.f, F64Transmute { u: 0x1220000000000000 }.f, F64Transmute { u: 0x1230000000000000 }.f, F64Transmute { u: 0x1240000000000000 }.f, F64Transmute { u: 0x1250000000000000 }.f, F64Transmute { u: 0x1260000000000000 }.f, F64Transmute { u: 0x1270000000000000 }.f, F64Transmute { u: 0x1280000000000000 }.f, F64Transmute { u: 0x1290000000000000 }.f, F64Transmute { u: 0x12A0000000000000 }.f, F64Transmute { u: 0x12B0000000000000 }.f, F64Transmute { u: 0x12C0000000000000 }.f, F64Transmute { u: 0x12D0000000000000 }.f, F64Transmute { u: 0x12E0000000000000 }.f, F64Transmute { u: 0x12F0000000000000 }.f, F64Transmute { u: 0x1300000000000000 }.f, F64Transmute { u: 0x1310000000000000 }.f, F64Transmute { u: 0x1320000000000000 }.f, F64Transmute { u: 0x1330000000000000 }.f, F64Transmute { u: 0x1340000000000000 }.f, F64Transmute { u: 0x1350000000000000 }.f, F64Transmute { u: 0x1360000000000000 }.f, F64Transmute { u: 0x1370000000000000 }.f, F64Transmute { u: 0x1380000000000000 }.f, F64Transmute { u: 0x1390000000000000 }.f, F64Transmute { u: 0x13A0000000000000 }.f, F64Transmute { u: 0x13B0000000000000 }.f, F64Transmute { u: 0x13C0000000000000 }.f, F64Transmute { u: 0x13D0000000000000 }.f, F64Transmute { u: 0x13E0000000000000 }.f, F64Transmute { u: 0x13F0000000000000 }.f, F64Transmute { u: 0x1400000000000000 }.f, F64Transmute { u: 0x1410000000000000 }.f, F64Transmute { u: 0x1420000000000000 }.f, F64Transmute { u: 0x1430000000000000 }.f, F64Transmute { u: 0x1440000000000000 }.f, F64Transmute { u: 0x1450000000000000 }.f, F64Transmute { u: 0x1460000000000000 }.f, F64Transmute { u: 0x1470000000000000 }.f, F64Transmute { u: 0x1480000000000000 }.f, F64Transmute { u: 0x1490000000000000 }.f, F64Transmute { u: 0x14A0000000000000 }.f, F64Transmute { u: 0x14B0000000000000 }.f, F64Transmute { u: 0x14C0000000000000 }.f, F64Transmute { u: 0x14D0000000000000 }.f, F64Transmute { u: 0x14E0000000000000 }.f, F64Transmute { u: 0x14F0000000000000 }.f, F64Transmute { u: 0x1500000000000000 }.f, F64Transmute { u: 0x1510000000000000 }.f, F64Transmute { u: 0x1520000000000000 }.f, F64Transmute { u: 0x1530000000000000 }.f, F64Transmute { u: 0x1540000000000000 }.f, F64Transmute { u: 0x1550000000000000 }.f, F64Transmute { u: 0x1560000000000000 }.f, F64Transmute { u: 0x1570000000000000 }.f, F64Transmute { u: 0x1580000000000000 }.f, F64Transmute { u: 0x1590000000000000 }.f, F64Transmute { u: 0x15A0000000000000 }.f, F64Transmute { u: 0x15B0000000000000 }.f, F64Transmute { u: 0x15C0000000000000 }.f, F64Transmute { u: 0x15D0000000000000 }.f, F64Transmute { u: 0x15E0000000000000 }.f, F64Transmute { u: 0x15F0000000000000 }.f, F64Transmute { u: 0x1600000000000000 }.f, F64Transmute { u: 0x1610000000000000 }.f, F64Transmute { u: 0x1620000000000000 }.f, F64Transmute { u: 0x1630000000000000 }.f, F64Transmute { u: 0x1640000000000000 }.f, F64Transmute { u: 0x1650000000000000 }.f, F64Transmute { u: 0x1660000000000000 }.f, F64Transmute { u: 0x1670000000000000 }.f, F64Transmute { u: 0x1680000000000000 }.f, F64Transmute { u: 0x1690000000000000 }.f, F64Transmute { u: 0x16A0000000000000 }.f, F64Transmute { u: 0x16B0000000000000 }.f, F64Transmute { u: 0x16C0000000000000 }.f, F64Transmute { u: 0x16D0000000000000 }.f, F64Transmute { u: 0x16E0000000000000 }.f, F64Transmute { u: 0x16F0000000000000 }.f, F64Transmute { u: 0x1700000000000000 }.f, F64Transmute { u: 0x1710000000000000 }.f, F64Transmute { u: 0x1720000000000000 }.f, F64Transmute { u: 0x1730000000000000 }.f, F64Transmute { u: 0x1740000000000000 }.f, F64Transmute { u: 0x1750000000000000 }.f, F64Transmute { u: 0x1760000000000000 }.f, F64Transmute { u: 0x1770000000000000 }.f, F64Transmute { u: 0x1780000000000000 }.f, F64Transmute { u: 0x1790000000000000 }.f, F64Transmute { u: 0x17A0000000000000 }.f, F64Transmute { u: 0x17B0000000000000 }.f, F64Transmute { u: 0x17C0000000000000 }.f, F64Transmute { u: 0x17D0000000000000 }.f, F64Transmute { u: 0x17E0000000000000 }.f, F64Transmute { u: 0x17F0000000000000 }.f, F64Transmute { u: 0x1800000000000000 }.f, F64Transmute { u: 0x1810000000000000 }.f, F64Transmute { u: 0x1820000000000000 }.f, F64Transmute { u: 0x1830000000000000 }.f, F64Transmute { u: 0x1840000000000000 }.f, F64Transmute { u: 0x1850000000000000 }.f, F64Transmute { u: 0x1860000000000000 }.f, F64Transmute { u: 0x1870000000000000 }.f, F64Transmute { u: 0x1880000000000000 }.f, F64Transmute { u: 0x1890000000000000 }.f, F64Transmute { u: 0x18A0000000000000 }.f, F64Transmute { u: 0x18B0000000000000 }.f, F64Transmute { u: 0x18C0000000000000 }.f, F64Transmute { u: 0x18D0000000000000 }.f, F64Transmute { u: 0x18E0000000000000 }.f, F64Transmute { u: 0x18F0000000000000 }.f, F64Transmute { u: 0x1900000000000000 }.f, F64Transmute { u: 0x1910000000000000 }.f, F64Transmute { u: 0x1920000000000000 }.f, F64Transmute { u: 0x1930000000000000 }.f, F64Transmute { u: 0x1940000000000000 }.f, F64Transmute { u: 0x1950000000000000 }.f, F64Transmute { u: 0x1960000000000000 }.f, F64Transmute { u: 0x1970000000000000 }.f, F64Transmute { u: 0x1980000000000000 }.f, F64Transmute { u: 0x1990000000000000 }.f, F64Transmute { u: 0x19A0000000000000 }.f, F64Transmute { u: 0x19B0000000000000 }.f, F64Transmute { u: 0x19C0000000000000 }.f, F64Transmute { u: 0x19D0000000000000 }.f, F64Transmute { u: 0x19E0000000000000 }.f, F64Transmute { u: 0x19F0000000000000 }.f, F64Transmute { u: 0x1A00000000000000 }.f, F64Transmute { u: 0x1A10000000000000 }.f, F64Transmute { u: 0x1A20000000000000 }.f, F64Transmute { u: 0x1A30000000000000 }.f, F64Transmute { u: 0x1A40000000000000 }.f, F64Transmute { u: 0x1A50000000000000 }.f, F64Transmute { u: 0x1A60000000000000 }.f, F64Transmute { u: 0x1A70000000000000 }.f, F64Transmute { u: 0x1A80000000000000 }.f, F64Transmute { u: 0x1A90000000000000 }.f, F64Transmute { u: 0x1AA0000000000000 }.f, F64Transmute { u: 0x1AB0000000000000 }.f, F64Transmute { u: 0x1AC0000000000000 }.f, F64Transmute { u: 0x1AD0000000000000 }.f, F64Transmute { u: 0x1AE0000000000000 }.f, F64Transmute { u: 0x1AF0000000000000 }.f, F64Transmute { u: 0x1B00000000000000 }.f, F64Transmute { u: 0x1B10000000000000 }.f, F64Transmute { u: 0x1B20000000000000 }.f, F64Transmute { u: 0x1B30000000000000 }.f, F64Transmute { u: 0x1B40000000000000 }.f, F64Transmute { u: 0x1B50000000000000 }.f, F64Transmute { u: 0x1B60000000000000 }.f, F64Transmute { u: 0x1B70000000000000 }.f, F64Transmute { u: 0x1B80000000000000 }.f, F64Transmute { u: 0x1B90000000000000 }.f, F64Transmute { u: 0x1BA0000000000000 }.f, F64Transmute { u: 0x1BB0000000000000 }.f, F64Transmute { u: 0x1BC0000000000000 }.f, F64Transmute { u: 0x1BD0000000000000 }.f, F64Transmute { u: 0x1BE0000000000000 }.f, F64Transmute { u: 0x1BF0000000000000 }.f, F64Transmute { u: 0x1C00000000000000 }.f, F64Transmute { u: 0x1C10000000000000 }.f, F64Transmute { u: 0x1C20000000000000 }.f, F64Transmute { u: 0x1C30000000000000 }.f, F64Transmute { u: 0x1C40000000000000 }.f, F64Transmute { u: 0x1C50000000000000 }.f, F64Transmute { u: 0x1C60000000000000 }.f, F64Transmute { u: 0x1C70000000000000 }.f, F64Transmute { u: 0x1C80000000000000 }.f, F64Transmute { u: 0x1C90000000000000 }.f, F64Transmute { u: 0x1CA0000000000000 }.f, F64Transmute { u: 0x1CB0000000000000 }.f, F64Transmute { u: 0x1CC0000000000000 }.f, F64Transmute { u: 0x1CD0000000000000 }.f, F64Transmute { u: 0x1CE0000000000000 }.f, F64Transmute { u: 0x1CF0000000000000 }.f, F64Transmute { u: 0x1D00000000000000 }.f, F64Transmute { u: 0x1D10000000000000 }.f, F64Transmute { u: 0x1D20000000000000 }.f, F64Transmute { u: 0x1D30000000000000 }.f, F64Transmute { u: 0x1D40000000000000 }.f, F64Transmute { u: 0x1D50000000000000 }.f, F64Transmute { u: 0x1D60000000000000 }.f, F64Transmute { u: 0x1D70000000000000 }.f, F64Transmute { u: 0x1D80000000000000 }.f, F64Transmute { u: 0x1D90000000000000 }.f, F64Transmute { u: 0x1DA0000000000000 }.f, F64Transmute { u: 0x1DB0000000000000 }.f, F64Transmute { u: 0x1DC0000000000000 }.f, F64Transmute { u: 0x1DD0000000000000 }.f, F64Transmute { u: 0x1DE0000000000000 }.f, F64Transmute { u: 0x1DF0000000000000 }.f, F64Transmute { u: 0x1E00000000000000 }.f, F64Transmute { u: 0x1E10000000000000 }.f, F64Transmute { u: 0x1E20000000000000 }.f, F64Transmute { u: 0x1E30000000000000 }.f, F64Transmute { u: 0x1E40000000000000 }.f, F64Transmute { u: 0x1E50000000000000 }.f, F64Transmute { u: 0x1E60000000000000 }.f, F64Transmute { u: 0x1E70000000000000 }.f, F64Transmute { u: 0x1E80000000000000 }.f, F64Transmute { u: 0x1E90000000000000 }.f, F64Transmute { u: 0x1EA0000000000000 }.f, F64Transmute { u: 0x1EB0000000000000 }.f, F64Transmute { u: 0x1EC0000000000000 }.f, F64Transmute { u: 0x1ED0000000000000 }.f, F64Transmute { u: 0x1EE0000000000000 }.f, F64Transmute { u: 0x1EF0000000000000 }.f, F64Transmute { u: 0x1F00000000000000 }.f, F64Transmute { u: 0x1F10000000000000 }.f, F64Transmute { u: 0x1F20000000000000 }.f, F64Transmute { u: 0x1F30000000000000 }.f, F64Transmute { u: 0x1F40000000000000 }.f, F64Transmute { u: 0x1F50000000000000 }.f, F64Transmute { u: 0x1F60000000000000 }.f, F64Transmute { u: 0x1F70000000000000 }.f, F64Transmute { u: 0x1F80000000000000 }.f, F64Transmute { u: 0x1F90000000000000 }.f, F64Transmute { u: 0x1FA0000000000000 }.f, F64Transmute { u: 0x1FB0000000000000 }.f, F64Transmute { u: 0x1FC0000000000000 }.f, F64Transmute { u: 0x1FD0000000000000 }.f, F64Transmute { u: 0x1FE0000000000000 }.f, F64Transmute { u: 0x1FF0000000000000 }.f, F64Transmute { u: 0x2000000000000000 }.f, F64Transmute { u: 0x2010000000000000 }.f, F64Transmute { u: 0x2020000000000000 }.f, F64Transmute { u: 0x2030000000000000 }.f, F64Transmute { u: 0x2040000000000000 }.f, F64Transmute { u: 0x2050000000000000 }.f, F64Transmute { u: 0x2060000000000000 }.f, F64Transmute { u: 0x2070000000000000 }.f, F64Transmute { u: 0x2080000000000000 }.f, F64Transmute { u: 0x2090000000000000 }.f, F64Transmute { u: 0x20A0000000000000 }.f, F64Transmute { u: 0x20B0000000000000 }.f, F64Transmute { u: 0x20C0000000000000 }.f, F64Transmute { u: 0x20D0000000000000 }.f, F64Transmute { u: 0x20E0000000000000 }.f, F64Transmute { u: 0x20F0000000000000 }.f, F64Transmute { u: 0x2100000000000000 }.f, F64Transmute { u: 0x2110000000000000 }.f, F64Transmute { u: 0x2120000000000000 }.f, F64Transmute { u: 0x2130000000000000 }.f, F64Transmute { u: 0x2140000000000000 }.f, F64Transmute { u: 0x2150000000000000 }.f, F64Transmute { u: 0x2160000000000000 }.f, F64Transmute { u: 0x2170000000000000 }.f, F64Transmute { u: 0x2180000000000000 }.f, F64Transmute { u: 0x2190000000000000 }.f, F64Transmute { u: 0x21A0000000000000 }.f, F64Transmute { u: 0x21B0000000000000 }.f, F64Transmute { u: 0x21C0000000000000 }.f, F64Transmute { u: 0x21D0000000000000 }.f, F64Transmute { u: 0x21E0000000000000 }.f, F64Transmute { u: 0x21F0000000000000 }.f, F64Transmute { u: 0x2200000000000000 }.f, F64Transmute { u: 0x2210000000000000 }.f, F64Transmute { u: 0x2220000000000000 }.f, F64Transmute { u: 0x2230000000000000 }.f, F64Transmute { u: 0x2240000000000000 }.f, F64Transmute { u: 0x2250000000000000 }.f, F64Transmute { u: 0x2260000000000000 }.f, F64Transmute { u: 0x2270000000000000 }.f, F64Transmute { u: 0x2280000000000000 }.f, F64Transmute { u: 0x2290000000000000 }.f, F64Transmute { u: 0x22A0000000000000 }.f, F64Transmute { u: 0x22B0000000000000 }.f, F64Transmute { u: 0x22C0000000000000 }.f, F64Transmute { u: 0x22D0000000000000 }.f, F64Transmute { u: 0x22E0000000000000 }.f, F64Transmute { u: 0x22F0000000000000 }.f, F64Transmute { u: 0x2300000000000000 }.f, F64Transmute { u: 0x2310000000000000 }.f, F64Transmute { u: 0x2320000000000000 }.f, F64Transmute { u: 0x2330000000000000 }.f, F64Transmute { u: 0x2340000000000000 }.f, F64Transmute { u: 0x2350000000000000 }.f, F64Transmute { u: 0x2360000000000000 }.f, F64Transmute { u: 0x2370000000000000 }.f, F64Transmute { u: 0x2380000000000000 }.f, F64Transmute { u: 0x2390000000000000 }.f, F64Transmute { u: 0x23A0000000000000 }.f, F64Transmute { u: 0x23B0000000000000 }.f, F64Transmute { u: 0x23C0000000000000 }.f, F64Transmute { u: 0x23D0000000000000 }.f, F64Transmute { u: 0x23E0000000000000 }.f, F64Transmute { u: 0x23F0000000000000 }.f, F64Transmute { u: 0x2400000000000000 }.f, F64Transmute { u: 0x2410000000000000 }.f, F64Transmute { u: 0x2420000000000000 }.f, F64Transmute { u: 0x2430000000000000 }.f, F64Transmute { u: 0x2440000000000000 }.f, F64Transmute { u: 0x2450000000000000 }.f, F64Transmute { u: 0x2460000000000000 }.f, F64Transmute { u: 0x2470000000000000 }.f, F64Transmute { u: 0x2480000000000000 }.f, F64Transmute { u: 0x2490000000000000 }.f, F64Transmute { u: 0x24A0000000000000 }.f, F64Transmute { u: 0x24B0000000000000 }.f, F64Transmute { u: 0x24C0000000000000 }.f, F64Transmute { u: 0x24D0000000000000 }.f, F64Transmute { u: 0x24E0000000000000 }.f, F64Transmute { u: 0x24F0000000000000 }.f, F64Transmute { u: 0x2500000000000000 }.f, F64Transmute { u: 0x2510000000000000 }.f, F64Transmute { u: 0x2520000000000000 }.f, F64Transmute { u: 0x2530000000000000 }.f, F64Transmute { u: 0x2540000000000000 }.f, F64Transmute { u: 0x2550000000000000 }.f, F64Transmute { u: 0x2560000000000000 }.f, F64Transmute { u: 0x2570000000000000 }.f, F64Transmute { u: 0x2580000000000000 }.f, F64Transmute { u: 0x2590000000000000 }.f, F64Transmute { u: 0x25A0000000000000 }.f, F64Transmute { u: 0x25B0000000000000 }.f, F64Transmute { u: 0x25C0000000000000 }.f, F64Transmute { u: 0x25D0000000000000 }.f, F64Transmute { u: 0x25E0000000000000 }.f, F64Transmute { u: 0x25F0000000000000 }.f, F64Transmute { u: 0x2600000000000000 }.f, F64Transmute { u: 0x2610000000000000 }.f, F64Transmute { u: 0x2620000000000000 }.f, F64Transmute { u: 0x2630000000000000 }.f, F64Transmute { u: 0x2640000000000000 }.f, F64Transmute { u: 0x2650000000000000 }.f, F64Transmute { u: 0x2660000000000000 }.f, F64Transmute { u: 0x2670000000000000 }.f, F64Transmute { u: 0x2680000000000000 }.f, F64Transmute { u: 0x2690000000000000 }.f, F64Transmute { u: 0x26A0000000000000 }.f, F64Transmute { u: 0x26B0000000000000 }.f, F64Transmute { u: 0x26C0000000000000 }.f, F64Transmute { u: 0x26D0000000000000 }.f, F64Transmute { u: 0x26E0000000000000 }.f, F64Transmute { u: 0x26F0000000000000 }.f, F64Transmute { u: 0x2700000000000000 }.f, F64Transmute { u: 0x2710000000000000 }.f, F64Transmute { u: 0x2720000000000000 }.f, F64Transmute { u: 0x2730000000000000 }.f, F64Transmute { u: 0x2740000000000000 }.f, F64Transmute { u: 0x2750000000000000 }.f, F64Transmute { u: 0x2760000000000000 }.f, F64Transmute { u: 0x2770000000000000 }.f, F64Transmute { u: 0x2780000000000000 }.f, F64Transmute { u: 0x2790000000000000 }.f, F64Transmute { u: 0x27A0000000000000 }.f, F64Transmute { u: 0x27B0000000000000 }.f, F64Transmute { u: 0x27C0000000000000 }.f, F64Transmute { u: 0x27D0000000000000 }.f, F64Transmute { u: 0x27E0000000000000 }.f, F64Transmute { u: 0x27F0000000000000 }.f, F64Transmute { u: 0x2800000000000000 }.f, F64Transmute { u: 0x2810000000000000 }.f, F64Transmute { u: 0x2820000000000000 }.f, F64Transmute { u: 0x2830000000000000 }.f, F64Transmute { u: 0x2840000000000000 }.f, F64Transmute { u: 0x2850000000000000 }.f, F64Transmute { u: 0x2860000000000000 }.f, F64Transmute { u: 0x2870000000000000 }.f, F64Transmute { u: 0x2880000000000000 }.f, F64Transmute { u: 0x2890000000000000 }.f, F64Transmute { u: 0x28A0000000000000 }.f, F64Transmute { u: 0x28B0000000000000 }.f, F64Transmute { u: 0x28C0000000000000 }.f, F64Transmute { u: 0x28D0000000000000 }.f, F64Transmute { u: 0x28E0000000000000 }.f, F64Transmute { u: 0x28F0000000000000 }.f, F64Transmute { u: 0x2900000000000000 }.f, F64Transmute { u: 0x2910000000000000 }.f, F64Transmute { u: 0x2920000000000000 }.f, F64Transmute { u: 0x2930000000000000 }.f, F64Transmute { u: 0x2940000000000000 }.f, F64Transmute { u: 0x2950000000000000 }.f, F64Transmute { u: 0x2960000000000000 }.f, F64Transmute { u: 0x2970000000000000 }.f, F64Transmute { u: 0x2980000000000000 }.f, F64Transmute { u: 0x2990000000000000 }.f, F64Transmute { u: 0x29A0000000000000 }.f, F64Transmute { u: 0x29B0000000000000 }.f, F64Transmute { u: 0x29C0000000000000 }.f, F64Transmute { u: 0x29D0000000000000 }.f, F64Transmute { u: 0x29E0000000000000 }.f, F64Transmute { u: 0x29F0000000000000 }.f, F64Transmute { u: 0x2A00000000000000 }.f, F64Transmute { u: 0x2A10000000000000 }.f, F64Transmute { u: 0x2A20000000000000 }.f, F64Transmute { u: 0x2A30000000000000 }.f, F64Transmute { u: 0x2A40000000000000 }.f, F64Transmute { u: 0x2A50000000000000 }.f, F64Transmute { u: 0x2A60000000000000 }.f, F64Transmute { u: 0x2A70000000000000 }.f, F64Transmute { u: 0x2A80000000000000 }.f, F64Transmute { u: 0x2A90000000000000 }.f, F64Transmute { u: 0x2AA0000000000000 }.f, F64Transmute { u: 0x2AB0000000000000 }.f, F64Transmute { u: 0x2AC0000000000000 }.f, F64Transmute { u: 0x2AD0000000000000 }.f, F64Transmute { u: 0x2AE0000000000000 }.f, F64Transmute { u: 0x2AF0000000000000 }.f, F64Transmute { u: 0x2B00000000000000 }.f, F64Transmute { u: 0x2B10000000000000 }.f, F64Transmute { u: 0x2B20000000000000 }.f, F64Transmute { u: 0x2B30000000000000 }.f, F64Transmute { u: 0x2B40000000000000 }.f, F64Transmute { u: 0x2B50000000000000 }.f, F64Transmute { u: 0x2B60000000000000 }.f, F64Transmute { u: 0x2B70000000000000 }.f, F64Transmute { u: 0x2B80000000000000 }.f, F64Transmute { u: 0x2B90000000000000 }.f, F64Transmute { u: 0x2BA0000000000000 }.f, F64Transmute { u: 0x2BB0000000000000 }.f, F64Transmute { u: 0x2BC0000000000000 }.f, F64Transmute { u: 0x2BD0000000000000 }.f, F64Transmute { u: 0x2BE0000000000000 }.f, F64Transmute { u: 0x2BF0000000000000 }.f, F64Transmute { u: 0x2C00000000000000 }.f, F64Transmute { u: 0x2C10000000000000 }.f, F64Transmute { u: 0x2C20000000000000 }.f, F64Transmute { u: 0x2C30000000000000 }.f, F64Transmute { u: 0x2C40000000000000 }.f, F64Transmute { u: 0x2C50000000000000 }.f, F64Transmute { u: 0x2C60000000000000 }.f, F64Transmute { u: 0x2C70000000000000 }.f, F64Transmute { u: 0x2C80000000000000 }.f, F64Transmute { u: 0x2C90000000000000 }.f, F64Transmute { u: 0x2CA0000000000000 }.f, F64Transmute { u: 0x2CB0000000000000 }.f, F64Transmute { u: 0x2CC0000000000000 }.f, F64Transmute { u: 0x2CD0000000000000 }.f, F64Transmute { u: 0x2CE0000000000000 }.f, F64Transmute { u: 0x2CF0000000000000 }.f, F64Transmute { u: 0x2D00000000000000 }.f, F64Transmute { u: 0x2D10000000000000 }.f, F64Transmute { u: 0x2D20000000000000 }.f, F64Transmute { u: 0x2D30000000000000 }.f, F64Transmute { u: 0x2D40000000000000 }.f, F64Transmute { u: 0x2D50000000000000 }.f, F64Transmute { u: 0x2D60000000000000 }.f, F64Transmute { u: 0x2D70000000000000 }.f, F64Transmute { u: 0x2D80000000000000 }.f, F64Transmute { u: 0x2D90000000000000 }.f, F64Transmute { u: 0x2DA0000000000000 }.f, F64Transmute { u: 0x2DB0000000000000 }.f, F64Transmute { u: 0x2DC0000000000000 }.f, F64Transmute { u: 0x2DD0000000000000 }.f, F64Transmute { u: 0x2DE0000000000000 }.f, F64Transmute { u: 0x2DF0000000000000 }.f, F64Transmute { u: 0x2E00000000000000 }.f, F64Transmute { u: 0x2E10000000000000 }.f, F64Transmute { u: 0x2E20000000000000 }.f, F64Transmute { u: 0x2E30000000000000 }.f, F64Transmute { u: 0x2E40000000000000 }.f, F64Transmute { u: 0x2E50000000000000 }.f, F64Transmute { u: 0x2E60000000000000 }.f, F64Transmute { u: 0x2E70000000000000 }.f, F64Transmute { u: 0x2E80000000000000 }.f, F64Transmute { u: 0x2E90000000000000 }.f, F64Transmute { u: 0x2EA0000000000000 }.f, F64Transmute { u: 0x2EB0000000000000 }.f, F64Transmute { u: 0x2EC0000000000000 }.f, F64Transmute { u: 0x2ED0000000000000 }.f, F64Transmute { u: 0x2EE0000000000000 }.f, F64Transmute { u: 0x2EF0000000000000 }.f, F64Transmute { u: 0x2F00000000000000 }.f, F64Transmute { u: 0x2F10000000000000 }.f, F64Transmute { u: 0x2F20000000000000 }.f, F64Transmute { u: 0x2F30000000000000 }.f, F64Transmute { u: 0x2F40000000000000 }.f, F64Transmute { u: 0x2F50000000000000 }.f, F64Transmute { u: 0x2F60000000000000 }.f, F64Transmute { u: 0x2F70000000000000 }.f, F64Transmute { u: 0x2F80000000000000 }.f, F64Transmute { u: 0x2F90000000000000 }.f, F64Transmute { u: 0x2FA0000000000000 }.f, F64Transmute { u: 0x2FB0000000000000 }.f, F64Transmute { u: 0x2FC0000000000000 }.f, F64Transmute { u: 0x2FD0000000000000 }.f, F64Transmute { u: 0x2FE0000000000000 }.f, F64Transmute { u: 0x2FF0000000000000 }.f, F64Transmute { u: 0x3000000000000000 }.f, F64Transmute { u: 0x3010000000000000 }.f, F64Transmute { u: 0x3020000000000000 }.f, F64Transmute { u: 0x3030000000000000 }.f, F64Transmute { u: 0x3040000000000000 }.f, F64Transmute { u: 0x3050000000000000 }.f, F64Transmute { u: 0x3060000000000000 }.f, F64Transmute { u: 0x3070000000000000 }.f, F64Transmute { u: 0x3080000000000000 }.f, F64Transmute { u: 0x3090000000000000 }.f, F64Transmute { u: 0x30A0000000000000 }.f, F64Transmute { u: 0x30B0000000000000 }.f, F64Transmute { u: 0x30C0000000000000 }.f, F64Transmute { u: 0x30D0000000000000 }.f, F64Transmute { u: 0x30E0000000000000 }.f, F64Transmute { u: 0x30F0000000000000 }.f, F64Transmute { u: 0x3100000000000000 }.f, F64Transmute { u: 0x3110000000000000 }.f, F64Transmute { u: 0x3120000000000000 }.f, F64Transmute { u: 0x3130000000000000 }.f, F64Transmute { u: 0x3140000000000000 }.f, F64Transmute { u: 0x3150000000000000 }.f, F64Transmute { u: 0x3160000000000000 }.f, F64Transmute { u: 0x3170000000000000 }.f, F64Transmute { u: 0x3180000000000000 }.f, F64Transmute { u: 0x3190000000000000 }.f, F64Transmute { u: 0x31A0000000000000 }.f, F64Transmute { u: 0x31B0000000000000 }.f, F64Transmute { u: 0x31C0000000000000 }.f, F64Transmute { u: 0x31D0000000000000 }.f, F64Transmute { u: 0x31E0000000000000 }.f, F64Transmute { u: 0x31F0000000000000 }.f, F64Transmute { u: 0x3200000000000000 }.f, F64Transmute { u: 0x3210000000000000 }.f, F64Transmute { u: 0x3220000000000000 }.f, F64Transmute { u: 0x3230000000000000 }.f, F64Transmute { u: 0x3240000000000000 }.f, F64Transmute { u: 0x3250000000000000 }.f, F64Transmute { u: 0x3260000000000000 }.f, F64Transmute { u: 0x3270000000000000 }.f, F64Transmute { u: 0x3280000000000000 }.f, F64Transmute { u: 0x3290000000000000 }.f, F64Transmute { u: 0x32A0000000000000 }.f, F64Transmute { u: 0x32B0000000000000 }.f, F64Transmute { u: 0x32C0000000000000 }.f, F64Transmute { u: 0x32D0000000000000 }.f, F64Transmute { u: 0x32E0000000000000 }.f, F64Transmute { u: 0x32F0000000000000 }.f, F64Transmute { u: 0x3300000000000000 }.f, F64Transmute { u: 0x3310000000000000 }.f, F64Transmute { u: 0x3320000000000000 }.f, F64Transmute { u: 0x3330000000000000 }.f, F64Transmute { u: 0x3340000000000000 }.f, F64Transmute { u: 0x3350000000000000 }.f, F64Transmute { u: 0x3360000000000000 }.f, F64Transmute { u: 0x3370000000000000 }.f, F64Transmute { u: 0x3380000000000000 }.f, F64Transmute { u: 0x3390000000000000 }.f, F64Transmute { u: 0x33A0000000000000 }.f, F64Transmute { u: 0x33B0000000000000 }.f, F64Transmute { u: 0x33C0000000000000 }.f, F64Transmute { u: 0x33D0000000000000 }.f, F64Transmute { u: 0x33E0000000000000 }.f, F64Transmute { u: 0x33F0000000000000 }.f, F64Transmute { u: 0x3400000000000000 }.f, F64Transmute { u: 0x3410000000000000 }.f, F64Transmute { u: 0x3420000000000000 }.f, F64Transmute { u: 0x3430000000000000 }.f, F64Transmute { u: 0x3440000000000000 }.f, F64Transmute { u: 0x3450000000000000 }.f, F64Transmute { u: 0x3460000000000000 }.f, F64Transmute { u: 0x3470000000000000 }.f, F64Transmute { u: 0x3480000000000000 }.f, F64Transmute { u: 0x3490000000000000 }.f, F64Transmute { u: 0x34A0000000000000 }.f, F64Transmute { u: 0x34B0000000000000 }.f, F64Transmute { u: 0x34C0000000000000 }.f, F64Transmute { u: 0x34D0000000000000 }.f, F64Transmute { u: 0x34E0000000000000 }.f, F64Transmute { u: 0x34F0000000000000 }.f, F64Transmute { u: 0x3500000000000000 }.f, F64Transmute { u: 0x3510000000000000 }.f, F64Transmute { u: 0x3520000000000000 }.f, F64Transmute { u: 0x3530000000000000 }.f, F64Transmute { u: 0x3540000000000000 }.f, F64Transmute { u: 0x3550000000000000 }.f, F64Transmute { u: 0x3560000000000000 }.f, F64Transmute { u: 0x3570000000000000 }.f, F64Transmute { u: 0x3580000000000000 }.f, F64Transmute { u: 0x3590000000000000 }.f, F64Transmute { u: 0x35A0000000000000 }.f, F64Transmute { u: 0x35B0000000000000 }.f, F64Transmute { u: 0x35C0000000000000 }.f, F64Transmute { u: 0x35D0000000000000 }.f, F64Transmute { u: 0x35E0000000000000 }.f, F64Transmute { u: 0x35F0000000000000 }.f, F64Transmute { u: 0x3600000000000000 }.f, F64Transmute { u: 0x3610000000000000 }.f, F64Transmute { u: 0x3620000000000000 }.f, F64Transmute { u: 0x3630000000000000 }.f, F64Transmute { u: 0x3640000000000000 }.f, F64Transmute { u: 0x3650000000000000 }.f, F64Transmute { u: 0x3660000000000000 }.f, F64Transmute { u: 0x3670000000000000 }.f, F64Transmute { u: 0x3680000000000000 }.f, F64Transmute { u: 0x3690000000000000 }.f, F64Transmute { u: 0x36A0000000000000 }.f, F64Transmute { u: 0x36B0000000000000 }.f, F64Transmute { u: 0x36C0000000000000 }.f, F64Transmute { u: 0x36D0000000000000 }.f, F64Transmute { u: 0x36E0000000000000 }.f, F64Transmute { u: 0x36F0000000000000 }.f, F64Transmute { u: 0x3700000000000000 }.f, F64Transmute { u: 0x3710000000000000 }.f, F64Transmute { u: 0x3720000000000000 }.f, F64Transmute { u: 0x3730000000000000 }.f, F64Transmute { u: 0x3740000000000000 }.f, F64Transmute { u: 0x3750000000000000 }.f, F64Transmute { u: 0x3760000000000000 }.f, F64Transmute { u: 0x3770000000000000 }.f, F64Transmute { u: 0x3780000000000000 }.f, F64Transmute { u: 0x3790000000000000 }.f, F64Transmute { u: 0x37A0000000000000 }.f, F64Transmute { u: 0x37B0000000000000 }.f, F64Transmute { u: 0x37C0000000000000 }.f, F64Transmute { u: 0x37D0000000000000 }.f, F64Transmute { u: 0x37E0000000000000 }.f, F64Transmute { u: 0x37F0000000000000 }.f, F64Transmute { u: 0x3800000000000000 }.f, F64Transmute { u: 0x3810000000000000 }.f, F64Transmute { u: 0x3820000000000000 }.f, F64Transmute { u: 0x3830000000000000 }.f, F64Transmute { u: 0x3840000000000000 }.f, F64Transmute { u: 0x3850000000000000 }.f, F64Transmute { u: 0x3860000000000000 }.f, F64Transmute { u: 0x3870000000000000 }.f, F64Transmute { u: 0x3880000000000000 }.f, F64Transmute { u: 0x3890000000000000 }.f, F64Transmute { u: 0x38A0000000000000 }.f, F64Transmute { u: 0x38B0000000000000 }.f, F64Transmute { u: 0x38C0000000000000 }.f, F64Transmute { u: 0x38D0000000000000 }.f, F64Transmute { u: 0x38E0000000000000 }.f, F64Transmute { u: 0x38F0000000000000 }.f, F64Transmute { u: 0x3900000000000000 }.f, F64Transmute { u: 0x3910000000000000 }.f, F64Transmute { u: 0x3920000000000000 }.f, F64Transmute { u: 0x3930000000000000 }.f, F64Transmute { u: 0x3940000000000000 }.f, F64Transmute { u: 0x3950000000000000 }.f, F64Transmute { u: 0x3960000000000000 }.f, F64Transmute { u: 0x3970000000000000 }.f, F64Transmute { u: 0x3980000000000000 }.f, F64Transmute { u: 0x3990000000000000 }.f, F64Transmute { u: 0x39A0000000000000 }.f, F64Transmute { u: 0x39B0000000000000 }.f, F64Transmute { u: 0x39C0000000000000 }.f, F64Transmute { u: 0x39D0000000000000 }.f, F64Transmute { u: 0x39E0000000000000 }.f, F64Transmute { u: 0x39F0000000000000 }.f, F64Transmute { u: 0x3A00000000000000 }.f, F64Transmute { u: 0x3A10000000000000 }.f, F64Transmute { u: 0x3A20000000000000 }.f, F64Transmute { u: 0x3A30000000000000 }.f, F64Transmute { u: 0x3A40000000000000 }.f, F64Transmute { u: 0x3A50000000000000 }.f, F64Transmute { u: 0x3A60000000000000 }.f, F64Transmute { u: 0x3A70000000000000 }.f, F64Transmute { u: 0x3A80000000000000 }.f, F64Transmute { u: 0x3A90000000000000 }.f, F64Transmute { u: 0x3AA0000000000000 }.f, F64Transmute { u: 0x3AB0000000000000 }.f, F64Transmute { u: 0x3AC0000000000000 }.f, F64Transmute { u: 0x3AD0000000000000 }.f, F64Transmute { u: 0x3AE0000000000000 }.f, F64Transmute { u: 0x3AF0000000000000 }.f, F64Transmute { u: 0x3B00000000000000 }.f, F64Transmute { u: 0x3B10000000000000 }.f, F64Transmute { u: 0x3B20000000000000 }.f, F64Transmute { u: 0x3B30000000000000 }.f, F64Transmute { u: 0x3B40000000000000 }.f, F64Transmute { u: 0x3B50000000000000 }.f, F64Transmute { u: 0x3B60000000000000 }.f, F64Transmute { u: 0x3B70000000000000 }.f, F64Transmute { u: 0x3B80000000000000 }.f, F64Transmute { u: 0x3B90000000000000 }.f, F64Transmute { u: 0x3BA0000000000000 }.f, F64Transmute { u: 0x3BB0000000000000 }.f, F64Transmute { u: 0x3BC0000000000000 }.f, F64Transmute { u: 0x3BD0000000000000 }.f, F64Transmute { u: 0x3BE0000000000000 }.f, F64Transmute { u: 0x3BF0000000000000 }.f, F64Transmute { u: 0x3C00000000000000 }.f, F64Transmute { u: 0x3C10000000000000 }.f, F64Transmute { u: 0x3C20000000000000 }.f, F64Transmute { u: 0x3C30000000000000 }.f, F64Transmute { u: 0x3C40000000000000 }.f, F64Transmute { u: 0x3C50000000000000 }.f, F64Transmute { u: 0x3C60000000000000 }.f, F64Transmute { u: 0x3C70000000000000 }.f, F64Transmute { u: 0x3C80000000000000 }.f, F64Transmute { u: 0x3C90000000000000 }.f, F64Transmute { u: 0x3CA0000000000000 }.f, F64Transmute { u: 0x3CB0000000000000 }.f, F64Transmute { u: 0x3CC0000000000000 }.f, F64Transmute { u: 0x3CD0000000000000 }.f, F64Transmute { u: 0x3CE0000000000000 }.f, F64Transmute { u: 0x3CF0000000000000 }.f, F64Transmute { u: 0x3D00000000000000 }.f, F64Transmute { u: 0x3D10000000000000 }.f, F64Transmute { u: 0x3D20000000000000 }.f, F64Transmute { u: 0x3D30000000000000 }.f, F64Transmute { u: 0x3D40000000000000 }.f, F64Transmute { u: 0x3D50000000000000 }.f, F64Transmute { u: 0x3D60000000000000 }.f, F64Transmute { u: 0x3D70000000000000 }.f, F64Transmute { u: 0x3D80000000000000 }.f, F64Transmute { u: 0x3D90000000000000 }.f, F64Transmute { u: 0x3DA0000000000000 }.f, F64Transmute { u: 0x3DB0000000000000 }.f, F64Transmute { u: 0x3DC0000000000000 }.f, F64Transmute { u: 0x3DD0000000000000 }.f, F64Transmute { u: 0x3DE0000000000000 }.f, F64Transmute { u: 0x3DF0000000000000 }.f, F64Transmute { u: 0x3E00000000000000 }.f, F64Transmute { u: 0x3E10000000000000 }.f, F64Transmute { u: 0x3E20000000000000 }.f, F64Transmute { u: 0x3E30000000000000 }.f, F64Transmute { u: 0x3E40000000000000 }.f, F64Transmute { u: 0x3E50000000000000 }.f, F64Transmute { u: 0x3E60000000000000 }.f, F64Transmute { u: 0x3E70000000000000 }.f, F64Transmute { u: 0x3E80000000000000 }.f, F64Transmute { u: 0x3E90000000000000 }.f, F64Transmute { u: 0x3EA0000000000000 }.f, F64Transmute { u: 0x3EB0000000000000 }.f, F64Transmute { u: 0x3EC0000000000000 }.f, F64Transmute { u: 0x3ED0000000000000 }.f, F64Transmute { u: 0x3EE0000000000000 }.f, F64Transmute { u: 0x3EF0000000000000 }.f, F64Transmute { u: 0x3F00000000000000 }.f, F64Transmute { u: 0x3F10000000000000 }.f, F64Transmute { u: 0x3F20000000000000 }.f, F64Transmute { u: 0x3F30000000000000 }.f, F64Transmute { u: 0x3F40000000000000 }.f, F64Transmute { u: 0x3F50000000000000 }.f, F64Transmute { u: 0x3F60000000000000 }.f, F64Transmute { u: 0x3F70000000000000 }.f, F64Transmute { u: 0x3F80000000000000 }.f, F64Transmute { u: 0x3F90000000000000 }.f, F64Transmute { u: 0x3FA0000000000000 }.f, F64Transmute { u: 0x3FB0000000000000 }.f, F64Transmute { u: 0x3FC0000000000000 }.f, F64Transmute { u: 0x3FD0000000000000 }.f, F64Transmute { u: 0x3FE0000000000000 }.f, F64Transmute { u: 0x3FF0000000000000 }.f, F64Transmute { u: 0x4000000000000000 }.f, F64Transmute { u: 0x4010000000000000 }.f, F64Transmute { u: 0x4020000000000000 }.f, F64Transmute { u: 0x4030000000000000 }.f, F64Transmute { u: 0x4040000000000000 }.f, F64Transmute { u: 0x4050000000000000 }.f, F64Transmute { u: 0x4060000000000000 }.f, F64Transmute { u: 0x4070000000000000 }.f, F64Transmute { u: 0x4080000000000000 }.f, F64Transmute { u: 0x4090000000000000 }.f, F64Transmute { u: 0x40A0000000000000 }.f, F64Transmute { u: 0x40B0000000000000 }.f, F64Transmute { u: 0x40C0000000000000 }.f, F64Transmute { u: 0x40D0000000000000 }.f, F64Transmute { u: 0x40E0000000000000 }.f, F64Transmute { u: 0x40F0000000000000 }.f, F64Transmute { u: 0x4100000000000000 }.f, F64Transmute { u: 0x4110000000000000 }.f, F64Transmute { u: 0x4120000000000000 }.f, F64Transmute { u: 0x4130000000000000 }.f, F64Transmute { u: 0x4140000000000000 }.f, F64Transmute { u: 0x4150000000000000 }.f, F64Transmute { u: 0x4160000000000000 }.f, F64Transmute { u: 0x4170000000000000 }.f, F64Transmute { u: 0x4180000000000000 }.f, F64Transmute { u: 0x4190000000000000 }.f, F64Transmute { u: 0x41A0000000000000 }.f, F64Transmute { u: 0x41B0000000000000 }.f, F64Transmute { u: 0x41C0000000000000 }.f, F64Transmute { u: 0x41D0000000000000 }.f, F64Transmute { u: 0x41E0000000000000 }.f, F64Transmute { u: 0x41F0000000000000 }.f, F64Transmute { u: 0x4200000000000000 }.f, F64Transmute { u: 0x4210000000000000 }.f, F64Transmute { u: 0x4220000000000000 }.f, F64Transmute { u: 0x4230000000000000 }.f, F64Transmute { u: 0x4240000000000000 }.f, F64Transmute { u: 0x4250000000000000 }.f, F64Transmute { u: 0x4260000000000000 }.f, F64Transmute { u: 0x4270000000000000 }.f, F64Transmute { u: 0x4280000000000000 }.f, F64Transmute { u: 0x4290000000000000 }.f, F64Transmute { u: 0x42A0000000000000 }.f, F64Transmute { u: 0x42B0000000000000 }.f, F64Transmute { u: 0x42C0000000000000 }.f, F64Transmute { u: 0x42D0000000000000 }.f, F64Transmute { u: 0x42E0000000000000 }.f, F64Transmute { u: 0x42F0000000000000 }.f, F64Transmute { u: 0x4300000000000000 }.f, F64Transmute { u: 0x4310000000000000 }.f, F64Transmute { u: 0x4320000000000000 }.f, F64Transmute { u: 0x4330000000000000 }.f, F64Transmute { u: 0x4340000000000000 }.f, F64Transmute { u: 0x4350000000000000 }.f, F64Transmute { u: 0x4360000000000000 }.f, F64Transmute { u: 0x4370000000000000 }.f, F64Transmute { u: 0x4380000000000000 }.f, F64Transmute { u: 0x4390000000000000 }.f, F64Transmute { u: 0x43A0000000000000 }.f, F64Transmute { u: 0x43B0000000000000 }.f, F64Transmute { u: 0x43C0000000000000 }.f, F64Transmute { u: 0x43D0000000000000 }.f, F64Transmute { u: 0x43E0000000000000 }.f, F64Transmute { u: 0x43F0000000000000 }.f, F64Transmute { u: 0x4400000000000000 }.f, F64Transmute { u: 0x4410000000000000 }.f, F64Transmute { u: 0x4420000000000000 }.f, F64Transmute { u: 0x4430000000000000 }.f, F64Transmute { u: 0x4440000000000000 }.f, F64Transmute { u: 0x4450000000000000 }.f, F64Transmute { u: 0x4460000000000000 }.f, F64Transmute { u: 0x4470000000000000 }.f, F64Transmute { u: 0x4480000000000000 }.f, F64Transmute { u: 0x4490000000000000 }.f, F64Transmute { u: 0x44A0000000000000 }.f, F64Transmute { u: 0x44B0000000000000 }.f, F64Transmute { u: 0x44C0000000000000 }.f, F64Transmute { u: 0x44D0000000000000 }.f, F64Transmute { u: 0x44E0000000000000 }.f, F64Transmute { u: 0x44F0000000000000 }.f, F64Transmute { u: 0x4500000000000000 }.f, F64Transmute { u: 0x4510000000000000 }.f, F64Transmute { u: 0x4520000000000000 }.f, F64Transmute { u: 0x4530000000000000 }.f, F64Transmute { u: 0x4540000000000000 }.f, F64Transmute { u: 0x4550000000000000 }.f, F64Transmute { u: 0x4560000000000000 }.f, F64Transmute { u: 0x4570000000000000 }.f, F64Transmute { u: 0x4580000000000000 }.f, F64Transmute { u: 0x4590000000000000 }.f, F64Transmute { u: 0x45A0000000000000 }.f, F64Transmute { u: 0x45B0000000000000 }.f, F64Transmute { u: 0x45C0000000000000 }.f, F64Transmute { u: 0x45D0000000000000 }.f, F64Transmute { u: 0x45E0000000000000 }.f, F64Transmute { u: 0x45F0000000000000 }.f, F64Transmute { u: 0x4600000000000000 }.f, F64Transmute { u: 0x4610000000000000 }.f, F64Transmute { u: 0x4620000000000000 }.f, F64Transmute { u: 0x4630000000000000 }.f, F64Transmute { u: 0x4640000000000000 }.f, F64Transmute { u: 0x4650000000000000 }.f, F64Transmute { u: 0x4660000000000000 }.f, F64Transmute { u: 0x4670000000000000 }.f, F64Transmute { u: 0x4680000000000000 }.f, F64Transmute { u: 0x4690000000000000 }.f, F64Transmute { u: 0x46A0000000000000 }.f, F64Transmute { u: 0x46B0000000000000 }.f, F64Transmute { u: 0x46C0000000000000 }.f, F64Transmute { u: 0x46D0000000000000 }.f, F64Transmute { u: 0x46E0000000000000 }.f, F64Transmute { u: 0x46F0000000000000 }.f, F64Transmute { u: 0x4700000000000000 }.f, F64Transmute { u: 0x4710000000000000 }.f, F64Transmute { u: 0x4720000000000000 }.f, F64Transmute { u: 0x4730000000000000 }.f, F64Transmute { u: 0x4740000000000000 }.f, F64Transmute { u: 0x4750000000000000 }.f, F64Transmute { u: 0x4760000000000000 }.f, F64Transmute { u: 0x4770000000000000 }.f, F64Transmute { u: 0x4780000000000000 }.f, F64Transmute { u: 0x4790000000000000 }.f, F64Transmute { u: 0x47A0000000000000 }.f, F64Transmute { u: 0x47B0000000000000 }.f, F64Transmute { u: 0x47C0000000000000 }.f, F64Transmute { u: 0x47D0000000000000 }.f, F64Transmute { u: 0x47E0000000000000 }.f, F64Transmute { u: 0x47F0000000000000 }.f, F64Transmute { u: 0x4800000000000000 }.f, F64Transmute { u: 0x4810000000000000 }.f, F64Transmute { u: 0x4820000000000000 }.f, F64Transmute { u: 0x4830000000000000 }.f, F64Transmute { u: 0x4840000000000000 }.f, F64Transmute { u: 0x4850000000000000 }.f, F64Transmute { u: 0x4860000000000000 }.f, F64Transmute { u: 0x4870000000000000 }.f, F64Transmute { u: 0x4880000000000000 }.f, F64Transmute { u: 0x4890000000000000 }.f, F64Transmute { u: 0x48A0000000000000 }.f, F64Transmute { u: 0x48B0000000000000 }.f, F64Transmute { u: 0x48C0000000000000 }.f, F64Transmute { u: 0x48D0000000000000 }.f, F64Transmute { u: 0x48E0000000000000 }.f, F64Transmute { u: 0x48F0000000000000 }.f, F64Transmute { u: 0x4900000000000000 }.f, F64Transmute { u: 0x4910000000000000 }.f, F64Transmute { u: 0x4920000000000000 }.f, F64Transmute { u: 0x4930000000000000 }.f, F64Transmute { u: 0x4940000000000000 }.f, F64Transmute { u: 0x4950000000000000 }.f, F64Transmute { u: 0x4960000000000000 }.f, F64Transmute { u: 0x4970000000000000 }.f, F64Transmute { u: 0x4980000000000000 }.f, F64Transmute { u: 0x4990000000000000 }.f, F64Transmute { u: 0x49A0000000000000 }.f, F64Transmute { u: 0x49B0000000000000 }.f, F64Transmute { u: 0x49C0000000000000 }.f, F64Transmute { u: 0x49D0000000000000 }.f, F64Transmute { u: 0x49E0000000000000 }.f, F64Transmute { u: 0x49F0000000000000 }.f, F64Transmute { u: 0x4A00000000000000 }.f, F64Transmute { u: 0x4A10000000000000 }.f, F64Transmute { u: 0x4A20000000000000 }.f, F64Transmute { u: 0x4A30000000000000 }.f, F64Transmute { u: 0x4A40000000000000 }.f, F64Transmute { u: 0x4A50000000000000 }.f, F64Transmute { u: 0x4A60000000000000 }.f, F64Transmute { u: 0x4A70000000000000 }.f, F64Transmute { u: 0x4A80000000000000 }.f, F64Transmute { u: 0x4A90000000000000 }.f, F64Transmute { u: 0x4AA0000000000000 }.f, F64Transmute { u: 0x4AB0000000000000 }.f, F64Transmute { u: 0x4AC0000000000000 }.f, F64Transmute { u: 0x4AD0000000000000 }.f, F64Transmute { u: 0x4AE0000000000000 }.f, F64Transmute { u: 0x4AF0000000000000 }.f, F64Transmute { u: 0x4B00000000000000 }.f, F64Transmute { u: 0x4B10000000000000 }.f, F64Transmute { u: 0x4B20000000000000 }.f, F64Transmute { u: 0x4B30000000000000 }.f, F64Transmute { u: 0x4B40000000000000 }.f, F64Transmute { u: 0x4B50000000000000 }.f, F64Transmute { u: 0x4B60000000000000 }.f, F64Transmute { u: 0x4B70000000000000 }.f, F64Transmute { u: 0x4B80000000000000 }.f, F64Transmute { u: 0x4B90000000000000 }.f, F64Transmute { u: 0x4BA0000000000000 }.f, F64Transmute { u: 0x4BB0000000000000 }.f, F64Transmute { u: 0x4BC0000000000000 }.f, F64Transmute { u: 0x4BD0000000000000 }.f, F64Transmute { u: 0x4BE0000000000000 }.f, F64Transmute { u: 0x4BF0000000000000 }.f, F64Transmute { u: 0x4C00000000000000 }.f, F64Transmute { u: 0x4C10000000000000 }.f, F64Transmute { u: 0x4C20000000000000 }.f, F64Transmute { u: 0x4C30000000000000 }.f, F64Transmute { u: 0x4C40000000000000 }.f, F64Transmute { u: 0x4C50000000000000 }.f, F64Transmute { u: 0x4C60000000000000 }.f, F64Transmute { u: 0x4C70000000000000 }.f, F64Transmute { u: 0x4C80000000000000 }.f, F64Transmute { u: 0x4C90000000000000 }.f, F64Transmute { u: 0x4CA0000000000000 }.f, F64Transmute { u: 0x4CB0000000000000 }.f, F64Transmute { u: 0x4CC0000000000000 }.f, F64Transmute { u: 0x4CD0000000000000 }.f, F64Transmute { u: 0x4CE0000000000000 }.f, F64Transmute { u: 0x4CF0000000000000 }.f, F64Transmute { u: 0x4D00000000000000 }.f, F64Transmute { u: 0x4D10000000000000 }.f, F64Transmute { u: 0x4D20000000000000 }.f, F64Transmute { u: 0x4D30000000000000 }.f, F64Transmute { u: 0x4D40000000000000 }.f, F64Transmute { u: 0x4D50000000000000 }.f, F64Transmute { u: 0x4D60000000000000 }.f, F64Transmute { u: 0x4D70000000000000 }.f, F64Transmute { u: 0x4D80000000000000 }.f, F64Transmute { u: 0x4D90000000000000 }.f, F64Transmute { u: 0x4DA0000000000000 }.f, F64Transmute { u: 0x4DB0000000000000 }.f, F64Transmute { u: 0x4DC0000000000000 }.f, F64Transmute { u: 0x4DD0000000000000 }.f, F64Transmute { u: 0x4DE0000000000000 }.f, F64Transmute { u: 0x4DF0000000000000 }.f, F64Transmute { u: 0x4E00000000000000 }.f, F64Transmute { u: 0x4E10000000000000 }.f, F64Transmute { u: 0x4E20000000000000 }.f, F64Transmute { u: 0x4E30000000000000 }.f, F64Transmute { u: 0x4E40000000000000 }.f, F64Transmute { u: 0x4E50000000000000 }.f, F64Transmute { u: 0x4E60000000000000 }.f, F64Transmute { u: 0x4E70000000000000 }.f, F64Transmute { u: 0x4E80000000000000 }.f, F64Transmute { u: 0x4E90000000000000 }.f, F64Transmute { u: 0x4EA0000000000000 }.f, F64Transmute { u: 0x4EB0000000000000 }.f, F64Transmute { u: 0x4EC0000000000000 }.f, F64Transmute { u: 0x4ED0000000000000 }.f, F64Transmute { u: 0x4EE0000000000000 }.f, F64Transmute { u: 0x4EF0000000000000 }.f, F64Transmute { u: 0x4F00000000000000 }.f, F64Transmute { u: 0x4F10000000000000 }.f, F64Transmute { u: 0x4F20000000000000 }.f, F64Transmute { u: 0x4F30000000000000 }.f, F64Transmute { u: 0x4F40000000000000 }.f, F64Transmute { u: 0x4F50000000000000 }.f, F64Transmute { u: 0x4F60000000000000 }.f, F64Transmute { u: 0x4F70000000000000 }.f, F64Transmute { u: 0x4F80000000000000 }.f, F64Transmute { u: 0x4F90000000000000 }.f, F64Transmute { u: 0x4FA0000000000000 }.f, F64Transmute { u: 0x4FB0000000000000 }.f, F64Transmute { u: 0x4FC0000000000000 }.f, F64Transmute { u: 0x4FD0000000000000 }.f, F64Transmute { u: 0x4FE0000000000000 }.f, F64Transmute { u: 0x4FF0000000000000 }.f, F64Transmute { u: 0x5000000000000000 }.f, F64Transmute { u: 0x5010000000000000 }.f, F64Transmute { u: 0x5020000000000000 }.f, F64Transmute { u: 0x5030000000000000 }.f, F64Transmute { u: 0x5040000000000000 }.f, F64Transmute { u: 0x5050000000000000 }.f, F64Transmute { u: 0x5060000000000000 }.f, F64Transmute { u: 0x5070000000000000 }.f, F64Transmute { u: 0x5080000000000000 }.f, F64Transmute { u: 0x5090000000000000 }.f, F64Transmute { u: 0x50A0000000000000 }.f, F64Transmute { u: 0x50B0000000000000 }.f, F64Transmute { u: 0x50C0000000000000 }.f, F64Transmute { u: 0x50D0000000000000 }.f, F64Transmute { u: 0x50E0000000000000 }.f, F64Transmute { u: 0x50F0000000000000 }.f, F64Transmute { u: 0x5100000000000000 }.f, F64Transmute { u: 0x5110000000000000 }.f, F64Transmute { u: 0x5120000000000000 }.f, F64Transmute { u: 0x5130000000000000 }.f, F64Transmute { u: 0x5140000000000000 }.f, F64Transmute { u: 0x5150000000000000 }.f, F64Transmute { u: 0x5160000000000000 }.f, F64Transmute { u: 0x5170000000000000 }.f, F64Transmute { u: 0x5180000000000000 }.f, F64Transmute { u: 0x5190000000000000 }.f, F64Transmute { u: 0x51A0000000000000 }.f, F64Transmute { u: 0x51B0000000000000 }.f, F64Transmute { u: 0x51C0000000000000 }.f, F64Transmute { u: 0x51D0000000000000 }.f, F64Transmute { u: 0x51E0000000000000 }.f, F64Transmute { u: 0x51F0000000000000 }.f, F64Transmute { u: 0x5200000000000000 }.f, F64Transmute { u: 0x5210000000000000 }.f, F64Transmute { u: 0x5220000000000000 }.f, F64Transmute { u: 0x5230000000000000 }.f, F64Transmute { u: 0x5240000000000000 }.f, F64Transmute { u: 0x5250000000000000 }.f, F64Transmute { u: 0x5260000000000000 }.f, F64Transmute { u: 0x5270000000000000 }.f, F64Transmute { u: 0x5280000000000000 }.f, F64Transmute { u: 0x5290000000000000 }.f, F64Transmute { u: 0x52A0000000000000 }.f, F64Transmute { u: 0x52B0000000000000 }.f, F64Transmute { u: 0x52C0000000000000 }.f, F64Transmute { u: 0x52D0000000000000 }.f, F64Transmute { u: 0x52E0000000000000 }.f, F64Transmute { u: 0x52F0000000000000 }.f, F64Transmute { u: 0x5300000000000000 }.f, F64Transmute { u: 0x5310000000000000 }.f, F64Transmute { u: 0x5320000000000000 }.f, F64Transmute { u: 0x5330000000000000 }.f, F64Transmute { u: 0x5340000000000000 }.f, F64Transmute { u: 0x5350000000000000 }.f, F64Transmute { u: 0x5360000000000000 }.f, F64Transmute { u: 0x5370000000000000 }.f, F64Transmute { u: 0x5380000000000000 }.f, F64Transmute { u: 0x5390000000000000 }.f, F64Transmute { u: 0x53A0000000000000 }.f, F64Transmute { u: 0x53B0000000000000 }.f, F64Transmute { u: 0x53C0000000000000 }.f, F64Transmute { u: 0x53D0000000000000 }.f, F64Transmute { u: 0x53E0000000000000 }.f, F64Transmute { u: 0x53F0000000000000 }.f, F64Transmute { u: 0x5400000000000000 }.f, F64Transmute { u: 0x5410000000000000 }.f, F64Transmute { u: 0x5420000000000000 }.f, F64Transmute { u: 0x5430000000000000 }.f, F64Transmute { u: 0x5440000000000000 }.f, F64Transmute { u: 0x5450000000000000 }.f, F64Transmute { u: 0x5460000000000000 }.f, F64Transmute { u: 0x5470000000000000 }.f, F64Transmute { u: 0x5480000000000000 }.f, F64Transmute { u: 0x5490000000000000 }.f, F64Transmute { u: 0x54A0000000000000 }.f, F64Transmute { u: 0x54B0000000000000 }.f, F64Transmute { u: 0x54C0000000000000 }.f, F64Transmute { u: 0x54D0000000000000 }.f, F64Transmute { u: 0x54E0000000000000 }.f, F64Transmute { u: 0x54F0000000000000 }.f, F64Transmute { u: 0x5500000000000000 }.f, F64Transmute { u: 0x5510000000000000 }.f, F64Transmute { u: 0x5520000000000000 }.f, F64Transmute { u: 0x5530000000000000 }.f, F64Transmute { u: 0x5540000000000000 }.f, F64Transmute { u: 0x5550000000000000 }.f, F64Transmute { u: 0x5560000000000000 }.f, F64Transmute { u: 0x5570000000000000 }.f, F64Transmute { u: 0x5580000000000000 }.f, F64Transmute { u: 0x5590000000000000 }.f, F64Transmute { u: 0x55A0000000000000 }.f, F64Transmute { u: 0x55B0000000000000 }.f, F64Transmute { u: 0x55C0000000000000 }.f, F64Transmute { u: 0x55D0000000000000 }.f, F64Transmute { u: 0x55E0000000000000 }.f, F64Transmute { u: 0x55F0000000000000 }.f, F64Transmute { u: 0x5600000000000000 }.f, F64Transmute { u: 0x5610000000000000 }.f, F64Transmute { u: 0x5620000000000000 }.f, F64Transmute { u: 0x5630000000000000 }.f, F64Transmute { u: 0x5640000000000000 }.f, F64Transmute { u: 0x5650000000000000 }.f, F64Transmute { u: 0x5660000000000000 }.f, F64Transmute { u: 0x5670000000000000 }.f, F64Transmute { u: 0x5680000000000000 }.f, F64Transmute { u: 0x5690000000000000 }.f, F64Transmute { u: 0x56A0000000000000 }.f, F64Transmute { u: 0x56B0000000000000 }.f, F64Transmute { u: 0x56C0000000000000 }.f, F64Transmute { u: 0x56D0000000000000 }.f, F64Transmute { u: 0x56E0000000000000 }.f, F64Transmute { u: 0x56F0000000000000 }.f, F64Transmute { u: 0x5700000000000000 }.f, F64Transmute { u: 0x5710000000000000 }.f, F64Transmute { u: 0x5720000000000000 }.f, F64Transmute { u: 0x5730000000000000 }.f, F64Transmute { u: 0x5740000000000000 }.f, F64Transmute { u: 0x5750000000000000 }.f, F64Transmute { u: 0x5760000000000000 }.f, F64Transmute { u: 0x5770000000000000 }.f, F64Transmute { u: 0x5780000000000000 }.f, F64Transmute { u: 0x5790000000000000 }.f, F64Transmute { u: 0x57A0000000000000 }.f, F64Transmute { u: 0x57B0000000000000 }.f, F64Transmute { u: 0x57C0000000000000 }.f, F64Transmute { u: 0x57D0000000000000 }.f, F64Transmute { u: 0x57E0000000000000 }.f, F64Transmute { u: 0x57F0000000000000 }.f, F64Transmute { u: 0x5800000000000000 }.f, F64Transmute { u: 0x5810000000000000 }.f, F64Transmute { u: 0x5820000000000000 }.f, F64Transmute { u: 0x5830000000000000 }.f, F64Transmute { u: 0x5840000000000000 }.f, F64Transmute { u: 0x5850000000000000 }.f, F64Transmute { u: 0x5860000000000000 }.f, F64Transmute { u: 0x5870000000000000 }.f, F64Transmute { u: 0x5880000000000000 }.f, F64Transmute { u: 0x5890000000000000 }.f, F64Transmute { u: 0x58A0000000000000 }.f, F64Transmute { u: 0x58B0000000000000 }.f, F64Transmute { u: 0x58C0000000000000 }.f, F64Transmute { u: 0x58D0000000000000 }.f, F64Transmute { u: 0x58E0000000000000 }.f, F64Transmute { u: 0x58F0000000000000 }.f, F64Transmute { u: 0x5900000000000000 }.f, F64Transmute { u: 0x5910000000000000 }.f, F64Transmute { u: 0x5920000000000000 }.f, F64Transmute { u: 0x5930000000000000 }.f, F64Transmute { u: 0x5940000000000000 }.f, F64Transmute { u: 0x5950000000000000 }.f, F64Transmute { u: 0x5960000000000000 }.f, F64Transmute { u: 0x5970000000000000 }.f, F64Transmute { u: 0x5980000000000000 }.f, F64Transmute { u: 0x5990000000000000 }.f, F64Transmute { u: 0x59A0000000000000 }.f, F64Transmute { u: 0x59B0000000000000 }.f, F64Transmute { u: 0x59C0000000000000 }.f, F64Transmute { u: 0x59D0000000000000 }.f, F64Transmute { u: 0x59E0000000000000 }.f, F64Transmute { u: 0x59F0000000000000 }.f, F64Transmute { u: 0x5A00000000000000 }.f, F64Transmute { u: 0x5A10000000000000 }.f, F64Transmute { u: 0x5A20000000000000 }.f, F64Transmute { u: 0x5A30000000000000 }.f, F64Transmute { u: 0x5A40000000000000 }.f, F64Transmute { u: 0x5A50000000000000 }.f, F64Transmute { u: 0x5A60000000000000 }.f, F64Transmute { u: 0x5A70000000000000 }.f, F64Transmute { u: 0x5A80000000000000 }.f, F64Transmute { u: 0x5A90000000000000 }.f, F64Transmute { u: 0x5AA0000000000000 }.f, F64Transmute { u: 0x5AB0000000000000 }.f, F64Transmute { u: 0x5AC0000000000000 }.f, F64Transmute { u: 0x5AD0000000000000 }.f, F64Transmute { u: 0x5AE0000000000000 }.f, F64Transmute { u: 0x5AF0000000000000 }.f, F64Transmute { u: 0x5B00000000000000 }.f, F64Transmute { u: 0x5B10000000000000 }.f, F64Transmute { u: 0x5B20000000000000 }.f, F64Transmute { u: 0x5B30000000000000 }.f, F64Transmute { u: 0x5B40000000000000 }.f, F64Transmute { u: 0x5B50000000000000 }.f, F64Transmute { u: 0x5B60000000000000 }.f, F64Transmute { u: 0x5B70000000000000 }.f, F64Transmute { u: 0x5B80000000000000 }.f, F64Transmute { u: 0x5B90000000000000 }.f, F64Transmute { u: 0x5BA0000000000000 }.f, F64Transmute { u: 0x5BB0000000000000 }.f, F64Transmute { u: 0x5BC0000000000000 }.f, F64Transmute { u: 0x5BD0000000000000 }.f, F64Transmute { u: 0x5BE0000000000000 }.f, F64Transmute { u: 0x5BF0000000000000 }.f, F64Transmute { u: 0x5C00000000000000 }.f, F64Transmute { u: 0x5C10000000000000 }.f, F64Transmute { u: 0x5C20000000000000 }.f, F64Transmute { u: 0x5C30000000000000 }.f, F64Transmute { u: 0x5C40000000000000 }.f, F64Transmute { u: 0x5C50000000000000 }.f, F64Transmute { u: 0x5C60000000000000 }.f, F64Transmute { u: 0x5C70000000000000 }.f, F64Transmute { u: 0x5C80000000000000 }.f, F64Transmute { u: 0x5C90000000000000 }.f, F64Transmute { u: 0x5CA0000000000000 }.f, F64Transmute { u: 0x5CB0000000000000 }.f, F64Transmute { u: 0x5CC0000000000000 }.f, F64Transmute { u: 0x5CD0000000000000 }.f, F64Transmute { u: 0x5CE0000000000000 }.f, F64Transmute { u: 0x5CF0000000000000 }.f, F64Transmute { u: 0x5D00000000000000 }.f, F64Transmute { u: 0x5D10000000000000 }.f, F64Transmute { u: 0x5D20000000000000 }.f, F64Transmute { u: 0x5D30000000000000 }.f, F64Transmute { u: 0x5D40000000000000 }.f, F64Transmute { u: 0x5D50000000000000 }.f, F64Transmute { u: 0x5D60000000000000 }.f, F64Transmute { u: 0x5D70000000000000 }.f, F64Transmute { u: 0x5D80000000000000 }.f, F64Transmute { u: 0x5D90000000000000 }.f, F64Transmute { u: 0x5DA0000000000000 }.f, F64Transmute { u: 0x5DB0000000000000 }.f, F64Transmute { u: 0x5DC0000000000000 }.f, F64Transmute { u: 0x5DD0000000000000 }.f, F64Transmute { u: 0x5DE0000000000000 }.f, F64Transmute { u: 0x5DF0000000000000 }.f, F64Transmute { u: 0x5E00000000000000 }.f, F64Transmute { u: 0x5E10000000000000 }.f, F64Transmute { u: 0x5E20000000000000 }.f, F64Transmute { u: 0x5E30000000000000 }.f, F64Transmute { u: 0x5E40000000000000 }.f, F64Transmute { u: 0x5E50000000000000 }.f, F64Transmute { u: 0x5E60000000000000 }.f, F64Transmute { u: 0x5E70000000000000 }.f, F64Transmute { u: 0x5E80000000000000 }.f, F64Transmute { u: 0x5E90000000000000 }.f, F64Transmute { u: 0x5EA0000000000000 }.f, F64Transmute { u: 0x5EB0000000000000 }.f, F64Transmute { u: 0x5EC0000000000000 }.f, F64Transmute { u: 0x5ED0000000000000 }.f, F64Transmute { u: 0x5EE0000000000000 }.f, F64Transmute { u: 0x5EF0000000000000 }.f, F64Transmute { u: 0x5F00000000000000 }.f, F64Transmute { u: 0x5F10000000000000 }.f, F64Transmute { u: 0x5F20000000000000 }.f, F64Transmute { u: 0x5F30000000000000 }.f, F64Transmute { u: 0x5F40000000000000 }.f, F64Transmute { u: 0x5F50000000000000 }.f, F64Transmute { u: 0x5F60000000000000 }.f, F64Transmute { u: 0x5F70000000000000 }.f, F64Transmute { u: 0x5F80000000000000 }.f, F64Transmute { u: 0x5F90000000000000 }.f, F64Transmute { u: 0x5FA0000000000000 }.f, F64Transmute { u: 0x5FB0000000000000 }.f, F64Transmute { u: 0x5FC0000000000000 }.f, F64Transmute { u: 0x5FD0000000000000 }.f, F64Transmute { u: 0x5FE0000000000000 }.f, F64Transmute { u: 0x5FF0000000000000 }.f, F64Transmute { u: 0x6000000000000000 }.f, F64Transmute { u: 0x6010000000000000 }.f, F64Transmute { u: 0x6020000000000000 }.f, F64Transmute { u: 0x6030000000000000 }.f, F64Transmute { u: 0x6040000000000000 }.f, F64Transmute { u: 0x6050000000000000 }.f, F64Transmute { u: 0x6060000000000000 }.f, F64Transmute { u: 0x6070000000000000 }.f, F64Transmute { u: 0x6080000000000000 }.f, F64Transmute { u: 0x6090000000000000 }.f, F64Transmute { u: 0x60A0000000000000 }.f, F64Transmute { u: 0x60B0000000000000 }.f, F64Transmute { u: 0x60C0000000000000 }.f, F64Transmute { u: 0x60D0000000000000 }.f, F64Transmute { u: 0x60E0000000000000 }.f, F64Transmute { u: 0x60F0000000000000 }.f, F64Transmute { u: 0x6100000000000000 }.f, F64Transmute { u: 0x6110000000000000 }.f, F64Transmute { u: 0x6120000000000000 }.f, F64Transmute { u: 0x6130000000000000 }.f, F64Transmute { u: 0x6140000000000000 }.f, F64Transmute { u: 0x6150000000000000 }.f, F64Transmute { u: 0x6160000000000000 }.f, F64Transmute { u: 0x6170000000000000 }.f, F64Transmute { u: 0x6180000000000000 }.f, F64Transmute { u: 0x6190000000000000 }.f, F64Transmute { u: 0x61A0000000000000 }.f, F64Transmute { u: 0x61B0000000000000 }.f, F64Transmute { u: 0x61C0000000000000 }.f, F64Transmute { u: 0x61D0000000000000 }.f, F64Transmute { u: 0x61E0000000000000 }.f, F64Transmute { u: 0x61F0000000000000 }.f, F64Transmute { u: 0x6200000000000000 }.f, F64Transmute { u: 0x6210000000000000 }.f, F64Transmute { u: 0x6220000000000000 }.f, F64Transmute { u: 0x6230000000000000 }.f, F64Transmute { u: 0x6240000000000000 }.f, F64Transmute { u: 0x6250000000000000 }.f, F64Transmute { u: 0x6260000000000000 }.f, F64Transmute { u: 0x6270000000000000 }.f, F64Transmute { u: 0x6280000000000000 }.f, F64Transmute { u: 0x6290000000000000 }.f, F64Transmute { u: 0x62A0000000000000 }.f, F64Transmute { u: 0x62B0000000000000 }.f, F64Transmute { u: 0x62C0000000000000 }.f, F64Transmute { u: 0x62D0000000000000 }.f, F64Transmute { u: 0x62E0000000000000 }.f, F64Transmute { u: 0x62F0000000000000 }.f, F64Transmute { u: 0x6300000000000000 }.f, F64Transmute { u: 0x6310000000000000 }.f, F64Transmute { u: 0x6320000000000000 }.f, F64Transmute { u: 0x6330000000000000 }.f, F64Transmute { u: 0x6340000000000000 }.f, F64Transmute { u: 0x6350000000000000 }.f, F64Transmute { u: 0x6360000000000000 }.f, F64Transmute { u: 0x6370000000000000 }.f, F64Transmute { u: 0x6380000000000000 }.f, F64Transmute { u: 0x6390000000000000 }.f, F64Transmute { u: 0x63A0000000000000 }.f, F64Transmute { u: 0x63B0000000000000 }.f, F64Transmute { u: 0x63C0000000000000 }.f, F64Transmute { u: 0x63D0000000000000 }.f, F64Transmute { u: 0x63E0000000000000 }.f, F64Transmute { u: 0x63F0000000000000 }.f, F64Transmute { u: 0x6400000000000000 }.f, F64Transmute { u: 0x6410000000000000 }.f, F64Transmute { u: 0x6420000000000000 }.f, F64Transmute { u: 0x6430000000000000 }.f, F64Transmute { u: 0x6440000000000000 }.f, F64Transmute { u: 0x6450000000000000 }.f, F64Transmute { u: 0x6460000000000000 }.f, F64Transmute { u: 0x6470000000000000 }.f, F64Transmute { u: 0x6480000000000000 }.f, F64Transmute { u: 0x6490000000000000 }.f, F64Transmute { u: 0x64A0000000000000 }.f, F64Transmute { u: 0x64B0000000000000 }.f, F64Transmute { u: 0x64C0000000000000 }.f, F64Transmute { u: 0x64D0000000000000 }.f, F64Transmute { u: 0x64E0000000000000 }.f, F64Transmute { u: 0x64F0000000000000 }.f, F64Transmute { u: 0x6500000000000000 }.f, F64Transmute { u: 0x6510000000000000 }.f, F64Transmute { u: 0x6520000000000000 }.f, F64Transmute { u: 0x6530000000000000 }.f, F64Transmute { u: 0x6540000000000000 }.f, F64Transmute { u: 0x6550000000000000 }.f, F64Transmute { u: 0x6560000000000000 }.f, F64Transmute { u: 0x6570000000000000 }.f, F64Transmute { u: 0x6580000000000000 }.f, F64Transmute { u: 0x6590000000000000 }.f, F64Transmute { u: 0x65A0000000000000 }.f, F64Transmute { u: 0x65B0000000000000 }.f, F64Transmute { u: 0x65C0000000000000 }.f, F64Transmute { u: 0x65D0000000000000 }.f, F64Transmute { u: 0x65E0000000000000 }.f, F64Transmute { u: 0x65F0000000000000 }.f, F64Transmute { u: 0x6600000000000000 }.f, F64Transmute { u: 0x6610000000000000 }.f, F64Transmute { u: 0x6620000000000000 }.f, F64Transmute { u: 0x6630000000000000 }.f, F64Transmute { u: 0x6640000000000000 }.f, F64Transmute { u: 0x6650000000000000 }.f, F64Transmute { u: 0x6660000000000000 }.f, F64Transmute { u: 0x6670000000000000 }.f, F64Transmute { u: 0x6680000000000000 }.f, F64Transmute { u: 0x6690000000000000 }.f, F64Transmute { u: 0x66A0000000000000 }.f, F64Transmute { u: 0x66B0000000000000 }.f, F64Transmute { u: 0x66C0000000000000 }.f, F64Transmute { u: 0x66D0000000000000 }.f, F64Transmute { u: 0x66E0000000000000 }.f, F64Transmute { u: 0x66F0000000000000 }.f, F64Transmute { u: 0x6700000000000000 }.f, F64Transmute { u: 0x6710000000000000 }.f, F64Transmute { u: 0x6720000000000000 }.f, F64Transmute { u: 0x6730000000000000 }.f, F64Transmute { u: 0x6740000000000000 }.f, F64Transmute { u: 0x6750000000000000 }.f, F64Transmute { u: 0x6760000000000000 }.f, F64Transmute { u: 0x6770000000000000 }.f, F64Transmute { u: 0x6780000000000000 }.f, F64Transmute { u: 0x6790000000000000 }.f, F64Transmute { u: 0x67A0000000000000 }.f, F64Transmute { u: 0x67B0000000000000 }.f, F64Transmute { u: 0x67C0000000000000 }.f, F64Transmute { u: 0x67D0000000000000 }.f, F64Transmute { u: 0x67E0000000000000 }.f, F64Transmute { u: 0x67F0000000000000 }.f, F64Transmute { u: 0x6800000000000000 }.f, F64Transmute { u: 0x6810000000000000 }.f, F64Transmute { u: 0x6820000000000000 }.f, F64Transmute { u: 0x6830000000000000 }.f, F64Transmute { u: 0x6840000000000000 }.f, F64Transmute { u: 0x6850000000000000 }.f, F64Transmute { u: 0x6860000000000000 }.f, F64Transmute { u: 0x6870000000000000 }.f, F64Transmute { u: 0x6880000000000000 }.f, F64Transmute { u: 0x6890000000000000 }.f, F64Transmute { u: 0x68A0000000000000 }.f, F64Transmute { u: 0x68B0000000000000 }.f, F64Transmute { u: 0x68C0000000000000 }.f, F64Transmute { u: 0x68D0000000000000 }.f, F64Transmute { u: 0x68E0000000000000 }.f, F64Transmute { u: 0x68F0000000000000 }.f, F64Transmute { u: 0x6900000000000000 }.f, F64Transmute { u: 0x6910000000000000 }.f, F64Transmute { u: 0x6920000000000000 }.f, F64Transmute { u: 0x6930000000000000 }.f, F64Transmute { u: 0x6940000000000000 }.f, F64Transmute { u: 0x6950000000000000 }.f, F64Transmute { u: 0x6960000000000000 }.f, F64Transmute { u: 0x6970000000000000 }.f, F64Transmute { u: 0x6980000000000000 }.f, F64Transmute { u: 0x6990000000000000 }.f, F64Transmute { u: 0x69A0000000000000 }.f, F64Transmute { u: 0x69B0000000000000 }.f, F64Transmute { u: 0x69C0000000000000 }.f, F64Transmute { u: 0x69D0000000000000 }.f, F64Transmute { u: 0x69E0000000000000 }.f, F64Transmute { u: 0x69F0000000000000 }.f, F64Transmute { u: 0x6A00000000000000 }.f, F64Transmute { u: 0x6A10000000000000 }.f, F64Transmute { u: 0x6A20000000000000 }.f, F64Transmute { u: 0x6A30000000000000 }.f, F64Transmute { u: 0x6A40000000000000 }.f, F64Transmute { u: 0x6A50000000000000 }.f, F64Transmute { u: 0x6A60000000000000 }.f, F64Transmute { u: 0x6A70000000000000 }.f, F64Transmute { u: 0x6A80000000000000 }.f, F64Transmute { u: 0x6A90000000000000 }.f, F64Transmute { u: 0x6AA0000000000000 }.f, F64Transmute { u: 0x6AB0000000000000 }.f, F64Transmute { u: 0x6AC0000000000000 }.f, F64Transmute { u: 0x6AD0000000000000 }.f, F64Transmute { u: 0x6AE0000000000000 }.f, F64Transmute { u: 0x6AF0000000000000 }.f, F64Transmute { u: 0x6B00000000000000 }.f, F64Transmute { u: 0x6B10000000000000 }.f, F64Transmute { u: 0x6B20000000000000 }.f, F64Transmute { u: 0x6B30000000000000 }.f, F64Transmute { u: 0x6B40000000000000 }.f, F64Transmute { u: 0x6B50000000000000 }.f, F64Transmute { u: 0x6B60000000000000 }.f, F64Transmute { u: 0x6B70000000000000 }.f, F64Transmute { u: 0x6B80000000000000 }.f, F64Transmute { u: 0x6B90000000000000 }.f, F64Transmute { u: 0x6BA0000000000000 }.f, F64Transmute { u: 0x6BB0000000000000 }.f, F64Transmute { u: 0x6BC0000000000000 }.f, F64Transmute { u: 0x6BD0000000000000 }.f, F64Transmute { u: 0x6BE0000000000000 }.f, F64Transmute { u: 0x6BF0000000000000 }.f, F64Transmute { u: 0x6C00000000000000 }.f, F64Transmute { u: 0x6C10000000000000 }.f, F64Transmute { u: 0x6C20000000000000 }.f, F64Transmute { u: 0x6C30000000000000 }.f, F64Transmute { u: 0x6C40000000000000 }.f, F64Transmute { u: 0x6C50000000000000 }.f, F64Transmute { u: 0x6C60000000000000 }.f, F64Transmute { u: 0x6C70000000000000 }.f, F64Transmute { u: 0x6C80000000000000 }.f, F64Transmute { u: 0x6C90000000000000 }.f, F64Transmute { u: 0x6CA0000000000000 }.f, F64Transmute { u: 0x6CB0000000000000 }.f, F64Transmute { u: 0x6CC0000000000000 }.f, F64Transmute { u: 0x6CD0000000000000 }.f, F64Transmute { u: 0x6CE0000000000000 }.f, F64Transmute { u: 0x6CF0000000000000 }.f, F64Transmute { u: 0x6D00000000000000 }.f, F64Transmute { u: 0x6D10000000000000 }.f, F64Transmute { u: 0x6D20000000000000 }.f, F64Transmute { u: 0x6D30000000000000 }.f, F64Transmute { u: 0x6D40000000000000 }.f, F64Transmute { u: 0x6D50000000000000 }.f, F64Transmute { u: 0x6D60000000000000 }.f, F64Transmute { u: 0x6D70000000000000 }.f, F64Transmute { u: 0x6D80000000000000 }.f, F64Transmute { u: 0x6D90000000000000 }.f, F64Transmute { u: 0x6DA0000000000000 }.f, F64Transmute { u: 0x6DB0000000000000 }.f, F64Transmute { u: 0x6DC0000000000000 }.f, F64Transmute { u: 0x6DD0000000000000 }.f, F64Transmute { u: 0x6DE0000000000000 }.f, F64Transmute { u: 0x6DF0000000000000 }.f, F64Transmute { u: 0x6E00000000000000 }.f, F64Transmute { u: 0x6E10000000000000 }.f, F64Transmute { u: 0x6E20000000000000 }.f, F64Transmute { u: 0x6E30000000000000 }.f, F64Transmute { u: 0x6E40000000000000 }.f, F64Transmute { u: 0x6E50000000000000 }.f, F64Transmute { u: 0x6E60000000000000 }.f, F64Transmute { u: 0x6E70000000000000 }.f, F64Transmute { u: 0x6E80000000000000 }.f, F64Transmute { u: 0x6E90000000000000 }.f, F64Transmute { u: 0x6EA0000000000000 }.f, F64Transmute { u: 0x6EB0000000000000 }.f, F64Transmute { u: 0x6EC0000000000000 }.f, F64Transmute { u: 0x6ED0000000000000 }.f, F64Transmute { u: 0x6EE0000000000000 }.f, F64Transmute { u: 0x6EF0000000000000 }.f, F64Transmute { u: 0x6F00000000000000 }.f, F64Transmute { u: 0x6F10000000000000 }.f, F64Transmute { u: 0x6F20000000000000 }.f, F64Transmute { u: 0x6F30000000000000 }.f, F64Transmute { u: 0x6F40000000000000 }.f, F64Transmute { u: 0x6F50000000000000 }.f, F64Transmute { u: 0x6F60000000000000 }.f, F64Transmute { u: 0x6F70000000000000 }.f, F64Transmute { u: 0x6F80000000000000 }.f, F64Transmute { u: 0x6F90000000000000 }.f, F64Transmute { u: 0x6FA0000000000000 }.f, F64Transmute { u: 0x6FB0000000000000 }.f, F64Transmute { u: 0x6FC0000000000000 }.f, F64Transmute { u: 0x6FD0000000000000 }.f, F64Transmute { u: 0x6FE0000000000000 }.f, F64Transmute { u: 0x6FF0000000000000 }.f, F64Transmute { u: 0x7000000000000000 }.f, F64Transmute { u: 0x7010000000000000 }.f, F64Transmute { u: 0x7020000000000000 }.f, F64Transmute { u: 0x7030000000000000 }.f, F64Transmute { u: 0x7040000000000000 }.f, F64Transmute { u: 0x7050000000000000 }.f, F64Transmute { u: 0x7060000000000000 }.f, F64Transmute { u: 0x7070000000000000 }.f, F64Transmute { u: 0x7080000000000000 }.f, F64Transmute { u: 0x7090000000000000 }.f, F64Transmute { u: 0x70A0000000000000 }.f, F64Transmute { u: 0x70B0000000000000 }.f, F64Transmute { u: 0x70C0000000000000 }.f, F64Transmute { u: 0x70D0000000000000 }.f, F64Transmute { u: 0x70E0000000000000 }.f, F64Transmute { u: 0x70F0000000000000 }.f, F64Transmute { u: 0x7100000000000000 }.f, F64Transmute { u: 0x7110000000000000 }.f, F64Transmute { u: 0x7120000000000000 }.f, F64Transmute { u: 0x7130000000000000 }.f, F64Transmute { u: 0x7140000000000000 }.f, F64Transmute { u: 0x7150000000000000 }.f, F64Transmute { u: 0x7160000000000000 }.f, F64Transmute { u: 0x7170000000000000 }.f, F64Transmute { u: 0x7180000000000000 }.f, F64Transmute { u: 0x7190000000000000 }.f, F64Transmute { u: 0x71A0000000000000 }.f, F64Transmute { u: 0x71B0000000000000 }.f, F64Transmute { u: 0x71C0000000000000 }.f, F64Transmute { u: 0x71D0000000000000 }.f, F64Transmute { u: 0x71E0000000000000 }.f, F64Transmute { u: 0x71F0000000000000 }.f, F64Transmute { u: 0x7200000000000000 }.f, F64Transmute { u: 0x7210000000000000 }.f, F64Transmute { u: 0x7220000000000000 }.f, F64Transmute { u: 0x7230000000000000 }.f, F64Transmute { u: 0x7240000000000000 }.f, F64Transmute { u: 0x7250000000000000 }.f, F64Transmute { u: 0x7260000000000000 }.f, F64Transmute { u: 0x7270000000000000 }.f, F64Transmute { u: 0x7280000000000000 }.f, F64Transmute { u: 0x7290000000000000 }.f, F64Transmute { u: 0x72A0000000000000 }.f, F64Transmute { u: 0x72B0000000000000 }.f, F64Transmute { u: 0x72C0000000000000 }.f, F64Transmute { u: 0x72D0000000000000 }.f, F64Transmute { u: 0x72E0000000000000 }.f, F64Transmute { u: 0x72F0000000000000 }.f, F64Transmute { u: 0x7300000000000000 }.f, F64Transmute { u: 0x7310000000000000 }.f, F64Transmute { u: 0x7320000000000000 }.f, F64Transmute { u: 0x7330000000000000 }.f, F64Transmute { u: 0x7340000000000000 }.f, F64Transmute { u: 0x7350000000000000 }.f, F64Transmute { u: 0x7360000000000000 }.f, F64Transmute { u: 0x7370000000000000 }.f, F64Transmute { u: 0x7380000000000000 }.f, F64Transmute { u: 0x7390000000000000 }.f, F64Transmute { u: 0x73A0000000000000 }.f, F64Transmute { u: 0x73B0000000000000 }.f, F64Transmute { u: 0x73C0000000000000 }.f, F64Transmute { u: 0x73D0000000000000 }.f, F64Transmute { u: 0x73E0000000000000 }.f, F64Transmute { u: 0x73F0000000000000 }.f, F64Transmute { u: 0x7400000000000000 }.f, F64Transmute { u: 0x7410000000000000 }.f, F64Transmute { u: 0x7420000000000000 }.f, F64Transmute { u: 0x7430000000000000 }.f, F64Transmute { u: 0x7440000000000000 }.f, F64Transmute { u: 0x7450000000000000 }.f, F64Transmute { u: 0x7460000000000000 }.f, F64Transmute { u: 0x7470000000000000 }.f, F64Transmute { u: 0x7480000000000000 }.f, F64Transmute { u: 0x7490000000000000 }.f, F64Transmute { u: 0x74A0000000000000 }.f, F64Transmute { u: 0x74B0000000000000 }.f, F64Transmute { u: 0x74C0000000000000 }.f, F64Transmute { u: 0x74D0000000000000 }.f, F64Transmute { u: 0x74E0000000000000 }.f, F64Transmute { u: 0x74F0000000000000 }.f, F64Transmute { u: 0x7500000000000000 }.f, F64Transmute { u: 0x7510000000000000 }.f, F64Transmute { u: 0x7520000000000000 }.f, F64Transmute { u: 0x7530000000000000 }.f, F64Transmute { u: 0x7540000000000000 }.f, F64Transmute { u: 0x7550000000000000 }.f, F64Transmute { u: 0x7560000000000000 }.f, F64Transmute { u: 0x7570000000000000 }.f, F64Transmute { u: 0x7580000000000000 }.f, F64Transmute { u: 0x7590000000000000 }.f, F64Transmute { u: 0x75A0000000000000 }.f, F64Transmute { u: 0x75B0000000000000 }.f, F64Transmute { u: 0x75C0000000000000 }.f, F64Transmute { u: 0x75D0000000000000 }.f, F64Transmute { u: 0x75E0000000000000 }.f, F64Transmute { u: 0x75F0000000000000 }.f, F64Transmute { u: 0x7600000000000000 }.f, F64Transmute { u: 0x7610000000000000 }.f, F64Transmute { u: 0x7620000000000000 }.f, F64Transmute { u: 0x7630000000000000 }.f, F64Transmute { u: 0x7640000000000000 }.f, F64Transmute { u: 0x7650000000000000 }.f, F64Transmute { u: 0x7660000000000000 }.f, F64Transmute { u: 0x7670000000000000 }.f, F64Transmute { u: 0x7680000000000000 }.f, F64Transmute { u: 0x7690000000000000 }.f, F64Transmute { u: 0x76A0000000000000 }.f, F64Transmute { u: 0x76B0000000000000 }.f, F64Transmute { u: 0x76C0000000000000 }.f, F64Transmute { u: 0x76D0000000000000 }.f, F64Transmute { u: 0x76E0000000000000 }.f, F64Transmute { u: 0x76F0000000000000 }.f, F64Transmute { u: 0x7700000000000000 }.f, F64Transmute { u: 0x7710000000000000 }.f, F64Transmute { u: 0x7720000000000000 }.f, F64Transmute { u: 0x7730000000000000 }.f, F64Transmute { u: 0x7740000000000000 }.f, F64Transmute { u: 0x7750000000000000 }.f, F64Transmute { u: 0x7760000000000000 }.f, F64Transmute { u: 0x7770000000000000 }.f, F64Transmute { u: 0x7780000000000000 }.f, F64Transmute { u: 0x7790000000000000 }.f, F64Transmute { u: 0x77A0000000000000 }.f, F64Transmute { u: 0x77B0000000000000 }.f, F64Transmute { u: 0x77C0000000000000 }.f, F64Transmute { u: 0x77D0000000000000 }.f, F64Transmute { u: 0x77E0000000000000 }.f, F64Transmute { u: 0x77F0000000000000 }.f, F64Transmute { u: 0x7800000000000000 }.f, F64Transmute { u: 0x7810000000000000 }.f, F64Transmute { u: 0x7820000000000000 }.f, F64Transmute { u: 0x7830000000000000 }.f, F64Transmute { u: 0x7840000000000000 }.f, F64Transmute { u: 0x7850000000000000 }.f, F64Transmute { u: 0x7860000000000000 }.f, F64Transmute { u: 0x7870000000000000 }.f, F64Transmute { u: 0x7880000000000000 }.f, F64Transmute { u: 0x7890000000000000 }.f, F64Transmute { u: 0x78A0000000000000 }.f, F64Transmute { u: 0x78B0000000000000 }.f, F64Transmute { u: 0x78C0000000000000 }.f, F64Transmute { u: 0x78D0000000000000 }.f, F64Transmute { u: 0x78E0000000000000 }.f, F64Transmute { u: 0x78F0000000000000 }.f, F64Transmute { u: 0x7900000000000000 }.f, F64Transmute { u: 0x7910000000000000 }.f, F64Transmute { u: 0x7920000000000000 }.f, F64Transmute { u: 0x7930000000000000 }.f, F64Transmute { u: 0x7940000000000000 }.f, F64Transmute { u: 0x7950000000000000 }.f, F64Transmute { u: 0x7960000000000000 }.f, F64Transmute { u: 0x7970000000000000 }.f, F64Transmute { u: 0x7980000000000000 }.f, F64Transmute { u: 0x7990000000000000 }.f, F64Transmute { u: 0x79A0000000000000 }.f, F64Transmute { u: 0x79B0000000000000 }.f, F64Transmute { u: 0x79C0000000000000 }.f, F64Transmute { u: 0x79D0000000000000 }.f, F64Transmute { u: 0x79E0000000000000 }.f, F64Transmute { u: 0x79F0000000000000 }.f, F64Transmute { u: 0x7A00000000000000 }.f, F64Transmute { u: 0x7A10000000000000 }.f, F64Transmute { u: 0x7A20000000000000 }.f, F64Transmute { u: 0x7A30000000000000 }.f, F64Transmute { u: 0x7A40000000000000 }.f, F64Transmute { u: 0x7A50000000000000 }.f, F64Transmute { u: 0x7A60000000000000 }.f, F64Transmute { u: 0x7A70000000000000 }.f, F64Transmute { u: 0x7A80000000000000 }.f, F64Transmute { u: 0x7A90000000000000 }.f, F64Transmute { u: 0x7AA0000000000000 }.f, F64Transmute { u: 0x7AB0000000000000 }.f, F64Transmute { u: 0x7AC0000000000000 }.f, F64Transmute { u: 0x7AD0000000000000 }.f, F64Transmute { u: 0x7AE0000000000000 }.f, F64Transmute { u: 0x7AF0000000000000 }.f, F64Transmute { u: 0x7B00000000000000 }.f, F64Transmute { u: 0x7B10000000000000 }.f, F64Transmute { u: 0x7B20000000000000 }.f, F64Transmute { u: 0x7B30000000000000 }.f, F64Transmute { u: 0x7B40000000000000 }.f, F64Transmute { u: 0x7B50000000000000 }.f, F64Transmute { u: 0x7B60000000000000 }.f, F64Transmute { u: 0x7B70000000000000 }.f, F64Transmute { u: 0x7B80000000000000 }.f, F64Transmute { u: 0x7B90000000000000 }.f, F64Transmute { u: 0x7BA0000000000000 }.f, F64Transmute { u: 0x7BB0000000000000 }.f, F64Transmute { u: 0x7BC0000000000000 }.f, F64Transmute { u: 0x7BD0000000000000 }.f, F64Transmute { u: 0x7BE0000000000000 }.f, F64Transmute { u: 0x7BF0000000000000 }.f, F64Transmute { u: 0x7C00000000000000 }.f, F64Transmute { u: 0x7C10000000000000 }.f, F64Transmute { u: 0x7C20000000000000 }.f, F64Transmute { u: 0x7C30000000000000 }.f, F64Transmute { u: 0x7C40000000000000 }.f, F64Transmute { u: 0x7C50000000000000 }.f, F64Transmute { u: 0x7C60000000000000 }.f, F64Transmute { u: 0x7C70000000000000 }.f, F64Transmute { u: 0x7C80000000000000 }.f, F64Transmute { u: 0x7C90000000000000 }.f, F64Transmute { u: 0x7CA0000000000000 }.f, F64Transmute { u: 0x7CB0000000000000 }.f, F64Transmute { u: 0x7CC0000000000000 }.f, F64Transmute { u: 0x7CD0000000000000 }.f, F64Transmute { u: 0x7CE0000000000000 }.f, F64Transmute { u: 0x7CF0000000000000 }.f, F64Transmute { u: 0x7D00000000000000 }.f, F64Transmute { u: 0x7D10000000000000 }.f, F64Transmute { u: 0x7D20000000000000 }.f, F64Transmute { u: 0x7D30000000000000 }.f, F64Transmute { u: 0x7D40000000000000 }.f, F64Transmute { u: 0x7D50000000000000 }.f, F64Transmute { u: 0x7D60000000000000 }.f, F64Transmute { u: 0x7D70000000000000 }.f, F64Transmute { u: 0x7D80000000000000 }.f, F64Transmute { u: 0x7D90000000000000 }.f, F64Transmute { u: 0x7DA0000000000000 }.f, F64Transmute { u: 0x7DB0000000000000 }.f, F64Transmute { u: 0x7DC0000000000000 }.f, F64Transmute { u: 0x7DD0000000000000 }.f, F64Transmute { u: 0x7DE0000000000000 }.f, F64Transmute { u: 0x7DF0000000000000 }.f, F64Transmute { u: 0x7E00000000000000 }.f, F64Transmute { u: 0x7E10000000000000 }.f, F64Transmute { u: 0x7E20000000000000 }.f, F64Transmute { u: 0x7E30000000000000 }.f, F64Transmute { u: 0x7E40000000000000 }.f, F64Transmute { u: 0x7E50000000000000 }.f, F64Transmute { u: 0x7E60000000000000 }.f, F64Transmute { u: 0x7E70000000000000 }.f, F64Transmute { u: 0x7E80000000000000 }.f, F64Transmute { u: 0x7E90000000000000 }.f, F64Transmute { u: 0x7EA0000000000000 }.f, F64Transmute { u: 0x7EB0000000000000 }.f, F64Transmute { u: 0x7EC0000000000000 }.f, F64Transmute { u: 0x7ED0000000000000 }.f, F64Transmute { u: 0x7EE0000000000000 }.f, F64Transmute { u: 0x7EF0000000000000 }.f, F64Transmute { u: 0x7F00000000000000 }.f, F64Transmute { u: 0x7F10000000000000 }.f, F64Transmute { u: 0x7F20000000000000 }.f, F64Transmute { u: 0x7F30000000000000 }.f, F64Transmute { u: 0x7F40000000000000 }.f, F64Transmute { u: 0x7F50000000000000 }.f, F64Transmute { u: 0x7F60000000000000 }.f, F64Transmute { u: 0x7F70000000000000 }.f, F64Transmute { u: 0x7F80000000000000 }.f, F64Transmute { u: 0x7F90000000000000 }.f, F64Transmute { u: 0x7FA0000000000000 }.f, F64Transmute { u: 0x7FB0000000000000 }.f, F64Transmute { u: 0x7FC0000000000000 }.f, F64Transmute { u: 0x7FD0000000000000 }.f, F64Transmute { u: 0x7FE0000000000000 }.f, ]}; /// Precalculated values of radix**i for i in range [0, arr.len()-1]. /// Each value can be **exactly** represented as that type. const F64_POW10: [f64; 23] = [1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0, 10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0, 100000000000000.0, 1000000000000000.0, 10000000000000000.0, 100000000000000000.0, 1000000000000000000.0, 10000000000000000000.0, 100000000000000000000.0, 1000000000000000000000.0, 10000000000000000000000.0]; #[cfg(feature = "radix")] const F64_POW3: [f64; 34] = [1.0, 3.0, 9.0, 27.0, 81.0, 243.0, 729.0, 2187.0, 6561.0, 19683.0, 59049.0, 177147.0, 531441.0, 1594323.0, 4782969.0, 14348907.0, 43046721.0, 129140163.0, 387420489.0, 1162261467.0, 3486784401.0, 10460353203.0, 31381059609.0, 94143178827.0, 282429536481.0, 847288609443.0, 2541865828329.0, 7625597484987.0, 22876792454961.0, 68630377364883.0, 205891132094649.0, 617673396283947.0, 1853020188851841.0, 5559060566555523.0]; #[cfg(feature = "radix")] const F64_POW5: [f64; 23] = [1.0, 5.0, 25.0, 125.0, 625.0, 3125.0, 15625.0, 78125.0, 390625.0, 1953125.0, 9765625.0, 48828125.0, 244140625.0, 1220703125.0, 6103515625.0, 30517578125.0, 152587890625.0, 762939453125.0, 3814697265625.0, 19073486328125.0, 95367431640625.0, 476837158203125.0, 2384185791015625.0]; #[cfg(feature = "radix")] const F64_POW6: [f64; 34] = [1.0, 6.0, 36.0, 216.0, 1296.0, 7776.0, 46656.0, 279936.0, 1679616.0, 10077696.0, 60466176.0, 362797056.0, 2176782336.0, 13060694016.0, 78364164096.0, 470184984576.0, 2821109907456.0, 16926659444736.0, 101559956668416.0, 609359740010496.0, 3656158440062976.0, 21936950640377856.0, 131621703842267136.0, 789730223053602816.0, 4738381338321616896.0, 28430288029929701376.0, 170581728179578208256.0, 1023490369077469249536.0, 6140942214464815497216.0, 36845653286788892983296.0, 221073919720733357899776.0, 1326443518324400147398656.0, 7958661109946400884391936.0, 47751966659678405306351616.0]; #[cfg(feature = "radix")] const F64_POW7: [f64; 19] = [1.0, 7.0, 49.0, 343.0, 2401.0, 16807.0, 117649.0, 823543.0, 5764801.0, 40353607.0, 282475249.0, 1977326743.0, 13841287201.0, 96889010407.0, 678223072849.0, 4747561509943.0, 33232930569601.0, 232630513987207.0, 1628413597910449.0]; #[cfg(feature = "radix")] const F64_POW9: [f64; 17] = [1.0, 9.0, 81.0, 729.0, 6561.0, 59049.0, 531441.0, 4782969.0, 43046721.0, 387420489.0, 3486784401.0, 31381059609.0, 282429536481.0, 2541865828329.0, 22876792454961.0, 205891132094649.0, 1853020188851841.0]; #[cfg(feature = "radix")] const F64_POW11: [f64; 16] = [1.0, 11.0, 121.0, 1331.0, 14641.0, 161051.0, 1771561.0, 19487171.0, 214358881.0, 2357947691.0, 25937424601.0, 285311670611.0, 3138428376721.0, 34522712143931.0, 379749833583241.0, 4177248169415651.0]; #[cfg(feature = "radix")] const F64_POW12: [f64; 34] = [1.0, 12.0, 144.0, 1728.0, 20736.0, 248832.0, 2985984.0, 35831808.0, 429981696.0, 5159780352.0, 61917364224.0, 743008370688.0, 8916100448256.0, 106993205379072.0, 1283918464548864.0, 15407021574586368.0, 184884258895036416.0, 2218611106740436992.0, 26623333280885243904.0, 319479999370622926848.0, 3833759992447475122176.0, 46005119909369701466112.0, 552061438912436417593344.0, 6624737266949237011120128.0, 79496847203390844133441536.0, 953962166440690129601298432.0, 11447545997288281555215581184.0, 137370551967459378662586974208.0, 1648446623609512543951043690496.0, 19781359483314150527412524285952.0, 237376313799769806328950291431424.0, 2848515765597237675947403497177088.0, 34182189187166852111368841966125056.0, 410186270246002225336426103593500672.0]; #[cfg(feature = "radix")] const F64_POW13: [f64; 15] = [1.0, 13.0, 169.0, 2197.0, 28561.0, 371293.0, 4826809.0, 62748517.0, 815730721.0, 10604499373.0, 137858491849.0, 1792160394037.0, 23298085122481.0, 302875106592253.0, 3937376385699289.0]; #[cfg(feature = "radix")] const F64_POW14: [f64; 19] = [1.0, 14.0, 196.0, 2744.0, 38416.0, 537824.0, 7529536.0, 105413504.0, 1475789056.0, 20661046784.0, 289254654976.0, 4049565169664.0, 56693912375296.0, 793714773254144.0, 11112006825558016.0, 155568095557812224.0, 2177953337809371136.0, 30491346729331195904.0, 426878854210636742656.0]; #[cfg(feature = "radix")] const F64_POW15: [f64; 14] = [1.0, 15.0, 225.0, 3375.0, 50625.0, 759375.0, 11390625.0, 170859375.0, 2562890625.0, 38443359375.0, 576650390625.0, 8649755859375.0, 129746337890625.0, 1946195068359375.0]; #[cfg(feature = "radix")] const F64_POW17: [f64; 13] = [1.0, 17.0, 289.0, 4913.0, 83521.0, 1419857.0, 24137569.0, 410338673.0, 6975757441.0, 118587876497.0, 2015993900449.0, 34271896307633.0, 582622237229761.0]; #[cfg(feature = "radix")] const F64_POW18: [f64; 17] = [1.0, 18.0, 324.0, 5832.0, 104976.0, 1889568.0, 34012224.0, 612220032.0, 11019960576.0, 198359290368.0, 3570467226624.0, 64268410079232.0, 1156831381426176.0, 20822964865671168.0, 374813367582081024.0, 6746640616477458432.0, 121439531096594251776.0]; #[cfg(feature = "radix")] const F64_POW19: [f64; 13] = [1.0, 19.0, 361.0, 6859.0, 130321.0, 2476099.0, 47045881.0, 893871739.0, 16983563041.0, 322687697779.0, 6131066257801.0, 116490258898219.0, 2213314919066161.0]; #[cfg(feature = "radix")] const F64_POW20: [f64; 23] = [1.0, 20.0, 400.0, 8000.0, 160000.0, 3200000.0, 64000000.0, 1280000000.0, 25600000000.0, 512000000000.0, 10240000000000.0, 204800000000000.0, 4096000000000000.0, 81920000000000000.0, 1638400000000000000.0, 32768000000000000000.0, 655360000000000000000.0, 13107200000000000000000.0, 262144000000000000000000.0, 5242880000000000000000000.0, 104857600000000000000000000.0, 2097152000000000000000000000.0, 41943040000000000000000000000.0]; #[cfg(feature = "radix")] const F64_POW21: [f64; 13] = [1.0, 21.0, 441.0, 9261.0, 194481.0, 4084101.0, 85766121.0, 1801088541.0, 37822859361.0, 794280046581.0, 16679880978201.0, 350277500542221.0, 7355827511386641.0]; #[cfg(feature = "radix")] const F64_POW22: [f64; 16] = [1.0, 22.0, 484.0, 10648.0, 234256.0, 5153632.0, 113379904.0, 2494357888.0, 54875873536.0, 1207269217792.0, 26559922791424.0, 584318301411328.0, 12855002631049216.0, 282810057883082752.0, 6221821273427820544.0, 136880068015412051968.0]; #[cfg(feature = "radix")] const F64_POW23: [f64; 12] = [1.0, 23.0, 529.0, 12167.0, 279841.0, 6436343.0, 148035889.0, 3404825447.0, 78310985281.0, 1801152661463.0, 41426511213649.0, 952809757913927.0]; #[cfg(feature = "radix")] const F64_POW24: [f64; 34] = [1.0, 24.0, 576.0, 13824.0, 331776.0, 7962624.0, 191102976.0, 4586471424.0, 110075314176.0, 2641807540224.0, 63403380965376.0, 1521681143169024.0, 36520347436056576.0, 876488338465357824.0, 21035720123168587776.0, 504857282956046106624.0, 12116574790945106558976.0, 290797794982682557415424.0, 6979147079584381377970176.0, 167499529910025153071284224.0, 4019988717840603673710821376.0, 96479729228174488169059713024.0, 2315513501476187716057433112576.0, 55572324035428505185378394701824.0, 1333735776850284124449081472843776.0, 32009658644406818986777955348250624.0, 768231807465763655682670928358014976.0, 18437563379178327736384102280592359424.0, 442501521100279865673218454734216626176.0, 10620036506406716776157242913621199028224.0, 254880876153761202627773829926908776677376.0, 6117141027690268863066571918245810640257024.0, 146811384664566452713597726037899455366168576.0, 3523473231949594865126345424909586928788045824.0]; #[cfg(feature = "radix")] const F64_POW25: [f64; 12] = [1.0, 25.0, 625.0, 15625.0, 390625.0, 9765625.0, 244140625.0, 6103515625.0, 152587890625.0, 3814697265625.0, 95367431640625.0, 2384185791015625.0]; #[cfg(feature = "radix")] const F64_POW26: [f64; 15] = [1.0, 26.0, 676.0, 17576.0, 456976.0, 11881376.0, 308915776.0, 8031810176.0, 208827064576.0, 5429503678976.0, 141167095653376.0, 3670344486987776.0, 95428956661682176.0, 2481152873203736576.0, 64509974703297150976.0]; #[cfg(feature = "radix")] const F64_POW27: [f64; 12] = [1.0, 27.0, 729.0, 19683.0, 531441.0, 14348907.0, 387420489.0, 10460353203.0, 282429536481.0, 7625597484987.0, 205891132094649.0, 5559060566555523.0]; #[cfg(feature = "radix")] const F64_POW28: [f64; 19] = [1.0, 28.0, 784.0, 21952.0, 614656.0, 17210368.0, 481890304.0, 13492928512.0, 377801998336.0, 10578455953408.0, 296196766695424.0, 8293509467471872.0, 232218265089212416.0, 6502111422497947648.0, 182059119829942534144.0, 5097655355238390956032.0, 142734349946674946768896.0, 3996561798506898509529088.0, 111903730358193158266814464.0]; #[cfg(feature = "radix")] const F64_POW29: [f64; 11] = [1.0, 29.0, 841.0, 24389.0, 707281.0, 20511149.0, 594823321.0, 17249876309.0, 500246412961.0, 14507145975869.0, 420707233300201.0]; #[cfg(feature = "radix")] const F64_POW30: [f64; 14] = [1.0, 30.0, 900.0, 27000.0, 810000.0, 24300000.0, 729000000.0, 21870000000.0, 656100000000.0, 19683000000000.0, 590490000000000.0, 17714700000000000.0, 531441000000000000.0, 15943230000000000000.0]; #[cfg(feature = "radix")] const F64_POW31: [f64; 11] = [1.0, 31.0, 961.0, 29791.0, 923521.0, 28629151.0, 887503681.0, 27512614111.0, 852891037441.0, 26439622160671.0, 819628286980801.0]; #[cfg(feature = "radix")] const F64_POW33: [f64; 11] = [1.0, 33.0, 1089.0, 35937.0, 1185921.0, 39135393.0, 1291467969.0, 42618442977.0, 1406408618241.0, 46411484401953.0, 1531578985264449.0]; #[cfg(feature = "radix")] const F64_POW34: [f64; 13] = [1.0, 34.0, 1156.0, 39304.0, 1336336.0, 45435424.0, 1544804416.0, 52523350144.0, 1785793904896.0, 60716992766464.0, 2064377754059776.0, 70188843638032384.0, 2386420683693101056.0]; #[cfg(feature = "radix")] const F64_POW35: [f64; 11] = [1.0, 35.0, 1225.0, 42875.0, 1500625.0, 52521875.0, 1838265625.0, 64339296875.0, 2251875390625.0, 78815638671875.0, 2758547353515625.0]; #[cfg(feature = "radix")] const F64_POW36: [f64; 17] = [1.0, 36.0, 1296.0, 46656.0, 1679616.0, 60466176.0, 2176782336.0, 78364164096.0, 2821109907456.0, 101559956668416.0, 3656158440062976.0, 131621703842267136.0, 4738381338321616896.0, 170581728179578208256.0, 6140942214464815497216.0, 221073919720733357899776.0, 7958661109946400884391936.0]; // Compile-time guarantees for our tables. const_assert!(F64_POW10[1] / F64_POW10[0] == 10.0); #[cfg(feature = "radix")] const_assert!(F64_POW2[1] / F64_POW2[0] == 2.0); #[cfg(feature = "radix")] const_assert!(F64_POW3[1] / F64_POW3[0] == 3.0); #[cfg(feature = "radix")] const_assert!(F64_POW5[1] / F64_POW5[0] == 5.0); #[cfg(feature = "radix")] const_assert!(F64_POW6[1] / F64_POW6[0] == 6.0); #[cfg(feature = "radix")] const_assert!(F64_POW7[1] / F64_POW7[0] == 7.0); #[cfg(feature = "radix")] const_assert!(F64_POW9[1] / F64_POW9[0] == 9.0); #[cfg(feature = "radix")] const_assert!(F64_POW11[1] / F64_POW11[0] == 11.0); #[cfg(feature = "radix")] const_assert!(F64_POW12[1] / F64_POW12[0] == 12.0); #[cfg(feature = "radix")] const_assert!(F64_POW13[1] / F64_POW13[0] == 13.0); #[cfg(feature = "radix")] const_assert!(F64_POW14[1] / F64_POW14[0] == 14.0); #[cfg(feature = "radix")] const_assert!(F64_POW15[1] / F64_POW15[0] == 15.0); #[cfg(feature = "radix")] const_assert!(F64_POW17[1] / F64_POW17[0] == 17.0); #[cfg(feature = "radix")] const_assert!(F64_POW18[1] / F64_POW18[0] == 18.0); #[cfg(feature = "radix")] const_assert!(F64_POW19[1] / F64_POW19[0] == 19.0); #[cfg(feature = "radix")] const_assert!(F64_POW20[1] / F64_POW20[0] == 20.0); #[cfg(feature = "radix")] const_assert!(F64_POW21[1] / F64_POW21[0] == 21.0); #[cfg(feature = "radix")] const_assert!(F64_POW22[1] / F64_POW22[0] == 22.0); #[cfg(feature = "radix")] const_assert!(F64_POW23[1] / F64_POW23[0] == 23.0); #[cfg(feature = "radix")] const_assert!(F64_POW24[1] / F64_POW24[0] == 24.0); #[cfg(feature = "radix")] const_assert!(F64_POW25[1] / F64_POW25[0] == 25.0); #[cfg(feature = "radix")] const_assert!(F64_POW26[1] / F64_POW26[0] == 26.0); #[cfg(feature = "radix")] const_assert!(F64_POW27[1] / F64_POW27[0] == 27.0); #[cfg(feature = "radix")] const_assert!(F64_POW28[1] / F64_POW28[0] == 28.0); #[cfg(feature = "radix")] const_assert!(F64_POW29[1] / F64_POW29[0] == 29.0); #[cfg(feature = "radix")] const_assert!(F64_POW30[1] / F64_POW30[0] == 30.0); #[cfg(feature = "radix")] const_assert!(F64_POW31[1] / F64_POW31[0] == 31.0); #[cfg(feature = "radix")] const_assert!(F64_POW33[1] / F64_POW33[0] == 33.0); #[cfg(feature = "radix")] const_assert!(F64_POW34[1] / F64_POW34[0] == 34.0); #[cfg(feature = "radix")] const_assert!(F64_POW35[1] / F64_POW35[0] == 35.0); #[cfg(feature = "radix")] const_assert!(F64_POW36[1] / F64_POW36[0] == 36.0); impl TablePower for f64 { const POW2_EXPONENT_BIAS: i32 = 1074; #[cfg(feature = "radix")] #[inline] fn table_pow2(exponent: i32) -> f64 { debug_assert!(exponent + Self::POW2_EXPONENT_BIAS >= 0, "table_pow2() have negative exponent."); F64_POW2[(exponent + Self::POW2_EXPONENT_BIAS).as_usize()] } #[inline] fn table_pow(radix: T, exponent: i32) -> f64 { debug_assert!(exponent >= 0, "table_pow() have negative exponent."); debug_assert_radix!(radix); let exponent = exponent as usize; #[cfg(not(feature = "radix"))] { F64_POW10[exponent] } #[cfg(feature = "radix")] { match radix.as_i32() { 3 => F64_POW3 [exponent], 5 => F64_POW5 [exponent], 6 => F64_POW6 [exponent], 7 => F64_POW7 [exponent], 9 => F64_POW9 [exponent], 10 => F64_POW10[exponent], 11 => F64_POW11[exponent], 12 => F64_POW12[exponent], 13 => F64_POW13[exponent], 14 => F64_POW14[exponent], 15 => F64_POW15[exponent], 17 => F64_POW17[exponent], 18 => F64_POW18[exponent], 19 => F64_POW19[exponent], 20 => F64_POW20[exponent], 21 => F64_POW21[exponent], 22 => F64_POW22[exponent], 23 => F64_POW23[exponent], 24 => F64_POW24[exponent], 25 => F64_POW25[exponent], 26 => F64_POW26[exponent], 27 => F64_POW27[exponent], 28 => F64_POW28[exponent], 29 => F64_POW29[exponent], 30 => F64_POW30[exponent], 31 => F64_POW31[exponent], 33 => F64_POW33[exponent], 34 => F64_POW34[exponent], 35 => F64_POW35[exponent], 36 => F64_POW36[exponent], // Invalid radix _ => unreachable!(), } } } } }} // cfg_if lexical-core-0.7.6/src/util/test.rs000075500000000000000000000060260000000000000152620ustar 00000000000000//! Test utilities. use super::config::BUFFER_SIZE; cfg_if! { if #[cfg(feature = "correct")] { use arrayvec; use super::sequence::{CloneableVecLike, VecLike}; }} // cfg_if // BASES /// Pow2 bases. #[cfg(all(feature = "correct", feature = "radix"))] pub(crate) const BASE_POW2: [u32; 5] = [2, 4, 8, 16, 32]; /// Non-pow2 bases. #[cfg(feature = "radix")] pub(crate) const BASE_POWN: [u32; 30] = [ 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36 ]; #[cfg(not(feature = "radix"))] pub(crate) const BASE_POWN: [u32; 1] = [10]; // BUFFER /// Create new buffer for itoa or ftoa functionality. #[inline] pub(crate) fn new_buffer() -> [u8; BUFFER_SIZE] { [b'\0'; BUFFER_SIZE] } // BYTE SLICE /// Use to help type deduction. #[inline] pub(crate) fn as_slice<'a, T>(x: &'a [T]) -> &'a [T] { x } cfg_if! { if #[cfg(feature = "correct")] { // FROM U32 #[cfg(limb_width_32)] pub(crate) type DataType = arrayvec::ArrayVec<[u32; 128]>; #[cfg(limb_width_64)] pub(crate) type DataType = arrayvec::ArrayVec<[u64; 64]>; #[cfg(limb_width_32)] pub(crate) fn from_u32(x: &[u32]) -> DataType { x.iter().cloned().collect() } #[cfg(limb_width_64)] pub(crate) fn from_u32(x: &[u32]) -> DataType { let mut v = DataType::default(); v.reserve(x.len() / 2); for xi in x.chunks(2) { match xi.len() { 1 => v.push(xi[0] as u64), 2 => v.push(((xi[1] as u64) << 32) | (xi[0] as u64)), _ => unreachable!(), } } v } #[cfg(limb_width_32)] pub(crate) fn deduce_from_u32>(x: &[u32]) -> T { from_u32(x).iter().cloned().collect() } #[cfg(limb_width_64)] pub(crate) fn deduce_from_u32>(x: &[u32]) -> T { from_u32(x).iter().cloned().collect() } }} // cfg_if // LITERAL BYTE SLICES /// Create a literal byte slice. macro_rules! b { ($l:expr) => ($l.as_bytes()); } // FLOATING-POINT EQUALITY cfg_if! { if #[cfg(feature = "correct")] { /// Assert two 32-bit floats are equal. macro_rules! assert_f32_eq { ($l:expr, $r:expr $(, $opt:ident = $val:expr)+) => (assert_eq!($l, $r);); ($l:expr, $r:expr) => (assert_eq!($l, $r);); } /// Assert two 64-bit floats are equal. macro_rules! assert_f64_eq { ($l:expr, $r:expr $(, $opt:ident = $val:expr)+) => (assert_eq!($l, $r);); ($l:expr, $r:expr) => (assert_eq!($l, $r);); } } else { /// Assert two 32-bit floats are equal. macro_rules! assert_f32_eq { ($l:expr, $r:expr $(, $opt:ident = $val:expr)+) => (approx::assert_relative_eq!($l, $r $(, $opt = $val)*);); ($l:expr, $r:expr) => (approx::assert_relative_eq!($l, $r, epsilon=1e-20);); } /// Assert two 64-bit floats are equal. macro_rules! assert_f64_eq { ($l:expr, $r:expr $(, $opt:ident = $val:expr)+) => (approx::assert_relative_eq!($l, $r $(, $opt = $val)*);); ($l:expr, $r:expr) => (approx::assert_relative_eq!($l, $r, epsilon=1e-20, max_relative=1e-12);); } }} // cfg_if lexical-core-0.7.6/src/util/traits.rs000075500000000000000000000507050000000000000156140ustar 00000000000000//! Wrap the low-level API into idiomatic serializers. use super::format::NumberFormat; use super::num::Number; use super::result::Result; // HELPERS /// Map partial result to complete result. macro_rules! to_complete { ($cb:expr, $bytes:expr $(,$args:expr)*) => { match $cb($bytes $(,$args)*) { Err(e) => Err(e), Ok((value, processed)) => if processed == $bytes.len() { Ok(value) } else{ Err((ErrorCode::InvalidDigit, processed).into()) } } }; } // FROM LEXICAL /// Trait for numerical types that can be parsed from bytes. pub trait FromLexical: Number { /// Checked parser for a string-to-number conversion. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. /// /// Returns a `Result` containing either the parsed value, /// or an error containing any errors that occurred during parsing. /// /// Numeric overflow takes precedence over the presence of an invalid /// digit, and therefore may mask an invalid digit error. /// /// * `bytes` - Slice containing a numeric string. fn from_lexical(bytes: &[u8]) -> Result; /// Checked parser for a string-to-number conversion. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. /// /// Returns a `Result` containing either the parsed value /// and the number of processed digits, or an error containing /// any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. fn from_lexical_partial(bytes: &[u8]) -> Result<(Self, usize)>; /// Checked parser for a string-to-number conversion. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. /// /// Returns a `Result` containing either the parsed value, /// or an error containing any errors that occurred during parsing. /// /// Numeric overflow takes precedence over the presence of an invalid /// digit, and therefore may mask an invalid digit error. /// /// * `bytes` - Slice containing a numeric string. /// * `radix` - Radix for the number parsing. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[cfg(feature = "radix")] fn from_lexical_radix(bytes: &[u8], radix: u8) -> Result; /// Checked parser for a string-to-number conversion. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. /// /// Returns a `Result` containing either the parsed value /// and the number of processed digits, or an error containing /// any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. /// * `radix` - Radix for the number parsing. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[cfg(feature = "radix")] fn from_lexical_partial_radix(bytes: &[u8], radix: u8) -> Result<(Self, usize)>; } // Implement FromLexical for numeric type. macro_rules! from_lexical { ($cb:expr, $t:ty) => ( impl FromLexical for $t { #[inline] fn from_lexical(bytes: &[u8]) -> Result<$t> { to_complete!($cb, bytes, 10) } #[inline] fn from_lexical_partial(bytes: &[u8]) -> Result<($t, usize)> { $cb(bytes, 10) } #[cfg(feature = "radix")] #[inline] fn from_lexical_radix(bytes: &[u8], radix: u8) -> Result<$t> { to_complete!($cb, bytes, radix.as_u32()) } #[cfg(feature = "radix")] #[inline] fn from_lexical_partial_radix(bytes: &[u8], radix: u8) -> Result<($t, usize)> { $cb(bytes, radix.as_u32()) } } ) } // FROM LEXICAL LOSSY /// Trait for floating-point types that can be parsed using lossy algorithms from bytes. pub trait FromLexicalLossy: FromLexical { /// Lossy, checked parser for a string-to-number conversion. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. This parser is /// lossy, so numerical rounding may occur during parsing. /// /// Returns a `Result` containing either the parsed value, /// or an error containing any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. fn from_lexical_lossy(bytes: &[u8]) -> Result; /// Lossy, checked parser for a string-to-number conversion. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. This parser is /// lossy, so numerical rounding may occur during parsing. /// /// Returns a `Result` containing either the parsed value /// and the number of processed digits, or an error containing /// any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. fn from_lexical_partial_lossy(bytes: &[u8]) -> Result<(Self, usize)>; /// Lossy, checked parser for a string-to-number conversion. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. This parser is /// lossy, so numerical rounding may occur during parsing. /// /// Returns a `Result` containing either the parsed value, /// or an error containing any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. /// * `radix` - Radix for the number parsing. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[cfg(feature = "radix")] fn from_lexical_lossy_radix(bytes: &[u8], radix: u8) -> Result; /// Lossy, checked parser for a string-to-number conversion. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. This parser is /// lossy, so numerical rounding may occur during parsing. /// /// Returns a `Result` containing either the parsed value /// and the number of processed digits, or an error containing /// any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. /// * `radix` - Radix for the number parsing. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[cfg(feature = "radix")] fn from_lexical_partial_lossy_radix(bytes: &[u8], radix: u8) -> Result<(Self, usize)>; } // Implement FromLexicalLossy for numeric type. macro_rules! from_lexical_lossy { ($cb:expr, $t:ty) => ( impl FromLexicalLossy for $t { #[inline] fn from_lexical_lossy(bytes: &[u8]) -> Result<$t> { to_complete!($cb, bytes, 10) } #[inline] fn from_lexical_partial_lossy(bytes: &[u8]) -> Result<($t, usize)> { $cb(bytes, 10) } #[cfg(feature = "radix")] #[inline] fn from_lexical_lossy_radix(bytes: &[u8], radix: u8) -> Result<$t> { to_complete!($cb, bytes, radix.as_u32()) } #[cfg(feature = "radix")] #[inline] fn from_lexical_partial_lossy_radix(bytes: &[u8], radix: u8) -> Result<($t, usize)> { $cb(bytes, radix.as_u32()) } } ) } // FROM LEXICAL FORMAT /// Trait for number that can be parsed using a custom format specification. #[cfg(feature = "format")] pub trait FromLexicalFormat: FromLexical { /// Checked parser for a string-to-number conversion. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. The numerical format /// is specified by the format bitflags, which customize the required /// components, digit separators, and other parameters of the number. /// /// Returns a `Result` containing either the parsed value, /// or an error containing any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. /// * `format` - Numerical format. fn from_lexical_format(bytes: &[u8], format: NumberFormat) -> Result; /// Checked parser for a string-to-number conversion. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. The numerical format /// is specified by the format bitflags, which customize the required /// components, digit separators, and other parameters of the number. /// /// Returns a `Result` containing either the parsed value /// and the number of processed digits, or an error containing /// any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. /// * `format` - Numerical format. fn from_lexical_partial_format(bytes: &[u8], format: NumberFormat) -> Result<(Self, usize)>; /// Checked parser for a string-to-number conversion. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. The numerical format /// is specified by the format bitflags, which customize the required /// components, digit separators, and other parameters of the number. /// /// Returns a `Result` containing either the parsed value, /// or an error containing any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. /// * `radix` - Radix for the number parsing. /// * `format` - Numerical format. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[cfg(feature = "radix")] fn from_lexical_format_radix(bytes: &[u8], radix: u8, format: NumberFormat) -> Result; /// Checked parser for a string-to-number conversion. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. The numerical format /// is specified by the format bitflags, which customize the required /// components, digit separators, and other parameters of the number. /// /// Returns a `Result` containing either the parsed value /// and the number of processed digits, or an error containing /// any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. /// * `radix` - Radix for the number parsing. /// * `format` - Numerical format. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[cfg(feature = "radix")] fn from_lexical_partial_format_radix(bytes: &[u8], radix: u8, format: NumberFormat) -> Result<(Self, usize)>; } // Implement FromLexicalFormat for numeric type. #[cfg(feature = "format")] macro_rules! from_lexical_format { ($cb:expr, $t:ty) => ( impl FromLexicalFormat for $t { #[inline] fn from_lexical_format(bytes: &[u8], format: NumberFormat) -> Result<$t> { to_complete!($cb, bytes, 10, format) } #[inline] fn from_lexical_partial_format(bytes: &[u8], format: NumberFormat) -> Result<($t, usize)> { $cb(bytes, 10, format) } #[cfg(feature = "radix")] #[inline] fn from_lexical_format_radix(bytes: &[u8], radix: u8, format: NumberFormat) -> Result<$t> { to_complete!($cb, bytes, radix.as_u32(), format) } #[cfg(feature = "radix")] #[inline] fn from_lexical_partial_format_radix(bytes: &[u8], radix: u8, format: NumberFormat) -> Result<($t, usize)> { $cb(bytes, radix.as_u32(), format) } } ) } // FROM LEXICAL LOSSY /// Trait for floating-point types that can be parsed using lossy algorithms with a custom format specification. #[cfg(feature = "format")] pub trait FromLexicalLossyFormat: FromLexical { /// Lossy, checked parser for a string-to-number conversion. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. This parser is /// lossy, so numerical rounding may occur during parsing. The /// numerical format is specified by the format bitflags, which /// customize the required components, digit separators, and other /// parameters of the number. /// /// Returns a `Result` containing either the parsed value, /// or an error containing any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. /// * `format` - Numerical format. fn from_lexical_lossy_format(bytes: &[u8], format: NumberFormat) -> Result; /// Lossy, checked parser for a string-to-number conversion. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. This parser is /// lossy, so numerical rounding may occur during parsing. The /// numerical format is specified by the format bitflags, which /// customize the required components, digit separators, and other /// parameters of the number. /// /// Returns a `Result` containing either the parsed value /// and the number of processed digits, or an error containing /// any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. /// * `format` - Numerical format. fn from_lexical_partial_lossy_format(bytes: &[u8], format: NumberFormat) -> Result<(Self, usize)>; /// Lossy, checked parser for a string-to-number conversion. /// /// This method parses the entire string, returning an error if /// any invalid digits are found during parsing. This parser is /// lossy, so numerical rounding may occur during parsing. The /// numerical format is specified by the format bitflags, which /// customize the required components, digit separators, and other /// parameters of the number. /// /// Returns a `Result` containing either the parsed value, /// or an error containing any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. /// * `radix` - Radix for the number parsing. /// * `format` - Numerical format. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[cfg(feature = "radix")] fn from_lexical_lossy_format_radix(bytes: &[u8], radix: u8, format: NumberFormat) -> Result; /// Lossy, checked parser for a string-to-number conversion. /// /// This method parses until an invalid digit is found (or the end /// of the string), returning the number of processed digits /// and the parsed value until that point. This parser is /// lossy, so numerical rounding may occur during parsing. The /// numerical format is specified by the format bitflags, which /// customize the required components, digit separators, and other /// parameters of the number. /// /// Returns a `Result` containing either the parsed value /// and the number of processed digits, or an error containing /// any errors that occurred during parsing. /// /// * `bytes` - Slice containing a numeric string. /// * `radix` - Radix for the number parsing. /// * `format` - Numerical format. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. #[cfg(feature = "radix")] fn from_lexical_partial_lossy_format_radix(bytes: &[u8], radix: u8, format: NumberFormat) -> Result<(Self, usize)>; } // Implement FromLexicalLossyFormat for numeric type. #[cfg(feature = "format")] macro_rules! from_lexical_lossy_format { ($cb:expr, $t:ty) => ( impl FromLexicalLossyFormat for $t { #[inline] fn from_lexical_lossy_format(bytes: &[u8], format: NumberFormat) -> Result<$t> { to_complete!($cb, bytes, 10, format) } #[inline] fn from_lexical_partial_lossy_format(bytes: &[u8], format: NumberFormat) -> Result<($t, usize)> { $cb(bytes, 10, format) } #[cfg(feature = "radix")] #[inline] fn from_lexical_lossy_format_radix(bytes: &[u8], radix: u8, format: NumberFormat) -> Result<$t> { to_complete!($cb, bytes, radix.as_u32(), format) } #[cfg(feature = "radix")] #[inline] fn from_lexical_partial_lossy_format_radix(bytes: &[u8], radix: u8, format: NumberFormat) -> Result<($t, usize)> { $cb(bytes, radix.as_u32(), format) } } ) } // TO LEXICAL /// Trait for numerical types that can be serialized to bytes. /// /// To determine the number of bytes required to serialize a value to /// string, check the associated constants from a required trait: /// - [`FORMATTED_SIZE`] /// - [`FORMATTED_SIZE_DECIMAL`] /// /// [`FORMATTED_SIZE`]: trait.Number.html#associatedconstant.FORMATTED_SIZE /// [`FORMATTED_SIZE_DECIMAL`]: trait.Number.html#associatedconstant.FORMATTED_SIZE_DECIMAL pub trait ToLexical: Number { /// Serializer for a number-to-string conversion. /// /// Returns a subslice of the input buffer containing the written bytes, /// starting from the same address in memory as the input slice. /// /// * `value` - Number to serialize. /// * `bytes` - Slice containing a numeric string. /// /// # Panics /// /// Panics if the buffer is not of sufficient size. The caller /// must provide a slice of sufficient size. In order to ensure /// the function will not panic, ensure the buffer has at least /// [`FORMATTED_SIZE_DECIMAL`] elements. /// /// [`FORMATTED_SIZE_DECIMAL`]: trait.Number.html#associatedconstant.FORMATTED_SIZE_DECIMAL fn to_lexical<'a>(self, bytes: &'a mut [u8]) -> &'a mut [u8]; /// Serializer for a number-to-string conversion. /// /// Returns a subslice of the input buffer containing the written bytes, /// starting from the same address in memory as the input slice. /// /// * `value` - Number to serialize. /// * `radix` - Radix for number encoding. /// * `bytes` - Slice containing a numeric string. /// /// # Panics /// /// Panics if the radix is not in the range `[2, 36]`. /// /// Also panics if the buffer is not of sufficient size. The caller /// must provide a slice of sufficient size. In order to ensure /// the function will not panic, ensure the buffer has at least /// [`FORMATTED_SIZE`] elements. /// /// [`FORMATTED_SIZE`]: trait.Number.html#associatedconstant.FORMATTED_SIZE #[cfg(feature = "radix")] fn to_lexical_radix<'a>(self, radix: u8, bytes: &'a mut [u8]) -> &'a mut [u8]; } // Implement ToLexical for numeric type. macro_rules! to_lexical { ($cb:expr, $t:ty) => ( impl ToLexical for $t { #[inline] fn to_lexical<'a>(self, bytes: &'a mut [u8]) -> &'a mut [u8] { assert_buffer!(10, bytes, $t); let len = $cb(self, 10, bytes); &mut index_mut!(bytes[..len]) } #[cfg(feature = "radix")] #[inline] fn to_lexical_radix<'a>(self, radix: u8, bytes: &'a mut [u8]) -> &'a mut [u8] { assert_radix!(radix); assert_buffer!(radix, bytes, $t); let len = $cb(self, radix.as_u32(), bytes); &mut index_mut!(bytes[..len]) } } ) } lexical-core-0.7.6/src/util/wrapped.rs000075500000000000000000000374670000000000000157620ustar 00000000000000//! Wrapped float that behaves like an integer. //! //! Comprehensive wrapper for the Float trait that acts like an Integer //! trait, allowed floats to be mocked as integers. //! Operations natively supported by floats are wrapped, while //! those that can be mocked (like overflow-checked operations) //! are implemented, and others (like bitshift assigns) are unimplemented. use crate::lib::{cmp, fmt, iter, ops}; use super::cast::*; use super::config::*; use super::num::*; use super::primitive::*; // WRAPPED FLOAT /// Wrap a float to act like an integer. /// /// Required for the lossy atof algorithm. #[derive(Clone, Copy, Debug, PartialOrd)] pub(crate) struct WrappedFloat { /// Internal data. data: T, } impl WrappedFloat { /// Wrap existing float. #[inline] pub fn from_float(t: T) -> Self { WrappedFloat { data: t } } /// Consume wrapper and return float. #[inline] pub fn into_inner(self) -> T { self.data } } // IMPL AS PRIMITIVE impl PartialEq for WrappedFloat { fn eq(&self, other: &Self) -> bool { // Need to return true when both are NaN, since the default // PartialEq for floats returns false when both are NaN. // We demand total ordering, do it the right way, if self.data.is_nan() && other.data.is_nan() { true } else { self.data == other.data } } } impl AsPrimitive for WrappedFloat { #[inline] fn as_u8(self) -> u8 { as_cast(self.data) } #[inline] fn as_u16(self) -> u16 { as_cast(self.data) } #[inline] fn as_u32(self) -> u32 { as_cast(self.data) } #[inline] fn as_u64(self) -> u64 { as_cast(self.data) } #[inline] fn as_u128(self) -> u128 { as_cast(self.data) } #[inline] fn as_usize(self) -> usize { as_cast(self.data) } #[inline] fn as_i8(self) -> i8 { as_cast(self.data) } #[inline] fn as_i16(self) -> i16 { as_cast(self.data) } #[inline] fn as_i32(self) -> i32 { as_cast(self.data) } #[inline] fn as_i64(self) -> i64 { as_cast(self.data) } #[inline] fn as_i128(self) -> i128 { as_cast(self.data) } #[inline] fn as_isize(self) -> isize { as_cast(self.data) } #[inline] fn as_f32(self) -> f32 { as_cast(self.data) } #[inline] fn as_f64(self) -> f64 { as_cast(self.data) } } // IMPL TRY PRIMITIVE impl TryPrimitive for WrappedFloat { #[inline] fn try_u8(self) -> Option { try_cast(self.data) } #[inline] fn try_u16(self) -> Option { try_cast(self.data) } #[inline] fn try_u32(self) -> Option { try_cast(self.data) } #[inline] fn try_u64(self) -> Option { try_cast(self.data) } #[inline] fn try_u128(self) -> Option { try_cast(self.data) } #[inline] fn try_usize(self) -> Option { try_cast(self.data) } #[inline] fn try_i8(self) -> Option { try_cast(self.data) } #[inline] fn try_i16(self) -> Option { try_cast(self.data) } #[inline] fn try_i32(self) -> Option { try_cast(self.data) } #[inline] fn try_i64(self) -> Option { try_cast(self.data) } #[inline] fn try_i128(self) -> Option { try_cast(self.data) } #[inline] fn try_isize(self) -> Option { try_cast(self.data) } #[inline] fn try_f32(self) -> Option { try_cast(self.data) } #[inline] fn try_f64(self) -> Option { try_cast(self.data) } } // IMPL AS CAST impl AsCast for WrappedFloat { #[inline] fn as_cast(n: N) -> Self { // Wrap to wide float and back down. Should be a no-op. Just indirection. WrappedFloat { data: as_cast(n.as_f64()) } } } // IMPL TRY CAST impl> TryCast for WrappedFloat { #[inline] fn try_cast(self) -> Option { try_cast(self.data) } } // IMPL PRIMITIVE impl fmt::Display for WrappedFloat { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.data, f) } } impl Primitive for WrappedFloat { } // IMPL NUMBER impl iter::Product for WrappedFloat { #[inline] fn product>>(iter: Iter) -> Self { iter.fold(Self::from_float(T::ONE), ops::Mul::mul) } } impl iter::Sum for WrappedFloat { #[inline] fn sum>>(iter: Iter) -> Self { iter.fold(Self::from_float(T::ZERO), ops::Add::add) } } /// Implement arithmetic operations. macro_rules! ops_impl { ($($t:ident, $meth:ident ;)*) => ($( impl ops::$t for WrappedFloat { type Output = Self; #[inline] fn $meth(self, other: Self) -> Self::Output { WrappedFloat { data: self.data.$meth(other.data) } } } )*); } ops_impl! { Add, add ; Div, div ; Mul, mul ; Rem, rem ; Sub, sub ; } /// Implement arithmetic assignment operations. macro_rules! ops_assign_impl { ($($t:ident, $meth:ident ;)*) => ($( impl ops::$t for WrappedFloat { #[inline] fn $meth(&mut self, other: Self) { self.data.$meth(other.data) } } )*); } ops_assign_impl! { AddAssign, add_assign ; DivAssign, div_assign ; MulAssign, mul_assign ; RemAssign, rem_assign ; SubAssign, sub_assign ; } impl Number for WrappedFloat { const FORMATTED_SIZE: usize = T::FORMATTED_SIZE; const FORMATTED_SIZE_DECIMAL: usize = T::FORMATTED_SIZE_DECIMAL; const IS_SIGNED: bool = T::IS_SIGNED; } // IMPL INTEGER impl Ord for WrappedFloat { #[inline] fn cmp(&self, other: &Self) -> cmp::Ordering { // Implements total ordering for a float, while keeping typical // behavior. All ordering is preserved, except for NaN, // such that if both are NaN, they compare equal. // PartialOrd are fails to provide an Ordering if // either are NaN, so we just need to provide consistent // ordering if either is NaN. if let Some(ordering) = self.partial_cmp(&other) { ordering } else if !self.data.is_nan() { cmp::Ordering::Less } else if other.data.is_nan() { cmp::Ordering::Equal } else { cmp::Ordering::Greater } } } impl Eq for WrappedFloat { } impl fmt::Octal for WrappedFloat { #[inline] fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { unimplemented!() } } impl fmt::LowerHex for WrappedFloat { #[inline] fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { unimplemented!() } } impl fmt::UpperHex for WrappedFloat { #[inline] fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { unimplemented!() } } /// Unimplement bitwise operations. macro_rules! bitwise_impl { ($($t:ident, $meth:ident ;)*) => ($( impl ops::$t for WrappedFloat { type Output = Self; #[inline] fn $meth(self, _: Self) -> Self::Output { unimplemented!() } } )*); } bitwise_impl! { BitAnd, bitand ; BitOr, bitor ; BitXor, bitxor ; } /// Unimplement bitwise assignment operations. macro_rules! bitwise_assign_impl { ($($t:ident, $meth:ident ;)*) => ($( impl ops::$t for WrappedFloat { #[inline] fn $meth(&mut self, _: Self) { unimplemented!() } } )*); } bitwise_assign_impl! { BitAndAssign, bitand_assign ; BitOrAssign, bitor_assign ; BitXorAssign, bitxor_assign ; } impl ops::Not for WrappedFloat { type Output = Self; #[inline] fn not(self) -> Self::Output { unimplemented!() } } /// Unimplement bitshift operations. macro_rules! bitshift_impl { ($t:tt, $meth:ident ; $($s:ty)*) => ($( // Iterate over all primitives. impl ops::$t<$s> for WrappedFloat { type Output = Self; #[inline] fn $meth(self, _: $s) -> Self::Output { unimplemented!() } } )*); ($($t:ident, $meth:ident ;)*) => ($( // Base case, same as self. impl ops::$t<> for WrappedFloat { type Output = Self; #[inline] fn $meth(self, _: Self) -> Self::Output { unimplemented!() } } bitshift_impl!($t, $meth ; u8 u16 u32 u64 usize i8 i16 i32 i64 isize); )*); } bitshift_impl! { Shl, shl ; Shr, shr ; } /// Unimplement bitshift assignment operations. macro_rules! bitshift_assign_impl { ($t:tt, $meth:ident ; $($s:ty)*) => ($( // Iterate over all primitives. impl ops::$t<$s> for WrappedFloat { #[inline] fn $meth(&mut self, _: $s) { unimplemented!() } } )*); ($($t:ident, $meth:ident ;)*) => ($( // Base case, same as self. impl ops::$t<> for WrappedFloat { #[inline] fn $meth(&mut self, _: Self) { unimplemented!() } } bitshift_assign_impl!($t, $meth ; u8 u16 u32 u64 usize i8 i16 i32 i64 isize); )*); } bitshift_assign_impl! { ShlAssign, shl_assign ; ShrAssign, shr_assign ; } impl Integer for WrappedFloat { const ZERO: Self = WrappedFloat { data: T::ZERO }; const ONE: Self = WrappedFloat { data: T::ONE }; const TWO: Self = WrappedFloat { data: T::TWO }; const MAX: Self = WrappedFloat { data: T::MAX }; const MIN: Self = WrappedFloat { data: T::MIN }; const BITS: usize = T::BITS; #[inline] fn max_value() -> Self { Self::MAX } #[inline] fn min_value() -> Self { Self::MIN } #[inline] fn count_ones(self) -> u32 { unreachable!() } #[inline] fn count_zeros(self) -> u32 { unreachable!() } #[inline] fn leading_zeros(self) -> u32 { unreachable!() } #[inline] fn trailing_zeros(self) -> u32 { unreachable!() } #[inline] fn pow(self, _: u32) -> Self { unreachable!() } #[inline] fn checked_add(self, i: Self) -> Option { Some(self + i) } #[inline] fn checked_sub(self, i: Self) -> Option { Some(self - i) } #[inline] fn checked_mul(self, i: Self) -> Option { Some(self * i) } #[inline] fn checked_div(self, i: Self) -> Option { Some(self / i) } #[inline] fn checked_rem(self, i: Self) -> Option { Some(self % i) } #[inline] fn checked_neg(self) -> Option { Some(-self) } #[inline] fn checked_shl(self, _: u32) -> Option { unimplemented!() } #[inline] fn checked_shr(self, _: u32) -> Option { unimplemented!() } #[inline] fn wrapping_add(self, i: Self) -> Self { self + i } #[inline] fn wrapping_sub(self, i: Self) -> Self { self - i } #[inline] fn wrapping_mul(self, i: Self) -> Self { self * i } #[inline] fn wrapping_div(self, i: Self) -> Self { self / i } #[inline] fn wrapping_rem(self, i: Self) -> Self { self % i } #[inline] fn wrapping_neg(self) -> Self { -self } #[inline] fn wrapping_shl(self, _: u32) -> Self { unimplemented!() } #[inline] fn wrapping_shr(self, _: u32) -> Self { unimplemented!() } #[inline] fn overflowing_add(self, i: Self) -> (Self, bool) { (self + i, false) } #[inline] fn overflowing_sub(self, i: Self) -> (Self, bool) { (self - i, false) } #[inline] fn overflowing_mul(self, i: Self) -> (Self, bool) { (self * i, false) } #[inline] fn overflowing_div(self, i: Self) -> (Self, bool) { (self / i, false) } #[inline] fn overflowing_rem(self, i: Self) -> (Self, bool) { (self % i, false) } #[inline] fn overflowing_neg(self) -> (Self, bool) { (-self, false) } #[inline] fn overflowing_shl(self, _: u32) -> (Self, bool) { unimplemented!() } #[inline] fn overflowing_shr(self, _: u32) -> (Self, bool) { unimplemented!() } #[inline] fn saturating_add(self, i: Self) -> Self { self + i } #[inline] fn saturating_sub(self, i: Self) -> Self { self - i } #[inline] fn saturating_mul(self, i: Self) -> Self { self * i } } // SIGNED INTEGER impl ops::Neg for WrappedFloat { type Output = Self; #[inline] fn neg(self) -> Self { WrappedFloat { data: -self.data } } } impl SignedInteger for WrappedFloat { fn checked_abs(self) -> Option { Some(self.wrapping_abs()) } fn wrapping_abs(self) -> Self { WrappedFloat { data: self.data.abs() } } fn overflowing_abs(self) -> (Self, bool) { (self.wrapping_abs(), false) } } // TEST // ---- #[cfg(test)] mod tests { use super::*; fn check_integer(mut x: T) { // Copy, partialeq, partialord, ord, eq let _ = x; assert!(x > T::ONE); assert!(x != T::ONE); assert_eq!(x.min(T::ONE), T::ONE); assert_eq!(x.max(T::ONE), x); // Operations let _ = x + T::ONE; let _ = x - T::ONE; let _ = x * T::ONE; let _ = x / T::ONE; let _ = x % T::ONE; x += T::ONE; x -= T::ONE; x *= T::ONE; x /= T::ONE; x %= T::ONE; // Functions assert!(T::ZERO.is_zero()); assert!(!T::ONE.is_zero()); assert!(T::ONE.is_one()); assert!(!T::ZERO.is_one()); // As cast let _: u8 = as_cast(x); let _: u16 = as_cast(x); let _: u32 = as_cast(x); let _: u64 = as_cast(x); let _: u128 = as_cast(x); let _: usize = as_cast(x); let _: i8 = as_cast(x); let _: i16 = as_cast(x); let _: i32 = as_cast(x); let _: i64 = as_cast(x); let _: i128 = as_cast(x); let _: isize = as_cast(x); let _: f32 = as_cast(x); let _: f64 = as_cast(x); } fn check_try_cast_compile(x: T) { // Try cast let _: Option = try_cast(x); let _: Option = try_cast(x); let _: Option = try_cast(x); let _: Option = try_cast(x); let _: Option = try_cast(x); let _: Option = try_cast(x); let _: Option = try_cast(x); let _: Option = try_cast(x); let _: Option = try_cast(x); let _: Option = try_cast(x); let _: Option = try_cast(x); let _: Option = try_cast(x); let _: Option = try_cast(x); let _: Option = try_cast(x); } #[allow(dead_code)] // Compile-only fn try_cast_test() { check_try_cast_compile(WrappedFloat::from_float(65f32)); check_try_cast_compile(WrappedFloat::from_float(65f64)); } #[test] fn integer_test() { check_integer(WrappedFloat::from_float(65f32)); check_integer(WrappedFloat::from_float(65f64)); } }