├── .clang-tidy ├── .gcov └── make │ ├── make_gcov_01_generic.gmk │ ├── make_gcov_02_files.gmk │ └── make_gcov_03_flags.gmk ├── .github ├── toolchains │ └── gcc.cmake └── workflows │ ├── CodeQL.yml │ ├── wide_integer.yml │ ├── wide_integer_codecov.yml │ ├── wide_integer_fuzzing.yml │ └── wide_integer_sonar.yml ├── .gitignore ├── .props └── Directory.Build.props ├── .tidy └── make │ ├── make_tidy_01_generic.gmk │ ├── make_tidy_02_files.gmk │ └── make_tidy_03_flags.gmk ├── CMakeLists.txt ├── LICENSE_1_0.txt ├── README.md ├── boost └── multiprecision │ └── uintwide_t_backend.hpp ├── codecov.yml ├── examples ├── CMakeLists.txt ├── build │ └── test_examples.sh ├── example000_numeric_limits.cpp ├── example000a_builtin_convert.cpp ├── example001_mul_div.cpp ├── example001a_div_mod.cpp ├── example002_shl_shr.cpp ├── example003_sqrt.cpp ├── example003a_cbrt.cpp ├── example004_rootk_pow.cpp ├── example005_powm.cpp ├── example005a_pow_factors_of_p99.cpp ├── example006_gcd.cpp ├── example007_random_generator.cpp ├── example008_miller_rabin_prime.cpp ├── example008a_miller_rabin_prime.cpp ├── example009_timed_mul.cpp ├── example009a_timed_mul_4_by_4.cpp ├── example009b_timed_mul_8_by_8.cpp ├── example010_uint48_t.cpp ├── example011_uint24_t.cpp ├── example012_rsa_crypto.cpp ├── example013_ecdsa_sign_verify.cpp ├── example014_pi_spigot_wide.cpp └── example_uintwide_t.h ├── math └── wide_integer │ └── uintwide_t.h ├── run_fuzzing.sh ├── sonar-project.properties ├── target ├── build │ └── test_examples_emulator.gdb └── micros │ └── stm32f429 │ └── make │ ├── single │ └── crt.cpp │ └── stm32f429.ld ├── test ├── CMakeLists.txt ├── coverity.c ├── fuzzing │ ├── test_fuzzing_add.cpp │ ├── test_fuzzing_div.cpp │ ├── test_fuzzing_mul.cpp │ ├── test_fuzzing_powm.cpp │ ├── test_fuzzing_prime.cpp │ ├── test_fuzzing_sdiv.cpp │ ├── test_fuzzing_sqrt.cpp │ └── test_fuzzing_sub.cpp ├── parallel_for.h ├── stopwatch.h ├── test.cpp ├── test.hpp ├── test_arithmetic.hpp ├── test_uintwide_t.h ├── test_uintwide_t_boost_backend.cpp ├── test_uintwide_t_boost_backend_via_test_arithmetic.cpp ├── test_uintwide_t_edge_cases.cpp ├── test_uintwide_t_examples.cpp ├── test_uintwide_t_float_convert.cpp ├── test_uintwide_t_int_convert.cpp ├── test_uintwide_t_n_base.cpp ├── test_uintwide_t_n_base.h ├── test_uintwide_t_n_binary_ops_base.cpp ├── test_uintwide_t_n_binary_ops_base.h ├── test_uintwide_t_n_binary_ops_mul_div_4_by_4_template.h ├── test_uintwide_t_n_binary_ops_mul_n_by_m_template.h ├── test_uintwide_t_n_binary_ops_template.h ├── test_uintwide_t_n_binary_ops_template_signed.h ├── test_uintwide_t_n_number_theory_funcs_template.h ├── test_uintwide_t_spot_values.cpp └── test_uintwide_t_xtra_from_issue_335.cpp ├── util └── utility │ └── util_pseudorandom_time_point_seed.h ├── wide_integer.sln ├── wide_integer.vcxproj ├── wide_integer.vcxproj.filters ├── wide_integer_vs2022.sln ├── wide_integer_vs2022.vcxproj └── wide_integer_vs2022.vcxproj.filters /.gcov/make/make_gcov_01_generic.gmk: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Copyright Christopher Kormanyos 2022 - 2024. 3 | # Distributed under the Boost Software License, 4 | # Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | # or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | # ------------------------------------------------------------------------------ 7 | 8 | PATH_MAKE = $(CURDIR) 9 | PATH_PRJ = $(PATH_MAKE)/../.. 10 | PATH_SRC = $(PATH_PRJ) 11 | PATH_BIN = $(PATH_MAKE)/bin 12 | PATH_ERR = $(PATH_MAKE)/err 13 | PATH_OBJ = $(PATH_MAKE)/obj 14 | 15 | CAT = cat 16 | GNUECHO = echo 17 | LS = ls 18 | MKDIR = mkdir 19 | GCOV = gcov 20 | LCOV = lcov 21 | GENHTML = genhtml 22 | RM = rm 23 | SED = sed 24 | 25 | include make_gcov_02_files.gmk 26 | include make_gcov_03_flags.gmk 27 | 28 | FILES_ALL = $(FILES_PRJ) 29 | FILES_O = $(addprefix $(PATH_OBJ)/, $(notdir $(addsuffix .o, $(FILES_ALL)))) 30 | FILES_GCOV = $(addprefix $(PATH_OBJ)/, $(notdir $(addsuffix .gcov, $(FILES_ALL)))) 31 | 32 | # ------------------------------------------------------------------------------ 33 | # VPATH definition: VPATH is required for make to find the source files. 34 | # ------------------------------------------------------------------------------ 35 | VPATH := $(sort $(dir $(FILES_ALL))) 36 | 37 | 38 | # ------------------------------------------------------------------------------ 39 | # Executable file: 40 | # ------------------------------------------------------------------------------ 41 | 42 | .PHONY: $(PATH_BIN)/wide_integer.exe 43 | $(PATH_BIN)/wide_integer.exe: $(FILES_O) 44 | # Link coverage-instrumented executable 45 | @$(GNUECHO) +++ link object files to $(PATH_BIN)/wide_integer.exe 46 | @$(CC) -x none $(CXXFLAGS) $(FILES_O) -o $(PATH_BIN)/wide_integer.exe 47 | @$(GNUECHO) 48 | 49 | 50 | # ------------------------------------------------------------------------------ 51 | # Main dependency: 52 | # Compile all files and link them. 53 | # Run gcov and get results. 54 | # (See also https://github.com/codecov/example-cpp11-cmake) 55 | # ------------------------------------------------------------------------------ 56 | 57 | .PHONY: gcov 58 | gcov: $(PATH_BIN)/wide_integer.exe 59 | # Obtain results 60 | @$(GNUECHO) +++ execute $(PATH_BIN)/wide_integer.exe 61 | @$(PATH_BIN)/wide_integer.exe 62 | @$(GNUECHO) 63 | @$(GNUECHO) +++ running gcov 64 | @$(GCOV) $(GCOV_FLAGS) $(addsuffix .cpp,$(FILES_PRJ)) 65 | @$(GNUECHO) 66 | @$(GNUECHO) +++ running lcov 67 | @$(LCOV) $(LCOV_BRANCH) -c --directory obj --output-file coverage_unfiltered.info 68 | @$(LCOV) $(LCOV_BRANCH) --remove coverage_unfiltered.info $(LCOV_REMOVES) --output-file coverage.info 69 | @$(GNUECHO) 70 | @$(GNUECHO) +++ running genhtml 71 | @$(GENHTML) coverage.info $(LCOV_BRANCH) --demangle-cpp --output-directory $(PATH_BIN)/report 72 | @$(GNUECHO) 73 | 74 | # ------------------------------------------------------------------------------ 75 | # Clean temporary files. 76 | # ------------------------------------------------------------------------------ 77 | 78 | .PHONY: clean 79 | clean: 80 | # creating output directories 81 | @$(GNUECHO) +++ cleaning output directories 82 | @-$(RM) -rf $(PATH_BIN)* || uname -r 83 | @-$(RM) -rf $(PATH_ERR)* || uname -r 84 | @-$(RM) -rf $(PATH_OBJ)* || uname -r 85 | @-$(RM) -f *.gcov || uname -r 86 | @-$(RM) -f coverage* || uname -r 87 | @$(GNUECHO) 88 | 89 | 90 | # ------------------------------------------------------------------------------ 91 | # Prepare the gcov build. 92 | # ------------------------------------------------------------------------------ 93 | 94 | .PHONY: prepare 95 | prepare: clean 96 | @$(GNUECHO) +++ creating output directories 97 | @-$(MKDIR) -p $(PATH_BIN) 98 | @-$(MKDIR) -p $(PATH_ERR) 99 | @-$(MKDIR) -p $(PATH_OBJ) 100 | @$(GNUECHO) 101 | @$(GNUECHO) +++ print gcov version 102 | @$(GCOV) --version 103 | @$(GNUECHO) 104 | @$(GNUECHO) +++ print include paths 105 | @$(GNUECHO) $(C_INCLUDES) 106 | @$(GNUECHO) 107 | 108 | # ------------------------------------------------------------------------------ 109 | # pattern rule for compilation of cpp-files 110 | # ------------------------------------------------------------------------------ 111 | $(PATH_OBJ)/%.o : %.cpp 112 | @-$(GNUECHO) +++ compiling: $(notdir $<) to $(notdir $(PATH_OBJ)/$(basename $(@F)).o) 113 | @-$(CC) $(CXXFLAGS) -x c++ -c $(C_INCLUDES) $(C_DEFINES) $< -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err 114 | @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|:\([0-9]*\):|(\1) :|' $(PATH_ERR)/$(basename $(@F)).err 115 | -------------------------------------------------------------------------------- /.gcov/make/make_gcov_02_files.gmk: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Copyright Christopher Kormanyos 2022. 3 | # Distributed under the Boost Software License, 4 | # Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | # or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | # ------------------------------------------------------------------------------ 7 | 8 | FILES_PRJ = $(PATH_SRC)/test/test \ 9 | $(PATH_SRC)/test/test_uintwide_t_boost_backend \ 10 | $(PATH_SRC)/test/test_uintwide_t_edge_cases \ 11 | $(PATH_SRC)/test/test_uintwide_t_examples \ 12 | $(PATH_SRC)/test/test_uintwide_t_float_convert \ 13 | $(PATH_SRC)/test/test_uintwide_t_int_convert \ 14 | $(PATH_SRC)/test/test_uintwide_t_n_base \ 15 | $(PATH_SRC)/test/test_uintwide_t_n_binary_ops_base \ 16 | $(PATH_SRC)/test/test_uintwide_t_spot_values \ 17 | $(PATH_SRC)/examples/example000a_builtin_convert \ 18 | $(PATH_SRC)/examples/example000_numeric_limits \ 19 | $(PATH_SRC)/examples/example001_mul_div \ 20 | $(PATH_SRC)/examples/example001a_div_mod \ 21 | $(PATH_SRC)/examples/example002_shl_shr \ 22 | $(PATH_SRC)/examples/example003_sqrt \ 23 | $(PATH_SRC)/examples/example003a_cbrt \ 24 | $(PATH_SRC)/examples/example004_rootk_pow \ 25 | $(PATH_SRC)/examples/example005_powm \ 26 | $(PATH_SRC)/examples/example005a_pow_factors_of_p99 \ 27 | $(PATH_SRC)/examples/example006_gcd \ 28 | $(PATH_SRC)/examples/example007_random_generator \ 29 | $(PATH_SRC)/examples/example008_miller_rabin_prime \ 30 | $(PATH_SRC)/examples/example008a_miller_rabin_prime \ 31 | $(PATH_SRC)/examples/example009_timed_mul \ 32 | $(PATH_SRC)/examples/example009a_timed_mul_4_by_4 \ 33 | $(PATH_SRC)/examples/example009b_timed_mul_8_by_8 \ 34 | $(PATH_SRC)/examples/example010_uint48_t \ 35 | $(PATH_SRC)/examples/example011_uint24_t \ 36 | $(PATH_SRC)/examples/example012_rsa_crypto \ 37 | $(PATH_SRC)/examples/example013_ecdsa_sign_verify \ 38 | $(PATH_SRC)/examples/example014_pi_spigot_wide 39 | -------------------------------------------------------------------------------- /.gcov/make/make_gcov_03_flags.gmk: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Copyright Christopher Kormanyos 2022 - 2024. 3 | # Distributed under the Boost Software License, 4 | # Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | # or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | # ------------------------------------------------------------------------------ 7 | 8 | BOOST_ROOT_FOR_GCOV = /mnt/c/boost/boost_1_85_0 9 | CC = g++ 10 | STD = c++14 11 | ALL_COV = 0 12 | 13 | ifneq ($(MY_BOOST_ROOT),) 14 | BOOST_ROOT_FOR_GCOV := $(MY_BOOST_ROOT) 15 | endif 16 | 17 | ifneq ($(MY_CC),) 18 | CC := $(MY_CC) 19 | endif 20 | 21 | ifneq ($(MY_STD),) 22 | STD := $(MY_STD) 23 | endif 24 | 25 | ifneq ($(MY_STD),) 26 | STD := $(MY_STD) 27 | endif 28 | 29 | ifneq ($(MY_ALL_COV),) 30 | ALL_COV := $(MY_ALL_COV) 31 | endif 32 | 33 | CXXFLAGS = -march=native \ 34 | -mtune=native \ 35 | -O2 \ 36 | -Wall \ 37 | -Wextra \ 38 | -Wconversion \ 39 | -Wsign-conversion \ 40 | -std=$(STD) \ 41 | -pthread \ 42 | -lpthread \ 43 | -fno-inline-functions \ 44 | -fprofile-arcs \ 45 | -ftest-coverage 46 | 47 | C_DEFINES = WIDE_INTEGER_HAS_COVERAGE \ 48 | WIDE_INTEGER_HAS_LIMB_TYPE_UINT64 \ 49 | WIDE_INTEGER_HAS_MUL_8_BY_8_UNROLL 50 | 51 | C_INCLUDES = $(PATH_SRC) \ 52 | $(BOOST_ROOT_FOR_GCOV) 53 | 54 | C_DEFINES :=$(addprefix -D,$(C_DEFINES)) 55 | C_INCLUDES :=$(addprefix -I,$(C_INCLUDES)) 56 | 57 | GCOV_FLAGS = --object-directory obj \ 58 | --demangled-names 59 | 60 | 61 | # ------------------------------------------------------------------------------ 62 | # All gcov flags: The GCOV_FLAGS below are equivalent to -abcfu 63 | # ------------------------------------------------------------------------------ 64 | 65 | ifneq ($(ALL_COV),0) 66 | GCOV_FLAGS := $(GCOV_FLAGS) \ 67 | --all-blocks \ 68 | --branch-counts \ 69 | --branch-probabilities \ 70 | --function-summaries \ 71 | --unconditional-branches 72 | endif 73 | 74 | LCOV_BRANCH = 75 | 76 | ifneq ($(ALL_COV),0) 77 | LCOV_BRANCH := --rc lcov_branch_coverage=1 78 | endif 79 | 80 | LCOV_REMOVES = '/usr/*' \ 81 | '*boost/*' 82 | -------------------------------------------------------------------------------- /.github/toolchains/gcc.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_FLAGS_INIT "-Wall -Wconversion -Werror -Wextra -Wno-psabi -Wpedantic -Wshadow -Wundef") 2 | -------------------------------------------------------------------------------- /.github/workflows/CodeQL.yml: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Copyright Christopher Kormanyos 2022 - 2024. 3 | # Distributed under the Boost Software License, 4 | # Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | # or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | # ------------------------------------------------------------------------------ 7 | 8 | name: CodeQL 9 | on: 10 | push: 11 | branches: 12 | - '**' 13 | pull_request: 14 | types: [opened, synchronize, reopened] 15 | jobs: 16 | analyze: 17 | name: Analyze 18 | runs-on: ubuntu-latest 19 | permissions: 20 | actions: read 21 | contents: read 22 | security-events: write 23 | strategy: 24 | fail-fast: false 25 | matrix: 26 | language: [ cpp ] 27 | 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v4 31 | 32 | - name: clone-submods-bootstrap-headers-boost-develop 33 | run: | 34 | git clone -b develop --depth 1 https://github.com/boostorg/boost.git ../boost-root 35 | cd ../boost-root 36 | git submodule update --init tools 37 | git submodule update --init libs/config 38 | git submodule update --init libs/multiprecision 39 | ./bootstrap.sh 40 | ./b2 headers 41 | 42 | - name: Configure (cpp) 43 | if: ${{ matrix.language == 'cpp' }} 44 | run: echo configure_command_empty 45 | 46 | - name: Initialize CodeQL 47 | uses: github/codeql-action/init@v3 48 | with: 49 | languages: ${{ matrix.language }} 50 | queries: +security-and-quality 51 | 52 | - name: Build cpp 53 | if: ${{ matrix.language == 'cpp' }} 54 | run: | 55 | echo 'build application on the command line' 56 | g++ -fno-exceptions -fno-rtti -finline-functions -m64 -O2 -Werror -Wall -Wextra -Wconversion -Wsign-conversion -Wshadow -Wundef -Wunused-parameter -Wuninitialized -Wunreachable-code -Winit-self -Wzero-as-null-pointer-constant -std=c++14 -DWIDE_INTEGER_HAS_LIMB_TYPE_UINT64 -I. -I../boost-root -pthread -lpthread test/test.cpp test/test_uintwide_t_boost_backend.cpp test/test_uintwide_t_edge_cases.cpp test/test_uintwide_t_examples.cpp test/test_uintwide_t_float_convert.cpp test/test_uintwide_t_int_convert.cpp test/test_uintwide_t_n_base.cpp test/test_uintwide_t_n_binary_ops_base.cpp test/test_uintwide_t_spot_values.cpp examples/example000_numeric_limits.cpp examples/example000a_builtin_convert.cpp examples/example001_mul_div.cpp examples/example001a_div_mod.cpp examples/example002_shl_shr.cpp examples/example003_sqrt.cpp examples/example003a_cbrt.cpp examples/example004_rootk_pow.cpp examples/example005_powm.cpp examples/example005a_pow_factors_of_p99.cpp examples/example006_gcd.cpp examples/example007_random_generator.cpp examples/example008_miller_rabin_prime.cpp examples/example008a_miller_rabin_prime.cpp examples/example009_timed_mul.cpp examples/example009a_timed_mul_4_by_4.cpp examples/example009b_timed_mul_8_by_8.cpp examples/example010_uint48_t.cpp examples/example011_uint24_t.cpp examples/example012_rsa_crypto.cpp examples/example013_ecdsa_sign_verify.cpp examples/example014_pi_spigot_wide.cpp -o wide_integer.exe 57 | 58 | - name: Perform CodeQL Analysis 59 | uses: github/codeql-action/analyze@v3 60 | with: 61 | category: "/language:${{ matrix.language }}" 62 | -------------------------------------------------------------------------------- /.github/workflows/wide_integer_codecov.yml: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Copyright Christopher Kormanyos 2022 - 2024. 3 | # Distributed under the Boost Software License, 4 | # Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | # or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | # ------------------------------------------------------------------------------ 7 | 8 | name: wide_integer_codecov 9 | on: 10 | push: 11 | branches: 12 | - master 13 | pull_request: 14 | types: [opened, synchronize, reopened] 15 | jobs: 16 | gnumake-gcc-gcov-native: 17 | runs-on: ubuntu-latest 18 | defaults: 19 | run: 20 | shell: bash 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | standard: [ c++14 ] 25 | compiler: [ g++ ] 26 | steps: 27 | - uses: actions/checkout@v4 28 | with: 29 | fetch-depth: '0' 30 | - name: update-tools 31 | run: sudo apt install lcov 32 | - name: clone-submods-bootstrap-headers-boost-develop 33 | run: | 34 | git clone -b develop --depth 1 https://github.com/boostorg/boost.git ../boost-root 35 | cd ../boost-root 36 | git submodule update --init tools 37 | git submodule update --init libs/config 38 | git submodule update --init libs/multiprecision 39 | ./bootstrap.sh 40 | ./b2 headers 41 | - name: gnumake-gcc-gcov-native 42 | run: | 43 | grep BOOST_VERSION ../boost-root/boost/version.hpp 44 | cd .gcov/make 45 | echo "build and run gcov/lcov/genhtml" 46 | echo "make prepare -f make_gcov_01_generic.gmk MY_ALL_COV=0 MY_BOOST_ROOT=../../../boost-root MY_CC=${{ matrix.compiler }} MY_STD=${{ matrix.standard }}" 47 | echo 48 | make prepare -f make_gcov_01_generic.gmk MY_ALL_COV=0 MY_BOOST_ROOT=../../../boost-root MY_CC=${{ matrix.compiler }} MY_STD=${{ matrix.standard }} 49 | echo 50 | echo "make gcov -f make_gcov_01_generic.gmk --jobs=8 MY_ALL_COV=0 MY_BOOST_ROOT=../../../boost-root MY_CC=${{ matrix.compiler }} MY_STD=${{ matrix.standard }}" 51 | echo 52 | make gcov -f make_gcov_01_generic.gmk --jobs=8 MY_ALL_COV=0 MY_BOOST_ROOT=../../../boost-root MY_CC=${{ matrix.compiler }} MY_STD=${{ matrix.standard }} 53 | echo 54 | echo "return to wide-integer root directory" 55 | cd ../.. 56 | - name: upload-codecov 57 | uses: codecov/codecov-action@v4 58 | with: 59 | plugin: gcov 60 | file: ${{ runner.workspace }}/wide-integer/.gcov/make/coverage.info 61 | token: ${{ secrets.CODECOV_TOKEN }} 62 | fail_ci_if_error: true 63 | verbose: false 64 | -------------------------------------------------------------------------------- /.github/workflows/wide_integer_fuzzing.yml: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Copyright Christopher Kormanyos 2024. 3 | # Distributed under the Boost Software License, 4 | # Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | # or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | # ------------------------------------------------------------------------------ 7 | 8 | name: wide_integer_fuzzing 9 | on: 10 | push: 11 | branches: 12 | - '**' 13 | pull_request: 14 | schedule: 15 | - cron: '0 2 * * *' # run at 2:00 AM UTC 16 | jobs: 17 | clang-fuzzing: 18 | runs-on: ubuntu-latest 19 | defaults: 20 | run: 21 | shell: bash 22 | strategy: 23 | fail-fast: false 24 | matrix: 25 | compiler: [ clang++ ] 26 | steps: 27 | - uses: actions/checkout@v4 28 | with: 29 | fetch-depth: '0' 30 | - name: update-tools 31 | run: sudo apt install llvm lld 32 | - name: clone-submods-bootstrap-headers-boost-develop 33 | run: | 34 | git clone -b develop --depth 1 https://github.com/boostorg/boost.git ../boost-root 35 | cd ../boost-root 36 | git submodule update --init tools 37 | git submodule update --init libs/config 38 | git submodule update --init libs/multiprecision 39 | ./bootstrap.sh 40 | ./b2 headers 41 | - name: clang-fuzzing 42 | run: | 43 | grep BOOST_VERSION ../boost-root/boost/version.hpp 44 | ${{ matrix.compiler }} -v 45 | echo "run fuzzing test" 46 | ./run_fuzzing.sh 47 | -------------------------------------------------------------------------------- /.github/workflows/wide_integer_sonar.yml: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Copyright Christopher Kormanyos 2022 - 2024. 3 | # Distributed under the Boost Software License, 4 | # Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | # or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | # ------------------------------------------------------------------------------ 7 | 8 | name: wide_integer_sonar 9 | on: 10 | push: 11 | branches: 12 | - master 13 | pull_request: 14 | types: [opened, synchronize, reopened] 15 | jobs: 16 | build: 17 | name: sonar-gcc-native 18 | runs-on: ubuntu-latest 19 | env: 20 | SONAR_SCANNER_VERSION: 5.0.1.3006 21 | SONAR_SERVER_URL: "https://sonarcloud.io" 22 | BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed 23 | steps: 24 | - uses: actions/checkout@v4 25 | with: 26 | fetch-depth: 0 27 | - name: clone-submods-bootstrap-headers-boost-develop 28 | run: | 29 | git clone -b develop --depth 1 https://github.com/boostorg/boost.git ../boost-root 30 | cd ../boost-root 31 | git submodule update --init tools 32 | git submodule update --init libs/config 33 | git submodule update --init libs/multiprecision 34 | ./bootstrap.sh 35 | ./b2 headers 36 | - name: Set up JDK 17 37 | uses: actions/setup-java@v4 38 | with: 39 | distribution: 'temurin' 40 | java-version: '17' 41 | overwrite-settings: true 42 | - name: Download and set up sonar-scanner 43 | env: 44 | SONAR_SCANNER_DOWNLOAD_URL: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${{ env.SONAR_SCANNER_VERSION }}-linux.zip 45 | run: | 46 | mkdir -p $HOME/.sonar 47 | curl -sSLo $HOME/.sonar/sonar-scanner.zip ${{ env.SONAR_SCANNER_DOWNLOAD_URL }} 48 | unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/ 49 | echo "$HOME/.sonar/sonar-scanner-${{ env.SONAR_SCANNER_VERSION }}-linux/bin" >> $GITHUB_PATH 50 | - name: Download and set up build-wrapper 51 | env: 52 | BUILD_WRAPPER_DOWNLOAD_URL: ${{ env.SONAR_SERVER_URL }}/static/cpp/build-wrapper-linux-x86.zip 53 | run: | 54 | curl -sSLo $HOME/.sonar/build-wrapper-linux-x86.zip ${{ env.BUILD_WRAPPER_DOWNLOAD_URL }} 55 | unzip -o $HOME/.sonar/build-wrapper-linux-x86.zip -d $HOME/.sonar/ 56 | echo "$HOME/.sonar/build-wrapper-linux-x86" >> $GITHUB_PATH 57 | - name: Run build-wrapper 58 | run: | 59 | java -version 60 | build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} g++ -finline-functions -m64 -O3 -Werror -Wall -Wextra -Wconversion -Wsign-conversion -std=c++14 -DWIDE_INTEGER_HAS_LIMB_TYPE_UINT64 -DWIDE_INTEGER_HAS_MUL_8_BY_8_UNROLL -I. -I../boost-root -pthread -lpthread test/test.cpp test/test_uintwide_t_boost_backend.cpp test/test_uintwide_t_edge_cases.cpp test/test_uintwide_t_examples.cpp test/test_uintwide_t_float_convert.cpp test/test_uintwide_t_int_convert.cpp test/test_uintwide_t_n_base.cpp test/test_uintwide_t_n_binary_ops_base.cpp test/test_uintwide_t_spot_values.cpp examples/example000_numeric_limits.cpp examples/example000a_builtin_convert.cpp examples/example001_mul_div.cpp examples/example001a_div_mod.cpp examples/example002_shl_shr.cpp examples/example003_sqrt.cpp examples/example003a_cbrt.cpp examples/example004_rootk_pow.cpp examples/example005_powm.cpp examples/example005a_pow_factors_of_p99.cpp examples/example006_gcd.cpp examples/example007_random_generator.cpp examples/example008_miller_rabin_prime.cpp examples/example008a_miller_rabin_prime.cpp examples/example009_timed_mul.cpp examples/example009a_timed_mul_4_by_4.cpp examples/example009b_timed_mul_8_by_8.cpp examples/example010_uint48_t.cpp examples/example011_uint24_t.cpp examples/example012_rsa_crypto.cpp examples/example013_ecdsa_sign_verify.cpp examples/example014_pi_spigot_wide.cpp -o wide_integer.exe 61 | - name: Run sonar-scanner 62 | env: 63 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 64 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 65 | run: | 66 | java -version 67 | sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" 68 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | wide_integer.vcxproj.user 3 | x64/ 4 | wide_integer_vs2022.vcxproj.user 5 | -------------------------------------------------------------------------------- /.props/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | 5 | 6 | -------------------------------------------------------------------------------- /.tidy/make/make_tidy_01_generic.gmk: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Copyright Christopher Kormanyos 2022. 3 | # Distributed under the Boost Software License, 4 | # Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | # or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | # ------------------------------------------------------------------------------ 7 | 8 | PATH_MAKE = $(CURDIR) 9 | PATH_PRJ = $(PATH_MAKE)/../.. 10 | PATH_SRC = $(PATH_PRJ) 11 | PATH_TMP = $(PATH_MAKE)/tmp 12 | PATH_ERR = $(PATH_MAKE)/err 13 | 14 | CAT = cat 15 | GNUECHO = echo 16 | LS = ls 17 | MKDIR = mkdir 18 | TIDY = clang-tidy 19 | RM = rm 20 | SED = sed 21 | 22 | include make_tidy_02_files.gmk 23 | include make_tidy_03_flags.gmk 24 | 25 | FILES_ALL = $(FILES_PRJ) 26 | FILES_TIDY_TXT = $(addprefix $(PATH_TMP)/, $(notdir $(addsuffix .tidy_txt, $(FILES_ALL)))) 27 | 28 | # ------------------------------------------------------------------------------ 29 | # VPATH definition: VPATH is required for make to find the source files. 30 | # ------------------------------------------------------------------------------ 31 | VPATH := $(sort $(dir $(FILES_ALL))) 32 | 33 | # ------------------------------------------------------------------------------ 34 | # Main dependency: Run clang-tidy on all files and tidy tidy results. 35 | # ------------------------------------------------------------------------------ 36 | 37 | .PHONY: tidy 38 | tidy: $(FILES_TIDY_TXT) 39 | # Summarize tidy results 40 | @$(GNUECHO) +++ summarize clang-tidy results 41 | @$(GNUECHO) +++ concatenate $(PATH_TMP)/*.tidy_txt to $(PATH_TMP)/all.tidy_txt 42 | @$(CAT) $(PATH_TMP)/*.tidy_txt > $(PATH_TMP)/all.tidy_txt 43 | @$(GNUECHO) 44 | @$(GNUECHO) +++ verify existence of $(PATH_TMP)/all.tidy_txt 45 | @$(LS) -la $(PATH_TMP)/all.tidy_txt 46 | @$(GNUECHO) 47 | @$(GNUECHO) +++ print summary of tidy from $(PATH_TMP)/all.tidy_txt: 48 | @-$(SED) -n l $(PATH_TMP)/all.tidy_txt 49 | @$(GNUECHO) 50 | 51 | 52 | # ------------------------------------------------------------------------------ 53 | # Clean temporary files. 54 | # ------------------------------------------------------------------------------ 55 | 56 | .PHONY: prepare 57 | prepare: 58 | # creating output directories 59 | @$(GNUECHO) +++ creating output directories 60 | @-$(MKDIR) -p $(PATH_ERR) 61 | @-$(MKDIR) -p $(PATH_TMP) 62 | @$(GNUECHO) 63 | @$(GNUECHO) +++ cleaning output directories 64 | @-$(RM) -rf $(PATH_ERR)/*.tidy_err 65 | @-$(RM) -rf $(PATH_TMP)/*.tidy_txt 66 | @$(GNUECHO) 67 | @$(GNUECHO) +++ print clang-tidy version 68 | @$(TIDY) --version 69 | @$(GNUECHO) 70 | @$(GNUECHO) +++ print include paths 71 | @$(GNUECHO) $(C_INCLUDES) 72 | @$(GNUECHO) 73 | 74 | # ------------------------------------------------------------------------------ 75 | # pattern rule for clang-tidy analysis of cpp-files 76 | # ------------------------------------------------------------------------------ 77 | $(PATH_TMP)/%.tidy_txt : %.cpp 78 | @-$(GNUECHO) +++ tidying: $< 79 | @-$(TIDY) $(TIDY_FLAGS) $< -- $(CXX_FLAGS) $(C_INCLUDES) $(C_DEFINES) > $(PATH_TMP)/$(basename $(@F)).tidy_txt 2> $(PATH_ERR)/$(basename $(@F)).tidy_err 80 | @-$(GNUECHO) 81 | @-$(GNUECHO) +++ print $(PATH_ERR)/$(basename $(@F)).tidy_err 82 | @-$(SED) -n l $(PATH_ERR)/$(basename $(@F)).tidy_err 83 | @-$(GNUECHO) 84 | -------------------------------------------------------------------------------- /.tidy/make/make_tidy_02_files.gmk: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Copyright Christopher Kormanyos 2022 - 2024. 3 | # Distributed under the Boost Software License, 4 | # Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | # or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | # ------------------------------------------------------------------------------ 7 | 8 | FILES_PRJ = $(PATH_SRC)/test/test_uintwide_t_edge_cases \ 9 | $(PATH_SRC)/test/test_uintwide_t_examples \ 10 | $(PATH_SRC)/test/test_uintwide_t_float_convert \ 11 | $(PATH_SRC)/test/test_uintwide_t_int_convert \ 12 | $(PATH_SRC)/test/test_uintwide_t_n_base \ 13 | $(PATH_SRC)/test/test_uintwide_t_n_binary_ops_base \ 14 | $(PATH_SRC)/test/test_uintwide_t_spot_values \ 15 | $(PATH_SRC)/examples/example000a_builtin_convert \ 16 | $(PATH_SRC)/examples/example000_numeric_limits \ 17 | $(PATH_SRC)/examples/example001_mul_div \ 18 | $(PATH_SRC)/examples/example001a_div_mod \ 19 | $(PATH_SRC)/examples/example002_shl_shr \ 20 | $(PATH_SRC)/examples/example003_sqrt \ 21 | $(PATH_SRC)/examples/example003a_cbrt \ 22 | $(PATH_SRC)/examples/example004_rootk_pow \ 23 | $(PATH_SRC)/examples/example005_powm \ 24 | $(PATH_SRC)/examples/example005a_pow_factors_of_p99 \ 25 | $(PATH_SRC)/examples/example006_gcd \ 26 | $(PATH_SRC)/examples/example007_random_generator \ 27 | $(PATH_SRC)/examples/example008_miller_rabin_prime \ 28 | $(PATH_SRC)/examples/example008a_miller_rabin_prime \ 29 | $(PATH_SRC)/examples/example009_timed_mul \ 30 | $(PATH_SRC)/examples/example009a_timed_mul_4_by_4 \ 31 | $(PATH_SRC)/examples/example009b_timed_mul_8_by_8 \ 32 | $(PATH_SRC)/examples/example010_uint48_t \ 33 | $(PATH_SRC)/examples/example011_uint24_t \ 34 | $(PATH_SRC)/examples/example012_rsa_crypto \ 35 | $(PATH_SRC)/examples/example013_ecdsa_sign_verify \ 36 | $(PATH_SRC)/examples/example014_pi_spigot_wide 37 | -------------------------------------------------------------------------------- /.tidy/make/make_tidy_03_flags.gmk: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Copyright Christopher Kormanyos 2022 - 2024. 3 | # Distributed under the Boost Software License, 4 | # Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | # or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | # ------------------------------------------------------------------------------ 7 | 8 | BOOST_ROOT_FOR_TIDY = /mnt/c/boost/boost_1_78_0 9 | CC = clang++ 10 | STD = c++14 11 | 12 | ifneq ($(MY_BOOST_ROOT),) 13 | BOOST_ROOT_FOR_TIDY := $(MY_BOOST_ROOT) 14 | endif 15 | 16 | ifneq ($(MY_CC),) 17 | CC := $(MY_CC) 18 | endif 19 | 20 | ifneq ($(MY_STD),) 21 | STD := $(MY_STD) 22 | endif 23 | 24 | CXX_FLAGS = $(CC) \ 25 | -march=native \ 26 | -mtune=native \ 27 | -O3 \ 28 | -Wall \ 29 | -Wextra \ 30 | -Wconversion \ 31 | -Wsign-conversion \ 32 | -std=$(STD) 33 | 34 | C_DEFINES = WIDE_INTEGER_HAS_MUL_8_BY_8_UNROLL 35 | 36 | C_INCLUDES = $(PATH_SRC) \ 37 | $(BOOST_ROOT_FOR_TIDY) 38 | 39 | C_DEFINES :=$(addprefix -D,$(C_DEFINES)) 40 | C_INCLUDES :=$(addprefix -I,$(C_INCLUDES)) 41 | 42 | 43 | TIDY_CHECKS = "*, \ 44 | -cert-dcl58-cpp, \ 45 | -cppcoreguidelines-rvalue-reference-param-not-moved, \ 46 | -cppcoreguidelines-avoid-do-while, \ 47 | -modernize-type-traits, \ 48 | -modernize-use-constraints, \ 49 | -misc-header-include-cycle, \ 50 | -misc-include-cleaner, \ 51 | -misc-const-correctness, \ 52 | -performance-avoid-endl, \ 53 | -readability-identifier-length, \ 54 | -readability-redundant-casting, \ 55 | -altera-struct-pack-align, \ 56 | -altera-unroll-loops, \ 57 | -fuchsia-*, \ 58 | -llvmlibc-*" 59 | 60 | TIDY_FLAGS = --extra-arg-before=--driver-mode=g++ \ 61 | --header-filter=uintwide_t \ 62 | -warnings-as-errors=* \ 63 | -checks=$(TIDY_CHECKS) 64 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(wide-integer) 2 | 3 | cmake_minimum_required(VERSION 3.16.3) 4 | 5 | find_package(Boost) 6 | if (Boost_FOUND) 7 | include(CTest) 8 | 9 | add_subdirectory("examples") 10 | add_subdirectory("test") 11 | endif() 12 | 13 | add_library(WideInteger INTERFACE) 14 | target_compile_features(WideInteger INTERFACE cxx_std_14) 15 | 16 | target_include_directories( 17 | WideInteger SYSTEM INTERFACE 18 | $ 19 | $) 20 | 21 | install(TARGETS WideInteger EXPORT WideIntegerTargets) 22 | install( 23 | FILES math/wide_integer/uintwide_t.h 24 | DESTINATION include/math/wide_integer/) 25 | install(EXPORT WideIntegerTargets 26 | FILE WideIntegerConfig.cmake 27 | NAMESPACE WideInteger:: 28 | DESTINATION lib/cmake/wide-integer) 29 | -------------------------------------------------------------------------------- /LICENSE_1_0.txt: -------------------------------------------------------------------------------- 1 | 2 | Boost Software License - Version 1.0 - August 17th, 2003 3 | 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: yes 3 | 4 | coverage: 5 | precision: 1 6 | round: up 7 | range: '50...100' 8 | status: 9 | project: 10 | default: # This can be anything, but it needs to exist as the name 11 | # basic settings 12 | target: 90% 13 | threshold: 3% 14 | if_ci_failed: error #success, failure, error, ignore 15 | only_pulls: false 16 | patch: 17 | default: 18 | target: 75% 19 | threshold: 25% 20 | 21 | parsers: 22 | gcov: 23 | branch_detection: 24 | conditional: no 25 | loop: no 26 | method: no 27 | macro: no 28 | 29 | comment: 30 | layout: 'reach,diff,flags,files,footer' 31 | behavior: default 32 | require_changes: no 33 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(Examples 2 | example000_numeric_limits.cpp 3 | example000a_builtin_convert.cpp 4 | example001_mul_div.cpp 5 | example001a_div_mod.cpp 6 | example002_shl_shr.cpp 7 | example003_sqrt.cpp 8 | example003a_cbrt.cpp 9 | example004_rootk_pow.cpp 10 | example005_powm.cpp 11 | example005a_pow_factors_of_p99.cpp 12 | example006_gcd.cpp 13 | example007_random_generator.cpp 14 | example008_miller_rabin_prime.cpp 15 | example008a_miller_rabin_prime.cpp 16 | example009_timed_mul.cpp 17 | example009a_timed_mul_4_by_4.cpp 18 | example009b_timed_mul_8_by_8.cpp 19 | example010_uint48_t.cpp 20 | example011_uint24_t.cpp 21 | example012_rsa_crypto.cpp 22 | example013_ecdsa_sign_verify.cpp 23 | example014_pi_spigot_wide.cpp) 24 | target_compile_features(Examples PRIVATE cxx_std_20) 25 | target_include_directories(Examples PRIVATE ${PROJECT_SOURCE_DIR}) 26 | target_include_directories(Examples SYSTEM PUBLIC ${Boost_INCLUDE_DIRS}) 27 | -------------------------------------------------------------------------------- /examples/example000a_builtin_convert.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2021 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | 11 | namespace local 12 | { 13 | template 14 | constexpr auto fabs(NumericType a) -> NumericType 15 | { 16 | return ((a < static_cast(INT8_C(0))) ? -a : a); // LCOV_EXCL_LINE 17 | } 18 | } // namespace local 19 | 20 | #if defined(WIDE_INTEGER_NAMESPACE) 21 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example000a_builtin_convert() -> bool 22 | #else 23 | auto ::math::wide_integer::example000a_builtin_convert() -> bool 24 | #endif 25 | { 26 | auto result_is_ok = true; 27 | 28 | #if defined(WIDE_INTEGER_NAMESPACE) 29 | using WIDE_INTEGER_NAMESPACE::math::wide_integer::int256_t; 30 | #else 31 | using ::math::wide_integer::int256_t; 32 | #endif 33 | 34 | { 35 | constexpr int256_t n = -1234567.89; // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 36 | 37 | constexpr auto result_n_is_ok = (n == -1234567); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 38 | 39 | static_assert(result_n_is_ok, "Error: example000a_builtin_convert not OK!"); 40 | 41 | result_is_ok = (result_n_is_ok && result_is_ok); 42 | } 43 | 44 | { 45 | constexpr int256_t n = "-12345678900000000000000000000000"; 46 | 47 | constexpr auto f = static_cast(n); 48 | 49 | constexpr auto closeness = local::fabs(1.0F - local::fabs(f / -1.23456789E31F)); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 50 | constexpr auto result_f_is_ok = (closeness < std::numeric_limits::epsilon()); 51 | 52 | static_assert(result_f_is_ok, "Error: example000a_builtin_convert not OK!"); 53 | 54 | result_is_ok = (result_f_is_ok && result_is_ok); 55 | } 56 | 57 | { 58 | constexpr int256_t n = "-123456789000000000"; 59 | 60 | constexpr auto n64 = static_cast(n); 61 | 62 | constexpr auto result_n_is_ok = (n64 == INT64_C(-123456789000000000)); 63 | 64 | static_assert((n64 == INT64_C(-123456789000000000)), "Error: example000a_builtin_convert not OK!"); 65 | 66 | result_is_ok = (result_n_is_ok && result_is_ok); 67 | } 68 | 69 | return result_is_ok; 70 | } 71 | 72 | // Enable this if you would like to activate this main() as a standalone example. 73 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE000A_BUILTIN_CONVERT) 74 | 75 | #include 76 | #include 77 | 78 | auto main() -> int 79 | { 80 | #if defined(WIDE_INTEGER_NAMESPACE) 81 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example000a_builtin_convert(); 82 | #else 83 | const auto result_is_ok = ::math::wide_integer::example000a_builtin_convert(); 84 | #endif 85 | 86 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 87 | 88 | return (result_is_ok ? 0 : -1); 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /examples/example001_mul_div.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | 11 | #if (defined(__GNUC__) && defined(__AVR__) && (__GNUC__ < 10)) 12 | #define WIDE_INTEGER_EXAMPLE001_CONSTEXPR_OR_CONST const // NOLINT(cppcoreguidelines-macro-usage) 13 | #define WIDE_INTEGER_EXAMPLE001_CONSTEXPR_IS_COMPILE_TIME_CONSTANT 0 // NOLINT(cppcoreguidelines-macro-usage) 14 | #else 15 | #define WIDE_INTEGER_EXAMPLE001_CONSTEXPR_OR_CONST constexpr // NOLINT(cppcoreguidelines-macro-usage) 16 | #define WIDE_INTEGER_EXAMPLE001_CONSTEXPR_IS_COMPILE_TIME_CONSTANT 1 // NOLINT(cppcoreguidelines-macro-usage) 17 | #endif 18 | 19 | #if defined(WIDE_INTEGER_NAMESPACE) 20 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example001_mul_div() -> bool 21 | #else 22 | auto ::math::wide_integer::example001_mul_div() -> bool 23 | #endif 24 | { 25 | #if defined(WIDE_INTEGER_NAMESPACE) 26 | using WIDE_INTEGER_NAMESPACE::math::wide_integer::uint256_t; 27 | using WIDE_INTEGER_NAMESPACE::math::wide_integer::uint512_t; 28 | #else 29 | using ::math::wide_integer::uint256_t; 30 | using ::math::wide_integer::uint512_t; 31 | #endif 32 | 33 | static_assert(( std::numeric_limits::digits == static_cast(INT16_C(256)) 34 | && std::numeric_limits::digits == static_cast(INT16_C(512))), 35 | "Error: Incorrect digit count for this example"); 36 | 37 | WIDE_INTEGER_EXAMPLE001_CONSTEXPR_OR_CONST uint256_t a("0xF4DF741DE58BCB2F37F18372026EF9CBCFC456CB80AF54D53BDEED78410065DE"); 38 | WIDE_INTEGER_EXAMPLE001_CONSTEXPR_OR_CONST uint256_t b("0x166D63E0202B3D90ECCEAA046341AB504658F55B974A7FD63733ECF89DD0DF75"); 39 | 40 | WIDE_INTEGER_EXAMPLE001_CONSTEXPR_OR_CONST auto c = uint512_t(a) * uint512_t(b); 41 | WIDE_INTEGER_EXAMPLE001_CONSTEXPR_OR_CONST auto d = (a / b); 42 | 43 | WIDE_INTEGER_EXAMPLE001_CONSTEXPR_OR_CONST auto result_is_ok = 44 | ( 45 | (c == "0x1573D6A7CEA734D99865C4F428184983CDB018B80E9CC44B83C773FBE11993E7E491A360C57EB4306C61F9A04F7F7D99BE3676AAD2D71C5592D5AE70F84AF076") 46 | && (static_cast(d) == static_cast(UINT8_C(10))) 47 | ); 48 | 49 | #if (defined(WIDE_INTEGER_EXAMPLE001_CONSTEXPR_IS_COMPILE_TIME_CONSTANT) \ 50 | && (WIDE_INTEGER_EXAMPLE001_CONSTEXPR_IS_COMPILE_TIME_CONSTANT == 1)) 51 | static_assert(result_is_ok, "Error: example001_mul_div not OK!"); 52 | #endif 53 | 54 | return result_is_ok; 55 | } 56 | 57 | // Enable this if you would like to activate this main() as a standalone example. 58 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE001_MUL_DIV) 59 | 60 | #if !defined(WIDE_INTEGER_DISABLE_IOSTREAM) 61 | #include 62 | #include 63 | #endif 64 | 65 | constexpr auto example_standalone_foodcafe = static_cast(UINT32_C(0xF00DCAFE)); 66 | 67 | extern "C" 68 | { 69 | extern volatile std::uint32_t example_standalone_result; 70 | 71 | auto example_run_standalone () -> bool; 72 | auto example_get_standalone_result() noexcept -> bool; 73 | 74 | auto example_run_standalone() -> bool 75 | { 76 | bool result_is_ok = true; 77 | 78 | for(unsigned i = 0U; i < 64U; ++i) 79 | { 80 | #if defined(WIDE_INTEGER_NAMESPACE) 81 | result_is_ok &= WIDE_INTEGER_NAMESPACE::math::wide_integer::example001_mul_div(); 82 | #else 83 | result_is_ok &= ::math::wide_integer::example001_mul_div(); 84 | #endif 85 | } 86 | 87 | example_standalone_result = 88 | static_cast 89 | ( 90 | result_is_ok ? example_standalone_foodcafe : static_cast(UINT32_C(0xFFFFFFFF)) 91 | ); 92 | 93 | #if !defined(WIDE_INTEGER_DISABLE_IOSTREAM) 94 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 95 | #endif 96 | 97 | return result_is_ok; 98 | } 99 | 100 | auto example_get_standalone_result() noexcept -> bool 101 | { 102 | return { example_standalone_result == static_cast(UINT32_C(0xF00DCAFE)) }; 103 | } 104 | } 105 | 106 | auto main() -> int 107 | { 108 | auto result_is_ok = true; 109 | 110 | result_is_ok = (::example_run_standalone () && result_is_ok); 111 | result_is_ok = (::example_get_standalone_result() && result_is_ok); 112 | 113 | return (result_is_ok ? 0 : -1); 114 | } 115 | 116 | extern "C" 117 | { 118 | volatile std::uint32_t example_standalone_result { }; 119 | } 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /examples/example001a_div_mod.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 -2022. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | 11 | #if defined(WIDE_INTEGER_NAMESPACE) 12 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example001a_div_mod() -> bool 13 | #else 14 | auto ::math::wide_integer::example001a_div_mod() -> bool 15 | #endif 16 | { 17 | #if defined(WIDE_INTEGER_NAMESPACE) 18 | using WIDE_INTEGER_NAMESPACE::math::wide_integer::uint512_t; 19 | #else 20 | using ::math::wide_integer::uint512_t; 21 | #endif 22 | 23 | // QuotientRemainder[698937339790347543053797400564366118744312537138445607919548628175822115805812983955794321304304417541511379093392776018867245622409026835324102460829431,100041341335406267530943777943625254875702684549707174207105689918734693139781] 24 | // {6986485091668619828842978360442127600954041171641881730123945989288792389271,100041341335406267530943777943625254875702684549707174207105689918734693139780} 25 | 26 | constexpr uint512_t a("698937339790347543053797400564366118744312537138445607919548628175822115805812983955794321304304417541511379093392776018867245622409026835324102460829431"); 27 | constexpr uint512_t b("100041341335406267530943777943625254875702684549707174207105689918734693139781"); 28 | 29 | constexpr uint512_t c = (a / b); 30 | constexpr uint512_t d = (a % b); 31 | 32 | constexpr bool result_is_ok = ( (c == "6986485091668619828842978360442127600954041171641881730123945989288792389271") 33 | && (d == "100041341335406267530943777943625254875702684549707174207105689918734693139780")); 34 | 35 | static_assert(result_is_ok, "Error: example001a_div_mod not OK!"); 36 | 37 | return result_is_ok; 38 | } 39 | 40 | // Enable this if you would like to activate this main() as a standalone example. 41 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE001A_DIV_MOD) 42 | 43 | #include 44 | #include 45 | 46 | auto main() -> int 47 | { 48 | #if defined(WIDE_INTEGER_NAMESPACE) 49 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example001a_div_mod(); 50 | #else 51 | const auto result_is_ok = ::math::wide_integer::example001a_div_mod(); 52 | #endif 53 | 54 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 55 | 56 | return (result_is_ok ? 0 : -1); 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /examples/example002_shl_shr.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | 11 | #if defined(WIDE_INTEGER_NAMESPACE) 12 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example002_shl_shr() -> bool 13 | #else 14 | auto ::math::wide_integer::example002_shl_shr() -> bool 15 | #endif 16 | { 17 | #if defined(WIDE_INTEGER_NAMESPACE) 18 | using WIDE_INTEGER_NAMESPACE::math::wide_integer::uint256_t; 19 | #else 20 | using ::math::wide_integer::uint256_t; 21 | #endif 22 | 23 | constexpr uint256_t a("0xF4DF741DE58BCB2F37F18372026EF9CBCFC456CB80AF54D53BDEED78410065DE"); 24 | 25 | constexpr uint256_t c = (a << 67); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 26 | constexpr uint256_t d = (a >> 79); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 27 | 28 | const auto result_is_ok = ( (c == "0xBF8C1B901377CE5E7E22B65C057AA6A9DEF76BC208032EF00000000000000000") 29 | && (d == "0x1E9BEE83BCB17965E6FE306E404DDF3979F88AD97015E")); 30 | 31 | static_assert(result_is_ok, "Error: example002_shl_shr not OK!"); 32 | 33 | return result_is_ok; 34 | } 35 | 36 | // Enable this if you would like to activate this main() as a standalone example. 37 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE002_SHL_SHR) 38 | 39 | #include 40 | #include 41 | 42 | auto main() -> int 43 | { 44 | #if defined(WIDE_INTEGER_NAMESPACE) 45 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example002_shl_shr(); 46 | #else 47 | const auto result_is_ok = ::math::wide_integer::example002_shl_shr(); 48 | #endif 49 | 50 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 51 | 52 | return (result_is_ok ? 0 : -1); 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /examples/example003_sqrt.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | 11 | #if (defined(__GNUC__) && defined(__AVR__) && (__GNUC__ < 10)) 12 | #define WIDE_INTEGER_EXAMPLE003_CONSTEXPR_OR_CONST const // NOLINT(cppcoreguidelines-macro-usage) 13 | #define WIDE_INTEGER_EXAMPLE003_CONSTEXPR_IS_COMPILE_TIME_CONSTANT 0 // NOLINT(cppcoreguidelines-macro-usage) 14 | #else 15 | #define WIDE_INTEGER_EXAMPLE003_CONSTEXPR_OR_CONST constexpr // NOLINT(cppcoreguidelines-macro-usage) 16 | #define WIDE_INTEGER_EXAMPLE003_CONSTEXPR_IS_COMPILE_TIME_CONSTANT 1 // NOLINT(cppcoreguidelines-macro-usage) 17 | #endif 18 | 19 | #if defined(WIDE_INTEGER_NAMESPACE) 20 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example003_sqrt() -> bool 21 | #else 22 | auto ::math::wide_integer::example003_sqrt() -> bool 23 | #endif 24 | { 25 | #if defined(WIDE_INTEGER_NAMESPACE) 26 | using WIDE_INTEGER_NAMESPACE::math::wide_integer::uint256_t; 27 | #else 28 | using ::math::wide_integer::uint256_t; 29 | #endif 30 | 31 | WIDE_INTEGER_EXAMPLE003_CONSTEXPR_OR_CONST uint256_t a("0xF4DF741DE58BCB2F37F18372026EF9CBCFC456CB80AF54D53BDEED78410065DE"); 32 | 33 | WIDE_INTEGER_EXAMPLE003_CONSTEXPR_OR_CONST uint256_t s = sqrt(a); 34 | 35 | WIDE_INTEGER_EXAMPLE003_CONSTEXPR_OR_CONST bool result_is_ok = (s == "0xFA5FE7853F1D4AD92BDF244179CA178B"); 36 | 37 | #if (defined(WIDE_INTEGER_EXAMPLE003_CONSTEXPR_IS_COMPILE_TIME_CONSTANT) \ 38 | && (WIDE_INTEGER_EXAMPLE003_CONSTEXPR_IS_COMPILE_TIME_CONSTANT == 1)) 39 | static_assert(result_is_ok, "Error: example003_sqrt not OK!"); 40 | #endif 41 | 42 | return result_is_ok; 43 | } 44 | 45 | // Enable this if you would like to activate this main() as a standalone example. 46 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE003_SQRT) 47 | 48 | #if !defined(WIDE_INTEGER_DISABLE_IOSTREAM) 49 | #include 50 | #include 51 | #endif 52 | 53 | constexpr auto example_standalone_foodcafe = static_cast(UINT32_C(0xF00DCAFE)); 54 | 55 | extern "C" 56 | { 57 | extern volatile std::uint32_t example_standalone_result; 58 | 59 | auto example_run_standalone () -> bool; 60 | auto example_get_standalone_result() noexcept -> bool; 61 | 62 | auto example_run_standalone() -> bool 63 | { 64 | bool result_is_ok = true; 65 | 66 | for(unsigned i = 0U; i < 64U; ++i) 67 | { 68 | #if defined(WIDE_INTEGER_NAMESPACE) 69 | result_is_ok &= WIDE_INTEGER_NAMESPACE::math::wide_integer::example003_sqrt(); 70 | #else 71 | result_is_ok &= ::math::wide_integer::example003_sqrt(); 72 | #endif 73 | } 74 | 75 | example_standalone_result = 76 | static_cast 77 | ( 78 | result_is_ok ? example_standalone_foodcafe : static_cast(UINT32_C(0xFFFFFFFF)) 79 | ); 80 | 81 | #if !defined(WIDE_INTEGER_DISABLE_IOSTREAM) 82 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 83 | #endif 84 | 85 | return result_is_ok; 86 | } 87 | 88 | auto example_get_standalone_result() noexcept -> bool 89 | { 90 | return { example_standalone_result == static_cast(UINT32_C(0xF00DCAFE)) }; 91 | } 92 | } 93 | 94 | auto main() -> int 95 | { 96 | auto result_is_ok = true; 97 | 98 | result_is_ok = (::example_run_standalone () && result_is_ok); 99 | result_is_ok = (::example_get_standalone_result() && result_is_ok); 100 | 101 | return (result_is_ok ? 0 : -1); 102 | } 103 | 104 | extern "C" 105 | { 106 | volatile std::uint32_t example_standalone_result { }; 107 | } 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /examples/example003a_cbrt.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #if defined(WIDE_INTEGER_NAMESPACE) 14 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example003a_cbrt() -> bool 15 | #else 16 | auto ::math::wide_integer::example003a_cbrt() -> bool 17 | #endif 18 | { 19 | #if defined(WIDE_INTEGER_NAMESPACE) 20 | using uint11264_t = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t(UINT32_C(11264)), std::uint32_t, std::allocator>; 21 | #else 22 | using uint11264_t = ::math::wide_integer::uintwide_t(UINT32_C(11264)), std::uint32_t, std::allocator>; 23 | #endif 24 | 25 | // Create the string '1' + 3,333 times '0', which is 26 | // equivalent to the decimal integral value 10^3333. 27 | 28 | const std::string str_a = "1" + std::string(3333U, '0'); 29 | 30 | const uint11264_t a = str_a.data(); 31 | 32 | const uint11264_t s = cbrt(a); 33 | 34 | // Create the string '1' + 1,111 times '0', which is 35 | // equivalent to the decimal integral value 10^1111. 36 | // (This is the cube root of 10^3333.) 37 | 38 | const std::string str_control = "1" + std::string(1111U, '0'); 39 | 40 | const auto result_is_ok = (s == uint11264_t(str_control.data())); 41 | 42 | return result_is_ok; 43 | } 44 | 45 | // Enable this if you would like to activate this main() as a standalone example. 46 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE003A_CBRT) 47 | 48 | #include 49 | #include 50 | 51 | auto main() -> int 52 | { 53 | #if defined(WIDE_INTEGER_NAMESPACE) 54 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example003a_cbrt(); 55 | #else 56 | const auto result_is_ok = ::math::wide_integer::example003a_cbrt(); 57 | #endif 58 | 59 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 60 | 61 | return (result_is_ok ? 0 : -1); 62 | } 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /examples/example004_rootk_pow.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | 11 | #if defined(WIDE_INTEGER_NAMESPACE) 12 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example004_rootk_pow() -> bool 13 | #else 14 | auto ::math::wide_integer::example004_rootk_pow() -> bool 15 | #endif 16 | { 17 | bool result_is_ok = true; 18 | 19 | { 20 | #if defined(WIDE_INTEGER_NAMESPACE) 21 | using WIDE_INTEGER_NAMESPACE::math::wide_integer::uint256_t; 22 | #else 23 | using ::math::wide_integer::uint256_t; 24 | #endif 25 | 26 | constexpr uint256_t x("0x95E0E51079E1D11737D3FD01429AA745582FEB4381D61FA56948C1A949E43C32"); 27 | constexpr uint256_t r = rootk(x, 7U); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 28 | 29 | constexpr bool result_is_ok_root = (r == UINT64_C(0x16067D1894)); 30 | 31 | result_is_ok = (result_is_ok_root && result_is_ok); 32 | 33 | static_assert(result_is_ok_root, "Error: example004_rootk_pow not OK!"); 34 | } 35 | 36 | { 37 | #if defined(WIDE_INTEGER_NAMESPACE) 38 | using WIDE_INTEGER_NAMESPACE::math::wide_integer::uint256_t; 39 | #else 40 | using ::math::wide_integer::uint256_t; 41 | #endif 42 | 43 | constexpr uint256_t r { static_cast(UINT64_C(0x16067D1894)) }; 44 | constexpr uint256_t p = pow(r, static_cast(UINT8_C(7))); 45 | 46 | constexpr bool result_is_ok_pow = (p == "0x95E0E5104B2F636571834936C982E40EFA25682E7370CD1C248051E1CDC34000"); 47 | 48 | result_is_ok = (result_is_ok_pow && result_is_ok); 49 | 50 | static_assert(result_is_ok_pow, "Error: example004_rootk_pow not OK!"); 51 | } 52 | 53 | { 54 | #if defined(WIDE_INTEGER_NAMESPACE) 55 | using WIDE_INTEGER_NAMESPACE::math::wide_integer::int256_t; 56 | #else 57 | using ::math::wide_integer::int256_t; 58 | #endif 59 | 60 | constexpr int256_t x("-17791969125525294590007745776736486317864490689865550963808715359713140948018"); 61 | constexpr int256_t r = cbrt(x); 62 | 63 | constexpr bool result_is_ok_root = (r == int256_t("-26106060416733621800766427")); 64 | 65 | result_is_ok = (result_is_ok_root && result_is_ok); 66 | 67 | static_assert(result_is_ok_root, "Error: example004_rootk_pow not OK!"); 68 | } 69 | 70 | { 71 | #if defined(WIDE_INTEGER_NAMESPACE) 72 | using WIDE_INTEGER_NAMESPACE::math::wide_integer::int256_t; 73 | #else 74 | using ::math::wide_integer::int256_t; 75 | #endif 76 | 77 | constexpr int256_t x("-17791969125525294590007745776736486317864490689865550963808715359713140948018"); 78 | constexpr int256_t r = rootk(x, 3); 79 | 80 | constexpr bool result_is_ok_root = (r == int256_t("-26106060416733621800766427")); 81 | 82 | result_is_ok = (result_is_ok_root && result_is_ok); 83 | 84 | static_assert(result_is_ok_root, "Error: example004_rootk_pow not OK!"); 85 | } 86 | 87 | return result_is_ok; 88 | } 89 | 90 | // Enable this if you would like to activate this main() as a standalone example. 91 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE004_ROOTK_POW) 92 | 93 | #include 94 | #include 95 | 96 | auto main() -> int 97 | { 98 | #if defined(WIDE_INTEGER_NAMESPACE) 99 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example004_rootk_pow(); 100 | #else 101 | const auto result_is_ok = ::math::wide_integer::example004_rootk_pow(); 102 | #endif 103 | 104 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 105 | 106 | return (result_is_ok ? 0 : -1); 107 | } 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /examples/example005_powm.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | 11 | #if defined(WIDE_INTEGER_NAMESPACE) 12 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example005_powm() -> bool 13 | #else 14 | auto ::math::wide_integer::example005_powm() -> bool 15 | #endif 16 | { 17 | #if defined(WIDE_INTEGER_NAMESPACE) 18 | using WIDE_INTEGER_NAMESPACE::math::wide_integer::uint256_t; 19 | #else 20 | using ::math::wide_integer::uint256_t; 21 | #endif 22 | 23 | constexpr uint256_t b("0xDA4033C9B1B0675C20B7879EA63FFFBEEBEC3F89F78D22C393FAD98E7AE9BF69"); 24 | constexpr uint256_t p("0xA4748AD2DAFEED29C73927BD0945EF45EFEC9DAA95CC59390D406FC27236A174"); 25 | constexpr uint256_t m("0xB6EC4DAB21E2856D488D669C210DC1FAD00366F92D602B1D42B88E24531F907E"); 26 | 27 | const uint256_t c = powm(b, p, m); 28 | 29 | const auto result_is_ok = 30 | (c == "0x5231F0EF6BBB3E78B9D7B1FA5F86EFA932E71BABD8A1CFF2C9EE5C396284ED07"); 31 | 32 | return result_is_ok; 33 | } 34 | 35 | // Enable this if you would like to activate this main() as a standalone example. 36 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE005_POWM) 37 | 38 | #include 39 | #include 40 | 41 | auto main() -> int 42 | { 43 | #if defined(WIDE_INTEGER_NAMESPACE) 44 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example005_powm(); 45 | #else 46 | const auto result_is_ok = ::math::wide_integer::example005_powm(); 47 | #endif 48 | 49 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 50 | 51 | return (result_is_ok ? 0 : -1); 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /examples/example005a_pow_factors_of_p99.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | 11 | #if defined(WIDE_INTEGER_NAMESPACE) 12 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example005a_pow_factors_of_p99() -> bool 13 | #else 14 | auto ::math::wide_integer::example005a_pow_factors_of_p99() -> bool 15 | #endif 16 | { 17 | #if defined(WIDE_INTEGER_NAMESPACE) 18 | using uint384_t = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t(UINT32_C(384))>; 19 | #else 20 | using uint384_t = ::math::wide_integer::uintwide_t(UINT32_C(384))>; 21 | #endif 22 | 23 | const uint384_t c = (pow(uint384_t(10U), 99) - 1) / 9; 24 | 25 | // Consider Table 9, page 410 of the classic work: 26 | // H. Riesel, "Prime Numbers and Computer Methods of Factorization", 27 | // Second Edition (Birkhaeuser, 1994). In that table, we find the 28 | // prime factorization of P99 = (10^99 - 1) / 9. This example 29 | // verifies the tabulated result. 30 | 31 | // FactorInteger[(10^33 - 1)/9] 32 | const uint384_t control_p33 33 | { 34 | uint384_t(3U) 35 | * uint384_t(37U) 36 | * uint384_t(67U) 37 | * uint384_t(21649U) 38 | * uint384_t(513239U) 39 | * uint384_t("1344628210313298373") 40 | }; 41 | 42 | // FactorInteger[(10^99 - 1)/9] 43 | const uint384_t control_p99 44 | { 45 | control_p33 46 | * uint384_t(3U) 47 | * uint384_t(199U) 48 | * uint384_t(397U) 49 | * uint384_t(34849U) 50 | * uint384_t(333667U) 51 | * uint384_t("362853724342990469324766235474268869786311886053883") 52 | }; 53 | 54 | const auto result_is_ok = (c == control_p99); 55 | 56 | return result_is_ok; 57 | } 58 | 59 | // Enable this if you would like to activate this main() as a standalone example. 60 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE005A_POW_FACTORS_OF_P99) 61 | 62 | #include 63 | #include 64 | 65 | auto main() -> int 66 | { 67 | #if defined(WIDE_INTEGER_NAMESPACE) 68 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example005a_pow_factors_of_p99(); 69 | #else 70 | const auto result_is_ok = ::math::wide_integer::example005a_pow_factors_of_p99(); 71 | #endif 72 | 73 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 74 | 75 | return (result_is_ok ? 0 : -1); 76 | } 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /examples/example006_gcd.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | 11 | #if defined(WIDE_INTEGER_NAMESPACE) 12 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example006_gcd() -> bool 13 | #else 14 | auto ::math::wide_integer::example006_gcd() -> bool 15 | #endif 16 | { 17 | #if defined(WIDE_INTEGER_NAMESPACE) 18 | using WIDE_INTEGER_NAMESPACE::math::wide_integer::uint256_t; 19 | #else 20 | using ::math::wide_integer::uint256_t; 21 | #endif 22 | 23 | auto result_is_ok = true; 24 | 25 | { 26 | constexpr auto a = uint256_t("0x1035452A5197CF882B5B5EB64C8CCFEE4D772F9F7B66A239649A43093464EFF5"); 27 | constexpr auto b = uint256_t("0xB4F6151D727361113083D9A0DEB91B0B62A250F65DA6543823703D0140C873AD"); 28 | 29 | constexpr auto c = gcd(a, b); 30 | 31 | constexpr auto result_gcd_is_ok = (static_cast(c) == static_cast(UINT32_C(11759761))); 32 | 33 | static_assert(result_gcd_is_ok, "Error: example006_gcd not OK!"); 34 | 35 | result_is_ok = (result_gcd_is_ok && result_is_ok); 36 | } 37 | 38 | { 39 | constexpr auto a = uint256_t("0xD2690CD26CD57A3C443993851A70D3B62F841573668DF7B229508371A0AEDE7F"); 40 | constexpr auto b = uint256_t("0xFE719235CD0B1A314D4CA6940AEDC38BDF8E9484E68CE814EDAA17D87B0B4CC8"); 41 | 42 | constexpr auto c = gcd(a, b); 43 | 44 | constexpr auto result_gcd_is_ok = (static_cast(c) == static_cast(UINT32_C(12170749))); 45 | 46 | static_assert(result_gcd_is_ok, "Error: example006_gcd not OK!"); 47 | 48 | result_is_ok = (result_gcd_is_ok && result_is_ok); 49 | } 50 | 51 | { 52 | constexpr auto a = uint256_t("0x7495AFF66DCB1085DC4CC294ECCBB1B455F65765DD4E9735564FDD80A05168A"); 53 | constexpr auto b = uint256_t("0x7A0543EF0705942D09962172ED5038814AE6EDF8EED2FC6C52CF317D253BC81F"); 54 | 55 | constexpr auto c = gcd(a, b); 56 | 57 | constexpr auto result_gcd_is_ok = (static_cast(c) == static_cast(UINT32_C(13520497))); 58 | 59 | static_assert(result_gcd_is_ok, "Error: example006_gcd not OK!"); 60 | 61 | result_is_ok = (result_gcd_is_ok && result_is_ok); 62 | } 63 | 64 | return result_is_ok; 65 | } 66 | 67 | // Enable this if you would like to activate this main() as a standalone example. 68 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE006_GCD) 69 | 70 | #include 71 | #include 72 | 73 | auto main() -> int 74 | { 75 | #if defined(WIDE_INTEGER_NAMESPACE) 76 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example006_gcd(); 77 | #else 78 | const auto result_is_ok = ::math::wide_integer::example006_gcd(); 79 | #endif 80 | 81 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 82 | 83 | return (result_is_ok ? 0 : -1); 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /examples/example007_random_generator.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace local_random 16 | { 17 | template 19 | auto generate() -> bool 20 | { 21 | using random_engine_type = std::mersenne_twister_engine(UINT32_C( 64)), 23 | static_cast(UINT32_C(312)), 24 | static_cast(UINT32_C(156)), 25 | static_cast(UINT32_C( 31)), 26 | UINT64_C(0xB5026F5AA96619E9), 27 | static_cast(UINT32_C( 29)), 28 | UINT64_C(0x5555555555555555), 29 | static_cast(UINT32_C( 17)), 30 | UINT64_C(0x71D67FFFEDA60000), 31 | static_cast(UINT32_C( 37)), 32 | UINT64_C(0xFFF7EEE000000000), 33 | static_cast(UINT32_C( 43)), 34 | UINT64_C(6364136223846793005)>; 35 | 36 | #if defined(WIDE_INTEGER_NAMESPACE) 37 | using wide_integer_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t(UINT32_C(256)), std::uint32_t, AllocatorType>; 38 | using distribution_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uniform_int_distribution; 39 | #else 40 | using wide_integer_type = ::math::wide_integer::uintwide_t(UINT32_C(256)), std::uint32_t, AllocatorType>; 41 | using distribution_type = ::math::wide_integer::uniform_int_distribution; 42 | #endif 43 | 44 | // Generate a random number with wide_integer_type having limbs of type LimbType. 45 | // Purosely use the default seed. 46 | random_engine_type generator; // NOLINT(cert-msc32-c,cert-msc51-cpp) 47 | 48 | distribution_type distribution { }; 49 | 50 | const wide_integer_type n = distribution(generator); 51 | 52 | const auto result_is_ok = 53 | (n == wide_integer_type("0xF258D22D4DB91392B5EE8CB6ABE457F8401F7AC78BC80F1CC96D191CF6F6AEA6")); 54 | 55 | return result_is_ok; 56 | } 57 | } // namespace local_random 58 | 59 | #if defined(WIDE_INTEGER_NAMESPACE) 60 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example007_random_generator() -> bool 61 | #else 62 | auto ::math::wide_integer::example007_random_generator() -> bool 63 | #endif 64 | { 65 | const bool result_08_is_ok = local_random::generate (); 66 | const bool result_16_is_ok = local_random::generate(); 67 | const bool result_32_is_ok = local_random::generate(); 68 | 69 | const auto result_is_ok = ( result_08_is_ok 70 | && result_16_is_ok 71 | && result_32_is_ok); 72 | 73 | return result_is_ok; 74 | } 75 | 76 | // Enable this if you would like to activate this main() as a standalone example. 77 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE007_RANDOM_GENERATOR) 78 | 79 | #include 80 | #include 81 | 82 | auto main() -> int 83 | { 84 | #if defined(WIDE_INTEGER_NAMESPACE) 85 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example007_random_generator(); 86 | #else 87 | const auto result_is_ok = ::math::wide_integer::example007_random_generator(); 88 | #endif 89 | 90 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 91 | 92 | return (result_is_ok ? 0 : -1); 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /examples/example008a_miller_rabin_prime.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | // This Miller-Rabin primality test is loosely based on 9 | // an adaptation of some code from Boost.Multiprecision. 10 | // The Boost.Multiprecision code can be found here: 11 | // https://www.boost.org/doc/libs/1_78_0/libs/multiprecision/doc/html/boost_multiprecision/tut/primetest.html 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | 21 | #if !defined(BOOST_VERSION) 22 | #error BOOST_VERSION is not defined. Ensure that is properly included. 23 | #endif 24 | 25 | #if ((BOOST_VERSION >= 107900) && !defined(BOOST_MP_STANDALONE)) 26 | #define BOOST_MP_STANDALONE 27 | #endif 28 | 29 | #if ((BOOST_VERSION >= 108000) && !defined(BOOST_NO_EXCEPTIONS)) 30 | #define BOOST_NO_EXCEPTIONS 31 | #endif 32 | 33 | #if (BOOST_VERSION < 108000) 34 | #if defined(__GNUC__) 35 | #pragma GCC diagnostic push 36 | #pragma GCC diagnostic ignored "-Wconversion" 37 | #pragma GCC diagnostic push 38 | #pragma GCC diagnostic ignored "-Wsign-conversion" 39 | #pragma GCC diagnostic push 40 | #pragma GCC diagnostic ignored "-Wunused-parameter" 41 | #endif 42 | #endif 43 | 44 | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)) 45 | #pragma GCC diagnostic push 46 | #pragma GCC diagnostic ignored "-Wrestrict" 47 | #pragma GCC diagnostic push 48 | #pragma GCC diagnostic ignored "-Warray-bounds" 49 | #endif 50 | 51 | #if (BOOST_VERSION < 108000) 52 | #if ((defined(__clang__) && (__clang_major__ > 9)) && !defined(__APPLE__)) 53 | #pragma GCC diagnostic push 54 | #pragma GCC diagnostic ignored "-Wdeprecated-copy" 55 | #endif 56 | #endif 57 | 58 | #include 59 | #include 60 | 61 | #include 62 | 63 | namespace local_miller_rabin { 64 | 65 | template 66 | auto lexical_cast(const UnsignedIntegralType& u) -> std::string 67 | { 68 | std::stringstream ss; 69 | 70 | ss << u; 71 | 72 | return ss.str(); 73 | } 74 | 75 | } // namespace local_miller_rabin 76 | 77 | #if defined(WIDE_INTEGER_NAMESPACE) 78 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example008a_miller_rabin_prime() -> bool 79 | #else 80 | auto ::math::wide_integer::example008a_miller_rabin_prime() -> bool 81 | #endif 82 | { 83 | #if defined(WIDE_INTEGER_NAMESPACE) 84 | using boost_wide_integer_type = 85 | boost::multiprecision::number(UINT32_C(512))>, 86 | boost::multiprecision::et_off>; 87 | #else 88 | using boost_wide_integer_type = 89 | boost::multiprecision::number(UINT32_C(512))>, 90 | boost::multiprecision::et_off>; 91 | #endif 92 | 93 | // This example uses wide_integer's uniform_int_distribution to select 94 | // prime candidates. These prime candidates are subsequently converted 95 | // (via string-streaming) to Boost.Multiprecision integers. 96 | 97 | #if defined(WIDE_INTEGER_NAMESPACE) 98 | using local_wide_integer_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t (std::numeric_limits::digits)>; 99 | using local_distribution_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uniform_int_distribution(std::numeric_limits::digits)>; 100 | #else 101 | using local_wide_integer_type = ::math::wide_integer::uintwide_t (std::numeric_limits::digits)>; 102 | using local_distribution_type = ::math::wide_integer::uniform_int_distribution(std::numeric_limits::digits)>; 103 | #endif 104 | 105 | using random_engine1_type = std::mt19937; 106 | using random_engine2_type = std::linear_congruential_engine; // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 107 | 108 | const auto seed_start = ::util::util_pseudorandom_time_point_seed::value(); 109 | 110 | random_engine1_type gen1(static_cast(seed_start)); 111 | random_engine2_type gen2(static_cast(seed_start)); 112 | 113 | // Select prime candidates from a range of 10^150 ... max(uint512_t)-1. 114 | constexpr local_wide_integer_type 115 | dist_min 116 | ( 117 | "1" 118 | "00000000000000000000000000000000000000000000000000" 119 | "00000000000000000000000000000000000000000000000000" 120 | "00000000000000000000000000000000000000000000000000" 121 | ); 122 | 123 | constexpr auto dist_max = 124 | local_wide_integer_type 125 | { 126 | (std::numeric_limits::max)() 127 | - static_cast(INT8_C(1)) 128 | }; 129 | 130 | local_distribution_type 131 | dist 132 | { 133 | dist_min, 134 | dist_max 135 | }; 136 | 137 | boost_wide_integer_type p0; 138 | boost_wide_integer_type p1; 139 | 140 | auto dist_func = 141 | [&dist, &gen1]() // NOLINT(modernize-use-trailing-return-type) 142 | { 143 | const auto n = dist(gen1); 144 | 145 | return boost_wide_integer_type(local_miller_rabin::lexical_cast(n)); 146 | }; 147 | 148 | for(;;) 149 | { 150 | p0 = dist_func(); 151 | 152 | const auto p0_is_probably_prime = boost::multiprecision::miller_rabin_test(p0, 25U, gen2); 153 | 154 | if(p0_is_probably_prime) 155 | { 156 | break; 157 | } 158 | } 159 | 160 | const auto seed_next = ::util::util_pseudorandom_time_point_seed::value(); 161 | 162 | gen1.seed(static_cast(seed_next)); 163 | 164 | for(;;) 165 | { 166 | p1 = dist_func(); 167 | 168 | const auto p1_is_probably_prime = boost::multiprecision::miller_rabin_test(p1, 25U, gen2); 169 | 170 | if(p1_is_probably_prime) 171 | { 172 | break; 173 | } 174 | } 175 | 176 | const boost_wide_integer_type gd = gcd(p0, p1); 177 | 178 | const auto result_is_ok = ( (p0 > boost_wide_integer_type(local_miller_rabin::lexical_cast(dist_min))) 179 | && (p1 > boost_wide_integer_type(local_miller_rabin::lexical_cast(dist_min))) 180 | && (p0 != 0U) 181 | && (p1 != 0U) 182 | && (p0 != p1) 183 | && (gd == 1U)); 184 | 185 | return result_is_ok; 186 | } 187 | 188 | // Enable this if you would like to activate this main() as a standalone example. 189 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE008A_MILLER_RABIN_PRIME) 190 | 191 | #include 192 | #include 193 | 194 | auto main() -> int // NOLINT(bugprone-exception-escape) 195 | { 196 | #if defined(WIDE_INTEGER_NAMESPACE) 197 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example008a_miller_rabin_prime(); 198 | #else 199 | const auto result_is_ok = ::math::wide_integer::example008a_miller_rabin_prime(); 200 | #endif 201 | 202 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 203 | 204 | return (result_is_ok ? 0 : -1); 205 | } 206 | 207 | #endif 208 | 209 | #if (BOOST_VERSION < 108000) 210 | #if ((defined(__clang__) && (__clang_major__ > 9)) && !defined(__APPLE__)) 211 | #pragma GCC diagnostic pop 212 | #endif 213 | #endif 214 | 215 | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)) 216 | #pragma GCC diagnostic pop 217 | #pragma GCC diagnostic pop 218 | #endif 219 | 220 | #if (BOOST_VERSION < 108000) 221 | #if defined(__GNUC__) 222 | #pragma GCC diagnostic pop 223 | #pragma GCC diagnostic pop 224 | #pragma GCC diagnostic pop 225 | #endif 226 | #endif 227 | -------------------------------------------------------------------------------- /examples/example009_timed_mul.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace local_timed_mul 24 | { 25 | constexpr std::uint32_t wide_integer_test9_digits2 = static_cast(1ULL << 15U); 26 | 27 | template 29 | auto get_random_big_uint(RandomEngineType& rng, UnsignedIntegralIteratorType it_out) -> void 30 | { 31 | using local_uint_type = typename std::iterator_traits::value_type; 32 | 33 | #if defined(WIDE_INTEGER_NAMESPACE) 34 | using distribution_type = 35 | WIDE_INTEGER_NAMESPACE::math::wide_integer::uniform_int_distribution::digits, typename local_uint_type::limb_type>; 36 | #else 37 | using distribution_type = 38 | ::math::wide_integer::uniform_int_distribution::digits, typename local_uint_type::limb_type>; 39 | #endif 40 | 41 | distribution_type distribution; 42 | 43 | *it_out = distribution(rng); 44 | } 45 | 46 | #if defined(WIDE_INTEGER_NAMESPACE) 47 | using big_uint_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t; 48 | #else 49 | using big_uint_type = ::math::wide_integer::uintwide_t; 50 | #endif 51 | 52 | auto local_a() -> std::vector& 53 | { 54 | static std::vector 55 | my_local_a 56 | ( 57 | static_cast::size_type>(UINT32_C(128)) 58 | ); 59 | 60 | return my_local_a; 61 | } 62 | 63 | auto local_b() -> std::vector& 64 | { 65 | static std::vector my_local_b(local_a().size()); 66 | 67 | return my_local_b; 68 | } 69 | } // namespace local_timed_mul 70 | 71 | #if defined(WIDE_INTEGER_NAMESPACE) 72 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example009_timed_mul() -> bool 73 | #else 74 | auto ::math::wide_integer::example009_timed_mul() -> bool 75 | #endif 76 | { 77 | using random_engine_type = 78 | std::linear_congruential_engine; 79 | 80 | random_engine_type rng; // NOLINT(cert-msc32-c,cert-msc51-cpp) 81 | 82 | rng.seed(::util::util_pseudorandom_time_point_seed::value()); 83 | 84 | for(auto i = static_cast::size_type>(0U); i < local_timed_mul::local_a().size(); ++i) 85 | { 86 | local_timed_mul::get_random_big_uint(rng, local_timed_mul::local_a().begin() + static_cast::difference_type>(i)); 87 | local_timed_mul::get_random_big_uint(rng, local_timed_mul::local_b().begin() + static_cast::difference_type>(i)); 88 | } 89 | 90 | std::uint64_t count = 0U; 91 | std::size_t index = 0U; 92 | 93 | using stopwatch_type = concurrency::stopwatch; 94 | 95 | stopwatch_type my_stopwatch { }; 96 | 97 | while(stopwatch_type::elapsed_time(my_stopwatch) < static_cast(6.0L)) // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 98 | { 99 | local_timed_mul::local_a().at(index) * local_timed_mul::local_b().at(index); 100 | 101 | ++count; 102 | ++index; 103 | 104 | if(index >= local_timed_mul::local_a().size()) 105 | { 106 | index = 0U; 107 | } 108 | } 109 | 110 | const float kops_per_sec = static_cast(count) / static_cast(static_cast(stopwatch_type::elapsed_time(my_stopwatch) * 1000.0F)); 111 | 112 | { 113 | const auto flg = std::cout.flags(); 114 | 115 | std::cout << "bits: " 116 | << std::numeric_limits::digits 117 | << ", kops_per_sec: " 118 | << std::fixed 119 | << std::setprecision(3) 120 | << kops_per_sec 121 | << ", count: " 122 | << count 123 | << std::endl; 124 | 125 | std::cout.flags(flg); 126 | } 127 | 128 | const auto result_is_ok = (kops_per_sec > (std::numeric_limits::min)()); 129 | 130 | return result_is_ok; 131 | } 132 | 133 | // Enable this if you would like to activate this main() as a standalone example. 134 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE009_TIMED_MUL) 135 | 136 | auto main() -> int 137 | { 138 | #if defined(WIDE_INTEGER_NAMESPACE) 139 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example009_timed_mul(); 140 | #else 141 | const auto result_is_ok = ::math::wide_integer::example009_timed_mul(); 142 | #endif 143 | 144 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 145 | 146 | return (result_is_ok ? 0 : -1); 147 | } 148 | 149 | #endif 150 | -------------------------------------------------------------------------------- /examples/example009a_timed_mul_4_by_4.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace local_timed_mul_4_by_4 24 | { 25 | template 27 | auto get_random_big_uint(RandomEngineType& rng, UnsignedIntegralIteratorType it_out) -> void 28 | { 29 | using local_uint_type = typename std::iterator_traits::value_type; 30 | 31 | #if defined(WIDE_INTEGER_NAMESPACE) 32 | using distribution_type = 33 | WIDE_INTEGER_NAMESPACE::math::wide_integer::uniform_int_distribution::digits, typename local_uint_type::limb_type>; 34 | #else 35 | using distribution_type = 36 | ::math::wide_integer::uniform_int_distribution::digits, typename local_uint_type::limb_type>; 37 | #endif 38 | 39 | distribution_type distribution; 40 | 41 | *it_out = distribution(rng); 42 | } 43 | 44 | #if defined(WIDE_INTEGER_NAMESPACE) 45 | using big_uint_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t(UINT32_C(128))>; 46 | #else 47 | using big_uint_type = ::math::wide_integer::uintwide_t(UINT32_C(128))>; 48 | #endif 49 | 50 | auto local_a() -> std::vector& 51 | { 52 | static std::vector 53 | my_local_a 54 | ( 55 | static_cast::size_type>(UINT32_C(1024)) 56 | ); 57 | 58 | return my_local_a; 59 | } 60 | 61 | auto local_b() -> std::vector& 62 | { 63 | static std::vector my_local_b(local_a().size()); 64 | 65 | return my_local_b; 66 | } 67 | } // namespace local_timed_mul_4_by_4 68 | 69 | #if defined(WIDE_INTEGER_NAMESPACE) 70 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example009a_timed_mul_4_by_4() -> bool 71 | #else 72 | auto ::math::wide_integer::example009a_timed_mul_4_by_4() -> bool 73 | #endif 74 | { 75 | using random_engine_type = 76 | std::linear_congruential_engine; 77 | 78 | random_engine_type rng; // NOLINT(cert-msc32-c,cert-msc51-cpp) 79 | 80 | rng.seed(::util::util_pseudorandom_time_point_seed::value()); 81 | 82 | for(auto i = static_cast::size_type>(0U); i < local_timed_mul_4_by_4::local_a().size(); ++i) 83 | { 84 | local_timed_mul_4_by_4::get_random_big_uint(rng, local_timed_mul_4_by_4::local_a().begin() + static_cast::difference_type>(i)); 85 | local_timed_mul_4_by_4::get_random_big_uint(rng, local_timed_mul_4_by_4::local_b().begin() + static_cast::difference_type>(i)); 86 | } 87 | 88 | std::uint64_t count = 0U; 89 | std::size_t index = 0U; 90 | 91 | using stopwatch_type = concurrency::stopwatch; 92 | 93 | stopwatch_type my_stopwatch { }; 94 | 95 | while(stopwatch_type::elapsed_time(my_stopwatch) < static_cast(6.0L)) // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 96 | { 97 | local_timed_mul_4_by_4::local_a().at(index + 0U) * local_timed_mul_4_by_4::local_b().at(index + 0U); 98 | local_timed_mul_4_by_4::local_a().at(index + 1U) * local_timed_mul_4_by_4::local_b().at(index + 1U); 99 | local_timed_mul_4_by_4::local_a().at(index + 2U) * local_timed_mul_4_by_4::local_b().at(index + 2U); 100 | local_timed_mul_4_by_4::local_a().at(index + 3U) * local_timed_mul_4_by_4::local_b().at(index + 3U); 101 | 102 | count += 4U; 103 | index += 4U; 104 | 105 | if(index >= local_timed_mul_4_by_4::local_a().size()) 106 | { 107 | index = 0U; 108 | } 109 | } 110 | 111 | const float kops_per_sec = static_cast(count) / static_cast(static_cast(stopwatch_type::elapsed_time(my_stopwatch) * 1000.0F)); 112 | 113 | { 114 | const auto flg = std::cout.flags(); 115 | 116 | std::cout << "bits: " 117 | << std::numeric_limits::digits 118 | << ", kops_per_sec: " 119 | << std::fixed 120 | << std::setprecision(2) 121 | << kops_per_sec 122 | << ", count: " 123 | << count 124 | << std::endl; 125 | 126 | std::cout.flags(flg); 127 | } 128 | 129 | const auto result_is_ok = (kops_per_sec > (std::numeric_limits::min)()); 130 | 131 | return result_is_ok; 132 | } 133 | 134 | // Enable this if you would like to activate this main() as a standalone example. 135 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE009A_TIMED_MUL_4_BY_4) 136 | 137 | auto main() -> int 138 | { 139 | #if defined(WIDE_INTEGER_NAMESPACE) 140 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example009a_timed_mul_4_by_4(); 141 | #else 142 | const auto result_is_ok = ::math::wide_integer::example009a_timed_mul_4_by_4(); 143 | #endif 144 | 145 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 146 | 147 | return (result_is_ok ? 0 : -1); 148 | } 149 | 150 | #endif 151 | -------------------------------------------------------------------------------- /examples/example009b_timed_mul_8_by_8.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace local_timed_mul_8_by_8 24 | { 25 | template 27 | auto get_random_big_uint(RandomEngineType& rng, UnsignedIntegralIteratorType it_out) -> void 28 | { 29 | using local_uint_type = typename std::iterator_traits::value_type; 30 | 31 | #if defined(WIDE_INTEGER_NAMESPACE) 32 | using distribution_type = 33 | WIDE_INTEGER_NAMESPACE::math::wide_integer::uniform_int_distribution::digits, typename local_uint_type::limb_type>; 34 | #else 35 | using distribution_type = 36 | ::math::wide_integer::uniform_int_distribution::digits, typename local_uint_type::limb_type>; 37 | #endif 38 | 39 | distribution_type distribution; 40 | 41 | *it_out = distribution(rng); 42 | } 43 | 44 | #if defined(WIDE_INTEGER_NAMESPACE) 45 | using big_uint_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t(UINT32_C(256))>; 46 | #else 47 | using big_uint_type = ::math::wide_integer::uintwide_t(UINT32_C(256))>; 48 | #endif 49 | 50 | auto local_a() -> std::vector& 51 | { 52 | static std::vector 53 | my_local_a 54 | ( 55 | static_cast::size_type>(UINT32_C(1024)) 56 | ); 57 | 58 | return my_local_a; 59 | } 60 | 61 | auto local_b() -> std::vector& 62 | { 63 | static std::vector my_local_b(local_a().size()); 64 | 65 | return my_local_b; 66 | } 67 | } // namespace local_timed_mul_8_by_8 68 | 69 | #if defined(WIDE_INTEGER_NAMESPACE) 70 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example009b_timed_mul_8_by_8() -> bool 71 | #else 72 | auto ::math::wide_integer::example009b_timed_mul_8_by_8() -> bool 73 | #endif 74 | { 75 | using random_engine_type = 76 | std::linear_congruential_engine; 77 | 78 | random_engine_type rng; // NOLINT(cert-msc32-c,cert-msc51-cpp) 79 | 80 | rng.seed(::util::util_pseudorandom_time_point_seed::value()); 81 | 82 | for(auto i = static_cast::size_type>(0U); i < local_timed_mul_8_by_8::local_a().size(); ++i) 83 | { 84 | local_timed_mul_8_by_8::get_random_big_uint(rng, local_timed_mul_8_by_8::local_a().begin() + static_cast::difference_type>(i)); 85 | local_timed_mul_8_by_8::get_random_big_uint(rng, local_timed_mul_8_by_8::local_b().begin() + static_cast::difference_type>(i)); 86 | } 87 | 88 | std::uint64_t count = 0U; 89 | std::size_t index = 0U; 90 | 91 | using stopwatch_type = concurrency::stopwatch; 92 | 93 | stopwatch_type my_stopwatch { }; 94 | 95 | while(stopwatch_type::elapsed_time(my_stopwatch) < static_cast(6.0L)) // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 96 | { 97 | local_timed_mul_8_by_8::local_a().at(index + 0U) * local_timed_mul_8_by_8::local_b().at(index + 0U); 98 | local_timed_mul_8_by_8::local_a().at(index + 1U) * local_timed_mul_8_by_8::local_b().at(index + 1U); 99 | local_timed_mul_8_by_8::local_a().at(index + 2U) * local_timed_mul_8_by_8::local_b().at(index + 2U); 100 | local_timed_mul_8_by_8::local_a().at(index + 3U) * local_timed_mul_8_by_8::local_b().at(index + 3U); 101 | 102 | count += 4U; 103 | index += 4U; 104 | 105 | if(index >= local_timed_mul_8_by_8::local_a().size()) 106 | { 107 | index = 0U; 108 | } 109 | } 110 | 111 | const float kops_per_sec = static_cast(count) / static_cast(static_cast(stopwatch_type::elapsed_time(my_stopwatch) * 1000.0F)); 112 | 113 | { 114 | const auto flg = std::cout.flags(); 115 | 116 | std::cout << "bits: " 117 | << std::numeric_limits::digits 118 | << ", kops_per_sec: " 119 | << std::fixed 120 | << std::setprecision(2) 121 | << kops_per_sec 122 | << ", count: " 123 | << count 124 | << std::endl; 125 | 126 | std::cout.flags(flg); 127 | } 128 | 129 | const auto result_is_ok = (kops_per_sec > (std::numeric_limits::min)()); 130 | 131 | return result_is_ok; 132 | } 133 | 134 | // Enable this if you would like to activate this main() as a standalone example. 135 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE009B_TIMED_MUL_8_BY_8) 136 | 137 | auto main() -> int 138 | { 139 | #if defined(WIDE_INTEGER_NAMESPACE) 140 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example009b_timed_mul_8_by_8(); 141 | #else 142 | const auto result_is_ok = ::math::wide_integer::example009b_timed_mul_8_by_8(); 143 | #endif 144 | 145 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 146 | 147 | return (result_is_ok ? 0 : -1); 148 | } 149 | 150 | #endif 151 | -------------------------------------------------------------------------------- /examples/example010_uint48_t.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #if defined(WIDE_INTEGER_NAMESPACE) 14 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example010_uint48_t() -> bool 15 | #else 16 | auto ::math::wide_integer::example010_uint48_t() -> bool 17 | #endif 18 | { 19 | #if defined(WIDE_INTEGER_NAMESPACE) 20 | using uint48_t = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t(UINT32_C(48)), std::uint8_t>; 21 | #else 22 | using uint48_t = ::math::wide_integer::uintwide_t(UINT32_C(48)), std::uint8_t>; 23 | #endif 24 | 25 | #if defined(WIDE_INTEGER_NAMESPACE) 26 | using distribution_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uniform_int_distribution(UINT32_C(48)), typename uint48_t::limb_type>; 27 | #else 28 | using distribution_type = ::math::wide_integer::uniform_int_distribution(UINT32_C(48)), typename uint48_t::limb_type>; 29 | #endif 30 | 31 | using random_engine_type = std::linear_congruential_engine; 32 | 33 | random_engine_type generator(static_cast(UINT32_C(0xF00DCAFE))); // NOLINT(cert-msc32-c,cert-msc51-cpp,cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 34 | 35 | distribution_type distribution; 36 | 37 | const auto a64 = static_cast(distribution(generator)); 38 | const auto b64 = static_cast(distribution(generator)); 39 | 40 | const uint48_t a(a64); 41 | const uint48_t b(b64); 42 | 43 | const uint48_t c_add = (a + b); 44 | const uint48_t c_sub = (a - b); 45 | const uint48_t c_mul = (a * b); 46 | const uint48_t c_div = (a / b); 47 | 48 | const auto result_is_ok = ( ( (c_add == static_cast((a64 + b64) & static_cast(UINT64_C(0x0000FFFFFFFFFFFF)))) 49 | && (c_sub == static_cast((a64 - b64) & static_cast(UINT64_C(0x0000FFFFFFFFFFFF)))) 50 | && (c_mul == static_cast((a64 * b64) & static_cast(UINT64_C(0x0000FFFFFFFFFFFF)))) 51 | && (c_div == static_cast((a64 / b64) & static_cast(UINT64_C(0x0000FFFFFFFFFFFF))))) 52 | && 53 | ( (static_cast(c_add) == static_cast((a64 + b64) & static_cast(UINT64_C(0x0000FFFFFFFFFFFF)))) 54 | && (static_cast(c_sub) == static_cast((a64 - b64) & static_cast(UINT64_C(0x0000FFFFFFFFFFFF)))) 55 | && (static_cast(c_mul) == static_cast((a64 * b64) & static_cast(UINT64_C(0x0000FFFFFFFFFFFF)))) 56 | && (static_cast(c_div) == static_cast((a64 / b64) & static_cast(UINT64_C(0x0000FFFFFFFFFFFF)))))); 57 | 58 | return result_is_ok; 59 | } 60 | 61 | // Enable this if you would like to activate this main() as a standalone example. 62 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE010_UINT48_T) 63 | 64 | #include 65 | #include 66 | 67 | auto main() -> int 68 | { 69 | #if defined(WIDE_INTEGER_NAMESPACE) 70 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example010_uint48_t(); 71 | #else 72 | const auto result_is_ok = ::math::wide_integer::example010_uint48_t(); 73 | #endif 74 | 75 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 76 | 77 | return (result_is_ok ? 0 : -1); 78 | } 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /examples/example011_uint24_t.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2018 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #if defined(WIDE_INTEGER_NAMESPACE) 14 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::example011_uint24_t() -> bool 15 | #else 16 | auto ::math::wide_integer::example011_uint24_t() -> bool 17 | #endif 18 | { 19 | #if defined(WIDE_INTEGER_NAMESPACE) 20 | using uint24_t = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t(UINT32_C(24)), std::uint8_t>; 21 | #else 22 | using uint24_t = ::math::wide_integer::uintwide_t(UINT32_C(24)), std::uint8_t>; 23 | #endif 24 | 25 | #if defined(WIDE_INTEGER_NAMESPACE) 26 | using distribution_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uniform_int_distribution(UINT32_C(24)), typename uint24_t::limb_type>; 27 | #else 28 | using distribution_type = ::math::wide_integer::uniform_int_distribution(UINT32_C(24)), typename uint24_t::limb_type>; 29 | #endif 30 | 31 | using random_engine_type = std::linear_congruential_engine; 32 | 33 | random_engine_type generator(UINT32_C(0xDEADBEEF)); // NOLINT(cert-msc32-c,cert-msc51-cpp) 34 | 35 | distribution_type distribution; 36 | 37 | const auto a32 = static_cast(distribution(generator)); 38 | const auto b32 = static_cast(distribution(generator)); 39 | 40 | const uint24_t a(a32); 41 | const uint24_t b(b32); 42 | 43 | const uint24_t c_add = (a + b); 44 | const uint24_t c_sub = (a - b); 45 | const uint24_t c_mul = (a * b); 46 | const uint24_t c_div = (a / b); 47 | 48 | const auto result_is_ok = ( ( (c_add == static_cast(static_cast(a32 + b32) & UINT32_C(0x00FFFFFF))) 49 | && (c_sub == static_cast(static_cast(a32 - b32) & UINT32_C(0x00FFFFFF))) 50 | && (c_mul == static_cast(static_cast(a32 * b32) & UINT32_C(0x00FFFFFF))) 51 | && (c_div == static_cast(static_cast(a32 / b32) & UINT32_C(0x00FFFFFF)))) 52 | && 53 | ( (static_cast(c_add) == static_cast(static_cast(a32 + b32) & UINT32_C(0x00FFFFFF))) 54 | && (static_cast(c_sub) == static_cast(static_cast(a32 - b32) & UINT32_C(0x00FFFFFF))) 55 | && (static_cast(c_mul) == static_cast(static_cast(a32 * b32) & UINT32_C(0x00FFFFFF))) 56 | && (static_cast(c_div) == static_cast(static_cast(a32 / b32) & UINT32_C(0x00FFFFFF))))); 57 | 58 | return result_is_ok; 59 | } 60 | 61 | // Enable this if you would like to activate this main() as a standalone example. 62 | #if defined(WIDE_INTEGER_STANDALONE_EXAMPLE011_UINT24_T) 63 | 64 | #include 65 | #include 66 | 67 | auto main() -> int 68 | { 69 | #if defined(WIDE_INTEGER_NAMESPACE) 70 | const auto result_is_ok = WIDE_INTEGER_NAMESPACE::math::wide_integer::example011_uint24_t(); 71 | #else 72 | const auto result_is_ok = ::math::wide_integer::example011_uint24_t(); 73 | #endif 74 | 75 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 76 | 77 | return (result_is_ok ? 0 : -1); 78 | } 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /examples/example_uintwide_t.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2021 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #ifndef EXAMPLE_UINTWIDE_T_2021_04_29_H // NOLINT(llvm-header-guard) 9 | #define EXAMPLE_UINTWIDE_T_2021_04_29_H 10 | 11 | // This file contains function prototypes of the uintwide_t examples. 12 | 13 | #include 14 | 15 | WIDE_INTEGER_NAMESPACE_BEGIN 16 | 17 | #if(__cplusplus >= 201703L) 18 | namespace math::wide_integer { 19 | #else 20 | namespace math { namespace wide_integer { // NOLINT(modernize-concat-nested-namespaces) 21 | #endif 22 | 23 | auto example000_numeric_limits () -> bool; 24 | auto example000a_builtin_convert () -> bool; 25 | auto example001_mul_div () -> bool; 26 | auto example001a_div_mod () -> bool; 27 | auto example002_shl_shr () -> bool; 28 | auto example003_sqrt () -> bool; 29 | auto example003a_cbrt () -> bool; 30 | auto example004_rootk_pow () -> bool; 31 | auto example005_powm () -> bool; 32 | auto example005a_pow_factors_of_p99() -> bool; 33 | auto example006_gcd () -> bool; 34 | auto example007_random_generator () -> bool; 35 | auto example008_miller_rabin_prime () -> bool; 36 | auto example008a_miller_rabin_prime() -> bool; 37 | auto example009_timed_mul () -> bool; 38 | auto example009a_timed_mul_4_by_4 () -> bool; 39 | auto example009b_timed_mul_8_by_8 () -> bool; 40 | auto example010_uint48_t () -> bool; 41 | auto example011_uint24_t () -> bool; 42 | auto example012_rsa_crypto () -> bool; 43 | auto example013_ecdsa_sign_verify () -> bool; 44 | auto example014_pi_spigot_wide () -> bool; 45 | 46 | #if(__cplusplus >= 201703L) 47 | } // namespace math::wide_integer 48 | #else 49 | } // namespace wide_integer 50 | } // namespace math 51 | #endif 52 | 53 | WIDE_INTEGER_NAMESPACE_END 54 | 55 | #endif // EXAMPLE_UINTWIDE_T_2021_04_29_H 56 | -------------------------------------------------------------------------------- /run_fuzzing.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Example call: 4 | # bash run_fuzzing.sh /mnt/c/boost/boost_1_87_0 5 | 6 | if [[ "$1" != "" ]]; then 7 | MY_BOOST="$1" 8 | else 9 | MY_BOOST=../boost-root 10 | fi 11 | 12 | 13 | echo 'compiling test/fuzzing/test_fuzzing_add.cpp' && clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I$MY_BOOST test/fuzzing/test_fuzzing_add.cpp -o test_fuzzing_add 14 | echo 'compiling test/fuzzing/test_fuzzing_sub.cpp' && clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I$MY_BOOST test/fuzzing/test_fuzzing_sub.cpp -o test_fuzzing_sub 15 | echo 'compiling test/fuzzing/test_fuzzing_mul.cpp' && clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I$MY_BOOST test/fuzzing/test_fuzzing_mul.cpp -o test_fuzzing_mul 16 | echo 'compiling test/fuzzing/test_fuzzing_div.cpp' && clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I$MY_BOOST test/fuzzing/test_fuzzing_div.cpp -o test_fuzzing_div 17 | echo 'compiling test/fuzzing/test_fuzzing_sdiv.cpp' && clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I$MY_BOOST test/fuzzing/test_fuzzing_sdiv.cpp -o test_fuzzing_sdiv 18 | echo 'compiling test/fuzzing/test_fuzzing_sqrt.cpp' && clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I$MY_BOOST test/fuzzing/test_fuzzing_sqrt.cpp -o test_fuzzing_sqrt 19 | echo 'compiling test/fuzzing/test_fuzzing_powm.cpp' && clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I$MY_BOOST test/fuzzing/test_fuzzing_powm.cpp -o test_fuzzing_powm 20 | echo 'compiling test/fuzzing/test_fuzzing_prime.cpp' && clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I$MY_BOOST test/fuzzing/test_fuzzing_prime.cpp -o test_fuzzing_prime 21 | 22 | 23 | ls -la test_fuzzing_add test_fuzzing_sub test_fuzzing_mul test_fuzzing_div test_fuzzing_sdiv test_fuzzing_sqrt test_fuzzing_powm test_fuzzing_prime 24 | exit_compile=$? 25 | 26 | 27 | # Start each executable in the background and save their process IDs 28 | ./test_fuzzing_add -max_total_time=900 -max_len=34 -verbosity=0 -close_fd_mask=3 & 29 | pid_add=$! 30 | 31 | ./test_fuzzing_sub -max_total_time=900 -max_len=34 -verbosity=0 -close_fd_mask=3 & 32 | pid_sub=$! 33 | 34 | ./test_fuzzing_mul -max_total_time=900 -max_len=34 -verbosity=0 -close_fd_mask=3 & 35 | pid_mul=$! 36 | 37 | ./test_fuzzing_div -max_total_time=900 -max_len=34 -verbosity=0 -close_fd_mask=3 & 38 | pid_div=$! 39 | 40 | ./test_fuzzing_sdiv -max_total_time=900 -max_len=34 -verbosity=0 -close_fd_mask=3 & 41 | pid_sdiv=$! 42 | 43 | ./test_fuzzing_sqrt -max_total_time=900 -max_len=34 -verbosity=0 -close_fd_mask=3 & 44 | pid_sqrt=$! 45 | 46 | ./test_fuzzing_powm -max_total_time=900 -max_len=34 -verbosity=0 -close_fd_mask=3 & 47 | pid_powm=$! 48 | 49 | ./test_fuzzing_prime -max_total_time=900 -max_len=34 -verbosity=0 -close_fd_mask=3 & 50 | pid_prime=$! 51 | 52 | 53 | # Wait for each job and capture its exit status 54 | wait $pid_add 55 | exit_add=$? 56 | wait $pid_sub 57 | exit_sub=$? 58 | wait $pid_mul 59 | exit_mul=$? 60 | wait $pid_div 61 | exit_div=$? 62 | wait $pid_sdiv 63 | exit_sdiv=$? 64 | wait $pid_sqrt 65 | exit_sqrt=$? 66 | wait $pid_powm 67 | exit_powm=$? 68 | wait $pid_prime 69 | exit_prime=$? 70 | 71 | # Check the status of compilation and of each executable 72 | 73 | echo "exit_compile : " "$exit_compile" 74 | echo "exit_add : " "$exit_add" 75 | echo "exit_sub : " "$exit_sub" 76 | echo "exit_mul : " "$exit_mul" 77 | echo "exit_div : " "$exit_div" 78 | echo "exit_sdiv : " "$exit_sdiv" 79 | echo "exit_sqrt : " "$exit_sqrt" 80 | echo "exit_powm : " "$exit_powm" 81 | echo "exit_prime : " "$exit_prime" 82 | 83 | result_total=$((exit_compile+exit_add+exit_sub+exit_mul+exit_div+exit_sdiv+exit_sqrt+exit_powm+exit_prime)) 84 | 85 | echo "result_total : " "$result_total" 86 | 87 | exit $result_total 88 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=ckormanyos_wide-integer 2 | sonar.organization=ckormanyos 3 | 4 | # This is the name and version displayed in the SonarCloud UI. 5 | sonar.projectName=wide-integer 6 | sonar.projectVersion=1.0 7 | 8 | # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. 9 | sonar.sources=. 10 | 11 | # Encoding of the source code. Default is default system encoding 12 | #sonar.sourceEncoding=UTF-8 13 | 14 | sonar.python.version=2.7 15 | 16 | sonar.cfamily.cache.enabled=false 17 | -------------------------------------------------------------------------------- /target/build/test_examples_emulator.gdb: -------------------------------------------------------------------------------- 1 | # /////////////////////////////////////////////////////////////////// 2 | # // Copyright Christopher Kormanyos 2020 - 2024. 3 | # // Distributed under the Boost Software License, 4 | # // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | # // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | # // 7 | 8 | # Connect to the target (e.g., OpenOCD or another GDB server). 9 | target remote localhost:9999 10 | monitor halt 11 | 12 | # Ensure that the program is loaded. 13 | load 14 | 15 | # Set a breakpoint at the specified subroutine. 16 | break example_get_standalone_result 17 | 18 | # Start or continue program execution. 19 | continue 20 | 21 | # Format and print the value of a variable. 22 | printf "value 0x%X\n\n", example_standalone_result 23 | 24 | # Delete (all) breakpoint(s). 25 | delete 26 | 27 | # Perform a non-elegant quit of the GDB session. 28 | quit 29 | -------------------------------------------------------------------------------- /target/micros/stm32f429/make/stm32f429.ld: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Copyright Christopher Kormanyos 2007 - 2024. 4 | Distributed under the Boost Software License, 5 | Version 1.0. (See accompanying file LICENSE_1_0.txt 6 | or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | */ 8 | 9 | /* Linker script for STM32F4xx ARM(R) Cortex(TM)-M4 MCU */ 10 | 11 | ENTRY(__my_startup) 12 | 13 | INPUT(libc.a libm.a libgcc.a) 14 | 15 | OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 16 | OUTPUT_ARCH(arm) 17 | 18 | /* The beginning and end of the program ROM area */ 19 | /* Set up a ROM area with a size of 64K */ 20 | _rom_begin = 0x08000000; 21 | _rom_end = 0x08010000; 22 | 23 | /* The beginning and end (i.e., the top) of the stack */ 24 | /* Set up a stack with a size of 4K */ 25 | _stack_begin = 0x20007000; 26 | _stack_end = 0x20008000; 27 | 28 | __initial_stack_pointer = 0x20008000 - 4; 29 | 30 | MEMORY 31 | { 32 | ROM(rx) : ORIGIN = 0x08000000, LENGTH = 64K 33 | RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 0x7000 34 | } 35 | 36 | SECTIONS 37 | { 38 | . = 0x08000000; 39 | . = ALIGN(4); 40 | 41 | /* ISR vectors */ 42 | .isr_vector : 43 | { 44 | *(.isr_vector) 45 | . = ALIGN(0x10); 46 | KEEP(*(.isr_vector)) 47 | } > ROM = 0xAAAA 48 | 49 | /* startup */ 50 | .startup : 51 | { 52 | *(.startup) 53 | . = ALIGN(0x10); 54 | KEEP(*(.startup)) 55 | } > ROM = 0x5555 56 | 57 | /* Program code (text), read-only data and static ctors */ 58 | .text : 59 | { 60 | _ctors_begin = .; 61 | KEEP(*(SORT(.init_array.*))) 62 | KEEP(*(.init_array*)) 63 | _ctors_end = .; 64 | *(.progmem*) 65 | . = ALIGN(4); 66 | *(.text) 67 | . = ALIGN(4); 68 | *(.text*) 69 | . = ALIGN(4); 70 | *(.rodata) 71 | . = ALIGN(4); 72 | *(.rodata*) 73 | . = ALIGN(4); 74 | *(.glue_7) 75 | . = ALIGN(4); 76 | *(.glue_7t) 77 | . = ALIGN(4); 78 | } > ROM 79 | 80 | .ARM.extab : 81 | { 82 | . = ALIGN(4); 83 | *(.ARM.extab) 84 | *(.gnu.linkonce.armextab.*) 85 | . = ALIGN(4); 86 | } > ROM 87 | 88 | .exidx : 89 | { 90 | . = ALIGN(4); 91 | PROVIDE(__exidx_start = .); 92 | *(.ARM.exidx*) 93 | . = ALIGN(4); 94 | PROVIDE(__exidx_end = .); 95 | } > ROM 96 | 97 | .ARM.attributes : 98 | { 99 | *(.ARM.attributes) 100 | } > ROM 101 | 102 | . = 0x20000000; 103 | . = ALIGN(4); 104 | 105 | /* The ROM-to-RAM initialized data section */ 106 | .data : 107 | { 108 | _data_begin = .; 109 | *(.data) 110 | . = ALIGN(4); 111 | KEEP (*(.data)) 112 | *(.data*) 113 | . = ALIGN(4); 114 | KEEP (*(.data*)) 115 | _data_end = .; 116 | } > RAM AT > ROM 117 | 118 | /* The uninitialized (zero-cleared) data section */ 119 | .bss : 120 | { 121 | _bss_begin = .; 122 | *(.bss) 123 | . = ALIGN(4); 124 | KEEP (*(.bss)) 125 | *(.bss*) 126 | . = ALIGN(4); 127 | KEEP (*(.bss*)) 128 | _bss_end = .; 129 | } > RAM 130 | 131 | PROVIDE(end = .); 132 | PROVIDE(_fini = .); 133 | 134 | _rom_data_begin = LOADADDR(.data); 135 | } 136 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | enable_testing() 2 | find_package(Threads) 3 | if (Boost_FOUND) 4 | add_executable(test_uintwide_t 5 | test_uintwide_t_boost_backend.cpp 6 | test_uintwide_t_edge_cases.cpp 7 | test_uintwide_t_examples.cpp 8 | test_uintwide_t_float_convert.cpp 9 | test_uintwide_t_int_convert.cpp 10 | test_uintwide_t_n_base.cpp 11 | test_uintwide_t_n_binary_ops_base.cpp 12 | test_uintwide_t_spot_values.cpp 13 | test.cpp) 14 | target_compile_features(test_uintwide_t PRIVATE cxx_std_20) 15 | target_include_directories(test_uintwide_t PRIVATE ${PROJECT_SOURCE_DIR}) 16 | target_link_libraries(test_uintwide_t Examples ${CMAKE_THREAD_LIBS_INIT}) 17 | add_test(test test_uintwide_t) 18 | endif() 19 | -------------------------------------------------------------------------------- /test/coverity.c: -------------------------------------------------------------------------------- 1 | /* Coverity Scan model */ 2 | 3 | void dummy(void) 4 | { 5 | } 6 | -------------------------------------------------------------------------------- /test/fuzzing/test_fuzzing_add.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | // cd /mnt/c/Users/ckorm/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer 9 | // clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I/mnt/c/boost/boost_1_85_0 test/fuzzing/test_fuzzing_add.cpp -o test_fuzzing_add 10 | // ./test_fuzzing_add -max_total_time=300 11 | 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace fuzzing 23 | { 24 | using boost_uint_backend_type = 25 | boost::multiprecision::cpp_int_backend(UINT32_C(256)), 26 | static_cast(UINT32_C(256)), 27 | boost::multiprecision::unsigned_magnitude>; 28 | 29 | using boost_uint_type = boost::multiprecision::number; 31 | 32 | using local_uint_type = ::math::wide_integer::uint256_t; 33 | 34 | auto eval_op(const std::uint8_t* data, std::size_t size) -> bool; 35 | } 36 | 37 | auto fuzzing::eval_op(const std::uint8_t* data, std::size_t size) -> bool 38 | { 39 | const std::size_t 40 | max_size 41 | { 42 | static_cast 43 | ( 44 | std::numeric_limits::digits / 8 45 | ) 46 | }; 47 | 48 | bool result_is_ok { true }; 49 | 50 | if((size > std::size_t { UINT8_C(1) }) && (size <= std::size_t { max_size * 2U })) 51 | { 52 | local_uint_type a_local { 0U }; 53 | local_uint_type b_local { 0U }; 54 | 55 | boost_uint_type a_boost { 0U }; 56 | boost_uint_type b_boost { 0U }; 57 | 58 | // Import data into the uintwide_t values. 59 | import_bits 60 | ( 61 | a_local, 62 | data, 63 | data + std::size_t { size / 2U }, 64 | 8U 65 | ); 66 | 67 | import_bits 68 | ( 69 | b_local, 70 | data + std::size_t { size / 2U }, 71 | data + size, 72 | 8U 73 | ); 74 | 75 | // Import data into the boost values. 76 | import_bits 77 | ( 78 | a_boost, 79 | data, 80 | data + std::size_t { size / 2U }, 81 | 8U 82 | ); 83 | 84 | import_bits 85 | ( 86 | b_boost, 87 | data + std::size_t { size / 2U }, 88 | data + size, 89 | 8U 90 | ); 91 | 92 | local_uint_type result_local { a_local + b_local }; 93 | boost_uint_type result_boost { a_boost + b_boost }; 94 | 95 | std::vector result_data_local(max_size, UINT8_C(0)); 96 | std::vector result_data_boost(result_data_local.size(), UINT8_C(0)); 97 | 98 | export_bits(result_local, result_data_local.data(), 8U); 99 | export_bits(result_boost, result_data_boost.data(), 8U); 100 | 101 | // Verify that both uintwide_t as well as boost obtain the same result. 102 | const bool result_op_is_ok = 103 | std::equal 104 | ( 105 | result_data_local.cbegin(), 106 | result_data_local.cend(), 107 | result_data_boost.cbegin(), 108 | result_data_boost.cend() 109 | ); 110 | 111 | result_is_ok = (result_op_is_ok && result_is_ok); 112 | } 113 | 114 | // Assert the correct result. 115 | assert(result_is_ok); 116 | 117 | return result_is_ok; 118 | } 119 | 120 | // The fuzzing entry point. 121 | extern "C" 122 | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 123 | { 124 | const bool result_one_add_is_ok { fuzzing::eval_op(data, size) }; 125 | 126 | return (result_one_add_is_ok ? 0 : -1); 127 | } 128 | -------------------------------------------------------------------------------- /test/fuzzing/test_fuzzing_div.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | // cd /mnt/c/Users/ckorm/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer 9 | // clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I/mnt/c/boost/boost_1_85_0 test/fuzzing/test_fuzzing_div.cpp -o test_fuzzing_div 10 | // ./test_fuzzing_div -max_total_time=300 11 | 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace fuzzing 23 | { 24 | using boost_uint_backend_type = 25 | boost::multiprecision::cpp_int_backend(UINT32_C(256)), 26 | static_cast(UINT32_C(256)), 27 | boost::multiprecision::unsigned_magnitude>; 28 | 29 | using boost_uint_type = boost::multiprecision::number; 31 | 32 | using local_uint_type = ::math::wide_integer::uint256_t; 33 | 34 | auto eval_op(const std::uint8_t* data, std::size_t size) -> bool; 35 | } 36 | 37 | auto fuzzing::eval_op(const std::uint8_t* data, std::size_t size) -> bool 38 | { 39 | const std::size_t 40 | max_size 41 | { 42 | static_cast 43 | ( 44 | std::numeric_limits::digits / 8 45 | ) 46 | }; 47 | 48 | bool result_is_ok { true }; 49 | 50 | if((size > std::size_t { UINT8_C(1) }) && (size <= std::size_t { max_size * 2U })) 51 | { 52 | local_uint_type a_local { 0U }; 53 | local_uint_type b_local { 0U }; 54 | 55 | boost_uint_type a_boost { 0U }; 56 | boost_uint_type b_boost { 0U }; 57 | 58 | // Import data into the uintwide_t values. 59 | import_bits 60 | ( 61 | a_local, 62 | data, 63 | data + std::size_t { size / 2U }, 64 | 8U 65 | ); 66 | 67 | import_bits 68 | ( 69 | b_local, 70 | data + std::size_t { size / 2U }, 71 | data + size, 72 | 8U 73 | ); 74 | 75 | // Import data into the boost values. 76 | import_bits 77 | ( 78 | a_boost, 79 | data, 80 | data + std::size_t { size / 2U }, 81 | 8U 82 | ); 83 | 84 | import_bits 85 | ( 86 | b_boost, 87 | data + std::size_t { size / 2U }, 88 | data + size, 89 | 8U 90 | ); 91 | 92 | if(a_local < b_local) 93 | { 94 | std::swap(a_local, b_local); 95 | std::swap(a_boost, b_boost); 96 | } 97 | 98 | if(b_local != 0U) 99 | { 100 | local_uint_type result_local { a_local / b_local }; 101 | boost_uint_type result_boost { a_boost / b_boost }; 102 | 103 | std::vector result_data_local(max_size, UINT8_C(0)); 104 | std::vector result_data_boost(result_data_local.size(), UINT8_C(0)); 105 | 106 | export_bits(result_local, result_data_local.data(), 8U); 107 | export_bits(result_boost, result_data_boost.data(), 8U); 108 | 109 | // Verify that both uintwide_t as well as boost obtain the same result. 110 | const bool result_op_is_ok = 111 | std::equal 112 | ( 113 | result_data_local.cbegin(), 114 | result_data_local.cend(), 115 | result_data_boost.cbegin(), 116 | result_data_boost.cend() 117 | ); 118 | 119 | result_is_ok = (result_op_is_ok && result_is_ok); 120 | } 121 | } 122 | 123 | // Assert the correct result. 124 | assert(result_is_ok); 125 | 126 | return result_is_ok; 127 | } 128 | 129 | // The fuzzing entry point. 130 | extern "C" 131 | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 132 | { 133 | const bool result_one_div_is_ok { fuzzing::eval_op(data, size) }; 134 | 135 | return (result_one_div_is_ok ? 0 : -1); 136 | } 137 | -------------------------------------------------------------------------------- /test/fuzzing/test_fuzzing_mul.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | // cd /mnt/c/Users/ckorm/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer 9 | // clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I/mnt/c/boost/boost_1_85_0 test/fuzzing/test_fuzzing_mul.cpp -o test_fuzzing_mul 10 | // ./test_fuzzing_mul -max_total_time=300 11 | 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace fuzzing 23 | { 24 | using boost_uint_backend_type = 25 | boost::multiprecision::cpp_int_backend(UINT32_C(256)), 26 | static_cast(UINT32_C(256)), 27 | boost::multiprecision::unsigned_magnitude>; 28 | 29 | using boost_uint_type = boost::multiprecision::number; 31 | 32 | using local_uint_type = ::math::wide_integer::uint256_t; 33 | 34 | auto eval_op(const std::uint8_t* data, std::size_t size) -> bool; 35 | } 36 | 37 | auto fuzzing::eval_op(const std::uint8_t* data, std::size_t size) -> bool 38 | { 39 | const std::size_t 40 | max_size 41 | { 42 | static_cast 43 | ( 44 | std::numeric_limits::digits / 8 45 | ) 46 | }; 47 | 48 | bool result_is_ok { true }; 49 | 50 | if((size > std::size_t { UINT8_C(1) }) && (size <= std::size_t { max_size * 2U })) 51 | { 52 | local_uint_type a_local { 0U }; 53 | local_uint_type b_local { 0U }; 54 | 55 | boost_uint_type a_boost { 0U }; 56 | boost_uint_type b_boost { 0U }; 57 | 58 | // Import data into the uintwide_t values. 59 | import_bits 60 | ( 61 | a_local, 62 | data, 63 | data + std::size_t { size / 2U }, 64 | 8U 65 | ); 66 | 67 | import_bits 68 | ( 69 | b_local, 70 | data + std::size_t { size / 2U }, 71 | data + size, 72 | 8U 73 | ); 74 | 75 | // Import data into the boost values. 76 | import_bits 77 | ( 78 | a_boost, 79 | data, 80 | data + std::size_t { size / 2U }, 81 | 8U 82 | ); 83 | 84 | import_bits 85 | ( 86 | b_boost, 87 | data + std::size_t { size / 2U }, 88 | data + size, 89 | 8U 90 | ); 91 | 92 | local_uint_type result_local { a_local * b_local }; 93 | boost_uint_type result_boost { a_boost * b_boost }; 94 | 95 | std::vector result_data_local(max_size, UINT8_C(0)); 96 | std::vector result_data_boost(result_data_local.size(), UINT8_C(0)); 97 | 98 | export_bits(result_local, result_data_local.data(), 8U); 99 | export_bits(result_boost, result_data_boost.data(), 8U); 100 | 101 | // Verify that both uintwide_t as well as boost obtain the same result. 102 | const bool result_op_is_ok = 103 | std::equal 104 | ( 105 | result_data_local.cbegin(), 106 | result_data_local.cend(), 107 | result_data_boost.cbegin(), 108 | result_data_boost.cend() 109 | ); 110 | 111 | result_is_ok = (result_op_is_ok && result_is_ok); 112 | } 113 | 114 | // Assert the correct result. 115 | assert(result_is_ok); 116 | 117 | return result_is_ok; 118 | } 119 | 120 | // The fuzzing entry point. 121 | extern "C" 122 | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 123 | { 124 | const bool result_one_mul_is_ok { fuzzing::eval_op(data, size) }; 125 | 126 | return (result_one_mul_is_ok ? 0 : -1); 127 | } 128 | -------------------------------------------------------------------------------- /test/fuzzing/test_fuzzing_powm.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | // cd /mnt/c/Users/ckorm/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer 9 | // clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I/mnt/c/boost/boost_1_85_0 test/fuzzing/test_fuzzing_powm.cpp -o test_fuzzing_powm 10 | // ./test_fuzzing_powm -max_total_time=300 11 | 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace fuzzing 23 | { 24 | using boost_uint_backend_type = 25 | boost::multiprecision::cpp_int_backend(UINT32_C(256)), 26 | static_cast(UINT32_C(256)), 27 | boost::multiprecision::unsigned_magnitude>; 28 | 29 | using boost_uint_type = boost::multiprecision::number; 31 | 32 | using local_uint_type = ::math::wide_integer::uint256_t; 33 | 34 | auto eval_op(const std::uint8_t* data, std::size_t size) -> bool; 35 | } 36 | 37 | auto fuzzing::eval_op(const std::uint8_t* data, std::size_t size) -> bool 38 | { 39 | const std::size_t 40 | max_size 41 | { 42 | static_cast 43 | ( 44 | std::numeric_limits::digits / 8 45 | ) 46 | }; 47 | 48 | bool result_is_ok { true }; 49 | 50 | if((size > std::size_t { UINT8_C(6) }) && (size <= std::size_t { max_size * 3U })) 51 | { 52 | local_uint_type b_local { 0U }; 53 | local_uint_type p_local { 0U }; 54 | local_uint_type m_local { 0U }; 55 | 56 | boost_uint_type b_boost { 0U }; 57 | boost_uint_type p_boost { 0U }; 58 | boost_uint_type m_boost { 0U }; 59 | 60 | // Import data into the uintwide_t values. 61 | import_bits 62 | ( 63 | b_local, 64 | data, 65 | data + std::size_t { size / 3U }, 66 | 8U 67 | ); 68 | 69 | import_bits 70 | ( 71 | p_local, 72 | data + std::size_t { size / 3U }, 73 | data + std::size_t { std::size_t { size * 2U } / 3U }, 74 | 8U 75 | ); 76 | 77 | import_bits 78 | ( 79 | m_local, 80 | data + std::size_t { std::size_t { size * 2U } / 3U }, 81 | data + size, 82 | 8U 83 | ); 84 | 85 | // Import data into the boost values. 86 | import_bits 87 | ( 88 | b_boost, 89 | data, 90 | data + std::size_t { size / 3U }, 91 | 8U 92 | ); 93 | 94 | import_bits 95 | ( 96 | p_boost, 97 | data + std::size_t { size / 3U }, 98 | data + std::size_t { std::size_t { size * 2U } / 3U }, 99 | 8U 100 | ); 101 | 102 | import_bits 103 | ( 104 | m_boost, 105 | data + std::size_t { std::size_t { size * 2U } / 3U }, 106 | data + size, 107 | 8U 108 | ); 109 | 110 | if(m_local != 0U) 111 | { 112 | local_uint_type result_local { powm(b_local, p_local, m_local) }; 113 | boost_uint_type result_boost { powm(b_boost, p_boost, m_boost) }; 114 | 115 | std::vector result_data_local(max_size, UINT8_C(0)); 116 | std::vector result_data_boost(result_data_local.size(), UINT8_C(0)); 117 | 118 | export_bits(result_local, result_data_local.data(), 8U); 119 | export_bits(result_boost, result_data_boost.data(), 8U); 120 | 121 | // Verify that both uintwide_t as well as boost obtain the same result. 122 | const bool result_op_is_ok = 123 | std::equal 124 | ( 125 | result_data_local.cbegin(), 126 | result_data_local.cend(), 127 | result_data_boost.cbegin(), 128 | result_data_boost.cend() 129 | ); 130 | 131 | result_is_ok = (result_op_is_ok && result_is_ok); 132 | } 133 | } 134 | 135 | // Assert the correct result. 136 | assert(result_is_ok); 137 | 138 | return result_is_ok; 139 | } 140 | 141 | // The fuzzing entry point. 142 | extern "C" 143 | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 144 | { 145 | const bool result_one_div_is_ok { fuzzing::eval_op(data, size) }; 146 | 147 | return (result_one_div_is_ok ? 0 : -1); 148 | } 149 | -------------------------------------------------------------------------------- /test/fuzzing/test_fuzzing_prime.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | // cd /mnt/c/Users/ckorm/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer 9 | // clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I/mnt/c/boost/boost_1_85_0 test/fuzzing/test_fuzzing_prime.cpp -o test_fuzzing_prime 10 | // ./test_fuzzing_prime -max_total_time=300 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace fuzzing 24 | { 25 | using boost_uint_backend_type = 26 | boost::multiprecision::cpp_int_backend(UINT32_C(256)), 27 | static_cast(UINT32_C(256)), 28 | boost::multiprecision::unsigned_magnitude>; 29 | 30 | using boost_uint_type = boost::multiprecision::number; 32 | 33 | using local_uint_type = ::math::wide_integer::uint256_t; 34 | 35 | auto eval_op(const std::uint8_t* data, std::size_t size) -> bool; 36 | } 37 | 38 | auto fuzzing::eval_op(const std::uint8_t* data, std::size_t size) -> bool 39 | { 40 | const std::size_t 41 | max_size 42 | { 43 | static_cast 44 | ( 45 | std::numeric_limits::digits / 8 46 | ) 47 | }; 48 | 49 | bool result_is_ok { true }; 50 | 51 | if((size > std::size_t { max_size / 2U }) && (size <= max_size)) 52 | { 53 | using random_engine_type = std::mt19937_64; 54 | 55 | using distribution_type = ::math::wide_integer::uniform_int_distribution; 56 | 57 | //random_engine1_type generator1(util::util_pseudorandom_time_point_seed::value()); 58 | random_engine_type 59 | generator 60 | { 61 | util::util_pseudorandom_time_point_seed::value() 62 | }; 63 | 64 | distribution_type distribution { }; 65 | 66 | local_uint_type p0 { 0U }; 67 | boost_uint_type pb { 0U }; 68 | 69 | // Import the data into the uintwide_t prime candidate. 70 | import_bits 71 | ( 72 | p0, 73 | data, 74 | data + size, 75 | 8U 76 | ); 77 | 78 | // Import the data into the boost prime candidate. 79 | import_bits 80 | ( 81 | pb, 82 | data, 83 | data + size, 84 | 8U 85 | ); 86 | 87 | // Ensure that both uintwide_t as well as boost obtain 88 | // the same prime (or non-prime) result. 89 | 90 | const bool miller_rabin_result_local { miller_rabin(p0, 25U, distribution, generator) }; 91 | const bool miller_rabin_result_boost { boost::multiprecision::miller_rabin_test(pb, 25U, generator) }; 92 | 93 | const bool 94 | result_op_is_ok 95 | { 96 | miller_rabin_result_local == miller_rabin_result_boost 97 | }; 98 | 99 | result_is_ok = (result_op_is_ok && result_is_ok); 100 | } 101 | 102 | // Assert the correct result. 103 | assert(result_is_ok); 104 | 105 | return result_is_ok; 106 | } 107 | 108 | // The fuzzing entry point. 109 | extern "C" 110 | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 111 | { 112 | const bool result_one_prime_is_ok { fuzzing::eval_op(data, size) }; 113 | 114 | return (result_one_prime_is_ok ? 0 : -1); 115 | } 116 | -------------------------------------------------------------------------------- /test/fuzzing/test_fuzzing_sdiv.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | // cd /mnt/c/Users/ckorm/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer 9 | // clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I/mnt/c/boost/boost_1_85_0 test/fuzzing/test_fuzzing_sdiv.cpp -o test_fuzzing_sdiv 10 | // ./test_fuzzing_sdiv -max_total_time=300 11 | 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | namespace fuzzing 25 | { 26 | auto pseudo_random_sign_bit() -> int 27 | { 28 | static unsigned seed_prescaler { }; 29 | 30 | static std::mt19937 engine { }; 31 | 32 | if((seed_prescaler++ % 0x10000U) == 0U) 33 | { 34 | std::random_device rd { }; 35 | 36 | engine.seed(rd()); 37 | } 38 | 39 | // Create a uniform distribution for the bit position (0 to 1). 40 | static std::uniform_int_distribution bit_dist(0, 1); 41 | 42 | // Generate a pseudo-random sign bit. 43 | return bit_dist(engine); 44 | } 45 | 46 | using boost_uint_backend_type = 47 | boost::multiprecision::cpp_int_backend(UINT32_C(256)), 48 | static_cast(UINT32_C(256)), 49 | boost::multiprecision::unsigned_magnitude>; 50 | 51 | using boost_uint_type = boost::multiprecision::number; 53 | 54 | using local_uint_type = ::math::wide_integer::uint256_t; 55 | 56 | using boost_sint_backend_type = 57 | boost::multiprecision::cpp_int_backend(UINT32_C(256)), 58 | static_cast(UINT32_C(256)), 59 | boost::multiprecision::signed_magnitude>; 60 | 61 | using boost_sint_type = boost::multiprecision::number; 63 | 64 | using local_sint_type = ::math::wide_integer::int256_t; 65 | 66 | auto eval_op(const std::uint8_t* data, std::size_t size) -> bool; 67 | } 68 | 69 | auto fuzzing::eval_op(const std::uint8_t* data, std::size_t size) -> bool 70 | { 71 | const std::size_t 72 | max_size 73 | { 74 | static_cast 75 | ( 76 | std::numeric_limits::digits / 8 77 | ) 78 | }; 79 | 80 | bool result_is_ok { true }; 81 | 82 | if((size > std::size_t { UINT8_C(1) }) && (size <= std::size_t { max_size * 2U })) 83 | { 84 | local_uint_type a_local { 0U }; 85 | local_uint_type b_local { 0U }; 86 | 87 | // Import data into the uintwide_t values. 88 | import_bits 89 | ( 90 | a_local, 91 | data, 92 | data + std::size_t { size / 2U }, 93 | 8U 94 | ); 95 | 96 | import_bits 97 | ( 98 | b_local, 99 | data + std::size_t { size / 2U }, 100 | data + size, 101 | 8U 102 | ); 103 | 104 | if(a_local + 256U < b_local) 105 | { 106 | std::swap(a_local, b_local); 107 | } 108 | 109 | if(b_local != 0U) 110 | { 111 | local_sint_type a_signed_local { a_local }; 112 | local_sint_type b_signed_local { b_local }; 113 | 114 | const int 115 | sign_mixer 116 | { 117 | (pseudo_random_sign_bit() << 1U) | pseudo_random_sign_bit() 118 | }; 119 | 120 | if (sign_mixer == 0) { } 121 | else if(sign_mixer == 1) { a_signed_local = -a_signed_local; } 122 | else if(sign_mixer == 2) { b_signed_local = -b_signed_local; } 123 | else { a_signed_local = -a_signed_local; b_signed_local = -b_signed_local; } 124 | 125 | std::stringstream strm_a_local { }; 126 | std::stringstream strm_b_local { }; 127 | 128 | strm_a_local << a_signed_local; 129 | strm_b_local << b_signed_local; 130 | 131 | boost_sint_type a_signed_boost { strm_a_local.str() }; 132 | boost_sint_type b_signed_boost { strm_b_local.str() }; 133 | 134 | local_sint_type result_signed_local { a_signed_local / b_signed_local }; 135 | boost_sint_type result_signed_boost { a_signed_boost / b_signed_boost }; 136 | 137 | std::vector result_signed_data_local(max_size, UINT8_C(0)); 138 | std::vector result_signed_data_boost(result_signed_data_local.size(), UINT8_C(0)); 139 | 140 | export_bits(result_signed_local, result_signed_data_local.data(), 8U); 141 | export_bits(result_signed_boost, result_signed_data_boost.data(), 8U); 142 | 143 | // Verify that both uintwide_t as well as boost obtain the same result. 144 | const bool result_op_is_ok = 145 | std::equal 146 | ( 147 | result_signed_data_local.cbegin(), 148 | result_signed_data_local.cend(), 149 | result_signed_data_boost.cbegin(), 150 | result_signed_data_boost.cend() 151 | ); 152 | 153 | result_is_ok = (result_op_is_ok && result_is_ok); 154 | } 155 | } 156 | 157 | // Assert the correct result. 158 | assert(result_is_ok); 159 | 160 | return result_is_ok; 161 | } 162 | 163 | // The fuzzing entry point. 164 | extern "C" 165 | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 166 | { 167 | const bool result_one_div_is_ok { fuzzing::eval_op(data, size) }; 168 | 169 | return (result_one_div_is_ok ? 0 : -1); 170 | } 171 | -------------------------------------------------------------------------------- /test/fuzzing/test_fuzzing_sqrt.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | // cd /mnt/c/Users/ckorm/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer 9 | // clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I/mnt/c/boost/boost_1_85_0 test/fuzzing/test_fuzzing_sqrt.cpp -o test_fuzzing_sqrt 10 | // ./test_fuzzing_sqrt -max_total_time=300 11 | 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | namespace fuzzing 25 | { 26 | using boost_uint_backend_type = 27 | boost::multiprecision::cpp_int_backend(UINT32_C(256)), 28 | static_cast(UINT32_C(256)), 29 | boost::multiprecision::unsigned_magnitude>; 30 | 31 | using boost_uint_type = boost::multiprecision::number; 33 | 34 | using local_uint_type = ::math::wide_integer::uint256_t; 35 | 36 | auto eval_op(const std::uint8_t* data, std::size_t size) -> bool; 37 | } 38 | 39 | auto fuzzing::eval_op(const std::uint8_t* data, std::size_t size) -> bool 40 | { 41 | const std::size_t 42 | max_size 43 | { 44 | static_cast 45 | ( 46 | std::numeric_limits::digits / 8 47 | ) 48 | }; 49 | 50 | bool result_is_ok { true }; 51 | 52 | if(size <= max_size) 53 | { 54 | local_uint_type a_local { 0U }; 55 | 56 | // Import data into the uintwide_t values. 57 | import_bits 58 | ( 59 | a_local, 60 | data, 61 | data + size, 62 | 8U 63 | ); 64 | 65 | std::stringstream strm_a_local { }; 66 | 67 | strm_a_local << a_local; 68 | 69 | boost_uint_type a_boost { strm_a_local.str() }; 70 | 71 | local_uint_type result_local { sqrt(a_local) }; 72 | boost_uint_type result_boost { sqrt(a_boost) }; 73 | 74 | std::vector result_data_local(max_size, UINT8_C(0)); 75 | std::vector result_data_boost(max_size, UINT8_C(0)); 76 | 77 | export_bits(result_local, result_data_local.data(), 8U); 78 | export_bits(result_boost, result_data_boost.data(), 8U); 79 | 80 | // Verify that both uintwide_t as well as boost obtain the same result. 81 | const bool result_op_is_ok = 82 | std::equal 83 | ( 84 | result_data_local.cbegin(), 85 | result_data_local.cend(), 86 | result_data_boost.cbegin(), 87 | result_data_boost.cend() 88 | ); 89 | 90 | result_is_ok = (result_op_is_ok && result_is_ok); 91 | } 92 | 93 | // Assert the correct result. 94 | assert(result_is_ok); 95 | 96 | return result_is_ok; 97 | } 98 | 99 | // The fuzzing entry point. 100 | extern "C" 101 | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 102 | { 103 | const bool result_one_div_is_ok { fuzzing::eval_op(data, size) }; 104 | 105 | return (result_one_div_is_ok ? 0 : -1); 106 | } 107 | -------------------------------------------------------------------------------- /test/fuzzing/test_fuzzing_sub.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | // cd /mnt/c/Users/ckorm/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer 9 | // clang++ -std=c++20 -g -O2 -Wall -Wextra -fsanitize=fuzzer -I. -I/mnt/c/boost/boost_1_85_0 test/fuzzing/test_fuzzing_sub.cpp -o test_fuzzing_sub 10 | // ./test_fuzzing_sub -max_total_time=300 11 | 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace fuzzing 23 | { 24 | using boost_uint_backend_type = 25 | boost::multiprecision::cpp_int_backend(UINT32_C(256)), 26 | static_cast(UINT32_C(256)), 27 | boost::multiprecision::unsigned_magnitude>; 28 | 29 | using boost_uint_type = boost::multiprecision::number; 31 | 32 | using local_uint_type = ::math::wide_integer::uint256_t; 33 | 34 | auto eval_op(const std::uint8_t* data, std::size_t size) -> bool; 35 | } 36 | 37 | auto fuzzing::eval_op(const std::uint8_t* data, std::size_t size) -> bool 38 | { 39 | const std::size_t 40 | max_size 41 | { 42 | static_cast 43 | ( 44 | std::numeric_limits::digits / 8 45 | ) 46 | }; 47 | 48 | bool result_is_ok { true }; 49 | 50 | if((size > std::size_t { UINT8_C(1) }) && (size <= std::size_t { max_size * 2U })) 51 | { 52 | local_uint_type a_local { 0U }; 53 | local_uint_type b_local { 0U }; 54 | 55 | boost_uint_type a_boost { 0U }; 56 | boost_uint_type b_boost { 0U }; 57 | 58 | // Import data into the uintwide_t values. 59 | import_bits 60 | ( 61 | a_local, 62 | data, 63 | data + std::size_t { size / 2U }, 64 | 8U 65 | ); 66 | 67 | import_bits 68 | ( 69 | b_local, 70 | data + std::size_t { size / 2U }, 71 | data + size, 72 | 8U 73 | ); 74 | 75 | // Import data into the boost values. 76 | import_bits 77 | ( 78 | a_boost, 79 | data, 80 | data + std::size_t { size / 2U }, 81 | 8U 82 | ); 83 | 84 | import_bits 85 | ( 86 | b_boost, 87 | data + std::size_t { size / 2U }, 88 | data + size, 89 | 8U 90 | ); 91 | 92 | local_uint_type result_local { a_local - b_local }; 93 | boost_uint_type result_boost { a_boost - b_boost }; 94 | 95 | std::vector result_data_local(max_size, UINT8_C(0)); 96 | std::vector result_data_boost(result_data_local.size(), UINT8_C(0)); 97 | 98 | export_bits(result_local, result_data_local.data(), 8U); 99 | export_bits(result_boost, result_data_boost.data(), 8U); 100 | 101 | // Verify that both uintwide_t as well as boost obtain the same result. 102 | const bool result_op_is_ok = 103 | std::equal 104 | ( 105 | result_data_local.cbegin(), 106 | result_data_local.cend(), 107 | result_data_boost.cbegin(), 108 | result_data_boost.cend() 109 | ); 110 | 111 | result_is_ok = (result_op_is_ok && result_is_ok); 112 | } 113 | 114 | // Assert the correct result. 115 | assert(result_is_ok); 116 | 117 | return result_is_ok; 118 | } 119 | 120 | // The fuzzing entry point. 121 | extern "C" 122 | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 123 | { 124 | const bool result_one_sub_is_ok { fuzzing::eval_op(data, size) }; 125 | 126 | return (result_one_sub_is_ok ? 0 : -1); 127 | } 128 | -------------------------------------------------------------------------------- /test/parallel_for.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2017 - 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #ifndef PARALLEL_FOR_2017_12_18_H // NOLINT(llvm-header-guard) 9 | #define PARALLEL_FOR_2017_12_18_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace my_concurrency 16 | { 17 | template 19 | auto parallel_for(index_type start, 20 | index_type end, 21 | callable_function_type parallel_function) -> void 22 | { 23 | // Estimate the number of threads available. 24 | const auto number_of_threads_hint = 25 | static_cast 26 | ( 27 | std::thread::hardware_concurrency() 28 | ); 29 | 30 | const auto number_of_threads = // NOLINT(altera-id-dependent-backward-branch) 31 | static_cast 32 | ( 33 | (number_of_threads_hint == static_cast(UINT8_C(0))) ? static_cast(UINT8_C(4)) : number_of_threads_hint // NOLINT(altera-id-dependent-backward-branch) 34 | ); 35 | 36 | // Set the size of a slice for the range functions. 37 | const auto n = 38 | static_cast 39 | ( 40 | static_cast(end - start) + static_cast(1) 41 | ); 42 | 43 | const auto slice = 44 | (std::max) 45 | ( 46 | static_cast(std::round(static_cast(n) / static_cast(number_of_threads))), 47 | static_cast(1) 48 | ); 49 | 50 | // Inner loop. 51 | const auto launch_range = 52 | [¶llel_function](index_type index_lo, index_type index_hi) 53 | { 54 | for(auto i = index_lo; i < index_hi; ++i) // NOLINT(altera-id-dependent-backward-branch) 55 | { 56 | parallel_function(i); 57 | } 58 | }; 59 | 60 | // Create the thread pool and launch the jobs. 61 | std::vector pool { }; 62 | 63 | pool.reserve(number_of_threads); 64 | 65 | auto i1 = start; 66 | auto i2 = (std::min)(static_cast(start + slice), end); 67 | 68 | for(auto i = static_cast(0U); ((static_cast(i + 1) < static_cast(number_of_threads)) && (i1 < end)); ++i) // NOLINT(altera-id-dependent-backward-branch) 69 | { 70 | pool.emplace_back(launch_range, i1, i2); 71 | 72 | i1 = i2; 73 | 74 | i2 = (std::min)(static_cast(i2 + slice), end); 75 | } 76 | 77 | if(i1 < end) 78 | { 79 | pool.emplace_back(launch_range, i1, end); 80 | } 81 | 82 | // Wait for the jobs to finish. 83 | for(auto& thread_in_pool : pool) 84 | { 85 | if(thread_in_pool.joinable()) 86 | { 87 | thread_in_pool.join(); 88 | } 89 | } 90 | } 91 | 92 | // Provide a serial version for easy comparison. 93 | template 95 | auto sequential_for(index_type start, 96 | index_type end, 97 | callable_function_type sequential_function) -> void 98 | { 99 | for(index_type i = start; i < end; ++i) 100 | { 101 | sequential_function(i); 102 | } 103 | } 104 | } // namespace my_concurrency 105 | 106 | #endif // PARALLEL_FOR_2017_12_18_H 107 | -------------------------------------------------------------------------------- /test/stopwatch.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2013 - 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #ifndef STOPWATCH_2024_03_28_H // NOLINT(llvm-header-guard) 9 | #define STOPWATCH_2024_03_28_H 10 | 11 | #include 12 | #include 13 | 14 | #if defined(_MSC_VER) && !defined(__GNUC__) 15 | #define STOPWATCH_NODISCARD 16 | #else 17 | #if (defined(__cplusplus) && (__cplusplus >= 201703L)) 18 | #define STOPWATCH_NODISCARD [[nodiscard]] // NOLINT(cppcoreguidelines-macro-usage) 19 | #else 20 | #define STOPWATCH_NODISCARD 21 | #endif 22 | #endif 23 | 24 | // See also: https://godbolt.org/z/37a4n9f4Y 25 | 26 | namespace concurrency { 27 | 28 | struct stopwatch 29 | { 30 | public: 31 | using time_point_type = std::uintmax_t; 32 | 33 | auto reset() -> void 34 | { 35 | m_start = now(); 36 | } 37 | 38 | template 39 | static auto elapsed_time(const stopwatch& my_stopwatch) noexcept -> RepresentationRequestedTimeType 40 | { 41 | using local_time_type = RepresentationRequestedTimeType; 42 | 43 | return 44 | local_time_type 45 | { 46 | static_cast(my_stopwatch.elapsed()) 47 | / local_time_type { UINTMAX_C(1000000000) } 48 | }; 49 | } 50 | 51 | private: 52 | time_point_type m_start { now() }; // NOLINT(readability-identifier-naming) 53 | 54 | STOPWATCH_NODISCARD static auto now() -> time_point_type 55 | { 56 | #if defined(__CYGWIN__) 57 | 58 | return static_cast(std::clock()); 59 | 60 | #else 61 | 62 | timespec ts { }; 63 | 64 | const int ntsp { timespec_get(&ts, TIME_UTC) }; 65 | 66 | static_cast(ntsp); 67 | 68 | return 69 | static_cast 70 | ( 71 | static_cast(static_cast(ts.tv_sec) * UINTMAX_C(1000000000)) 72 | + static_cast(ts.tv_nsec) 73 | ); 74 | 75 | #endif 76 | } 77 | 78 | STOPWATCH_NODISCARD auto elapsed() const -> time_point_type 79 | { 80 | const time_point_type stop { now() }; 81 | 82 | #if defined(__CYGWIN__) 83 | 84 | const time_point_type 85 | elapsed_ns 86 | { 87 | static_cast 88 | ( 89 | static_cast(static_cast(stop - m_start) * UINTMAX_C(1000000000)) 90 | / static_cast(CLOCKS_PER_SEC) 91 | ) 92 | }; 93 | 94 | #else 95 | 96 | const time_point_type 97 | elapsed_ns 98 | { 99 | static_cast 100 | ( 101 | stop - m_start 102 | ) 103 | }; 104 | 105 | #endif 106 | 107 | return elapsed_ns; 108 | } 109 | }; 110 | 111 | } // namespace concurrency 112 | 113 | #endif // STOPWATCH_2024_03_28_H 114 | -------------------------------------------------------------------------------- /test/test_uintwide_t.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2019 - 2024. // 3 | // Distributed under the Boost Software License, // 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt // 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) // 6 | /////////////////////////////////////////////////////////////////// 7 | 8 | #ifndef TEST_UINTWIDE_T_2019_12_15_H // NOLINT(llvm-header-guard) 9 | #define TEST_UINTWIDE_T_2019_12_15_H 10 | 11 | #include 12 | 13 | WIDE_INTEGER_NAMESPACE_BEGIN 14 | 15 | #if(__cplusplus >= 201703L) 16 | namespace math::wide_integer { 17 | #else 18 | namespace math { namespace wide_integer { // NOLINT(modernize-concat-nested-namespaces) 19 | #endif 20 | 21 | auto test_uintwide_t_boost_backend() -> bool; 22 | auto test_uintwide_t_examples () -> bool; 23 | auto test_uintwide_t_edge_cases () -> bool; 24 | auto test_uintwide_t_float_convert() -> bool; 25 | auto test_uintwide_t_int_convert () -> bool; 26 | auto test_uintwide_t_spot_values () -> bool; 27 | 28 | #if(__cplusplus >= 201703L) 29 | } // namespace math::wide_integer 30 | #else 31 | } // namespace wide_integer 32 | } // namespace math 33 | #endif 34 | 35 | WIDE_INTEGER_NAMESPACE_END 36 | 37 | #endif // TEST_UINTWIDE_T_2019_12_15_H 38 | -------------------------------------------------------------------------------- /test/test_uintwide_t_boost_backend.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2019 - 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #include 9 | 10 | #if !defined(BOOST_VERSION) 11 | #error BOOST_VERSION is not defined. Ensure that is properly included. 12 | #endif 13 | 14 | #if ((BOOST_VERSION >= 107900) && !defined(BOOST_MP_STANDALONE)) 15 | #define BOOST_MP_STANDALONE 16 | #endif 17 | 18 | #if ((BOOST_VERSION >= 108000) && !defined(BOOST_NO_EXCEPTIONS)) 19 | #define BOOST_NO_EXCEPTIONS 20 | #endif 21 | 22 | #if (((BOOST_VERSION == 108000) || (BOOST_VERSION == 108100)) && defined(BOOST_NO_EXCEPTIONS)) 23 | #if defined(__clang__) 24 | #pragma GCC diagnostic push 25 | #pragma GCC diagnostic ignored "-Wsometimes-uninitialized" 26 | #endif 27 | #if defined(_MSC_VER) 28 | #pragma warning(push) 29 | #pragma warning(disable : 4701) 30 | #endif 31 | #endif 32 | 33 | #if (BOOST_VERSION < 108000) 34 | #if defined(__GNUC__) 35 | #pragma GCC diagnostic push 36 | #pragma GCC diagnostic ignored "-Wconversion" 37 | #pragma GCC diagnostic push 38 | #pragma GCC diagnostic ignored "-Wsign-conversion" 39 | #pragma GCC diagnostic push 40 | #pragma GCC diagnostic ignored "-Wunused-parameter" 41 | #endif 42 | #endif 43 | 44 | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)) 45 | #pragma GCC diagnostic push 46 | #pragma GCC diagnostic ignored "-Wrestrict" 47 | #endif 48 | 49 | #if (BOOST_VERSION < 108000) 50 | #if ((defined(__clang__) && (__clang_major__ > 9)) && !defined(__APPLE__)) 51 | #pragma GCC diagnostic push 52 | #pragma GCC diagnostic ignored "-Wdeprecated-copy" 53 | #endif 54 | #endif 55 | 56 | #include 57 | #include 58 | 59 | #include 60 | 61 | using local_uint_type = 62 | #if defined(WIDE_INTEGER_NAMESPACE) 63 | boost::multiprecision::number(UINT32_C(1024))>, 64 | boost::multiprecision::et_off>; 65 | #else 66 | boost::multiprecision::number(UINT32_C(1024))>, 67 | boost::multiprecision::et_off>; 68 | #endif 69 | 70 | using boost_uint_backend_type = 71 | boost::multiprecision::cpp_int_backend(UINT32_C(1024)), 72 | static_cast(UINT32_C(1024)), 73 | boost::multiprecision::unsigned_magnitude>; 74 | 75 | using boost_uint_type = boost::multiprecision::number; 77 | 78 | #if defined(WIDE_INTEGER_NAMESPACE) 79 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::test_uintwide_t_boost_backend() -> bool 80 | #else 81 | auto ::math::wide_integer::test_uintwide_t_boost_backend() -> bool 82 | #endif 83 | { 84 | bool result_is_ok = true; 85 | 86 | // Test a non-trivial calculation. A naive algorithm for calculating 87 | // a factorial (in this case 100!) has been selected. 88 | { 89 | local_uint_type u = 1U; 90 | 91 | for(auto i = static_cast(UINT32_C(2)); i <= static_cast(UINT32_C(100)); ++i) 92 | { 93 | u *= i; 94 | } 95 | 96 | const local_uint_type local_control("93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000"); 97 | const boost_uint_type boost_control("93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000"); 98 | 99 | const bool local_control_is_ok = (u == local_control); 100 | 101 | { 102 | std::stringstream strm_lhs; 103 | strm_lhs << u; 104 | 105 | std::stringstream strm_rhs; 106 | strm_rhs << boost_control; 107 | 108 | const bool boost_control_is_ok = (strm_lhs.str() == strm_rhs.str()); 109 | 110 | result_is_ok = ((local_control_is_ok && boost_control_is_ok) && result_is_ok); 111 | } 112 | 113 | // Test divide-by-limb. 114 | u /= static_cast(UINT8_C(10)); 115 | 116 | result_is_ok = ((u == local_uint_type("9332621544394415268169923885626670049071596826438162146859296389521759999322991560894146397615651828625369792082722375825118521091686400000000000000000000000")) && result_is_ok); 117 | 118 | // Test full multiplication. 119 | u *= u; 120 | 121 | result_is_ok = ((u == local_uint_type("87097824890894800794165901619444858655697206439408401342159325362433799963465833258779670963327549206446903807622196074763642894114359201905739606775078813946074899053317297580134329929871847646073758894343134833829668015151562808541626917661957374931734536035195944960000000000000000000000000000000000000000000000")) && result_is_ok); 122 | } 123 | 124 | // Test a very simple constexpr example. 125 | { 126 | constexpr local_uint_type cu { "123" }; 127 | 128 | constexpr bool result_cu_is_ok = (cu == 123U); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 129 | 130 | result_is_ok = (result_cu_is_ok && result_is_ok); 131 | 132 | static_assert(result_cu_is_ok, "Error: test_uintwide_t_boost_backend not OK!"); 133 | } 134 | 135 | return result_is_ok; 136 | } 137 | 138 | #if (BOOST_VERSION < 108000) 139 | #if ((defined(__clang__) && (__clang_major__ > 9)) && !defined(__APPLE__)) 140 | #pragma GCC diagnostic pop 141 | #endif 142 | #endif 143 | 144 | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)) 145 | #pragma GCC diagnostic pop 146 | #endif 147 | 148 | #if (BOOST_VERSION < 108000) 149 | #if defined(__GNUC__) 150 | #pragma GCC diagnostic pop 151 | #pragma GCC diagnostic pop 152 | #pragma GCC diagnostic pop 153 | #endif 154 | #endif 155 | 156 | #if (((BOOST_VERSION == 108000) || (BOOST_VERSION == 108100)) && defined(BOOST_NO_EXCEPTIONS)) 157 | #if defined(__clang__) 158 | #pragma GCC diagnostic pop 159 | #endif 160 | #if defined(_MSC_VER) 161 | #pragma warning(pop) 162 | #endif 163 | #endif 164 | -------------------------------------------------------------------------------- /test/test_uintwide_t_boost_backend_via_test_arithmetic.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////// 2 | // Copyright 2022 Christopher Kormanyos. 3 | // Distributed under the Boost 4 | // Software License, Version 1.0. (See accompanying file 5 | // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt 6 | 7 | #include 8 | 9 | #if !defined(BOOST_VERSION) 10 | #error BOOST_VERSION is not defined. Ensure that is properly included. 11 | #endif 12 | 13 | #if ((BOOST_VERSION >= 107900) && !defined(BOOST_MP_STANDALONE)) 14 | #define BOOST_MP_STANDALONE 15 | #endif 16 | 17 | #if ((BOOST_VERSION >= 108000) && !defined(BOOST_NO_EXCEPTIONS)) 18 | #define BOOST_NO_EXCEPTIONS 19 | #endif 20 | 21 | #if (BOOST_VERSION < 108000) 22 | #if defined(__GNUC__) 23 | #pragma GCC diagnostic push 24 | #pragma GCC diagnostic ignored "-Wconversion" 25 | #pragma GCC diagnostic push 26 | #pragma GCC diagnostic ignored "-Wsign-conversion" 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wunused-parameter" 29 | #endif 30 | #endif 31 | 32 | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)) 33 | #pragma GCC diagnostic push 34 | #pragma GCC diagnostic ignored "-Wrestrict" 35 | #endif 36 | 37 | #if (BOOST_VERSION < 108000) 38 | #if ((defined(__clang__) && (__clang_major__ > 9)) && !defined(__APPLE__)) 39 | #pragma GCC diagnostic push 40 | #pragma GCC diagnostic ignored "-Wdeprecated-copy" 41 | #endif 42 | #endif 43 | 44 | #if defined(__GNUC__) 45 | #pragma GCC diagnostic push 46 | #pragma GCC diagnostic ignored "-Wshadow" 47 | #endif 48 | 49 | #include 50 | #include 51 | 52 | #include "test_arithmetic.hpp" 53 | 54 | #include 55 | 56 | 57 | // cd /mnt/c/Users/User/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer 58 | // g++-10 -finline-functions -march=native -mtune=native -O3 -Wall -std=gnu++20 -DWIDE_INTEGER_HAS_LIMB_TYPE_UINT64 -I. -I/mnt/c/boost/boost_1_78_0 test/test_uintwide_t_boost_backend_via_test_arithmetic.cpp -o test_uintwide_t_boost_backend_via_test_arithmetic.exe 59 | 60 | auto main() -> int 61 | { 62 | using local_big_uint_backend_type = 63 | boost::multiprecision::uintwide_t_backend(UINT32_C(1024)), std::uint8_t, std::allocator>; 64 | 65 | using local_big_uint_type = 66 | boost::multiprecision::number; 68 | 69 | test(); 70 | 71 | const int n_errors = boost::report_errors(); 72 | 73 | return ((n_errors == 0) ? 0 : -1); 74 | } 75 | 76 | #if defined(__GNUC__) 77 | #pragma GCC diagnostic pop 78 | #endif 79 | 80 | #if (BOOST_VERSION < 108000) 81 | #if ((defined(__clang__) && (__clang_major__ > 9)) && !defined(__APPLE__)) 82 | #pragma GCC diagnostic pop 83 | #endif 84 | #endif 85 | 86 | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)) 87 | #pragma GCC diagnostic pop 88 | #endif 89 | 90 | #if (BOOST_VERSION < 108000) 91 | #if defined(__GNUC__) 92 | #pragma GCC diagnostic pop 93 | #pragma GCC diagnostic pop 94 | #pragma GCC diagnostic pop 95 | #endif 96 | #endif 97 | -------------------------------------------------------------------------------- /test/test_uintwide_t_examples.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2019 - 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #if defined(WIDE_INTEGER_NAMESPACE) 15 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::test_uintwide_t_examples() -> bool 16 | #else 17 | auto ::math::wide_integer::test_uintwide_t_examples() -> bool 18 | #endif 19 | { 20 | bool result_is_ok = true; 21 | 22 | result_is_ok = (math::wide_integer::example000_numeric_limits () && result_is_ok); std::cout << "result_is_ok after example000_numeric_limits : " << std::boolalpha << result_is_ok << std::endl; 23 | result_is_ok = (math::wide_integer::example000a_builtin_convert () && result_is_ok); std::cout << "result_is_ok after example000a_builtin_convert : " << std::boolalpha << result_is_ok << std::endl; 24 | result_is_ok = (math::wide_integer::example001_mul_div () && result_is_ok); std::cout << "result_is_ok after example001_mul_div : " << std::boolalpha << result_is_ok << std::endl; 25 | result_is_ok = (math::wide_integer::example001a_div_mod () && result_is_ok); std::cout << "result_is_ok after example001a_div_mod : " << std::boolalpha << result_is_ok << std::endl; 26 | result_is_ok = (math::wide_integer::example002_shl_shr () && result_is_ok); std::cout << "result_is_ok after example002_shl_shr : " << std::boolalpha << result_is_ok << std::endl; 27 | result_is_ok = (math::wide_integer::example003_sqrt () && result_is_ok); std::cout << "result_is_ok after example003_sqrt : " << std::boolalpha << result_is_ok << std::endl; 28 | result_is_ok = (math::wide_integer::example003a_cbrt () && result_is_ok); std::cout << "result_is_ok after example003a_cbrt : " << std::boolalpha << result_is_ok << std::endl; 29 | result_is_ok = (math::wide_integer::example004_rootk_pow () && result_is_ok); std::cout << "result_is_ok after example004_rootk_pow : " << std::boolalpha << result_is_ok << std::endl; 30 | result_is_ok = (math::wide_integer::example005_powm () && result_is_ok); std::cout << "result_is_ok after example005_powm : " << std::boolalpha << result_is_ok << std::endl; 31 | result_is_ok = (math::wide_integer::example005a_pow_factors_of_p99() && result_is_ok); std::cout << "result_is_ok after example005a_pow_factors_of_p99: " << std::boolalpha << result_is_ok << std::endl; 32 | result_is_ok = (math::wide_integer::example006_gcd () && result_is_ok); std::cout << "result_is_ok after example006_gcd : " << std::boolalpha << result_is_ok << std::endl; 33 | result_is_ok = (math::wide_integer::example007_random_generator () && result_is_ok); std::cout << "result_is_ok after example007_random_generator : " << std::boolalpha << result_is_ok << std::endl; 34 | result_is_ok = (math::wide_integer::example008_miller_rabin_prime () && result_is_ok); std::cout << "result_is_ok after example008_miller_rabin_prime : " << std::boolalpha << result_is_ok << std::endl; 35 | result_is_ok = (math::wide_integer::example008a_miller_rabin_prime() && result_is_ok); std::cout << "result_is_ok after example008a_miller_rabin_prime: " << std::boolalpha << result_is_ok << std::endl; 36 | result_is_ok = (math::wide_integer::example009_timed_mul () && result_is_ok); std::cout << "result_is_ok after example009_timed_mul : " << std::boolalpha << result_is_ok << std::endl; 37 | result_is_ok = (math::wide_integer::example009a_timed_mul_4_by_4 () && result_is_ok); std::cout << "result_is_ok after example009a_timed_mul_4_by_4 : " << std::boolalpha << result_is_ok << std::endl; 38 | result_is_ok = (math::wide_integer::example009b_timed_mul_8_by_8 () && result_is_ok); std::cout << "result_is_ok after example009b_timed_mul_8_by_8 : " << std::boolalpha << result_is_ok << std::endl; 39 | result_is_ok = (math::wide_integer::example010_uint48_t () && result_is_ok); std::cout << "result_is_ok after example010_uint48_t : " << std::boolalpha << result_is_ok << std::endl; 40 | result_is_ok = (math::wide_integer::example011_uint24_t () && result_is_ok); std::cout << "result_is_ok after example011_uint24_t : " << std::boolalpha << result_is_ok << std::endl; 41 | #if !(defined(_MSC_VER) && defined(_DEBUG)) 42 | result_is_ok = (math::wide_integer::example012_rsa_crypto () && result_is_ok); std::cout << "result_is_ok after example012_rsa_crypto : " << std::boolalpha << result_is_ok << std::endl; 43 | #endif 44 | result_is_ok = (math::wide_integer::example013_ecdsa_sign_verify () && result_is_ok); std::cout << "result_is_ok after example013_ecdsa_sign_verify : " << std::boolalpha << result_is_ok << std::endl; 45 | result_is_ok = (math::wide_integer::example014_pi_spigot_wide () && result_is_ok); std::cout << "result_is_ok after example014_pi_spigot_wide : " << std::boolalpha << result_is_ok << std::endl; 46 | 47 | return result_is_ok; 48 | } 49 | -------------------------------------------------------------------------------- /test/test_uintwide_t_int_convert.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2021 - 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | #if !defined(BOOST_VERSION) 15 | #error BOOST_VERSION is not defined. Ensure that is properly included. 16 | #endif 17 | 18 | #if ((BOOST_VERSION >= 107900) && !defined(BOOST_MP_STANDALONE)) 19 | #define BOOST_MP_STANDALONE 20 | #endif 21 | 22 | #if ((BOOST_VERSION >= 108000) && !defined(BOOST_NO_EXCEPTIONS)) 23 | #define BOOST_NO_EXCEPTIONS 24 | #endif 25 | 26 | #if (((BOOST_VERSION == 108000) || (BOOST_VERSION == 108100)) && defined(BOOST_NO_EXCEPTIONS)) 27 | #if defined(__clang__) 28 | #pragma GCC diagnostic push 29 | #pragma GCC diagnostic ignored "-Wsometimes-uninitialized" 30 | #endif 31 | #if defined(_MSC_VER) 32 | #pragma warning(push) 33 | #pragma warning(disable : 4701) 34 | #endif 35 | #endif 36 | 37 | #if (BOOST_VERSION < 108000) 38 | #if defined(__GNUC__) 39 | #pragma GCC diagnostic push 40 | #pragma GCC diagnostic ignored "-Wconversion" 41 | #pragma GCC diagnostic push 42 | #pragma GCC diagnostic ignored "-Wsign-conversion" 43 | #pragma GCC diagnostic push 44 | #pragma GCC diagnostic ignored "-Wunused-parameter" 45 | #endif 46 | #endif 47 | 48 | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)) 49 | #pragma GCC diagnostic push 50 | #pragma GCC diagnostic ignored "-Wrestrict" 51 | #endif 52 | 53 | #if (BOOST_VERSION < 108000) 54 | #if ((defined(__clang__) && (__clang_major__ > 9)) && !defined(__APPLE__)) 55 | #pragma GCC diagnostic push 56 | #pragma GCC diagnostic ignored "-Wdeprecated-copy" 57 | #endif 58 | #endif 59 | 60 | #include 61 | 62 | #include 63 | #include 64 | 65 | namespace local_int_convert 66 | { 67 | auto engine_val() -> std::mt19937& { static std::mt19937 my_engine_val; return my_engine_val; } // NOLINT(cert-msc32-c,cert-msc51-cpp) 68 | auto engine_sgn() -> std::ranlux24_base& { static std::ranlux24_base my_engine_sgn; return my_engine_sgn; } // NOLINT(cert-msc32-c,cert-msc51-cpp) 69 | auto engine_len() -> std::linear_congruential_engine& { static std::linear_congruential_engine my_engine_len; return my_engine_len; } // NOLINT(cert-msc32-c,cert-msc51-cpp,cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 70 | 71 | template 73 | auto get_random_digit_string(std::string& str) -> void // NOLINT(google-runtime-references) 74 | { 75 | static_assert(MinDigitsToGet >= 2U, "Error: The minimum number of digits to get must be 2 or more"); 76 | 77 | static std::uniform_int_distribution 78 | dist_sgn 79 | ( 80 | static_cast(UINT8_C(0)), 81 | static_cast(UINT8_C(1)) 82 | ); 83 | 84 | static std::uniform_int_distribution 85 | dist_len 86 | ( 87 | MinDigitsToGet, 88 | MaxDigitsToGet 89 | ); 90 | 91 | static std::uniform_int_distribution 92 | dist_first 93 | ( 94 | static_cast(UINT8_C(1)), 95 | static_cast(UINT8_C(9)) 96 | ); 97 | 98 | static std::uniform_int_distribution 99 | dist_following 100 | ( 101 | static_cast(UINT8_C(0)), 102 | static_cast(UINT8_C(9)) 103 | ); 104 | 105 | const bool is_neg = (dist_sgn(engine_sgn()) != 0); 106 | 107 | const auto len = static_cast(dist_len(engine_len())); 108 | 109 | std::string::size_type pos = 0U; 110 | 111 | if(is_neg) 112 | { 113 | str.resize(len + 1U); 114 | 115 | str.at(pos) = '-'; 116 | 117 | ++pos; 118 | } 119 | else 120 | { 121 | str.resize(len); 122 | } 123 | 124 | str.at(pos) = 125 | static_cast 126 | ( 127 | dist_first(engine_val()) 128 | + static_cast::result_type>(UINT32_C(0x30)) 129 | ); 130 | 131 | ++pos; 132 | 133 | while(pos < str.length()) 134 | { 135 | str.at(pos) = 136 | static_cast 137 | ( 138 | dist_following(engine_val()) 139 | + static_cast::result_type>(UINT32_C(0x30)) 140 | ); 141 | 142 | ++pos; 143 | } 144 | } 145 | 146 | template 147 | auto hexlexical_cast(const UnsignedIntegralType& u) -> std::string 148 | { 149 | std::stringstream ss; 150 | 151 | ss << std::hex << u; 152 | 153 | return ss.str(); 154 | } 155 | } // namespace local_int_convert 156 | 157 | #if defined(WIDE_INTEGER_NAMESPACE) 158 | auto WIDE_INTEGER_NAMESPACE::math::wide_integer::test_uintwide_t_int_convert() -> bool 159 | #else 160 | auto ::math::wide_integer::test_uintwide_t_int_convert() -> bool 161 | #endif 162 | { 163 | constexpr auto digits2 = static_cast(UINT32_C(256)); 164 | 165 | using boost_sint_backend_type = 166 | boost::multiprecision::cpp_int_backend; 169 | 170 | using boost_sint_type = boost::multiprecision::number; 171 | 172 | #if defined(WIDE_INTEGER_HAS_LIMB_TYPE_UINT64) 173 | using local_limb_type = std::uint64_t; 174 | #else 175 | using local_limb_type = std::uint32_t; 176 | #endif 177 | 178 | #if defined(WIDE_INTEGER_NAMESPACE) 179 | using local_sint_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t; 180 | #else 181 | using local_sint_type = ::math::wide_integer::uintwide_t; 182 | #endif 183 | 184 | local_int_convert::engine_val().seed(::util::util_pseudorandom_time_point_seed::value()); 185 | local_int_convert::engine_sgn().seed(::util::util_pseudorandom_time_point_seed::value()); 186 | local_int_convert::engine_len().seed(::util::util_pseudorandom_time_point_seed::value::result_type>()); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 187 | 188 | bool result_is_ok = true; 189 | 190 | for(auto i = static_cast(UINT32_C(0)); 191 | i < static_cast(UINT32_C(0x100000)); 192 | ++i) 193 | { 194 | std::string str_digits; 195 | 196 | local_int_convert::get_random_digit_string(UINT32_C(18)), static_cast(UINT32_C(2))>(str_digits); 197 | 198 | const auto n_boost = boost_sint_type(str_digits.c_str()); 199 | const auto n_local = local_sint_type(str_digits.c_str()); 200 | 201 | const auto n_ctrl_boost = static_cast(n_boost); 202 | const auto n_ctrl_local = static_cast(n_local); 203 | 204 | const bool result_n_is_ok = (n_ctrl_boost == n_ctrl_local); 205 | 206 | result_is_ok = (result_n_is_ok && result_is_ok); 207 | } 208 | 209 | return result_is_ok; 210 | } 211 | 212 | #if (BOOST_VERSION < 108000) 213 | #if ((defined(__clang__) && (__clang_major__ > 9)) && !defined(__APPLE__)) 214 | #pragma GCC diagnostic pop 215 | #endif 216 | #endif 217 | 218 | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)) 219 | #pragma GCC diagnostic pop 220 | #endif 221 | 222 | #if (BOOST_VERSION < 108000) 223 | #if defined(__GNUC__) 224 | #pragma GCC diagnostic pop 225 | #pragma GCC diagnostic pop 226 | #pragma GCC diagnostic pop 227 | #endif 228 | #endif 229 | 230 | #if (((BOOST_VERSION == 108000) || (BOOST_VERSION == 108100)) && defined(BOOST_NO_EXCEPTIONS)) 231 | #if defined(__clang__) 232 | #pragma GCC diagnostic pop 233 | #endif 234 | #if defined(_MSC_VER) 235 | #pragma warning(pop) 236 | #endif 237 | #endif 238 | -------------------------------------------------------------------------------- /test/test_uintwide_t_n_base.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2021 - 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #include 9 | 10 | auto test_uintwide_t_n_base::my_random_generator() -> test_uintwide_t_n_base::random_engine_type& 11 | { 12 | static random_engine_type my_generator; // NOLINT(cert-msc32-c,cert-msc51-cpp) 13 | 14 | return my_generator; 15 | } 16 | -------------------------------------------------------------------------------- /test/test_uintwide_t_n_base.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2019 - 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #ifndef TEST_UINTWIDE_T_N_BASE_2019_12_29_H // NOLINT(llvm-header-guard) 9 | #define TEST_UINTWIDE_T_N_BASE_2019_12_29_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include 18 | 19 | #if !defined(BOOST_VERSION) 20 | #error BOOST_VERSION is not defined. Ensure that is properly included. 21 | #endif 22 | 23 | #if ((BOOST_VERSION >= 107900) && !defined(BOOST_MP_STANDALONE)) 24 | #define BOOST_MP_STANDALONE 25 | #endif 26 | 27 | #if ((BOOST_VERSION >= 108000) && !defined(BOOST_NO_EXCEPTIONS)) 28 | #define BOOST_NO_EXCEPTIONS 29 | #endif 30 | 31 | #if (BOOST_VERSION < 108000) 32 | #if defined(__GNUC__) 33 | #pragma GCC diagnostic push 34 | #pragma GCC diagnostic ignored "-Wconversion" 35 | #pragma GCC diagnostic push 36 | #pragma GCC diagnostic ignored "-Wsign-conversion" 37 | #pragma GCC diagnostic push 38 | #pragma GCC diagnostic ignored "-Wunused-parameter" 39 | #endif 40 | #endif 41 | 42 | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)) 43 | #pragma GCC diagnostic push 44 | #pragma GCC diagnostic ignored "-Wrestrict" 45 | #endif 46 | 47 | #if (BOOST_VERSION < 108000) 48 | #if ((defined(__clang__) && (__clang_major__ > 9)) && !defined(__APPLE__)) 49 | #pragma GCC diagnostic push 50 | #pragma GCC diagnostic ignored "-Wdeprecated-copy" 51 | #endif 52 | #endif 53 | 54 | #include 55 | 56 | #include 57 | #include 58 | 59 | class test_uintwide_t_n_base 60 | { 61 | public: 62 | virtual ~test_uintwide_t_n_base() = default; 63 | 64 | #if defined(WIDE_INTEGER_NAMESPACE) 65 | WIDE_INTEGER_NODISCARD 66 | virtual auto get_digits2() const -> WIDE_INTEGER_NAMESPACE::math::wide_integer::size_t = 0; 67 | #else 68 | WIDE_INTEGER_NODISCARD 69 | virtual auto get_digits2() const -> ::math::wide_integer::size_t = 0; 70 | #endif 71 | 72 | WIDE_INTEGER_NODISCARD 73 | auto size() const -> std::size_t { return number_of_cases; } 74 | 75 | virtual auto initialize() -> void = 0; 76 | 77 | test_uintwide_t_n_base() = delete; 78 | 79 | test_uintwide_t_n_base(const test_uintwide_t_n_base&) = delete; 80 | test_uintwide_t_n_base( test_uintwide_t_n_base&&) = delete; 81 | 82 | auto operator=(const test_uintwide_t_n_base&) -> test_uintwide_t_n_base& = delete; 83 | auto operator=( test_uintwide_t_n_base&&) -> test_uintwide_t_n_base& = delete; 84 | 85 | protected: 86 | using random_engine_type = 87 | std::linear_congruential_engine; // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) 88 | 89 | static auto my_random_generator() -> random_engine_type&; 90 | 91 | explicit test_uintwide_t_n_base(const std::size_t count) 92 | : number_of_cases(count) { } 93 | 94 | template 95 | static auto hexlexical_cast(const UnsignedIntegralType& u) -> std::string 96 | { 97 | std::stringstream ss; 98 | 99 | ss << std::hex << u; 100 | 101 | return ss.str(); 102 | } 103 | 104 | template 105 | static auto declexical_cast(const IntegralType& n) -> std::string 106 | { 107 | std::stringstream ss; 108 | 109 | ss << std::dec << n; 110 | 111 | return ss.str(); 112 | } 113 | 114 | template 117 | static auto get_equal_random_test_values_boost_and_local_n( OtherLocalUintType* u_local, 118 | OtherBoostUintType* u_boost, 119 | const std::size_t count) -> void 120 | { 121 | using other_local_uint_type = OtherLocalUintType; 122 | using other_boost_uint_type = OtherBoostUintType; 123 | 124 | my_random_generator().seed(util::util_pseudorandom_time_point_seed::value()); 125 | 126 | #if defined(WIDE_INTEGER_NAMESPACE) 127 | using distribution_type = 128 | WIDE_INTEGER_NAMESPACE::math::wide_integer::uniform_int_distribution; 129 | #else 130 | using distribution_type = 131 | ::math::wide_integer::uniform_int_distribution; 132 | #endif 133 | 134 | distribution_type distribution; 135 | 136 | std::atomic_flag rnd_lock = ATOMIC_FLAG_INIT; 137 | 138 | my_concurrency::parallel_for 139 | ( 140 | static_cast(0U), 141 | count, 142 | [&u_local, &u_boost, &distribution, &rnd_lock](std::size_t i) 143 | { 144 | while(rnd_lock.test_and_set()) { ; } 145 | const other_local_uint_type a = distribution(my_random_generator()); 146 | rnd_lock.clear(); 147 | 148 | u_local[i] = a; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 149 | u_boost[i] = other_boost_uint_type("0x" + hexlexical_cast(a)); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 150 | } 151 | ); 152 | } 153 | 154 | private: 155 | const std::size_t number_of_cases; 156 | }; 157 | 158 | #if (BOOST_VERSION < 108000) 159 | #if ((defined(__clang__) && (__clang_major__ > 9)) && !defined(__APPLE__)) 160 | #pragma GCC diagnostic pop 161 | #endif 162 | #endif 163 | 164 | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)) 165 | #pragma GCC diagnostic pop 166 | #endif 167 | 168 | #if (BOOST_VERSION < 108000) 169 | #if defined(__GNUC__) 170 | #pragma GCC diagnostic pop 171 | #pragma GCC diagnostic pop 172 | #pragma GCC diagnostic pop 173 | #endif 174 | #endif 175 | 176 | #endif // TEST_UINTWIDE_T_N_BASE_2019_12_29_H 177 | -------------------------------------------------------------------------------- /test/test_uintwide_t_n_binary_ops_base.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2019 - 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #include 9 | 10 | #if !defined(BOOST_VERSION) 11 | #error BOOST_VERSION is not defined. Ensure that is properly included. 12 | #endif 13 | 14 | #if ((BOOST_VERSION >= 107900) && !defined(BOOST_MP_STANDALONE)) 15 | #define BOOST_MP_STANDALONE 16 | #endif 17 | 18 | #if ((BOOST_VERSION >= 108000) && !defined(BOOST_NO_EXCEPTIONS)) 19 | #define BOOST_NO_EXCEPTIONS 20 | #endif 21 | 22 | #if (((BOOST_VERSION == 108000) || (BOOST_VERSION == 108100)) && defined(BOOST_NO_EXCEPTIONS)) 23 | #if defined(__clang__) 24 | #pragma GCC diagnostic push 25 | #pragma GCC diagnostic ignored "-Wsometimes-uninitialized" 26 | #endif 27 | #if defined(_MSC_VER) 28 | #pragma warning(push) 29 | #pragma warning(disable : 4701) 30 | #endif 31 | #endif 32 | 33 | #if (BOOST_VERSION < 108000) 34 | #if defined(__GNUC__) 35 | #pragma GCC diagnostic push 36 | #pragma GCC diagnostic ignored "-Wconversion" 37 | #pragma GCC diagnostic push 38 | #pragma GCC diagnostic ignored "-Wsign-conversion" 39 | #pragma GCC diagnostic push 40 | #pragma GCC diagnostic ignored "-Wunused-parameter" 41 | #endif 42 | #endif 43 | 44 | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)) 45 | #pragma GCC diagnostic push 46 | #pragma GCC diagnostic ignored "-Wrestrict" 47 | #endif 48 | 49 | #if (BOOST_VERSION < 108000) 50 | #if ((defined(__clang__) && (__clang_major__ > 9)) && !defined(__APPLE__)) 51 | #pragma GCC diagnostic push 52 | #pragma GCC diagnostic ignored "-Wdeprecated-copy" 53 | #endif 54 | #endif 55 | 56 | #include 57 | 58 | auto test_uintwide_t_n_binary_ops_base::my_rnd() -> std::random_device& 59 | { 60 | static std::random_device my_random_device; 61 | 62 | return my_random_device; 63 | } 64 | 65 | auto test_uintwide_t_n_binary_ops_base::my_gen() -> test_uintwide_t_n_binary_ops_base::random_generator_type& 66 | { 67 | static random_generator_type my_generator(my_rnd()()); 68 | 69 | return my_generator; 70 | } 71 | 72 | #if (BOOST_VERSION < 108000) 73 | #if ((defined(__clang__) && (__clang_major__ > 9)) && !defined(__APPLE__)) 74 | #pragma GCC diagnostic pop 75 | #endif 76 | #endif 77 | 78 | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)) 79 | #pragma GCC diagnostic pop 80 | #endif 81 | 82 | #if (BOOST_VERSION < 108000) 83 | #if defined(__GNUC__) 84 | #pragma GCC diagnostic pop 85 | #pragma GCC diagnostic pop 86 | #pragma GCC diagnostic pop 87 | #endif 88 | #endif 89 | 90 | #if (((BOOST_VERSION == 108000) || (BOOST_VERSION == 108100)) && defined(BOOST_NO_EXCEPTIONS)) 91 | #if defined(__clang__) 92 | #pragma GCC diagnostic pop 93 | #endif 94 | #if defined(_MSC_VER) 95 | #pragma warning(pop) 96 | #endif 97 | #endif 98 | -------------------------------------------------------------------------------- /test/test_uintwide_t_n_binary_ops_base.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2019 - 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #ifndef TEST_UINTWIDE_T_N_BINARY_OPS_BASE_2019_12_19_H // NOLINT(llvm-header-guard) 9 | #define TEST_UINTWIDE_T_N_BINARY_OPS_BASE_2019_12_19_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | class test_uintwide_t_n_binary_ops_base : public test_uintwide_t_n_base 19 | { 20 | public: 21 | explicit test_uintwide_t_n_binary_ops_base(const std::size_t count) 22 | : test_uintwide_t_n_base(count) { } 23 | 24 | test_uintwide_t_n_binary_ops_base() = delete; 25 | 26 | test_uintwide_t_n_binary_ops_base(const test_uintwide_t_n_binary_ops_base&) = delete; 27 | test_uintwide_t_n_binary_ops_base( test_uintwide_t_n_binary_ops_base&&) = delete; 28 | 29 | auto operator=(const test_uintwide_t_n_binary_ops_base&) -> test_uintwide_t_n_binary_ops_base& = delete; 30 | auto operator=( test_uintwide_t_n_binary_ops_base&&) -> test_uintwide_t_n_binary_ops_base& = delete; 31 | 32 | ~test_uintwide_t_n_binary_ops_base() override = default; 33 | 34 | virtual auto do_test(std::size_t rounds) -> bool = 0; 35 | 36 | protected: 37 | using random_generator_type = std::mersenne_twister_engine(UINT32_C( 32)), 39 | static_cast(UINT32_C(624)), 40 | static_cast(UINT32_C(397)), 41 | static_cast(UINT32_C( 31)), 42 | UINT32_C(0x9908B0DF), 43 | static_cast(UINT32_C( 11)), 44 | UINT32_C(0xFFFFFFFF), 45 | static_cast(UINT32_C( 7)), 46 | UINT32_C(0x9D2C5680), 47 | static_cast(UINT32_C( 15)), 48 | UINT32_C(0xEFC60000), 49 | static_cast(UINT32_C( 18)), 50 | UINT32_C(1812433253)>; 51 | 52 | static auto my_rnd() -> std::random_device&; 53 | static auto my_gen() -> random_generator_type&; 54 | }; 55 | 56 | #endif // TEST_UINTWIDE_T_N_BINARY_OPS_BASE_2019_12_19_H 57 | -------------------------------------------------------------------------------- /test/test_uintwide_t_n_binary_ops_mul_n_by_m_template.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2019 - 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #ifndef TEST_UINTWIDE_T_N_BINARY_OPS_MUL_N_BY_M_TEMPLATE_2019_12_26_H // NOLINT(llvm-header-guard) 9 | #define TEST_UINTWIDE_T_N_BINARY_OPS_MUL_N_BY_M_TEMPLATE_2019_12_26_H 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #if defined(WIDE_INTEGER_NAMESPACE) 17 | template 20 | #else 21 | template 24 | #endif 25 | class test_uintwide_t_n_binary_ops_mul_n_by_m_template : public test_uintwide_t_n_binary_ops_base // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) 26 | { 27 | private: 28 | #if defined(WIDE_INTEGER_NAMESPACE) 29 | static constexpr auto digits2a = static_cast(MyDigits2A); 30 | static constexpr auto digits2b = static_cast(MyDigits2B); 31 | #else 32 | static constexpr auto digits2a = static_cast(MyDigits2A); 33 | static constexpr auto digits2b = static_cast(MyDigits2B); 34 | #endif 35 | 36 | #if defined(WIDE_INTEGER_NAMESPACE) 37 | WIDE_INTEGER_NODISCARD auto get_digits2a() const -> WIDE_INTEGER_NAMESPACE::math::wide_integer::size_t { return digits2a; } 38 | WIDE_INTEGER_NODISCARD auto get_digits2b() const -> WIDE_INTEGER_NAMESPACE::math::wide_integer::size_t { return digits2b; } 39 | WIDE_INTEGER_NODISCARD auto get_digits2 () const -> WIDE_INTEGER_NAMESPACE::math::wide_integer::size_t override { return digits2a + digits2b; } 40 | #else 41 | WIDE_INTEGER_NODISCARD auto get_digits2a() const -> ::math::wide_integer::size_t { return digits2a; } 42 | WIDE_INTEGER_NODISCARD auto get_digits2b() const -> ::math::wide_integer::size_t { return digits2b; } 43 | WIDE_INTEGER_NODISCARD auto get_digits2 () const -> ::math::wide_integer::size_t override { return digits2a + digits2b; } 44 | #endif 45 | 46 | using boost_uint_backend_a_allocator_type = void; 47 | 48 | using boost_uint_backend_a_type = 49 | boost::multiprecision::cpp_int_backend; 54 | 55 | using boost_uint_backend_b_allocator_type = void; 56 | 57 | using boost_uint_backend_b_type = 58 | boost::multiprecision::cpp_int_backend; 63 | 64 | using boost_uint_backend_c_allocator_type = void; 65 | 66 | using boost_uint_backend_c_type = 67 | boost::multiprecision::cpp_int_backend; 72 | 73 | using boost_uint_a_type = boost::multiprecision::number; 74 | using boost_uint_b_type = boost::multiprecision::number; 75 | using boost_uint_c_type = boost::multiprecision::number; 76 | 77 | using local_limb_type = MyLimbType; 78 | 79 | #if defined(WIDE_INTEGER_NAMESPACE) 80 | using local_uint_a_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t; 81 | using local_uint_b_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t; 82 | using local_uint_c_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uintwide_t; 83 | #else 84 | using local_uint_a_type = ::math::wide_integer::uintwide_t; 85 | using local_uint_b_type = ::math::wide_integer::uintwide_t; 86 | using local_uint_c_type = ::math::wide_integer::uintwide_t; 87 | #endif 88 | 89 | public: 90 | explicit test_uintwide_t_n_binary_ops_mul_n_by_m_template(const std::size_t count) 91 | : test_uintwide_t_n_binary_ops_base(count) { } 92 | 93 | ~test_uintwide_t_n_binary_ops_mul_n_by_m_template() override = default; 94 | 95 | auto do_test(std::size_t rounds) -> bool override 96 | { 97 | bool result_is_ok = true; 98 | 99 | for(std::size_t i = 0U; i < rounds; ++i) 100 | { 101 | std::cout << "initialize() boost compare with uintwide_t: round " << i << ", digits2: " << this->get_digits2() << std::endl; 102 | this->initialize(); 103 | 104 | std::cout << "test_binary_mul() boost compare with uintwide_t: round " << i << ", digits2: " << this->get_digits2() << std::endl; 105 | result_is_ok = (test_binary_mul() && result_is_ok); 106 | } 107 | 108 | return result_is_ok; 109 | } 110 | 111 | auto initialize() -> void override 112 | { 113 | a_local.clear(); 114 | b_local.clear(); 115 | 116 | a_boost.clear(); 117 | b_boost.clear(); 118 | 119 | a_local.resize(size()); 120 | b_local.resize(size()); 121 | 122 | a_boost.resize(size()); 123 | b_boost.resize(size()); 124 | 125 | get_equal_random_test_values_boost_and_local_n(a_local.data(), a_boost.data(), size()); 126 | get_equal_random_test_values_boost_and_local_n(b_local.data(), b_boost.data(), size()); 127 | } 128 | 129 | WIDE_INTEGER_NODISCARD auto test_binary_mul() const -> bool 130 | { 131 | bool result_is_ok = true; 132 | 133 | std::atomic_flag test_lock = ATOMIC_FLAG_INIT; 134 | 135 | my_concurrency::parallel_for 136 | ( 137 | static_cast(0U), 138 | size(), 139 | [&test_lock, &result_is_ok, this](std::size_t i) 140 | { 141 | const boost_uint_c_type c_boost = boost_uint_c_type(a_boost[i]) 142 | * b_boost[i]; 143 | 144 | const local_uint_c_type c_local = static_cast(a_local[i]) 145 | * static_cast(b_local[i]); 146 | 147 | const std::string str_boost = hexlexical_cast(c_boost); 148 | const std::string str_local = hexlexical_cast(c_local); 149 | 150 | while(test_lock.test_and_set()) { ; } 151 | result_is_ok = ((str_boost == str_local) && result_is_ok); 152 | test_lock.clear(); 153 | } 154 | ); 155 | 156 | return result_is_ok; 157 | } 158 | 159 | private: 160 | std::vector a_local { }; // NOLINT(readability-identifier-naming) 161 | std::vector b_local { }; // NOLINT(readability-identifier-naming) 162 | 163 | std::vector a_boost { }; // NOLINT(readability-identifier-naming) 164 | std::vector b_boost { }; // NOLINT(readability-identifier-naming) 165 | }; 166 | 167 | #endif // TEST_UINTWIDE_T_N_BINARY_OPS_MUL_N_BY_M_TEMPLATE_2019_12_26_H 168 | -------------------------------------------------------------------------------- /test/test_uintwide_t_n_number_theory_funcs_template.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2019 - 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #ifndef TEST_UINTWIDE_T_N_NUMBER_THEORY_FUNCS_TEMPLATE_2019_12_29_H // NOLINT(llvm-header-guard) 9 | #define TEST_UINTWIDE_T_N_NUMBER_THEORY_FUNCS_TEMPLATE_2019_12_29_H 10 | 11 | #include 12 | 13 | #if defined(WIDE_INTEGER_NAMESPACE) 14 | template 16 | #else 17 | template 19 | #endif 20 | class test_uintwide_t_n_number_theory_funcs_template : public test_uintwide_t_n_base 21 | { 22 | public: 23 | #if defined(WIDE_INTEGER_NAMESPACE) 24 | static constexpr auto digits2 = static_cast(MyWidth2); 25 | #else 26 | static constexpr auto digits2 = static_cast(MyWidth2); 27 | #endif 28 | 29 | test_uintwide_t_n_number_theory_funcs_template(const std::size_t count) 30 | : test_uintwide_t_n_base(count) { } 31 | 32 | virtual ~test_uintwide_t_n_number_theory_funcs_template() = default; 33 | 34 | #if defined(WIDE_INTEGER_NAMESPACE) 35 | virtual auto get_digits2() const -> WIDE_INTEGER_NAMESPACE::math::wide_integer::size_t { return digits2; } 36 | #else 37 | virtual auto get_digits2() const -> ::math::wide_integer::size_t { return digits2; } 38 | #endif 39 | 40 | virtual auto initialize() -> void { } 41 | }; 42 | 43 | #endif // TEST_UINTWIDE_T_N_NUMBER_THEORY_FUNCS_TEMPLATE_2019_12_29_H 44 | -------------------------------------------------------------------------------- /test/test_uintwide_t_xtra_from_issue_335.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2022 - 2024. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #if !defined(WIDE_INTEGER_DISABLE_PRIVATE_CLASS_DATA_MEMBERS) 13 | #define WIDE_INTEGER_DISABLE_PRIVATE_CLASS_DATA_MEMBERS 14 | #endif 15 | 16 | // cd /mnt/c/Users/User/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer 17 | // g++-10 -finline-functions -m64 -O3 -Werror -Wall -Wextra -Wconversion -Wsign-conversion -Wshadow -Wundef -Wunused-parameter -Wuninitialized -Wunreachable-code -Winit-self -Wzero-as-null-pointer-constant -std=c++20 -DWIDE_INTEGER_DISABLE_PRIVATE_CLASS_DATA_MEMBERS -DWIDE_INTEGER_NAMESPACE=ckormanyos -I. test/test_uintwide_t_xtra_from_issue_335.cpp -o test_uintwide_t_xtra_from_issue_335.exe 18 | 19 | #include 20 | 21 | namespace from_issue_335 22 | { 23 | // See also: https://github.com/ckormanyos/wide-integer/issues/335 24 | 25 | template(8U * sizeof(UInt)), 27 | UInt MaxValue = -UInt(1)> 28 | auto f(uint32_t n) -> std::string 29 | { 30 | std::stringstream strm; 31 | 32 | strm << BitCount << "-bit ; MaxValue = " << MaxValue << ", n = " << UInt(n); 33 | 34 | return strm.str(); 35 | } 36 | 37 | auto test_uintwide_t_xtra_from_issue_335() -> bool 38 | { 39 | #if defined(WIDE_INTEGER_NAMESPACE) 40 | using local_wide_integer_type = WIDE_INTEGER_NAMESPACE::math::wide_integer::uint256_t; 41 | #else 42 | using local_wide_integer_type = ::math::wide_integer::uint256_t; 43 | #endif 44 | 45 | // String result: 46 | // "256-bit ; MaxValue = 115792089237316195423570985008687907853269984665640564039457584007913129639935, n = 42" 47 | const auto str_result = f(42); 48 | 49 | std::cout << str_result << std::endl; 50 | 51 | const auto result_is_ok = 52 | ( 53 | str_result == "256-bit ; MaxValue = 115792089237316195423570985008687907853269984665640564039457584007913129639935, n = 42" 54 | ); 55 | 56 | return result_is_ok; 57 | } 58 | } 59 | 60 | auto main() -> int 61 | { 62 | const auto result_is_ok = from_issue_335::test_uintwide_t_xtra_from_issue_335(); 63 | 64 | std::cout << "result_is_ok: " << std::boolalpha << result_is_ok << std::endl; 65 | 66 | return (result_is_ok ? 0 : -1); 67 | } 68 | -------------------------------------------------------------------------------- /util/utility/util_pseudorandom_time_point_seed.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright Christopher Kormanyos 2023. 3 | // Distributed under the Boost Software License, 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #ifndef UTIL_PSEUDORANDOM_TIME_POINT_SEED_2023_10_27_H // NOLINT(llvm-header-guard) 9 | #define UTIL_PSEUDORANDOM_TIME_POINT_SEED_2023_10_27_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace util { 22 | 23 | struct util_pseudorandom_time_point_seed 24 | { 25 | public: 26 | template 27 | static auto value() -> IntegralType 28 | { 29 | const std::uint64_t t_now { now() }; 30 | 31 | std::stringstream strm { }; 32 | 33 | using strtime_uint8_array_type = std::array(UINT8_C(16))>; 34 | 35 | strtime_uint8_array_type buf_u8 { }; buf_u8.fill(static_cast(UINT8_C(0))); 36 | 37 | // Get the string representation of the time point. 38 | strm << std::setw(std::tuple_size::value) << std::hex << std::uppercase << std::setfill('0') << t_now; 39 | 40 | const std::string str_tm { strm.str() }; 41 | 42 | std::copy(str_tm.cbegin(), str_tm.cend(), buf_u8.begin()); 43 | 44 | using local_integral_type = IntegralType; 45 | 46 | return static_cast(crc_crc64(buf_u8.data(), buf_u8.size())); 47 | } 48 | 49 | static constexpr auto test() noexcept -> bool; 50 | 51 | private: 52 | static auto now() -> std::uint64_t 53 | { 54 | #if defined(__CYGWIN__) 55 | 56 | return static_cast(std::clock()); 57 | 58 | #else 59 | 60 | // Get the time (t_now). 61 | timespec ts { }; 62 | 63 | timespec_get(&ts, TIME_UTC); 64 | 65 | return 66 | static_cast 67 | ( 68 | static_cast(static_cast(ts.tv_sec) * UINT64_C(1000000000)) 69 | + static_cast(ts.tv_nsec) 70 | ); 71 | 72 | #endif 73 | } 74 | 75 | template 77 | static constexpr auto crc_bitwise_template(const std::uint8_t* message, 78 | const std::size_t count, 79 | const UnsignedIntegralType polynomial, // NOLINT(bugprone-easily-swappable-parameters) 80 | const UnsignedIntegralType initial_value, 81 | const UnsignedIntegralType final_xor_value) -> UnsignedIntegralType 82 | { 83 | using value_type = UnsignedIntegralType; 84 | 85 | // The data_type is fixed to exactly 8-bits in width at the moment. 86 | using data_type = std::uint8_t; 87 | 88 | value_type crc = initial_value; 89 | 90 | // Perform the polynomial division, one element at a time. 91 | for(auto data_index = static_cast(UINT8_C(0)); data_index < count; ++data_index) 92 | { 93 | // Obtain the next data element (and reflect it if necessary). 94 | const data_type next_data_element = message[data_index]; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 95 | 96 | { 97 | constexpr auto left_shift_amount = 98 | static_cast 99 | ( 100 | std::numeric_limits::digits - std::numeric_limits::digits 101 | ); 102 | 103 | crc ^= static_cast(static_cast(next_data_element) << left_shift_amount); 104 | } 105 | 106 | // Process the next data byte, one bit at a time. 107 | for(std::uint_fast8_t index = 0U; 108 | index < static_cast(std::numeric_limits::digits); 109 | ++index) 110 | { 111 | const auto high_bit_value = 112 | static_cast 113 | ( 114 | crc 115 | & static_cast 116 | ( 117 | static_cast(UINT8_C(1)) << static_cast(std::numeric_limits::digits - 1) 118 | ) 119 | ); 120 | 121 | const bool high_bit_of_crc_is_set = (high_bit_value != static_cast(UINT8_C(0))); 122 | 123 | crc = crc << static_cast(UINT8_C(1)); 124 | 125 | if(high_bit_of_crc_is_set) 126 | { 127 | // Shift through the polynomial. Also left-justify the 128 | // polynomial within the width of value_type, if necessary. 129 | 130 | crc ^= static_cast(polynomial); 131 | } 132 | } 133 | } 134 | 135 | // Perform the final XOR on the result. 136 | crc ^= final_xor_value; 137 | 138 | return crc; 139 | } 140 | 141 | static constexpr auto crc_crc64(const std::uint8_t* message, const std::size_t count) -> std::uint64_t 142 | { 143 | // check: 0x6C40DF5F0B497347 144 | return crc_bitwise_template(UINT8_C(64)), std::uint64_t> 145 | ( 146 | message, 147 | count, 148 | static_cast(UINT64_C(0x42F0E1EBA9EA3693)), 149 | static_cast(UINT64_C(0x0000000000000000)), 150 | static_cast(UINT64_C(0x0000000000000000)) 151 | ); 152 | } 153 | }; 154 | 155 | constexpr auto util_pseudorandom_time_point_seed::test() noexcept -> bool 156 | { 157 | constexpr std::uint8_t crc64_test_data[static_cast(UINT8_C(9))] = // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) 158 | { 159 | 0x31U, 0x32U, 0x33U, 0x34U, 0x35U, 0x36U, 0x37U, 0x38U, 0x39U 160 | }; 161 | 162 | constexpr auto crc64_test_result = crc_bitwise_template(UINT8_C(64)), std::uint64_t> 163 | ( 164 | crc64_test_data, // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay,hicpp-no-array-decay) 165 | sizeof(crc64_test_data), 166 | static_cast(UINT64_C(0x42F0E1EBA9EA3693)), 167 | static_cast(UINT64_C(0x0000000000000000)), 168 | static_cast(UINT64_C(0x0000000000000000)) 169 | ); 170 | 171 | // check: 0x6C40DF5F0B497347 172 | return (crc64_test_result == static_cast(UINT64_C(0x6C40DF5F0B497347))); 173 | } 174 | 175 | static_assert(util::util_pseudorandom_time_point_seed::test(), "Error: crc64 implementation is not working properly"); 176 | 177 | } // namespace util 178 | 179 | #endif // UTIL_PSEUDORANDOM_TIME_POINT_SEED_2023_10_27_H 180 | -------------------------------------------------------------------------------- /wide_integer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28010.2036 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wide_integer", "wide_integer.vcxproj", "{3D16BABC-0908-40AB-AFF2-FD60B9172A5B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Debug|x64.ActiveCfg = Debug|x64 17 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Debug|x64.Build.0 = Debug|x64 18 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Debug|x86.ActiveCfg = Debug|Win32 19 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Debug|x86.Build.0 = Debug|Win32 20 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Release|x64.ActiveCfg = Release|x64 21 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Release|x64.Build.0 = Release|x64 22 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Release|x86.ActiveCfg = Release|Win32 23 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {23A7720B-5B7B-4E07-92C8-F66F79D7E0C0} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /wide_integer_vs2022.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32519.379 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wide_integer_vs2022", "wide_integer_vs2022.vcxproj", "{3D16BABC-0908-40AB-AFF2-FD60B9172A5B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Debug|x64.ActiveCfg = Debug|x64 17 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Debug|x64.Build.0 = Debug|x64 18 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Debug|x86.ActiveCfg = Debug|Win32 19 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Debug|x86.Build.0 = Debug|Win32 20 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Release|x64.ActiveCfg = Release|x64 21 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Release|x64.Build.0 = Release|x64 22 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Release|x86.ActiveCfg = Release|Win32 23 | {3D16BABC-0908-40AB-AFF2-FD60B9172A5B}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {23A7720B-5B7B-4E07-92C8-F66F79D7E0C0} 30 | EndGlobalSection 31 | EndGlobal 32 | --------------------------------------------------------------------------------