koffi 2.3.6-beta.6 → 2.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/package.json +2 -2
- package/src/cnoke/cnoke.js +3 -7
- package/src/cnoke/src/builder.js +9 -6
- package/src/cnoke/src/index.js +2 -2
- package/src/koffi/build/2.3.7/koffi_darwin_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_darwin_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_freebsd_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_freebsd_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_freebsd_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_linux_arm32hf/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_linux_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_linux_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_linux_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_openbsd_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_openbsd_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_win32_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_win32_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.7/koffi_win32_x64/koffi.node +0 -0
- package/src/koffi/src/ffi.cc +2 -2
- package/src/koffi/src/index.d.ts +2 -2
- package/src/koffi/src/index.js +1 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_darwin_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_darwin_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_freebsd_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_freebsd_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_freebsd_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_linux_arm32hf/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_linux_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_linux_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_linux_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_openbsd_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_openbsd_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_win32_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_win32_arm64/koffi.pdb +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_win32_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_win32_ia32/koffi.pdb +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_win32_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.6/koffi_win32_x64/koffi.pdb +0 -0
- package/vendor/brotli/BUILD +0 -144
- package/vendor/brotli/CMakeLists.txt +0 -421
- package/vendor/brotli/CONTRIBUTING.md +0 -27
- package/vendor/brotli/LICENSE +0 -19
- package/vendor/brotli/MANIFEST.in +0 -17
- package/vendor/brotli/Makefile +0 -55
- package/vendor/brotli/Makefile.am +0 -38
- package/vendor/brotli/README +0 -15
- package/vendor/brotli/README.md +0 -104
- package/vendor/brotli/WORKSPACE +0 -21
- package/vendor/brotli/bootstrap +0 -35
- package/vendor/brotli/c/common/constants.c +0 -15
- package/vendor/brotli/c/common/constants.h +0 -200
- package/vendor/brotli/c/common/context.c +0 -156
- package/vendor/brotli/c/common/context.h +0 -113
- package/vendor/brotli/c/common/dictionary.c +0 -5914
- package/vendor/brotli/c/common/dictionary.h +0 -64
- package/vendor/brotli/c/common/platform.c +0 -22
- package/vendor/brotli/c/common/platform.h +0 -596
- package/vendor/brotli/c/common/transform.c +0 -291
- package/vendor/brotli/c/common/transform.h +0 -85
- package/vendor/brotli/c/common/version.h +0 -26
- package/vendor/brotli/c/dec/bit_reader.c +0 -76
- package/vendor/brotli/c/dec/bit_reader.h +0 -351
- package/vendor/brotli/c/dec/decode.c +0 -2608
- package/vendor/brotli/c/dec/huffman.c +0 -339
- package/vendor/brotli/c/dec/huffman.h +0 -121
- package/vendor/brotli/c/dec/prefix.h +0 -732
- package/vendor/brotli/c/dec/state.c +0 -159
- package/vendor/brotli/c/dec/state.h +0 -365
- package/vendor/brotli/c/enc/backward_references.c +0 -145
- package/vendor/brotli/c/enc/backward_references.h +0 -39
- package/vendor/brotli/c/enc/backward_references_hq.c +0 -843
- package/vendor/brotli/c/enc/backward_references_hq.h +0 -95
- package/vendor/brotli/c/enc/backward_references_inc.h +0 -163
- package/vendor/brotli/c/enc/bit_cost.c +0 -35
- package/vendor/brotli/c/enc/bit_cost.h +0 -63
- package/vendor/brotli/c/enc/bit_cost_inc.h +0 -127
- package/vendor/brotli/c/enc/block_encoder_inc.h +0 -34
- package/vendor/brotli/c/enc/block_splitter.c +0 -194
- package/vendor/brotli/c/enc/block_splitter.h +0 -51
- package/vendor/brotli/c/enc/block_splitter_inc.h +0 -440
- package/vendor/brotli/c/enc/brotli_bit_stream.c +0 -1314
- package/vendor/brotli/c/enc/brotli_bit_stream.h +0 -84
- package/vendor/brotli/c/enc/cluster.c +0 -56
- package/vendor/brotli/c/enc/cluster.h +0 -48
- package/vendor/brotli/c/enc/cluster_inc.h +0 -320
- package/vendor/brotli/c/enc/command.c +0 -28
- package/vendor/brotli/c/enc/command.h +0 -190
- package/vendor/brotli/c/enc/compress_fragment.c +0 -790
- package/vendor/brotli/c/enc/compress_fragment.h +0 -61
- package/vendor/brotli/c/enc/compress_fragment_two_pass.c +0 -645
- package/vendor/brotli/c/enc/compress_fragment_two_pass.h +0 -54
- package/vendor/brotli/c/enc/dictionary_hash.c +0 -1846
- package/vendor/brotli/c/enc/dictionary_hash.h +0 -25
- package/vendor/brotli/c/enc/encode.c +0 -1927
- package/vendor/brotli/c/enc/encoder_dict.c +0 -33
- package/vendor/brotli/c/enc/encoder_dict.h +0 -43
- package/vendor/brotli/c/enc/entropy_encode.c +0 -503
- package/vendor/brotli/c/enc/entropy_encode.h +0 -122
- package/vendor/brotli/c/enc/entropy_encode_static.h +0 -539
- package/vendor/brotli/c/enc/fast_log.c +0 -105
- package/vendor/brotli/c/enc/fast_log.h +0 -66
- package/vendor/brotli/c/enc/find_match_length.h +0 -79
- package/vendor/brotli/c/enc/hash.h +0 -488
- package/vendor/brotli/c/enc/hash_composite_inc.h +0 -125
- package/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +0 -293
- package/vendor/brotli/c/enc/hash_longest_match64_inc.h +0 -267
- package/vendor/brotli/c/enc/hash_longest_match_inc.h +0 -262
- package/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +0 -266
- package/vendor/brotli/c/enc/hash_rolling_inc.h +0 -212
- package/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +0 -329
- package/vendor/brotli/c/enc/histogram.c +0 -100
- package/vendor/brotli/c/enc/histogram.h +0 -63
- package/vendor/brotli/c/enc/histogram_inc.h +0 -51
- package/vendor/brotli/c/enc/literal_cost.c +0 -175
- package/vendor/brotli/c/enc/literal_cost.h +0 -30
- package/vendor/brotli/c/enc/memory.c +0 -170
- package/vendor/brotli/c/enc/memory.h +0 -114
- package/vendor/brotli/c/enc/metablock.c +0 -663
- package/vendor/brotli/c/enc/metablock.h +0 -105
- package/vendor/brotli/c/enc/metablock_inc.h +0 -183
- package/vendor/brotli/c/enc/params.h +0 -46
- package/vendor/brotli/c/enc/prefix.h +0 -53
- package/vendor/brotli/c/enc/quality.h +0 -165
- package/vendor/brotli/c/enc/ringbuffer.h +0 -167
- package/vendor/brotli/c/enc/static_dict.c +0 -486
- package/vendor/brotli/c/enc/static_dict.h +0 -40
- package/vendor/brotli/c/enc/static_dict_lut.h +0 -5864
- package/vendor/brotli/c/enc/utf8_util.c +0 -85
- package/vendor/brotli/c/enc/utf8_util.h +0 -32
- package/vendor/brotli/c/enc/write_bits.h +0 -87
- package/vendor/brotli/c/include/brotli/decode.h +0 -344
- package/vendor/brotli/c/include/brotli/encode.h +0 -448
- package/vendor/brotli/c/include/brotli/port.h +0 -288
- package/vendor/brotli/c/include/brotli/types.h +0 -83
- package/vendor/brotli/c/tools/brotli.c +0 -1116
- package/vendor/brotli/c/tools/brotli.md +0 -107
- package/vendor/brotli/compiler_config_setting.bzl +0 -28
- package/vendor/brotli/configure +0 -8
- package/vendor/brotli/configure-cmake +0 -318
- package/vendor/brotli/configure.ac +0 -14
- package/vendor/brotli/docs/brotli.1 +0 -132
- package/vendor/brotli/docs/constants.h.3 +0 -47
- package/vendor/brotli/docs/decode.h.3 +0 -415
- package/vendor/brotli/docs/encode.h.3 +0 -586
- package/vendor/brotli/docs/types.h.3 +0 -117
- package/vendor/brotli/premake5.lua +0 -78
- package/vendor/brotli/python/Makefile +0 -57
- package/vendor/brotli/python/README.md +0 -54
- package/vendor/brotli/python/_brotli.cc +0 -753
- package/vendor/brotli/python/bro.py +0 -160
- package/vendor/brotli/python/brotli.py +0 -56
- package/vendor/brotli/python/tests/__init__.py +0 -0
- package/vendor/brotli/python/tests/_test_utils.py +0 -112
- package/vendor/brotli/python/tests/bro_test.py +0 -102
- package/vendor/brotli/python/tests/compress_test.py +0 -41
- package/vendor/brotli/python/tests/compressor_test.py +0 -94
- package/vendor/brotli/python/tests/decompress_test.py +0 -42
- package/vendor/brotli/python/tests/decompressor_test.py +0 -59
- package/vendor/brotli/scripts/libbrotlicommon.pc.in +0 -11
- package/vendor/brotli/scripts/libbrotlidec.pc.in +0 -12
- package/vendor/brotli/scripts/libbrotlienc.pc.in +0 -12
- package/vendor/brotli/scripts/sources.lst +0 -104
- package/vendor/brotli/setup.cfg +0 -5
- package/vendor/brotli/setup.py +0 -293
- package/vendor/brotli/tests/Makefile +0 -17
- package/vendor/brotli/tests/compatibility_test.sh +0 -25
- package/vendor/brotli/tests/roundtrip_test.sh +0 -36
- package/vendor/brotli/tests/run-compatibility-test.cmake +0 -31
- package/vendor/brotli/tests/run-roundtrip-test.cmake +0 -36
- package/vendor/brotli/tests/testdata/empty +0 -0
- package/vendor/brotli/tests/testdata/empty.compressed +0 -1
- package/vendor/brotli/tests/testdata/ukkonooa +0 -1
- package/vendor/brotli/tests/testdata/ukkonooa.compressed +0 -0
- package/vendor/dragonbox/CMakeLists.txt +0 -123
- package/vendor/dragonbox/LICENSE-Apache2-LLVM +0 -218
- package/vendor/dragonbox/LICENSE-Boost +0 -23
- package/vendor/dragonbox/README.md +0 -277
- package/vendor/dragonbox/cmake/dragonboxConfig.cmake +0 -1
- package/vendor/dragonbox/include/dragonbox/dragonbox.h +0 -2674
- package/vendor/dragonbox/include/dragonbox/dragonbox_to_chars.h +0 -108
- package/vendor/dragonbox/other_files/Dragonbox.pdf +0 -0
- package/vendor/dragonbox/other_files/Dragonbox_old.pdf +0 -0
- package/vendor/dragonbox/other_files/milo_benchmark.png +0 -0
- package/vendor/dragonbox/other_files/unknown_win64_vc2019.html +0 -540
- package/vendor/dragonbox/other_files/unknown_win64_vc2019_randomdigit_time.png +0 -0
- package/vendor/dragonbox/source/dragonbox_to_chars.cpp +0 -303
- package/vendor/dragonbox/subproject/3rdparty/grisu_exact/CMakeLists.txt +0 -24
- package/vendor/dragonbox/subproject/3rdparty/grisu_exact/fp_to_chars.cpp +0 -238
- package/vendor/dragonbox/subproject/3rdparty/grisu_exact/fp_to_chars.h +0 -95
- package/vendor/dragonbox/subproject/3rdparty/grisu_exact/grisu_exact.h +0 -2666
- package/vendor/dragonbox/subproject/3rdparty/ryu/CMakeLists.txt +0 -16
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/common.h +0 -114
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/d2s.c +0 -509
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/d2s_full_table.h +0 -367
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/d2s_intrinsics.h +0 -357
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/digit_table.h +0 -35
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/f2s.c +0 -345
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/f2s_full_table.h +0 -55
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/f2s_intrinsics.h +0 -128
- package/vendor/dragonbox/subproject/3rdparty/ryu/ryu/ryu.h +0 -46
- package/vendor/dragonbox/subproject/3rdparty/schubfach/CMakeLists.txt +0 -22
- package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_32.cc +0 -699
- package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_32.h +0 -31
- package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_64.cc +0 -1354
- package/vendor/dragonbox/subproject/3rdparty/schubfach/schubfach_64.h +0 -31
- package/vendor/dragonbox/subproject/3rdparty/shaded_plots/example_shaded_plots.m +0 -68
- package/vendor/dragonbox/subproject/3rdparty/shaded_plots/license.txt +0 -25
- package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_distribution.m +0 -92
- package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_distribution_prctile.m +0 -121
- package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_histogram_shaded.m +0 -99
- package/vendor/dragonbox/subproject/3rdparty/shaded_plots/plot_shaded.m +0 -93
- package/vendor/dragonbox/subproject/benchmark/CMakeLists.txt +0 -65
- package/vendor/dragonbox/subproject/benchmark/include/benchmark.h +0 -40
- package/vendor/dragonbox/subproject/benchmark/matlab/plot_benchmarks.m +0 -22
- package/vendor/dragonbox/subproject/benchmark/matlab/plot_digit_benchmark.m +0 -78
- package/vendor/dragonbox/subproject/benchmark/matlab/plot_uniform_benchmark.m +0 -95
- package/vendor/dragonbox/subproject/benchmark/results/digits_benchmark_binary32_clang.png +0 -0
- package/vendor/dragonbox/subproject/benchmark/results/digits_benchmark_binary32_msvc.png +0 -0
- package/vendor/dragonbox/subproject/benchmark/results/digits_benchmark_binary64_clang.png +0 -0
- package/vendor/dragonbox/subproject/benchmark/results/digits_benchmark_binary64_msvc.png +0 -0
- package/vendor/dragonbox/subproject/benchmark/results/uniform_benchmark_binary32_clang.png +0 -0
- package/vendor/dragonbox/subproject/benchmark/results/uniform_benchmark_binary32_msvc.png +0 -0
- package/vendor/dragonbox/subproject/benchmark/results/uniform_benchmark_binary64_clang.png +0 -0
- package/vendor/dragonbox/subproject/benchmark/results/uniform_benchmark_binary64_msvc.png +0 -0
- package/vendor/dragonbox/subproject/benchmark/source/benchmark.cpp +0 -238
- package/vendor/dragonbox/subproject/benchmark/source/dragonbox.cpp +0 -30
- package/vendor/dragonbox/subproject/benchmark/source/grisu_exact.cpp +0 -36
- package/vendor/dragonbox/subproject/benchmark/source/ryu.cpp +0 -27
- package/vendor/dragonbox/subproject/benchmark/source/schubfach.cpp +0 -31
- package/vendor/dragonbox/subproject/common/CMakeLists.txt +0 -42
- package/vendor/dragonbox/subproject/common/include/best_rational_approx.h +0 -97
- package/vendor/dragonbox/subproject/common/include/big_uint.h +0 -218
- package/vendor/dragonbox/subproject/common/include/continued_fractions.h +0 -174
- package/vendor/dragonbox/subproject/common/include/good_rational_approx.h +0 -267
- package/vendor/dragonbox/subproject/common/include/random_float.h +0 -182
- package/vendor/dragonbox/subproject/common/include/rational_continued_fractions.h +0 -57
- package/vendor/dragonbox/subproject/common/source/big_uint.cpp +0 -602
- package/vendor/dragonbox/subproject/meta/CMakeLists.txt +0 -41
- package/vendor/dragonbox/subproject/meta/results/binary32_generated_cache.txt +0 -82
- package/vendor/dragonbox/subproject/meta/results/binary64_compressed_cache_error_table.txt +0 -10
- package/vendor/dragonbox/subproject/meta/results/binary64_generated_cache.txt +0 -623
- package/vendor/dragonbox/subproject/meta/source/generate_cache.cpp +0 -126
- package/vendor/dragonbox/subproject/meta/source/live_test.cpp +0 -81
- package/vendor/dragonbox/subproject/meta/source/perf_test.cpp +0 -104
- package/vendor/dragonbox/subproject/meta/source/sandbox.cpp +0 -20
- package/vendor/dragonbox/subproject/test/CMakeLists.txt +0 -70
- package/vendor/dragonbox/subproject/test/results/binary32.csv +0 -255
- package/vendor/dragonbox/subproject/test/results/binary64.csv +0 -2047
- package/vendor/dragonbox/subproject/test/results/plot_required_bits.m +0 -18
- package/vendor/dragonbox/subproject/test/source/test_all_shorter_interval_cases.cpp +0 -88
- package/vendor/dragonbox/subproject/test/source/uniform_random_test.cpp +0 -95
- package/vendor/dragonbox/subproject/test/source/verify_cache_precision.cpp +0 -338
- package/vendor/dragonbox/subproject/test/source/verify_compressed_cache.cpp +0 -154
- package/vendor/dragonbox/subproject/test/source/verify_fast_multiplication.cpp +0 -168
- package/vendor/dragonbox/subproject/test/source/verify_log_computation.cpp +0 -251
- package/vendor/dragonbox/subproject/test/source/verify_magic_division.cpp +0 -113
- package/vendor/miniz/ChangeLog.md +0 -239
- package/vendor/miniz/LICENSE +0 -22
- package/vendor/miniz/examples/example1.c +0 -105
- package/vendor/miniz/examples/example2.c +0 -164
- package/vendor/miniz/examples/example3.c +0 -269
- package/vendor/miniz/examples/example4.c +0 -102
- package/vendor/miniz/examples/example5.c +0 -327
- package/vendor/miniz/examples/example6.c +0 -166
- package/vendor/miniz/miniz.c +0 -7835
- package/vendor/miniz/miniz.h +0 -1422
- package/vendor/miniz/readme.md +0 -46
- /package/src/koffi/build/{2.3.6-beta.6 → 2.3.7}/koffi_win32_arm64/koffi.exp +0 -0
- /package/src/koffi/build/{2.3.6-beta.6 → 2.3.7}/koffi_win32_arm64/koffi.lib +0 -0
- /package/src/koffi/build/{2.3.6-beta.6 → 2.3.7}/koffi_win32_ia32/koffi.exp +0 -0
- /package/src/koffi/build/{2.3.6-beta.6 → 2.3.7}/koffi_win32_ia32/koffi.lib +0 -0
- /package/src/koffi/build/{2.3.6-beta.6 → 2.3.7}/koffi_win32_x64/koffi.exp +0 -0
- /package/src/koffi/build/{2.3.6-beta.6 → 2.3.7}/koffi_win32_x64/koffi.lib +0 -0
|
@@ -1,2674 +0,0 @@
|
|
|
1
|
-
// Copyright 2020-2022 Junekey Jeon
|
|
2
|
-
//
|
|
3
|
-
// The contents of this file may be used under the terms of
|
|
4
|
-
// the Apache License v2.0 with LLVM Exceptions.
|
|
5
|
-
//
|
|
6
|
-
// (See accompanying file LICENSE-Apache or copy at
|
|
7
|
-
// https://llvm.org/foundation/relicensing/LICENSE.txt)
|
|
8
|
-
//
|
|
9
|
-
// Alternatively, the contents of this file may be used under the terms of
|
|
10
|
-
// the Boost Software License, Version 1.0.
|
|
11
|
-
// (See accompanying file LICENSE-Boost or copy at
|
|
12
|
-
// https://www.boost.org/LICENSE_1_0.txt)
|
|
13
|
-
//
|
|
14
|
-
// Unless required by applicable law or agreed to in writing, this software
|
|
15
|
-
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
16
|
-
// KIND, either express or implied.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
#ifndef JKJ_HEADER_DRAGONBOX
|
|
20
|
-
#define JKJ_HEADER_DRAGONBOX
|
|
21
|
-
|
|
22
|
-
#include <cassert>
|
|
23
|
-
#include <cstdint>
|
|
24
|
-
#include <cstring>
|
|
25
|
-
#include <limits>
|
|
26
|
-
#include <type_traits>
|
|
27
|
-
|
|
28
|
-
// Suppress additional buffer overrun check.
|
|
29
|
-
// I have no idea why MSVC thinks some functions here are vulnerable to the buffer overrun
|
|
30
|
-
// attacks. No, they aren't.
|
|
31
|
-
#if defined(__GNUC__) || defined(__clang__)
|
|
32
|
-
#define JKJ_SAFEBUFFERS
|
|
33
|
-
#define JKJ_FORCEINLINE inline __attribute__((always_inline))
|
|
34
|
-
#elif defined(_MSC_VER)
|
|
35
|
-
#define JKJ_SAFEBUFFERS __declspec(safebuffers)
|
|
36
|
-
#define JKJ_FORCEINLINE __forceinline
|
|
37
|
-
#else
|
|
38
|
-
#define JKJ_SAFEBUFFERS
|
|
39
|
-
#define JKJ_FORCEINLINE inline
|
|
40
|
-
#endif
|
|
41
|
-
|
|
42
|
-
#if defined(__has_builtin)
|
|
43
|
-
#define JKJ_DRAGONBOX_HAS_BUILTIN(x) __has_builtin(x)
|
|
44
|
-
#else
|
|
45
|
-
#define JKJ_DRAGONBOX_HAS_BUILTIN(x) false
|
|
46
|
-
#endif
|
|
47
|
-
|
|
48
|
-
#if defined(_MSC_VER)
|
|
49
|
-
#include <intrin.h>
|
|
50
|
-
#endif
|
|
51
|
-
|
|
52
|
-
namespace jkj::dragonbox {
|
|
53
|
-
namespace detail {
|
|
54
|
-
template <class T>
|
|
55
|
-
constexpr std::size_t
|
|
56
|
-
physical_bits = sizeof(T) * std::numeric_limits<unsigned char>::digits;
|
|
57
|
-
|
|
58
|
-
template <class T>
|
|
59
|
-
constexpr std::size_t value_bits =
|
|
60
|
-
std::numeric_limits<std::enable_if_t<std::is_unsigned_v<T>, T>>::digits;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// These classes expose encoding specs of IEEE-754-like floating-point formats.
|
|
64
|
-
// Currently available formats are IEEE754-binary32 & IEEE754-binary64.
|
|
65
|
-
|
|
66
|
-
struct ieee754_binary32 {
|
|
67
|
-
static constexpr int significand_bits = 23;
|
|
68
|
-
static constexpr int exponent_bits = 8;
|
|
69
|
-
static constexpr int min_exponent = -126;
|
|
70
|
-
static constexpr int max_exponent = 127;
|
|
71
|
-
static constexpr int exponent_bias = -127;
|
|
72
|
-
static constexpr int decimal_digits = 9;
|
|
73
|
-
};
|
|
74
|
-
struct ieee754_binary64 {
|
|
75
|
-
static constexpr int significand_bits = 52;
|
|
76
|
-
static constexpr int exponent_bits = 11;
|
|
77
|
-
static constexpr int min_exponent = -1022;
|
|
78
|
-
static constexpr int max_exponent = 1023;
|
|
79
|
-
static constexpr int exponent_bias = -1023;
|
|
80
|
-
static constexpr int decimal_digits = 17;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// A floating-point traits class defines ways to interpret a bit pattern of given size as an
|
|
84
|
-
// encoding of floating-point number. This is a default implementation of such a traits class,
|
|
85
|
-
// supporting ways to interpret 32-bits into a binary32-encoded floating-point number and to
|
|
86
|
-
// interpret 64-bits into a binary64-encoded floating-point number. Users might specialize this
|
|
87
|
-
// class to change the default behavior for certain types.
|
|
88
|
-
template <class T>
|
|
89
|
-
struct default_float_traits {
|
|
90
|
-
// I don't know if there is a truly reliable way of detecting
|
|
91
|
-
// IEEE-754 binary32/binary64 formats; I just did my best here.
|
|
92
|
-
static_assert(std::numeric_limits<T>::is_iec559 && std::numeric_limits<T>::radix == 2 &&
|
|
93
|
-
(detail::physical_bits<T> == 32 || detail::physical_bits<T> == 64),
|
|
94
|
-
"default_ieee754_traits only works for 32-bits or 64-bits types "
|
|
95
|
-
"supporting binary32 or binary64 formats!");
|
|
96
|
-
|
|
97
|
-
// The type that is being viewed.
|
|
98
|
-
using type = T;
|
|
99
|
-
|
|
100
|
-
// Refers to the format specification class.
|
|
101
|
-
using format =
|
|
102
|
-
std::conditional_t<detail::physical_bits<T> == 32, ieee754_binary32, ieee754_binary64>;
|
|
103
|
-
|
|
104
|
-
// Defines an unsigned integer type that is large enough to carry a variable of type T.
|
|
105
|
-
// Most of the operations will be done on this integer type.
|
|
106
|
-
using carrier_uint =
|
|
107
|
-
std::conditional_t<detail::physical_bits<T> == 32, std::uint32_t, std::uint64_t>;
|
|
108
|
-
static_assert(sizeof(carrier_uint) == sizeof(T));
|
|
109
|
-
|
|
110
|
-
// Number of bits in the above unsigned integer type.
|
|
111
|
-
static constexpr int carrier_bits = int(detail::physical_bits<carrier_uint>);
|
|
112
|
-
|
|
113
|
-
// Convert from carrier_uint into the original type.
|
|
114
|
-
// Depending on the floating-point encoding format, this operation might not be possible for
|
|
115
|
-
// some specific bit patterns. However, the contract is that u always denotes a
|
|
116
|
-
// valid bit pattern, so this function must be assumed to be noexcept.
|
|
117
|
-
static T carrier_to_float(carrier_uint u) noexcept {
|
|
118
|
-
T x;
|
|
119
|
-
std::memcpy(&x, &u, sizeof(carrier_uint));
|
|
120
|
-
return x;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Same as above.
|
|
124
|
-
static carrier_uint float_to_carrier(T x) noexcept {
|
|
125
|
-
carrier_uint u;
|
|
126
|
-
std::memcpy(&u, &x, sizeof(carrier_uint));
|
|
127
|
-
return u;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Extract exponent bits from a bit pattern.
|
|
131
|
-
// The result must be aligned to the LSB so that there is no additional zero paddings
|
|
132
|
-
// on the right. This function does not do bias adjustment.
|
|
133
|
-
static constexpr unsigned int extract_exponent_bits(carrier_uint u) noexcept {
|
|
134
|
-
constexpr int significand_bits = format::significand_bits;
|
|
135
|
-
constexpr int exponent_bits = format::exponent_bits;
|
|
136
|
-
static_assert(detail::value_bits<unsigned int> > exponent_bits);
|
|
137
|
-
constexpr auto exponent_bits_mask =
|
|
138
|
-
(unsigned int)(((unsigned int)(1) << exponent_bits) - 1);
|
|
139
|
-
return (unsigned int)(u >> significand_bits) & exponent_bits_mask;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Extract significand bits from a bit pattern.
|
|
143
|
-
// The result must be aligned to the LSB so that there is no additional zero paddings
|
|
144
|
-
// on the right. The result does not contain the implicit bit.
|
|
145
|
-
static constexpr carrier_uint extract_significand_bits(carrier_uint u) noexcept {
|
|
146
|
-
constexpr auto mask = carrier_uint((carrier_uint(1) << format::significand_bits) - 1);
|
|
147
|
-
return carrier_uint(u & mask);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Remove the exponent bits and extract significand bits together with the sign bit.
|
|
151
|
-
static constexpr carrier_uint remove_exponent_bits(carrier_uint u,
|
|
152
|
-
unsigned int exponent_bits) noexcept {
|
|
153
|
-
return u ^ (carrier_uint(exponent_bits) << format::significand_bits);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Shift the obtained signed significand bits to the left by 1 to remove the sign bit.
|
|
157
|
-
static constexpr carrier_uint remove_sign_bit_and_shift(carrier_uint u) noexcept {
|
|
158
|
-
return carrier_uint(carrier_uint(u) << 1);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// The actual value of exponent is obtained by adding this value to the extracted exponent
|
|
162
|
-
// bits.
|
|
163
|
-
static constexpr int exponent_bias =
|
|
164
|
-
1 - (1 << (carrier_bits - format::significand_bits - 2));
|
|
165
|
-
|
|
166
|
-
// Obtain the actual value of the binary exponent from the extracted exponent bits.
|
|
167
|
-
static constexpr int binary_exponent(unsigned int exponent_bits) noexcept {
|
|
168
|
-
if (exponent_bits == 0) {
|
|
169
|
-
return format::min_exponent;
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
return int(exponent_bits) + format::exponent_bias;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Obtain the actual value of the binary exponent from the extracted significand bits and
|
|
177
|
-
// exponent bits.
|
|
178
|
-
static constexpr carrier_uint binary_significand(carrier_uint significand_bits,
|
|
179
|
-
unsigned int exponent_bits) noexcept {
|
|
180
|
-
if (exponent_bits == 0) {
|
|
181
|
-
return significand_bits;
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
return significand_bits | (carrier_uint(1) << format::significand_bits);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
/* Various boolean observer functions */
|
|
190
|
-
|
|
191
|
-
static constexpr bool is_nonzero(carrier_uint u) noexcept { return (u << 1) != 0; }
|
|
192
|
-
static constexpr bool is_positive(carrier_uint u) noexcept {
|
|
193
|
-
constexpr auto sign_bit = carrier_uint(1)
|
|
194
|
-
<< (format::significand_bits + format::exponent_bits);
|
|
195
|
-
return u < sign_bit;
|
|
196
|
-
}
|
|
197
|
-
static constexpr bool is_negative(carrier_uint u) noexcept { return !is_positive(u); }
|
|
198
|
-
static constexpr bool is_finite(unsigned int exponent_bits) noexcept {
|
|
199
|
-
constexpr unsigned int exponent_bits_all_set = (1u << format::exponent_bits) - 1;
|
|
200
|
-
return exponent_bits != exponent_bits_all_set;
|
|
201
|
-
}
|
|
202
|
-
static constexpr bool has_all_zero_significand_bits(carrier_uint u) noexcept {
|
|
203
|
-
return (u << 1) == 0;
|
|
204
|
-
}
|
|
205
|
-
static constexpr bool has_even_significand_bits(carrier_uint u) noexcept {
|
|
206
|
-
return u % 2 == 0;
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
// Convenient wrappers for floating-point traits classes.
|
|
211
|
-
// In order to reduce the argument passing overhead, these classes should be as simple as
|
|
212
|
-
// possible (e.g., no inheritance, no private non-static data member, etc.; this is an
|
|
213
|
-
// unfortunate fact about common ABI convention).
|
|
214
|
-
|
|
215
|
-
template <class T, class Traits = default_float_traits<T>>
|
|
216
|
-
struct float_bits;
|
|
217
|
-
|
|
218
|
-
template <class T, class Traits = default_float_traits<T>>
|
|
219
|
-
struct signed_significand_bits;
|
|
220
|
-
|
|
221
|
-
template <class T, class Traits>
|
|
222
|
-
struct float_bits {
|
|
223
|
-
using type = T;
|
|
224
|
-
using traits_type = Traits;
|
|
225
|
-
using carrier_uint = typename traits_type::carrier_uint;
|
|
226
|
-
|
|
227
|
-
carrier_uint u;
|
|
228
|
-
|
|
229
|
-
float_bits() = default;
|
|
230
|
-
constexpr explicit float_bits(carrier_uint bit_pattern) noexcept : u{bit_pattern} {}
|
|
231
|
-
constexpr explicit float_bits(T float_value) noexcept
|
|
232
|
-
: u{traits_type::float_to_carrier(float_value)} {}
|
|
233
|
-
|
|
234
|
-
constexpr T to_float() const noexcept { return traits_type::carrier_to_float(u); }
|
|
235
|
-
|
|
236
|
-
// Extract exponent bits from a bit pattern.
|
|
237
|
-
// The result must be aligned to the LSB so that there is no additional zero paddings
|
|
238
|
-
// on the right. This function does not do bias adjustment.
|
|
239
|
-
constexpr unsigned int extract_exponent_bits() const noexcept {
|
|
240
|
-
return traits_type::extract_exponent_bits(u);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Extract significand bits from a bit pattern.
|
|
244
|
-
// The result must be aligned to the LSB so that there is no additional zero paddings
|
|
245
|
-
// on the right. The result does not contain the implicit bit.
|
|
246
|
-
constexpr carrier_uint extract_significand_bits() const noexcept {
|
|
247
|
-
return traits_type::extract_significand_bits(u);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// Remove the exponent bits and extract significand bits together with the sign bit.
|
|
251
|
-
constexpr auto remove_exponent_bits(unsigned int exponent_bits) const noexcept {
|
|
252
|
-
return signed_significand_bits<type, traits_type>(
|
|
253
|
-
traits_type::remove_exponent_bits(u, exponent_bits));
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Obtain the actual value of the binary exponent from the extracted exponent bits.
|
|
257
|
-
static constexpr int binary_exponent(unsigned int exponent_bits) noexcept {
|
|
258
|
-
return traits_type::binary_exponent(exponent_bits);
|
|
259
|
-
}
|
|
260
|
-
constexpr int binary_exponent() const noexcept {
|
|
261
|
-
return binary_exponent(extract_exponent_bits());
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Obtain the actual value of the binary exponent from the extracted significand bits and
|
|
265
|
-
// exponent bits.
|
|
266
|
-
static constexpr carrier_uint binary_significand(carrier_uint significand_bits,
|
|
267
|
-
unsigned int exponent_bits) noexcept {
|
|
268
|
-
return traits_type::binary_significand(significand_bits, exponent_bits);
|
|
269
|
-
}
|
|
270
|
-
constexpr carrier_uint binary_significand() const noexcept {
|
|
271
|
-
return binary_significand(extract_significand_bits(), extract_exponent_bits());
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
constexpr bool is_nonzero() const noexcept { return traits_type::is_nonzero(u); }
|
|
275
|
-
constexpr bool is_positive() const noexcept { return traits_type::is_positive(u); }
|
|
276
|
-
constexpr bool is_negative() const noexcept { return traits_type::is_negative(u); }
|
|
277
|
-
constexpr bool is_finite(unsigned int exponent_bits) const noexcept {
|
|
278
|
-
return traits_type::is_finite(exponent_bits);
|
|
279
|
-
}
|
|
280
|
-
constexpr bool is_finite() const noexcept {
|
|
281
|
-
return traits_type::is_finite(extract_exponent_bits());
|
|
282
|
-
}
|
|
283
|
-
constexpr bool has_even_significand_bits() const noexcept {
|
|
284
|
-
return traits_type::has_even_significand_bits(u);
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
template <class T, class Traits>
|
|
289
|
-
struct signed_significand_bits {
|
|
290
|
-
using type = T;
|
|
291
|
-
using traits_type = Traits;
|
|
292
|
-
using carrier_uint = typename traits_type::carrier_uint;
|
|
293
|
-
|
|
294
|
-
carrier_uint u;
|
|
295
|
-
|
|
296
|
-
signed_significand_bits() = default;
|
|
297
|
-
constexpr explicit signed_significand_bits(carrier_uint bit_pattern) noexcept
|
|
298
|
-
: u{bit_pattern} {}
|
|
299
|
-
|
|
300
|
-
// Shift the obtained signed significand bits to the left by 1 to remove the sign bit.
|
|
301
|
-
constexpr carrier_uint remove_sign_bit_and_shift() const noexcept {
|
|
302
|
-
return traits_type::remove_sign_bit_and_shift(u);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
constexpr bool is_positive() const noexcept { return traits_type::is_positive(u); }
|
|
306
|
-
constexpr bool is_negative() const noexcept { return traits_type::is_negative(u); }
|
|
307
|
-
constexpr bool has_all_zero_significand_bits() const noexcept {
|
|
308
|
-
return traits_type::has_all_zero_significand_bits(u);
|
|
309
|
-
}
|
|
310
|
-
constexpr bool has_even_significand_bits() const noexcept {
|
|
311
|
-
return traits_type::has_even_significand_bits(u);
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
namespace detail {
|
|
316
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
317
|
-
// Bit operation intrinsics.
|
|
318
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
319
|
-
|
|
320
|
-
namespace bits {
|
|
321
|
-
// Most compilers should be able to optimize this into the ROR instruction.
|
|
322
|
-
inline std::uint32_t rotr(std::uint32_t n, std::uint32_t r) noexcept {
|
|
323
|
-
r &= 31;
|
|
324
|
-
return (n >> r) | (n << (32 - r));
|
|
325
|
-
}
|
|
326
|
-
inline std::uint64_t rotr(std::uint64_t n, std::uint32_t r) noexcept {
|
|
327
|
-
r &= 63;
|
|
328
|
-
return (n >> r) | (n << (64 - r));
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
333
|
-
// Utilities for wide unsigned integer arithmetic.
|
|
334
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
335
|
-
|
|
336
|
-
namespace wuint {
|
|
337
|
-
// Compilers might support built-in 128-bit integer types. However, it seems that
|
|
338
|
-
// emulating them with a pair of 64-bit integers actually produces a better code,
|
|
339
|
-
// so we avoid using those built-ins. That said, they are still useful for
|
|
340
|
-
// implementing 64-bit x 64-bit -> 128-bit multiplication.
|
|
341
|
-
|
|
342
|
-
// clang-format off
|
|
343
|
-
#if defined(__SIZEOF_INT128__)
|
|
344
|
-
// To silence "error: ISO C++ does not support '__int128' for 'type name'
|
|
345
|
-
// [-Wpedantic]"
|
|
346
|
-
#if defined(__GNUC__)
|
|
347
|
-
__extension__
|
|
348
|
-
#endif
|
|
349
|
-
using builtin_uint128_t = unsigned __int128;
|
|
350
|
-
#endif
|
|
351
|
-
// clang-format on
|
|
352
|
-
|
|
353
|
-
struct uint128 {
|
|
354
|
-
uint128() = default;
|
|
355
|
-
|
|
356
|
-
std::uint64_t high_;
|
|
357
|
-
std::uint64_t low_;
|
|
358
|
-
|
|
359
|
-
constexpr uint128(std::uint64_t high, std::uint64_t low) noexcept
|
|
360
|
-
: high_{high}, low_{low} {}
|
|
361
|
-
|
|
362
|
-
constexpr std::uint64_t high() const noexcept { return high_; }
|
|
363
|
-
constexpr std::uint64_t low() const noexcept { return low_; }
|
|
364
|
-
|
|
365
|
-
uint128& operator+=(std::uint64_t n) & noexcept {
|
|
366
|
-
#if JKJ_DRAGONBOX_HAS_BUILTIN(__builtin_addcll)
|
|
367
|
-
unsigned long long carry;
|
|
368
|
-
low_ = __builtin_addcll(low_, n, 0, &carry);
|
|
369
|
-
high_ = __builtin_addcll(high_, 0, carry, &carry);
|
|
370
|
-
#elif JKJ_DRAGONBOX_HAS_BUILTIN(__builtin_ia32_addcarryx_u64)
|
|
371
|
-
unsigned long long result;
|
|
372
|
-
auto carry = __builtin_ia32_addcarryx_u64(0, low_, n, &result);
|
|
373
|
-
low_ = result;
|
|
374
|
-
__builtin_ia32_addcarryx_u64(carry, high_, 0, &result);
|
|
375
|
-
high_ = result;
|
|
376
|
-
#elif defined(_MSC_VER) && defined(_M_X64)
|
|
377
|
-
auto carry = _addcarry_u64(0, low_, n, &low_);
|
|
378
|
-
_addcarry_u64(carry, high_, 0, &high_);
|
|
379
|
-
#else
|
|
380
|
-
auto sum = low_ + n;
|
|
381
|
-
high_ += (sum < low_ ? 1 : 0);
|
|
382
|
-
low_ = sum;
|
|
383
|
-
#endif
|
|
384
|
-
return *this;
|
|
385
|
-
}
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
static inline std::uint64_t umul64(std::uint32_t x, std::uint32_t y) noexcept {
|
|
389
|
-
#if defined(_MSC_VER) && defined(_M_IX86)
|
|
390
|
-
return __emulu(x, y);
|
|
391
|
-
#else
|
|
392
|
-
return x * std::uint64_t(y);
|
|
393
|
-
#endif
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
// Get 128-bit result of multiplication of two 64-bit unsigned integers.
|
|
397
|
-
JKJ_SAFEBUFFERS inline uint128 umul128(std::uint64_t x, std::uint64_t y) noexcept {
|
|
398
|
-
#if defined(__SIZEOF_INT128__)
|
|
399
|
-
auto result = builtin_uint128_t(x) * builtin_uint128_t(y);
|
|
400
|
-
return {std::uint64_t(result >> 64), std::uint64_t(result)};
|
|
401
|
-
#elif defined(_MSC_VER) && defined(_M_X64)
|
|
402
|
-
uint128 result;
|
|
403
|
-
result.low_ = _umul128(x, y, &result.high_);
|
|
404
|
-
return result;
|
|
405
|
-
#else
|
|
406
|
-
auto a = std::uint32_t(x >> 32);
|
|
407
|
-
auto b = std::uint32_t(x);
|
|
408
|
-
auto c = std::uint32_t(y >> 32);
|
|
409
|
-
auto d = std::uint32_t(y);
|
|
410
|
-
|
|
411
|
-
auto ac = umul64(a, c);
|
|
412
|
-
auto bc = umul64(b, c);
|
|
413
|
-
auto ad = umul64(a, d);
|
|
414
|
-
auto bd = umul64(b, d);
|
|
415
|
-
|
|
416
|
-
auto intermediate = (bd >> 32) + std::uint32_t(ad) + std::uint32_t(bc);
|
|
417
|
-
|
|
418
|
-
return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32),
|
|
419
|
-
(intermediate << 32) + std::uint32_t(bd)};
|
|
420
|
-
#endif
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
JKJ_SAFEBUFFERS inline std::uint64_t umul128_upper64(std::uint64_t x,
|
|
424
|
-
std::uint64_t y) noexcept {
|
|
425
|
-
#if defined(__SIZEOF_INT128__)
|
|
426
|
-
auto result = builtin_uint128_t(x) * builtin_uint128_t(y);
|
|
427
|
-
return std::uint64_t(result >> 64);
|
|
428
|
-
#elif defined(_MSC_VER) && defined(_M_X64)
|
|
429
|
-
return __umulh(x, y);
|
|
430
|
-
#else
|
|
431
|
-
auto a = std::uint32_t(x >> 32);
|
|
432
|
-
auto b = std::uint32_t(x);
|
|
433
|
-
auto c = std::uint32_t(y >> 32);
|
|
434
|
-
auto d = std::uint32_t(y);
|
|
435
|
-
|
|
436
|
-
auto ac = umul64(a, c);
|
|
437
|
-
auto bc = umul64(b, c);
|
|
438
|
-
auto ad = umul64(a, d);
|
|
439
|
-
auto bd = umul64(b, d);
|
|
440
|
-
|
|
441
|
-
auto intermediate = (bd >> 32) + std::uint32_t(ad) + std::uint32_t(bc);
|
|
442
|
-
|
|
443
|
-
return ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32);
|
|
444
|
-
#endif
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// Get upper 128-bits of multiplication of a 64-bit unsigned integer and a 128-bit
|
|
448
|
-
// unsigned integer.
|
|
449
|
-
JKJ_SAFEBUFFERS inline uint128 umul192_upper128(std::uint64_t x, uint128 y) noexcept {
|
|
450
|
-
auto r = umul128(x, y.high());
|
|
451
|
-
r += umul128_upper64(x, y.low());
|
|
452
|
-
return r;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
// Get upper 64-bits of multiplication of a 32-bit unsigned integer and a 64-bit
|
|
456
|
-
// unsigned integer.
|
|
457
|
-
inline std::uint64_t umul96_upper64(std::uint32_t x, std::uint64_t y) noexcept {
|
|
458
|
-
#if defined(__SIZEOF_INT128__) || (defined(_MSC_VER) && defined(_M_X64))
|
|
459
|
-
return umul128_upper64(std::uint64_t(x) << 32, y);
|
|
460
|
-
#else
|
|
461
|
-
auto yh = std::uint32_t(y >> 32);
|
|
462
|
-
auto yl = std::uint32_t(y);
|
|
463
|
-
|
|
464
|
-
auto xyh = umul64(x, yh);
|
|
465
|
-
auto xyl = umul64(x, yl);
|
|
466
|
-
|
|
467
|
-
return xyh + (xyl >> 32);
|
|
468
|
-
#endif
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
// Get lower 128-bits of multiplication of a 64-bit unsigned integer and a 128-bit
|
|
472
|
-
// unsigned integer.
|
|
473
|
-
JKJ_SAFEBUFFERS inline uint128 umul192_lower128(std::uint64_t x, uint128 y) noexcept {
|
|
474
|
-
auto high = x * y.high();
|
|
475
|
-
auto high_low = umul128(x, y.low());
|
|
476
|
-
return {high + high_low.high(), high_low.low()};
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
// Get lower 64-bits of multiplication of a 32-bit unsigned integer and a 64-bit
|
|
480
|
-
// unsigned integer.
|
|
481
|
-
inline std::uint64_t umul96_lower64(std::uint32_t x, std::uint64_t y) noexcept {
|
|
482
|
-
return x * y;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
487
|
-
// Some simple utilities for constexpr computation.
|
|
488
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
489
|
-
|
|
490
|
-
template <int k, class Int>
|
|
491
|
-
constexpr Int compute_power(Int a) noexcept {
|
|
492
|
-
static_assert(k >= 0);
|
|
493
|
-
Int p = 1;
|
|
494
|
-
for (int i = 0; i < k; ++i) {
|
|
495
|
-
p *= a;
|
|
496
|
-
}
|
|
497
|
-
return p;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
template <int a, class UInt>
|
|
501
|
-
constexpr int count_factors(UInt n) noexcept {
|
|
502
|
-
static_assert(a > 1);
|
|
503
|
-
int c = 0;
|
|
504
|
-
while (n % a == 0) {
|
|
505
|
-
n /= a;
|
|
506
|
-
++c;
|
|
507
|
-
}
|
|
508
|
-
return c;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
512
|
-
// Utilities for fast/constexpr log computation.
|
|
513
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
514
|
-
|
|
515
|
-
namespace log {
|
|
516
|
-
static_assert((-1 >> 1) == -1, "right-shift for signed integers must be arithmetic");
|
|
517
|
-
|
|
518
|
-
// Compute floor(e * c - s).
|
|
519
|
-
enum class multiply : std::uint32_t {};
|
|
520
|
-
enum class subtract : std::uint32_t {};
|
|
521
|
-
enum class shift : std::size_t {};
|
|
522
|
-
enum class min_exponent : std::int32_t {};
|
|
523
|
-
enum class max_exponent : std::int32_t {};
|
|
524
|
-
|
|
525
|
-
template <multiply m, subtract f, shift k, min_exponent e_min, max_exponent e_max>
|
|
526
|
-
constexpr int compute(int e) noexcept {
|
|
527
|
-
assert(std::int32_t(e_min) <= e && e <= std::int32_t(e_max));
|
|
528
|
-
return int((std::int32_t(e) * std::int32_t(m) - std::int32_t(f)) >> std::size_t(k));
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
// For constexpr computation.
|
|
532
|
-
// Returns -1 when n = 0.
|
|
533
|
-
template <class UInt>
|
|
534
|
-
constexpr int floor_log2(UInt n) noexcept {
|
|
535
|
-
int count = -1;
|
|
536
|
-
while (n != 0) {
|
|
537
|
-
++count;
|
|
538
|
-
n >>= 1;
|
|
539
|
-
}
|
|
540
|
-
return count;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
static constexpr int floor_log10_pow2_min_exponent = -2620;
|
|
544
|
-
static constexpr int floor_log10_pow2_max_exponent = 2620;
|
|
545
|
-
constexpr int floor_log10_pow2(int e) noexcept {
|
|
546
|
-
using namespace log;
|
|
547
|
-
return compute<multiply(315653), subtract(0), shift(20),
|
|
548
|
-
min_exponent(floor_log10_pow2_min_exponent),
|
|
549
|
-
max_exponent(floor_log10_pow2_max_exponent)>(e);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
static constexpr int floor_log2_pow10_min_exponent = -1233;
|
|
553
|
-
static constexpr int floor_log2_pow10_max_exponent = 1233;
|
|
554
|
-
constexpr int floor_log2_pow10(int e) noexcept {
|
|
555
|
-
using namespace log;
|
|
556
|
-
return compute<multiply(1741647), subtract(0), shift(19),
|
|
557
|
-
min_exponent(floor_log2_pow10_min_exponent),
|
|
558
|
-
max_exponent(floor_log2_pow10_max_exponent)>(e);
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
static constexpr int floor_log10_pow2_minus_log10_4_over_3_min_exponent = -2985;
|
|
562
|
-
static constexpr int floor_log10_pow2_minus_log10_4_over_3_max_exponent = 2936;
|
|
563
|
-
constexpr int floor_log10_pow2_minus_log10_4_over_3(int e) noexcept {
|
|
564
|
-
using namespace log;
|
|
565
|
-
return compute<multiply(631305), subtract(261663), shift(21),
|
|
566
|
-
min_exponent(floor_log10_pow2_minus_log10_4_over_3_min_exponent),
|
|
567
|
-
max_exponent(floor_log10_pow2_minus_log10_4_over_3_max_exponent)>(e);
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
static constexpr int floor_log5_pow2_min_exponent = -1831;
|
|
571
|
-
static constexpr int floor_log5_pow2_max_exponent = 1831;
|
|
572
|
-
constexpr int floor_log5_pow2(int e) noexcept {
|
|
573
|
-
using namespace log;
|
|
574
|
-
return compute<multiply(225799), subtract(0), shift(19),
|
|
575
|
-
min_exponent(floor_log5_pow2_min_exponent),
|
|
576
|
-
max_exponent(floor_log5_pow2_max_exponent)>(e);
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
static constexpr int floor_log5_pow2_minus_log5_3_min_exponent = -3543;
|
|
580
|
-
static constexpr int floor_log5_pow2_minus_log5_3_max_exponent = 2427;
|
|
581
|
-
constexpr int floor_log5_pow2_minus_log5_3(int e) noexcept {
|
|
582
|
-
using namespace log;
|
|
583
|
-
return compute<multiply(451597), subtract(715764), shift(20),
|
|
584
|
-
min_exponent(floor_log5_pow2_minus_log5_3_min_exponent),
|
|
585
|
-
max_exponent(floor_log5_pow2_minus_log5_3_max_exponent)>(e);
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
590
|
-
// Utilities for fast divisibility tests.
|
|
591
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
592
|
-
|
|
593
|
-
namespace div {
|
|
594
|
-
// Replace n by floor(n / 10^N).
|
|
595
|
-
// Returns true if and only if n is divisible by 10^N.
|
|
596
|
-
// Precondition: n <= 10^(N+1)
|
|
597
|
-
// !!It takes an in-out parameter!!
|
|
598
|
-
template <int N>
|
|
599
|
-
struct divide_by_pow10_info;
|
|
600
|
-
|
|
601
|
-
template <>
|
|
602
|
-
struct divide_by_pow10_info<1> {
|
|
603
|
-
static constexpr std::uint32_t magic_number = 6554;
|
|
604
|
-
static constexpr int shift_amount = 16;
|
|
605
|
-
};
|
|
606
|
-
|
|
607
|
-
template <>
|
|
608
|
-
struct divide_by_pow10_info<2> {
|
|
609
|
-
static constexpr std::uint32_t magic_number = 656;
|
|
610
|
-
static constexpr int shift_amount = 16;
|
|
611
|
-
};
|
|
612
|
-
|
|
613
|
-
template <int N>
|
|
614
|
-
constexpr bool check_divisibility_and_divide_by_pow10(std::uint32_t& n) noexcept {
|
|
615
|
-
// Make sure the computation for max_n does not overflow.
|
|
616
|
-
static_assert(N + 1 <= log::floor_log10_pow2(31));
|
|
617
|
-
assert(n <= compute_power<N + 1>(std::uint32_t(10)));
|
|
618
|
-
|
|
619
|
-
using info = divide_by_pow10_info<N>;
|
|
620
|
-
n *= info::magic_number;
|
|
621
|
-
|
|
622
|
-
constexpr auto mask = std::uint32_t(std::uint32_t(1) << info::shift_amount) - 1;
|
|
623
|
-
bool result = ((n & mask) < info::magic_number);
|
|
624
|
-
|
|
625
|
-
n >>= info::shift_amount;
|
|
626
|
-
return result;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
// Compute floor(n / 10^N) for small n and N.
|
|
630
|
-
// Precondition: n <= 10^(N+1)
|
|
631
|
-
template <int N>
|
|
632
|
-
constexpr std::uint32_t small_division_by_pow10(std::uint32_t n) noexcept {
|
|
633
|
-
// Make sure the computation for max_n does not overflow.
|
|
634
|
-
static_assert(N + 1 <= log::floor_log10_pow2(31));
|
|
635
|
-
assert(n <= compute_power<N + 1>(std::uint32_t(10)));
|
|
636
|
-
|
|
637
|
-
return (n * divide_by_pow10_info<N>::magic_number) >>
|
|
638
|
-
divide_by_pow10_info<N>::shift_amount;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
// Compute floor(n / 10^N) for small N.
|
|
642
|
-
// Precondition: n <= n_max
|
|
643
|
-
template <int N, class UInt, UInt n_max>
|
|
644
|
-
constexpr UInt divide_by_pow10(UInt n) noexcept {
|
|
645
|
-
static_assert(N >= 0);
|
|
646
|
-
|
|
647
|
-
// Specialize for 32-bit division by 100.
|
|
648
|
-
// Compiler is supposed to generate the identical code for just writing
|
|
649
|
-
// "n / 100", but for some reason MSVC generates an inefficient code
|
|
650
|
-
// (mul + mov for no apparent reason, instead of single imul),
|
|
651
|
-
// so we does this manually.
|
|
652
|
-
if constexpr (std::is_same_v<UInt, std::uint32_t> && N == 2) {
|
|
653
|
-
return std::uint32_t(wuint::umul64(n, std::uint32_t(1374389535)) >> 37);
|
|
654
|
-
}
|
|
655
|
-
// Specialize for 64-bit division by 1000.
|
|
656
|
-
// Ensure that the correctness condition is met.
|
|
657
|
-
if constexpr (std::is_same_v<UInt, std::uint64_t> && N == 3 &&
|
|
658
|
-
n_max <= std::uint64_t(15534100272597517998ull)) {
|
|
659
|
-
return wuint::umul128_upper64(n, std::uint64_t(2361183241434822607ull)) >> 7;
|
|
660
|
-
}
|
|
661
|
-
else {
|
|
662
|
-
constexpr auto divisor = compute_power<N>(UInt(10));
|
|
663
|
-
return n / divisor;
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
670
|
-
// Return types for the main interface function.
|
|
671
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
672
|
-
|
|
673
|
-
template <class UInt, bool is_signed, bool trailing_zero_flag>
|
|
674
|
-
struct decimal_fp;
|
|
675
|
-
|
|
676
|
-
template <class UInt>
|
|
677
|
-
struct decimal_fp<UInt, false, false> {
|
|
678
|
-
using carrier_uint = UInt;
|
|
679
|
-
|
|
680
|
-
carrier_uint significand;
|
|
681
|
-
int exponent;
|
|
682
|
-
};
|
|
683
|
-
|
|
684
|
-
template <class UInt>
|
|
685
|
-
struct decimal_fp<UInt, true, false> {
|
|
686
|
-
using carrier_uint = UInt;
|
|
687
|
-
|
|
688
|
-
carrier_uint significand;
|
|
689
|
-
int exponent;
|
|
690
|
-
bool is_negative;
|
|
691
|
-
};
|
|
692
|
-
|
|
693
|
-
template <class UInt>
|
|
694
|
-
struct decimal_fp<UInt, false, true> {
|
|
695
|
-
using carrier_uint = UInt;
|
|
696
|
-
|
|
697
|
-
carrier_uint significand;
|
|
698
|
-
int exponent;
|
|
699
|
-
bool may_have_trailing_zeros;
|
|
700
|
-
};
|
|
701
|
-
|
|
702
|
-
template <class UInt>
|
|
703
|
-
struct decimal_fp<UInt, true, true> {
|
|
704
|
-
using carrier_uint = UInt;
|
|
705
|
-
|
|
706
|
-
carrier_uint significand;
|
|
707
|
-
int exponent;
|
|
708
|
-
bool is_negative;
|
|
709
|
-
bool may_have_trailing_zeros;
|
|
710
|
-
};
|
|
711
|
-
|
|
712
|
-
template <class UInt>
|
|
713
|
-
using unsigned_decimal_fp = decimal_fp<UInt, false, false>;
|
|
714
|
-
|
|
715
|
-
template <class UInt>
|
|
716
|
-
using signed_decimal_fp = decimal_fp<UInt, true, false>;
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
720
|
-
// Computed cache entries.
|
|
721
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
722
|
-
|
|
723
|
-
namespace detail {
|
|
724
|
-
template <class FloatFormat>
|
|
725
|
-
struct cache_holder;
|
|
726
|
-
|
|
727
|
-
template <>
|
|
728
|
-
struct cache_holder<ieee754_binary32> {
|
|
729
|
-
using cache_entry_type = std::uint64_t;
|
|
730
|
-
static constexpr int cache_bits = 64;
|
|
731
|
-
static constexpr int min_k = -31;
|
|
732
|
-
static constexpr int max_k = 46;
|
|
733
|
-
static constexpr cache_entry_type cache[] = {
|
|
734
|
-
0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f, 0xfd87b5f28300ca0e,
|
|
735
|
-
0x9e74d1b791e07e49, 0xc612062576589ddb, 0xf79687aed3eec552, 0x9abe14cd44753b53,
|
|
736
|
-
0xc16d9a0095928a28, 0xf1c90080baf72cb2, 0x971da05074da7bef, 0xbce5086492111aeb,
|
|
737
|
-
0xec1e4a7db69561a6, 0x9392ee8e921d5d08, 0xb877aa3236a4b44a, 0xe69594bec44de15c,
|
|
738
|
-
0x901d7cf73ab0acda, 0xb424dc35095cd810, 0xe12e13424bb40e14, 0x8cbccc096f5088cc,
|
|
739
|
-
0xafebff0bcb24aaff, 0xdbe6fecebdedd5bf, 0x89705f4136b4a598, 0xabcc77118461cefd,
|
|
740
|
-
0xd6bf94d5e57a42bd, 0x8637bd05af6c69b6, 0xa7c5ac471b478424, 0xd1b71758e219652c,
|
|
741
|
-
0x83126e978d4fdf3c, 0xa3d70a3d70a3d70b, 0xcccccccccccccccd, 0x8000000000000000,
|
|
742
|
-
0xa000000000000000, 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000,
|
|
743
|
-
0xc350000000000000, 0xf424000000000000, 0x9896800000000000, 0xbebc200000000000,
|
|
744
|
-
0xee6b280000000000, 0x9502f90000000000, 0xba43b74000000000, 0xe8d4a51000000000,
|
|
745
|
-
0x9184e72a00000000, 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000,
|
|
746
|
-
0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000, 0xad78ebc5ac620000,
|
|
747
|
-
0xd8d726b7177a8000, 0x878678326eac9000, 0xa968163f0a57b400, 0xd3c21bcecceda100,
|
|
748
|
-
0x84595161401484a0, 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940985,
|
|
749
|
-
0xa18f07d736b90be6, 0xc9f2c9cd04674edf, 0xfc6f7c4045812297, 0x9dc5ada82b70b59e,
|
|
750
|
-
0xc5371912364ce306, 0xf684df56c3e01bc7, 0x9a130b963a6c115d, 0xc097ce7bc90715b4,
|
|
751
|
-
0xf0bdc21abb48db21, 0x96769950b50d88f5, 0xbc143fa4e250eb32, 0xeb194f8e1ae525fe,
|
|
752
|
-
0x92efd1b8d0cf37bf, 0xb7abc627050305ae, 0xe596b7b0c643c71a, 0x8f7e32ce7bea5c70,
|
|
753
|
-
0xb35dbf821ae4f38c, 0xe0352f62a19e306f};
|
|
754
|
-
};
|
|
755
|
-
|
|
756
|
-
template <>
|
|
757
|
-
struct cache_holder<ieee754_binary64> {
|
|
758
|
-
using cache_entry_type = wuint::uint128;
|
|
759
|
-
static constexpr int cache_bits = 128;
|
|
760
|
-
static constexpr int min_k = -292;
|
|
761
|
-
static constexpr int max_k = 326;
|
|
762
|
-
static constexpr cache_entry_type cache[] = {
|
|
763
|
-
{0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b}, {0x9faacf3df73609b1, 0x77b191618c54e9ad},
|
|
764
|
-
{0xc795830d75038c1d, 0xd59df5b9ef6a2418}, {0xf97ae3d0d2446f25, 0x4b0573286b44ad1e},
|
|
765
|
-
{0x9becce62836ac577, 0x4ee367f9430aec33}, {0xc2e801fb244576d5, 0x229c41f793cda740},
|
|
766
|
-
{0xf3a20279ed56d48a, 0x6b43527578c11110}, {0x9845418c345644d6, 0x830a13896b78aaaa},
|
|
767
|
-
{0xbe5691ef416bd60c, 0x23cc986bc656d554}, {0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa9},
|
|
768
|
-
{0x94b3a202eb1c3f39, 0x7bf7d71432f3d6aa}, {0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc54},
|
|
769
|
-
{0xe858ad248f5c22c9, 0xd1b3400f8f9cff69}, {0x91376c36d99995be, 0x23100809b9c21fa2},
|
|
770
|
-
{0xb58547448ffffb2d, 0xabd40a0c2832a78b}, {0xe2e69915b3fff9f9, 0x16c90c8f323f516d},
|
|
771
|
-
{0x8dd01fad907ffc3b, 0xae3da7d97f6792e4}, {0xb1442798f49ffb4a, 0x99cd11cfdf41779d},
|
|
772
|
-
{0xdd95317f31c7fa1d, 0x40405643d711d584}, {0x8a7d3eef7f1cfc52, 0x482835ea666b2573},
|
|
773
|
-
{0xad1c8eab5ee43b66, 0xda3243650005eed0}, {0xd863b256369d4a40, 0x90bed43e40076a83},
|
|
774
|
-
{0x873e4f75e2224e68, 0x5a7744a6e804a292}, {0xa90de3535aaae202, 0x711515d0a205cb37},
|
|
775
|
-
{0xd3515c2831559a83, 0x0d5a5b44ca873e04}, {0x8412d9991ed58091, 0xe858790afe9486c3},
|
|
776
|
-
{0xa5178fff668ae0b6, 0x626e974dbe39a873}, {0xce5d73ff402d98e3, 0xfb0a3d212dc81290},
|
|
777
|
-
{0x80fa687f881c7f8e, 0x7ce66634bc9d0b9a}, {0xa139029f6a239f72, 0x1c1fffc1ebc44e81},
|
|
778
|
-
{0xc987434744ac874e, 0xa327ffb266b56221}, {0xfbe9141915d7a922, 0x4bf1ff9f0062baa9},
|
|
779
|
-
{0x9d71ac8fada6c9b5, 0x6f773fc3603db4aa}, {0xc4ce17b399107c22, 0xcb550fb4384d21d4},
|
|
780
|
-
{0xf6019da07f549b2b, 0x7e2a53a146606a49}, {0x99c102844f94e0fb, 0x2eda7444cbfc426e},
|
|
781
|
-
{0xc0314325637a1939, 0xfa911155fefb5309}, {0xf03d93eebc589f88, 0x793555ab7eba27cb},
|
|
782
|
-
{0x96267c7535b763b5, 0x4bc1558b2f3458df}, {0xbbb01b9283253ca2, 0x9eb1aaedfb016f17},
|
|
783
|
-
{0xea9c227723ee8bcb, 0x465e15a979c1cadd}, {0x92a1958a7675175f, 0x0bfacd89ec191eca},
|
|
784
|
-
{0xb749faed14125d36, 0xcef980ec671f667c}, {0xe51c79a85916f484, 0x82b7e12780e7401b},
|
|
785
|
-
{0x8f31cc0937ae58d2, 0xd1b2ecb8b0908811}, {0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa16},
|
|
786
|
-
{0xdfbdcece67006ac9, 0x67a791e093e1d49b}, {0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e1},
|
|
787
|
-
{0xaecc49914078536d, 0x58fae9f773886e19}, {0xda7f5bf590966848, 0xaf39a475506a899f},
|
|
788
|
-
{0x888f99797a5e012d, 0x6d8406c952429604}, {0xaab37fd7d8f58178, 0xc8e5087ba6d33b84},
|
|
789
|
-
{0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a65}, {0x855c3be0a17fcd26, 0x5cf2eea09a550680},
|
|
790
|
-
{0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f}, {0xd0601d8efc57b08b, 0xf13b94daf124da27},
|
|
791
|
-
{0x823c12795db6ce57, 0x76c53d08d6b70859}, {0xa2cb1717b52481ed, 0x54768c4b0c64ca6f},
|
|
792
|
-
{0xcb7ddcdda26da268, 0xa9942f5dcf7dfd0a}, {0xfe5d54150b090b02, 0xd3f93b35435d7c4d},
|
|
793
|
-
{0x9efa548d26e5a6e1, 0xc47bc5014a1a6db0}, {0xc6b8e9b0709f109a, 0x359ab6419ca1091c},
|
|
794
|
-
{0xf867241c8cc6d4c0, 0xc30163d203c94b63}, {0x9b407691d7fc44f8, 0x79e0de63425dcf1e},
|
|
795
|
-
{0xc21094364dfb5636, 0x985915fc12f542e5}, {0xf294b943e17a2bc4, 0x3e6f5b7b17b2939e},
|
|
796
|
-
{0x979cf3ca6cec5b5a, 0xa705992ceecf9c43}, {0xbd8430bd08277231, 0x50c6ff782a838354},
|
|
797
|
-
{0xece53cec4a314ebd, 0xa4f8bf5635246429}, {0x940f4613ae5ed136, 0x871b7795e136be9a},
|
|
798
|
-
{0xb913179899f68584, 0x28e2557b59846e40}, {0xe757dd7ec07426e5, 0x331aeada2fe589d0},
|
|
799
|
-
{0x9096ea6f3848984f, 0x3ff0d2c85def7622}, {0xb4bca50b065abe63, 0x0fed077a756b53aa},
|
|
800
|
-
{0xe1ebce4dc7f16dfb, 0xd3e8495912c62895}, {0x8d3360f09cf6e4bd, 0x64712dd7abbbd95d},
|
|
801
|
-
{0xb080392cc4349dec, 0xbd8d794d96aacfb4}, {0xdca04777f541c567, 0xecf0d7a0fc5583a1},
|
|
802
|
-
{0x89e42caaf9491b60, 0xf41686c49db57245}, {0xac5d37d5b79b6239, 0x311c2875c522ced6},
|
|
803
|
-
{0xd77485cb25823ac7, 0x7d633293366b828c}, {0x86a8d39ef77164bc, 0xae5dff9c02033198},
|
|
804
|
-
{0xa8530886b54dbdeb, 0xd9f57f830283fdfd}, {0xd267caa862a12d66, 0xd072df63c324fd7c},
|
|
805
|
-
{0x8380dea93da4bc60, 0x4247cb9e59f71e6e}, {0xa46116538d0deb78, 0x52d9be85f074e609},
|
|
806
|
-
{0xcd795be870516656, 0x67902e276c921f8c}, {0x806bd9714632dff6, 0x00ba1cd8a3db53b7},
|
|
807
|
-
{0xa086cfcd97bf97f3, 0x80e8a40eccd228a5}, {0xc8a883c0fdaf7df0, 0x6122cd128006b2ce},
|
|
808
|
-
{0xfad2a4b13d1b5d6c, 0x796b805720085f82}, {0x9cc3a6eec6311a63, 0xcbe3303674053bb1},
|
|
809
|
-
{0xc3f490aa77bd60fc, 0xbedbfc4411068a9d}, {0xf4f1b4d515acb93b, 0xee92fb5515482d45},
|
|
810
|
-
{0x991711052d8bf3c5, 0x751bdd152d4d1c4b}, {0xbf5cd54678eef0b6, 0xd262d45a78a0635e},
|
|
811
|
-
{0xef340a98172aace4, 0x86fb897116c87c35}, {0x9580869f0e7aac0e, 0xd45d35e6ae3d4da1},
|
|
812
|
-
{0xbae0a846d2195712, 0x8974836059cca10a}, {0xe998d258869facd7, 0x2bd1a438703fc94c},
|
|
813
|
-
{0x91ff83775423cc06, 0x7b6306a34627ddd0}, {0xb67f6455292cbf08, 0x1a3bc84c17b1d543},
|
|
814
|
-
{0xe41f3d6a7377eeca, 0x20caba5f1d9e4a94}, {0x8e938662882af53e, 0x547eb47b7282ee9d},
|
|
815
|
-
{0xb23867fb2a35b28d, 0xe99e619a4f23aa44}, {0xdec681f9f4c31f31, 0x6405fa00e2ec94d5},
|
|
816
|
-
{0x8b3c113c38f9f37e, 0xde83bc408dd3dd05}, {0xae0b158b4738705e, 0x9624ab50b148d446},
|
|
817
|
-
{0xd98ddaee19068c76, 0x3badd624dd9b0958}, {0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d7},
|
|
818
|
-
{0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4d}, {0xd47487cc8470652b, 0x7647c32000696720},
|
|
819
|
-
{0x84c8d4dfd2c63f3b, 0x29ecd9f40041e074}, {0xa5fb0a17c777cf09, 0xf468107100525891},
|
|
820
|
-
{0xcf79cc9db955c2cc, 0x7182148d4066eeb5}, {0x81ac1fe293d599bf, 0xc6f14cd848405531},
|
|
821
|
-
{0xa21727db38cb002f, 0xb8ada00e5a506a7d}, {0xca9cf1d206fdc03b, 0xa6d90811f0e4851d},
|
|
822
|
-
{0xfd442e4688bd304a, 0x908f4a166d1da664}, {0x9e4a9cec15763e2e, 0x9a598e4e043287ff},
|
|
823
|
-
{0xc5dd44271ad3cdba, 0x40eff1e1853f29fe}, {0xf7549530e188c128, 0xd12bee59e68ef47d},
|
|
824
|
-
{0x9a94dd3e8cf578b9, 0x82bb74f8301958cf}, {0xc13a148e3032d6e7, 0xe36a52363c1faf02},
|
|
825
|
-
{0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac2}, {0x96f5600f15a7b7e5, 0x29ab103a5ef8c0ba},
|
|
826
|
-
{0xbcb2b812db11a5de, 0x7415d448f6b6f0e8}, {0xebdf661791d60f56, 0x111b495b3464ad22},
|
|
827
|
-
{0x936b9fcebb25c995, 0xcab10dd900beec35}, {0xb84687c269ef3bfb, 0x3d5d514f40eea743},
|
|
828
|
-
{0xe65829b3046b0afa, 0x0cb4a5a3112a5113}, {0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ac},
|
|
829
|
-
{0xb3f4e093db73a093, 0x59ed216765690f57}, {0xe0f218b8d25088b8, 0x306869c13ec3532d},
|
|
830
|
-
{0x8c974f7383725573, 0x1e414218c73a13fc}, {0xafbd2350644eeacf, 0xe5d1929ef90898fb},
|
|
831
|
-
{0xdbac6c247d62a583, 0xdf45f746b74abf3a}, {0x894bc396ce5da772, 0x6b8bba8c328eb784},
|
|
832
|
-
{0xab9eb47c81f5114f, 0x066ea92f3f326565}, {0xd686619ba27255a2, 0xc80a537b0efefebe},
|
|
833
|
-
{0x8613fd0145877585, 0xbd06742ce95f5f37}, {0xa798fc4196e952e7, 0x2c48113823b73705},
|
|
834
|
-
{0xd17f3b51fca3a7a0, 0xf75a15862ca504c6}, {0x82ef85133de648c4, 0x9a984d73dbe722fc},
|
|
835
|
-
{0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebbb}, {0xcc963fee10b7d1b3, 0x318df905079926a9},
|
|
836
|
-
{0xffbbcfe994e5c61f, 0xfdf17746497f7053}, {0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa634},
|
|
837
|
-
{0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc1}, {0xf9bd690a1b68637b, 0x3dfdce7aa3c673b1},
|
|
838
|
-
{0x9c1661a651213e2d, 0x06bea10ca65c084f}, {0xc31bfa0fe5698db8, 0x486e494fcff30a63},
|
|
839
|
-
{0xf3e2f893dec3f126, 0x5a89dba3c3efccfb}, {0x986ddb5c6b3a76b7, 0xf89629465a75e01d},
|
|
840
|
-
{0xbe89523386091465, 0xf6bbb397f1135824}, {0xee2ba6c0678b597f, 0x746aa07ded582e2d},
|
|
841
|
-
{0x94db483840b717ef, 0xa8c2a44eb4571cdd}, {0xba121a4650e4ddeb, 0x92f34d62616ce414},
|
|
842
|
-
{0xe896a0d7e51e1566, 0x77b020baf9c81d18}, {0x915e2486ef32cd60, 0x0ace1474dc1d122f},
|
|
843
|
-
{0xb5b5ada8aaff80b8, 0x0d819992132456bb}, {0xe3231912d5bf60e6, 0x10e1fff697ed6c6a},
|
|
844
|
-
{0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2}, {0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb3},
|
|
845
|
-
{0xddd0467c64bce4a0, 0xac7cb3f6d05ddbdf}, {0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96c},
|
|
846
|
-
{0xad4ab7112eb3929d, 0x86c16c98d2c953c7}, {0xd89d64d57a607744, 0xe871c7bf077ba8b8},
|
|
847
|
-
{0x87625f056c7c4a8b, 0x11471cd764ad4973}, {0xa93af6c6c79b5d2d, 0xd598e40d3dd89bd0},
|
|
848
|
-
{0xd389b47879823479, 0x4aff1d108d4ec2c4}, {0x843610cb4bf160cb, 0xcedf722a585139bb},
|
|
849
|
-
{0xa54394fe1eedb8fe, 0xc2974eb4ee658829}, {0xce947a3da6a9273e, 0x733d226229feea33},
|
|
850
|
-
{0x811ccc668829b887, 0x0806357d5a3f5260}, {0xa163ff802a3426a8, 0xca07c2dcb0cf26f8},
|
|
851
|
-
{0xc9bcff6034c13052, 0xfc89b393dd02f0b6}, {0xfc2c3f3841f17c67, 0xbbac2078d443ace3},
|
|
852
|
-
{0x9d9ba7832936edc0, 0xd54b944b84aa4c0e}, {0xc5029163f384a931, 0x0a9e795e65d4df12},
|
|
853
|
-
{0xf64335bcf065d37d, 0x4d4617b5ff4a16d6}, {0x99ea0196163fa42e, 0x504bced1bf8e4e46},
|
|
854
|
-
{0xc06481fb9bcf8d39, 0xe45ec2862f71e1d7}, {0xf07da27a82c37088, 0x5d767327bb4e5a4d},
|
|
855
|
-
{0x964e858c91ba2655, 0x3a6a07f8d510f870}, {0xbbe226efb628afea, 0x890489f70a55368c},
|
|
856
|
-
{0xeadab0aba3b2dbe5, 0x2b45ac74ccea842f}, {0x92c8ae6b464fc96f, 0x3b0b8bc90012929e},
|
|
857
|
-
{0xb77ada0617e3bbcb, 0x09ce6ebb40173745}, {0xe55990879ddcaabd, 0xcc420a6a101d0516},
|
|
858
|
-
{0x8f57fa54c2a9eab6, 0x9fa946824a12232e}, {0xb32df8e9f3546564, 0x47939822dc96abfa},
|
|
859
|
-
{0xdff9772470297ebd, 0x59787e2b93bc56f8}, {0x8bfbea76c619ef36, 0x57eb4edb3c55b65b},
|
|
860
|
-
{0xaefae51477a06b03, 0xede622920b6b23f2}, {0xdab99e59958885c4, 0xe95fab368e45ecee},
|
|
861
|
-
{0x88b402f7fd75539b, 0x11dbcb0218ebb415}, {0xaae103b5fcd2a881, 0xd652bdc29f26a11a},
|
|
862
|
-
{0xd59944a37c0752a2, 0x4be76d3346f04960}, {0x857fcae62d8493a5, 0x6f70a4400c562ddc},
|
|
863
|
-
{0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb953}, {0xd097ad07a71f26b2, 0x7e2000a41346a7a8},
|
|
864
|
-
{0x825ecc24c873782f, 0x8ed400668c0c28c9}, {0xa2f67f2dfa90563b, 0x728900802f0f32fb},
|
|
865
|
-
{0xcbb41ef979346bca, 0x4f2b40a03ad2ffba}, {0xfea126b7d78186bc, 0xe2f610c84987bfa9},
|
|
866
|
-
{0x9f24b832e6b0f436, 0x0dd9ca7d2df4d7ca}, {0xc6ede63fa05d3143, 0x91503d1c79720dbc},
|
|
867
|
-
{0xf8a95fcf88747d94, 0x75a44c6397ce912b}, {0x9b69dbe1b548ce7c, 0xc986afbe3ee11abb},
|
|
868
|
-
{0xc24452da229b021b, 0xfbe85badce996169}, {0xf2d56790ab41c2a2, 0xfae27299423fb9c4},
|
|
869
|
-
{0x97c560ba6b0919a5, 0xdccd879fc967d41b}, {0xbdb6b8e905cb600f, 0x5400e987bbc1c921},
|
|
870
|
-
{0xed246723473e3813, 0x290123e9aab23b69}, {0x9436c0760c86e30b, 0xf9a0b6720aaf6522},
|
|
871
|
-
{0xb94470938fa89bce, 0xf808e40e8d5b3e6a}, {0xe7958cb87392c2c2, 0xb60b1d1230b20e05},
|
|
872
|
-
{0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c3}, {0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af4},
|
|
873
|
-
{0xe2280b6c20dd5232, 0x25c6da63c38de1b1}, {0x8d590723948a535f, 0x579c487e5a38ad0f},
|
|
874
|
-
{0xb0af48ec79ace837, 0x2d835a9df0c6d852}, {0xdcdb1b2798182244, 0xf8e431456cf88e66},
|
|
875
|
-
{0x8a08f0f8bf0f156b, 0x1b8e9ecb641b5900}, {0xac8b2d36eed2dac5, 0xe272467e3d222f40},
|
|
876
|
-
{0xd7adf884aa879177, 0x5b0ed81dcc6abb10}, {0x86ccbb52ea94baea, 0x98e947129fc2b4ea},
|
|
877
|
-
{0xa87fea27a539e9a5, 0x3f2398d747b36225}, {0xd29fe4b18e88640e, 0x8eec7f0d19a03aae},
|
|
878
|
-
{0x83a3eeeef9153e89, 0x1953cf68300424ad}, {0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd8},
|
|
879
|
-
{0xcdb02555653131b6, 0x3792f412cb06794e}, {0x808e17555f3ebf11, 0xe2bbd88bbee40bd1},
|
|
880
|
-
{0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec5}, {0xc8de047564d20a8b, 0xf245825a5a445276},
|
|
881
|
-
{0xfb158592be068d2e, 0xeed6e2f0f0d56713}, {0x9ced737bb6c4183d, 0x55464dd69685606c},
|
|
882
|
-
{0xc428d05aa4751e4c, 0xaa97e14c3c26b887}, {0xf53304714d9265df, 0xd53dd99f4b3066a9},
|
|
883
|
-
{0x993fe2c6d07b7fab, 0xe546a8038efe402a}, {0xbf8fdb78849a5f96, 0xde98520472bdd034},
|
|
884
|
-
{0xef73d256a5c0f77c, 0x963e66858f6d4441}, {0x95a8637627989aad, 0xdde7001379a44aa9},
|
|
885
|
-
{0xbb127c53b17ec159, 0x5560c018580d5d53}, {0xe9d71b689dde71af, 0xaab8f01e6e10b4a7},
|
|
886
|
-
{0x9226712162ab070d, 0xcab3961304ca70e9}, {0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d23},
|
|
887
|
-
{0xe45c10c42a2b3b05, 0x8cb89a7db77c506b}, {0x8eb98a7a9a5b04e3, 0x77f3608e92adb243},
|
|
888
|
-
{0xb267ed1940f1c61c, 0x55f038b237591ed4}, {0xdf01e85f912e37a3, 0x6b6c46dec52f6689},
|
|
889
|
-
{0x8b61313bbabce2c6, 0x2323ac4b3b3da016}, {0xae397d8aa96c1b77, 0xabec975e0a0d081b},
|
|
890
|
-
{0xd9c7dced53c72255, 0x96e7bd358c904a22}, {0x881cea14545c7575, 0x7e50d64177da2e55},
|
|
891
|
-
{0xaa242499697392d2, 0xdde50bd1d5d0b9ea}, {0xd4ad2dbfc3d07787, 0x955e4ec64b44e865},
|
|
892
|
-
{0x84ec3c97da624ab4, 0xbd5af13bef0b113f}, {0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58f},
|
|
893
|
-
{0xcfb11ead453994ba, 0x67de18eda5814af3}, {0x81ceb32c4b43fcf4, 0x80eacf948770ced8},
|
|
894
|
-
{0xa2425ff75e14fc31, 0xa1258379a94d028e}, {0xcad2f7f5359a3b3e, 0x096ee45813a04331},
|
|
895
|
-
{0xfd87b5f28300ca0d, 0x8bca9d6e188853fd}, {0x9e74d1b791e07e48, 0x775ea264cf55347e},
|
|
896
|
-
{0xc612062576589dda, 0x95364afe032a819e}, {0xf79687aed3eec551, 0x3a83ddbd83f52205},
|
|
897
|
-
{0x9abe14cd44753b52, 0xc4926a9672793543}, {0xc16d9a0095928a27, 0x75b7053c0f178294},
|
|
898
|
-
{0xf1c90080baf72cb1, 0x5324c68b12dd6339}, {0x971da05074da7bee, 0xd3f6fc16ebca5e04},
|
|
899
|
-
{0xbce5086492111aea, 0x88f4bb1ca6bcf585}, {0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6},
|
|
900
|
-
{0x9392ee8e921d5d07, 0x3aff322e62439fd0}, {0xb877aa3236a4b449, 0x09befeb9fad487c3},
|
|
901
|
-
{0xe69594bec44de15b, 0x4c2ebe687989a9b4}, {0x901d7cf73ab0acd9, 0x0f9d37014bf60a11},
|
|
902
|
-
{0xb424dc35095cd80f, 0x538484c19ef38c95}, {0xe12e13424bb40e13, 0x2865a5f206b06fba},
|
|
903
|
-
{0x8cbccc096f5088cb, 0xf93f87b7442e45d4}, {0xafebff0bcb24aafe, 0xf78f69a51539d749},
|
|
904
|
-
{0xdbe6fecebdedd5be, 0xb573440e5a884d1c}, {0x89705f4136b4a597, 0x31680a88f8953031},
|
|
905
|
-
{0xabcc77118461cefc, 0xfdc20d2b36ba7c3e}, {0xd6bf94d5e57a42bc, 0x3d32907604691b4d},
|
|
906
|
-
{0x8637bd05af6c69b5, 0xa63f9a49c2c1b110}, {0xa7c5ac471b478423, 0x0fcf80dc33721d54},
|
|
907
|
-
{0xd1b71758e219652b, 0xd3c36113404ea4a9}, {0x83126e978d4fdf3b, 0x645a1cac083126ea},
|
|
908
|
-
{0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4}, {0xcccccccccccccccc, 0xcccccccccccccccd},
|
|
909
|
-
{0x8000000000000000, 0x0000000000000000}, {0xa000000000000000, 0x0000000000000000},
|
|
910
|
-
{0xc800000000000000, 0x0000000000000000}, {0xfa00000000000000, 0x0000000000000000},
|
|
911
|
-
{0x9c40000000000000, 0x0000000000000000}, {0xc350000000000000, 0x0000000000000000},
|
|
912
|
-
{0xf424000000000000, 0x0000000000000000}, {0x9896800000000000, 0x0000000000000000},
|
|
913
|
-
{0xbebc200000000000, 0x0000000000000000}, {0xee6b280000000000, 0x0000000000000000},
|
|
914
|
-
{0x9502f90000000000, 0x0000000000000000}, {0xba43b74000000000, 0x0000000000000000},
|
|
915
|
-
{0xe8d4a51000000000, 0x0000000000000000}, {0x9184e72a00000000, 0x0000000000000000},
|
|
916
|
-
{0xb5e620f480000000, 0x0000000000000000}, {0xe35fa931a0000000, 0x0000000000000000},
|
|
917
|
-
{0x8e1bc9bf04000000, 0x0000000000000000}, {0xb1a2bc2ec5000000, 0x0000000000000000},
|
|
918
|
-
{0xde0b6b3a76400000, 0x0000000000000000}, {0x8ac7230489e80000, 0x0000000000000000},
|
|
919
|
-
{0xad78ebc5ac620000, 0x0000000000000000}, {0xd8d726b7177a8000, 0x0000000000000000},
|
|
920
|
-
{0x878678326eac9000, 0x0000000000000000}, {0xa968163f0a57b400, 0x0000000000000000},
|
|
921
|
-
{0xd3c21bcecceda100, 0x0000000000000000}, {0x84595161401484a0, 0x0000000000000000},
|
|
922
|
-
{0xa56fa5b99019a5c8, 0x0000000000000000}, {0xcecb8f27f4200f3a, 0x0000000000000000},
|
|
923
|
-
{0x813f3978f8940984, 0x4000000000000000}, {0xa18f07d736b90be5, 0x5000000000000000},
|
|
924
|
-
{0xc9f2c9cd04674ede, 0xa400000000000000}, {0xfc6f7c4045812296, 0x4d00000000000000},
|
|
925
|
-
{0x9dc5ada82b70b59d, 0xf020000000000000}, {0xc5371912364ce305, 0x6c28000000000000},
|
|
926
|
-
{0xf684df56c3e01bc6, 0xc732000000000000}, {0x9a130b963a6c115c, 0x3c7f400000000000},
|
|
927
|
-
{0xc097ce7bc90715b3, 0x4b9f100000000000}, {0xf0bdc21abb48db20, 0x1e86d40000000000},
|
|
928
|
-
{0x96769950b50d88f4, 0x1314448000000000}, {0xbc143fa4e250eb31, 0x17d955a000000000},
|
|
929
|
-
{0xeb194f8e1ae525fd, 0x5dcfab0800000000}, {0x92efd1b8d0cf37be, 0x5aa1cae500000000},
|
|
930
|
-
{0xb7abc627050305ad, 0xf14a3d9e40000000}, {0xe596b7b0c643c719, 0x6d9ccd05d0000000},
|
|
931
|
-
{0x8f7e32ce7bea5c6f, 0xe4820023a2000000}, {0xb35dbf821ae4f38b, 0xdda2802c8a800000},
|
|
932
|
-
{0xe0352f62a19e306e, 0xd50b2037ad200000}, {0x8c213d9da502de45, 0x4526f422cc340000},
|
|
933
|
-
{0xaf298d050e4395d6, 0x9670b12b7f410000}, {0xdaf3f04651d47b4c, 0x3c0cdd765f114000},
|
|
934
|
-
{0x88d8762bf324cd0f, 0xa5880a69fb6ac800}, {0xab0e93b6efee0053, 0x8eea0d047a457a00},
|
|
935
|
-
{0xd5d238a4abe98068, 0x72a4904598d6d880}, {0x85a36366eb71f041, 0x47a6da2b7f864750},
|
|
936
|
-
{0xa70c3c40a64e6c51, 0x999090b65f67d924}, {0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d},
|
|
937
|
-
{0x82818f1281ed449f, 0xbff8f10e7a8921a5}, {0xa321f2d7226895c7, 0xaff72d52192b6a0e},
|
|
938
|
-
{0xcbea6f8ceb02bb39, 0x9bf4f8a69f764491}, {0xfee50b7025c36a08, 0x02f236d04753d5b5},
|
|
939
|
-
{0x9f4f2726179a2245, 0x01d762422c946591}, {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef6},
|
|
940
|
-
{0xf8ebad2b84e0d58b, 0xd2e0898765a7deb3}, {0x9b934c3b330c8577, 0x63cc55f49f88eb30},
|
|
941
|
-
{0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fc}, {0xf316271c7fc3908a, 0x8bef464e3945ef7b},
|
|
942
|
-
{0x97edd871cfda3a56, 0x97758bf0e3cbb5ad}, {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea318},
|
|
943
|
-
{0xed63a231d4c4fb27, 0x4ca7aaa863ee4bde}, {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6b},
|
|
944
|
-
{0xb975d6b6ee39e436, 0xb3e2fd538e122b45}, {0xe7d34c64a9c85d44, 0x60dbbca87196b617},
|
|
945
|
-
{0x90e40fbeea1d3a4a, 0xbc8955e946fe31ce}, {0xb51d13aea4a488dd, 0x6babab6398bdbe42},
|
|
946
|
-
{0xe264589a4dcdab14, 0xc696963c7eed2dd2}, {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca3},
|
|
947
|
-
{0xb0de65388cc8ada8, 0x3b25a55f43294bcc}, {0xdd15fe86affad912, 0x49ef0eb713f39ebf},
|
|
948
|
-
{0x8a2dbf142dfcc7ab, 0x6e3569326c784338}, {0xacb92ed9397bf996, 0x49c2c37f07965405},
|
|
949
|
-
{0xd7e77a8f87daf7fb, 0xdc33745ec97be907}, {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a4},
|
|
950
|
-
{0xa8acd7c0222311bc, 0xc40832ea0d68ce0d}, {0xd2d80db02aabd62b, 0xf50a3fa490c30191},
|
|
951
|
-
{0x83c7088e1aab65db, 0x792667c6da79e0fb}, {0xa4b8cab1a1563f52, 0x577001b891185939},
|
|
952
|
-
{0xcde6fd5e09abcf26, 0xed4c0226b55e6f87}, {0x80b05e5ac60b6178, 0x544f8158315b05b5},
|
|
953
|
-
{0xa0dc75f1778e39d6, 0x696361ae3db1c722}, {0xc913936dd571c84c, 0x03bc3a19cd1e38ea},
|
|
954
|
-
{0xfb5878494ace3a5f, 0x04ab48a04065c724}, {0x9d174b2dcec0e47b, 0x62eb0d64283f9c77},
|
|
955
|
-
{0xc45d1df942711d9a, 0x3ba5d0bd324f8395}, {0xf5746577930d6500, 0xca8f44ec7ee3647a},
|
|
956
|
-
{0x9968bf6abbe85f20, 0x7e998b13cf4e1ecc}, {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67f},
|
|
957
|
-
{0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101f}, {0x95d04aee3b80ece5, 0xbba1f1d158724a13},
|
|
958
|
-
{0xbb445da9ca61281f, 0x2a8a6e45ae8edc98}, {0xea1575143cf97226, 0xf52d09d71a3293be},
|
|
959
|
-
{0x924d692ca61be758, 0x593c2626705f9c57}, {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836d},
|
|
960
|
-
{0xe498f455c38b997a, 0x0b6dfb9c0f956448}, {0x8edf98b59a373fec, 0x4724bd4189bd5ead},
|
|
961
|
-
{0xb2977ee300c50fe7, 0x58edec91ec2cb658}, {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ee},
|
|
962
|
-
{0x8b865b215899f46c, 0xbd79e0d20082ee75}, {0xae67f1e9aec07187, 0xecd8590680a3aa12},
|
|
963
|
-
{0xda01ee641a708de9, 0xe80e6f4820cc9496}, {0x884134fe908658b2, 0x3109058d147fdcde},
|
|
964
|
-
{0xaa51823e34a7eede, 0xbd4b46f0599fd416}, {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91b},
|
|
965
|
-
{0x850fadc09923329e, 0x03e2cf6bc604ddb1}, {0xa6539930bf6bff45, 0x84db8346b786151d},
|
|
966
|
-
{0xcfe87f7cef46ff16, 0xe612641865679a64}, {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07f},
|
|
967
|
-
{0xa26da3999aef7749, 0xe3be5e330f38f09e}, {0xcb090c8001ab551c, 0x5cadf5bfd3072cc6},
|
|
968
|
-
{0xfdcb4fa002162a63, 0x73d9732fc7c8f7f7}, {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afb},
|
|
969
|
-
{0xc646d63501a1511d, 0xb281e1fd541501b9}, {0xf7d88bc24209a565, 0x1f225a7ca91a4227},
|
|
970
|
-
{0x9ae757596946075f, 0x3375788de9b06959}, {0xc1a12d2fc3978937, 0x0052d6b1641c83af},
|
|
971
|
-
{0xf209787bb47d6b84, 0xc0678c5dbd23a49b}, {0x9745eb4d50ce6332, 0xf840b7ba963646e1},
|
|
972
|
-
{0xbd176620a501fbff, 0xb650e5a93bc3d899}, {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebf},
|
|
973
|
-
{0x93ba47c980e98cdf, 0xc66f336c36b10138}, {0xb8a8d9bbe123f017, 0xb80b0047445d4185},
|
|
974
|
-
{0xe6d3102ad96cec1d, 0xa60dc059157491e6}, {0x9043ea1ac7e41392, 0x87c89837ad68db30},
|
|
975
|
-
{0xb454e4a179dd1877, 0x29babe4598c311fc}, {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67b},
|
|
976
|
-
{0x8ce2529e2734bb1d, 0x1899e4a65f58660d}, {0xb01ae745b101e9e4, 0x5ec05dcff72e7f90},
|
|
977
|
-
{0xdc21a1171d42645d, 0x76707543f4fa1f74}, {0x899504ae72497eba, 0x6a06494a791c53a9},
|
|
978
|
-
{0xabfa45da0edbde69, 0x0487db9d17636893}, {0xd6f8d7509292d603, 0x45a9d2845d3c42b7},
|
|
979
|
-
{0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3}, {0xa7f26836f282b732, 0x8e6cac7768d7141f},
|
|
980
|
-
{0xd1ef0244af2364ff, 0x3207d795430cd927}, {0x8335616aed761f1f, 0x7f44e6bd49e807b9},
|
|
981
|
-
{0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a7}, {0xcd036837130890a1, 0x36dba887c37a8c10},
|
|
982
|
-
{0x802221226be55a64, 0xc2494954da2c978a}, {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6d},
|
|
983
|
-
{0xc83553c5c8965d3d, 0x6f92829494e5acc8}, {0xfa42a8b73abbf48c, 0xcb772339ba1f17fa},
|
|
984
|
-
{0x9c69a97284b578d7, 0xff2a760414536efc}, {0xc38413cf25e2d70d, 0xfef5138519684abb},
|
|
985
|
-
{0xf46518c2ef5b8cd1, 0x7eb258665fc25d6a}, {0x98bf2f79d5993802, 0xef2f773ffbd97a62},
|
|
986
|
-
{0xbeeefb584aff8603, 0xaafb550ffacfd8fb}, {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf39},
|
|
987
|
-
{0x952ab45cfa97a0b2, 0xdd945a747bf26184}, {0xba756174393d88df, 0x94f971119aeef9e5},
|
|
988
|
-
{0xe912b9d1478ceb17, 0x7a37cd5601aab85e}, {0x91abb422ccb812ee, 0xac62e055c10ab33b},
|
|
989
|
-
{0xb616a12b7fe617aa, 0x577b986b314d600a}, {0xe39c49765fdf9d94, 0xed5a7e85fda0b80c},
|
|
990
|
-
{0x8e41ade9fbebc27d, 0x14588f13be847308}, {0xb1d219647ae6b31c, 0x596eb2d8ae258fc9},
|
|
991
|
-
{0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bc}, {0x8aec23d680043bee, 0x25de7bb9480d5855},
|
|
992
|
-
{0xada72ccc20054ae9, 0xaf561aa79a10ae6b}, {0xd910f7ff28069da4, 0x1b2ba1518094da05},
|
|
993
|
-
{0x87aa9aff79042286, 0x90fb44d2f05d0843}, {0xa99541bf57452b28, 0x353a1607ac744a54},
|
|
994
|
-
{0xd3fa922f2d1675f2, 0x42889b8997915ce9}, {0x847c9b5d7c2e09b7, 0x69956135febada12},
|
|
995
|
-
{0xa59bc234db398c25, 0x43fab9837e699096}, {0xcf02b2c21207ef2e, 0x94f967e45e03f4bc},
|
|
996
|
-
{0x8161afb94b44f57d, 0x1d1be0eebac278f6}, {0xa1ba1ba79e1632dc, 0x6462d92a69731733},
|
|
997
|
-
{0xca28a291859bbf93, 0x7d7b8f7503cfdcff}, {0xfcb2cb35e702af78, 0x5cda735244c3d43f},
|
|
998
|
-
{0x9defbf01b061adab, 0x3a0888136afa64a8}, {0xc56baec21c7a1916, 0x088aaa1845b8fdd1},
|
|
999
|
-
{0xf6c69a72a3989f5b, 0x8aad549e57273d46}, {0x9a3c2087a63f6399, 0x36ac54e2f678864c},
|
|
1000
|
-
{0xc0cb28a98fcf3c7f, 0x84576a1bb416a7de}, {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d6},
|
|
1001
|
-
{0x969eb7c47859e743, 0x9f644ae5a4b1b326}, {0xbc4665b596706114, 0x873d5d9f0dde1fef},
|
|
1002
|
-
{0xeb57ff22fc0c7959, 0xa90cb506d155a7eb}, {0x9316ff75dd87cbd8, 0x09a7f12442d588f3},
|
|
1003
|
-
{0xb7dcbf5354e9bece, 0x0c11ed6d538aeb30}, {0xe5d3ef282a242e81, 0x8f1668c8a86da5fb},
|
|
1004
|
-
{0x8fa475791a569d10, 0xf96e017d694487bd}, {0xb38d92d760ec4455, 0x37c981dcc395a9ad},
|
|
1005
|
-
{0xe070f78d3927556a, 0x85bbe253f47b1418}, {0x8c469ab843b89562, 0x93956d7478ccec8f},
|
|
1006
|
-
{0xaf58416654a6babb, 0x387ac8d1970027b3}, {0xdb2e51bfe9d0696a, 0x06997b05fcc0319f},
|
|
1007
|
-
{0x88fcf317f22241e2, 0x441fece3bdf81f04}, {0xab3c2fddeeaad25a, 0xd527e81cad7626c4},
|
|
1008
|
-
{0xd60b3bd56a5586f1, 0x8a71e223d8d3b075}, {0x85c7056562757456, 0xf6872d5667844e4a},
|
|
1009
|
-
{0xa738c6bebb12d16c, 0xb428f8ac016561dc}, {0xd106f86e69d785c7, 0xe13336d701beba53},
|
|
1010
|
-
{0x82a45b450226b39c, 0xecc0024661173474}, {0xa34d721642b06084, 0x27f002d7f95d0191},
|
|
1011
|
-
{0xcc20ce9bd35c78a5, 0x31ec038df7b441f5}, {0xff290242c83396ce, 0x7e67047175a15272},
|
|
1012
|
-
{0x9f79a169bd203e41, 0x0f0062c6e984d387}, {0xc75809c42c684dd1, 0x52c07b78a3e60869},
|
|
1013
|
-
{0xf92e0c3537826145, 0xa7709a56ccdf8a83}, {0x9bbcc7a142b17ccb, 0x88a66076400bb692},
|
|
1014
|
-
{0xc2abf989935ddbfe, 0x6acff893d00ea436}, {0xf356f7ebf83552fe, 0x0583f6b8c4124d44},
|
|
1015
|
-
{0x98165af37b2153de, 0xc3727a337a8b704b}, {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5d},
|
|
1016
|
-
{0xeda2ee1c7064130c, 0x1162def06f79df74}, {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba9},
|
|
1017
|
-
{0xb9a74a0637ce2ee1, 0x6d953e2bd7173693}, {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0438},
|
|
1018
|
-
{0x910ab1d4db9914a0, 0x1d9c9892400a22a3}, {0xb54d5e4a127f59c8, 0x2503beb6d00cab4c},
|
|
1019
|
-
{0xe2a0b5dc971f303a, 0x2e44ae64840fd61e}, {0x8da471a9de737e24, 0x5ceaecfed289e5d3},
|
|
1020
|
-
{0xb10d8e1456105dad, 0x7425a83e872c5f48}, {0xdd50f1996b947518, 0xd12f124e28f7771a},
|
|
1021
|
-
{0x8a5296ffe33cc92f, 0x82bd6b70d99aaa70}, {0xace73cbfdc0bfb7b, 0x636cc64d1001550c},
|
|
1022
|
-
{0xd8210befd30efa5a, 0x3c47f7e05401aa4f}, {0x8714a775e3e95c78, 0x65acfaec34810a72},
|
|
1023
|
-
{0xa8d9d1535ce3b396, 0x7f1839a741a14d0e}, {0xd31045a8341ca07c, 0x1ede48111209a051},
|
|
1024
|
-
{0x83ea2b892091e44d, 0x934aed0aab460433}, {0xa4e4b66b68b65d60, 0xf81da84d56178540},
|
|
1025
|
-
{0xce1de40642e3f4b9, 0x36251260ab9d668f}, {0x80d2ae83e9ce78f3, 0xc1d72b7c6b42601a},
|
|
1026
|
-
{0xa1075a24e4421730, 0xb24cf65b8612f820}, {0xc94930ae1d529cfc, 0xdee033f26797b628},
|
|
1027
|
-
{0xfb9b7cd9a4a7443c, 0x169840ef017da3b2}, {0x9d412e0806e88aa5, 0x8e1f289560ee864f},
|
|
1028
|
-
{0xc491798a08a2ad4e, 0xf1a6f2bab92a27e3}, {0xf5b5d7ec8acb58a2, 0xae10af696774b1dc},
|
|
1029
|
-
{0x9991a6f3d6bf1765, 0xacca6da1e0a8ef2a}, {0xbff610b0cc6edd3f, 0x17fd090a58d32af4},
|
|
1030
|
-
{0xeff394dcff8a948e, 0xddfc4b4cef07f5b1}, {0x95f83d0a1fb69cd9, 0x4abdaf101564f98f},
|
|
1031
|
-
{0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f2}, {0xea53df5fd18d5513, 0x84c86189216dc5ee},
|
|
1032
|
-
{0x92746b9be2f8552c, 0x32fd3cf5b4e49bb5}, {0xb7118682dbb66a77, 0x3fbc8c33221dc2a2},
|
|
1033
|
-
{0xe4d5e82392a40515, 0x0fabaf3feaa5334b}, {0x8f05b1163ba6832d, 0x29cb4d87f2a7400f},
|
|
1034
|
-
{0xb2c71d5bca9023f8, 0x743e20e9ef511013}, {0xdf78e4b2bd342cf6, 0x914da9246b255417},
|
|
1035
|
-
{0x8bab8eefb6409c1a, 0x1ad089b6c2f7548f}, {0xae9672aba3d0c320, 0xa184ac2473b529b2},
|
|
1036
|
-
{0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741f}, {0x8865899617fb1871, 0x7e2fa67c7a658893},
|
|
1037
|
-
{0xaa7eebfb9df9de8d, 0xddbb901b98feeab8}, {0xd51ea6fa85785631, 0x552a74227f3ea566},
|
|
1038
|
-
{0x8533285c936b35de, 0xd53a88958f872760}, {0xa67ff273b8460356, 0x8a892abaf368f138},
|
|
1039
|
-
{0xd01fef10a657842c, 0x2d2b7569b0432d86}, {0x8213f56a67f6b29b, 0x9c3b29620e29fc74},
|
|
1040
|
-
{0xa298f2c501f45f42, 0x8349f3ba91b47b90}, {0xcb3f2f7642717713, 0x241c70a936219a74},
|
|
1041
|
-
{0xfe0efb53d30dd4d7, 0xed238cd383aa0111}, {0x9ec95d1463e8a506, 0xf4363804324a40ab},
|
|
1042
|
-
{0xc67bb4597ce2ce48, 0xb143c6053edcd0d6}, {0xf81aa16fdc1b81da, 0xdd94b7868e94050b},
|
|
1043
|
-
{0x9b10a4e5e9913128, 0xca7cf2b4191c8327}, {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f1},
|
|
1044
|
-
{0xf24a01a73cf2dccf, 0xbc633b39673c8ced}, {0x976e41088617ca01, 0xd5be0503e085d814},
|
|
1045
|
-
{0xbd49d14aa79dbc82, 0x4b2d8644d8a74e19}, {0xec9c459d51852ba2, 0xddf8e7d60ed1219f},
|
|
1046
|
-
{0x93e1ab8252f33b45, 0xcabb90e5c942b504}, {0xb8da1662e7b00a17, 0x3d6a751f3b936244},
|
|
1047
|
-
{0xe7109bfba19c0c9d, 0x0cc512670a783ad5}, {0x906a617d450187e2, 0x27fb2b80668b24c6},
|
|
1048
|
-
{0xb484f9dc9641e9da, 0xb1f9f660802dedf7}, {0xe1a63853bbd26451, 0x5e7873f8a0396974},
|
|
1049
|
-
{0x8d07e33455637eb2, 0xdb0b487b6423e1e9}, {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda63},
|
|
1050
|
-
{0xdc5c5301c56b75f7, 0x7641a140cc7810fc}, {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9e},
|
|
1051
|
-
{0xac2820d9623bf429, 0x546345fa9fbdcd45}, {0xd732290fbacaf133, 0xa97c177947ad4096},
|
|
1052
|
-
{0x867f59a9d4bed6c0, 0x49ed8eabcccc485e}, {0xa81f301449ee8c70, 0x5c68f256bfff5a75},
|
|
1053
|
-
{0xd226fc195c6a2f8c, 0x73832eec6fff3112}, {0x83585d8fd9c25db7, 0xc831fd53c5ff7eac},
|
|
1054
|
-
{0xa42e74f3d032f525, 0xba3e7ca8b77f5e56}, {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35ec},
|
|
1055
|
-
{0x80444b5e7aa7cf85, 0x7980d163cf5b81b4}, {0xa0555e361951c366, 0xd7e105bcc3326220},
|
|
1056
|
-
{0xc86ab5c39fa63440, 0x8dd9472bf3fefaa8}, {0xfa856334878fc150, 0xb14f98f6f0feb952},
|
|
1057
|
-
{0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d4}, {0xc3b8358109e84f07, 0x0a862f80ec4700c9},
|
|
1058
|
-
{0xf4a642e14c6262c8, 0xcd27bb612758c0fb}, {0x98e7e9cccfbd7dbd, 0x8038d51cb897789d},
|
|
1059
|
-
{0xbf21e44003acdd2c, 0xe0470a63e6bd56c4}, {0xeeea5d5004981478, 0x1858ccfce06cac75},
|
|
1060
|
-
{0x95527a5202df0ccb, 0x0f37801e0c43ebc9}, {0xbaa718e68396cffd, 0xd30560258f54e6bb},
|
|
1061
|
-
{0xe950df20247c83fd, 0x47c6b82ef32a206a}, {0x91d28b7416cdd27e, 0x4cdc331d57fa5442},
|
|
1062
|
-
{0xb6472e511c81471d, 0xe0133fe4adf8e953}, {0xe3d8f9e563a198e5, 0x58180fddd97723a7},
|
|
1063
|
-
{0x8e679c2f5e44ff8f, 0x570f09eaa7ea7649}, {0xb201833b35d63f73, 0x2cd2cc6551e513db},
|
|
1064
|
-
{0xde81e40a034bcf4f, 0xf8077f7ea65e58d2}, {0x8b112e86420f6191, 0xfb04afaf27faf783},
|
|
1065
|
-
{0xadd57a27d29339f6, 0x79c5db9af1f9b564}, {0xd94ad8b1c7380874, 0x18375281ae7822bd},
|
|
1066
|
-
{0x87cec76f1c830548, 0x8f2293910d0b15b6}, {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb23},
|
|
1067
|
-
{0xd433179d9c8cb841, 0x5fa60692a46151ec}, {0x849feec281d7f328, 0xdbc7c41ba6bcd334},
|
|
1068
|
-
{0xa5c7ea73224deff3, 0x12b9b522906c0801}, {0xcf39e50feae16bef, 0xd768226b34870a01},
|
|
1069
|
-
{0x81842f29f2cce375, 0xe6a1158300d46641}, {0xa1e53af46f801c53, 0x60495ae3c1097fd1},
|
|
1070
|
-
{0xca5e89b18b602368, 0x385bb19cb14bdfc5}, {0xfcf62c1dee382c42, 0x46729e03dd9ed7b6},
|
|
1071
|
-
{0x9e19db92b4e31ba9, 0x6c07a2c26a8346d2}, {0xc5a05277621be293, 0xc7098b7305241886},
|
|
1072
|
-
{0xf70867153aa2db38, 0xb8cbee4fc66d1ea8}};
|
|
1073
|
-
};
|
|
1074
|
-
|
|
1075
|
-
// Compressed cache for double
|
|
1076
|
-
struct compressed_cache_detail {
|
|
1077
|
-
static constexpr int compression_ratio = 27;
|
|
1078
|
-
static constexpr std::size_t compressed_table_size =
|
|
1079
|
-
(cache_holder<ieee754_binary64>::max_k - cache_holder<ieee754_binary64>::min_k +
|
|
1080
|
-
compression_ratio) /
|
|
1081
|
-
compression_ratio;
|
|
1082
|
-
|
|
1083
|
-
struct cache_holder_t {
|
|
1084
|
-
wuint::uint128 table[compressed_table_size];
|
|
1085
|
-
};
|
|
1086
|
-
static constexpr cache_holder_t cache = [] {
|
|
1087
|
-
cache_holder_t res{};
|
|
1088
|
-
for (std::size_t i = 0; i < compressed_table_size; ++i) {
|
|
1089
|
-
res.table[i] = cache_holder<ieee754_binary64>::cache[i * compression_ratio];
|
|
1090
|
-
}
|
|
1091
|
-
return res;
|
|
1092
|
-
}();
|
|
1093
|
-
|
|
1094
|
-
struct pow5_holder_t {
|
|
1095
|
-
std::uint64_t table[compression_ratio];
|
|
1096
|
-
};
|
|
1097
|
-
static constexpr pow5_holder_t pow5 = [] {
|
|
1098
|
-
pow5_holder_t res{};
|
|
1099
|
-
std::uint64_t p = 1;
|
|
1100
|
-
for (std::size_t i = 0; i < compression_ratio; ++i) {
|
|
1101
|
-
res.table[i] = p;
|
|
1102
|
-
p *= 5;
|
|
1103
|
-
}
|
|
1104
|
-
return res;
|
|
1105
|
-
}();
|
|
1106
|
-
};
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
1111
|
-
// Policies.
|
|
1112
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
1113
|
-
|
|
1114
|
-
namespace detail {
|
|
1115
|
-
// Forward declare the implementation class.
|
|
1116
|
-
template <class Float, class FloatTraits = default_float_traits<Float>>
|
|
1117
|
-
struct impl;
|
|
1118
|
-
|
|
1119
|
-
namespace policy_impl {
|
|
1120
|
-
// Sign policies.
|
|
1121
|
-
namespace sign {
|
|
1122
|
-
struct base {};
|
|
1123
|
-
|
|
1124
|
-
struct ignore : base {
|
|
1125
|
-
using sign_policy = ignore;
|
|
1126
|
-
static constexpr bool return_has_sign = false;
|
|
1127
|
-
|
|
1128
|
-
template <class SignedSignificandBits, class ReturnType>
|
|
1129
|
-
static constexpr void handle_sign(SignedSignificandBits, ReturnType&) noexcept {
|
|
1130
|
-
}
|
|
1131
|
-
};
|
|
1132
|
-
|
|
1133
|
-
struct return_sign : base {
|
|
1134
|
-
using sign_policy = return_sign;
|
|
1135
|
-
static constexpr bool return_has_sign = true;
|
|
1136
|
-
|
|
1137
|
-
template <class SignedSignificandBits, class ReturnType>
|
|
1138
|
-
static constexpr void handle_sign(SignedSignificandBits s,
|
|
1139
|
-
ReturnType& r) noexcept {
|
|
1140
|
-
r.is_negative = s.is_negative();
|
|
1141
|
-
}
|
|
1142
|
-
};
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
// Trailing zero policies.
|
|
1146
|
-
namespace trailing_zero {
|
|
1147
|
-
struct base {};
|
|
1148
|
-
|
|
1149
|
-
struct ignore : base {
|
|
1150
|
-
using trailing_zero_policy = ignore;
|
|
1151
|
-
static constexpr bool report_trailing_zeros = false;
|
|
1152
|
-
|
|
1153
|
-
template <class Impl, class ReturnType>
|
|
1154
|
-
static constexpr void on_trailing_zeros(ReturnType&) noexcept {}
|
|
1155
|
-
|
|
1156
|
-
template <class Impl, class ReturnType>
|
|
1157
|
-
static constexpr void no_trailing_zeros(ReturnType&) noexcept {}
|
|
1158
|
-
};
|
|
1159
|
-
|
|
1160
|
-
struct remove : base {
|
|
1161
|
-
using trailing_zero_policy = remove;
|
|
1162
|
-
static constexpr bool report_trailing_zeros = false;
|
|
1163
|
-
|
|
1164
|
-
template <class Impl, class ReturnType>
|
|
1165
|
-
JKJ_FORCEINLINE static constexpr void
|
|
1166
|
-
on_trailing_zeros(ReturnType& r) noexcept {
|
|
1167
|
-
r.exponent += Impl::remove_trailing_zeros(r.significand);
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
template <class Impl, class ReturnType>
|
|
1171
|
-
static constexpr void no_trailing_zeros(ReturnType&) noexcept {}
|
|
1172
|
-
};
|
|
1173
|
-
|
|
1174
|
-
struct report : base {
|
|
1175
|
-
using trailing_zero_policy = report;
|
|
1176
|
-
static constexpr bool report_trailing_zeros = true;
|
|
1177
|
-
|
|
1178
|
-
template <class Impl, class ReturnType>
|
|
1179
|
-
static constexpr void on_trailing_zeros(ReturnType& r) noexcept {
|
|
1180
|
-
r.may_have_trailing_zeros = true;
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
template <class Impl, class ReturnType>
|
|
1184
|
-
static constexpr void no_trailing_zeros(ReturnType& r) noexcept {
|
|
1185
|
-
r.may_have_trailing_zeros = false;
|
|
1186
|
-
}
|
|
1187
|
-
};
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
// Decimal-to-binary rounding mode policies.
|
|
1191
|
-
namespace decimal_to_binary_rounding {
|
|
1192
|
-
struct base {};
|
|
1193
|
-
|
|
1194
|
-
enum class tag_t { to_nearest, left_closed_directed, right_closed_directed };
|
|
1195
|
-
namespace interval_type {
|
|
1196
|
-
struct symmetric_boundary {
|
|
1197
|
-
static constexpr bool is_symmetric = true;
|
|
1198
|
-
bool is_closed;
|
|
1199
|
-
constexpr bool include_left_endpoint() const noexcept { return is_closed; }
|
|
1200
|
-
constexpr bool include_right_endpoint() const noexcept { return is_closed; }
|
|
1201
|
-
};
|
|
1202
|
-
struct asymmetric_boundary {
|
|
1203
|
-
static constexpr bool is_symmetric = false;
|
|
1204
|
-
bool is_left_closed;
|
|
1205
|
-
constexpr bool include_left_endpoint() const noexcept {
|
|
1206
|
-
return is_left_closed;
|
|
1207
|
-
}
|
|
1208
|
-
constexpr bool include_right_endpoint() const noexcept {
|
|
1209
|
-
return !is_left_closed;
|
|
1210
|
-
}
|
|
1211
|
-
};
|
|
1212
|
-
struct closed {
|
|
1213
|
-
static constexpr bool is_symmetric = true;
|
|
1214
|
-
static constexpr bool include_left_endpoint() noexcept { return true; }
|
|
1215
|
-
static constexpr bool include_right_endpoint() noexcept { return true; }
|
|
1216
|
-
};
|
|
1217
|
-
struct open {
|
|
1218
|
-
static constexpr bool is_symmetric = true;
|
|
1219
|
-
static constexpr bool include_left_endpoint() noexcept { return false; }
|
|
1220
|
-
static constexpr bool include_right_endpoint() noexcept { return false; }
|
|
1221
|
-
};
|
|
1222
|
-
struct left_closed_right_open {
|
|
1223
|
-
static constexpr bool is_symmetric = false;
|
|
1224
|
-
static constexpr bool include_left_endpoint() noexcept { return true; }
|
|
1225
|
-
static constexpr bool include_right_endpoint() noexcept { return false; }
|
|
1226
|
-
};
|
|
1227
|
-
struct right_closed_left_open {
|
|
1228
|
-
static constexpr bool is_symmetric = false;
|
|
1229
|
-
static constexpr bool include_left_endpoint() noexcept { return false; }
|
|
1230
|
-
static constexpr bool include_right_endpoint() noexcept { return true; }
|
|
1231
|
-
};
|
|
1232
|
-
}
|
|
1233
|
-
|
|
1234
|
-
struct nearest_to_even : base {
|
|
1235
|
-
using decimal_to_binary_rounding_policy = nearest_to_even;
|
|
1236
|
-
static constexpr auto tag = tag_t::to_nearest;
|
|
1237
|
-
using normal_interval_type = interval_type::symmetric_boundary;
|
|
1238
|
-
using shorter_interval_type = interval_type::closed;
|
|
1239
|
-
|
|
1240
|
-
template <class SignedSignificandBits, class Func>
|
|
1241
|
-
static auto delegate(SignedSignificandBits, Func&& f) noexcept {
|
|
1242
|
-
return f(nearest_to_even{});
|
|
1243
|
-
}
|
|
1244
|
-
|
|
1245
|
-
template <class SignedSignificandBits, class Func>
|
|
1246
|
-
static constexpr auto invoke_normal_interval_case(SignedSignificandBits s,
|
|
1247
|
-
Func&& f) noexcept {
|
|
1248
|
-
return f(s.has_even_significand_bits());
|
|
1249
|
-
}
|
|
1250
|
-
template <class SignedSignificandBits, class Func>
|
|
1251
|
-
static constexpr auto invoke_shorter_interval_case(SignedSignificandBits,
|
|
1252
|
-
Func&& f) noexcept {
|
|
1253
|
-
return f();
|
|
1254
|
-
}
|
|
1255
|
-
};
|
|
1256
|
-
struct nearest_to_odd : base {
|
|
1257
|
-
using decimal_to_binary_rounding_policy = nearest_to_odd;
|
|
1258
|
-
static constexpr auto tag = tag_t::to_nearest;
|
|
1259
|
-
using normal_interval_type = interval_type::symmetric_boundary;
|
|
1260
|
-
using shorter_interval_type = interval_type::open;
|
|
1261
|
-
|
|
1262
|
-
template <class SignedSignificandBits, class Func>
|
|
1263
|
-
static auto delegate(SignedSignificandBits, Func&& f) noexcept {
|
|
1264
|
-
return f(nearest_to_odd{});
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
template <class SignedSignificandBits, class Func>
|
|
1268
|
-
static constexpr auto invoke_normal_interval_case(SignedSignificandBits s,
|
|
1269
|
-
Func&& f) noexcept {
|
|
1270
|
-
return f(!s.has_even_significand_bits());
|
|
1271
|
-
}
|
|
1272
|
-
template <class SignedSignificandBits, class Func>
|
|
1273
|
-
static constexpr auto invoke_shorter_interval_case(SignedSignificandBits,
|
|
1274
|
-
Func&& f) noexcept {
|
|
1275
|
-
return f();
|
|
1276
|
-
}
|
|
1277
|
-
};
|
|
1278
|
-
struct nearest_toward_plus_infinity : base {
|
|
1279
|
-
using decimal_to_binary_rounding_policy = nearest_toward_plus_infinity;
|
|
1280
|
-
static constexpr auto tag = tag_t::to_nearest;
|
|
1281
|
-
using normal_interval_type = interval_type::asymmetric_boundary;
|
|
1282
|
-
using shorter_interval_type = interval_type::asymmetric_boundary;
|
|
1283
|
-
|
|
1284
|
-
template <class SignedSignificandBits, class Func>
|
|
1285
|
-
static auto delegate(SignedSignificandBits, Func&& f) noexcept {
|
|
1286
|
-
return f(nearest_toward_plus_infinity{});
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
template <class SignedSignificandBits, class Func>
|
|
1290
|
-
static constexpr auto invoke_normal_interval_case(SignedSignificandBits s,
|
|
1291
|
-
Func&& f) noexcept {
|
|
1292
|
-
return f(!s.is_negative());
|
|
1293
|
-
}
|
|
1294
|
-
template <class SignedSignificandBits, class Func>
|
|
1295
|
-
static constexpr auto invoke_shorter_interval_case(SignedSignificandBits s,
|
|
1296
|
-
Func&& f) noexcept {
|
|
1297
|
-
return f(!s.is_negative());
|
|
1298
|
-
}
|
|
1299
|
-
};
|
|
1300
|
-
struct nearest_toward_minus_infinity : base {
|
|
1301
|
-
using decimal_to_binary_rounding_policy = nearest_toward_minus_infinity;
|
|
1302
|
-
static constexpr auto tag = tag_t::to_nearest;
|
|
1303
|
-
using normal_interval_type = interval_type::asymmetric_boundary;
|
|
1304
|
-
using shorter_interval_type = interval_type::asymmetric_boundary;
|
|
1305
|
-
|
|
1306
|
-
template <class SignedSignificandBits, class Func>
|
|
1307
|
-
static auto delegate(SignedSignificandBits, Func&& f) noexcept {
|
|
1308
|
-
return f(nearest_toward_minus_infinity{});
|
|
1309
|
-
}
|
|
1310
|
-
|
|
1311
|
-
template <class SignedSignificandBits, class Func>
|
|
1312
|
-
static constexpr auto invoke_normal_interval_case(SignedSignificandBits s,
|
|
1313
|
-
Func&& f) noexcept {
|
|
1314
|
-
return f(s.is_negative());
|
|
1315
|
-
}
|
|
1316
|
-
template <class SignedSignificandBits, class Func>
|
|
1317
|
-
static constexpr auto invoke_shorter_interval_case(SignedSignificandBits s,
|
|
1318
|
-
Func&& f) noexcept {
|
|
1319
|
-
return f(s.is_negative());
|
|
1320
|
-
}
|
|
1321
|
-
};
|
|
1322
|
-
struct nearest_toward_zero : base {
|
|
1323
|
-
using decimal_to_binary_rounding_policy = nearest_toward_zero;
|
|
1324
|
-
static constexpr auto tag = tag_t::to_nearest;
|
|
1325
|
-
using normal_interval_type = interval_type::right_closed_left_open;
|
|
1326
|
-
using shorter_interval_type = interval_type::right_closed_left_open;
|
|
1327
|
-
|
|
1328
|
-
template <class SignedSignificandBits, class Func>
|
|
1329
|
-
static auto delegate(SignedSignificandBits, Func&& f) noexcept {
|
|
1330
|
-
return f(nearest_toward_zero{});
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
template <class SignedSignificandBits, class Func>
|
|
1334
|
-
static constexpr auto invoke_normal_interval_case(SignedSignificandBits,
|
|
1335
|
-
Func&& f) noexcept {
|
|
1336
|
-
return f();
|
|
1337
|
-
}
|
|
1338
|
-
template <class SignedSignificandBits, class Func>
|
|
1339
|
-
static constexpr auto invoke_shorter_interval_case(SignedSignificandBits,
|
|
1340
|
-
Func&& f) noexcept {
|
|
1341
|
-
return f();
|
|
1342
|
-
}
|
|
1343
|
-
};
|
|
1344
|
-
struct nearest_away_from_zero : base {
|
|
1345
|
-
using decimal_to_binary_rounding_policy = nearest_away_from_zero;
|
|
1346
|
-
static constexpr auto tag = tag_t::to_nearest;
|
|
1347
|
-
using normal_interval_type = interval_type::left_closed_right_open;
|
|
1348
|
-
using shorter_interval_type = interval_type::left_closed_right_open;
|
|
1349
|
-
|
|
1350
|
-
template <class SignedSignificandBits, class Func>
|
|
1351
|
-
static auto delegate(SignedSignificandBits, Func&& f) noexcept {
|
|
1352
|
-
return f(nearest_away_from_zero{});
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
template <class SignedSignificandBits, class Func>
|
|
1356
|
-
static constexpr auto invoke_normal_interval_case(SignedSignificandBits,
|
|
1357
|
-
Func&& f) noexcept {
|
|
1358
|
-
return f();
|
|
1359
|
-
}
|
|
1360
|
-
template <class SignedSignificandBits, class Func>
|
|
1361
|
-
static constexpr auto invoke_shorter_interval_case(SignedSignificandBits,
|
|
1362
|
-
Func&& f) noexcept {
|
|
1363
|
-
return f();
|
|
1364
|
-
}
|
|
1365
|
-
};
|
|
1366
|
-
|
|
1367
|
-
namespace detail {
|
|
1368
|
-
struct nearest_always_closed {
|
|
1369
|
-
static constexpr auto tag = tag_t::to_nearest;
|
|
1370
|
-
using normal_interval_type = interval_type::closed;
|
|
1371
|
-
using shorter_interval_type = interval_type::closed;
|
|
1372
|
-
|
|
1373
|
-
template <class SignedSignificandBits, class Func>
|
|
1374
|
-
static constexpr auto invoke_normal_interval_case(SignedSignificandBits,
|
|
1375
|
-
Func&& f) noexcept {
|
|
1376
|
-
return f();
|
|
1377
|
-
}
|
|
1378
|
-
template <class SignedSignificandBits, class Func>
|
|
1379
|
-
static constexpr auto invoke_shorter_interval_case(SignedSignificandBits,
|
|
1380
|
-
Func&& f) noexcept {
|
|
1381
|
-
return f();
|
|
1382
|
-
}
|
|
1383
|
-
};
|
|
1384
|
-
struct nearest_always_open {
|
|
1385
|
-
static constexpr auto tag = tag_t::to_nearest;
|
|
1386
|
-
using normal_interval_type = interval_type::open;
|
|
1387
|
-
using shorter_interval_type = interval_type::open;
|
|
1388
|
-
|
|
1389
|
-
template <class SignedSignificandBits, class Func>
|
|
1390
|
-
static constexpr auto invoke_normal_interval_case(SignedSignificandBits,
|
|
1391
|
-
Func&& f) noexcept {
|
|
1392
|
-
return f();
|
|
1393
|
-
}
|
|
1394
|
-
template <class SignedSignificandBits, class Func>
|
|
1395
|
-
static constexpr auto invoke_shorter_interval_case(SignedSignificandBits,
|
|
1396
|
-
Func&& f) noexcept {
|
|
1397
|
-
return f();
|
|
1398
|
-
}
|
|
1399
|
-
};
|
|
1400
|
-
}
|
|
1401
|
-
|
|
1402
|
-
struct nearest_to_even_static_boundary : base {
|
|
1403
|
-
using decimal_to_binary_rounding_policy = nearest_to_even_static_boundary;
|
|
1404
|
-
template <class SignedSignificandBits, class Func>
|
|
1405
|
-
static auto delegate(SignedSignificandBits s, Func&& f) noexcept {
|
|
1406
|
-
if (s.has_even_significand_bits()) {
|
|
1407
|
-
return f(detail::nearest_always_closed{});
|
|
1408
|
-
}
|
|
1409
|
-
else {
|
|
1410
|
-
return f(detail::nearest_always_open{});
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
};
|
|
1414
|
-
struct nearest_to_odd_static_boundary : base {
|
|
1415
|
-
using decimal_to_binary_rounding_policy = nearest_to_odd_static_boundary;
|
|
1416
|
-
template <class SignedSignificandBits, class Func>
|
|
1417
|
-
static auto delegate(SignedSignificandBits s, Func&& f) noexcept {
|
|
1418
|
-
if (s.has_even_significand_bits()) {
|
|
1419
|
-
return f(detail::nearest_always_open{});
|
|
1420
|
-
}
|
|
1421
|
-
else {
|
|
1422
|
-
return f(detail::nearest_always_closed{});
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
};
|
|
1426
|
-
struct nearest_toward_plus_infinity_static_boundary : base {
|
|
1427
|
-
using decimal_to_binary_rounding_policy =
|
|
1428
|
-
nearest_toward_plus_infinity_static_boundary;
|
|
1429
|
-
template <class SignedSignificandBits, class Func>
|
|
1430
|
-
static auto delegate(SignedSignificandBits s, Func&& f) noexcept {
|
|
1431
|
-
if (s.is_negative()) {
|
|
1432
|
-
return f(nearest_toward_zero{});
|
|
1433
|
-
}
|
|
1434
|
-
else {
|
|
1435
|
-
return f(nearest_away_from_zero{});
|
|
1436
|
-
}
|
|
1437
|
-
}
|
|
1438
|
-
};
|
|
1439
|
-
struct nearest_toward_minus_infinity_static_boundary : base {
|
|
1440
|
-
using decimal_to_binary_rounding_policy =
|
|
1441
|
-
nearest_toward_minus_infinity_static_boundary;
|
|
1442
|
-
template <class SignedSignificandBits, class Func>
|
|
1443
|
-
static auto delegate(SignedSignificandBits s, Func&& f) noexcept {
|
|
1444
|
-
if (s.is_negative()) {
|
|
1445
|
-
return f(nearest_away_from_zero{});
|
|
1446
|
-
}
|
|
1447
|
-
else {
|
|
1448
|
-
return f(nearest_toward_zero{});
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
};
|
|
1452
|
-
|
|
1453
|
-
namespace detail {
|
|
1454
|
-
struct left_closed_directed {
|
|
1455
|
-
static constexpr auto tag = tag_t::left_closed_directed;
|
|
1456
|
-
};
|
|
1457
|
-
struct right_closed_directed {
|
|
1458
|
-
static constexpr auto tag = tag_t::right_closed_directed;
|
|
1459
|
-
};
|
|
1460
|
-
}
|
|
1461
|
-
|
|
1462
|
-
struct toward_plus_infinity : base {
|
|
1463
|
-
using decimal_to_binary_rounding_policy = toward_plus_infinity;
|
|
1464
|
-
template <class SignedSignificandBits, class Func>
|
|
1465
|
-
static auto delegate(SignedSignificandBits s, Func&& f) noexcept {
|
|
1466
|
-
if (s.is_negative()) {
|
|
1467
|
-
return f(detail::left_closed_directed{});
|
|
1468
|
-
}
|
|
1469
|
-
else {
|
|
1470
|
-
return f(detail::right_closed_directed{});
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
};
|
|
1474
|
-
struct toward_minus_infinity : base {
|
|
1475
|
-
using decimal_to_binary_rounding_policy = toward_minus_infinity;
|
|
1476
|
-
template <class SignedSignificandBits, class Func>
|
|
1477
|
-
static auto delegate(SignedSignificandBits s, Func&& f) noexcept {
|
|
1478
|
-
if (s.is_negative()) {
|
|
1479
|
-
return f(detail::right_closed_directed{});
|
|
1480
|
-
}
|
|
1481
|
-
else {
|
|
1482
|
-
return f(detail::left_closed_directed{});
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
};
|
|
1486
|
-
struct toward_zero : base {
|
|
1487
|
-
using decimal_to_binary_rounding_policy = toward_zero;
|
|
1488
|
-
template <class SignedSignificandBits, class Func>
|
|
1489
|
-
static auto delegate(SignedSignificandBits, Func&& f) noexcept {
|
|
1490
|
-
return f(detail::left_closed_directed{});
|
|
1491
|
-
}
|
|
1492
|
-
};
|
|
1493
|
-
struct away_from_zero : base {
|
|
1494
|
-
using decimal_to_binary_rounding_policy = away_from_zero;
|
|
1495
|
-
template <class SignedSignificandBits, class Func>
|
|
1496
|
-
static auto delegate(SignedSignificandBits, Func&& f) noexcept {
|
|
1497
|
-
return f(detail::right_closed_directed{});
|
|
1498
|
-
}
|
|
1499
|
-
};
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
// Binary-to-decimal rounding policies.
|
|
1503
|
-
// (Always assumes nearest rounding modes.)
|
|
1504
|
-
namespace binary_to_decimal_rounding {
|
|
1505
|
-
struct base {};
|
|
1506
|
-
|
|
1507
|
-
enum class tag_t { do_not_care, to_even, to_odd, away_from_zero, toward_zero };
|
|
1508
|
-
|
|
1509
|
-
struct do_not_care : base {
|
|
1510
|
-
using binary_to_decimal_rounding_policy = do_not_care;
|
|
1511
|
-
static constexpr auto tag = tag_t::do_not_care;
|
|
1512
|
-
|
|
1513
|
-
template <class ReturnType>
|
|
1514
|
-
static constexpr bool prefer_round_down(ReturnType const&) noexcept {
|
|
1515
|
-
return false;
|
|
1516
|
-
}
|
|
1517
|
-
};
|
|
1518
|
-
|
|
1519
|
-
struct to_even : base {
|
|
1520
|
-
using binary_to_decimal_rounding_policy = to_even;
|
|
1521
|
-
static constexpr auto tag = tag_t::to_even;
|
|
1522
|
-
|
|
1523
|
-
template <class ReturnType>
|
|
1524
|
-
static constexpr bool prefer_round_down(ReturnType const& r) noexcept {
|
|
1525
|
-
return r.significand % 2 != 0;
|
|
1526
|
-
}
|
|
1527
|
-
};
|
|
1528
|
-
|
|
1529
|
-
struct to_odd : base {
|
|
1530
|
-
using binary_to_decimal_rounding_policy = to_odd;
|
|
1531
|
-
static constexpr auto tag = tag_t::to_odd;
|
|
1532
|
-
|
|
1533
|
-
template <class ReturnType>
|
|
1534
|
-
static constexpr bool prefer_round_down(ReturnType const& r) noexcept {
|
|
1535
|
-
return r.significand % 2 == 0;
|
|
1536
|
-
}
|
|
1537
|
-
};
|
|
1538
|
-
|
|
1539
|
-
struct away_from_zero : base {
|
|
1540
|
-
using binary_to_decimal_rounding_policy = away_from_zero;
|
|
1541
|
-
static constexpr auto tag = tag_t::away_from_zero;
|
|
1542
|
-
|
|
1543
|
-
template <class ReturnType>
|
|
1544
|
-
static constexpr bool prefer_round_down(ReturnType const&) noexcept {
|
|
1545
|
-
return false;
|
|
1546
|
-
}
|
|
1547
|
-
};
|
|
1548
|
-
|
|
1549
|
-
struct toward_zero : base {
|
|
1550
|
-
using binary_to_decimal_rounding_policy = toward_zero;
|
|
1551
|
-
static constexpr auto tag = tag_t::toward_zero;
|
|
1552
|
-
|
|
1553
|
-
template <class ReturnType>
|
|
1554
|
-
static constexpr bool prefer_round_down(ReturnType const&) noexcept {
|
|
1555
|
-
return true;
|
|
1556
|
-
}
|
|
1557
|
-
};
|
|
1558
|
-
}
|
|
1559
|
-
|
|
1560
|
-
// Cache policies.
|
|
1561
|
-
namespace cache {
|
|
1562
|
-
struct base {};
|
|
1563
|
-
|
|
1564
|
-
struct full : base {
|
|
1565
|
-
using cache_policy = full;
|
|
1566
|
-
template <class FloatFormat>
|
|
1567
|
-
static constexpr typename cache_holder<FloatFormat>::cache_entry_type
|
|
1568
|
-
get_cache(int k) noexcept {
|
|
1569
|
-
assert(k >= cache_holder<FloatFormat>::min_k &&
|
|
1570
|
-
k <= cache_holder<FloatFormat>::max_k);
|
|
1571
|
-
return cache_holder<FloatFormat>::cache[std::size_t(
|
|
1572
|
-
k - cache_holder<FloatFormat>::min_k)];
|
|
1573
|
-
}
|
|
1574
|
-
};
|
|
1575
|
-
|
|
1576
|
-
struct compact : base {
|
|
1577
|
-
using cache_policy = compact;
|
|
1578
|
-
template <class FloatFormat>
|
|
1579
|
-
static constexpr typename cache_holder<FloatFormat>::cache_entry_type
|
|
1580
|
-
get_cache(int k) noexcept {
|
|
1581
|
-
assert(k >= cache_holder<FloatFormat>::min_k &&
|
|
1582
|
-
k <= cache_holder<FloatFormat>::max_k);
|
|
1583
|
-
|
|
1584
|
-
if constexpr (std::is_same_v<FloatFormat, ieee754_binary64>) {
|
|
1585
|
-
// Compute the base index.
|
|
1586
|
-
auto const cache_index =
|
|
1587
|
-
int(std::uint32_t(k - cache_holder<FloatFormat>::min_k) /
|
|
1588
|
-
compressed_cache_detail::compression_ratio);
|
|
1589
|
-
auto const kb =
|
|
1590
|
-
cache_index * compressed_cache_detail::compression_ratio +
|
|
1591
|
-
cache_holder<FloatFormat>::min_k;
|
|
1592
|
-
auto const offset = k - kb;
|
|
1593
|
-
|
|
1594
|
-
// Get the base cache.
|
|
1595
|
-
auto const base_cache =
|
|
1596
|
-
compressed_cache_detail::cache.table[cache_index];
|
|
1597
|
-
|
|
1598
|
-
if (offset == 0) {
|
|
1599
|
-
return base_cache;
|
|
1600
|
-
}
|
|
1601
|
-
else {
|
|
1602
|
-
// Compute the required amount of bit-shift.
|
|
1603
|
-
auto const alpha = log::floor_log2_pow10(kb + offset) -
|
|
1604
|
-
log::floor_log2_pow10(kb) - offset;
|
|
1605
|
-
assert(alpha > 0 && alpha < 64);
|
|
1606
|
-
|
|
1607
|
-
// Try to recover the real cache.
|
|
1608
|
-
auto const pow5 = compressed_cache_detail::pow5.table[offset];
|
|
1609
|
-
auto recovered_cache = wuint::umul128(base_cache.high(), pow5);
|
|
1610
|
-
auto const middle_low = wuint::umul128(base_cache.low(), pow5);
|
|
1611
|
-
|
|
1612
|
-
recovered_cache += middle_low.high();
|
|
1613
|
-
|
|
1614
|
-
auto const high_to_middle = recovered_cache.high() << (64 - alpha);
|
|
1615
|
-
auto const middle_to_low = recovered_cache.low() << (64 - alpha);
|
|
1616
|
-
|
|
1617
|
-
recovered_cache = wuint::uint128{
|
|
1618
|
-
(recovered_cache.low() >> alpha) | high_to_middle,
|
|
1619
|
-
((middle_low.low() >> alpha) | middle_to_low)};
|
|
1620
|
-
|
|
1621
|
-
assert(recovered_cache.low() + 1 != 0);
|
|
1622
|
-
recovered_cache = {recovered_cache.high(),
|
|
1623
|
-
recovered_cache.low() + 1};
|
|
1624
|
-
|
|
1625
|
-
return recovered_cache;
|
|
1626
|
-
}
|
|
1627
|
-
}
|
|
1628
|
-
else {
|
|
1629
|
-
// Just use the full cache for anything other than binary64
|
|
1630
|
-
return cache_holder<FloatFormat>::cache[std::size_t(
|
|
1631
|
-
k - cache_holder<FloatFormat>::min_k)];
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
};
|
|
1635
|
-
}
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
|
|
1639
|
-
namespace policy {
|
|
1640
|
-
namespace sign {
|
|
1641
|
-
inline constexpr auto ignore = detail::policy_impl::sign::ignore{};
|
|
1642
|
-
inline constexpr auto return_sign = detail::policy_impl::sign::return_sign{};
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
namespace trailing_zero {
|
|
1646
|
-
inline constexpr auto ignore = detail::policy_impl::trailing_zero::ignore{};
|
|
1647
|
-
inline constexpr auto remove = detail::policy_impl::trailing_zero::remove{};
|
|
1648
|
-
inline constexpr auto report = detail::policy_impl::trailing_zero::report{};
|
|
1649
|
-
}
|
|
1650
|
-
|
|
1651
|
-
namespace decimal_to_binary_rounding {
|
|
1652
|
-
inline constexpr auto nearest_to_even =
|
|
1653
|
-
detail::policy_impl::decimal_to_binary_rounding::nearest_to_even{};
|
|
1654
|
-
inline constexpr auto nearest_to_odd =
|
|
1655
|
-
detail::policy_impl::decimal_to_binary_rounding::nearest_to_odd{};
|
|
1656
|
-
inline constexpr auto nearest_toward_plus_infinity =
|
|
1657
|
-
detail::policy_impl::decimal_to_binary_rounding::nearest_toward_plus_infinity{};
|
|
1658
|
-
inline constexpr auto nearest_toward_minus_infinity =
|
|
1659
|
-
detail::policy_impl::decimal_to_binary_rounding::nearest_toward_minus_infinity{};
|
|
1660
|
-
inline constexpr auto nearest_toward_zero =
|
|
1661
|
-
detail::policy_impl::decimal_to_binary_rounding::nearest_toward_zero{};
|
|
1662
|
-
inline constexpr auto nearest_away_from_zero =
|
|
1663
|
-
detail::policy_impl::decimal_to_binary_rounding::nearest_away_from_zero{};
|
|
1664
|
-
|
|
1665
|
-
inline constexpr auto nearest_to_even_static_boundary =
|
|
1666
|
-
detail::policy_impl::decimal_to_binary_rounding::nearest_to_even_static_boundary{};
|
|
1667
|
-
inline constexpr auto nearest_to_odd_static_boundary =
|
|
1668
|
-
detail::policy_impl::decimal_to_binary_rounding::nearest_to_odd_static_boundary{};
|
|
1669
|
-
inline constexpr auto nearest_toward_plus_infinity_static_boundary =
|
|
1670
|
-
detail::policy_impl::decimal_to_binary_rounding::
|
|
1671
|
-
nearest_toward_plus_infinity_static_boundary{};
|
|
1672
|
-
inline constexpr auto nearest_toward_minus_infinity_static_boundary =
|
|
1673
|
-
detail::policy_impl::decimal_to_binary_rounding::
|
|
1674
|
-
nearest_toward_minus_infinity_static_boundary{};
|
|
1675
|
-
|
|
1676
|
-
inline constexpr auto toward_plus_infinity =
|
|
1677
|
-
detail::policy_impl::decimal_to_binary_rounding::toward_plus_infinity{};
|
|
1678
|
-
inline constexpr auto toward_minus_infinity =
|
|
1679
|
-
detail::policy_impl::decimal_to_binary_rounding::toward_minus_infinity{};
|
|
1680
|
-
inline constexpr auto toward_zero =
|
|
1681
|
-
detail::policy_impl::decimal_to_binary_rounding::toward_zero{};
|
|
1682
|
-
inline constexpr auto away_from_zero =
|
|
1683
|
-
detail::policy_impl::decimal_to_binary_rounding::away_from_zero{};
|
|
1684
|
-
}
|
|
1685
|
-
|
|
1686
|
-
namespace binary_to_decimal_rounding {
|
|
1687
|
-
inline constexpr auto do_not_care =
|
|
1688
|
-
detail::policy_impl::binary_to_decimal_rounding::do_not_care{};
|
|
1689
|
-
inline constexpr auto to_even =
|
|
1690
|
-
detail::policy_impl::binary_to_decimal_rounding::to_even{};
|
|
1691
|
-
inline constexpr auto to_odd =
|
|
1692
|
-
detail::policy_impl::binary_to_decimal_rounding::to_odd{};
|
|
1693
|
-
inline constexpr auto away_from_zero =
|
|
1694
|
-
detail::policy_impl::binary_to_decimal_rounding::away_from_zero{};
|
|
1695
|
-
inline constexpr auto toward_zero =
|
|
1696
|
-
detail::policy_impl::binary_to_decimal_rounding::toward_zero{};
|
|
1697
|
-
}
|
|
1698
|
-
|
|
1699
|
-
namespace cache {
|
|
1700
|
-
inline constexpr auto full = detail::policy_impl::cache::full{};
|
|
1701
|
-
inline constexpr auto compact = detail::policy_impl::cache::compact{};
|
|
1702
|
-
}
|
|
1703
|
-
}
|
|
1704
|
-
|
|
1705
|
-
namespace detail {
|
|
1706
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
1707
|
-
// The main algorithm.
|
|
1708
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
1709
|
-
|
|
1710
|
-
template <class Float, class FloatTraits>
|
|
1711
|
-
struct impl : private FloatTraits, private FloatTraits::format {
|
|
1712
|
-
using format = typename FloatTraits::format;
|
|
1713
|
-
using carrier_uint = typename FloatTraits::carrier_uint;
|
|
1714
|
-
|
|
1715
|
-
using FloatTraits::carrier_bits;
|
|
1716
|
-
using format::significand_bits;
|
|
1717
|
-
using format::min_exponent;
|
|
1718
|
-
using format::max_exponent;
|
|
1719
|
-
using format::exponent_bias;
|
|
1720
|
-
using format::decimal_digits;
|
|
1721
|
-
|
|
1722
|
-
static constexpr int kappa = std::is_same_v<format, ieee754_binary32> ? 1 : 2;
|
|
1723
|
-
static_assert(kappa >= 1);
|
|
1724
|
-
static_assert(carrier_bits >= significand_bits + 2 + log::floor_log2_pow10(kappa + 1));
|
|
1725
|
-
|
|
1726
|
-
static constexpr int min_k = [] {
|
|
1727
|
-
constexpr auto a = -log::floor_log10_pow2_minus_log10_4_over_3(
|
|
1728
|
-
int(max_exponent - significand_bits));
|
|
1729
|
-
constexpr auto b =
|
|
1730
|
-
-log::floor_log10_pow2(int(max_exponent - significand_bits)) + kappa;
|
|
1731
|
-
return a < b ? a : b;
|
|
1732
|
-
}();
|
|
1733
|
-
static_assert(min_k >= cache_holder<format>::min_k);
|
|
1734
|
-
|
|
1735
|
-
static constexpr int max_k = [] {
|
|
1736
|
-
// We do invoke shorter_interval_case for exponent == min_exponent case,
|
|
1737
|
-
// so we should not add 1 here.
|
|
1738
|
-
constexpr auto a = -log::floor_log10_pow2_minus_log10_4_over_3(
|
|
1739
|
-
int(min_exponent - significand_bits /*+ 1*/));
|
|
1740
|
-
constexpr auto b =
|
|
1741
|
-
-log::floor_log10_pow2(int(min_exponent - significand_bits)) + kappa;
|
|
1742
|
-
return a > b ? a : b;
|
|
1743
|
-
}();
|
|
1744
|
-
static_assert(max_k <= cache_holder<format>::max_k);
|
|
1745
|
-
|
|
1746
|
-
using cache_entry_type = typename cache_holder<format>::cache_entry_type;
|
|
1747
|
-
static constexpr auto cache_bits = cache_holder<format>::cache_bits;
|
|
1748
|
-
|
|
1749
|
-
static constexpr int max_power_of_factor_of_5 =
|
|
1750
|
-
log::floor_log5_pow2(int(significand_bits + 2));
|
|
1751
|
-
static constexpr int divisibility_check_by_5_threshold =
|
|
1752
|
-
log::floor_log2_pow10(max_power_of_factor_of_5 + kappa + 1);
|
|
1753
|
-
|
|
1754
|
-
static constexpr int case_fc_pm_half_lower_threshold =
|
|
1755
|
-
-kappa - log::floor_log5_pow2(kappa);
|
|
1756
|
-
|
|
1757
|
-
static constexpr int case_shorter_interval_left_endpoint_lower_threshold = 2;
|
|
1758
|
-
static constexpr int case_shorter_interval_left_endpoint_upper_threshold =
|
|
1759
|
-
2 +
|
|
1760
|
-
log::floor_log2(
|
|
1761
|
-
compute_power<
|
|
1762
|
-
count_factors<5>((carrier_uint(1) << (significand_bits + 2)) - 1) + 1>(10) /
|
|
1763
|
-
3);
|
|
1764
|
-
|
|
1765
|
-
static constexpr int case_shorter_interval_right_endpoint_lower_threshold = 0;
|
|
1766
|
-
static constexpr int case_shorter_interval_right_endpoint_upper_threshold =
|
|
1767
|
-
2 +
|
|
1768
|
-
log::floor_log2(
|
|
1769
|
-
compute_power<
|
|
1770
|
-
count_factors<5>((carrier_uint(1) << (significand_bits + 1)) + 1) + 1>(10) /
|
|
1771
|
-
3);
|
|
1772
|
-
|
|
1773
|
-
static constexpr int shorter_interval_tie_lower_threshold =
|
|
1774
|
-
-log::floor_log5_pow2_minus_log5_3(significand_bits + 4) - 2 - significand_bits;
|
|
1775
|
-
static constexpr int shorter_interval_tie_upper_threshold =
|
|
1776
|
-
-log::floor_log5_pow2(significand_bits + 2) - 2 - significand_bits;
|
|
1777
|
-
|
|
1778
|
-
struct compute_mul_result {
|
|
1779
|
-
carrier_uint result;
|
|
1780
|
-
bool is_integer;
|
|
1781
|
-
};
|
|
1782
|
-
struct compute_mul_parity_result {
|
|
1783
|
-
bool parity;
|
|
1784
|
-
bool is_integer;
|
|
1785
|
-
};
|
|
1786
|
-
|
|
1787
|
-
//// The main algorithm assumes the input is a normal/subnormal finite number
|
|
1788
|
-
|
|
1789
|
-
template <class ReturnType, class IntervalType, class TrailingZeroPolicy,
|
|
1790
|
-
class BinaryToDecimalRoundingPolicy, class CachePolicy,
|
|
1791
|
-
class... AdditionalArgs>
|
|
1792
|
-
JKJ_SAFEBUFFERS static ReturnType
|
|
1793
|
-
compute_nearest_normal(carrier_uint const two_fc, int const exponent,
|
|
1794
|
-
AdditionalArgs... additional_args) noexcept {
|
|
1795
|
-
//////////////////////////////////////////////////////////////////////
|
|
1796
|
-
// Step 1: Schubfach multiplier calculation
|
|
1797
|
-
//////////////////////////////////////////////////////////////////////
|
|
1798
|
-
|
|
1799
|
-
ReturnType ret_value;
|
|
1800
|
-
IntervalType interval_type{additional_args...};
|
|
1801
|
-
|
|
1802
|
-
// Compute k and beta.
|
|
1803
|
-
int const minus_k = log::floor_log10_pow2(exponent) - kappa;
|
|
1804
|
-
auto const cache = CachePolicy::template get_cache<format>(-minus_k);
|
|
1805
|
-
int const beta = exponent + log::floor_log2_pow10(-minus_k);
|
|
1806
|
-
|
|
1807
|
-
// Compute zi and deltai.
|
|
1808
|
-
// 10^kappa <= deltai < 10^(kappa + 1)
|
|
1809
|
-
auto const deltai = compute_delta(cache, beta);
|
|
1810
|
-
// For the case of binary32, the result of integer check is not correct for
|
|
1811
|
-
// 29711844 * 2^-82
|
|
1812
|
-
// = 6.1442653300000000008655037797566933477355632930994033813476... * 10^-18
|
|
1813
|
-
// and 29711844 * 2^-81
|
|
1814
|
-
// = 1.2288530660000000001731007559513386695471126586198806762695... * 10^-17,
|
|
1815
|
-
// and they are the unique counterexamples. However, since 29711844 is even,
|
|
1816
|
-
// this does not cause any problem for the endpoints calculations; it can only
|
|
1817
|
-
// cause a problem when we need to perform integer check for the center.
|
|
1818
|
-
// Fortunately, with these inputs, that branch is never executed, so we are fine.
|
|
1819
|
-
auto const [zi, is_z_integer] = compute_mul((two_fc | 1) << beta, cache);
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
//////////////////////////////////////////////////////////////////////
|
|
1823
|
-
// Step 2: Try larger divisor; remove trailing zeros if necessary
|
|
1824
|
-
//////////////////////////////////////////////////////////////////////
|
|
1825
|
-
|
|
1826
|
-
constexpr auto big_divisor = compute_power<kappa + 1>(std::uint32_t(10));
|
|
1827
|
-
constexpr auto small_divisor = compute_power<kappa>(std::uint32_t(10));
|
|
1828
|
-
|
|
1829
|
-
// Using an upper bound on zi, we might be able to optimize the division
|
|
1830
|
-
// better than the compiler; we are computing zi / big_divisor here.
|
|
1831
|
-
ret_value.significand =
|
|
1832
|
-
div::divide_by_pow10<kappa + 1, carrier_uint,
|
|
1833
|
-
(carrier_uint(1) << (significand_bits + 1)) * big_divisor -
|
|
1834
|
-
1>(zi);
|
|
1835
|
-
auto r = std::uint32_t(zi - big_divisor * ret_value.significand);
|
|
1836
|
-
|
|
1837
|
-
if (r < deltai) {
|
|
1838
|
-
// Exclude the right endpoint if necessary.
|
|
1839
|
-
if (r == 0 && is_z_integer && !interval_type.include_right_endpoint()) {
|
|
1840
|
-
if constexpr (BinaryToDecimalRoundingPolicy::tag ==
|
|
1841
|
-
policy_impl::binary_to_decimal_rounding::tag_t::do_not_care) {
|
|
1842
|
-
ret_value.significand *= 10;
|
|
1843
|
-
ret_value.exponent = minus_k + kappa;
|
|
1844
|
-
--ret_value.significand;
|
|
1845
|
-
return ret_value;
|
|
1846
|
-
}
|
|
1847
|
-
else {
|
|
1848
|
-
--ret_value.significand;
|
|
1849
|
-
r = big_divisor;
|
|
1850
|
-
goto small_divisor_case_label;
|
|
1851
|
-
}
|
|
1852
|
-
}
|
|
1853
|
-
}
|
|
1854
|
-
else if (r > deltai) {
|
|
1855
|
-
goto small_divisor_case_label;
|
|
1856
|
-
}
|
|
1857
|
-
else {
|
|
1858
|
-
// r == deltai; compare fractional parts.
|
|
1859
|
-
auto const two_fl = two_fc - 1;
|
|
1860
|
-
|
|
1861
|
-
if (!interval_type.include_left_endpoint() ||
|
|
1862
|
-
exponent < case_fc_pm_half_lower_threshold ||
|
|
1863
|
-
exponent > divisibility_check_by_5_threshold) {
|
|
1864
|
-
// If the left endpoint is not included, the condition for
|
|
1865
|
-
// success is z^(f) < delta^(f) (odd parity).
|
|
1866
|
-
// Otherwise, the inequalities on exponent ensure that
|
|
1867
|
-
// x is not an integer, so if z^(f) >= delta^(f) (even parity), we in fact
|
|
1868
|
-
// have strict inequality.
|
|
1869
|
-
if (!compute_mul_parity(two_fl, cache, beta).parity) {
|
|
1870
|
-
goto small_divisor_case_label;
|
|
1871
|
-
}
|
|
1872
|
-
}
|
|
1873
|
-
else {
|
|
1874
|
-
auto const [xi_parity, x_is_integer] =
|
|
1875
|
-
compute_mul_parity(two_fl, cache, beta);
|
|
1876
|
-
if (!xi_parity && !x_is_integer) {
|
|
1877
|
-
goto small_divisor_case_label;
|
|
1878
|
-
}
|
|
1879
|
-
}
|
|
1880
|
-
}
|
|
1881
|
-
ret_value.exponent = minus_k + kappa + 1;
|
|
1882
|
-
|
|
1883
|
-
// We may need to remove trailing zeros.
|
|
1884
|
-
TrailingZeroPolicy::template on_trailing_zeros<impl>(ret_value);
|
|
1885
|
-
return ret_value;
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
//////////////////////////////////////////////////////////////////////
|
|
1889
|
-
// Step 3: Find the significand with the smaller divisor
|
|
1890
|
-
//////////////////////////////////////////////////////////////////////
|
|
1891
|
-
|
|
1892
|
-
small_divisor_case_label:
|
|
1893
|
-
TrailingZeroPolicy::template no_trailing_zeros<impl>(ret_value);
|
|
1894
|
-
ret_value.significand *= 10;
|
|
1895
|
-
ret_value.exponent = minus_k + kappa;
|
|
1896
|
-
|
|
1897
|
-
if constexpr (BinaryToDecimalRoundingPolicy::tag ==
|
|
1898
|
-
policy_impl::binary_to_decimal_rounding::tag_t::do_not_care) {
|
|
1899
|
-
// Normally, we want to compute
|
|
1900
|
-
// ret_value.significand += r / small_divisor
|
|
1901
|
-
// and return, but we need to take care of the case that the resulting
|
|
1902
|
-
// value is exactly the right endpoint, while that is not included in the
|
|
1903
|
-
// interval.
|
|
1904
|
-
if (!interval_type.include_right_endpoint()) {
|
|
1905
|
-
// Is r divisible by 10^kappa?
|
|
1906
|
-
if (is_z_integer && div::check_divisibility_and_divide_by_pow10<kappa>(r)) {
|
|
1907
|
-
// This should be in the interval.
|
|
1908
|
-
ret_value.significand += r - 1;
|
|
1909
|
-
}
|
|
1910
|
-
else {
|
|
1911
|
-
ret_value.significand += r;
|
|
1912
|
-
}
|
|
1913
|
-
}
|
|
1914
|
-
else {
|
|
1915
|
-
ret_value.significand += div::small_division_by_pow10<kappa>(r);
|
|
1916
|
-
}
|
|
1917
|
-
}
|
|
1918
|
-
else {
|
|
1919
|
-
auto dist = r - (deltai / 2) + (small_divisor / 2);
|
|
1920
|
-
bool const approx_y_parity = ((dist ^ (small_divisor / 2)) & 1) != 0;
|
|
1921
|
-
|
|
1922
|
-
// Is dist divisible by 10^kappa?
|
|
1923
|
-
bool const divisible_by_small_divisor =
|
|
1924
|
-
div::check_divisibility_and_divide_by_pow10<kappa>(dist);
|
|
1925
|
-
|
|
1926
|
-
// Add dist / 10^kappa to the significand.
|
|
1927
|
-
ret_value.significand += dist;
|
|
1928
|
-
|
|
1929
|
-
if (divisible_by_small_divisor) {
|
|
1930
|
-
// Check z^(f) >= epsilon^(f).
|
|
1931
|
-
// We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1,
|
|
1932
|
-
// where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f).
|
|
1933
|
-
// Since there are only 2 possibilities, we only need to care about the
|
|
1934
|
-
// parity. Also, zi and r should have the same parity since the divisor is
|
|
1935
|
-
// an even number.
|
|
1936
|
-
auto const [yi_parity, is_y_integer] =
|
|
1937
|
-
compute_mul_parity(two_fc, cache, beta);
|
|
1938
|
-
if (yi_parity != approx_y_parity) {
|
|
1939
|
-
--ret_value.significand;
|
|
1940
|
-
}
|
|
1941
|
-
else {
|
|
1942
|
-
// If z^(f) >= epsilon^(f), we might have a tie
|
|
1943
|
-
// when z^(f) == epsilon^(f), or equivalently, when y is an integer.
|
|
1944
|
-
// For tie-to-up case, we can just choose the upper one.
|
|
1945
|
-
if (BinaryToDecimalRoundingPolicy::prefer_round_down(ret_value) &&
|
|
1946
|
-
is_y_integer) {
|
|
1947
|
-
--ret_value.significand;
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
}
|
|
1951
|
-
}
|
|
1952
|
-
return ret_value;
|
|
1953
|
-
}
|
|
1954
|
-
|
|
1955
|
-
template <class ReturnType, class IntervalType, class TrailingZeroPolicy,
|
|
1956
|
-
class BinaryToDecimalRoundingPolicy, class CachePolicy,
|
|
1957
|
-
class... AdditionalArgs>
|
|
1958
|
-
JKJ_SAFEBUFFERS static ReturnType
|
|
1959
|
-
compute_nearest_shorter(int const exponent,
|
|
1960
|
-
AdditionalArgs... additional_args) noexcept {
|
|
1961
|
-
ReturnType ret_value;
|
|
1962
|
-
IntervalType interval_type{additional_args...};
|
|
1963
|
-
|
|
1964
|
-
// Compute k and beta.
|
|
1965
|
-
int const minus_k = log::floor_log10_pow2_minus_log10_4_over_3(exponent);
|
|
1966
|
-
int const beta = exponent + log::floor_log2_pow10(-minus_k);
|
|
1967
|
-
|
|
1968
|
-
// Compute xi and zi.
|
|
1969
|
-
auto const cache = CachePolicy::template get_cache<format>(-minus_k);
|
|
1970
|
-
|
|
1971
|
-
auto xi = compute_left_endpoint_for_shorter_interval_case(cache, beta);
|
|
1972
|
-
auto zi = compute_right_endpoint_for_shorter_interval_case(cache, beta);
|
|
1973
|
-
|
|
1974
|
-
// If we don't accept the right endpoint and
|
|
1975
|
-
// if the right endpoint is an integer, decrease it.
|
|
1976
|
-
if (!interval_type.include_right_endpoint() &&
|
|
1977
|
-
is_right_endpoint_integer_shorter_interval(exponent)) {
|
|
1978
|
-
--zi;
|
|
1979
|
-
}
|
|
1980
|
-
// If we don't accept the left endpoint or
|
|
1981
|
-
// if the left endpoint is not an integer, increase it.
|
|
1982
|
-
if (!interval_type.include_left_endpoint() ||
|
|
1983
|
-
!is_left_endpoint_integer_shorter_interval(exponent)) {
|
|
1984
|
-
++xi;
|
|
1985
|
-
}
|
|
1986
|
-
|
|
1987
|
-
// Try bigger divisor.
|
|
1988
|
-
ret_value.significand = zi / 10;
|
|
1989
|
-
|
|
1990
|
-
// If succeed, remove trailing zeros if necessary and return.
|
|
1991
|
-
if (ret_value.significand * 10 >= xi) {
|
|
1992
|
-
ret_value.exponent = minus_k + 1;
|
|
1993
|
-
TrailingZeroPolicy::template on_trailing_zeros<impl>(ret_value);
|
|
1994
|
-
return ret_value;
|
|
1995
|
-
}
|
|
1996
|
-
|
|
1997
|
-
// Otherwise, compute the round-up of y.
|
|
1998
|
-
TrailingZeroPolicy::template no_trailing_zeros<impl>(ret_value);
|
|
1999
|
-
ret_value.significand = compute_round_up_for_shorter_interval_case(cache, beta);
|
|
2000
|
-
ret_value.exponent = minus_k;
|
|
2001
|
-
|
|
2002
|
-
// When tie occurs, choose one of them according to the rule.
|
|
2003
|
-
if (BinaryToDecimalRoundingPolicy::prefer_round_down(ret_value) &&
|
|
2004
|
-
exponent >= shorter_interval_tie_lower_threshold &&
|
|
2005
|
-
exponent <= shorter_interval_tie_upper_threshold) {
|
|
2006
|
-
--ret_value.significand;
|
|
2007
|
-
}
|
|
2008
|
-
else if (ret_value.significand < xi) {
|
|
2009
|
-
++ret_value.significand;
|
|
2010
|
-
}
|
|
2011
|
-
return ret_value;
|
|
2012
|
-
}
|
|
2013
|
-
|
|
2014
|
-
template <class ReturnType, class TrailingZeroPolicy, class CachePolicy>
|
|
2015
|
-
JKJ_SAFEBUFFERS static ReturnType
|
|
2016
|
-
compute_left_closed_directed(carrier_uint const two_fc, int exponent) noexcept {
|
|
2017
|
-
//////////////////////////////////////////////////////////////////////
|
|
2018
|
-
// Step 1: Schubfach multiplier calculation
|
|
2019
|
-
//////////////////////////////////////////////////////////////////////
|
|
2020
|
-
|
|
2021
|
-
ReturnType ret_value;
|
|
2022
|
-
|
|
2023
|
-
// Compute k and beta.
|
|
2024
|
-
int const minus_k = log::floor_log10_pow2(exponent) - kappa;
|
|
2025
|
-
auto const cache = CachePolicy::template get_cache<format>(-minus_k);
|
|
2026
|
-
int const beta = exponent + log::floor_log2_pow10(-minus_k);
|
|
2027
|
-
|
|
2028
|
-
// Compute xi and deltai.
|
|
2029
|
-
// 10^kappa <= deltai < 10^(kappa + 1)
|
|
2030
|
-
auto const deltai = compute_delta(cache, beta);
|
|
2031
|
-
auto [xi, is_x_integer] = compute_mul(two_fc << beta, cache);
|
|
2032
|
-
|
|
2033
|
-
// Deal with the unique exceptional cases
|
|
2034
|
-
// 29711844 * 2^-82
|
|
2035
|
-
// = 6.1442653300000000008655037797566933477355632930994033813476... * 10^-18
|
|
2036
|
-
// and 29711844 * 2^-81
|
|
2037
|
-
// = 1.2288530660000000001731007559513386695471126586198806762695... * 10^-17
|
|
2038
|
-
// for binary32.
|
|
2039
|
-
if constexpr (std::is_same_v<format, ieee754_binary32>) {
|
|
2040
|
-
if (exponent <= -80) {
|
|
2041
|
-
is_x_integer = false;
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
2044
|
-
|
|
2045
|
-
if (!is_x_integer) {
|
|
2046
|
-
++xi;
|
|
2047
|
-
}
|
|
2048
|
-
|
|
2049
|
-
//////////////////////////////////////////////////////////////////////
|
|
2050
|
-
// Step 2: Try larger divisor; remove trailing zeros if necessary
|
|
2051
|
-
//////////////////////////////////////////////////////////////////////
|
|
2052
|
-
|
|
2053
|
-
constexpr auto big_divisor = compute_power<kappa + 1>(std::uint32_t(10));
|
|
2054
|
-
|
|
2055
|
-
// Using an upper bound on xi, we might be able to optimize the division
|
|
2056
|
-
// better than the compiler; we are computing xi / big_divisor here.
|
|
2057
|
-
ret_value.significand =
|
|
2058
|
-
div::divide_by_pow10<kappa + 1, carrier_uint,
|
|
2059
|
-
(carrier_uint(1) << (significand_bits + 1)) * big_divisor -
|
|
2060
|
-
1>(xi);
|
|
2061
|
-
auto r = std::uint32_t(xi - big_divisor * ret_value.significand);
|
|
2062
|
-
|
|
2063
|
-
if (r != 0) {
|
|
2064
|
-
++ret_value.significand;
|
|
2065
|
-
r = big_divisor - r;
|
|
2066
|
-
}
|
|
2067
|
-
|
|
2068
|
-
if (r > deltai) {
|
|
2069
|
-
goto small_divisor_case_label;
|
|
2070
|
-
}
|
|
2071
|
-
else if (r == deltai) {
|
|
2072
|
-
// Compare the fractional parts.
|
|
2073
|
-
// This branch is never taken for the exceptional cases
|
|
2074
|
-
// 2f_c = 29711482, e = -81
|
|
2075
|
-
// (6.1442649164096937243516663440523473127541365101933479309082... * 10^-18)
|
|
2076
|
-
// and 2f_c = 29711482, e = -80
|
|
2077
|
-
// (1.2288529832819387448703332688104694625508273020386695861816... * 10^-17).
|
|
2078
|
-
auto const [zi_parity, is_z_integer] =
|
|
2079
|
-
compute_mul_parity(two_fc + 2, cache, beta);
|
|
2080
|
-
if (zi_parity || is_z_integer) {
|
|
2081
|
-
goto small_divisor_case_label;
|
|
2082
|
-
}
|
|
2083
|
-
}
|
|
2084
|
-
|
|
2085
|
-
// The ceiling is inside, so we are done.
|
|
2086
|
-
ret_value.exponent = minus_k + kappa + 1;
|
|
2087
|
-
TrailingZeroPolicy::template on_trailing_zeros<impl>(ret_value);
|
|
2088
|
-
return ret_value;
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
//////////////////////////////////////////////////////////////////////
|
|
2092
|
-
// Step 3: Find the significand with the smaller divisor
|
|
2093
|
-
//////////////////////////////////////////////////////////////////////
|
|
2094
|
-
|
|
2095
|
-
small_divisor_case_label:
|
|
2096
|
-
ret_value.significand *= 10;
|
|
2097
|
-
ret_value.significand -= div::small_division_by_pow10<kappa>(r);
|
|
2098
|
-
ret_value.exponent = minus_k + kappa;
|
|
2099
|
-
TrailingZeroPolicy::template no_trailing_zeros<impl>(ret_value);
|
|
2100
|
-
return ret_value;
|
|
2101
|
-
}
|
|
2102
|
-
|
|
2103
|
-
template <class ReturnType, class TrailingZeroPolicy, class CachePolicy>
|
|
2104
|
-
JKJ_SAFEBUFFERS static ReturnType
|
|
2105
|
-
compute_right_closed_directed(carrier_uint const two_fc, int const exponent,
|
|
2106
|
-
bool shorter_interval) noexcept {
|
|
2107
|
-
//////////////////////////////////////////////////////////////////////
|
|
2108
|
-
// Step 1: Schubfach multiplier calculation
|
|
2109
|
-
//////////////////////////////////////////////////////////////////////
|
|
2110
|
-
|
|
2111
|
-
ReturnType ret_value;
|
|
2112
|
-
|
|
2113
|
-
// Compute k and beta.
|
|
2114
|
-
int const minus_k =
|
|
2115
|
-
log::floor_log10_pow2(exponent - (shorter_interval ? 1 : 0)) - kappa;
|
|
2116
|
-
auto const cache = CachePolicy::template get_cache<format>(-minus_k);
|
|
2117
|
-
int const beta = exponent + log::floor_log2_pow10(-minus_k);
|
|
2118
|
-
|
|
2119
|
-
// Compute zi and deltai.
|
|
2120
|
-
// 10^kappa <= deltai < 10^(kappa + 1)
|
|
2121
|
-
auto const deltai =
|
|
2122
|
-
shorter_interval ? compute_delta(cache, beta - 1) : compute_delta(cache, beta);
|
|
2123
|
-
carrier_uint const zi = compute_mul(two_fc << beta, cache).result;
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
//////////////////////////////////////////////////////////////////////
|
|
2127
|
-
// Step 2: Try larger divisor; remove trailing zeros if necessary
|
|
2128
|
-
//////////////////////////////////////////////////////////////////////
|
|
2129
|
-
|
|
2130
|
-
constexpr auto big_divisor = compute_power<kappa + 1>(std::uint32_t(10));
|
|
2131
|
-
|
|
2132
|
-
// Using an upper bound on zi, we might be able to optimize the division better than
|
|
2133
|
-
// the compiler; we are computing zi / big_divisor here.
|
|
2134
|
-
ret_value.significand =
|
|
2135
|
-
div::divide_by_pow10<kappa + 1, carrier_uint,
|
|
2136
|
-
(carrier_uint(1) << (significand_bits + 1)) * big_divisor -
|
|
2137
|
-
1>(zi);
|
|
2138
|
-
auto const r = std::uint32_t(zi - big_divisor * ret_value.significand);
|
|
2139
|
-
|
|
2140
|
-
if (r > deltai) {
|
|
2141
|
-
goto small_divisor_case_label;
|
|
2142
|
-
}
|
|
2143
|
-
else if (r == deltai) {
|
|
2144
|
-
// Compare the fractional parts.
|
|
2145
|
-
if (!compute_mul_parity(two_fc - (shorter_interval ? 1 : 2), cache, beta)
|
|
2146
|
-
.parity) {
|
|
2147
|
-
goto small_divisor_case_label;
|
|
2148
|
-
}
|
|
2149
|
-
}
|
|
2150
|
-
|
|
2151
|
-
// The floor is inside, so we are done.
|
|
2152
|
-
ret_value.exponent = minus_k + kappa + 1;
|
|
2153
|
-
TrailingZeroPolicy::template on_trailing_zeros<impl>(ret_value);
|
|
2154
|
-
return ret_value;
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
//////////////////////////////////////////////////////////////////////
|
|
2158
|
-
// Step 3: Find the significand with the small divisor
|
|
2159
|
-
//////////////////////////////////////////////////////////////////////
|
|
2160
|
-
|
|
2161
|
-
small_divisor_case_label:
|
|
2162
|
-
ret_value.significand *= 10;
|
|
2163
|
-
ret_value.significand += div::small_division_by_pow10<kappa>(r);
|
|
2164
|
-
ret_value.exponent = minus_k + kappa;
|
|
2165
|
-
TrailingZeroPolicy::template no_trailing_zeros<impl>(ret_value);
|
|
2166
|
-
return ret_value;
|
|
2167
|
-
}
|
|
2168
|
-
|
|
2169
|
-
// Remove trailing zeros from n and return the number of zeros removed.
|
|
2170
|
-
JKJ_FORCEINLINE static int remove_trailing_zeros(carrier_uint& n) noexcept {
|
|
2171
|
-
assert(n != 0);
|
|
2172
|
-
|
|
2173
|
-
if constexpr (std::is_same_v<format, ieee754_binary32>) {
|
|
2174
|
-
constexpr auto mod_inv_5 = std::uint32_t(0xcccc'cccd);
|
|
2175
|
-
constexpr auto mod_inv_25 = mod_inv_5 * mod_inv_5;
|
|
2176
|
-
|
|
2177
|
-
int s = 0;
|
|
2178
|
-
while (true) {
|
|
2179
|
-
auto q = bits::rotr(n * mod_inv_25, 2);
|
|
2180
|
-
if (q <= std::numeric_limits<std::uint32_t>::max() / 100) {
|
|
2181
|
-
n = q;
|
|
2182
|
-
s += 2;
|
|
2183
|
-
}
|
|
2184
|
-
else {
|
|
2185
|
-
break;
|
|
2186
|
-
}
|
|
2187
|
-
}
|
|
2188
|
-
auto q = bits::rotr(n * mod_inv_5, 1);
|
|
2189
|
-
if (q <= std::numeric_limits<std::uint32_t>::max() / 10) {
|
|
2190
|
-
n = q;
|
|
2191
|
-
s |= 1;
|
|
2192
|
-
}
|
|
2193
|
-
|
|
2194
|
-
return s;
|
|
2195
|
-
}
|
|
2196
|
-
else {
|
|
2197
|
-
static_assert(std::is_same_v<format, ieee754_binary64>);
|
|
2198
|
-
|
|
2199
|
-
// Divide by 10^8 and reduce to 32-bits if divisible.
|
|
2200
|
-
// Since ret_value.significand <= (2^53 * 1000 - 1) / 1000 < 10^16,
|
|
2201
|
-
// n is at most of 16 digits.
|
|
2202
|
-
|
|
2203
|
-
// This magic number is ceil(2^90 / 10^8).
|
|
2204
|
-
constexpr auto magic_number = std::uint64_t(12379400392853802749ull);
|
|
2205
|
-
auto nm = wuint::umul128(n, magic_number);
|
|
2206
|
-
|
|
2207
|
-
// Is n is divisible by 10^8?
|
|
2208
|
-
if ((nm.high() & ((std::uint64_t(1) << (90 - 64)) - 1)) == 0 &&
|
|
2209
|
-
nm.low() < magic_number) {
|
|
2210
|
-
// If yes, work with the quotient.
|
|
2211
|
-
auto n32 = std::uint32_t(nm.high() >> (90 - 64));
|
|
2212
|
-
|
|
2213
|
-
constexpr auto mod_inv_5 = std::uint32_t(0xcccc'cccd);
|
|
2214
|
-
constexpr auto mod_inv_25 = mod_inv_5 * mod_inv_5;
|
|
2215
|
-
|
|
2216
|
-
int s = 8;
|
|
2217
|
-
while (true) {
|
|
2218
|
-
auto q = bits::rotr(n32 * mod_inv_25, 2);
|
|
2219
|
-
if (q <= std::numeric_limits<std::uint32_t>::max() / 100) {
|
|
2220
|
-
n32 = q;
|
|
2221
|
-
s += 2;
|
|
2222
|
-
}
|
|
2223
|
-
else {
|
|
2224
|
-
break;
|
|
2225
|
-
}
|
|
2226
|
-
}
|
|
2227
|
-
auto q = bits::rotr(n32 * mod_inv_5, 1);
|
|
2228
|
-
if (q <= std::numeric_limits<std::uint32_t>::max() / 10) {
|
|
2229
|
-
n32 = q;
|
|
2230
|
-
s |= 1;
|
|
2231
|
-
}
|
|
2232
|
-
|
|
2233
|
-
n = n32;
|
|
2234
|
-
return s;
|
|
2235
|
-
}
|
|
2236
|
-
|
|
2237
|
-
// If n is not divisible by 10^8, work with n itself.
|
|
2238
|
-
constexpr auto mod_inv_5 = std::uint64_t(0xcccc'cccc'cccc'cccd);
|
|
2239
|
-
constexpr auto mod_inv_25 = mod_inv_5 * mod_inv_5;
|
|
2240
|
-
|
|
2241
|
-
int s = 0;
|
|
2242
|
-
while (true) {
|
|
2243
|
-
auto q = bits::rotr(n * mod_inv_25, 2);
|
|
2244
|
-
if (q <= std::numeric_limits<std::uint64_t>::max() / 100) {
|
|
2245
|
-
n = q;
|
|
2246
|
-
s += 2;
|
|
2247
|
-
}
|
|
2248
|
-
else {
|
|
2249
|
-
break;
|
|
2250
|
-
}
|
|
2251
|
-
}
|
|
2252
|
-
auto q = bits::rotr(n * mod_inv_5, 1);
|
|
2253
|
-
if (q <= std::numeric_limits<std::uint64_t>::max() / 10) {
|
|
2254
|
-
n = q;
|
|
2255
|
-
s |= 1;
|
|
2256
|
-
}
|
|
2257
|
-
|
|
2258
|
-
return s;
|
|
2259
|
-
}
|
|
2260
|
-
}
|
|
2261
|
-
|
|
2262
|
-
static compute_mul_result compute_mul(carrier_uint u,
|
|
2263
|
-
cache_entry_type const& cache) noexcept {
|
|
2264
|
-
if constexpr (std::is_same_v<format, ieee754_binary32>) {
|
|
2265
|
-
auto r = wuint::umul96_upper64(u, cache);
|
|
2266
|
-
return {carrier_uint(r >> 32), carrier_uint(r) == 0};
|
|
2267
|
-
}
|
|
2268
|
-
else {
|
|
2269
|
-
static_assert(std::is_same_v<format, ieee754_binary64>);
|
|
2270
|
-
auto r = wuint::umul192_upper128(u, cache);
|
|
2271
|
-
return {r.high(), r.low() == 0};
|
|
2272
|
-
}
|
|
2273
|
-
}
|
|
2274
|
-
|
|
2275
|
-
static constexpr std::uint32_t compute_delta(cache_entry_type const& cache,
|
|
2276
|
-
int beta) noexcept {
|
|
2277
|
-
if constexpr (std::is_same_v<format, ieee754_binary32>) {
|
|
2278
|
-
return std::uint32_t(cache >> (cache_bits - 1 - beta));
|
|
2279
|
-
}
|
|
2280
|
-
else {
|
|
2281
|
-
static_assert(std::is_same_v<format, ieee754_binary64>);
|
|
2282
|
-
return std::uint32_t(cache.high() >> (carrier_bits - 1 - beta));
|
|
2283
|
-
}
|
|
2284
|
-
}
|
|
2285
|
-
|
|
2286
|
-
static compute_mul_parity_result compute_mul_parity(carrier_uint two_f,
|
|
2287
|
-
cache_entry_type const& cache,
|
|
2288
|
-
int beta) noexcept {
|
|
2289
|
-
assert(beta >= 1);
|
|
2290
|
-
assert(beta < 64);
|
|
2291
|
-
|
|
2292
|
-
if constexpr (std::is_same_v<format, ieee754_binary32>) {
|
|
2293
|
-
auto r = wuint::umul96_lower64(two_f, cache);
|
|
2294
|
-
return {((r >> (64 - beta)) & 1) != 0, std::uint32_t(r >> (32 - beta)) == 0};
|
|
2295
|
-
}
|
|
2296
|
-
else {
|
|
2297
|
-
static_assert(std::is_same_v<format, ieee754_binary64>);
|
|
2298
|
-
auto r = wuint::umul192_lower128(two_f, cache);
|
|
2299
|
-
return {((r.high() >> (64 - beta)) & 1) != 0,
|
|
2300
|
-
((r.high() << beta) | (r.low() >> (64 - beta))) == 0};
|
|
2301
|
-
}
|
|
2302
|
-
}
|
|
2303
|
-
|
|
2304
|
-
static constexpr carrier_uint
|
|
2305
|
-
compute_left_endpoint_for_shorter_interval_case(cache_entry_type const& cache,
|
|
2306
|
-
int beta) noexcept {
|
|
2307
|
-
if constexpr (std::is_same_v<format, ieee754_binary32>) {
|
|
2308
|
-
return carrier_uint((cache - (cache >> (significand_bits + 2))) >>
|
|
2309
|
-
(cache_bits - significand_bits - 1 - beta));
|
|
2310
|
-
}
|
|
2311
|
-
else {
|
|
2312
|
-
static_assert(std::is_same_v<format, ieee754_binary64>);
|
|
2313
|
-
return (cache.high() - (cache.high() >> (significand_bits + 2))) >>
|
|
2314
|
-
(carrier_bits - significand_bits - 1 - beta);
|
|
2315
|
-
}
|
|
2316
|
-
}
|
|
2317
|
-
|
|
2318
|
-
static constexpr carrier_uint
|
|
2319
|
-
compute_right_endpoint_for_shorter_interval_case(cache_entry_type const& cache,
|
|
2320
|
-
int beta) noexcept {
|
|
2321
|
-
if constexpr (std::is_same_v<format, ieee754_binary32>) {
|
|
2322
|
-
return carrier_uint((cache + (cache >> (significand_bits + 1))) >>
|
|
2323
|
-
(cache_bits - significand_bits - 1 - beta));
|
|
2324
|
-
}
|
|
2325
|
-
else {
|
|
2326
|
-
static_assert(std::is_same_v<format, ieee754_binary64>);
|
|
2327
|
-
return (cache.high() + (cache.high() >> (significand_bits + 1))) >>
|
|
2328
|
-
(carrier_bits - significand_bits - 1 - beta);
|
|
2329
|
-
}
|
|
2330
|
-
}
|
|
2331
|
-
|
|
2332
|
-
static constexpr carrier_uint
|
|
2333
|
-
compute_round_up_for_shorter_interval_case(cache_entry_type const& cache,
|
|
2334
|
-
int beta) noexcept {
|
|
2335
|
-
if constexpr (std::is_same_v<format, ieee754_binary32>) {
|
|
2336
|
-
return (carrier_uint(cache >> (cache_bits - significand_bits - 2 - beta)) + 1) /
|
|
2337
|
-
2;
|
|
2338
|
-
}
|
|
2339
|
-
else {
|
|
2340
|
-
static_assert(std::is_same_v<format, ieee754_binary64>);
|
|
2341
|
-
return ((cache.high() >> (carrier_bits - significand_bits - 2 - beta)) + 1) / 2;
|
|
2342
|
-
}
|
|
2343
|
-
}
|
|
2344
|
-
|
|
2345
|
-
static constexpr bool
|
|
2346
|
-
is_right_endpoint_integer_shorter_interval(int exponent) noexcept {
|
|
2347
|
-
return exponent >= case_shorter_interval_right_endpoint_lower_threshold &&
|
|
2348
|
-
exponent <= case_shorter_interval_right_endpoint_upper_threshold;
|
|
2349
|
-
}
|
|
2350
|
-
|
|
2351
|
-
static constexpr bool is_left_endpoint_integer_shorter_interval(int exponent) noexcept {
|
|
2352
|
-
return exponent >= case_shorter_interval_left_endpoint_lower_threshold &&
|
|
2353
|
-
exponent <= case_shorter_interval_left_endpoint_upper_threshold;
|
|
2354
|
-
}
|
|
2355
|
-
};
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
2359
|
-
// Policy holder.
|
|
2360
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
2361
|
-
|
|
2362
|
-
namespace policy_impl {
|
|
2363
|
-
// The library will specify a list of accepted kinds of policies and their defaults, and
|
|
2364
|
-
// the user will pass a list of policies. The aim of helper classes/functions here is to
|
|
2365
|
-
// do the following:
|
|
2366
|
-
// 1. Check if the policy parameters given by the user are all valid; that means,
|
|
2367
|
-
// each of them should be of the kinds specified by the library.
|
|
2368
|
-
// If that's not the case, then the compilation fails.
|
|
2369
|
-
// 2. Check if multiple policy parameters for the same kind is specified by the user.
|
|
2370
|
-
// If that's the case, then the compilation fails.
|
|
2371
|
-
// 3. Build a class deriving from all policies the user have given, and also from
|
|
2372
|
-
// the default policies if the user did not specify one for some kinds.
|
|
2373
|
-
// A policy belongs to a certain kind if it is deriving from a base class.
|
|
2374
|
-
|
|
2375
|
-
// For a given kind, find a policy belonging to that kind.
|
|
2376
|
-
// Check if there are more than one such policies.
|
|
2377
|
-
enum class policy_found_info { not_found, unique, repeated };
|
|
2378
|
-
template <class Policy, policy_found_info info>
|
|
2379
|
-
struct found_policy_pair {
|
|
2380
|
-
using policy = Policy;
|
|
2381
|
-
static constexpr auto found_info = info;
|
|
2382
|
-
};
|
|
2383
|
-
|
|
2384
|
-
template <class Base, class DefaultPolicy>
|
|
2385
|
-
struct base_default_pair {
|
|
2386
|
-
using base = Base;
|
|
2387
|
-
|
|
2388
|
-
template <class FoundPolicyInfo>
|
|
2389
|
-
static constexpr FoundPolicyInfo get_policy_impl(FoundPolicyInfo) {
|
|
2390
|
-
return {};
|
|
2391
|
-
}
|
|
2392
|
-
template <class FoundPolicyInfo, class FirstPolicy, class... RemainingPolicies>
|
|
2393
|
-
static constexpr auto get_policy_impl(FoundPolicyInfo, FirstPolicy,
|
|
2394
|
-
RemainingPolicies... remainings) {
|
|
2395
|
-
if constexpr (std::is_base_of_v<Base, FirstPolicy>) {
|
|
2396
|
-
if constexpr (FoundPolicyInfo::found_info == policy_found_info::not_found) {
|
|
2397
|
-
return get_policy_impl(
|
|
2398
|
-
found_policy_pair<FirstPolicy, policy_found_info::unique>{},
|
|
2399
|
-
remainings...);
|
|
2400
|
-
}
|
|
2401
|
-
else {
|
|
2402
|
-
return get_policy_impl(
|
|
2403
|
-
found_policy_pair<FirstPolicy, policy_found_info::repeated>{},
|
|
2404
|
-
remainings...);
|
|
2405
|
-
}
|
|
2406
|
-
}
|
|
2407
|
-
else {
|
|
2408
|
-
return get_policy_impl(FoundPolicyInfo{}, remainings...);
|
|
2409
|
-
}
|
|
2410
|
-
}
|
|
2411
|
-
|
|
2412
|
-
template <class... Policies>
|
|
2413
|
-
static constexpr auto get_policy(Policies... policies) {
|
|
2414
|
-
return get_policy_impl(
|
|
2415
|
-
found_policy_pair<DefaultPolicy, policy_found_info::not_found>{},
|
|
2416
|
-
policies...);
|
|
2417
|
-
}
|
|
2418
|
-
};
|
|
2419
|
-
template <class... BaseDefaultPairs>
|
|
2420
|
-
struct base_default_pair_list {};
|
|
2421
|
-
|
|
2422
|
-
// Check if a given policy belongs to one of the kinds specified by the library.
|
|
2423
|
-
template <class Policy>
|
|
2424
|
-
constexpr bool check_policy_validity(Policy, base_default_pair_list<>) {
|
|
2425
|
-
return false;
|
|
2426
|
-
}
|
|
2427
|
-
template <class Policy, class FirstBaseDefaultPair, class... RemainingBaseDefaultPairs>
|
|
2428
|
-
constexpr bool check_policy_validity(
|
|
2429
|
-
Policy,
|
|
2430
|
-
base_default_pair_list<FirstBaseDefaultPair, RemainingBaseDefaultPairs...>) {
|
|
2431
|
-
return std::is_base_of_v<typename FirstBaseDefaultPair::base, Policy> ||
|
|
2432
|
-
check_policy_validity(
|
|
2433
|
-
Policy{}, base_default_pair_list<RemainingBaseDefaultPairs...>{});
|
|
2434
|
-
}
|
|
2435
|
-
|
|
2436
|
-
template <class BaseDefaultPairList>
|
|
2437
|
-
constexpr bool check_policy_list_validity(BaseDefaultPairList) {
|
|
2438
|
-
return true;
|
|
2439
|
-
}
|
|
2440
|
-
|
|
2441
|
-
template <class BaseDefaultPairList, class FirstPolicy, class... RemainingPolicies>
|
|
2442
|
-
constexpr bool check_policy_list_validity(BaseDefaultPairList, FirstPolicy,
|
|
2443
|
-
RemainingPolicies... remaining_policies) {
|
|
2444
|
-
return check_policy_validity(FirstPolicy{}, BaseDefaultPairList{}) &&
|
|
2445
|
-
check_policy_list_validity(BaseDefaultPairList{}, remaining_policies...);
|
|
2446
|
-
}
|
|
2447
|
-
|
|
2448
|
-
// Build policy_holder.
|
|
2449
|
-
template <bool repeated_, class... FoundPolicyPairs>
|
|
2450
|
-
struct found_policy_pair_list {
|
|
2451
|
-
static constexpr bool repeated = repeated_;
|
|
2452
|
-
};
|
|
2453
|
-
|
|
2454
|
-
template <class... Policies>
|
|
2455
|
-
struct policy_holder : Policies... {};
|
|
2456
|
-
|
|
2457
|
-
template <bool repeated, class... FoundPolicyPairs, class... Policies>
|
|
2458
|
-
constexpr auto
|
|
2459
|
-
make_policy_holder_impl(base_default_pair_list<>,
|
|
2460
|
-
found_policy_pair_list<repeated, FoundPolicyPairs...>,
|
|
2461
|
-
Policies...) {
|
|
2462
|
-
return found_policy_pair_list<repeated, FoundPolicyPairs...>{};
|
|
2463
|
-
}
|
|
2464
|
-
|
|
2465
|
-
template <class FirstBaseDefaultPair, class... RemainingBaseDefaultPairs, bool repeated,
|
|
2466
|
-
class... FoundPolicyPairs, class... Policies>
|
|
2467
|
-
constexpr auto make_policy_holder_impl(
|
|
2468
|
-
base_default_pair_list<FirstBaseDefaultPair, RemainingBaseDefaultPairs...>,
|
|
2469
|
-
found_policy_pair_list<repeated, FoundPolicyPairs...>, Policies... policies) {
|
|
2470
|
-
using new_found_policy_pair =
|
|
2471
|
-
decltype(FirstBaseDefaultPair::get_policy(policies...));
|
|
2472
|
-
|
|
2473
|
-
return make_policy_holder_impl(
|
|
2474
|
-
base_default_pair_list<RemainingBaseDefaultPairs...>{},
|
|
2475
|
-
found_policy_pair_list < repeated ||
|
|
2476
|
-
new_found_policy_pair::found_info == policy_found_info::repeated,
|
|
2477
|
-
new_found_policy_pair, FoundPolicyPairs... > {}, policies...);
|
|
2478
|
-
}
|
|
2479
|
-
|
|
2480
|
-
template <bool repeated, class... RawPolicies>
|
|
2481
|
-
constexpr auto convert_to_policy_holder(found_policy_pair_list<repeated>,
|
|
2482
|
-
RawPolicies...) {
|
|
2483
|
-
return policy_holder<RawPolicies...>{};
|
|
2484
|
-
}
|
|
2485
|
-
|
|
2486
|
-
template <bool repeated, class FirstFoundPolicyPair, class... RemainingFoundPolicyPairs,
|
|
2487
|
-
class... RawPolicies>
|
|
2488
|
-
constexpr auto
|
|
2489
|
-
convert_to_policy_holder(found_policy_pair_list<repeated, FirstFoundPolicyPair,
|
|
2490
|
-
RemainingFoundPolicyPairs...>,
|
|
2491
|
-
RawPolicies... policies) {
|
|
2492
|
-
return convert_to_policy_holder(
|
|
2493
|
-
found_policy_pair_list<repeated, RemainingFoundPolicyPairs...>{},
|
|
2494
|
-
typename FirstFoundPolicyPair::policy{}, policies...);
|
|
2495
|
-
}
|
|
2496
|
-
|
|
2497
|
-
template <class BaseDefaultPairList, class... Policies>
|
|
2498
|
-
constexpr auto make_policy_holder(BaseDefaultPairList, Policies... policies) {
|
|
2499
|
-
static_assert(check_policy_list_validity(BaseDefaultPairList{}, Policies{}...),
|
|
2500
|
-
"jkj::dragonbox: an invalid policy is specified");
|
|
2501
|
-
|
|
2502
|
-
using policy_pair_list = decltype(make_policy_holder_impl(
|
|
2503
|
-
BaseDefaultPairList{}, found_policy_pair_list<false>{}, policies...));
|
|
2504
|
-
|
|
2505
|
-
static_assert(!policy_pair_list::repeated,
|
|
2506
|
-
"jkj::dragonbox: each policy should be specified at most once");
|
|
2507
|
-
|
|
2508
|
-
return convert_to_policy_holder(policy_pair_list{});
|
|
2509
|
-
}
|
|
2510
|
-
}
|
|
2511
|
-
}
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
2515
|
-
// The interface function.
|
|
2516
|
-
////////////////////////////////////////////////////////////////////////////////////////
|
|
2517
|
-
|
|
2518
|
-
template <class Float, class FloatTraits = default_float_traits<Float>, class... Policies>
|
|
2519
|
-
JKJ_SAFEBUFFERS auto
|
|
2520
|
-
to_decimal(signed_significand_bits<Float, FloatTraits> signed_significand_bits,
|
|
2521
|
-
unsigned int exponent_bits, Policies... policies) noexcept {
|
|
2522
|
-
// Build policy holder type.
|
|
2523
|
-
using namespace detail::policy_impl;
|
|
2524
|
-
using policy_holder = decltype(make_policy_holder(
|
|
2525
|
-
base_default_pair_list<base_default_pair<sign::base, sign::return_sign>,
|
|
2526
|
-
base_default_pair<trailing_zero::base, trailing_zero::remove>,
|
|
2527
|
-
base_default_pair<decimal_to_binary_rounding::base,
|
|
2528
|
-
decimal_to_binary_rounding::nearest_to_even>,
|
|
2529
|
-
base_default_pair<binary_to_decimal_rounding::base,
|
|
2530
|
-
binary_to_decimal_rounding::to_even>,
|
|
2531
|
-
base_default_pair<cache::base, cache::full>>{},
|
|
2532
|
-
policies...));
|
|
2533
|
-
|
|
2534
|
-
using return_type =
|
|
2535
|
-
decimal_fp<typename FloatTraits::carrier_uint, policy_holder::return_has_sign,
|
|
2536
|
-
policy_holder::report_trailing_zeros>;
|
|
2537
|
-
|
|
2538
|
-
return_type ret = policy_holder::delegate(
|
|
2539
|
-
signed_significand_bits,
|
|
2540
|
-
[exponent_bits, signed_significand_bits](auto interval_type_provider) {
|
|
2541
|
-
using format = typename FloatTraits::format;
|
|
2542
|
-
constexpr auto tag = decltype(interval_type_provider)::tag;
|
|
2543
|
-
|
|
2544
|
-
auto two_fc = signed_significand_bits.remove_sign_bit_and_shift();
|
|
2545
|
-
auto exponent = int(exponent_bits);
|
|
2546
|
-
|
|
2547
|
-
if constexpr (tag == decimal_to_binary_rounding::tag_t::to_nearest) {
|
|
2548
|
-
// Is the input a normal number?
|
|
2549
|
-
if (exponent != 0) {
|
|
2550
|
-
exponent += format::exponent_bias - format::significand_bits;
|
|
2551
|
-
|
|
2552
|
-
// Shorter interval case; proceed like Schubfach.
|
|
2553
|
-
// One might think this condition is wrong, since when exponent_bits == 1
|
|
2554
|
-
// and two_fc == 0, the interval is actullay regular. However, it turns out
|
|
2555
|
-
// that this seemingly wrong condition is actually fine, because the end
|
|
2556
|
-
// result is anyway the same.
|
|
2557
|
-
//
|
|
2558
|
-
// [binary32]
|
|
2559
|
-
// (fc-1/2) * 2^e = 1.175'494'28... * 10^-38
|
|
2560
|
-
// (fc-1/4) * 2^e = 1.175'494'31... * 10^-38
|
|
2561
|
-
// fc * 2^e = 1.175'494'35... * 10^-38
|
|
2562
|
-
// (fc+1/2) * 2^e = 1.175'494'42... * 10^-38
|
|
2563
|
-
//
|
|
2564
|
-
// Hence, shorter_interval_case will return 1.175'494'4 * 10^-38.
|
|
2565
|
-
// 1.175'494'3 * 10^-38 is also a correct shortest representation that will
|
|
2566
|
-
// be rejected if we assume shorter interval, but 1.175'494'4 * 10^-38 is
|
|
2567
|
-
// closer to the true value so it doesn't matter.
|
|
2568
|
-
//
|
|
2569
|
-
// [binary64]
|
|
2570
|
-
// (fc-1/2) * 2^e = 2.225'073'858'507'201'13... * 10^-308
|
|
2571
|
-
// (fc-1/4) * 2^e = 2.225'073'858'507'201'25... * 10^-308
|
|
2572
|
-
// fc * 2^e = 2.225'073'858'507'201'38... * 10^-308
|
|
2573
|
-
// (fc+1/2) * 2^e = 2.225'073'858'507'201'63... * 10^-308
|
|
2574
|
-
//
|
|
2575
|
-
// Hence, shorter_interval_case will return 2.225'073'858'507'201'4 *
|
|
2576
|
-
// 10^-308. This is indeed of the shortest length, and it is the unique one
|
|
2577
|
-
// closest to the true value among valid representations of the same length.
|
|
2578
|
-
static_assert(std::is_same_v<format, ieee754_binary32> ||
|
|
2579
|
-
std::is_same_v<format, ieee754_binary64>);
|
|
2580
|
-
|
|
2581
|
-
if (two_fc == 0) {
|
|
2582
|
-
return decltype(interval_type_provider)::invoke_shorter_interval_case(
|
|
2583
|
-
signed_significand_bits, [exponent](auto... additional_args) {
|
|
2584
|
-
return detail::impl<Float, FloatTraits>::
|
|
2585
|
-
template compute_nearest_shorter<
|
|
2586
|
-
return_type,
|
|
2587
|
-
typename decltype(interval_type_provider)::
|
|
2588
|
-
shorter_interval_type,
|
|
2589
|
-
typename policy_holder::trailing_zero_policy,
|
|
2590
|
-
typename policy_holder::
|
|
2591
|
-
binary_to_decimal_rounding_policy,
|
|
2592
|
-
typename policy_holder::cache_policy>(
|
|
2593
|
-
exponent, additional_args...);
|
|
2594
|
-
});
|
|
2595
|
-
}
|
|
2596
|
-
|
|
2597
|
-
two_fc |= (decltype(two_fc)(1) << (format::significand_bits + 1));
|
|
2598
|
-
}
|
|
2599
|
-
// Is the input a subnormal number?
|
|
2600
|
-
else {
|
|
2601
|
-
exponent = format::min_exponent - format::significand_bits;
|
|
2602
|
-
}
|
|
2603
|
-
|
|
2604
|
-
return decltype(interval_type_provider)::invoke_normal_interval_case(
|
|
2605
|
-
signed_significand_bits, [two_fc, exponent](auto... additional_args) {
|
|
2606
|
-
return detail::impl<Float, FloatTraits>::
|
|
2607
|
-
template compute_nearest_normal<
|
|
2608
|
-
return_type,
|
|
2609
|
-
typename decltype(interval_type_provider)::normal_interval_type,
|
|
2610
|
-
typename policy_holder::trailing_zero_policy,
|
|
2611
|
-
typename policy_holder::binary_to_decimal_rounding_policy,
|
|
2612
|
-
typename policy_holder::cache_policy>(two_fc, exponent,
|
|
2613
|
-
additional_args...);
|
|
2614
|
-
});
|
|
2615
|
-
}
|
|
2616
|
-
else if constexpr (tag == decimal_to_binary_rounding::tag_t::left_closed_directed) {
|
|
2617
|
-
// Is the input a normal number?
|
|
2618
|
-
if (exponent != 0) {
|
|
2619
|
-
exponent += format::exponent_bias - format::significand_bits;
|
|
2620
|
-
two_fc |= (decltype(two_fc)(1) << (format::significand_bits + 1));
|
|
2621
|
-
}
|
|
2622
|
-
// Is the input a subnormal number?
|
|
2623
|
-
else {
|
|
2624
|
-
exponent = format::min_exponent - format::significand_bits;
|
|
2625
|
-
}
|
|
2626
|
-
|
|
2627
|
-
return detail::impl<Float>::template compute_left_closed_directed<
|
|
2628
|
-
return_type, typename policy_holder::trailing_zero_policy,
|
|
2629
|
-
typename policy_holder::cache_policy>(two_fc, exponent);
|
|
2630
|
-
}
|
|
2631
|
-
else {
|
|
2632
|
-
static_assert(tag == decimal_to_binary_rounding::tag_t::right_closed_directed);
|
|
2633
|
-
|
|
2634
|
-
bool shorter_interval = false;
|
|
2635
|
-
|
|
2636
|
-
// Is the input a normal number?
|
|
2637
|
-
if (exponent != 0) {
|
|
2638
|
-
if (two_fc == 0 && exponent != 1) {
|
|
2639
|
-
shorter_interval = true;
|
|
2640
|
-
}
|
|
2641
|
-
exponent += format::exponent_bias - format::significand_bits;
|
|
2642
|
-
two_fc |= (decltype(two_fc)(1) << (format::significand_bits + 1));
|
|
2643
|
-
}
|
|
2644
|
-
// Is the input a subnormal number?
|
|
2645
|
-
else {
|
|
2646
|
-
exponent = format::min_exponent - format::significand_bits;
|
|
2647
|
-
}
|
|
2648
|
-
|
|
2649
|
-
return detail::impl<Float>::template compute_right_closed_directed<
|
|
2650
|
-
return_type, typename policy_holder::trailing_zero_policy,
|
|
2651
|
-
typename policy_holder::cache_policy>(two_fc, exponent, shorter_interval);
|
|
2652
|
-
}
|
|
2653
|
-
});
|
|
2654
|
-
|
|
2655
|
-
policy_holder::handle_sign(signed_significand_bits, ret);
|
|
2656
|
-
return ret;
|
|
2657
|
-
}
|
|
2658
|
-
|
|
2659
|
-
template <class Float, class FloatTraits = default_float_traits<Float>, class... Policies>
|
|
2660
|
-
auto to_decimal(Float x, Policies... policies) noexcept {
|
|
2661
|
-
auto const br = float_bits<Float, FloatTraits>(x);
|
|
2662
|
-
auto const exponent_bits = br.extract_exponent_bits();
|
|
2663
|
-
auto const s = br.remove_exponent_bits(exponent_bits);
|
|
2664
|
-
assert(br.is_finite());
|
|
2665
|
-
|
|
2666
|
-
return to_decimal<Float, FloatTraits>(s, exponent_bits, policies...);
|
|
2667
|
-
}
|
|
2668
|
-
}
|
|
2669
|
-
|
|
2670
|
-
#undef JKJ_FORCEINLINE
|
|
2671
|
-
#undef JKJ_SAFEBUFFERS
|
|
2672
|
-
#undef JKJ_DRAGONBOX_HAS_BUILTIN
|
|
2673
|
-
|
|
2674
|
-
#endif
|