pax_global_header00006660000000000000000000000064147703660070014524gustar00rootroot0000000000000052 comment=fb0390157d5c8811fc2a5a6d7d8eac27261f06fb tlfloat-1.15.0/000077500000000000000000000000001477036600700132555ustar00rootroot00000000000000tlfloat-1.15.0/.github/000077500000000000000000000000001477036600700146155ustar00rootroot00000000000000tlfloat-1.15.0/.github/ISSUE_TEMPLATE/000077500000000000000000000000001477036600700170005ustar00rootroot00000000000000tlfloat-1.15.0/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md000066400000000000000000000016451477036600700215130ustar00rootroot00000000000000--- name: Create a new issue about: Create an issue recognizing the effort we put into processing your issue title: Enter the title of your issue here labels: '' assignees: '' --- Our project provides only the current and previous versions of software free of charge. No other materials and services are provided free of charge unless they are explicitly stated to be free of charge. If you want us to process your issue, you will need to pay a fee. The specific amount you need to pay will be determined by negotiation, depending on the nature of the issue and your project. By becoming a sponsor of our project, you will receive a substantial discount on the cost of processing your issue. It is still possible to create an issue without paying a fee, but in that case we will not process your issue. If you have any questions, please contact us before creating an issue. Simply remove this notice when you create an issue. tlfloat-1.15.0/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000000341477036600700207650ustar00rootroot00000000000000blank_issues_enabled: false tlfloat-1.15.0/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000016651477036600700204260ustar00rootroot00000000000000Our project provides only the current and previous versions of software free of charge. No other materials and services are provided free of charge unless they are explicitly stated to be free of charge. Our project collects a fee from you to approve your PR. The specific amount you need to pay will be determined by negotiation, depending on the nature of the PR and your project. We will not charge a fee if you are not making a profit from the deliverables of this project, or for minor bug fixes that do not involve specification changes. The fee you pay is for the review and does not include the cost of any future maintenance of your code. Your code added by this PR may be removed without notice if our project finds it necessary. By becoming a sponsor of our project, no additional cost will be charged to review your PR. If you have any questions, please contact us before opening a PR. Simply remove this notice when you open a PR. tlfloat-1.15.0/CMakeLists.txt000066400000000000000000000330771477036600700160270ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.16) option(BUILD_LIBS "Build and install the library" ON) option(BUILD_TESTS "Build tests" ON) option(BUILD_UTILS "Build utilities" ON) option(BUILD_BENCH "Build benchmarking tools" OFF) option(ENABLE_INTSQRT "Enable fully integer sqrt" OFF) option(ENABLE_INLINING "Enable extensive function inlining" OFF) option(ENABLE_LTO "Enable LTO" OFF) option(ENABLE_ASAN "Enable address sanitizer" OFF) option(ENABLE_CUDA_TEST "Build CUDA tester" OFF) option(INSTALL_CONTINUOUS_TESTERS "Install continuous testers" OFF) option(ENABLE_DOXYGEN "Enable generating documents with Doxygen" OFF) option(ENABLE_COVERAGE "Enable generating coverage data" OFF) option(ENABLE_ARCH_OPTIMIZATION "Enable architecture-specific optimization upon building library" ON) option(BUILD_EXHAUSTIVE_TESTING "Build exhaustive testing for 16-bit and 32-bit arguments" OFF) option(ENABLE_EXHAUSTIVE_TESTING "Enable exhaustive testing for 16-bit and 32-bit arguments" OFF) set(SET_COMPILER_SUPPORTS_INT128 "auto" CACHE STRING "Set whether the compiler supports __int128 type") set(SET_COMPILER_SUPPORTS_ISOFLOAT128 "auto" CACHE STRING "Set whether the compiler supports _Float128 type") set(SET_COMPILER_SUPPORTS_FLOAT128 "auto" CACHE STRING "Set whether the compiler supports __float128 type") set(SET_LONGDOUBLE_IS_FLOAT128 "auto" CACHE STRING "Set whether long double is IEEE binary128") # set(TLFLOAT_VERSION_MAJOR 1) set(TLFLOAT_VERSION_MINOR 15) set(TLFLOAT_VERSION_PATCH 0) set(TLFLOAT_VERSION ${TLFLOAT_VERSION_MAJOR}.${TLFLOAT_VERSION_MINOR}.${TLFLOAT_VERSION_PATCH}) set(TLFLOAT_SOVERSION ${TLFLOAT_VERSION_MAJOR}) message(STATUS "Configuring TLFloat ${TLFLOAT_VERSION_MAJOR}.${TLFLOAT_VERSION_MINOR}.${TLFLOAT_VERSION_PATCH}") project(tlfloat) # enable_language(CXX) set(CMAKE_CXX_STANDARD 20) if(ENABLE_CUDA_TEST) enable_language(CUDA) set(CMAKE_CUDA_ARCHITECTURES 50) endif() # CMake configuration if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") message(FATAL_ERROR "In-source build not supported") endif() set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib") set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin") include_directories("${PROJECT_SOURCE_DIR}/src/include") include_directories("${PROJECT_BINARY_DIR}/include") set(TMPDIR "${CMAKE_BINARY_DIR}/tmp") file(MAKE_DIRECTORY "${TMPDIR}") if (NOT EXISTS ${CMAKE_BINARY_DIR}/CMakeCache.txt) if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) endif() endif() include(GNUInstallDirs) # Include packages find_library(LIB_MPFR mpfr) message(STATUS "LIB_MPFR : " ${LIB_MPFR}) if (LIB_MPFR) find_path(MPFR_INCLUDE_DIR mpfr.h) message(STATUS "MPFR_INCLUDE_DIR : " ${MPFR_INCLUDE_DIR}) if (MPFR_INCLUDE_DIR) include_directories("${MPFR_INCLUDE_DIR}") endif() endif() find_library(LIBM m) if (NOT LIBM) set(LIBM "") endif() find_package(OpenMP) # Detect compiler capabilities include(CheckCXXSourceCompiles) if (SET_COMPILER_SUPPORTS_INT128 STREQUAL "auto") if (CMAKE_CXX_COMPILER_TARGET) set(CMAKE_REQUIRED_FLAGS "--target=${CMAKE_CXX_COMPILER_TARGET}") endif() CHECK_CXX_SOURCE_COMPILES(" int main(int argc, char **argv) { __int128_t i = argc; __uint128_t u = argc; return (int)(i % 10) + (int)(u % 10); }" TLFLOAT_COMPILER_SUPPORTS_INT128) set(CMAKE_REQUIRED_FLAGS) else() if (SET_COMPILER_SUPPORTS_INT128) set(TLFLOAT_COMPILER_SUPPORTS_INT128 ON) else() set(TLFLOAT_COMPILER_SUPPORTS_INT128 OFF) endif() message(STATUS "Manually setting TLFLOAT_COMPILER_SUPPORTS_INT128 : " ${TLFLOAT_COMPILER_SUPPORTS_INT128}) endif() if (SET_COMPILER_SUPPORTS_ISOFLOAT128 STREQUAL "auto") if (CMAKE_CXX_COMPILER_TARGET) set(CMAKE_REQUIRED_FLAGS "--target=${CMAKE_CXX_COMPILER_TARGET}") endif() CHECK_CXX_SOURCE_COMPILES(" #include struct s { long long x, y; }; int main(int argc, char **argv) { constexpr s a = std::bit_cast(_Float128(0.1234)*_Float128(56.789)); static_assert((a.x ^ a.y) == 0xc7d695c93a4e2b71LL); _Float128 i = argc; return (int)i; } " TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128) set(CMAKE_REQUIRED_FLAGS) else() if (SET_COMPILER_SUPPORTS_ISOFLOAT128) set(TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128 ON) else() set(TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128 OFF) endif() message(STATUS "Manually setting TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128 : " ${TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128}) endif() if (SET_COMPILER_SUPPORTS_FLOAT128 STREQUAL "auto") if (CMAKE_CXX_COMPILER_TARGET) set(CMAKE_REQUIRED_FLAGS "--target=${CMAKE_CXX_COMPILER_TARGET}") endif() CHECK_CXX_SOURCE_COMPILES(" #include struct s { long long x, y; }; int main(int argc, char **argv) { constexpr s a = std::bit_cast(__float128(0.1234)*__float128(56.789)); static_assert((a.x ^ a.y) == 0xc7d695c93a4e2b71LL); __float128 i = argc; return (int)i; } " TLFLOAT_COMPILER_SUPPORTS_FLOAT128) set(CMAKE_REQUIRED_FLAGS) else() if (SET_COMPILER_SUPPORTS_FLOAT128) set(TLFLOAT_COMPILER_SUPPORTS_FLOAT128 ON) else() set(TLFLOAT_COMPILER_SUPPORTS_FLOAT128 OFF) endif() message(STATUS "Manually setting TLFLOAT_COMPILER_SUPPORTS_FLOAT128 : " ${TLFLOAT_COMPILER_SUPPORTS_FLOAT128}) endif() if (SET_LONGDOUBLE_IS_FLOAT128 STREQUAL "auto") if (CMAKE_CXX_COMPILER_TARGET) set(CMAKE_REQUIRED_FLAGS "--target=${CMAKE_CXX_COMPILER_TARGET}") endif() CHECK_CXX_SOURCE_COMPILES(" #include struct s { long long x, y; }; int main(void) { constexpr s a = std::bit_cast((long double)0.1234*(long double)56.789); static_assert((a.x ^ a.y) == 0xc7d695c93a4e2b71LL); } " TLFLOAT_LONGDOUBLE_IS_FLOAT128) set(CMAKE_REQUIRED_FLAGS) else() if (SET_LONGDOUBLE_IS_FLOAT128) set(TLFLOAT_LONGDOUBLE_IS_FLOAT128 ON) else() set(TLFLOAT_LONGDOUBLE_IS_FLOAT128 OFF) endif() message(STATUS "Manually setting TLFLOAT_LONGDOUBLE_IS_FLOAT128 : " ${TLFLOAT_LONGDOUBLE_IS_FLOAT128}) endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") set(CMAKE_REQUIRED_FLAGS "-march=armv8.2-a+fp16") CHECK_CXX_SOURCE_COMPILES(" #include #include int main(int argc, char **argv) { __fp16 hu = vaddh_f16(__fp16(atof(argv[1])), __fp16(0.2)); bool b = vceqh_f16(__fp16(atof(argv[1])), __fp16(0.2)); return (int)hu + (int)b; }" TLFLOAT_COMPILER_SUPPORTS_ARM_FP16) set(CMAKE_REQUIRED_FLAGS) endif() if (CMAKE_CXX_COMPILER_TARGET) set(CMAKE_REQUIRED_FLAGS "--target=${CMAKE_CXX_COMPILER_TARGET}") endif() CHECK_CXX_SOURCE_COMPILES(" #include #include #include int main(int argc, char **argv) { __fp16 a = (__fp16)(float)atof(argv[1]); __uint16_t u = std::bit_cast<__uint16_t>(a); a = std::bit_cast<__fp16>(u); return (float)a; } " TLFLOAT_COMPILER_SUPPORTS_FP16) CHECK_CXX_SOURCE_COMPILES(" #include #include #include int main(int argc, char **argv) { __bf16 a = (__bf16)(float)atof(argv[1]); __uint16_t u = std::bit_cast<__uint16_t>(a); a = std::bit_cast<__bf16>(u); return (float)a; } " TLFLOAT_COMPILER_SUPPORTS_BF16) CHECK_CXX_SOURCE_COMPILES(" #include #include #ifndef __GLIBC__ #error GLIBC macro not defined #endif int main(int argc, char **argv) {}" BUILDING_WITH_GLIBC) set(CMAKE_REQUIRED_FLAGS) if (LIB_MPFR) if (CMAKE_CXX_COMPILER_TARGET) set(CMAKE_REQUIRED_FLAGS "--target=${CMAKE_CXX_COMPILER_TARGET}") endif() set(CMAKE_REQUIRED_LIBRARIES ${LIB_MPFR}) CHECK_CXX_SOURCE_COMPILES(" #define MPFR_WANT_FLOAT128 #include int main() {}" TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) CHECK_CXX_SOURCE_COMPILES(" #include int main() { mpfr_t mx; mpfr_sinpi(mx, mx, GMP_RNDN); }" TLFLOAT_ENABLE_MPFR_SINPI) set(CMAKE_REQUIRED_LIBRARIES) set(CMAKE_REQUIRED_FLAGS) endif() if (TLFLOAT_COMPILER_SUPPORTS_FLOAT128) if (CMAKE_CXX_COMPILER_TARGET) set(CMAKE_REQUIRED_FLAGS "--target=${CMAKE_CXX_COMPILER_TARGET}") endif() set(CMAKE_REQUIRED_LIBRARIES quadmath) CHECK_CXX_SOURCE_COMPILES(" #include #include int main(int argc, char **argv) { __float128 f = atof(argv[1]); printf(\"%g\", (double)sinq(f)); }" TLFLOAT_ENABLE_LIBQUADMATH) set(CMAKE_REQUIRED_LIBRARIES) set(CMAKE_REQUIRED_FLAGS) endif() # Setting up memory-leak checks include(CTest) set(MEMORYCHECK_COMMAND_OPTIONS "--leak-check=full --error-exitcode=1") if (ENABLE_VALGRIND AND NOT CMAKE_CROSSCOMPILING) find_program(VALGRIND "valgrind") message(STATUS "VALGRIND : " ${VALGRIND}) endif() # Compiler options if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fcompare-debug-second -fconstexpr-ops-limit=1000000000 -fno-math-errno") set(INLINE_CXX_FLAGS "--inline-limit=1000000") set(NOEXCEPT_CXX_FLAGS "-fno-exceptions;-fno-rtti") if(CMAKE_SYSTEM_PROCESSOR MATCHES "i[3-6]86") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -msse2") endif() set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -Og") if (ENABLE_ASAN) if(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm64|aarch64)") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=hwaddress -static-libasan -fno-exceptions") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=hwaddress -static-libasan") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -static-libasan -fno-exceptions") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -static-libasan") endif() endif() if (COMMAND_GOLD) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold") endif() elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT WIN32) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fconstexpr-steps=1000000000 -fno-math-errno") set(INLINE_CXX_FLAGS "-mllvm;-inline-threshold=100000") set(NOEXCEPT_CXX_FLAGS "-fno-exceptions;-fno-rtti") if(CMAKE_SYSTEM_PROCESSOR MATCHES "i[3-6]86") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -msse2") endif() set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -Og") if (ENABLE_ASAN) if(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm64|aarch64)") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=hwaddress") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=hwaddress") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") endif() endif() elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND WIN32) get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME_WE) string(TOLOWER "${COMPILER_BASENAME}" LC_COMPILER_BASENAME) if ("${LC_COMPILER_BASENAME}" STREQUAL "clang-cl") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /clang:-fconstexpr-steps=1000000000") set(INLINE_CXX_FLAGS "/clang:-mllvm;/clang:-inline-threshold=100000") set(NOEXCEPT_CXX_FLAGS "") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fconstexpr-steps=1000000000 -fno-math-errno") set(INLINE_CXX_FLAGS "-mllvm;-inline-threshold=100000") set(NOEXCEPT_CXX_FLAGS "-fno-exceptions;-fno-rtti") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -Og") endif() elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /constexpr:steps1000000000") set(INLINE_CXX_FLAGS "") set(NOEXCEPT_CXX_FLAGS "") endif() string(TOLOWER "${CMAKE_BUILD_TYPE}" LC_CMAKE_BUILD_TYPE) if (WIN32) add_compile_definitions(_CRT_SECURE_NO_WARNINGS=1 _CRT_NONSTDC_NO_DEPRECATE=1) endif() if (NOT "${LC_CMAKE_BUILD_TYPE}" STREQUAL "release") add_compile_definitions(DEBUG=1) endif() if (NOT ENABLE_ARCH_OPTIMIZATION) add_definitions(-DTLFLOAT_DISABLE_ARCH_OPTIMIZATION) endif() if (ENABLE_LTO) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) endif() # Setting up for coverage report if (ENABLE_COVERAGE) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -fprofile-arcs -ftest-coverage") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -fprofile-arcs -ftest-coverage") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT WIN32) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-instr-generate -fcoverage-mapping") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping") endif() endif() # Setting up Doxygen if (ENABLE_DOXYGEN AND NOT WIN32) find_package(Doxygen) if (DOXYGEN_FOUND) configure_file("${PROJECT_SOURCE_DIR}/doxygen.conf.in" "${CMAKE_BINARY_DIR}/doxygen.conf" @ONLY) add_custom_target(doc_doxygen ALL COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/doxygen.conf" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM ) install( DIRECTORY "${CMAKE_BINARY_DIR}/doc_doxygen/" DESTINATION "${INSTALL_PREFIX}doc_doxygen" MESSAGE_NEVER COMPONENT tlfloat_Documentation ) endif() endif() # if (ENABLE_INTSQRT) set(TLFLOAT_ENABLE_INTSQRT True) endif() configure_file("${PROJECT_SOURCE_DIR}/src/include/tlfloat/tlfloatconfig.hpp.in" "${PROJECT_BINARY_DIR}/include/tlfloat/tlfloatconfig.hpp" @ONLY) configure_file("${PROJECT_SOURCE_DIR}/src/include/detect.h.in" "${PROJECT_BINARY_DIR}/include/detect.h" @ONLY) # Install CMake package config if (FALSE) # Currently disabled because I still don't fully understand how this works include(CMakePackageConfigHelpers) write_basic_package_version_file( tlfloatConfigVersion.cmake VERSION "${TLFLOAT_VERSION}" COMPATIBILITY SameMajorVersion ) install( EXPORT tlfloatTargets FILE tlfloatConfigVersion.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/tlfloat" COMPONENT tlfloat_Development ) install( EXPORT tlfloatTargets NAMESPACE tlfloat:: DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/tlfloat" COMPONENT tlfloat_Development ) endif() # add_subdirectory("src") # Show status if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "") message(STATUS "CMAKE_BUILD_TYPE : " ${CMAKE_BUILD_TYPE}) endif() tlfloat-1.15.0/CODE_OF_CONDUCT.md000066400000000000000000000667601477036600700160730ustar00rootroot00000000000000 # Community Guidelines for Sustainability of Open-Source Ecosystem Version 1.0.1, 2024-12-29 Copyright Naoki Shibata 2024. https://github.com/shibatch/nofreelunch This document is licensed under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/). ## Preface ### Free-riding and the burnout problem of OSS developers First of all, I would like to start by explaining a few economic concepts. Suppose you have paid to buy a hamburger. Then, of course, that hamburger is yours and you have all the right to decide what to do with it. You can eat all the hamburger without sharing it with your friends. But what if you are paying for flood control, i.e., the maintenance of rivers? Flood control is essential to building a modern city, but it is almost impossible to limit the people who will benefit from flood control. If you pay for the maintenance of the river, your friends will automatically benefit from it too. Goods and services such as parks, public roads, fire protection, police, flood control and knowledge are called public goods. A public good is defined as a good that is both non-excludable (anyone can access it) and non-rivalrous (one person’s use does not prevent another’s use). The cost of preventing people from using public goods is significantly high and it is difficult to collect a price for their use. If someone bears the cost and provides a public good, those who do not bear the cost can also receive the benefit. As a result, the incentive to bear the cost of providing public goods does not work, and everyone tries to get a free ride. In economics, a free rider is someone who enjoys a benefit without paying for it. OSS and free software (hereafter, OSS and free software are collectively referred to as FOSS) are public goods because they are both non-excludable and non-rivalrous, and thus they are being free-ridden by a large number of people and companies. It is undeniable that FOSS has become popular because they can be free-ridden as much as people want. But, development and maintenance of FOSS cannot proceed unless someone contributes resources. If no user pays for it, it is a natural consequence that maintenance will eventually cease to continue, which in essence means that the FOSS ecosystem is not sustainable. FOSS developers have little or no financial incentive to continue maintenance and development. As a result, FOSS developers tend to stop maintaining their projects much sooner than users expect, often abruptly. This problem is called the FOSS developer "burnout" problem. To make the FOSS ecosystem sustainable, the cost of maintenance must continue to be supplied from somewhere. Downloading software may seem like less of an incentive to pay a fee because you cannot see the face of the developer and the software is only information and not substance. However, there are real people involved in the development and maintenance of the software, and real resources are committed for this purpose. Needless to say, the burden of those costs should not be placed on the developers and maintainers. ### Lack of funds is not the cause of the problem Let me explain in simpler language. Imagine that you are offered a free lunch somewhere. In such a case, a rather large number of people would say, "Who is covering the cost of this lunch? Let me bear the cost of what I eat." But when it comes to using FOSS, the number of such people is much smaller. For some reason, people take it for granted that I provide a free lunch and that everyone else should receive the lunch I provide without paying for it. And then there are those who sell what is provided free of charge to others at a price. Certainly, as a free lunch provider, I don't forbid that, but isn't that making too much use of the generosity? If I ask those people to donate, sometimes they do, but often they look at me as if donating is something special. And when I stop offering free lunch, people say I have "burned out." Is it appropriate to call it “burnout” that I have run out of ingredients to prepare a free lunch? It doesn't have to be me who provides the ingredients for the free lunch, does it? It would be fine if the others could supply all the ingredients and prepare all the lunches instead, but this usually doesn't happen. Because the lunches prepared by others are not that tasty. Or they don't want to provide such a good lunch for free. If those who are making a profit give some of it back, then I can continue to offer free lunches. I think everyone would be happier that way, don't you? The problem of developer "burnout" becomes a problem because there is still commercial value in the software. If the software has no value anymore, it would not be called "burnout." In such a case, the project simply "fades away" without anyone noticing. If no one needs free lunch anymore, then no one will have a problem when I stop providing free lunch. In other words, the reason developers "burn out" is not because the funds are nowhere to be found, but because the funds do not reach them. In some cases, companies are making huge profits by using FOSS. If we can get these funds to reach the developers, the problem can be solved. ### Noncommercial license does not solve the problem Some may argue that if that is the case, then I should just make the license noncommercial. However, if I prohibit commercial use, even if conditionally, adopting the software will require complex deliberations within the company. The story is relatively simple if the number of computers that will run the software is known in advance and only that number of licenses need to be purchased. However, the use of FOSS is not limited to this. One of the advantages of FOSS is that it can be easily adopted when the number of computers running the software is not known in advance. If a license server were to be set up to monitor software usage, there would be increased hassles with server maintenance and security. If the company is required to pay, for example, a certain percentage of the profits earned, the paperwork for this would become cumbersome, and it would be necessary to publish the figures on which the payment is based. Here, I would like to explain another concept in economics. Consider the case where farmers graze cows on pastureland. If there are too many cows, the pasture will become desolate. If the pasture is owned by one farmer, he/she adjusts the number of cows so that the pasture does not become desolate. However, if a pasture is owned by multiple farmers, there is no advantage in reducing the number of cows because if one farmer reduces the number of cows, the others would increase it. Therefore, each farmer tries to increase the number of cows to maximize his/her own profit. As a result, the pastureland becomes desolate due to the fact that it is common land. This is called the tragedy of the commons. Companies are, after all, organizations that try to maximize shareholder profit. They try to use as much free stuff as possible, while they are less likely to use software that is not free for commercial use because of the complicated procedures to use it. There used to be many free-of-charge software products that prohibited commercial use, but many of them were not used much and eventually abandoned. In other words, whether the license prohibits commercial use or not, the developers will not be paid after all. From a different perspective, this means that the pasture of FOSS developers is being exploited until it becomes desolate. Even if each company is aware of the fact that it is exploiting FOSS developers, it has little incentive to stop, because even if one company stops, others will continue, and the result will be the same. Thus, it is unlikely that a company will voluntarily offer to make a donation, because even if only their company makes a donation, the result will not be much different if other companies do not also make donations. This structure of the problem is the same as the tragedy of the commons. A license that prohibits commercial use does not solve this problem. FOSS developers have to go around on their own to find companies that use their software and ask them for donations. There is no way to even know what a reasonable donation amount would be. In order to maximize shareholder profit, companies tend to refrain from activities that would benefit other companies, and as a result, they are often reluctant to contribute to society as a whole. Often a company needs a particular reason as to why it makes a particular contribution. In other words, a company needs an explanation of how its contribution will specifically benefit the company. However, most FOSS products are not designed to benefit a specific company. FOSS projects cannot be run only by members who participate from companies who think only of their own convenience. It is not surprising that contributions made under a declaration that only contributions beneficial to a particular organization can be made are less appreciated. ### Code of conduct comes to rescue To begin with, the general public only understands that FOSS is software that can be used for free, and there is no recognition that the general public is free-riding on various resources provided by developers. There is a general lack of awareness that if everyone continues to free-ride, those resources will quickly run out and the project will not last long. On the other hand, companies need a reason to pay for software that is labeled as free to use. In other words, there must be some logical framework for the manager to persuade his or her bosses to do this. For FOSS developers, the only place to write such a prohibition on free-riding was in the distribution license. However, since the distribution license is legally binding, even the slightest restriction on the conditions of use would prevent people from using the software, as mentioned above. Codes of conduct are not considered legally binding, and their contents are often unchecked by corporate legal departments. Nevertheless, their contents are similar to rules, and they are presented alongside distribution licenses. Incorporating a code of conduct into FOSS has already been established to some extent. Originally, a code of conduct was a series of practices that a company requires its employees to adhere to. Since this has expanded to FOSS projects, we can expect that there is little risk of companies completely ignoring it. A code of conduct is a set of rules that defines the normative behavior and responsibilities of individuals, parties, and groups. In other words, a code of conduct is a definition of the behaviors of members that are desirable and undesirable for a project. By having each member in the project agree to a code of conduct, the members are made aware that certain behaviors are undesirable for the project. In other words, members will not be able to openly engage in behavior that is undesirable for the project. Since a code of conduct is not legally binding, members would be able to continue to participate in the project without agreeing to the code of conduct or while violating it. However, even in that case, the fact that a particular member did not agree to or violated the code of conduct is visible. The purpose of having members make a pledge not to engage in undesirable behavior is not to exclude members who disagree or violate the code from the project, but to make other members aware of it. This allows the "name and shame" approach to discourage members from taking undesirable actions. If a particular member engages in an undesirable behavior, other members become aware of it, and the member with the undesirable behavior is excluded from participation in the overall decision-making process of the project. In other words, members with undesirable behavior will have difficulty participating in decision-making within the project. This assumes, of course, that members do not lie. ### How our guidelines work Community Guidelines for Sustainability of Open-Source Ecosystem are a code of conduct aiming to alleviate the burnout problems of FOSS developers. Our guidelines use the nature of the code of conduct described above to discourage free-riding on FOSS projects. Since a code of conduct defines desirable and undesirable behaviors of project members, it is not possible to directly ask companies to comply with the code. Therefore, our guidelines ask members representing a company to pledge that they will make effort to ensure that the company to which they belong does not free-ride. If a member's company continues to free-ride, that member can be regarded as not making sufficient efforts to ensure that the company does not free-ride. In addition, our guidelines do not require only that each company does not free-ride on projects that have adopted our guidelines, but also that they do not free-ride on FOSS projects in general. As there becomes greater public awareness of the importance of discouraging free-riding in order to sustain FOSS projects, it will become more difficult for companies to openly disagree with our guidelines. As more projects adopt our guidelines, we can expect that free-riding on FOSS projects in general will be discouraged. Now, based on the above, will this scheme really work? What is most concerning is the part that although prohibiting commercial use of software in a distribution license does not work, discouraging free-riding in a code of conduct will work. The reason why prohibiting commercial use does not work is that it requires a lot of internal deliberation and procedures within the company before the software can be used, and a budget must be set aside to purchase the software license at this point. Distribution licenses are supposed to be legally binding, which is incompatible with asking licensees to take some action without legally binding them to do so. On the other hand, a code of conduct, by its very nature, only prescribes the desired behavior of project members, not the conditions for the use of the software. The existence of a code of conduct makes it possible to check whether each member is behaving in a way that is desirable for the project. If companies continue to free-ride on FOSS, this will become visible to the public and subject to social criticism. It would be a serious PR loss for a company if it were to make the news that the company gets disciplined in a prominent FOSS project. Therefore, we can expect that companies will voluntarily make contributions even without a request from the project side. One of the purposes of creating new guidelines is to lower the workload on the maintainers. Adopting our guidelines will only require little work on the project. What is required in the project is to ensure transparency in project management so that public scrutiny can be conducted. Our guidelines will not work well if the public thinks that opaque decisions made within the project are inevitable because they were made for some reason that cannot be disclosed. For the guidelines to work well, the public must be able to judge the appropriateness of each decision made within the project. Transparency in project management would also have positive results in terms of ensuring diversity in the project. What our guidelines require is that each member takes action to discourage free-riding. Thus, even if a member's company is free-riding, that company will not be immediately denounced. A company's free-riding will only be brought to attention if it becomes a problem over some extended period of time. For companies, it is only when their own employees participate in a project that they need to comply with the intent of the code of conduct, which is usually long after the company has started using the software. Thus, the use of the software itself can be started easily, and minor violations can be tolerated. In addition, companies can decide the budget for their contribution to FOSS projects on their own discretion. At first glance, this might seem to mean that companies can continue to free-ride without worrying about the guidelines by silently allowing their employees to continue using the software without having them participate in the project. However, for companies that use FOSS extensively, not being involved in FOSS projects at all would cause various practical disadvantages. In addition, if the status of FOSS use and contribution to the project by each company becomes clear, the existence of large FOSS user companies that continue to free-ride in silence will naturally emerge. This may also mean that little-known companies will not be subject to much public scrutiny, and only well-known companies that use FOSS on a large scale will be significantly affected by the guidelines. However, this has the advantage of supporting companies that use FOSS on a small scale, thereby expanding the use of FOSS. Rather than going around pointing out every minor violation, we can expect to bring long-term benefits to the FOSS ecosystem by fostering companies that use FOSS on a large scale. What is important is visibility into the use of FOSS in each company, and for this purpose, it may be reasonable to mandate a usage indication in the distribution license. You might be wondering why our guidelines target only companies, even though individuals are also free-riding. This is due to the limitations of how our guidelines work. The basic stance of our guidelines is to request uniformly the same content regardless of whether the member belongs to a company or not. This is because confusion arises in the definition of the terms if we try to distinguish between companies and individuals. If members participating as individuals were asked to donate to the project, they would effectively be excluded from participating in the project. Thus, all that a member participating as an individual can do to deter free-riding is to call out to their friends not to free-ride, which is effectively the same as doing nothing. If donations were collected from individual users in a thin and broad base, the total amount could be large. However, it would be too costly to track the amount of each individual user's donation, and it would be difficult to establish a practical mechanism for this purpose. You might also wonder whether educational and research institutions are also included in the scope of free-ride deterrence. It is ultimately public scrutiny that determines whether the objectives of the guidelines are being followed. Also, the project has its own policy and philosophy independent of this. Educational and research institutions are generally believed to support FOSS operations directly or indirectly by the nature of their work. Thus, it can be assumed that whether they are taking specific actions to deter free-riding is not an issue. In reality, however, in many cases, even educational and research institutions do not support FOSS operations in their work content. Some institutions clearly disregard their contribution to FOSS projects. In such cases, free-riding should be considered a problem even for educational and research institutions. In addition, if FOSS plays an important role in a research project with a large research budget, it is only natural that the research project should make a commensurate contribution to the associated FOSS project. When applying for a research budget, the cost of the contribution to the relevant projects of the FOSS to be used in the research should be accounted for. I hope that the status of support for FOSS by educational and research institutions, including indirect ones, will become visible. There is another reason why companies should pay for the maintenance of FOSS. Public goods such as flood control and public road construction are usually paid for by taxpayers. However, if we try to do the same with FOSS maintenance, we will undoubtedly see terrible results. Because it is difficult to evaluate which FOSS is useful, large amounts of taxpayer money will be spent on maintenance of software that no one has ever heard of. There is also a problem that it is difficult to coordinate among the countries to which the members belong, since the development of FOSS takes place across countries. By having companies fund software that is valuable to them, we can expect that truly valuable software will be funded. ## Positioning and purpose of the guidelines Our guidelines summarize the standards of practice that the participating members of the project are expected to follow in order to facilitate the promotion and operation of the project. Our guidelines are not a set of rules, and no penalties or other consequences for violations are set forth in the guidelines. However, it is possible that your opinion will not be respected within the community if you disagree with or violate these guidelines. Since there is no provision in the software distribution license prohibiting the removal of the guidelines in a derivative project, you can fork the project to remove the guidelines. The guidelines ask members representing companies to pledge that they will make efforts to ensure that their companies do not engage in free-riding. However, this is nominal and members are not actually asked to take any specific action. What actually matters is the attitude of the company to which the member belongs, not the specific actions of the member. ## The guidelines The primary purpose for establishing our guidelines is to improve the sustainability of the FOSS ecosystem by encouraging companies that directly benefit from the commercial use of OSS or free software to contribute to the relevant projects to serve society as a whole. The members of the project are asked to help raise awareness to make this happen. The second purpose is to prevent conflicts among the members. Although this project is a software development project, political discussions may be sometimes required to keep the project moving forward. Some of the guidelines summarize the items that each member is expected to follow in order to avoid conflicts among members and to promote calm and smooth discussions. ### Striving to change perceptions about the use of OSS and free software * Project members strive to promote the public awareness that use of open source or free software for free without any contribution is free-riding and if everyone continues to free-ride, the project will not last long. * Project members strive to promote awareness of the existence, philosophy, purpose, and content of these guidelines to those who directly or indirectly use open source or free software. * Project members strive to promote the awareness that it is natural for organizations that make a profit from the commercial use of open source or free software to make contribution commensurate with the increased profits from the use of the software to relevant projects, where the contribution is made in order for the project to serve society as a whole. This contribution must not be biased to benefit any specific organizations beyond the purpose or original nature of the project. On top of that, the contribution herein refers to providing the following items. * Financial support * Contributing code or documentation * Providing assistance with tasks necessary to maintain the project * Providing in-kind equipment, services, and software necessary to run the project * Providing any other items needed for the project * Project members strive to promote the awareness that organizations that benefit from the commercial use of open source or free software should voluntarily and actively offer to contribute to the projects, not wait until they are asked to do so by the projects. * Project members strive to promote that companies should give high recognition to their members who contribute to open source or free software projects on the job. * Project members strive to promote that if a company agrees with the objectives of the guidelines, it should indicate this in some way so that the public is aware of it. ### Compliance with laws * Each member should comply with the laws of his/her own place of residence. * Each member should abide by laws of his/her own place of residence even if the laws do not have penal provisions. * Each member should not follow any request of anti-social groups or cults. * The terms "antisocial organization" and "cult" herein refer to organizations officially recognized as such in each member's place of residence. The same applies hereinafter. ### Maintaining transparency in project operations * Each member in the project should disclose information regarding his or her identity and affiliation when necessary to carry out the project. In requesting disclosure of the identity and affiliation of each member, an explanation should be given as to why this is necessary to carry out the project. * In engaging in activities within the project, each member should make an effort to disclose the basis for decisions in a manner that the general public can see and understand. * If the basis for a decision cannot be disclosed, the reason why it cannot be disclosed should be explained as much as possible. * If each member notices that the basis for a decision or the reason why it cannot be disclosed has not been explained in the project, the member should prompt the person who made the decision to explain it, even if the matter is not directly related to the member's own, or if it is a past matter. ### Keeping calm and logical discussion * Each member should refrain from posting a comment that is considered likely to cause strong emotions in those who read the comment. * Each member should refrain from posting a comment that is not in line with the project's objectives. * Each member of the project should not change the way he/she treats another member for any of the following reasons. * Discriminatory reasons (attributes that were determined at the time of the person's birth and cannot be changed) * Ideology or beliefs that are not relevant to the purpose of the project * Whether or not each member belongs to an antisocial group or cult is always regarded as relevant to the purpose of the project. The project may ban a member who is found to be a member of an anti-social organization or cult for the sole reason of his/her membership in such an organization. * Inequalities that existed in the past * Each member of the project should treat another member equally at the time the action is taken. * In principle, affirmative action is not supported in this project. Imposing disadvantages on members who do not support affirmative action is production of new inequalities and should be avoided. If affirmative action must be taken, the disadvantage for it should be borne entirely by the supporters of affirmative action. ### To resolve the problem throughout the community * Each member of the project should listen sincerely to the claims of other members that there have been violations of the above items and cooperates in resolving the problem. * Project members should not leave it up to the project maintainers to resolve the problems. * The relationship between the maintainers and the other members is not that of parents and children. The maintainers only have the privileges of the websites related to the project and basically what you cannot do is not possible for the maintainers either. ### Not taking the guidelines as an absolute * Each member should understand that each item of these guidelines is merely a means to achieve the objectives of the guidelines and to respect basic human rights. * Each member should always consider first how to achieve the objectives of the guidelines and respect basic human rights, and for this purpose, allow deviations from each item of these guidelines. tlfloat-1.15.0/Jenkinsfile000066400000000000000000000246431477036600700154520ustar00rootroot00000000000000pipeline { agent { label 'jenkinsfile' } stages { stage('Preamble') { parallel { stage('x86_64 linux clang-18') { agent { label 'x86_64 && ubuntu24 && cuda' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh ''' echo "x86_64 clang-18 on" `hostname` export CC=clang-18 export CXX=clang++-18 export CUDACXX=/opt/cuda-12.6/bin/nvcc mkdir build cd build cmake -GNinja -DCMAKE_INSTALL_PREFIX=../../install -DENABLE_CUDA_TEST=True -DENABLE_LTO=True .. cmake -E time ninja export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j `nproc` ''' } } stage('x86_64 linux gcc-13') { agent { label 'x86_64 && ubuntu24' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh ''' echo "x86_64 gcc-13 on" `hostname` export CC=gcc-13 export CXX=g++-13 mkdir build cd build cmake -GNinja -DCMAKE_INSTALL_PREFIX=../../install -DENABLE_ASAN=True .. cmake -E time ninja export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j `nproc` ''' } } stage('cross-s390x linux gcc') { agent { label 'x86_64 && ubuntu24 && cuda' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh ''' echo "cross-x390x on" `hostname` mkdir build cd build cmake -GNinja .. -DCMAKE_TOOLCHAIN_FILE=../toolchains/s390x-gcc.cmake cmake -E time ninja export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j `nproc` ''' } } stage('cross-ppc64el linux clang') { agent { label 'x86_64 && ubuntu24 && cuda' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh ''' echo "cross-ppc64el on" `hostname` mkdir build cd build cmake -GNinja .. -DCMAKE_TOOLCHAIN_FILE=../toolchains/ppc64el-llvm.cmake cmake -E time ninja export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j `nproc` ''' } } stage('x86_64 linux emscripten') { agent { label 'x86_64 && ubuntu24 && emscripten' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh '''#!/bin/bash set -e echo "emscripten on" `hostname` ~/opt/emsdk/emsdk install latest ~/opt/emsdk/emsdk activate latest source ~/opt/emsdk/emsdk_env.sh mkdir build cd build cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DSET_COMPILER_SUPPORTS_INT128=False -DSET_COMPILER_SUPPORTS_FLOAT128=False -DSET_LONGDOUBLE_IS_FLOAT128=False -DENABLE_INTSQRT=True .. cmake -E time ninja export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j `nproc` ''' } } stage('x86_64 freebsd clang') { agent { label 'x86_64 && freebsd' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh ''' echo "x86_64 freebsd on" `hostname` mkdir build cd build cmake -GNinja -DCMAKE_INSTALL_PREFIX=../../install -DENABLE_ASAN=False .. cmake -E time ninja export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j `nproc` ''' } } stage('aarch64 linux gcc-14') { agent { label 'aarch64 && ubuntu24' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh ''' echo "aarch64 gcc-14 on" `hostname` export CC=gcc-14 export CXX=g++-14 mkdir build cd build cmake -GNinja -DCMAKE_INSTALL_PREFIX=../../install .. cmake -E time oomstaller ninja -j `nproc` export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j `nproc` ''' } } stage('aarch64 linux clang-19') { agent { label 'aarch64 && ubuntu24' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh ''' echo "aarch64 clang-19 on" `hostname` export CC=clang-19 export CXX=clang++-19 mkdir build cd build cmake -GNinja -DCMAKE_INSTALL_PREFIX=../../install -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld-19" -DENABLE_ASAN=True .. cmake -E time oomstaller ninja -j `nproc` export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j `nproc` ''' } } stage('arm32 linux gcc-12') { agent { label 'armv7 && debian12' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh ''' echo "arm32 gcc-12 on" `hostname` export CC=gcc-12 export CXX=g++-12 mkdir build cd build cmake -GNinja -DCMAKE_INSTALL_PREFIX=../../install .. cmake -E time oomstaller ninja -j `nproc` export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j `nproc` ''' } } stage('x86_64 windows vs2022') { agent { label 'windows11 && vs2022' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm bat """ call "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat" if not %ERRORLEVEL% == 0 exit /b %ERRORLEVEL% call "winbuild-msvc.bat" -DCMAKE_BUILD_TYPE=Release if not %ERRORLEVEL% == 0 exit /b %ERRORLEVEL% ctest -j 4 --output-on-failure exit /b %ERRORLEVEL% """ } } stage('x86_64 windows clang') { agent { label 'windows11 && vs2022' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm bat """ call "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat" if not %ERRORLEVEL% == 0 exit /b %ERRORLEVEL% call "winbuild-clang.bat" -DCMAKE_BUILD_TYPE=Release if not %ERRORLEVEL% == 0 exit /b %ERRORLEVEL% ctest -j 4 --output-on-failure exit /b %ERRORLEVEL% """ } } stage('x86_64 windows clang-cl') { agent { label 'windows11 && vs2022' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm bat """ call "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat" if not %ERRORLEVEL% == 0 exit /b %ERRORLEVEL% call "winbuild-clang-cl.bat" -DCMAKE_BUILD_TYPE=Release exit /b %ERRORLEVEL% """ } } /* stage('aarch64 macos gcc-13') { agent { label 'macos' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh ''' eval "$(/opt/homebrew/bin/brew shellenv)" export CC=gcc-13 export CXX=g++-13 mkdir build cd build cmake -GNinja -DCMAKE_INSTALL_PREFIX=../../install -DBUILD_BENCH=True -DENABLE_INLINING=True .. cmake -E time ninja export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j 8 ''' } } */ stage('aarch64 macos clang-17') { agent { label 'macos' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh ''' eval "$(/opt/homebrew/bin/brew shellenv)" export CC=/opt/homebrew/opt/llvm@17/bin/clang-17 export CXX=/opt/homebrew/opt/llvm@17/bin/clang++ mkdir build cd build cmake -GNinja -DCMAKE_INSTALL_PREFIX=../../install -DBUILD_BENCH=True -DENABLE_INLINING=True .. cmake -E time ninja export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j 8 cd .. mkdir build2 cd build2 cmake -GNinja -DCMAKE_INSTALL_PREFIX=../../install2 -DBUILD_LIBS=False -DBUILD_UTILS=False .. cmake -E time ninja export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j 8 ''' } } stage('i386 linux gcc-12') { agent { label 'i386 && debian12' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh ''' echo "i386 gcc-12 on" `hostname` export CC=gcc-12 export CXX=g++-12 mkdir build cd build cmake -GNinja -DCMAKE_INSTALL_PREFIX=../../install .. cmake -E time ninja export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j `nproc` ''' } } stage('riscv linux gcc-13') { agent { label 'riscv && ubuntu23' } options { skipDefaultCheckout() } steps { cleanWs() checkout scm sh ''' echo "riscv gcc-13 on" `hostname` export CC=gcc-13 export CXX=g++-13 mkdir build cd build cmake -GNinja -DCMAKE_INSTALL_PREFIX=../../install .. cmake -E time oomstaller ninja -j `nproc` export CTEST_OUTPUT_ON_FAILURE=TRUE ctest -j `nproc` ''' } } } } } } tlfloat-1.15.0/LICENSE.txt000066400000000000000000000024721477036600700151050ustar00rootroot00000000000000Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. tlfloat-1.15.0/README.adoc000066400000000000000000000213571477036600700150520ustar00rootroot00000000000000== TLFloat - C++ template library for floating point operations Original distribution site : https://github.com/shibatch/tlfloat Doxygen-generated reference : https://shibatch.github.io/tlfloat-doxygen/ Some more documataion is available at : https://github.com/shibatch/tlfloat/wiki === Introduction This library implements C{pp} classes with which half, single, double, quadruple and octuple precision IEEE 754 floating point numbers can be operated. Internally, these classes are implemented as class templates on top of arbitrary-precision integer class templates so that the templates are expanded as arbitrary precision floating-point operations by just changing the template parameters, rather than implementing each floating-point operation for each precision. The arbitrary-precision integer class templates are also included in this library. === Features * Truly constexpr functions ** Compilable with C{pp}20 standard ** Most of the functions are implemented as templates *** Completely inlinable functions *** The functions can be evaluated at compile time ** No malloc required ** Works without libstdc{pp} * IEEE 754 compliant ** Supports subnormal numbers, NaN, infinity, and signed zero * Supports a wide range of precisions ** Half, float, double, quad, and octuple precisions ** Returns correctly rounded results for arithmetic oprations, fma and sqrt ** Returns 1-ulp accuracy results for other math.h functions *** All functions, including trigonometric functions, return 1ulp-accuracy results for all input range * Portable ** Compatible with Linux, Windows, microcontrollers, wasm, CUDA (version 12 or later) ** Constexpr functions can be called from CUDA devices with –expt-relaxed-constexpr compiler option * C/C{pp}11 API with libquadmath emulation ** Most of libquadmath functions can be used on x86_64 clang and MSVC ** 128-bit integer types can be used on MSVC ** C{pp}11 FP and int classes with overloaded operators are provided *** C{pp}11 functions in TLFloat are not constexpr * Moderately optimized ** Optimized for each architecture using intrinsics, etc. ** Library design allows compilers to fully inline operations ** All functions are thread-safe and reentrant * Implements most of the math.h functions ** Arithmetic operations, comparison, cast operations ** fma, sqrt, hypot, cbrt, fmod, remainder, remquo ** sin, cos, tan, sinpi, cospi, tanpi ** asin, acos, atan, atan2 ** log, log2, log10, log1p ** exp, exp2, exp10, expm1, pow ** sinh, cosh, tanh, asinh, acosh, atanh ** erf, erfc, tgamma ** trunc, floor, ceil, round, rint ** fabs, copysign, fmax, fmin, fdim ** ldexp, frexp, modf, nextafter ** isnan, isinf, finite, fpclassify, signbit * Implements I/O functions ** Conversion to/from C strings ** printf-family functions * Provides BigInt template classes in addition to the FP classes ** It provides operations for integers of artibrary length (2^N bits) ** They can be used in the similar way to the ordinary int/uint types ** Data formats are the same as ordinary int/uint ** These classes are internally used to implement the FP classes in TLFloat === How to build [arabic] . Check out the source code from our GitHub repository : `++git clone https://github.com/shibatch/tlfloat++` . Make a separate directory to create an out-of-source build : `++cd tlfloat && mkdir build && cd build++` . Run cmake to configure the project : `++cmake .. -DCMAKE_INSTALL_PREFIX=../../install++` . Run make to build and install the project : `make && make install` === Compiling hello world example Below is a simple C{pp} source code utilizing TLFloat. [source,c++] ---- #include #include #include using namespace tlfloat; Octuple machin() { return 4 * (4 * atan(1 / Octuple(5)) - atan(1 / Octuple(239))); } int main(int argc, char **argv) { std::cout << std::setprecision(70) << machin() << std::endl; } ---- To compile this source code, use the following command. [source,console] ---- g++ -std=c++20 -I./install/include hello.cpp ---- You have to specify C{pp}20 standard. Note that you do not need to link any library in this example. This program computes PI in octuple precision and shows it. [source,console] ---- $ ./a.out 3.141592653589793238462643383279502884197169399375105820974944592307816 ---- === Libquadmath emulation In gcc/g{pp} on x86_64 architecture, libquadmath provides math functions for quadruple precision floating point numbers. However, libquadmath is not available with clang or Visual Studio. By using the libquadmath emulation feature of TLFloat library, it is possible to use most of the features of libquadmath with clang and Visual Studio. Below is a simple C source code utilizing this feature. [source,c++] ---- #include #include #define TLFLOAT_LIBQUADMATH_EMULATION #include int main(int argc, char **argv) { if (argc < 3) exit(-1); __float128 q1 = strtoflt128(argv[1], NULL); __float128 q2 = strtoflt128(argv[2], NULL); char str[256]; quadmath_snprintf(str, sizeof(str), "%.30Qg", powq(q1, q2)); puts(str); } ---- To compile this source code, use the following command. [source,console] ---- clang quad.c -I./install/include -L./install/lib -ltlfloat -lm ---- Below is an example of executing this program. [source,console] ---- $ ./a.out 1.234 2.345 1.63732181977903314975233575019 ---- In order to use the libquadmath emulation feature, define TLFLOAT_LIBQUADMATH_EMULATION macro, include tlfloat/tlfloat.h instead of quadmath.h, and link with -ltlfloat -lm. If you need portability, replace __float128 with tlfloat_quad. === C++11 API Besides the C{pp}20 API, TLFloat provides classes that can be used with C{pp}11 standard. Below is a simple C{pp} source code utilizing this feature. [source,c++] ---- #include #include tlfloat_octuple AGM(int N) { tlfloat_octuple y = tlfloat_sqrto(2) - 1; tlfloat_octuple a = y * y * 2; for(int k=0;k *toHexString to_string_d \ TLFloat*::getUnpacked detail::UnpackedFloat \ TLFLOAT_OVERLOAD_OP2 TLFLOAT_OVERLOAD_CMP TLFLOAT_OVERLOAD_CMPQ \ TLFLOAT_OVERLOAD_OP2I TLFLOAT_OVERLOAD_CMPI TLFLOAT_OVERLOAD_OP2Q EXAMPLE_PATH = EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO FILTER_SOURCE_PATTERNS = USE_MDFILE_AS_MAINPAGE = README.md SOURCE_BROWSER = NO INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO REFERENCES_LINK_SOURCE = YES SOURCE_TOOLTIPS = YES USE_HTAGS = NO VERBATIM_HEADERS = NO CLANG_ASSISTED_PARSING = NO CLANG_OPTIONS = CLANG_DATABASE_PATH = ALPHABETICAL_INDEX = YES IGNORE_PREFIX = GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = HTML_COLORSTYLE_HUE = 220 HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_GAMMA = 80 HTML_DYNAMIC_MENUS = YES HTML_DYNAMIC_SECTIONS = NO HTML_INDEX_NUM_ENTRIES = 100 GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project DOCSET_PUBLISHER_ID = org.doxygen.Publisher DOCSET_PUBLISHER_NAME = Publisher GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO CHM_INDEX_ENCODING = BINARY_TOC = NO TOC_EXPAND = NO GENERATE_QHP = NO QCH_FILE = QHP_NAMESPACE = org.doxygen.Project QHP_VIRTUAL_FOLDER = doc QHP_CUST_FILTER_NAME = QHP_CUST_FILTER_ATTRS = QHP_SECT_FILTER_ATTRS = QHG_LOCATION = GENERATE_ECLIPSEHELP = NO ECLIPSE_DOC_ID = org.doxygen.Project DISABLE_INDEX = NO GENERATE_TREEVIEW = NO ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 FORMULA_MACROFILE = USE_MATHJAX = NO MATHJAX_FORMAT = HTML-CSS MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/ MATHJAX_EXTENSIONS = MATHJAX_CODEFILE = SEARCHENGINE = YES SERVER_BASED_SEARCH = NO EXTERNAL_SEARCH = NO SEARCHENGINE_URL = SEARCHDATA_FILE = searchdata.xml EXTERNAL_SEARCH_ID = EXTRA_SEARCH_MAPPINGS = GENERATE_LATEX = YES LATEX_OUTPUT = latex LATEX_CMD_NAME = MAKEINDEX_CMD_NAME = makeindex LATEX_MAKEINDEX_CMD = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4 EXTRA_PACKAGES = LATEX_HEADER = LATEX_FOOTER = LATEX_EXTRA_STYLESHEET = LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO LATEX_BIB_STYLE = plain LATEX_EMOJI_DIRECTORY = GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_SUBDIR = MAN_LINKS = NO GENERATE_XML = NO XML_OUTPUT = xml XML_PROGRAMLISTING = YES XML_NS_MEMB_FILE_SCOPE = NO GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook GENERATE_AUTOGEN_DEF = NO GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = TLFLOAT_LIBQUADMATH_EMULATION TLFLOAT_ENABLE_INT128_OPT TLFLOAT_DOXYGEN EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES DIA_PATH = HIDE_UNDOC_RELATIONS = YES HAVE_DOT = YES DOT_NUM_THREADS = 0 DOT_FONTPATH = CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO UML_LIMIT_NUM_FIELDS = 10 TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png INTERACTIVE_SVG = NO DOT_PATH = DOTFILE_DIRS = MSCFILE_DIRS = DIAFILE_DIRS = PLANTUML_JAR_PATH = PLANTUML_CFG_FILE = PLANTUML_INCLUDE_PATH = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES tlfloat-1.15.0/src/000077500000000000000000000000001477036600700140445ustar00rootroot00000000000000tlfloat-1.15.0/src/CMakeLists.txt000066400000000000000000000002101477036600700165750ustar00rootroot00000000000000add_subdirectory("tlfloat") add_subdirectory("util") if (BUILD_TESTS) add_subdirectory("tester") # tester has to come at last endif() tlfloat-1.15.0/src/include/000077500000000000000000000000001477036600700154675ustar00rootroot00000000000000tlfloat-1.15.0/src/include/detect.h.in000066400000000000000000000007501477036600700175170ustar00rootroot00000000000000#ifndef __TLFLOAT_DETECT_H_INCLUDED__ #define __TLFLOAT_DETECT_H_INCLUDED__ #cmakedefine TLFLOAT_COMPILER_SUPPORTS_INT128 #cmakedefine TLFLOAT_COMPILER_SUPPORTS_FLOAT128 #cmakedefine TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128 #cmakedefine TLFLOAT_LONGDOUBLE_IS_FLOAT128 #cmakedefine TLFLOAT_COMPILER_SUPPORTS_FP16 #cmakedefine TLFLOAT_COMPILER_SUPPORTS_BF16 #cmakedefine TLFLOAT_ENABLE_MPFR_WANT_FLOAT128 #cmakedefine TLFLOAT_ENABLE_MPFR_SINPI #cmakedefine TLFLOAT_ENABLE_LIBQUADMATH #endif tlfloat-1.15.0/src/include/psha2.hpp000066400000000000000000000111341477036600700172150ustar00rootroot00000000000000#ifndef __PSHA2_HPP_INCLUDED__ #define __PSHA2_HPP_INCLUDED__ #include #include struct PSHA2_256_Internal { // https://github.com/983/SHA-256 // This is public domain implementation of SHA256 static inline uint32_t rotr(uint32_t x, int n) { return (x >> n) | (x << (32 - n)); } static inline uint32_t step1(uint32_t e, uint32_t f, uint32_t g) { return (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) + ((e & f) ^ ((~ e) & g)); } static inline uint32_t step2(uint32_t a, uint32_t b, uint32_t c) { return (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + ((a & b) ^ (a & c) ^ (b & c)); } static inline void update_w(uint32_t *w, int i, const uint8_t *buffer) { int j; for(j = 0;j < 16;j++) { if (i < 16) { w[j] = ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) | ((uint32_t)buffer[2] << 8) | ((uint32_t)buffer[3]); buffer += 4; } else { uint32_t a = w[(j + 1) & 15]; uint32_t b = w[(j + 14) & 15]; uint32_t s0 = (rotr(a, 7) ^ rotr(a, 18) ^ (a >> 3)); uint32_t s1 = (rotr(b, 17) ^ rotr(b, 19) ^ (b >> 10)); w[j] += w[(j + 9) & 15] + s0 + s1; } } } uint32_t state[8]; uint64_t n_bits; uint8_t buffer_counter; uint8_t buffer[64]; PSHA2_256_Internal() { state[0] = 0x6a09e667; state[1] = 0xbb67ae85; state[2] = 0x3c6ef372; state[3] = 0xa54ff53a; state[4] = 0x510e527f; state[5] = 0x9b05688c; state[6] = 0x1f83d9ab; state[7] = 0x5be0cd19; n_bits = 0; buffer_counter = 0; for(int i=0;i<64;i++) buffer[i] = 0; } void block() { static const uint32_t k[] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, }; uint32_t a = state[0]; uint32_t b = state[1]; uint32_t c = state[2]; uint32_t d = state[3]; uint32_t e = state[4]; uint32_t f = state[5]; uint32_t g = state[6]; uint32_t h = state[7]; uint32_t w[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; for(int i = 0;i < 64;i += 16) { update_w(w, i, buffer); #if defined(__clang__) #pragma clang loop unroll(full) #endif for(int j = 0;j < 16;j += 4) { uint32_t temp; temp = h + step1(e, f, g) + k[i + j + 0] + w[j + 0]; h = temp + d; d = temp + step2(a, b, c); temp = g + step1(h, e, f) + k[i + j + 1] + w[j + 1]; g = temp + c; c = temp + step2(d, a, b); temp = f + step1(g, h, e) + k[i + j + 2] + w[j + 2]; f = temp + b; b = temp + step2(c, d, a); temp = e + step1(f, g, h) + k[i + j + 3] + w[j + 3]; e = temp + a; a = temp + step2(b, c, d); } } state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; state[5] += f; state[6] += g; state[7] += h; } void append_byte(uint8_t byte) { buffer[buffer_counter++] = byte; n_bits += 8; if (buffer_counter == 64) { buffer_counter = 0; block(); } } void append(const void *src, size_t n_bytes) { for(size_t i = 0;i < n_bytes;i++) { append_byte(((const uint8_t*)src)[i]); } } void appendWord(const void *src, size_t n_bytes) { #if !defined(__BYTE_ORDER__) || (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) for(size_t i = 0;i < n_bytes;i++) { append_byte(((const uint8_t*)src)[i]); } #else for(int i = int(n_bytes)-1;i >= 0;i--) { append_byte(((const uint8_t*)src)[i]); } #endif } void finalize() { uint64_t nb = n_bits; append_byte(0x80); while(buffer_counter != 64 - 8) { append_byte(0); } for(int i = 7;i >= 0;i--) { uint8_t byte = (nb >> 8 * i) & 0xff; append_byte(byte); } } void finalize_bytes(void *dst_bytes32) { uint8_t *ptr = (uint8_t*)dst_bytes32; finalize(); for(int i = 0;i < 8;i++) { for(int j = 3;j >= 0;j--) { *ptr++ = (state[i] >> j * 8) & 0xff; } } } }; #endif // #ifndef __PSHA2_HPP_INCLUDED__ tlfloat-1.15.0/src/include/suppress.hpp000066400000000000000000000026141477036600700200670ustar00rootroot00000000000000#ifdef _MSC_VER #pragma warning (disable : 4101) // unreferenced local variable #pragma warning (disable : 4244) // possible loss of data #pragma warning (disable : 4267) // possible loss of data #pragma warning (disable : 4334) // result of shift converted #pragma warning (disable : 4805) // unsafe mix of type #pragma warning (disable : 4996) // deprecation #endif #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic ignored "-Wunused" #pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wunused-function" #pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wattributes" #pragma GCC diagnostic ignored "-Wrestrict" #pragma GCC diagnostic ignored "-Wstringop-overflow" #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wformat-truncation" #pragma GCC diagnostic ignored "-Warray-bounds" #pragma GCC diagnostic ignored "-Wtautological-compare" #endif #if defined(__clang__) #pragma clang diagnostic ignored "-Wunknown-warning-option" #pragma clang diagnostic ignored "-Wunused" #pragma clang diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic ignored "-Wtautological-compare" #pragma clang diagnostic ignored "-Wunqualified-std-cast-call" #pragma clang diagnostic ignored "-Wbitwise-instead-of-logical" #pragma clang diagnostic ignored "-Wconstant-evaluated" #endif tlfloat-1.15.0/src/include/testerutil.hpp000066400000000000000000000665631477036600700204240ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "suppress.hpp" #include "psha2.hpp" #include using namespace std; using namespace tlfloat; #ifndef M_PI #define M_PI 3.141592653589793238462643383279502884 #endif class RNG { uint64_t res0 = 0, res1 = 0; uint32_t nBitsInRes = 0; public: virtual uint64_t next64() = 0; virtual uint32_t next32() { return (uint32_t)next(32); } uint64_t next(uint32_t bits) { if (bits == 64) return next64(); if (bits > nBitsInRes) { uint64_t u = next64(); res0 |= u << nBitsInRes; res1 = nBitsInRes == 0 ? 0 : (u >> (64 - nBitsInRes)); nBitsInRes += 64; } uint64_t ret = res0 & ((uint64_t(1) << bits) - 1); res0 >>= bits; res0 |= res1 << (64 - bits); res1 >>= bits; nBitsInRes -= bits; return ret; } void nextBytes(unsigned char *dst, size_t len) { while(len >= 8) { uint64_t u = next64(); for(int i=0;i<8;i++) dst[i] = (u >> (i * 8)) & 0xff; dst += 8; len -= 8; } uint64_t u = next(uint32_t(len * 8)); for(int i=0;i<(int)len;i++) dst[i] = (u >> (i * 8)) & 0xff; } #if !defined(__BYTE_ORDER__) || (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) void nextBytesW(unsigned char *dst, size_t len) { nextBytes(dst, len); } #else void nextBytesW(unsigned char * const dst, const size_t len_) { int len = len_, index = 0; while(len >= 8) { uint64_t u = next64(); for(int i=0;i<8;i++) dst[len_-1-i-index] = (u >> (i * 8)) & 0xff; index += 8; len -= 8; } uint64_t u = next(uint32_t(len * 8)); for(int i=0;i<(int)len;i++) dst[len_-1-i-index] = (u >> (i * 8)) & 0xff; } #endif unsigned clz64(uint64_t u) { unsigned z = 0; if (u & 0xffffffff00000000ULL) u >>= 32; else z += 32; if (u & 0x00000000ffff0000ULL) u >>= 16; else z += 16; if (u & 0x000000000000ff00ULL) u >>= 8; else z += 8; if (u & 0x00000000000000f0ULL) u >>= 4; else z += 4; if (u & 0x000000000000000cULL) u >>= 2; else z += 2; if (u & 0x0000000000000002ULL) u >>= 1; else z += 1; if (!u) z++; return z; } uint64_t nextLT(uint64_t bound) { if (bound == 0) return 0; unsigned b = sizeof(uint64_t)*8 - clz64(bound - 1); uint64_t r = next(b), u = uint64_t(1) << b; while(r >= bound) { r -= bound; u -= bound; while(u < bound) { r = (r << 1) | next(1); u *= 2; } } return r; } double nextDouble() { union { uint64_t u; double d; } c; c.u = next(52); c.u |= 0x3fe0000000000000ULL; return c.d; } bool nextBool() { return next(1); } virtual ~RNG() {} }; class LCG64 : public RNG { uint64_t state = 1; public: LCG64(uint64_t seed) { state = seed; for(int i=0;i<10;i++) next32(); } LCG64() { state = chrono::high_resolution_clock::now().time_since_epoch().count(); for(int i=0;i<10;i++) next32(); } uint32_t next32() { state = state * 6364136223846793005ULL + 1442695040888963407ULL; return uint32_t(state >> 32); } uint64_t next64() { uint32_t u = next32(); return u | (uint64_t(next32()) << 32); } }; class TLCG64 : public RNG { uint64_t state = 1; public: TLCG64() { state = chrono::high_resolution_clock::now().time_since_epoch().count(); for(int i=0;i<10;i++) next32(); } uint32_t next32() { uint64_t t = chrono::high_resolution_clock::now().time_since_epoch().count(); state = state * 6364136223846793005ULL + (t << 1) + 1; return uint32_t(state >> 32); } uint64_t next64() { uint32_t u = next32(); return u | (uint64_t(next32()) << 32); } }; shared_ptr createPreferredRNG() { return shared_ptr(new TLCG64()); } // #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 typedef __int128_t INT128; typedef __uint128_t UINT128; void print(char *const buf, UINT128 u) { if (u == 0) { buf[0] = '0'; buf[1] = '\0'; return; } char *p = buf; while(u != 0) { *p++ = "0123456789" [u % 10]; u /= 10; } for(char *q = buf, *r = p-1;q < r;q++, r--) { char c = *q; *q = *r; *r = c; } *p = '\0'; } string to_string(UINT128 value) { vector s((1 << 7)/3 + 2); print(s.data(), value); return string(s.data()); } string to_string(INT128 value) { vector s((1 << 7)/3 + 2); print(s.data(), value >= 0 ? value : -value); s.data()[s.size()-1] = '\0'; return (value >= 0 ? "" : "-") + string(s.data()); } ostream& operator<<(ostream &os, INT128 value) { return os << ::to_string(value); } ostream& operator<<(ostream &os, UINT128 value) { return os << ::to_string(value); } #endif // #ifdef __BIGINT_HPP_INCLUDED__ class CryptUtil { public: template static tlfloat::BigUInt genRand(tlfloat::BigUInt bound, shared_ptr rng) { tlfloat::BigUInt r = 0; if (bound == 0) { rng->nextBytesW((unsigned char *)&r, sizeof(r)); } else { unsigned b = (bound - 1).ilogbp1(); tlfloat::BigUInt u = tlfloat::BigUInt(1) << b; #if !defined(__BYTE_ORDER__) || (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) rng->nextBytesW((unsigned char *)&r, (b >> 6) << 3); #else rng->nextBytesW((unsigned char *)&r + sizeof(r) - ((b >> 6) << 3), (b >> 6) << 3); #endif r.setWord(b >> 6, rng->next(b & ((1 << 6)-1))); while(r >= bound) { r -= bound; u -= bound; while(u < bound) { r <<= 1; r.setWord(0, r.getWord(0) | rng->next(1)); u += u; } } } return r; } template static bool millerTest(shared_ptr rng, unsigned s, tlfloat::BigUInt d, const tlfloat::BigUInt& n, const tlfloat::BigUInt& recn) { tlfloat::BigUInt a = 2 + CryptUtil::genRand(n - 4, rng); tlfloat::BigUInt x = a.pow(d, n, recn); if (x == 1 || x == n - 1) return true; for(unsigned i=0;i static bool checkPrimality(const tlfloat::BigUInt& bu, shared_ptr rng, unsigned nloop=64) { if (bu == 0 || bu == 1 || bu == 4) return false; if (bu == 2 || bu == 3) return true; tlfloat::BigUInt n2 = bu, d = n2 - 1, recn = n2.reciprocal(); unsigned s = 0; while((d.getWord(0) & 1) == 0) { d >>= 1; s++; } for (unsigned i = 0;i < nloop;i++) if (!CryptUtil::millerTest(rng, s, d, n2, recn)) return false; return true; } template static tlfloat::BigUInt genPrime(tlfloat::BigUInt bound, shared_ptr rng) { tlfloat::BigUInt u = genRand(bound, rng); u.setWord(0, u.getWord(0) | 1); for(;;) { if (checkPrimality(u, rng)) break; u += 2; } return u; } }; #ifdef __TLFLOAT_H_INCLUDED__ #ifdef TLFLOAT_INT128_IS_STRUCT ostream& operator<<(ostream &os, tlfloat_int128_t value) { return os << tlfloat::to_string(value); } ostream& operator<<(ostream &os, tlfloat_uint128_t value) { return os << tlfloat::to_string(value); } #endif bool equal(tlfloat_int128_t b0, BigInt<7> i0) { bool b = int64_t(b0 >> 64) == int64_t(i0 >> 64) && int64_t(b0 & (tlfloat_int128_t)~uint64_t(0)) == int64_t(i0 & BigInt<7>(~uint64_t(0))); if (!b) { cerr << "tlfloat_int128 : " << b0 << endl; cerr << "BigInt<7> : " << i0 << endl; } return b; } bool equal(tlfloat_uint128_t b0, BigUInt<7> u0) { bool b = uint64_t(b0 >> 64) == uint64_t(u0 >> 64) && uint64_t(b0 & ~uint64_t(0)) == uint64_t(u0 & BigUInt<7>(~uint64_t(0))); if (!b) { cerr << "tlfloat_uint128 : " << b0 << endl; cerr << "BigUInt<7> : " << u0 << endl; } return b; } bool equal(BigInt<7> i0, tlfloat_int128_t b0) { return equal(b0, i0); } bool equal(BigUInt<7> u0, tlfloat_uint128_t b0) { return equal(b0, u0); } #elif defined(TLFLOAT_COMPILER_SUPPORTS_INT128) bool equal(__int128_t b0, BigInt<7> i0) { bool b = int64_t(b0 >> 64) == int64_t(i0 >> 64) && int64_t(b0 & ~uint64_t(0)) == int64_t(i0 & BigInt<7>(~uint64_t(0))); if (!b) { cerr << "int128 : " << b0 << endl; cerr << "BigInt<7> : " << i0 << endl; } return b; } bool equal(__uint128_t b0, BigUInt<7> u0) { bool b = uint64_t(b0 >> 64) == uint64_t(u0 >> 64) && uint64_t(b0 & ~uint64_t(0)) == uint64_t(u0 & BigUInt<7>(~uint64_t(0))); if (!b) { cerr << "uint128 : " << b0 << endl; cerr << "BigUInt<7> : " << u0 << endl; } return b; } bool equal(BigInt<7> i0, __int128_t b0) { return equal(b0, i0); } bool equal(BigUInt<7> u0, __uint128_t b0) { return equal(b0, u0); } #endif #endif // #ifdef __BIGINT_HPP_INCLUDED__ // #ifdef QUADMATH_H #define ENABLE_QUAD typedef __float128 quad; #define M_PIq_ M_PIq std::ostream& operator<<(std::ostream &os, const __float128& f) { char buf[128]; quadmath_snprintf(buf, sizeof(buf), "%.32Qg", f); return os << std::string(buf); } #endif #ifdef TLFLOAT_LONGDOUBLE_IS_FLOAT128 #define ENABLE_QUAD typedef long double quad; #define fabsq fabsl #define fmaq fmal #define sqrtq sqrtl #define ilogbq ilogbl #define finiteq finitel #define isnanq isnanl #define isinfq isinfl #define truncq truncl #define floorq floorl #define ceilq ceill #define roundq roundl #define rintq rintl #define M_PIq_ M_PIl #endif #ifdef _MSC_VER #define finite__ _finite #endif #ifndef finite__ #define finite__ isfinite #endif #ifdef __TLFLOAT_HPP_INCLUDED__ typedef tlfloat::detail::UnpackedFloat ufloat; typedef tlfloat::detail::UnpackedFloat, 11, 52> udouble; typedef tlfloat::detail::UnpackedFloat, tlfloat::BigUInt<8>, 15, 112> uquad; typedef tlfloat::detail::UnpackedFloat, tlfloat::BigUInt<9>, 19, 236> uoctuple; typedef tlfloat::detail::UnpackedFloat xfloat; typedef tlfloat::detail::UnpackedFloat, 0, 62> xdouble; typedef tlfloat::detail::UnpackedFloat, tlfloat::BigUInt<8>, 0, 126> xquad; typedef tlfloat::detail::UnpackedFloat, tlfloat::BigUInt<9>, 0, 254> xoctuple; typedef tlfloat::detail::UnpackedFloat, tlfloat::BigUInt<10>, 0, 510> xsedecuple; xfloat xfpi(0x6487ed51U, 0, false, false, false, false); xdouble xdpi(0x6487ed5110b4611aULL, 0, false, false, false, false); uint64_t piqa[] = {0x62633145c06e0e69, 0x6487ed5110b4611aULL}; xquad xqpi(tlfloat::BigUInt<7>(piqa), 0, false, false, false, false); uint64_t pioa[] = {0x0105DF531D89CD91ULL, 0x948127044533E63AULL, 0x62633145C06E0E68ULL, 0x6487ED5110B4611AULL}; xoctuple xopi(tlfloat::BigUInt<8>(pioa), 0, false, false, false, false); static const Octuple M_PIo_ = (Octuple)xopi.cast((const uoctuple *)nullptr); #ifdef ENABLE_QUAD static_assert(sizeof(quad) == 16, "quad precision FP not supported"); #else typedef tlfloat::detail::UnpackedFloat, tlfloat::BigUInt<8>, 0, 126> xquad; const tlfloat::Quad M_PIq_ = (tlfloat::Quad)xqpi.cast((tlfloat::detail::UnpackedFloat, tlfloat::BigUInt<8>, 15, 112> *)0); #endif #endif // #ifdef __TLFLOAT_HPP_INCLUDED__ #ifdef MPFR_VERSION_MAJOR std::string to_string(const mpfr_t& fr, int digits = 51) { mpfr_t t; mpfr_inits(t, NULL); int sign = mpfr_signbit(fr) ? -1 : 1; char *s = (char *)malloc(digits + 21); if (mpfr_inf_p(fr)) { sprintf(s, "%cinf", sign < 0 ? '-' : '+'); } else if (mpfr_nan_p(fr)) { sprintf(s, "nan"); } else { mpfr_exp_t e; s[0] = sign < 0 ? '-' : '+'; s[1] = '0'; s[2] = '.'; mpfr_abs(t, fr, GMP_RNDN); mpfr_get_str(s+3, &e, 10, digits, t, GMP_RNDN); int ie = e; char es[32]; snprintf(es, 30, "e%c%d", ie >= 0 ? '+' : '-', ie >= 0 ? ie : -ie); strncat(s, es, digits+20); } mpfr_clears(t, NULL); std::string str = s; free(s); return str; } std::ostream& operator<<(std::ostream &os, const mpfr_t& fr) { return os << to_string(fr); } void mpfr_set_inttype(mpfr_t &rop, uint16_t op, const mpfr_rnd_t rnd) { mpfr_set_d(rop, op, GMP_RNDN); } template static void mpfr_set_inttype(mpfr_t &rop, inttype op, const mpfr_rnd_t rnd) { mpfr_set_d(rop, 0, GMP_RNDN); for(unsigned u=0;u 4) op >>= 32; mpfr_add_d(rop, rop, ldexp(d, 32 * u), GMP_RNDN); } } template static void mpfr_set_unpacked(mpfr_t &rop, const Unpacked_t& ux, const mpfr_rnd_t rnd) { if (ux.isnan) { mpfr_set_nan(rop); return; } if (ux.isinf) { mpfr_set_inf(rop, ux.sign); mpfr_setsign(rop, rop, ux.sign, GMP_RNDN); return; } if (ux.iszero) { mpfr_set_zero(rop, ux.sign); mpfr_setsign(rop, rop, ux.sign, GMP_RNDN); return; } mpfr_set_inttype(rop, ux.mant, rnd); mpfr_set_exp(rop, ux.ilogb() + 1); mpfr_setsign(rop, rop, ux.sign, GMP_RNDN); } int mpfr_ph(mpfr_t &rop, const mpfr_t &op, int e) { mpfr_t pi; mpfr_inits(pi, NULL); mpfr_const_pi(pi, GMP_RNDN); mpfr_mul_d(pi, pi, ldexp(1, -e), GMP_RNDN); // long int q; mpfr_remquo(rop, &q, op, pi, GMP_RNDN); mpfr_clears(pi, NULL); return q; } template static int mpfr_ph(mpfr_t &rop, const Unpacked_t& ux, int e) { mpfr_t x; mpfr_inits(x, NULL); mpfr_set_unpacked(x, ux, GMP_RNDN); int q = mpfr_ph(rop, x, e); mpfr_clears(x, NULL); return q & 0xff; } #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad mpfr_sqrt(quad a) { mpfr_t x; mpfr_inits(x, NULL); mpfr_set_float128(x, a, GMP_RNDN); mpfr_sqrt(x, x, GMP_RNDN); quad d = mpfr_get_float128(x, GMP_RNDN); mpfr_clears(x, NULL); return d; } #endif template static double countULP(const Unpacked_t& ux, mpfr_t c, const Unpacked2_t& umin, const Unpacked2_t& umax, bool checkSignedZero=false) { const int nbmant = umin.nbmant_(); mpfr_t fra, frb, frc, frd, frmin, frmino2, frmax; mpfr_inits(fra, frb, frc, frd, frmin, frmino2, frmax, NULL); mpfr_set_unpacked(frmin, umin, GMP_RNDN); mpfr_mul_d(frmino2, frmin, 0.5, GMP_RNDN); mpfr_set_unpacked(frmax, umax, GMP_RNDN); mpfr_abs(fra, c, GMP_RNDN); bool ciszero = mpfr_cmp(fra, frmino2) < 0; bool cisinf = mpfr_cmp(fra, frmax) > 0; if (ciszero && !ux.iszero) { mpfr_clears(fra, frb, frc, frd, frmin, frmino2, frmax, NULL); return 10000; } if (checkSignedZero && ciszero && ux.iszero) { if (mpfr_signbit(c) != ux.sign) { mpfr_clears(fra, frb, frc, frd, frmin, frmino2, frmax, NULL); return 10002; } } if (cisinf && ux.isinf && mpfr_signbit(c) == ux.sign) { mpfr_clears(fra, frb, frc, frd, frmin, frmino2, frmax, NULL); return 0; } if (mpfr_nan_p(c) && ux.isnan) { mpfr_clears(fra, frb, frc, frd, frmin, frmino2, frmax, NULL); return 0; } if (mpfr_nan_p(c) || ux.isnan) { mpfr_clears(fra, frb, frc, frd, frmin, frmino2, frmax, NULL); return 10001; } int e = mpfr_get_exp(c); mpfr_set_d(frb, 1, GMP_RNDN); mpfr_set_exp(frb, e - nbmant); mpfr_max(frb, frb, frmin, GMP_RNDN); mpfr_set_unpacked(frd, ux, GMP_RNDN); mpfr_sub(fra, frd, c, GMP_RNDN); mpfr_div(fra, fra, frb, GMP_RNDN); double u = fabs(mpfr_get_d(fra, GMP_RNDN)); mpfr_clears(fra, frb, frc, frd, frmin, frmino2, frmax, NULL); return u; } #endif // #ifdef MPFR_VERSION_MAJOR int64_t rndint(shared_ptr rng, unsigned maxnb = 5) { unsigned nbits = rng->nextLT(maxnb); int64_t i = rng->nextLT(1 << nbits) + 1; if (rng->next(1)) i = -i; return i; } float rndf(shared_ptr rng) { uint64_t r = rng->nextLT(1000); if (r == 0) { static float a[] = { +0.0f, -0.0f, (float)+INFINITY, (float)-INFINITY, (float)NAN, +1.4013e-45f, +2.8026e-45f, +4.2039e-45f, +5.60519e-45f, +7.00649e-4f, -1.4013e-45f, -2.8026e-45f, -4.2039e-45f, -5.60519e-45f, -7.00649e-4f, }; return a[rng->nextLT(sizeof(a)/sizeof(float))]; } else if (r < 32) { for(;;) { float f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (!isfinite(f)) continue; if (-1 <= f && f <= 1) continue; f = rintf(f) * M_PI / 2; int32_t u; memcpy((void *)&u, (void *)&f, sizeof(u)); u += int(rng->nextLT(5)) - 2; memcpy((void *)&f, (void *)&u, sizeof(f)); return f; } } else if (r < 64) { for(;;) { float f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (isfinite(f)) return rndint(rng) + f; } } else { for(;;) { float f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (isfinite(f)) return f; } } } #ifndef TLFLOAT_FP_NAN #define TLFLOAT_FP_NAN 0 #define TLFLOAT_FP_INFINITE 1 #define TLFLOAT_FP_ZERO 2 #define TLFLOAT_FP_SUBNORMAL 3 #define TLFLOAT_FP_NORMAL 4 #endif bool eqquo(int64_t t, long int c) { if (sizeof(int64_t) == sizeof(long int)) { return t == c || (c == (1LL << (sizeof(long int)*8-1)) && t == 0); } else { return ((t & 7) == (c & 7) && ((t < 0) == (c < 0))) || ((c & 0x7fffffff) == 0); } } bool cmpfpclass(int sl, int tl) { if (sl == FP_NAN && tl == TLFLOAT_FP_NAN) return true; if (sl == FP_INFINITE && tl == TLFLOAT_FP_INFINITE) return true; if (sl == FP_ZERO && tl == TLFLOAT_FP_ZERO) return true; if (sl == FP_SUBNORMAL && tl == TLFLOAT_FP_SUBNORMAL) return true; if (sl == FP_NORMAL && tl == TLFLOAT_FP_NORMAL) return true; return false; } bool cmpf(float x, float y, int t=0) { if (isnan(x) && isnan(y)) return true; uint32_t u, v; memcpy((void *)&u, (void *)&x, sizeof(u)); memcpy((void *)&v, (void *)&y, sizeof(v)); if (t == 0) return u == v; int d = int(int32_t(u) - int32_t(v)); return -t <= d && d <= t; } double rndd(shared_ptr rng) { uint64_t r = rng->nextLT(1000); if (r == 0) { static double a[] = { +0.0, -0.0, +INFINITY, -INFINITY, NAN, +4.94066e-324, +9.88131e-324, +1.4822e-323, +1.97626e-323, +2.47033e-323, -4.94066e-324, -9.88131e-324, -1.4822e-323, -1.97626e-323, -2.47033e-323, }; return a[rng->nextLT(sizeof(a)/sizeof(double))]; } else if (r < 32) { for(;;) { double f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (!isfinite(f)) continue; if (-1 <= f && f <= 1) continue; f = rint(f) * M_PI / 2; int64_t u; memcpy((void *)&u, (void *)&f, sizeof(u)); u += int(rng->nextLT(5)) - 2; memcpy((void *)&f, (void *)&u, sizeof(f)); return f; } } else if (r < 64) { for(;;) { double f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (isfinite(f)) return rndint(rng) + f; } } else { for(;;) { double f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (isfinite(f)) return f; } } } bool cmpd(double x, double y, int t=0) { if (isnan(x) && isnan(y)) return true; uint64_t u, v; memcpy((void *)&u, (void *)&x, sizeof(u)); memcpy((void *)&v, (void *)&y, sizeof(v)); if (t == 0) return u == v; int d = int(int64_t(u) - int64_t(v)); return -t <= d && d <= t; } #ifdef __TLFLOAT_HPP_INCLUDED__ Quad rndQ(shared_ptr rng) { uint64_t r = rng->nextLT(1000); if (r == 0) { Quad pm = Quad::flt_true_min(), nm = -pm; Quad po = 1, no = -1; static Quad a[] = { +0.0, -0.0, +INFINITY, -INFINITY, NAN, pm, nextafter(pm, po), nextafter(nextafter(pm, po), po), nextafter(nextafter(nextafter(pm, po), po), po), nextafter(nextafter(nextafter(nextafter(pm, po), po), po), po), nm, nextafter(nm, no), nextafter(nextafter(nm, no), no), nextafter(nextafter(nextafter(nm, no), no), no), nextafter(nextafter(nextafter(nextafter(nm, no), no), no), no), }; return a[rng->nextLT(sizeof(a)/sizeof(Quad))]; } else if (r < 32) { for(;;) { Quad f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (!finite(f)) continue; if (-1 <= f && f <= 1) continue; f = rint(f) * M_PIo_ / 2; BigInt<7> u; memcpy((void *)&u, (void *)&f, sizeof(u)); u += int(rng->nextLT(5)) - 2; memcpy((void *)&f, (void *)&u, sizeof(f)); return f; } } else if (r < 64) { for(;;) { Quad f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (finite(f)) return rndint(rng) + f; } } else { for(;;) { Quad f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (finite(f)) return f; } } } #ifdef ENABLE_QUAD quad rndq(shared_ptr rng) { return (quad)rndQ(rng); } typedef quad quad_; bool cmpq(quad x, quad y, int t=0) { if (isnanq(x) && isnanq(y)) return true; BigUInt<7> u, v; memcpy((void *)&u, (void *)&x, sizeof(u)); memcpy((void *)&v, (void *)&y, sizeof(v)); if (t == 0) return u == v; int d = int(BigInt<7>(u) - BigInt<7>(v)); return -t <= d && d <= t; } #else typedef Quad quad_; quad_ rndq(shared_ptr rng) { return rndQ(rng); } #endif bool cmpq(Quad x, Quad y, int t=0) { if (isnan(x) && isnan(y)) return true; BigUInt<7> u, v; memcpy((void *)&u, (void *)&x, sizeof(u)); memcpy((void *)&v, (void *)&y, sizeof(v)); if (t == 0) return u == v; int d = int(BigInt<7>(u) - BigInt<7>(v)); return -t <= d && d <= t; } Octuple rndo(shared_ptr rng) { uint64_t r = rng->nextLT(1000); if (r == 0) { Octuple pm = Octuple::flt_true_min(), nm = -pm; Octuple po = 1, no = -1; static Octuple a[] = { +0.0, -0.0, +INFINITY, -INFINITY, NAN, pm, nextafter(pm, po), nextafter(nextafter(pm, po), po), nextafter(nextafter(nextafter(pm, po), po), po), nextafter(nextafter(nextafter(nextafter(pm, po), po), po), po), nm, nextafter(nm, no), nextafter(nextafter(nm, no), no), nextafter(nextafter(nextafter(nm, no), no), no), nextafter(nextafter(nextafter(nextafter(nm, no), no), no), no), }; return a[rng->nextLT(sizeof(a)/sizeof(Octuple))]; } else if (r < 32) { for(;;) { Octuple f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (!finite(f)) continue; if (-1 <= f && f <= 1) continue; f = rint(f) * M_PIo_ / 2; BigInt<8> u; memcpy((void *)&u, (void *)&f, sizeof(u)); u += int(rng->nextLT(5)) - 2; memcpy((void *)&f, (void *)&u, sizeof(f)); return f; } } else if (r < 64) { for(;;) { Octuple f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (finite(f)) return rndint(rng) + f; } } else { for(;;) { Octuple f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (finite(f)) return f; } } } bool cmpo(Octuple x, Octuple y, int t=0) { if (isnan(x) && isnan(y)) return true; BigUInt<8> u, v; memcpy((void *)&u, (void *)&x, sizeof(u)); memcpy((void *)&v, (void *)&y, sizeof(v)); if (t == 0) return u == v; int d = int(BigInt<8>(u) - BigInt<8>(v)); return -t <= d && d <= t; } #endif // #ifdef __TLFLOAT_HPP_INCLUDED__ template vector genTestValues(unsigned n, shared_ptr rng) { T values[] = { T("+0.0"), T("-0.0"), T::nan(), T::infinity(false), T::infinity(true), T::flt_true_min(false), nextafter(T::flt_true_min(false), 1), nextafter(nextafter(T::flt_true_min(false), 1), 1), nextafter(nextafter(nextafter(T::flt_true_min(false), 1), 1), 1), nextafter(nextafter(nextafter(nextafter(T::flt_true_min(false), 1), 1), 1), 1), T::flt_true_min(true), nextafter(T::flt_true_min(true), -1), nextafter(nextafter(T::flt_true_min(true), -1), -1), nextafter(nextafter(nextafter(T::flt_true_min(true), -1), -1), -1), nextafter(nextafter(nextafter(nextafter(T::flt_true_min(true), -1), -1), -1), -1), T::flt_max(false), nextafter(T::flt_max(false), 0), nextafter(nextafter(T::flt_max(false), 0), 0), nextafter(nextafter(nextafter(T::flt_max(false), 0), 0), 0), nextafter(nextafter(nextafter(nextafter(T::flt_max(false), 0), 0), 0), 0), T::flt_max(true), nextafter(T::flt_max(true), 0), nextafter(nextafter(T::flt_max(true), 0), 0), nextafter(nextafter(nextafter(T::flt_max(true), 0), 0), 0), nextafter(nextafter(nextafter(nextafter(T::flt_max(true), 0), 0), 0), 0), nextafter(nextafter(T::flt_min(false), 0), 0), nextafter(T::flt_min(false), 0), T::flt_min(false), nextafter(T::flt_min(false), 1), nextafter(nextafter(T::flt_min(false), 1), 1), nextafter(nextafter(T::flt_min(true), 0), 0), nextafter(T::flt_min(true), 0), T::flt_min(true), nextafter(T::flt_min(true), -1), nextafter(nextafter(T::flt_min(true), -1), -1), nextafter(T("+1.0"), 0), nextafter(nextafter(T("+1.0"), 0), 0), nextafter(nextafter(nextafter(T("+1.0"), 0), 0), 0), nextafter(T("+1.0"), 3), nextafter(nextafter(T("+1.0"), 3), 3), nextafter(nextafter(nextafter(T("+1.0"), 3), 3), 3), nextafter(T("+2.0"), 0), nextafter(nextafter(T("+2.0"), 0), 0), nextafter(nextafter(nextafter(T("+2.0"), 0), 0), 0), nextafter(T("+2.0"), 3), nextafter(nextafter(T("+2.0"), 3), 3), nextafter(nextafter(nextafter(T("+2.0"), 3), 3), 3), nextafter(T("-1.0"), 0), nextafter(nextafter(T("-1.0"), 0), 0), nextafter(nextafter(nextafter(T("-1.0"), 0), 0), 0), nextafter(T("-1.0"), -3), nextafter(nextafter(T("-1.0"), -3), -3), nextafter(nextafter(nextafter(T("-1.0"), -3), -3), -3), nextafter(T("-2.0"), 0), nextafter(nextafter(T("-2.0"), 0), 0), nextafter(nextafter(nextafter(T("-2.0"), 0), 0), 0), nextafter(T("-2.0"), -3), nextafter(nextafter(T("-2.0"), -3), -3), nextafter(nextafter(nextafter(T("-2.0"), -3), -3), -3), T("+0.25"), T("-0.25"), T("+0.5"), T("-0.5"), T("+1.0"), T("-1.0"), T("+1.5"), T("-1.5"), T("+2.0"), T("-2.0"), T("+2.5"), T("-2.5"), T("+3.0"), T("-3.0"), T("+4.0"), T("-4.0"), T("+100.0"), T("-100.0"), T("+100.5"), T("-100.5"), T("+101.0"), T("-101.0"), T("+102.0"), T("-102.0"), T("+103.0"), T("-103.0"), T("+1.234"), T("-1.234"), T("+1.234e+10"), T("-1.234e+10"), T("+1.234e+30"), T("-1.234e+30"), T("+1.234e-10"), T("-1.234e-10"), T("+1.234e-30"), T("-1.234e-30"), T("0x1.6ac5b262ca1ffp+849"), T("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170676"), T("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170676e+30"), T("2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274"), }; vector ret; for(unsigned i=0;inextBytesW((unsigned char *)&f, sizeof(f)); ret.push_back(f); } return ret; } #ifdef __BIGINT_HPP_INCLUDED__ struct converter128 { BigInt<7> bi; #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 __int128_t i128; __uint128_t u128; #endif #ifdef __TLFLOAT_H_INCLUDED__ tlfloat_int128_t ti128; tlfloat_uint128_t tu128; #endif converter128(uint64_t high, uint64_t low) { #if !defined(__BYTE_ORDER__) || (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) uint64_t u[2] = { low, high }; #else uint64_t u[2] = { high, low }; #endif memcpy(&bi, u, sizeof(bi)); #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 memcpy(&i128, u, sizeof(i128)); memcpy(&u128, u, sizeof(u128)); #endif #ifdef __TLFLOAT_H_INCLUDED__ memcpy(&ti128, u, sizeof(ti128)); memcpy(&tu128, u, sizeof(tu128)); #endif } }; #endif size_t fwrite_(const void *ptr, size_t size, size_t nmemb, FILE *fp) { #if !defined(__BYTE_ORDER__) || (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) return fwrite(ptr, size, nmemb, fp); #else size_t z = 0; for(size_t m=0;m #include #include #include #include #include #if defined(TLFLOAT_DOXYGEN) /** All architecture-specific optimizations (e.g., use of intrinsic functions) are disabled if this macro is defined */ #define TLFLOAT_DISABLE_ARCH_OPTIMIZATION /** Functions that require libstdc++ will be disabled if this macro is defined */ #define TLFLOAT_NO_LIBSTDCXX /** TLFLOAT_VERSION_MAJOR is the major version of TLFloat library */ #define TLFLOAT_VERSION_MAJOR /** TLFLOAT_VERSION_MAJOR is the minor version of TLFloat library */ #define TLFLOAT_VERSION_MINOR /** TLFLOAT_VERSION_MAJOR is the patch level of TLFloat library */ #define TLFLOAT_VERSION_PATCH #endif /*! \cond NO_DOCUMENTATION_WITH_DOXYGEN */ #define TLFLOAT_NOINLINE #define TLFLOAT_INLINE /*! \endcond */ #ifndef TLFLOAT_DISABLE_ARCH_OPTIMIZATION #if defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER)) #if defined(__x86_64__) && !defined(__CUDA_ARCH__) #include #define TLFLOAT_ENABLE_X86INTRIN #define TLFLOAT_ENABLE_ASM_GNU #endif #if defined(TLFLOAT_COMPILER_SUPPORTS_INT128) && !defined(__CUDA_ARCH__) #define TLFLOAT_ENABLE_INT128_OPT #endif #if !defined(__CUDA_ARCH__) #define TLFLOAT_ENABLE_GNUC_CLZ #ifdef TLFLOAT_ENABLE_INLINING #undef TLFLOAT_INLINE #define TLFLOAT_INLINE __attribute__((always_inline)) #endif #else #define TLFLOAT_ENABLE_CUDA_UMUL64HI #define TLFLOAT_ENABLE_CUDA_CLZ #endif #undef TLFLOAT_NOINLINE #define TLFLOAT_NOINLINE __attribute__((noinline)) #endif // #if defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER)) #ifdef _MSC_VER #if !defined(__CUDA_ARCH__) #if defined(_M_X64) #include #define TLFLOAT_ENABLE_X86INTRIN #endif // #if defined(_M_X64) #define TLFLOAT_ENABLE_VCUMUL128 #define TLFLOAT_ENABLE_VCBITSCANREVERSE #ifdef TLFLOAT_ENABLE_INLINING #undef TLFLOAT_INLINE #if !defined(__clang__) #define TLFLOAT_INLINE __forceinline #else #define TLFLOAT_INLINE __attribute__((always_inline)) #endif #endif // #ifdef TLFLOAT_ENABLE_INLINING #endif // #if !defined(__CUDA_ARCH__) #endif // #ifdef _MSC_VER #endif // #ifndef TLFLOAT_DISABLE_ARCH_OPTIMIZATION #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic ignored "-Wreorder" #endif #if defined(__clang__) #pragma clang diagnostic ignored "-Wreorder" #endif #endif /// TLFloat library defines all C++ classes and functions in tlfloat namespace namespace tlfloat { /** * This is a simple template struct similar to std::pair. Unlike * std::pair, the member functions are all constexpr. */ template struct xpair { firsttype first; secondtype second; constexpr TLFLOAT_INLINE xpair(const firsttype& f, const secondtype& s) : first(f), second(s) {} }; namespace detail { template struct xarray { T e[N]; }; static constexpr TLFLOAT_INLINE xpair adc64_(bool cin, uint64_t lhs, uint64_t rhs) { uint64_t al = (lhs & 0xffffffff) + (rhs & 0xffffffff) + cin; lhs >>= 32; rhs >>= 32; uint64_t ah = (lhs & 0xffffffff) + (rhs & 0xffffffff) + ((al >> 32) != 0); return xpair((al & 0xffffffff) | (ah << 32), (ah >> 32) != 0); } static constexpr TLFLOAT_INLINE xpair adc64(bool cin, uint64_t lhs, uint64_t rhs) { if (std::is_constant_evaluated()) return adc64_(cin, lhs, rhs); #if defined(TLFLOAT_ENABLE_X86INTRIN) xpair ret(0, false); ret.second = _addcarry_u64(cin, lhs, rhs, (long long unsigned *)&ret.first); return ret; #elif defined(TLFLOAT_ENABLE_INT128_OPT) __uint128_t a = __uint128_t(lhs) + rhs + cin; return xpair(uint64_t(a), (a >> 64) != 0); #else return adc64_(cin, lhs, rhs); #endif } static constexpr TLFLOAT_INLINE xpair sbc64_(bool cin, uint64_t lhs, uint64_t rhs) { uint64_t al = (lhs & 0xffffffff) - (rhs & 0xffffffff) - cin; lhs >>= 32; rhs >>= 32; uint64_t ah = (lhs & 0xffffffff) - (rhs & 0xffffffff) - ((al >> 32) != 0); return xpair((al & 0xffffffff) | (ah << 32), (ah >> 32) != 0); } static constexpr TLFLOAT_INLINE xpair sbc64(bool cin, uint64_t lhs, uint64_t rhs) { if (std::is_constant_evaluated()) return sbc64_(cin, lhs, rhs); #if defined(TLFLOAT_ENABLE_X86INTRIN) xpair ret(0, false); ret.second = _subborrow_u64(cin, lhs, rhs, (long long unsigned *)&ret.first); return ret; #elif defined(TLFLOAT_ENABLE_INT128_OPT) __uint128_t a = __uint128_t(lhs) - rhs - cin; return xpair(uint64_t(a), (a >> 64) != 0); #else return sbc64_(cin, lhs, rhs); #endif } static constexpr TLFLOAT_INLINE xpair mul128_(uint64_t lhs, uint64_t rhs) { uint64_t al = lhs & 0xffffffff, ah = lhs >> 32; uint64_t bl = rhs & 0xffffffff, bh = rhs >> 32; uint64_t m = ah * bl + ((al * bl) >> 32) + ((al * bh) & 0xffffffff); return xpair (ah * bh + (m >> 32) + ((al * bh) >> 32), lhs * rhs); } static constexpr TLFLOAT_INLINE xpair mul128(uint64_t lhs, uint64_t rhs) { if (std::is_constant_evaluated()) return mul128_(lhs, rhs); #ifdef TLFLOAT_ENABLE_VCUMUL128 xpair ret(0, 0); ret.second = _umul128(lhs, rhs, &ret.first); return ret; #elif defined(TLFLOAT_ENABLE_INT128_OPT) __uint128_t m = lhs * __uint128_t(rhs); return xpair(uint64_t(m >> 64), uint64_t(m)); #elif defined(TLFLOAT_ENABLE_CUDA_UMUL64HI) return xpair(__umul64hi(lhs, rhs), lhs * rhs); #else return mul128_(lhs, rhs); #endif } static constexpr TLFLOAT_INLINE unsigned clz64_(uint64_t u) { unsigned z = 0; if (u & 0xffffffff00000000ULL) u >>= 32; else z += 32; if (u & 0x00000000ffff0000ULL) u >>= 16; else z += 16; if (u & 0x000000000000ff00ULL) u >>= 8; else z += 8; if (u & 0x00000000000000f0ULL) u >>= 4; else z += 4; if (u & 0x000000000000000cULL) u >>= 2; else z += 2; if (u & 0x0000000000000002ULL) u >>= 1; else z += 1; if (!u) z++; return z; } static constexpr TLFLOAT_INLINE unsigned clz64(uint64_t u) { if (std::is_constant_evaluated()) return clz64_(u); #ifdef TLFLOAT_ENABLE_VCBITSCANREVERSE unsigned long idx = 0; return _BitScanReverse64(&idx, u) ? (63 - idx) : 64; #elif defined(TLFLOAT_ENABLE_GNUC_CLZ) return u == 0 ? 64 : __builtin_clzll(u); #elif defined(TLFLOAT_ENABLE_CUDA_CLZ) return __clzll(u); #else return clz64_(u); #endif } static constexpr TLFLOAT_INLINE xpair divmod128_64_(uint64_t nh_, uint64_t nl_, uint64_t d_) { assert(nh_ < d_); if (nh_ == 0) return xpair { nl_ / d_, nl_ % d_ }; const int s = clz64(d_); const uint64_t nh = (nh_ << s) | (s == 0 ? 0 : (nl_ >> (64 - s))), nl = nl_ << s, d = d_ << s; uint64_t dm0q = nh / (d >> 32), dm0r = nh % (d >> 32); if ((dm0q >> 32) || dm0q * (d & 0xffffffff) > (dm0r << 32) + (nl >> 32)) { dm0q--; if (!((dm0r += (d >> 32)) >> 32) && ((dm0q >> 32) || dm0q * (d & 0xffffffff) > (dm0r << 32) + (nl >> 32))) dm0q--; } const uint64_t n2 = (nh << 32) + (nl >> 32) - dm0q * d; uint64_t dm1q = n2 / (d >> 32), dm1r = n2 % (d >> 32); if ((dm1q >> 32) || dm1q * (d & 0xffffffff) > (dm1r << 32) + (nl & 0xffffffff)) { dm1q--; if (!((dm1r += (d >> 32)) >> 32) && ((dm1q >> 32) || dm1q * (d & 0xffffffff) > (dm1r << 32) + (nl & 0xffffffff))) dm1q--; } return xpair { ((uint64_t)dm0q << 32) + dm1q, (((n2 << 32) + (nl & 0xffffffff)) - dm1q * d) >> s }; } static constexpr TLFLOAT_INLINE xpair divmod128_64(uint64_t nh, uint64_t nl, uint64_t d) { assert(nh < d); if (std::is_constant_evaluated()) return divmod128_64_(nh, nl, d); #if defined(__x86_64__) && defined(TLFLOAT_ENABLE_ASM_GNU) uint64_t r, q; __asm__("divq %2\n" : "=d" (r), "=a" (q) : "rm" (d), "d" (nh), "a" (nl)); return xpair(q, r); #elif defined(TLFLOAT_ENABLE_INT128_OPT) __uint128_t n = (__uint128_t(nh) << 64) | nl; return xpair { uint64_t(n / d), uint64_t(n % d) }; #else return divmod128_64_(nh, nl, d); #endif } template class SafeArray { T* bufPtr; const int64_t bufSize; T dummyElm = 0; public: SafeArray(T* const bufPtr_, const int64_t bufSize_) : bufPtr(bufPtr_), bufSize(bufSize_) {} T operator[](int64_t pos) const { if (0 <= pos && pos < bufSize) return bufPtr[pos]; return 0; } T& operator[](int64_t pos) { if (0 <= pos && pos < bufSize) return bufPtr[pos]; return dummyElm; } void strcpyFrom(int64_t pos, const T *p) { if (pos < 0) return; while(pos < bufSize-1 && *p != 0) bufPtr[pos++] = *p++; if (pos < bufSize) bufPtr[pos] = 0; } void memmove(int64_t pos, const T *p, int64_t size) { if (!(0 <= pos && pos + size <= bufSize)) return; memcpy(&bufPtr[pos], p, size * sizeof(T)); } void memmove(int64_t dpos, int64_t spos, int64_t size) { if (!(0 <= dpos && dpos + size <= bufSize)) return; if (!(0 <= spos && spos + size <= bufSize)) return; ::memmove(&bufPtr[dpos], &bufPtr[spos], size * sizeof(T)); } }; template class UnpackedFloat; template), int> = 0> static constexpr TLFLOAT_INLINE T bitmask(int b) { return (T(1) << b) - 1; } template), int> = 0> static constexpr TLFLOAT_INLINE T bitmask(int b) { T u; for(int i=0;i<(int)sizeof(T) / 8;i++) { uint64_t w = 0; if (i < (b >> 6)) w = 0xffffffffffffffffULL; if (i == (b >> 6)) w = (1ULL << (b & 63))-1; u.setWord(i, w); } return u; } } // namespace detail template class TLFloat; /** * This is a trivially copyable template class that represents an * arbitrary precision unsigned integer. It can represent an * unsigned integer less than 2^N. The data size of an object is N * bits, where N must be 7 or greater. */ template class BigUInt { static_assert(N >= 7, "N must be 7 or larger"); static_assert(sizeof(unsigned long long int) == 8, "unsigned long long int must be 64-bit"); static_assert(sizeof(long long int) == 8, "long long int must be 64-bit"); static_assert(sizeof(unsigned int) == 4, "unsigned int must be 32-bit"); static_assert(sizeof(int) == 4, "int must be 32-bit"); public: #if !defined(__BYTE_ORDER__) || (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) BigUInt low = 0, high = 0; #else BigUInt high = 0, low = 0; #endif constexpr TLFLOAT_INLINE BigUInt(const BigUInt& h, const BigUInt& l) : low(l), high(h) {} #if !defined(TLFLOAT_DOXYGEN) // Karatsuba algorithm template= 10), int> = 0> static constexpr inline BigUInt mul(const BigUInt& lhs, const BigUInt& rhs) { if (std::is_constant_evaluated()) return BigUInt(lhs.mulhi(rhs), lhs * rhs); if (lhs.isZero() || rhs.isZero()) return BigUInt(0); if (lhs.isAllOne() && rhs.isAllOne()) return BigUInt(~BigUInt(1), BigUInt(1)); auto x0tx1 = lhs.high.adc(lhs.low, false), y0ty1 = rhs.high.adc(rhs.low, false); BigUInt z1 = BigUInt::mul(x0tx1.first, y0ty1.first); unsigned z1c = x0tx1.second & y0ty1.second; if (y0ty1.second) { auto t = z1.adc(BigUInt(x0tx1.first, 0), false); z1c += t.second; z1 = t.first; } if (x0tx1.second) { auto t = z1.adc(BigUInt(y0ty1.first, 0), false); z1c += t.second; z1 = t.first; } BigUInt z0 = BigUInt::mul(lhs.low, rhs.low), z2 = BigUInt::mul(lhs.high, rhs.high); auto z0pz2 = z0.adc(z2, false); z1c -= z0pz2.second; auto t = z1.sbc(z0pz2.first, false); return BigUInt(z2, z0) + (BigUInt(z1c - t.second, t.first) << (1 << (N-2))); } template = 0> static constexpr TLFLOAT_INLINE BigUInt mul(const BigUInt& lhs, const BigUInt& rhs) { if (std::is_constant_evaluated()) return BigUInt(lhs.mulhi(rhs), lhs * rhs); BigUInt ret(0); uint64_t ah = 0, am = 0, al = 0; const unsigned n = 1 << (N - 7); for(unsigned i=0;i m = detail::mul128(lhs.getWord(j), rhs.getWord(i - j)); xpair ub = detail::adc64(false, m.second, al); al = ub.first; ub = detail::adc64(ub.second, m.first, am); am = ub.first; ah += ub.second; } ret.setWord(i, uint64_t(al)); al = am; am = ah; ah = 0; } for(unsigned i=n;i m = detail::mul128(lhs.getWord(j), rhs.getWord(i - j)); xpair ub = detail::adc64(false, m.second, al); al = ub.first; ub = detail::adc64(ub.second, m.first, am); am = ub.first; ah += ub.second; } ret.setWord(i, uint64_t(al)); al = am; am = ah; ah = 0; } ret.setWord(n*2-1, uint64_t(al)); return ret; } template = 0> static constexpr TLFLOAT_INLINE BigUInt mul(const BigUInt& lhs, const BigUInt& rhs) { xpair m = detail::mul128(lhs.u64, rhs.u64); return BigUInt(m.first, m.second); } constexpr TLFLOAT_INLINE xpair inc() const { auto rl = low.inc(); xpair s(0, false); s.first.low = rl.first; s.first.high = high; if (rl.second) { auto rh = high.inc(); s.first.high = rh.first; s.second = rh.second; } return s; } constexpr TLFLOAT_INLINE xpair dec() const { auto rl = low.dec(); xpair s(0, false); s.first.low = rl.first; s.first.high = high; if (rl.second) { auto rh = high.dec(); s.first.high = rh.first; s.second = rh.second; } return s; } constexpr TLFLOAT_INLINE xpair adc(const BigUInt& rhs, bool c) const { auto rl = low.adc(rhs.low, c), rh = high.adc(rhs.high, rl.second); xpair s(0, false); s.first.high = rh.first; s.first.low = rl.first; s.second = rh.second; return s; } constexpr TLFLOAT_INLINE xpair sbc(const BigUInt& rhs, bool c) const { auto rl = low.sbc(rhs.low, c), rh = high.sbc(rhs.high, rl.second); xpair s(0, false); s.first.high = rh.first; s.first.low = rl.first; s.second = rh.second; return s; } constexpr TLFLOAT_INLINE BigUInt mulhi(const BigUInt& rhs) const { BigUInt ll = mul(low , rhs.low), lh = mul(low , rhs.high); BigUInt hl = mul(high, rhs.low); BigUInt m = hl + ll.high + lh.low, hh = mul(high, rhs.high); return hh + m.high + lh.high; } constexpr TLFLOAT_INLINE BigUInt mulhiAprx(const BigUInt& rhs) const { BigUInt hh = mul(high, rhs.high); BigUInt lh = low.mulhiAprx(rhs.high), hl = high.mulhiAprx(rhs.low); return hh + hl + lh; } constexpr TLFLOAT_INLINE BigUInt mulhiAprx2(const BigUInt& rhs) const { return mul(high, rhs) + low.mulhiAprx(rhs); } constexpr TLFLOAT_INLINE BigUInt reciprocalAprx() const { BigUInt x((high + ((~high >> (sizeof(high)*8 - 1)) & 1)).reciprocalAprx()); BigUInt y((-mulhiAprx2(x)).mulhiAprx2(x)); return y + y; } /* In Volume 2: Seminumerical Algorithms, Chapter 4.3: Multiple-Precision Arithmetic of The Art of Computer Programming, Donald Ervin Knuth presents "Algorithm D (Division of nonnegative integers)": */ static constexpr TLFLOAT_INLINE xpair div(BigUInt n_, const BigUInt d_) { assert(n_.high < d_); const int s = d_.clz(); const BigUInt n = n_ << s; const BigUInt d = d_ << s; BigUInt on0 = n.high; int dm0of = 0; if (on0.high >= d.high) { dm0of++; on0 -= d.high; if (on0.high >= d.high) { dm0of++; on0 -= d.high; if (on0.high >= d.high) { dm0of++; on0 -= d.high; } } } auto dm0 = BigUInt::div(on0, d.high); BigUInt dm0q = BigUInt(dm0.first) + dm0of, dm0r = dm0.second; if (!(dm0q >> (1 << (N-1))).isZero() || mul(dm0q.low, d.low) > BigUInt(dm0r.low, n.low.high)) { dm0q--; if (((dm0r += d.high) >> (1 << (N-1))).isZero() && (!(dm0q >> (1 << (N-1))).isZero() || mul(dm0q.low, d.low) > BigUInt(dm0r.low, n.low.high))) dm0q--; } const BigUInt n2 = BigUInt(n.high.low, n.low.high) - dm0q * d; BigUInt on1 = n2; int dm1of = 0; if (on1.high >= d.high) { dm1of++; on1 -= d.high; if (on1.high >= d.high) { dm1of++; on1 -= d.high; if (on1.high >= d.high) { dm1of++; on1 -= d.high; } } } auto dm1 = BigUInt::div(on1, d.high); BigUInt dm1q = BigUInt(dm1.first) + dm1of, dm1r = dm1.second; if (!(dm1q >> (1 << (N-1))).isZero() || mul(dm1q.low, d.low) > BigUInt(dm1r.low, n.low.low)) { dm1q--; if (((dm1r += d.high) >> (1 << (N-1))).isZero() && (!(dm1q >> (1 << (N-1))).isZero() || mul(dm1q.low, d.low) > BigUInt(dm1r.low, n.low.low))) dm1q--; } return xpair { BigUInt(dm0q.low, dm1q.low), (BigUInt(n2.low, n.low.low) - dm1q * d) >> s }; } #endif // #if !defined(TLFLOAT_DOXYGEN) public: template friend class BigUInt; template friend class BigInt; template friend class detail::UnpackedFloat; template friend class TLFloat; constexpr TLFLOAT_INLINE BigUInt() = default; /** Cast from any primitive unsigned integer */ template && std::is_unsigned_v && sizeof(T) <= 8), int> = 0> constexpr TLFLOAT_INLINE BigUInt(T u) : low(u), high(uint64_t(0)) {} /** Cast from any primitive signed integer */ template && !std::is_unsigned_v && sizeof(T) <= 8), int> = 0> constexpr TLFLOAT_INLINE BigUInt(T i) : BigUInt(i < 0 ? (~BigUInt(0U) - uint64_t(-int64_t(i)) + 1U) : uint64_t(i)) {} /** Cast to any primitive unsigned integer */ template && std::is_unsigned_v && sizeof(T) <= 8 && !std::is_same_v), int> = 0> constexpr TLFLOAT_INLINE explicit operator T() const { return T(uint64_t(low)); } /** Cast to any primitive signed integer */ template && !std::is_unsigned_v && sizeof(T) <= 8 && !std::is_same_v), int> = 0> constexpr TLFLOAT_INLINE explicit operator T() const { return uint64_t(low); } constexpr TLFLOAT_INLINE explicit operator bool() const { return !isZero(); } #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 constexpr TLFLOAT_INLINE BigUInt(__uint128_t u) : low(uint64_t(0)), high(uint64_t(0)) { setWord(0, uint64_t(u & 0xffffffffffffffffULL)); setWord(1, uint64_t(u >> 64)); } constexpr TLFLOAT_INLINE explicit operator __uint128_t() const { return (__uint128_t(getWord(1)) << 64) + getWord(0); } constexpr TLFLOAT_INLINE explicit BigUInt(__int128_t u) : BigUInt(__uint128_t(u)) {} constexpr TLFLOAT_INLINE explicit operator __int128_t() const { return __uint128_t(*this); } #endif constexpr TLFLOAT_INLINE BigUInt(const BigUInt& m) = default; constexpr TLFLOAT_INLINE explicit BigUInt(const BigUInt& h) : low(h.low.low), high(h.low.high) {} template* = nullptr> constexpr TLFLOAT_INLINE BigUInt(const BigUInt& l) : low(BigUInt(l)), high(uint64_t(0)) {} template (N+1))>* = nullptr> constexpr TLFLOAT_INLINE explicit BigUInt(const BigUInt& h) : BigUInt(BigUInt(h)) {} constexpr TLFLOAT_INLINE BigUInt& operator=(const BigUInt &u) = default; constexpr TLFLOAT_INLINE BigUInt(const uint64_t *p) : low(p), high(p + (1 << (N - 7))) {} constexpr explicit BigUInt(double d) { int x = 0; d = frexp(d, &x); d = ldexp(d, 53); x -= 53; uint64_t l = (uint64_t)fabs(d); if (x >= 0) { BigUInt u(l); u <<= x; low = u.low; high = u.high; } else if (x > -60) { l = l >> -x; BigUInt u(l); low = u.low; high = u.high; } else { low = high = 0; } } constexpr explicit operator double() const { int e0 = ilogbp1(); double d0 = double((*this << (53 - e0)).getWord(0)); double d1 = ldexp(d0, e0 - 53); BigUInt b = *this - BigUInt(d1); int e1 = b.ilogbp1(); double d2 = double((b << (64 - e1)).getWord(0)); double d3 = ldexp(d2, e1 - 64); return d1 + d3; } constexpr TLFLOAT_INLINE unsigned clz() const { return high.isZero2() ? low.clz() + (1 << (N-1)) : high.clz(); } constexpr TLFLOAT_INLINE unsigned ilogbp1() const { return (1U << N) - clz(); } constexpr TLFLOAT_INLINE bool isZero() const { return low.isZero() && high.isZero(); } constexpr TLFLOAT_INLINE bool isZero2() const { return high.isZero2() && low.isZero2(); } constexpr TLFLOAT_INLINE bool isAllOne() const { return low.isAllOne() && high.isAllOne(); } constexpr TLFLOAT_INLINE bool msb() const { return high.msb(); } constexpr TLFLOAT_INLINE uint64_t getWord(unsigned idx) const { if (idx >= (1 << (N-6))) return 0; return idx >= (1 << (N-7)) ? high.getWord(idx - (1 << (N-7))) : low.getWord(idx); } constexpr TLFLOAT_INLINE void setWord(unsigned idx, uint64_t u) { if (idx >= (1 << (N-6))) return; if (idx >= (1 << (N-7))) high.setWord(idx - (1 << (N-7)), u); else low.setWord(idx, u); } constexpr TLFLOAT_INLINE bool bit(unsigned idx) const { return (getWord(idx >> 6) >> (idx & 63)) & 1; } constexpr TLFLOAT_INLINE BigUInt& operator++() { *this = inc().first; return *this; } constexpr TLFLOAT_INLINE BigUInt& operator--() { *this = dec().first; return *this; } constexpr TLFLOAT_INLINE BigUInt operator++(int) { BigUInt t = *this; *this = inc().first; return t; } constexpr TLFLOAT_INLINE BigUInt operator--(int) { BigUInt t = *this; *this = dec().first; return t; } template = 0> constexpr TLFLOAT_INLINE BigUInt operator+(const BigUInt& rhs) const { return adc(rhs, false).first; } template = 0> constexpr TLFLOAT_INLINE BigUInt operator-(const BigUInt& rhs) const { return sbc(rhs, false).first; } #if 1 //!defined(TLFLOAT_ENABLE_INT128_OPT) template = 0> constexpr TLFLOAT_INLINE BigUInt operator+(const BigUInt& rhs) const { return adc(rhs, false).first; } template = 0> constexpr TLFLOAT_INLINE BigUInt operator-(const BigUInt& rhs) const { return sbc(rhs, false).first; } #else template = 0> constexpr TLFLOAT_INLINE BigUInt operator+(const BigUInt& rhs) const { return std::bit_cast(std::bit_cast<__uint128_t>(*this) + std::bit_cast<__uint128_t>(rhs)); } template = 0> constexpr TLFLOAT_INLINE BigUInt operator-(const BigUInt& rhs) const { return std::bit_cast(std::bit_cast<__uint128_t>(*this) - std::bit_cast<__uint128_t>(rhs)); } #endif constexpr TLFLOAT_INLINE BigUInt operator+(const BigUInt& rhs) const { auto rl = low.adc(rhs, false); auto rh = high.inc(); return BigUInt(rl.second ? rh.first : high, rl.first); } constexpr TLFLOAT_INLINE BigUInt operator-(const BigUInt& rhs) const { auto rl = low.sbc(rhs, false); auto rh = high.dec(); return BigUInt(rl.second ? rh.first : high, rl.first); } constexpr TLFLOAT_INLINE BigUInt operator-() const { BigUInt r = ~*this; r = r.inc().first; return r; } constexpr TLFLOAT_INLINE BigUInt operator+() const { return *this; } constexpr TLFLOAT_INLINE BigUInt operator*(const BigUInt& rhs) const { BigUInt ll = mul(low, rhs.low), lh = mul(low, rhs.high); BigUInt hl = mul(high, rhs.low); return BigUInt(lh.low + hl.low + ll.high, ll.low); } constexpr TLFLOAT_INLINE BigUInt operator*(const BigUInt& rhs) const { BigUInt ll = mul(low, rhs), hl = mul(high, rhs); return BigUInt(hl.low + ll.high, ll.low); } constexpr TLFLOAT_INLINE BigUInt operator/(const BigUInt& rhs) const { return div(*this, rhs).first; } constexpr TLFLOAT_INLINE BigUInt operator%(const BigUInt& rhs) const { return div(*this, rhs).second; } /** This method returns ((1 << N) / *this) */ constexpr TLFLOAT_INLINE BigUInt reciprocal() const { unsigned z = clz(); BigUInt t0 = (*this << z).reciprocalAprx(); if (z < (1 << N) - (1 << (N-4))) return t0 >> ((1 << N) - 1 - z); BigUInt t1 = (-(*this << z).mulhi(t0)).mulhi(t0); return t1 >> ((1 << N) - 2 - z); } /** This method returns approximation of (((1 << (N*2))-1) / ((1 << ((1 << N)-1)) | *this) - (1 << ((1 << N)))) */ constexpr TLFLOAT_INLINE BigUInt reciprocal2() const { BigUInt t0 = ((BigUInt(1) << ((1 << N)-1)) | *this); BigUInt t1 = t0.reciprocalAprx() << 1; BigUInt t2 = -t0.mulhi(t1); return t2.mulhi(t1) + (-t0).mulhi(t1) + (t2 - t0); } constexpr TLFLOAT_INLINE bool eq(BigUInt const& rhs) const { return low.eq(rhs.low) && high.eq(rhs.high); } constexpr TLFLOAT_INLINE bool operator==(BigUInt const& rhs) const { return eq(rhs); } constexpr TLFLOAT_INLINE bool operator!=(BigUInt const& rhs) const { return !eq(rhs); } constexpr TLFLOAT_INLINE int compare(BigUInt const& rhs) const { int c = high.compare(rhs.high); if (c == 0) return low.compare(rhs.low); return c; } constexpr TLFLOAT_INLINE bool operator> (BigUInt const& rhs) const { return compare(rhs) > 0; } constexpr TLFLOAT_INLINE bool operator< (BigUInt const& rhs) const { return rhs > *this; } constexpr TLFLOAT_INLINE bool operator<=(BigUInt const& rhs) const { return !(*this > rhs); } constexpr TLFLOAT_INLINE bool operator>=(BigUInt const& rhs) const { return !(*this < rhs); } constexpr TLFLOAT_INLINE BigUInt operator&(const BigUInt& rhs) const { return BigUInt(high & rhs.high, low & rhs.low); } constexpr TLFLOAT_INLINE BigUInt operator|(const BigUInt& rhs) const { return BigUInt(high | rhs.high, low | rhs.low); } constexpr TLFLOAT_INLINE BigUInt operator^(const BigUInt& rhs) const { return BigUInt(high ^ rhs.high, low ^ rhs.low); } constexpr TLFLOAT_INLINE BigUInt operator~() const { return BigUInt(~high, ~low); } constexpr TLFLOAT_INLINE BigUInt operator<<(int n) const { if (n > 0) { if (n >= (1 << N)) return uint64_t(0); return BigUInt((high << n) | (low >> ((1 << (N-1)) - n)) , (low << n)); } else if (n < 0) { if (n <= -(1 << N)) return uint64_t(0); return BigUInt((high >> -n) , (high << ((1 << (N-1)) + n)) | (low >> -n)); } return *this; } constexpr TLFLOAT_INLINE BigUInt operator>>(int n) const { return *this << -n; } constexpr TLFLOAT_INLINE BigUInt& operator<<=(int n) { *this = *this << n; return *this; } constexpr TLFLOAT_INLINE BigUInt& operator>>=(int n) { *this = *this >> n; return *this; } // template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigUInt operator+(const rhstype &rhs) const { return operator+(BigUInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigUInt operator-(const rhstype &rhs) const { return operator-(BigUInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigUInt operator*(const rhstype &rhs) const { return operator*(BigUInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigUInt operator/(const rhstype &rhs) const { return operator/(BigUInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigUInt operator%(const rhstype &rhs) const { return operator%(BigUInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigUInt operator&(const rhstype &rhs) const { return operator&(BigUInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigUInt operator|(const rhstype &rhs) const { return operator|(BigUInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigUInt operator^(const rhstype &rhs) const { return operator^(BigUInt(rhs)); } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigUInt operator+(const lhstype c, const BigUInt& rhs) { return BigUInt(c) + rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigUInt operator-(const lhstype c, const BigUInt& rhs) { return BigUInt(c) - rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigUInt operator*(const lhstype c, const BigUInt& rhs) { return BigUInt(c) * rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigUInt operator/(const lhstype c, const BigUInt& rhs) { return BigUInt(c) / rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigUInt operator%(const lhstype c, const BigUInt& rhs) { return BigUInt(c) % rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigUInt operator&(const lhstype c, const BigUInt& rhs) { return BigUInt(c) & rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigUInt operator|(const lhstype c, const BigUInt& rhs) { return BigUInt(c) | rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigUInt operator^(const lhstype c, const BigUInt& rhs) { return BigUInt(c) ^ rhs; } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE bool operator==(const rhstype& rhs) const { return operator==(BigUInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE bool operator!=(const rhstype& rhs) const { return operator!=(BigUInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE bool operator> (const rhstype& rhs) const { return operator> (BigUInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE bool operator< (const rhstype& rhs) const { return operator< (BigUInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE bool operator>=(const rhstype& rhs) const { return operator>=(BigUInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE bool operator<=(const rhstype& rhs) const { return operator<=(BigUInt(rhs)); } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend bool operator==(const lhstype& lhs, const BigUInt& rhs) { return BigUInt(lhs) == rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend bool operator!=(const lhstype& lhs, const BigUInt& rhs) { return BigUInt(lhs) != rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend bool operator> (const lhstype& lhs, const BigUInt& rhs) { return BigUInt(lhs) > rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend bool operator< (const lhstype& lhs, const BigUInt& rhs) { return BigUInt(lhs) < rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend bool operator>=(const lhstype& lhs, const BigUInt& rhs) { return BigUInt(lhs) >= rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend bool operator<=(const lhstype& lhs, const BigUInt& rhs) { return BigUInt(lhs) <= rhs; } // template constexpr TLFLOAT_INLINE BigUInt& operator=(const srctype& s) { BigUInt n(s); *this = n; return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator+=(const rhstype& rhs) { *this = *this + BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator-=(const rhstype& rhs) { *this = *this - BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator*=(const rhstype& rhs) { *this = *this * BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator/=(const rhstype& rhs) { *this = *this / BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator%=(const rhstype& rhs) { *this = *this % BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator&=(const rhstype& rhs) { *this = *this & BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator|=(const rhstype& rhs) { *this = *this | BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator^=(const rhstype& rhs) { *this = *this ^ BigUInt(rhs); return *this; } constexpr TLFLOAT_INLINE BigUInt& operator+=(bool rhs) { if (rhs) *this = this->inc().first; return *this; } // /** This method performs division and modulo at a time. Give rhs.reciprocal() as the second argument */ constexpr TLFLOAT_INLINE BigUInt divmod(const BigUInt& rhs, const BigUInt& recip, BigUInt* mod) const { if (rhs == 1) { *mod = 0; return *this; } BigUInt q = this->mulhi(recip), m = *this - q * rhs; if (!(rhs > m)) { q++; m = m - rhs; } if (mod) *mod = m; return q; } /** This method performs division and modulo at a time. Give rhs.reciprocal() as the second argument */ constexpr TLFLOAT_INLINE xpair divmod(const BigUInt& rhs, const BigUInt& recip) const { if (rhs == 1) return xpair(*this, 0); BigUInt q = this->mulhi(recip), m = *this - q * rhs; if (!(rhs > m)) { q++; m = m - rhs; } return xpair(q, m); } /** This method performs division and modulo at a time. */ constexpr TLFLOAT_INLINE xpair divmod(const BigUInt& rhs) const { return div(*this, rhs); } /** This method finds the quotient and remainder of (*this << ((1 << N)-1)) divided by (rhs | (1 << ((1 << N)-1))) at a time. Give rhs.reciprocal2() as the second argument. */ constexpr TLFLOAT_INLINE xpair divmod2(const BigUInt& rhs, const BigUInt& recip2) const { BigUInt q = (mulhi(recip2) >> 1) + (*this >> 1); BigUInt rhs2 = rhs | (BigUInt(1) << ((1 << N)-1)); BigUInt r = (BigUInt(*this) << ((1 << N)-1)) - BigUInt::mul(q, rhs2); if (r.bit((1 << (N+1))-1)) { q--; r += rhs2; } else if (!(rhs2 > r)) { q++; r -= rhs2; } return xpair(q, (BigUInt)r); } /** This method finds the quotient and remainder of (*this << ((1 << N)-1)) divided by (rhs | (1 << ((1 << N)-1))) at a time. */ constexpr TLFLOAT_INLINE xpair divmod2(const BigUInt& rhs) const { return div(BigUInt(*this) << ((1 << N)-1), rhs | (BigUInt(1) << ((1 << N)-1))); } constexpr TLFLOAT_INLINE BigUInt mod(const BigUInt& rhs, const BigUInt& recip) const { if (rhs == 1) return 0; BigUInt q = this->mulhi(recip), m = *this - q * rhs; return m >= rhs ? m - rhs : m; } constexpr BigUInt pow(BigUInt e, const BigUInt& m = 0, BigUInt recm = 0) const { if (m == 1) return 0; bool mIsZero = m.isZero(); if (!mIsZero && recm.isZero()) recm = m.reciprocal(); BigUInt r = 1, b = *this; if (!mIsZero) b = b.mod(m, recm); while(e > 0) { if (e.getWord(0) & 1) { r *= b; if (!mIsZero) r = r.mod(m, recm); } e >>= 1; b *= b; if (!mIsZero) b = b.mod(m, recm); } return r; } constexpr BigUInt gcd(BigUInt b) const { BigUInt a = *this; while(!b.isZero()) { BigUInt t = b; b = a % b; a = t; } return a; } // constexpr TLFLOAT_NOINLINE BigUInt(const char *p_, const char **endptr = nullptr, const int base_ = 10) { const char *p = p_; bool success = false; while(*p == ' ') p++; bool sign = false; if (*p == '-') { p++; sign = true; } else if (*p == '+') { p++; } int base = base_; if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X') && (base_ == 0 || base_ == 16)) { base = 16; p += 2; } else if (*p == '0' && (base_ == 0 || base_ == 8)) { base = 8; p += 1; success = true; } else if (base_ == 0) { base = 10; } if (base < 2 || base > 36) { low = high = 0; return; } BigUInt r; uint64_t u = 0, d = 1; while(*p != '\0') { int x = 0; if (('0' <= *p && *p <= '9')) { x = *p - '0'; } else if ('a' <= *p && *p <= 'z') { x = *p - 'a' + 10; } else if ('A' <= *p && *p <= 'Z') { x = *p - 'A' + 10; } else break; if (x >= base) break; u = u * base + x; d *= base; if (d >= (~uint64_t(0)) / base - 1) { r = r * d + u; u = 0; d = 1; } p++; success = true; } r = r * d + u; low = r.low; high = r.high; if (endptr) *endptr = success ? p : p_; if (sign) *this = 1 + ~(*this); } class Montgomery { BigUInt ninv(BigUInt n) { BigUInt nr(1); for (int i = 0; i < N; i++) nr *= 2 - n * nr; return nr; } public: const BigUInt n, nr; const BigUInt recn; const BigUInt one; constexpr Montgomery(BigUInt n) : n(n), nr(ninv(n)), recn(BigUInt(n).reciprocal()), one(transform(1)) {} Montgomery& operator=(const Montgomery&) = delete; Montgomery(Montgomery&) = delete; constexpr BigUInt reduce(const BigUInt& x) const { BigUInt q = x.low * nr; BigUInt m = q.mulhi(n); BigUInt y = x.high - m; return x.high < m ? y + n : y; } constexpr BigUInt mul(const BigUInt& x, const BigUInt& y) const { return reduce(BigUInt::mul(x, y)); } constexpr BigUInt transform(const BigUInt& x) const { return BigUInt(x, 0).mod(n, recn).low; } constexpr BigUInt pow(BigUInt a, BigUInt e) const { // a is in Montgomery representation BigUInt r = one; for (;;) { if (e.getWord(0) & 1) r = mul(r, a); e >>= 1; if (e.isZero()) break; a = mul(a, a); } return r; // r is in Montgomery representation } }; }; template<> class BigUInt<6> { public: uint64_t u64 = 0; private: constexpr TLFLOAT_INLINE xpair inc() const { xpair s = { 0, false }; s.first = u64 + 1; s.second = s.first == 0; return s; } constexpr TLFLOAT_INLINE xpair dec() const { xpair s = { 0, false }; s.second = u64 == 0; s.first = u64 - 1; return s; } constexpr TLFLOAT_INLINE xpair adc(const BigUInt& rhs, bool c) const { xpair s = { 0, false }; xpair ub = detail::adc64(c, u64, rhs.u64); s.first = ub.first; s.second = ub.second; return s; } constexpr TLFLOAT_INLINE xpair sbc(const BigUInt& rhs, bool c) const { xpair s = { 0, false }; xpair ub = detail::sbc64(c, u64, rhs.u64); s.first = ub.first; s.second = ub.second; return s; } constexpr TLFLOAT_INLINE BigUInt reciprocalAprx() const { BigUInt x(((~0ULL) / (u64 >> 32)) << 31); return (BigUInt(uint64_t(0)) - mulhi(x)).mulhi(x) << 1; } constexpr TLFLOAT_INLINE BigUInt mulhi(const BigUInt& rhs) const { return detail::mul128(u64, rhs.u64).first; } constexpr TLFLOAT_INLINE BigUInt mulhiAprx(const BigUInt& rhs) const { return mulhi(rhs); } static constexpr TLFLOAT_INLINE xpair div(BigUInt<7> u, BigUInt d) { assert(u.high.u64 < d.u64); auto a = detail::divmod128_64(u.high.u64, u.low.u64, d.u64); return xpair { a.first, a.second }; } public: template friend class BigUInt; template friend class BigInt; constexpr TLFLOAT_INLINE explicit BigUInt(const uint64_t *p) : u64(*p) {} constexpr TLFLOAT_INLINE bool isZero() const { return u64 == 0; } constexpr TLFLOAT_INLINE bool isZero2() const { return u64 == 0; } constexpr TLFLOAT_INLINE bool isAllOne() const { return u64 == ~uint64_t(0); } constexpr TLFLOAT_INLINE bool msb() const { return u64 >> 63; } constexpr TLFLOAT_INLINE uint64_t getWord(unsigned idx) const { return u64; } constexpr TLFLOAT_INLINE void setWord(unsigned idx, uint64_t u) { u64 = u; } constexpr TLFLOAT_INLINE bool eq(BigUInt const& rhs) const { return u64 == rhs.u64; } constexpr TLFLOAT_INLINE BigUInt& operator=(const BigUInt &u) = default; constexpr TLFLOAT_INLINE BigUInt operator+(const BigUInt& rhs) const { return u64 + rhs.u64; } constexpr TLFLOAT_INLINE BigUInt operator-(const BigUInt& rhs) const { return u64 - rhs.u64; } constexpr TLFLOAT_INLINE BigUInt operator*(const BigUInt& rhs) const { return u64 * rhs.u64; } constexpr TLFLOAT_INLINE BigUInt operator/(const BigUInt& rhs) const { return u64 / rhs.u64; } constexpr TLFLOAT_INLINE BigUInt operator%(const BigUInt& rhs) const { return u64 % rhs.u64; } constexpr TLFLOAT_INLINE BigUInt operator-() const { return 1 + ~u64; } constexpr TLFLOAT_INLINE BigUInt& operator++() { *this = u64+1; return *this; } constexpr TLFLOAT_INLINE BigUInt& operator--() { *this = u64-1; return *this; } constexpr TLFLOAT_INLINE BigUInt operator++(int) { BigUInt t = *this; *this = u64+1; return t; } constexpr TLFLOAT_INLINE BigUInt operator--(int) { BigUInt t = *this; *this = u64-1; return t; } constexpr TLFLOAT_INLINE bool operator==(BigUInt const& rhs) const { return u64 == rhs.u64; } constexpr TLFLOAT_INLINE bool operator!=(BigUInt const& rhs) const { return !(*this == rhs); } constexpr TLFLOAT_INLINE bool operator> (BigUInt const& rhs) const { return u64 > rhs.u64; } constexpr TLFLOAT_INLINE bool operator>=(BigUInt const& rhs) const { return u64 >= rhs.u64; } template constexpr TLFLOAT_INLINE BigUInt& operator+=(const rhstype& rhs) { *this = *this + BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator-=(const rhstype& rhs) { *this = *this - BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator*=(const rhstype& rhs) { *this = *this * BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator/=(const rhstype& rhs) { *this = *this / BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator%=(const rhstype& rhs) { *this = *this % BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator&=(const rhstype& rhs) { *this = *this & BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator|=(const rhstype& rhs) { *this = *this | BigUInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigUInt& operator^=(const rhstype& rhs) { *this = *this ^ BigUInt(rhs); return *this; } constexpr TLFLOAT_INLINE int compare(BigUInt const& rhs) const { if (u64 > rhs.u64) return +1; if (u64 < rhs.u64) return -1; return 0; } constexpr TLFLOAT_INLINE BigUInt operator&(const BigUInt& rhs) const { return u64 & rhs.u64; } constexpr TLFLOAT_INLINE BigUInt operator|(const BigUInt& rhs) const { return u64 | rhs.u64; } constexpr TLFLOAT_INLINE BigUInt operator^(const BigUInt& rhs) const { return u64 ^ rhs.u64; } constexpr TLFLOAT_INLINE BigUInt operator~() const { return ~u64; } constexpr TLFLOAT_INLINE BigUInt operator<<(int n) const { return (n > 63 || n < -63) ? 0 : n >= 0 ? (u64 << n) : (u64 >> -n); } constexpr TLFLOAT_INLINE BigUInt operator>>(int n) const { return *this << -n; } constexpr TLFLOAT_INLINE unsigned clz() const { return detail::clz64(u64); } // constexpr TLFLOAT_INLINE BigUInt() = default; constexpr TLFLOAT_INLINE BigUInt(const BigUInt &m) = default; constexpr TLFLOAT_INLINE BigUInt(uint64_t u) : u64(u) {} constexpr TLFLOAT_INLINE explicit operator unsigned long long int() const { return (unsigned long long)u64; } constexpr TLFLOAT_INLINE explicit operator unsigned long int() const { return (unsigned long)u64; } constexpr TLFLOAT_INLINE BigUInt(const BigUInt<7>& h) : BigUInt(h.low) {} constexpr TLFLOAT_INLINE BigUInt reciprocal2() const { BigUInt t0 = ((BigUInt(1) << ((1 << 6)-1)) | *this); BigUInt t1 = t0.reciprocalAprx() << 1; BigUInt t2 = -t0.mulhi(t1); return t2.mulhi(t1) + (-t0).mulhi(t1) + (t2 - t0); } constexpr TLFLOAT_INLINE xpair divmod2(const BigUInt& rhs, const BigUInt& recip2) const { BigUInt q = (mulhi(recip2) >> 1) + (*this >> 1); BigUInt rhs2 = rhs | (BigUInt(1) << ((1 << 6)-1)); BigUInt<7> r = (BigUInt<7>(*this) << ((1 << 6)-1)) - BigUInt<7>::mul(q, rhs2); if (r.bit((1 << 7)-1)) { q--; r += rhs2; } else if (!(rhs2 > r)) { q++; r -= rhs2; } return xpair(q, (BigUInt)r); } constexpr TLFLOAT_INLINE xpair divmod2(const BigUInt& rhs) const { return div(BigUInt<7>(*this) << ((1 << 6)-1), rhs | (1ULL << ((1 << 6)-1))); } constexpr TLFLOAT_INLINE xpair divmod(const BigUInt& rhs) const { return xpair { *this / rhs, *this % rhs }; } }; /** * This is a trivially copyable template class that represents an * arbitrary precision signed integer. It can represent an integer * between -(2^(N-1)) and 2^(N-1)-1. The data size of an object is * N bits, where N must be 7 or greater. */ template class BigInt { static_assert(N >= 7, "N must be 7 or larger"); BigUInt u = 0; template friend class BigUInt; template friend class BigInt; public: constexpr TLFLOAT_INLINE BigInt() = default; /** Cast from any primitive signed integer */ template && !std::is_unsigned_v && sizeof(T) <= 8), int> = 0> constexpr TLFLOAT_INLINE BigInt(T i) : u(i < 0 ? -BigUInt(uint64_t(-int64_t(i))) : BigUInt(uint64_t(i))) {} /** Cast from any primitive unsigned integer */ template && std::is_unsigned_v && sizeof(T) <= 8), int> = 0> constexpr TLFLOAT_INLINE BigInt(T u) : u(BigUInt(u)) {} /** Cast to any primitive signed integer */ template && !std::is_unsigned_v && sizeof(T) <= 8 && !std::is_same_v), int> = 0> constexpr TLFLOAT_INLINE explicit operator T() const { return T(u.getWord(0)); } /** Cast to any primitive unsigned integer */ template && std::is_unsigned_v && sizeof(T) <= 8 && !std::is_same_v), int> = 0> constexpr TLFLOAT_INLINE explicit operator T() const { return int64_t(*this); } constexpr TLFLOAT_INLINE explicit operator bool() const { return !u.isZero(); } #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 constexpr TLFLOAT_INLINE BigInt(__int128_t u) : BigInt(BigUInt(__uint128_t(u))) {} constexpr TLFLOAT_INLINE explicit operator __int128_t() const { return (__int128_t)BigUInt(*this); } constexpr TLFLOAT_INLINE explicit BigInt(__uint128_t u) : BigInt(BigUInt(u)) {} constexpr TLFLOAT_INLINE explicit operator __uint128_t() const { return (__uint128_t)BigUInt(*this); } #endif constexpr TLFLOAT_INLINE explicit BigInt(const BigUInt& up) : u(up) {} template* = nullptr> constexpr TLFLOAT_INLINE BigInt(const BigInt& l) : BigInt(BigInt(l)) {} template* = nullptr> constexpr TLFLOAT_INLINE BigInt(const BigInt& l) : u(BigUInt(l.u.msb() ? ~BigUInt(0) : BigUInt(0), l.u)) {} constexpr TLFLOAT_INLINE BigInt(const BigInt& m) = default; template* = nullptr> constexpr TLFLOAT_INLINE BigInt(const BigInt& h) : u(BigUInt(h.u.low)) {} template (N+1))>* = nullptr> constexpr TLFLOAT_INLINE explicit BigInt(const BigInt& h) : BigInt(BigInt(h)) {} constexpr TLFLOAT_INLINE BigInt(const uint64_t *p) : u(p) {} constexpr TLFLOAT_INLINE explicit BigInt(double d) : u(d < 0 ? -BigUInt(-d) : BigUInt(d)) {} constexpr TLFLOAT_INLINE explicit operator double() const { return u.msb() ? -double(-u) : double(u); } constexpr TLFLOAT_INLINE operator BigUInt() const { return u; } constexpr TLFLOAT_INLINE BigInt abs() const { return BigInt(u.msb() ? -u : u); } constexpr TLFLOAT_INLINE BigInt& operator=(const BigInt &ip) = default; constexpr TLFLOAT_INLINE BigInt& operator++() { u = u.inc().first; return *this; } constexpr TLFLOAT_INLINE BigInt operator++(int) { BigInt t = *this; u = u.inc().first; return t; } constexpr TLFLOAT_INLINE BigInt& operator--() { u = u.dec().first; return *this; } constexpr TLFLOAT_INLINE BigInt operator--(int) { BigInt t = *this; u = u.dec().first; return t; } constexpr TLFLOAT_INLINE BigInt operator+(const BigInt& rhs) const { return BigInt(u + rhs.u); } constexpr TLFLOAT_INLINE BigInt operator-(const BigInt& rhs) const { return BigInt(u - rhs.u); } constexpr TLFLOAT_INLINE BigInt operator-() const { return BigInt(-u); } constexpr TLFLOAT_INLINE BigInt operator+() const { return BigInt(u); } constexpr TLFLOAT_INLINE BigInt operator*(const BigInt& rhs) const { return BigInt(u * rhs.u); } constexpr TLFLOAT_INLINE BigInt operator/(const BigInt& rhs) const { BigUInt m = abs().u / rhs.abs().u; return BigInt((u.msb() ^ rhs.u.msb()) ? -m : m); } constexpr TLFLOAT_INLINE BigInt operator%(const BigInt& rhs) const { BigUInt m = abs().u % rhs.abs().u; return BigInt(u.msb() ? -m : m); } constexpr TLFLOAT_INLINE bool isNegative() const { return u.msb(); } constexpr TLFLOAT_INLINE bool isZero() const { return u.isZero(); } constexpr TLFLOAT_INLINE BigInt divmod(const BigInt& rhs, const BigUInt& recip, BigInt* mod) const { BigUInt r, q = abs().u.divmod(rhs.abs().u, recip, &r); if (u.msb() ^ rhs.u.msb()) { q = -q; r = -r; } *mod = BigInt(r); return BigInt(q); } constexpr TLFLOAT_INLINE BigInt pow(BigUInt e, const BigUInt& m = 0, BigUInt recm = 0) const { BigInt p = (BigInt)abs().u.pow(e, m, recm); if (isNegative() && (e.getWord(0) & 1) == 1) p = -p; return p; } constexpr TLFLOAT_INLINE BigUInt reciprocal() const { return u.reciprocal(); } constexpr TLFLOAT_INLINE int64_t getWord(unsigned idx) const { return u.getWord(idx); } constexpr TLFLOAT_INLINE bool operator==(BigInt const& rhs) const { return u.eq(rhs.u); } constexpr TLFLOAT_INLINE bool operator!=(BigInt const& rhs) const { return !u.eq(rhs.u); } constexpr TLFLOAT_INLINE int compare(BigInt const& rhs) const { if (u.msb()) { if (!rhs.u.msb()) return -1; return u.compare(rhs.u); } else { if (rhs.u.msb()) return +1; return u.compare(rhs.u); } } constexpr TLFLOAT_INLINE bool operator> (BigInt const& rhs) const { return compare(rhs) > 0; } constexpr TLFLOAT_INLINE bool operator< (BigInt const& rhs) const { return rhs > *this; } constexpr TLFLOAT_INLINE bool operator<=(BigInt const& rhs) const { return !(*this > rhs); } constexpr TLFLOAT_INLINE bool operator>=(BigInt const& rhs) const { return !(*this < rhs); } constexpr TLFLOAT_INLINE BigInt operator&(const BigInt& rhs) const { return BigInt(u & rhs.u); } constexpr TLFLOAT_INLINE BigInt operator|(const BigInt& rhs) const { return BigInt(u | rhs.u); } constexpr TLFLOAT_INLINE BigInt operator^(const BigInt& rhs) const { return BigInt(u ^ rhs.u); } constexpr TLFLOAT_INLINE BigInt operator~() const { return BigInt(~u); } constexpr TLFLOAT_INLINE BigInt operator>>(int n) const { if (!u.msb()) return BigInt(u >> n); return BigInt((u >> n) | ((~BigUInt(0)) << ((1 << N) - n))); } constexpr TLFLOAT_INLINE BigInt operator<<(int n) const { return BigInt(u << n); } constexpr TLFLOAT_INLINE BigInt& operator>>=(int n) { *this = *this >> n; return *this; } constexpr TLFLOAT_INLINE BigInt& operator<<=(int n) { *this = *this << n; return *this; } // template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigInt operator+(const rhstype &rhs) const { return operator+(BigInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigInt operator-(const rhstype &rhs) const { return operator-(BigInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigInt operator*(const rhstype &rhs) const { return operator*(BigInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigInt operator/(const rhstype &rhs) const { return operator/(BigInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigInt operator%(const rhstype &rhs) const { return operator%(BigInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigInt operator&(const rhstype &rhs) const { return operator&(BigInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigInt operator|(const rhstype &rhs) const { return operator|(BigInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE BigInt operator^(const rhstype &rhs) const { return operator^(BigInt(rhs)); } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigInt operator+(const lhstype c, const BigInt& rhs) { return BigInt(c) + rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigInt operator-(const lhstype c, const BigInt& rhs) { return BigInt(c) - rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigInt operator*(const lhstype c, const BigInt& rhs) { return BigInt(c) * rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigInt operator/(const lhstype c, const BigInt& rhs) { return BigInt(c) / rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigInt operator%(const lhstype c, const BigInt& rhs) { return BigInt(c) % rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigInt operator&(const lhstype c, const BigInt& rhs) { return BigInt(c) & rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigInt operator|(const lhstype c, const BigInt& rhs) { return BigInt(c) | rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend BigInt operator^(const lhstype c, const BigInt& rhs) { return BigInt(c) ^ rhs; } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE bool operator==(const rhstype& rhs) const { return operator==(BigInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE bool operator!=(const rhstype& rhs) const { return operator!=(BigInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE bool operator> (const rhstype& rhs) const { return operator> (BigInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE bool operator< (const rhstype& rhs) const { return operator< (BigInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE bool operator>=(const rhstype& rhs) const { return operator>=(BigInt(rhs)); } template || (sizeof(rhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE bool operator<=(const rhstype& rhs) const { return operator<=(BigInt(rhs)); } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend bool operator==(const lhstype& lhs, const BigInt& rhs) { return BigInt(lhs) == rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend bool operator!=(const lhstype& lhs, const BigInt& rhs) { return BigInt(lhs) != rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend bool operator> (const lhstype& lhs, const BigInt& rhs) { return BigInt(lhs) > rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend bool operator< (const lhstype& lhs, const BigInt& rhs) { return BigInt(lhs) < rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend bool operator>=(const lhstype& lhs, const BigInt& rhs) { return BigInt(lhs) >= rhs; } template || (sizeof(lhstype) < (8 << (N - 6)) && !std::is_floating_point_v)), int> = 0> constexpr TLFLOAT_INLINE friend bool operator<=(const lhstype& lhs, const BigInt& rhs) { return BigInt(lhs) <= rhs; } // template constexpr TLFLOAT_INLINE BigInt& operator=(const srctype& s) { BigInt n(s); *this = n; return *this; } template constexpr TLFLOAT_INLINE BigInt& operator+=(const rhstype& rhs) { *this = *this + BigInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigInt& operator-=(const rhstype& rhs) { *this = *this - BigInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigInt& operator*=(const rhstype& rhs) { *this = *this * BigInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigInt& operator/=(const rhstype& rhs) { *this = *this / BigInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigInt& operator%=(const rhstype& rhs) { *this = *this % BigInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigInt& operator&=(const rhstype& rhs) { *this = *this & BigInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigInt& operator|=(const rhstype& rhs) { *this = *this | BigInt(rhs); return *this; } template constexpr TLFLOAT_INLINE BigInt& operator^=(const rhstype& rhs) { *this = *this ^ BigInt(rhs); return *this; } // constexpr TLFLOAT_INLINE BigInt(const char *p, const char **endptr = nullptr, const int base = 10) { u = BigUInt(p, endptr, base); } TLFLOAT_NOINLINE static int snprint(char *cbuf, size_t bufsize, BigInt value, char typespec = 'd', int width = 0, int precision = -1, int base = 10, int nbits = 1 << N, bool flag_sign = false, bool flag_blank = false, bool flag_alt = false, bool flag_left = false, bool flag_zero = false, bool flag_upper = false, bool flag_unsigned = false, bool flag_ptr = false, const char *prefix = "") { detail::SafeArray buf(cbuf, bufsize); if (width > (int)bufsize) width = bufsize; if (typespec == 'u' || typespec == 'o' || typespec == 'x' || typespec == 'X') flag_unsigned = true; if (nbits < (1 << N)) { bool signbit = value < 0; value &= (BigUInt(1) << nbits) - 1; if (!flag_unsigned && signbit) value |= ~BigUInt(0) & ~((BigUInt(1) << nbits) - 1); } int sign = 0; if (!flag_unsigned) { if (value < 0) { value = -value; sign = '-'; } else if (flag_sign) { sign = '+'; } else if (flag_blank) { sign = ' '; } } int64_t idx = bufsize-1; const char *digits = flag_upper ? "0123456789ABCDEF" : "0123456789abcdef"; int length = 0; if (flag_ptr && value == 0) { buf.memmove(idx-5, "(nil)", 5); idx -= 5; } else { if (flag_unsigned) { BigUInt u = value; do { buf[--idx] = digits[int(u % base)]; u /= base; } while(u > 0); } else { BigInt v = value; do { buf[--idx] = digits[int(v % base)]; v /= base; } while(v > 0); } if (precision == 0 && value == 0) idx++; length = bufsize-1 - idx; for(int i = precision-length;i > 0;i--) buf[--idx] = '0'; if (sign) buf[--idx] = sign; if (flag_alt) { if (!(base == 8 && buf[idx] == '0') && !(base != 8 && value == 0)) { int prefixlen = strlen(prefix); buf.memmove(idx - prefixlen, prefix, prefixlen); idx -= prefixlen; } } } length = bufsize-1 - idx; if (!flag_left) { for(int i=0;i) == (1 << ( 6-3))); static_assert(sizeof(BigUInt< 7>) == (1 << ( 7-3))); static_assert(sizeof(BigUInt< 8>) == (1 << ( 8-3))); static_assert(sizeof(BigUInt< 9>) == (1 << ( 9-3))); static_assert(sizeof(BigUInt<10>) == (1 << (10-3))); static_assert(sizeof(BigInt< 7>) == (1 << ( 7-3))); static_assert(sizeof(BigInt< 8>) == (1 << ( 8-3))); static_assert(sizeof(BigInt< 9>) == (1 << ( 9-3))); static_assert(sizeof(BigInt<10>) == (1 << (10-3))); static_assert(std::is_trivially_copyable_v>); static_assert(std::is_trivially_copyable_v>); static_assert(std::is_trivially_copyable_v>); static_assert(std::is_trivially_copyable_v>); static_assert(std::is_trivially_copyable_v>); static_assert(std::is_trivially_copyable_v>); static_assert(std::is_trivially_copyable_v>); static_assert(std::is_trivially_copyable_v>); static_assert(std::is_trivially_copyable_v>); } #if defined(TLFLOAT_DOXYGEN) || !defined(TLFLOAT_NO_LIBSTDCXX) #include #include #include #include namespace tlfloat { #ifndef TLFLOAT_DOXYGEN inline std::string toHexString(const uint64_t u) { char buf[17]; snprintf(buf, 17, "%016llx", (unsigned long long)u); return std::string(buf); } inline std::string toHexString(uint32_t x) { return toHexString(uint64_t(x)); } inline std::string toHexString(uint16_t x) { return toHexString(uint64_t(x)); } inline std::string toHexString(const BigUInt<6> &u) { return toHexString(u.u64); } template static std::string toHexString(const BigUInt& u) { return toHexString(u.high) + toHexString(u.low); } template static std::string toHexString(const BigInt& u) { return toHexString(u.u); } #endif inline std::ostream& operator<<(std::ostream &os, const BigUInt<6>& u) { return os << u.u64; } template std::string to_string(const BigUInt& u) { std::vector s((1 << N)/3 + 4); BigInt::snprint(s.data(), s.size() - 1, BigInt(u), 'u'); return std::string(s.data()); } template static std::ostream& operator<<(std::ostream &os, const BigUInt& u) { std::vector buf(1000); std::ios_base::fmtflags f = os.flags(); char typespec = 'u'; int base = 10; if ((f & os.hex) != 0) { typespec = 'x'; base = 16; } if ((f & os.oct) != 0) { typespec = 'o'; base = 8; } BigInt::snprint(buf.data(), buf.size(), BigInt(u), typespec, os.width(), -1, base, 1 << N, false, false, false, (f & std::ios::left) != 0, false, (f & std::ios::uppercase) != 0); return os << buf.data(); } template std::string to_string(const BigInt& i) { std::vector s((1 << N)/3 + 4); BigInt::snprint(s.data(), s.size() - 1, i, 'd'); return std::string(s.data()); } template static std::ostream& operator<<(std::ostream &os, const BigInt& d) { std::vector buf(1000); std::ios_base::fmtflags f = os.flags(); char typespec = 'd'; int base = 10; if ((f & os.hex) != 0) { typespec = 'x'; base = 16; } if ((f & os.oct) != 0) { typespec = 'o'; base = 8; } BigInt::snprint(buf.data(), buf.size(), d, typespec, os.width(), -1, base, 1 << N, false, false, false, (f & std::ios::left) != 0, false, (f & std::ios::uppercase) != 0); return os << buf.data(); } } #endif // #if defined(TLFLOAT_DOXYGEN) || !defined(TLFLOAT_NO_LIBSTDCXX) #endif // #ifndef __BIGINT_HPP_INCLUDED__ #if defined(__cplusplus) && defined(__TLFLOAT_H_INCLUDED__) #warning Include tlfloat/bigint.hpp first, then tlfloat/tlfloat.h. #endif tlfloat-1.15.0/src/include/tlfloat/rpitab.hpp000066400000000000000000014703351477036600700211430ustar00rootroot00000000000000#include namespace tlfloat { namespace detail { #ifndef __CUDA_ARCH__ static constexpr uint8_t tlfloat_rpitab[] = { #else static __device__ constexpr uint8_t tlfloat_rpitab[] = { #endif 0x51, 0x7c, 0xc1, 0xb7, 0x27, 0x22, 0x0a, 0x94, 0xfe, 0x13, 0xab, 0xe8, 0xfa, 0x9a, 0x6e, 0xe0, 0x6d, 0xb1, 0x4a, 0xcc, 0x9e, 0x21, 0xc8, 0x20, 0xff, 0x28, 0xb1, 0xd5, 0xef, 0x5d, 0xe2, 0xb0, 0xdb, 0x92, 0x37, 0x1d, 0x21, 0x26, 0xe9, 0x70, 0x03, 0x24, 0x97, 0x75, 0x04, 0xe8, 0xc9, 0x0e, 0x7f, 0x0e, 0xf5, 0x8e, 0x58, 0x94, 0xd3, 0x9f, 0x74, 0x41, 0x1a, 0xfa, 0x97, 0x5d, 0xa2, 0x42, 0x74, 0xce, 0x38, 0x13, 0x5a, 0x2f, 0xbf, 0x20, 0x9c, 0xc8, 0xeb, 0x1c, 0xc1, 0xa9, 0x9c, 0xfa, 0x4e, 0x42, 0x2f, 0xc5, 0xde, 0xfc, 0x94, 0x1d, 0x8f, 0xfc, 0x4b, 0xff, 0xef, 0x02, 0xcc, 0x07, 0xf7, 0x97, 0x88, 0xc5, 0xad, 0x05, 0x36, 0x8f, 0xb6, 0x9b, 0x3f, 0x67, 0x93, 0xe5, 0x84, 0xdb, 0xa7, 0xa3, 0x1f, 0xb3, 0x4f, 0x2f, 0xf5, 0x16, 0xba, 0x93, 0xdd, 0x63, 0xf5, 0xf2, 0xf8, 0xbd, 0x9e, 0x83, 0x9c, 0xfb, 0xc5, 0x29, 0x49, 0x75, 0x35, 0xfd, 0xaf, 0xd8, 0x8f, 0xc6, 0xae, 0x84, 0x2b, 0x01, 0x98, 0x23, 0x7e, 0x3d, 0xb5, 0xd5, 0xf8, 0x67, 0xde, 0x10, 0x4d, 0x7a, 0x1b, 0x0e, 0xd4, 0xf1, 0xc8, 0xb0, 0xaf, 0x73, 0x0d, 0x84, 0x32, 0xcc, 0xc2, 0xaf, 0x8a, 0x50, 0x34, 0x20, 0x46, 0xff, 0xec, 0x40, 0x26, 0xb9, 0x93, 0x98, 0x83, 0x03, 0x0a, 0xab, 0x65, 0x39, 0xd4, 0x64, 0xb0, 0x71, 0x3d, 0xe0, 0x46, 0x35, 0xa3, 0xe2, 0x0c, 0xe1, 0xb3, 0xe6, 0xee, 0x74, 0x04, 0x95, 0x41, 0xac, 0xe2, 0x3b, 0x45, 0xcb, 0x0e, 0x53, 0x6e, 0xd7, 0xa2, 0x68, 0xab, 0x8c, 0x82, 0x9f, 0x52, 0xff, 0x83, 0x82, 0x9f, 0xbf, 0x19, 0xf4, 0x19, 0x61, 0x6f, 0x27, 0xcc, 0x19, 0x3e, 0xdd, 0xe1, 0x9e, 0x93, 0x77, 0xb5, 0x8f, 0x2f, 0x7c, 0x4f, 0x9d, 0x0f, 0x9a, 0xe5, 0x79, 0x3f, 0x8e, 0xc3, 0xf8, 0x90, 0xc8, 0x3e, 0x3e, 0x12, 0x35, 0x7d, 0x37, 0x6a, 0xbb, 0x96, 0x98, 0x21, 0x9d, 0x8a, 0xe3, 0x0a, 0x5a, 0xce, 0x8c, 0xe1, 0xe1, 0x62, 0x56, 0xa0, 0xa6, 0x96, 0x2e, 0x80, 0x06, 0x23, 0x3e, 0xc3, 0x16, 0xb8, 0xf1, 0xcd, 0x63, 0x4d, 0x80, 0x31, 0x19, 0xbe, 0x69, 0x5a, 0x4b, 0xd3, 0xda, 0x6a, 0xaa, 0x9b, 0xfb, 0x1f, 0x6b, 0x8c, 0x08, 0x51, 0xfe, 0x3b, 0x26, 0x95, 0x4e, 0xb2, 0x55, 0xeb, 0xb8, 0x7c, 0x3e, 0x31, 0xab, 0xd8, 0x3d, 0x73, 0x8a, 0x8b, 0xab, 0x24, 0xe0, 0x6c, 0xeb, 0x1d, 0x9c, 0x42, 0x53, 0xe5, 0x91, 0x92, 0x3b, 0xc5, 0x6b, 0x11, 0xaa, 0x2d, 0x5c, 0x8f, 0x80, 0x0d, 0x85, 0x78, 0xef, 0xe7, 0x0c, 0xff, 0x98, 0xcf, 0xb5, 0x0f, 0x33, 0x30, 0xab, 0xcc, 0xa3, 0xfd, 0xd6, 0x6c, 0x3f, 0xbf, 0x5b, 0xb2, 0x91, 0x44, 0xf4, 0x19, 0x30, 0x5f, 0xf3, 0x66, 0xe2, 0x77, 0x84, 0x9b, 0x36, 0x6a, 0x1f, 0xae, 0xeb, 0xef, 0x0b, 0x6f, 0x1d, 0xac, 0x49, 0x4d, 0xef, 0x14, 0x11, 0x69, 0x74, 0x43, 0x14, 0x26, 0xac, 0x71, 0x19, 0x65, 0x63, 0x0b, 0x71, 0x84, 0x65, 0xbe, 0xf0, 0x28, 0x60, 0x0b, 0xd3, 0x8e, 0xf9, 0xad, 0xf0, 0x0c, 0x1a, 0x09, 0x97, 0x31, 0x09, 0x41, 0x80, 0xa4, 0x41, 0xad, 0xc7, 0x7a, 0xbf, 0xd8, 0x56, 0xf9, 0x74, 0x8f, 0x21, 0xa5, 0x24, 0x69, 0xb3, 0x88, 0x6c, 0x6e, 0xd5, 0x21, 0x2f, 0xd7, 0x67, 0x30, 0xb5, 0x52, 0x14, 0x05, 0x5a, 0x4c, 0xe9, 0xf9, 0x53, 0x03, 0x3f, 0xbb, 0xae, 0x41, 0xe1, 0x51, 0xc4, 0x1e, 0x30, 0xbc, 0x39, 0xc5, 0x2d, 0x46, 0x57, 0xde, 0xeb, 0xb7, 0xb1, 0xd3, 0x16, 0xe5, 0xdf, 0xfa, 0x77, 0xc0, 0xc6, 0xb3, 0xe0, 0x93, 0x22, 0xe5, 0x2a, 0x9b, 0x6c, 0xe5, 0x69, 0x54, 0x14, 0x46, 0xb0, 0xe1, 0x3b, 0xe4, 0x89, 0x0a, 0x13, 0x02, 0x4d, 0xa3, 0x09, 0x62, 0x2c, 0xe2, 0x22, 0x62, 0xe4, 0x48, 0xd9, 0x26, 0xf9, 0x8b, 0x80, 0x56, 0xa1, 0xea, 0x72, 0xa4, 0x94, 0x88, 0x6a, 0xfe, 0xfe, 0x5f, 0x00, 0x66, 0x4a, 0x0f, 0x77, 0x67, 0x38, 0x7a, 0x9f, 0x09, 0xc0, 0x78, 0xf6, 0x61, 0xf3, 0xd9, 0x94, 0x7c, 0x63, 0xca, 0x02, 0xc9, 0x9f, 0x38, 0xe0, 0xd9, 0x84, 0x97, 0x79, 0xa2, 0x85, 0xce, 0x09, 0x44, 0x3d, 0x90, 0x55, 0xcf, 0xda, 0x97, 0x61, 0x49, 0x23, 0x97, 0x99, 0x3d, 0xb6, 0xaa, 0x86, 0x48, 0x53, 0xb9, 0x0f, 0xf3, 0xb5, 0xcb, 0x65, 0x98, 0xa5, 0x0b, 0x3c, 0xf1, 0x3c, 0xa0, 0xc4, 0xef, 0xfa, 0x4b, 0xca, 0x74, 0x42, 0x73, 0x71, 0x4b, 0x98, 0xcc, 0xb5, 0xf6, 0xc4, 0x1b, 0x2f, 0xaf, 0x87, 0x7e, 0xdd, 0xda, 0x4d, 0x24, 0x36, 0x52, 0x33, 0xa1, 0x39, 0x38, 0x99, 0x2e, 0xc6, 0xdc, 0x0a, 0xcf, 0x84, 0xf2, 0xde, 0x12, 0x98, 0xc6, 0x9c, 0xba, 0x7b, 0x8e, 0x02, 0x98, 0x00, 0x86, 0x06, 0xb4, 0x04, 0x25, 0xac, 0x77, 0x16, 0x48, 0x55, 0x23, 0x81, 0x73, 0xba, 0x12, 0x6b, 0x5e, 0xd3, 0x3e, 0xfb, 0xb9, 0x24, 0x37, 0x77, 0x8b, 0x4f, 0xd3, 0x4a, 0x47, 0x7b, 0x48, 0xda, 0x28, 0xa9, 0xe8, 0xf9, 0x05, 0x67, 0x99, 0xcc, 0x10, 0x3f, 0x25, 0xfa, 0xb4, 0x31, 0xd9, 0x2f, 0x9f, 0x6e, 0x81, 0xae, 0xa0, 0x3f, 0xc4, 0xc2, 0x94, 0xa9, 0x2a, 0xe0, 0x32, 0x1b, 0x88, 0x6c, 0x36, 0x99, 0x24, 0x19, 0x3a, 0xa6, 0x2d, 0xea, 0x38, 0xa7, 0x37, 0x2a, 0x22, 0xe0, 0x84, 0x85, 0xb4, 0xfa, 0x95, 0x6a, 0xb3, 0x0a, 0x4e, 0x83, 0x93, 0xa8, 0x02, 0x2e, 0xed, 0x9d, 0xda, 0x62, 0xbb, 0x75, 0x0b, 0xfc, 0xc3, 0xbe, 0xb5, 0xa4, 0xdd, 0x13, 0x8e, 0x94, 0xb4, 0xcb, 0x56, 0x66, 0x63, 0x2a, 0x0a, 0x56, 0xb5, 0x71, 0x48, 0x44, 0xec, 0xc4, 0x28, 0x39, 0x16, 0x5f, 0x52, 0x02, 0x4a, 0x03, 0xbb, 0xb8, 0x18, 0x79, 0x93, 0xfe, 0x00, 0x54, 0x38, 0xf5, 0x24, 0xe1, 0x33, 0x1e, 0xf0, 0x32, 0x41, 0xee, 0xcb, 0xcb, 0x9f, 0xd1, 0xfe, 0xca, 0x21, 0xc6, 0x43, 0x06, 0xef, 0x20, 0x98, 0xce, 0x9c, 0xc9, 0x46, 0x38, 0x6e, 0xf3, 0xdb, 0x8b, 0x9d, 0xef, 0x84, 0x15, 0x9b, 0x8a, 0xd0, 0x40, 0x2e, 0x49, 0xc0, 0x2d, 0x49, 0x08, 0x88, 0x6c, 0x74, 0x07, 0xd7, 0xc0, 0x36, 0x25, 0xff, 0xed, 0x87, 0xc8, 0x1c, 0x3b, 0x0c, 0x2c, 0x8a, 0xd2, 0xb1, 0x5d, 0xe5, 0xb0, 0xdc, 0xc4, 0xe3, 0xde, 0xa0, 0x08, 0x02, 0x79, 0x69, 0x13, 0xba, 0xa4, 0xfb, 0x5b, 0x75, 0xdd, 0x91, 0x6d, 0xd5, 0x0a, 0x05, 0x17, 0x93, 0x44, 0xbb, 0x41, 0xb2, 0x19, 0x9d, 0x84, 0x8d, 0x4a, 0x07, 0x55, 0x1d, 0x28, 0xe1, 0x51, 0x8e, 0xd7, 0x76, 0xd7, 0x89, 0x13, 0x2e, 0x26, 0xe1, 0x36, 0xce, 0x3d, 0x16, 0xcb, 0xab, 0x60, 0x41, 0x9f, 0x81, 0xfb, 0x78, 0x04, 0xc6, 0x20, 0x15, 0xcc, 0x98, 0xb6, 0x83, 0xda, 0x1c, 0x8a, 0x90, 0x06, 0x2d, 0xe1, 0xec, 0x62, 0x49, 0x7a, 0xa5, 0xd6, 0xe3, 0x52, 0xe5, 0x27, 0x66, 0x9b, 0xd3, 0x9b, 0x54, 0xf3, 0x4a, 0x49, 0x55, 0xb4, 0x21, 0x6e, 0xef, 0x31, 0x8c, 0xf7, 0xc6, 0x3b, 0x29, 0x45, 0xb4, 0x1b, 0xed, 0xfe, 0x55, 0xd0, 0xd7, 0x18, 0x8a, 0xef, 0xd0, 0xd7, 0x00, 0x6d, 0x7d, 0x86, 0x33, 0x26, 0xb2, 0x5b, 0x82, 0xf6, 0x98, 0x32, 0x94, 0xdf, 0xab, 0x2b, 0x9d, 0x7f, 0xa3, 0xdc, 0xfc, 0xb5, 0x79, 0xdf, 0x3a, 0xef, 0xc9, 0x94, 0x18, 0x40, 0x55, 0xfb, 0x46, 0x33, 0x0a, 0xe5, 0x82, 0x03, 0x11, 0x7d, 0x0e, 0xf2, 0x6c, 0xd2, 0x59, 0x9e, 0xc7, 0x8d, 0xab, 0x84, 0xe6, 0x9b, 0x74, 0xa1, 0x27, 0x52, 0x5f, 0x09, 0xda, 0x91, 0x99, 0x8d, 0x55, 0x78, 0x54, 0x32, 0xa7, 0xd2, 0xe0, 0xe9, 0x07, 0x9f, 0x85, 0xe6, 0xbc, 0x2d, 0xbb, 0x7c, 0x91, 0x82, 0x45, 0xbd, 0xb9, 0x0b, 0xc4, 0xa9, 0xd3, 0x63, 0x71, 0x37, 0x37, 0x80, 0x75, 0xf7, 0xac, 0x25, 0x4d, 0xdb, 0xed, 0x62, 0x5d, 0x33, 0x55, 0x67, 0xe7, 0xbb, 0x0e, 0x81, 0x68, 0x96, 0xf8, 0xd8, 0xe0, 0xcc, 0xc6, 0x3b, 0xd6, 0xe1, 0xed, 0x24, 0x43, 0x50, 0x2e, 0xfb, 0xfa, 0x40, 0x63, 0x17, 0xf8, 0x56, 0x4d, 0x76, 0x6e, 0xde, 0x2e, 0x1f, 0xb6, 0xef, 0x68, 0x0f, 0xe3, 0xc8, 0x5b, 0x6d, 0x95, 0x1d, 0x12, 0xd1, 0xcd, 0x57, 0x80, 0x49, 0xa9, 0xd6, 0x82, 0x2b, 0xdb, 0x5a, 0x16, 0x94, 0xbf, 0x40, 0x25, 0xd3, 0x83, 0xed, 0x07, 0x55, 0x3b, 0x50, 0xac, 0xbd, 0x95, 0x09, 0x0b, 0x16, 0xdb, 0xee, 0x7e, 0xf2, 0xfd, 0x7f, 0x6d, 0xc4, 0xfe, 0xdf, 0x44, 0xb6, 0x3b, 0x72, 0x7e, 0x54, 0x83, 0x38, 0x40, 0x1f, 0x0a, 0xb7, 0x42, 0xff, 0xc3, 0xfe, 0x83, 0x9f, 0x14, 0x19, 0xb3, 0xb0, 0xc3, 0x0c, 0x15, 0x75, 0x5e, 0xa6, 0xd7, 0xf3, 0xd9, 0xb7, 0x36, 0xc7, 0x9c, 0xb3, 0xca, 0xad, 0xdf, 0x98, 0xa4, 0x6b, 0xc2, 0x0b, 0x6f, 0x98, 0x21, 0x96, 0xe3, 0x9a, 0xb0, 0x92, 0xe7, 0x38, 0x64, 0xdc, 0x65, 0x98, 0x7e, 0xb6, 0x5f, 0xd1, 0x00, 0x52, 0x72, 0x36, 0x02, 0xd0, 0x6e, 0xad, 0x23, 0xb7, 0x90, 0xe9, 0x09, 0x31, 0x42, 0x2e, 0x5c, 0xa4, 0xb0, 0xb8, 0x70, 0x2b, 0x35, 0x80, 0xa9, 0x4c, 0x9b, 0xaa, 0xa8, 0x5b, 0xea, 0x8f, 0x62, 0x78, 0x99, 0xaf, 0xb7, 0x09, 0xf2, 0x18, 0x2e, 0xd4, 0x97, 0x42, 0xe1, 0xd9, 0x0e, 0x9b, 0x19, 0x50, 0xd2, 0x5b, 0x84, 0x6a, 0x58, 0xf5, 0x10, 0xfb, 0x8b, 0x72, 0x34, 0xc7, 0xbb, 0xff, 0x93, 0xc0, 0x01, 0x86, 0x16, 0xa0, 0x46, 0xd0, 0x66, 0xa7, 0xcc, 0xd2, 0x90, 0x69, 0xd1, 0x59, 0x85, 0x2e, 0x97, 0xa1, 0x7c, 0xda, 0x65, 0xed, 0x08, 0xe8, 0x5f, 0x3e, 0xe0, 0xed, 0xcd, 0xde, 0x8b, 0xd5, 0xc0, 0xd1, 0x65, 0x2e, 0x35, 0x04, 0x0b, 0xaa, 0x97, 0x2a, 0x80, 0x13, 0xf8, 0x0a, 0x3f, 0xc3, 0x03, 0xf0, 0xb2, 0x05, 0x8a, 0x46, 0xa0, 0xcb, 0x6f, 0x5f, 0x43, 0x95, 0x7e, 0xed, 0x5b, 0x12, 0xb5, 0x9a, 0x44, 0xbd, 0xff, 0x79, 0x82, 0xcf, 0x5f, 0xdc, 0xa7, 0xb5, 0x34, 0x54, 0x15, 0x25, 0x2d, 0x62, 0x27, 0xde, 0x7c, 0x16, 0xcc, 0x2d, 0x6b, 0xca, 0xe3, 0xfa, 0x46, 0xa6, 0x86, 0xd3, 0x1d, 0x10, 0x2f, 0xab, 0xd2, 0x58, 0x9f, 0x8a, 0x4a, 0x9c, 0x40, 0x00, 0x90, 0x66, 0x43, 0x6e, 0xb8, 0xdb, 0x6f, 0x64, 0xfa, 0xb0, 0x5f, 0x88, 0xb2, 0xa6, 0xb5, 0x83, 0x80, 0xd6, 0x58, 0x46, 0x68, 0x60, 0x59, 0x24, 0x2a, 0xa8, 0x87, 0x7d, 0x8f, 0x61, 0xb9, 0x4a, 0x9d, 0x83, 0x51, 0x9a, 0xa0, 0x60, 0x3d, 0xee, 0x03, 0x66, 0x22, 0xf0, 0x7d, 0x14, 0xa7, 0x64, 0x65, 0x6b, 0x20, 0xf9, 0xf4, 0x6f, 0x32, 0x3e, 0x6c, 0x32, 0x4d, 0x98, 0xdf, 0x6c, 0xe1, 0xcb, 0xd2, 0x6a, 0x2c, 0x3b, 0xe2, 0xf1, 0xb4, 0x89, 0xed, 0x78, 0x1e, 0x1d, 0x5d, 0x23, 0x0c, 0x23, 0x2f, 0xba, 0xaa, 0xfa, 0xde, 0xe9, 0x63, 0x49, 0x37, 0x2e, 0x97, 0x56, 0x76, 0xa2, 0x07, 0x21, 0x1f, 0x0e, 0x43, 0xe2, 0x30, 0xf4, 0xfe, 0x94, 0xf9, 0xeb, 0x73, 0xe5, 0x3e, 0x11, 0x1a, 0xc8, 0xb7, 0xe2, 0xf0, 0x04, 0x46, 0xeb, 0xff, 0xf1, 0x35, 0x37, 0x63, 0x7e, 0xd8, 0x60, 0x84, 0x49, 0xba, 0x2e, 0xbe, 0x59, 0x56, 0xb5, 0xce, 0xb7, 0x66, 0xbd, 0xb9, 0x1f, 0x35, 0x08, 0xe3, 0x54, 0xe7, 0xfb, 0xef, 0xb9, 0x94, 0xdd, 0x64, 0xda, 0xa8, 0x80, 0x5b, 0x86, 0xd9, 0x71, 0x12, 0x5d, 0x3a, 0x30, 0x3e, 0xf2, 0xc5, 0x6c, 0x3a, 0x16, 0x0a, 0x86, 0x86, 0x0c, 0x40, 0xca, 0x33, 0x3f, 0x0b, 0x14, 0x80, 0xbb, 0x3d, 0x4f, 0xdf, 0x7e, 0xfe, 0xf7, 0xa2, 0xab, 0x1b, 0x3f, 0x6c, 0x89, 0xec, 0xf6, 0x5c, 0xdd, 0x45, 0xfe, 0x4b, 0xe2, 0x13, 0xd4, 0x18, 0xe1, 0xb7, 0x78, 0x9b, 0x62, 0xca, 0x2b, 0x54, 0x6c, 0x5a, 0xd4, 0x5a, 0x07, 0x66, 0x67, 0x96, 0xc4, 0x89, 0x1a, 0x2b, 0xb7, 0xc4, 0xab, 0x16, 0x71, 0xe7, 0x4c, 0xdc, 0x90, 0x6b, 0x55, 0x2f, 0x35, 0xce, 0x15, 0x1f, 0x66, 0x2f, 0x88, 0xa5, 0x05, 0xfe, 0xfd, 0xfa, 0x70, 0xb6, 0x9d, 0xc7, 0x16, 0x43, 0x71, 0x42, 0x6a, 0x74, 0xd4, 0xda, 0x7e, 0x68, 0xf7, 0x77, 0xe4, 0x9a, 0x97, 0x30, 0x9c, 0x97, 0xa2, 0x10, 0x9c, 0x64, 0x6c, 0x8d, 0x85, 0x7e, 0x40, 0xb5, 0x25, 0x7d, 0xec, 0x0e, 0x17, 0xc2, 0x5a, 0x29, 0xc6, 0x4c, 0xa7, 0x66, 0x11, 0x2a, 0x6e, 0x2a, 0x95, 0x6b, 0x63, 0x60, 0x4b, 0x0c, 0x85, 0xdc, 0x38, 0x0d, 0x32, 0x4a, 0xb4, 0xb0, 0x2d, 0x13, 0x77, 0x29, 0x1f, 0x87, 0x88, 0xbf, 0x88, 0xda, 0xfa, 0x7a, 0xe5, 0xfe, 0x16, 0xde, 0x1a, 0x77, 0x5e, 0x1a, 0x66, 0x2e, 0xf4, 0x30, 0x2f, 0x6e, 0xcd, 0xc7, 0x33, 0xf7, 0x99, 0xc9, 0x5c, 0x0b, 0xe4, 0xcd, 0xac, 0x30, 0xde, 0x2b, 0xf0, 0xe3, 0x41, 0xa8, 0x88, 0x1f, 0x6c, 0x24, 0x38, 0xee, 0xee, 0x8e, 0x16, 0xd0, 0x8c, 0x57, 0xa3, 0x16, 0x10, 0xeb, 0xf9, 0xac, 0xcc, 0x3d, 0x6c, 0xe0, 0x2a, 0x4f, 0x7d, 0x43, 0x27, 0xfe, 0x03, 0x2b, 0x57, 0x3c, 0xf2, 0x9b, 0x11, 0x44, 0x91, 0x56, 0x9c, 0x6e, 0x49, 0xb3, 0xd5, 0x74, 0x2a, 0x9c, 0x13, 0x41, 0x4d, 0xf3, 0xe5, 0x52, 0x06, 0xa8, 0xd8, 0x99, 0xcc, 0x87, 0x6b, 0xd4, 0xa4, 0x02, 0xb4, 0xf8, 0x59, 0x32, 0xd3, 0xc4, 0x3f, 0xcb, 0xa6, 0x44, 0x1b, 0x68, 0xfc, 0xd9, 0xc9, 0x10, 0xa5, 0x41, 0x3d, 0x90, 0xe7, 0xcc, 0x6e, 0x4f, 0xa0, 0x2a, 0xa3, 0xee, 0x1d, 0x3a, 0x70, 0xa1, 0x75, 0xb3, 0xef, 0xce, 0xff, 0x2f, 0xea, 0x2f, 0x52, 0x33, 0xbd, 0xbd, 0x56, 0x5d, 0x51, 0x7b, 0x2a, 0x91, 0xc4, 0x15, 0xaa, 0xdd, 0x20, 0x84, 0x37, 0x2c, 0xc3, 0x15, 0x10, 0xc1, 0xa3, 0x9c, 0xf3, 0x71, 0xc4, 0xea, 0x4f, 0x72, 0xa0, 0x7d, 0xa4, 0xf4, 0xab, 0x7f, 0xe5, 0x07, 0x8e, 0x45, 0x2c, 0xe2, 0x95, 0xfd, 0x4a, 0x62, 0xe0, 0xe9, 0xe7, 0xe2, 0x87, 0xd7, 0x2d, 0x6d, 0xc3, 0x62, 0xa3, 0xb1, 0x21, 0xc2, 0x9d, 0xc3, 0x10, 0xca, 0x3c, 0x96, 0x43, 0xb0, 0x88, 0x3d, 0xa6, 0x15, 0x0d, 0x16, 0x40, 0x09, 0x5f, 0xa1, 0xc8, 0x13, 0x44, 0x44, 0x9e, 0x3c, 0x72, 0x62, 0x54, 0x3d, 0xed, 0xf2, 0xe1, 0x1d, 0x62, 0x75, 0x7a, 0x13, 0x45, 0x33, 0xfb, 0xdf, 0xc9, 0x06, 0x95, 0xd1, 0xb2, 0xd8, 0xc9, 0x9e, 0x85, 0xbe, 0x5e, 0xee, 0x28, 0xd2, 0x31, 0xee, 0x93, 0xee, 0xf0, 0xb4, 0x8c, 0xca, 0x4d, 0x4a, 0x94, 0xd4, 0x14, 0x67, 0x34, 0x5a, 0x76, 0x84, 0x90, 0x4f, 0xa2, 0x65, 0x4c, 0x27, 0x31, 0xc1, 0x38, 0x11, 0xbe, 0x3f, 0x19, 0x5c, 0x87, 0xc7, 0x7a, 0xd3, 0xf3, 0xab, 0x0a, 0x04, 0x78, 0x90, 0x95, 0x4e, 0xda, 0xa6, 0xbf, 0x37, 0xa8, 0x8c, 0xd2, 0xd5, 0xfc, 0xda, 0xeb, 0x6f, 0xc1, 0x30, 0xee, 0xcb, 0x01, 0x1b, 0x0b, 0x4f, 0x9d, 0x62, 0x50, 0xd1, 0x41, 0xb6, 0xf6, 0xb9, 0x3d, 0x46, 0x9c, 0xd4, 0xdc, 0x41, 0x2e, 0x19, 0x35, 0xad, 0x93, 0xa3, 0x76, 0x9a, 0x00, 0x3b, 0x80, 0x69, 0x2a, 0xfa, 0x7e, 0x26, 0xac, 0x80, 0xc0, 0x38, 0xf0, 0x70, 0x9f, 0xc4, 0xd9, 0x4a, 0xf9, 0xb2, 0x54, 0x78, 0xd7, 0x53, 0xa5, 0x9c, 0x7e, 0x26, 0x75, 0x59, 0x5d, 0xa3, 0x93, 0x85, 0xd5, 0xe1, 0xd3, 0x9a, 0x5d, 0x30, 0x29, 0x6e, 0x9a, 0x7c, 0x2b, 0x1d, 0x75, 0xbf, 0x45, 0x18, 0xdd, 0x9b, 0x2c, 0x4a, 0xdb, 0xa3, 0xfb, 0xd4, 0xca, 0x61, 0xd5, 0x69, 0xc9, 0x12, 0x8f, 0x3f, 0x9f, 0x6c, 0x4b, 0xa7, 0x5d, 0xd4, 0xa7, 0xec, 0x57, 0x00, 0xf3, 0x30, 0xda, 0x1c, 0x9e, 0xc7, 0x52, 0x91, 0xd5, 0x19, 0x83, 0x47, 0x0b, 0x19, 0xda, 0x9d, 0xd8, 0xc4, 0x0e, 0x9d, 0x4e, 0xa0, 0x09, 0xe8, 0x66, 0x0d, 0xf2, 0xfc, 0x31, 0x73, 0x9d, 0xf9, 0x47, 0x9c, 0xda, 0xdf, 0x85, 0xe1, 0x1a, 0x91, 0x3a, 0x3f, 0x51, 0x23, 0xe0, 0x6a, 0x96, 0x8f, 0x8c, 0xd6, 0xe9, 0xc8, 0x4a, 0x6f, 0xc9, 0x88, 0xe8, 0x5a, 0x15, 0x92, 0xa4, 0xb6, 0xd9, 0x71, 0x32, 0x59, 0x2f, 0x78, 0x9a, 0x9d, 0xe3, 0x52, 0x0d, 0x25, 0x68, 0x55, 0x64, 0x97, 0x32, 0x74, 0x43, 0x2b, 0x98, 0x48, 0xcc, 0x16, 0x7d, 0x98, 0x8d, 0x8d, 0x04, 0x39, 0x45, 0xde, 0xe7, 0x70, 0xb0, 0x70, 0xa1, 0x75, 0xb2, 0x0e, 0xe8, 0x5d, 0xd1, 0xf2, 0xac, 0xea, 0x2c, 0xbd, 0xc6, 0x15, 0x22, 0x41, 0xf9, 0x99, 0x5d, 0x7c, 0x24, 0x33, 0x96, 0x46, 0x8d, 0x97, 0xd4, 0xd8, 0x28, 0x79, 0xee, 0xfc, 0xfa, 0xb9, 0xed, 0xb0, 0xda, 0x7f, 0x11, 0x9f, 0x36, 0x20, 0xd3, 0x77, 0x51, 0x8c, 0x3b, 0xad, 0x13, 0x5e, 0x2f, 0x2e, 0x67, 0x53, 0x84, 0x4a, 0x6e, 0x2b, 0xf1, 0x00, 0xcb, 0x78, 0xf4, 0x1c, 0xdf, 0x24, 0x28, 0xae, 0x96, 0x97, 0xa7, 0x4a, 0xaa, 0xec, 0xb7, 0x61, 0x73, 0xeb, 0xaa, 0xb1, 0x82, 0x70, 0x60, 0x17, 0x07, 0x7e, 0x20, 0x50, 0x5d, 0xfc, 0xd9, 0xb8, 0x92, 0xd3, 0x91, 0x16, 0xfd, 0xfb, 0x0c, 0xec, 0x41, 0xc6, 0x0e, 0x33, 0x0c, 0xf3, 0x59, 0x06, 0xaa, 0xdd, 0xa8, 0x9b, 0xbc, 0xf4, 0x04, 0xd7, 0xc8, 0xa4, 0x86, 0xb9, 0xef, 0x05, 0x86, 0xd2, 0xe7, 0x3f, 0xac, 0x56, 0x0c, 0x9a, 0x39, 0x23, 0x33, 0xbd, 0x0d, 0x09, 0xcf, 0x13, 0x5e, 0x22, 0xaa, 0xf3, 0xac, 0x2e, 0x5a, 0xb8, 0x8e, 0x8a, 0x24, 0x34, 0xc8, 0xa4, 0x06, 0xb0, 0x2b, 0x56, 0xd5, 0xeb, 0x17, 0xb2, 0x4b, 0x77, 0x06, 0x10, 0x97, 0xf9, 0xae, 0xb6, 0xc4, 0x53, 0x3b, 0x42, 0x4a, 0xb2, 0x8f, 0x55, 0xcf, 0x05, 0x26, 0xef, 0x7f, 0x2b, 0x88, 0x08, 0x41, 0xb5, 0x1c, 0xfc, 0x75, 0x18, 0xcf, 0x1c, 0x0e, 0xf5, 0x64, 0x58, 0xe5, 0x64, 0xb5, 0x9b, 0xf9, 0x0f, 0x6a, 0x82, 0xf4, 0xcc, 0x23, 0xa1, 0xcf, 0xe2, 0xb6, 0x01, 0x98, 0xdb, 0x9d, 0xc5, 0xfc, 0x43, 0x72, 0xb5, 0x46, 0xe1, 0xa1, 0xb1, 0x18, 0x73, 0xc9, 0xe7, 0xea, 0xb5, 0x47, 0x96, 0xb9, 0x98, 0x02, 0x8d, 0x78, 0x10, 0xd0, 0x4f, 0xe5, 0xba, 0x0a, 0xd0, 0xea, 0xb5, 0x91, 0xb7, 0xfb, 0x92, 0x97, 0xa5, 0xe3, 0xdc, 0x52, 0xc8, 0xbf, 0xd6, 0x2c, 0xae, 0x2a, 0xef, 0x10, 0x96, 0x1c, 0x58, 0x99, 0x4b, 0x2e, 0x7f, 0xa8, 0x1b, 0x31, 0x31, 0x7d, 0x3d, 0x8b, 0x7a, 0x6c, 0xd3, 0x15, 0x67, 0xf3, 0xf8, 0x3a, 0x01, 0xea, 0x6b, 0x02, 0x37, 0xec, 0x8b, 0x18, 0xd8, 0xdf, 0xe5, 0xda, 0x28, 0x2d, 0xeb, 0xe4, 0x06, 0x70, 0xca, 0x35, 0xeb, 0x21, 0xa7, 0xec, 0x8e, 0x6f, 0xa2, 0xa1, 0xaf, 0x9a, 0x29, 0xf1, 0x5a, 0xd5, 0x64, 0xd7, 0x64, 0x09, 0x8a, 0x42, 0xfc, 0xe9, 0x5f, 0xdd, 0x6d, 0xcf, 0x3b, 0x7a, 0xdc, 0xd7, 0x8a, 0xe7, 0xe5, 0x18, 0xc1, 0x0a, 0x5a, 0xb6, 0xf4, 0xff, 0x26, 0xa8, 0x7e, 0x1a, 0xfa, 0xd7, 0x6a, 0xd1, 0x68, 0x60, 0xe4, 0xb0, 0x2b, 0x8c, 0x97, 0x5b, 0x74, 0x8e, 0xc9, 0x03, 0xe8, 0xa2, 0x57, 0x51, 0xe3, 0x1a, 0x1a, 0xb3, 0x13, 0x6a, 0xda, 0x18, 0xb0, 0xf1, 0x1b, 0xf8, 0xd1, 0x10, 0x4f, 0x7f, 0xca, 0xc7, 0x11, 0xa4, 0x9b, 0xcc, 0x1a, 0xfa, 0x53, 0x25, 0xee, 0x01, 0x61, 0x5f, 0x09, 0xdf, 0x40, 0x50, 0x05, 0xb9, 0x51, 0x88, 0xae, 0x2f, 0x8f, 0x0d, 0xe8, 0x86, 0xda, 0x69, 0xc3, 0x4f, 0x42, 0xcb, 0x4b, 0xb5, 0x95, 0x64, 0x8f, 0xc5, 0x13, 0x61, 0x18, 0x38, 0x78, 0x02, 0x0a, 0x09, 0x7e, 0x4f, 0xd2, 0xfb, 0x95, 0x1c, 0x4e, 0x34, 0x3c, 0x71, 0x55, 0x3b, 0x28, 0x67, 0xf0, 0xaa, 0xc9, 0x3a, 0x49, 0xa7, 0x1c, 0x05, 0x49, 0x7b, 0xaa, 0x99, 0xf8, 0x53, 0x1e, 0xda, 0x1c, 0xcc, 0xb8, 0xf1, 0x5b, 0xaa, 0xd4, 0xc5, 0x3e, 0x00, 0x47, 0x8c, 0xd6, 0x2a, 0x69, 0x17, 0x50, 0x5a, 0x7a, 0xf9, 0xf0, 0x30, 0x64, 0x24, 0xff, 0xe9, 0x34, 0xd7, 0x29, 0x67, 0x3d, 0x2f, 0xee, 0xf4, 0xe7, 0x03, 0x7d, 0x85, 0x74, 0x52, 0x86, 0x67, 0x75, 0x4e, 0x9f, 0x1b, 0xb3, 0x6e, 0xdc, 0x1a, 0x7a, 0x86, 0xd0, 0x48, 0x42, 0x37, 0xc4, 0x25, 0x71, 0xea, 0x84, 0xcd, 0x01, 0x97, 0x57, 0x16, 0xfe, 0x5a, 0x05, 0x7d, 0xcd, 0x99, 0xf1, 0x40, 0xee, 0x8d, 0x8b, 0x5d, 0x6c, 0x60, 0x57, 0xec, 0xb5, 0xcb, 0xda, 0x96, 0xe4, 0xce, 0x13, 0xbf, 0xac, 0xa8, 0xea, 0x90, 0xe6, 0x6b, 0x5b, 0x24, 0xb5, 0xac, 0x22, 0xb1, 0x59, 0xdd, 0x79, 0x50, 0xd2, 0xe2, 0x3e, 0x51, 0x67, 0xd4, 0xdc, 0x9e, 0xbd, 0xbd, 0xc4, 0xa4, 0x1e, 0x9c, 0x4b, 0x58, 0x1e, 0x63, 0xce, 0x58, 0xe8, 0x41, 0x2e, 0xc4, 0x76, 0xdb, 0xe9, 0xc1, 0x9c, 0x86, 0x37, 0x33, 0x74, 0x89, 0x6e, 0x08, 0x90, 0x1a, 0x06, 0xf3, 0xc1, 0x50, 0x7f, 0x73, 0x33, 0x3c, 0x40, 0xee, 0x05, 0x74, 0x05, 0x5f, 0xe6, 0x94, 0x60, 0xdb, 0xd6, 0x6f, 0x0c, 0x62, 0x7c, 0x11, 0xbb, 0x33, 0x5c, 0xca, 0xce, 0xda, 0x16, 0x03, 0xfd, 0x55, 0xeb, 0x01, 0xc5, 0x2a, 0xb8, 0x2b, 0x57, 0x75, 0xfa, 0xd8, 0x5e, 0xca, 0xf4, 0xa5, 0xf0, 0x05, 0xcf, 0x59, 0xd3, 0x0f, 0x11, 0xf9, 0x25, 0x6b, 0x16, 0x4d, 0x62, 0x78, 0xd6, 0xba, 0xe2, 0x09, 0x7c, 0x9d, 0xb7, 0x05, 0xa6, 0x17, 0x6a, 0x36, 0x07, 0x69, 0x72, 0xaf, 0x0b, 0x2a, 0xc3, 0xc3, 0x40, 0x7d, 0xfb, 0x3b, 0x5a, 0x0f, 0x34, 0xc7, 0x61, 0xd7, 0x14, 0x2e, 0xa4, 0xbb, 0xe4, 0x95, 0x0b, 0x1b, 0xa7, 0x0c, 0x9c, 0x83, 0x7c, 0x88, 0xe4, 0x8d, 0x55, 0x13, 0xa3, 0x3f, 0x86, 0xd2, 0xc9, 0x9f, 0xb4, 0xeb, 0x51, 0x2b, 0xc7, 0x61, 0x4f, 0xcf, 0xd5, 0x45, 0xa5, 0x6e, 0xcd, 0xe7, 0xdd, 0xae, 0x0e, 0x85, 0xf4, 0x46, 0xea, 0x99, 0xff, 0x6f, 0x1b, 0x7b, 0xf7, 0xb0, 0x59, 0x84, 0x58, 0xe6, 0x00, 0xc1, 0x4f, 0x5d, 0xac, 0x8a, 0x8b, 0xd8, 0xe6, 0x4b, 0x5b, 0xf7, 0x78, 0x66, 0xf1, 0x33, 0xe5, 0x39, 0xe8, 0xd0, 0x0c, 0xa1, 0xdc, 0x51, 0xba, 0x4b, 0x14, 0x75, 0x35, 0x1b, 0x93, 0x13, 0x17, 0x49, 0x40, 0xc2, 0xf5, 0x30, 0xaf, 0xef, 0x75, 0xb0, 0xeb, 0xf1, 0x67, 0xd3, 0xd7, 0x5b, 0xca, 0x46, 0x94, 0x5a, 0x46, 0x3d, 0x8e, 0x26, 0x01, 0x78, 0xaf, 0xce, 0xc2, 0x85, 0xc5, 0x16, 0xd8, 0x0b, 0x66, 0xea, 0xb1, 0xc7, 0x19, 0xfa, 0x59, 0xda, 0x2e, 0x14, 0x97, 0xa8, 0x95, 0x82, 0x5c, 0x86, 0xb7, 0xec, 0x1c, 0xca, 0xef, 0x56, 0xe2, 0x8e, 0xc1, 0x31, 0x56, 0x01, 0x84, 0xd1, 0x54, 0x8b, 0x01, 0x2d, 0x57, 0x85, 0x69, 0xf2, 0x13, 0xaf, 0xac, 0x85, 0x83, 0x3f, 0x3b, 0xa5, 0xb1, 0xf4, 0x55, 0x80, 0x95, 0x7f, 0x7e, 0x40, 0xa2, 0x0d, 0xb3, 0xdf, 0xd8, 0xcf, 0xb6, 0xa6, 0xbc, 0xaa, 0xbf, 0xfd, 0x26, 0x9d, 0x85, 0x94, 0xe0, 0x13, 0x26, 0xeb, 0x23, 0x9a, 0x50, 0xd6, 0xc3, 0x19, 0xf3, 0x84, 0x39, 0x2d, 0xef, 0xc5, 0x07, 0xdf, 0x7e, 0x34, 0x29, 0x28, 0xf0, 0x9d, 0xb3, 0x2e, 0x8b, 0x8c, 0x38, 0xd4, 0x20, 0xd1, 0x47, 0xa7, 0x17, 0x0a, 0x6d, 0x97, 0xd2, 0x12, 0x82, 0xe0, 0x16, 0x23, 0xa3, 0x9c, 0x30, 0x1b, 0x98, 0x24, 0x28, 0x96, 0xef, 0x96, 0x55, 0xad, 0x52, 0xac, 0x91, 0xc5, 0xd1, 0x3d, 0xe1, 0x23, 0x00, 0x03, 0x6d, 0xb4, 0xa8, 0xd8, 0xf0, 0x78, 0x9a, 0x0c, 0xbc, 0xd5, 0xcd, 0xe1, 0x00, 0x65, 0xf1, 0x65, 0x34, 0x87, 0xd3, 0x49, 0xa7, 0x98, 0xf9, 0x92, 0xf9, 0x7f, 0x7c, 0x88, 0x59, 0x96, 0xb7, 0xe6, 0x01, 0x0a, 0xe9, 0xbc, 0x36, 0x7f, 0xd7, 0x74, 0xae, 0x93, 0x0b, 0x7f, 0x11, 0xc2, 0x1f, 0x96, 0x41, 0x45, 0x66, 0xfa, 0x69, 0x24, 0xcf, 0x71, 0xe7, 0x58, 0x4f, 0x83, 0x7d, 0x9c, 0xa1, 0x70, 0x6b, 0x62, 0x71, 0x26, 0x0b, 0x1d, 0x34, 0x44, 0x70, 0x3f, 0xe8, 0x06, 0x59, 0x16, 0xea, 0x98, 0xde, 0x4d, 0xb1, 0xe2, 0x9e, 0x4a, 0x75, 0x96, 0xc7, 0xfd, 0x0f, 0x0d, 0x3f, 0xdd, 0x22, 0xf2, 0xbd, 0xbe, 0x13, 0x12, 0x73, 0xc5, 0x49, 0x56, 0x14, 0xcb, 0x1a, 0x0e, 0x89, 0xa9, 0x7b, 0xea, 0xd2, 0x10, 0xc8, 0xe8, 0x91, 0x8d, 0x16, 0x1c, 0x84, 0xab, 0xb7, 0x88, 0x8b, 0x0f, 0xff, 0xe3, 0x48, 0x19, 0x51, 0xff, 0x6c, 0x72, 0x1f, 0x4b, 0xef, 0xcb, 0x6d, 0x26, 0xfc, 0xd2, 0x39, 0x51, 0x1b, 0xed, 0xb3, 0x5f, 0x55, 0x90, 0x45, 0x80, 0xde, 0xdd, 0x47, 0xa5, 0x50, 0x5a, 0x60, 0xf4, 0x72, 0x01, 0xc3, 0x0a, 0x34, 0xad, 0x00, 0xec, 0xe8, 0xc8, 0xa7, 0x00, 0x74, 0x6f, 0x3a, 0x11, 0x1c, 0x7a, 0x6a, 0xc0, 0x21, 0x0b, 0x07, 0xf8, 0x6d, 0x25, 0x7c, 0x50, 0x7b, 0xa9, 0x3f, 0x2f, 0x65, 0xcc, 0x0e, 0x82, 0x5f, 0x6f, 0xd2, 0x3d, 0x0f, 0xa0, 0x22, 0xee, 0x34, 0x23, 0xbf, 0xa9, 0x46, 0x3f, 0x7b, 0xf8, 0x2c, 0x5a, 0xda, 0x52, 0x5d, 0xd7, 0x05, 0x1a, 0xa8, 0x93, 0x3f, 0x13, 0x2e, 0xdb, 0xe2, 0xcd, 0xde, 0x15, 0x34, 0x74, 0xe9, 0xbf, 0x0d, 0x6b, 0x0e, 0x8c, 0xfd, 0xab, 0x59, 0x2e, 0x34, 0x76, 0xd3, 0x8d, 0x77, 0xe4, 0xdf, 0x49, 0xbd, 0x7a, 0x2c, 0xca, 0x90, 0x7a, 0xed, 0x75, 0x83, 0xaa, 0x84, 0x63, 0x8f, 0xa3, 0x5e, 0xf4, 0x7d, 0x63, 0xc1, 0x4a, 0x4a, 0xe4, 0x9d, 0x55, 0x7d, 0xf6, 0xdd, 0xf8, 0xdf, 0x13, 0x1f, 0x27, 0x86, 0xef, 0x7e, 0xd7, 0xdc, 0xcf, 0x77, 0x58, 0x3b, 0x15, 0xd6, 0x24, 0xde, 0xe7, 0xb9, 0xdc, 0x68, 0x34, 0x49, 0x28, 0x85, 0x76, 0xc2, 0x46, 0x10, 0xbb, 0x3f, 0x9d, 0x2c, 0xea, 0x16, 0x6f, 0x07, 0xf5, 0x48, 0x95, 0x36, 0x17, 0xdb, 0x05, 0x24, 0x90, 0x4f, 0xf4, 0xae, 0xd1, 0x5a, 0xcb, 0x5d, 0x80, 0x2b, 0x31, 0x22, 0x8c, 0xce, 0x45, 0x97, 0xf5, 0x78, 0x62, 0x16, 0x7e, 0x1f, 0x36, 0x45, 0x7e, 0xfa, 0x07, 0xf9, 0x4e, 0x01, 0x16, 0xc0, 0x10, 0xa5, 0x46, 0x6b, 0x1f, 0x56, 0x89, 0xdd, 0x4a, 0x4d, 0xf7, 0xf6, 0x1b, 0x83, 0xd2, 0x68, 0xc5, 0x05, 0x21, 0x92, 0xa2, 0x2d, 0x5d, 0x3b, 0x0f, 0x83, 0x66, 0x50, 0xb6, 0xa6, 0x8a, 0x9b, 0x55, 0xaf, 0x06, 0x71, 0x99, 0xea, 0x61, 0x48, 0x9f, 0x94, 0x0d, 0xfb, 0xa3, 0x21, 0x1c, 0xf3, 0xc5, 0x89, 0x57, 0xfc, 0x00, 0xba, 0xfc, 0x22, 0x7c, 0xc1, 0x96, 0x72, 0xdb, 0xc6, 0xb6, 0xd2, 0x75, 0x27, 0x85, 0x76, 0xb6, 0x0d, 0xec, 0x1f, 0x8e, 0x97, 0x7e, 0x3b, 0x18, 0xc5, 0xec, 0x94, 0x7e, 0xee, 0x1d, 0xf8, 0xb9, 0x71, 0x5e, 0x5c, 0xbb, 0xa2, 0x57, 0xf0, 0x2d, 0xc0, 0xce, 0x6c, 0xba, 0x8f, 0xb9, 0x2a, 0x5c, 0xf2, 0x70, 0x2c, 0xd5, 0xb3, 0xb2, 0x97, 0x0d, 0xbe, 0xfd, 0xd6, 0x6c, 0x82, 0x73, 0x97, 0x05, 0x95, 0x4c, 0xca, 0x45, 0x8b, 0x5c, 0xd1, 0xc0, 0x75, 0x7c, 0xe8, 0xf9, 0xa9, 0xcc, 0xe5, 0xac, 0x6f, 0x3b, 0x16, 0x43, 0x51, 0xb5, 0x81, 0x0a, 0x5b, 0xec, 0xf9, 0x04, 0x1a, 0x71, 0x55, 0x3e, 0x1c, 0xc8, 0xbb, 0x9a, 0xf5, 0xd7, 0xc0, 0x29, 0xbd, 0x6e, 0x9b, 0x64, 0x52, 0xb1, 0x66, 0x83, 0xea, 0x42, 0xf4, 0x2f, 0x05, 0x2b, 0xea, 0xd6, 0xbc, 0x14, 0xc0, 0xb0, 0x15, 0x61, 0xf2, 0x2d, 0x89, 0x82, 0xf9, 0xd1, 0xf7, 0x93, 0x6d, 0x86, 0x84, 0x88, 0x10, 0xa5, 0x13, 0xbc, 0x86, 0x68, 0xf1, 0xe1, 0x0c, 0x16, 0xfa, 0x8e, 0x1e, 0x10, 0x00, 0xe0, 0x8e, 0x9c, 0x94, 0xc3, 0x63, 0x9e, 0x21, 0xe0, 0xa1, 0x32, 0x3a, 0x49, 0x3e, 0x73, 0x67, 0x01, 0xed, 0xd1, 0xdb, 0x95, 0x6f, 0x2d, 0x69, 0x45, 0x7d, 0xae, 0xfc, 0x44, 0x37, 0xa0, 0x30, 0x56, 0xa0, 0x9f, 0x48, 0x70, 0x04, 0x1d, 0xda, 0xa8, 0x00, 0x0f, 0x3e, 0xd0, 0x0d, 0xa0, 0x4d, 0x09, 0xcd, 0x56, 0xa5, 0x1b, 0xc3, 0x43, 0xe3, 0x62, 0xb5, 0x1e, 0xfb, 0x46, 0x61, 0xc5, 0xa5, 0x5b, 0xd7, 0x1c, 0xe4, 0xed, 0x68, 0xbf, 0x30, 0xbc, 0x42, 0x8d, 0xd1, 0xa2, 0xe9, 0xd5, 0x86, 0xd3, 0xf6, 0xa7, 0xcf, 0xa0, 0x1c, 0x65, 0x55, 0xe4, 0x3e, 0xcd, 0x35, 0x00, 0x3d, 0x2c, 0x26, 0x31, 0xf0, 0xa8, 0xa6, 0xa6, 0xef, 0x03, 0x1f, 0x9b, 0x42, 0x80, 0xf7, 0x94, 0xaf, 0xd1, 0x2c, 0xb2, 0xe5, 0x33, 0x98, 0xde, 0x41, 0x87, 0xc2, 0x35, 0xaa, 0xa7, 0x05, 0xea, 0x22, 0x81, 0x07, 0xab, 0x02, 0xed, 0x24, 0x86, 0xda, 0xf1, 0x9f, 0xd3, 0xa0, 0x25, 0x13, 0x8b, 0xe2, 0x70, 0xb8, 0x2c, 0xe5, 0x09, 0xfd, 0xba, 0x16, 0x15, 0xbd, 0x0e, 0x16, 0xeb, 0xf3, 0xaa, 0x54, 0xaa, 0x2e, 0x82, 0x01, 0x3a, 0x32, 0xa5, 0x0c, 0xed, 0x6f, 0xe3, 0xcc, 0x91, 0xf4, 0x4e, 0xe4, 0xa9, 0xf6, 0xe8, 0x2e, 0x75, 0x62, 0x41, 0xb0, 0x53, 0xe8, 0xcd, 0x0c, 0x00, 0x54, 0x84, 0xe6, 0x9b, 0xb2, 0xac, 0x2c, 0xba, 0xaf, 0x0c, 0xb6, 0xe5, 0x63, 0xf0, 0x38, 0xa0, 0xf9, 0x54, 0x35, 0xc6, 0xfa, 0x4e, 0xef, 0x4e, 0xec, 0xd2, 0x58, 0x1a, 0x5e, 0x24, 0x50, 0x86, 0x0c, 0xd2, 0x5a, 0x95, 0x15, 0x23, 0xe2, 0xcc, 0x99, 0x6f, 0x06, 0xfb, 0x3f, 0xb3, 0xeb, 0xd7, 0x19, 0xc9, 0xe4, 0x87, 0xc8, 0x9f, 0xbb, 0xaa, 0x4b, 0x8f, 0x60, 0xe3, 0x14, 0xbb, 0x92, 0xd5, 0x06, 0x85, 0x53, 0x7d, 0x05, 0x38, 0x74, 0x0b, 0x7a, 0x7b, 0xe5, 0x7a, 0x67, 0xbb, 0x88, 0xf7, 0xaf, 0x4b, 0x05, 0x49, 0x4c, 0x4a, 0xcb, 0x07, 0xdd, 0x17, 0x4d, 0x9e, 0x2e, 0x31, 0xc1, 0x50, 0x65, 0xa9, 0x28, 0x9d, 0xd8, 0x7e, 0x42, 0xb7, 0xfb, 0xd7, 0xd4, 0x6e, 0x84, 0x3d, 0xba, 0x28, 0xec, 0x93, 0xce, 0x2b, 0x64, 0x8b, 0x9e, 0x05, 0x40, 0x4c, 0xb5, 0x57, 0xed, 0xed, 0xdc, 0x0f, 0xf5, 0xd4, 0xfb, 0x61, 0x70, 0xa4, 0x8b, 0x01, 0x54, 0xbb, 0x4a, 0x08, 0xe7, 0x43, 0x4d, 0x29, 0xca, 0xae, 0x43, 0x1a, 0x93, 0x61, 0xa2, 0x35, 0xcf, 0xdf, 0x05, 0x5b, 0xce, 0x7d, 0x4e, 0x64, 0x5a, 0x7a, 0x4a, 0x2b, 0xde, 0x03, 0xe7, 0x57, 0x80, 0xef, 0xdb, 0x5c, 0xd9, 0xb6, 0xfe, 0xd0, 0x21, 0xbf, 0xd7, 0xdf, 0xfb, 0x36, 0xfd, 0x64, 0x41, 0x68, 0x8f, 0xa7, 0x6b, 0xa7, 0xec, 0xf7, 0x61, 0x9a, 0xd8, 0x96, 0x64, 0xe2, 0xc2, 0x34, 0x70, 0x57, 0xa5, 0x67, 0x06, 0xaa, 0x9c, 0xfa, 0xc8, 0xe8, 0xc6, 0xbc, 0x62, 0xf9, 0x19, 0x47, 0xc5, 0x4f, 0x14, 0x83, 0xc6, 0xa6, 0xa0, 0x5c, 0x0c, 0x18, 0xc3, 0xb9, 0xb9, 0xe5, 0xca, 0xb3, 0xad, 0xe4, 0x68, 0x6f, 0x37, 0x30, 0x4c, 0xb5, 0xad, 0xa8, 0x89, 0xe2, 0xbb, 0xd5, 0x55, 0xc0, 0x59, 0xc3, 0xee, 0xe4, 0x95, 0x3e, 0x35, 0x09, 0x94, 0x8e, 0xe6, 0xcc, 0xb3, 0x82, 0x25, 0xd7, 0x6a, 0x18, 0xd9, 0xe7, 0xbf, 0x71, 0x43, 0xb9, 0x47, 0x7a, 0x90, 0x91, 0x88, 0x5e, 0x7b, 0xb2, 0x8e, 0x08, 0x96, 0x3e, 0x86, 0x2e, 0xe3, 0x12, 0xe7, 0x01, 0x14, 0xcd, 0x86, 0x32, 0xd9, 0xd5, 0xeb, 0x1f, 0x3f, 0x09, 0xd0, 0x72, 0x59, 0xbc, 0x3b, 0x31, 0x6b, 0xf6, 0x4f, 0x94, 0x2c, 0xe0, 0x2c, 0x6c, 0x7d, 0x05, 0xc5, 0xeb, 0x34, 0x39, 0x64, 0xc7, 0x16, 0x9d, 0x55, 0xf0, 0x46, 0x58, 0x1c, 0x77, 0x2d, 0x7d, 0x70, 0x53, 0x4e, 0x4a, 0x38, 0xc0, 0x9e, 0x06, 0x94, 0x87, 0x88, 0xad, 0xa6, 0xaa, 0x24, 0x00, 0x37, 0x84, 0x59, 0x05, 0x01, 0x61, 0x48, 0xaa, 0xf3, 0x81, 0x3b, 0x74, 0xd0, 0x91, 0x10, 0x5c, 0xac, 0xd3, 0x0d, 0x23, 0xff, 0x93, 0xc0, 0xa0, 0xdc, 0x49, 0x6e, 0xe8, 0x61, 0x4e, 0x07, 0x59, 0xcf, 0xf3, 0x1f, 0x70, 0x68, 0x32, 0x82, 0x6f, 0xef, 0x7d, 0x31, 0x6e, 0x22, 0x77, 0xc1, 0xbc, 0x21, 0x74, 0xa0, 0xe7, 0x47, 0xf0, 0x06, 0xee, 0xf8, 0x54, 0xd8, 0x72, 0x6d, 0x7f, 0x51, 0x02, 0x45, 0x74, 0x30, 0xe2, 0x64, 0x74, 0x0d, 0xb0, 0xf4, 0x0e, 0x84, 0x3e, 0x0d, 0xcb, 0xed, 0xcd, 0x9c, 0x0b, 0xa8, 0x7d, 0xb1, 0xda, 0xe1, 0x84, 0xd8, 0xbc, 0x79, 0x53, 0x4f, 0x49, 0xab, 0xc9, 0x46, 0x35, 0x70, 0xaf, 0xa0, 0x4b, 0x73, 0x39, 0xcd, 0x2d, 0x71, 0xeb, 0x8e, 0xbf, 0xbc, 0x12, 0xad, 0xea, 0x0a, 0x12, 0x46, 0x05, 0xc6, 0x35, 0x0e, 0x38, 0x22, 0x34, 0x0c, 0xfa, 0xa5, 0x01, 0xab, 0x17, 0x5f, 0xda, 0xad, 0x13, 0x1a, 0x4e, 0xdf, 0xce, 0x0c, 0x5b, 0x5a, 0x7e, 0x8b, 0x30, 0xaf, 0xdd, 0x53, 0x79, 0x53, 0x38, 0x0a, 0xfc, 0x82, 0xb5, 0x25, 0x55, 0x50, 0xdb, 0x10, 0xf9, 0x25, 0x41, 0x2c, 0xa6, 0x06, 0xf6, 0x8e, 0x68, 0x67, 0x89, 0x5c, 0x19, 0x12, 0xe0, 0x52, 0x45, 0xb0, 0x36, 0x42, 0x6f, 0x66, 0x0b, 0x77, 0x7a, 0x04, 0xe7, 0xdd, 0xf2, 0x5d, 0xb4, 0x5f, 0xf0, 0x15, 0x0a, 0xc6, 0xda, 0x4f, 0x41, 0x40, 0x68, 0x9b, 0xf6, 0x08, 0xe6, 0x33, 0xf0, 0xc7, 0x93, 0x1f, 0x9b, 0xa0, 0x28, 0x3f, 0x66, 0x8a, 0x1c, 0x75, 0xe7, 0x7f, 0x51, 0x15, 0xea, 0x05, 0x74, 0x2e, 0xdd, 0x79, 0x81, 0x6f, 0x86, 0x5b, 0x94, 0xa0, 0x5c, 0x89, 0x29, 0x7b, 0x67, 0x8b, 0xea, 0xf4, 0x0a, 0xf8, 0x53, 0x76, 0x3f, 0x5e, 0x12, 0x26, 0x08, 0xfa, 0x09, 0x71, 0x96, 0x3d, 0xd4, 0x22, 0x2b, 0xcc, 0xb3, 0x0c, 0x45, 0x07, 0xcc, 0x20, 0x01, 0x77, 0x31, 0xa5, 0xc3, 0x0f, 0x5c, 0x52, 0xb0, 0x01, 0x19, 0x99, 0xad, 0x24, 0x8d, 0x24, 0x6c, 0xc9, 0xbe, 0x1d, 0xb3, 0x68, 0xb9, 0x96, 0x74, 0x5a, 0xd1, 0x8e, 0xaf, 0x5b, 0x9f, 0xd0, 0x0c, 0x51, 0xaa, 0xcf, 0xac, 0x93, 0x97, 0x66, 0x5b, 0x8c, 0x64, 0xe7, 0xa4, 0x62, 0x44, 0x35, 0x4f, 0x89, 0x9e, 0xcb, 0x11, 0xba, 0x85, 0xd5, 0x49, 0xcb, 0x75, 0xbd, 0xfd, 0xd1, 0xef, 0x26, 0x95, 0xb5, 0xb3, 0x30, 0xa9, 0xed, 0x39, 0xa9, 0x0f, 0xf8, 0xc3, 0xed, 0xe7, 0x21, 0x22, 0x19, 0x5b, 0xc8, 0x78, 0x81, 0xa1, 0x1b, 0xb2, 0x73, 0x64, 0x07, 0x80, 0xaf, 0x0d, 0x17, 0xdb, 0x34, 0x7c, 0xf8, 0x73, 0x66, 0xfe, 0xe0, 0x4e, 0xa6, 0x5f, 0x49, 0x1a, 0x3a, 0xe6, 0x76, 0x63, 0xa0, 0xd3, 0xcf, 0x72, 0x15, 0x12, 0xa2, 0x9c, 0xfa, 0x69, 0x96, 0xda, 0x45, 0x13, 0x2f, 0x89, 0xda, 0x1e, 0x23, 0x4c, 0xaf, 0xd8, 0x05, 0xf0, 0x40, 0xfa, 0x74, 0x4e, 0x09, 0x32, 0xfa, 0xe4, 0x5a, 0x7b, 0x0a, 0xa2, 0x0f, 0xdf, 0xd5, 0x4c, 0xfe, 0x91, 0x5e, 0xd0, 0xf9, 0x97, 0xef, 0x7e, 0x73, 0xd3, 0x21, 0xc1, 0x28, 0xe0, 0xf1, 0x5a, 0x37, 0x41, 0x56, 0xc5, 0xc1, 0x7c, 0x53, 0x48, 0xd4, 0xa4, 0x3d, 0xb5, 0x01, 0x02, 0x86, 0x22, 0x9f, 0xb7, 0x98, 0xb3, 0xe9, 0xb3, 0xfc, 0x8d, 0x0c, 0xa2, 0xfc, 0xb9, 0xce, 0xd9, 0xe9, 0xce, 0xa0, 0xf5, 0xe2, 0xf1, 0x24, 0x14, 0xcd, 0x71, 0x3d, 0x41, 0x7f, 0x4c, 0xee, 0xe9, 0xf9, 0x3a, 0x5c, 0x7c, 0xc1, 0x57, 0x21, 0x48, 0x09, 0x7f, 0xd3, 0x93, 0x03, 0xda, 0x9a, 0x67, 0xa3, 0x3e, 0x06, 0x12, 0x9a, 0x9d, 0xba, 0x48, 0x79, 0x28, 0x88, 0xb3, 0x61, 0x8a, 0x4f, 0xdd, 0x57, 0xc6, 0x5d, 0xf9, 0x70, 0x3b, 0xec, 0x8a, 0xf7, 0x52, 0xe8, 0xb5, 0x52, 0x96, 0x91, 0x4d, 0x2d, 0x29, 0x5d, 0x5b, 0x94, 0xbd, 0x10, 0xbb, 0x27, 0x85, 0x26, 0x21, 0xb7, 0x2c, 0x44, 0xde, 0xf7, 0xc0, 0x98, 0x34, 0xcb, 0xd4, 0x6c, 0xfc, 0xc4, 0x35, 0x66, 0xfb, 0xda, 0x94, 0xf2, 0x42, 0xb4, 0xa2, 0x2d, 0xe6, 0x3c, 0x5a, 0x3b, 0x5e, 0x63, 0xcc, 0x21, 0x55, 0x6c, 0x96, 0x18, 0x54, 0x54, 0xcb, 0x23, 0x17, 0x19, 0xc6, 0x3f, 0x38, 0x8d, 0xe7, 0x76, 0x30, 0xfa, 0x8e, 0x8d, 0x5e, 0x65, 0x02, 0xe5, 0x7f, 0xdb, 0x03, 0x3b, 0xe7, 0xbe, 0x46, 0xdb, 0x94, 0x70, 0xfb, 0xf7, 0xc9, 0xf2, 0xb8, 0x73, 0x35, 0x35, 0x57, 0xbf, 0x8e, 0xd6, 0xba, 0xe1, 0xe5, 0xcf, 0x00, 0x7d, 0xdd, 0x60, 0xa3, 0xda, 0x8c, 0xcd, 0x8a, 0x3a, 0x63, 0x49, 0x2e, 0xa5, 0x7c, 0x81, 0xee, 0x66, 0x49, 0x28, 0xa6, 0x3b, 0xdd, 0xfa, 0xcd, 0x4e, 0x1a, 0xc0, 0xe4, 0x0a, 0xa4, 0xeb, 0x66, 0xab, 0x87, 0x0a, 0x34, 0x72, 0x89, 0x1d, 0x2b, 0x33, 0x7d, 0x2c, 0xbe, 0xe4, 0x84, 0x67, 0x99, 0x17, 0xb0, 0x20, 0xff, 0x46, 0xe9, 0x71, 0x85, 0xe2, 0x9f, 0x9d, 0xc7, 0x21, 0x7d, 0x09, 0xb8, 0x7c, 0xab, 0x9b, 0x4f, 0x16, 0x93, 0x9c, 0x6e, 0x7b, 0x6f, 0x7e, 0xc3, 0x7f, 0x47, 0xf7, 0xd4, 0xd3, 0x75, 0xb0, 0xe8, 0xba, 0x3e, 0xec, 0xa3, 0xc5, 0xcf, 0x60, 0xc0, 0xff, 0x0c, 0xe6, 0x3f, 0x15, 0x3f, 0x00, 0xca, 0x32, 0xf5, 0xfc, 0xd0, 0x41, 0x3a, 0xc7, 0xeb, 0x90, 0x80, 0x08, 0x7f, 0xd1, 0xf9, 0xb0, 0xa3, 0x5b, 0x0e, 0x41, 0x39, 0x92, 0x52, 0x62, 0x0c, 0x53, 0xd2, 0xa8, 0x23, 0x01, 0xf1, 0xdd, 0xdd, 0x30, 0x36, 0x04, 0x89, 0x79, 0xe8, 0xde, 0x44, 0x31, 0xac, 0x54, 0x51, 0x23, 0xe0, 0xa1, 0x9f, 0x41, 0xa4, 0x74, 0x26, 0x92, 0xe4, 0x58, 0x70, 0x41, 0xda, 0x3e, 0x4e, 0xf4, 0x02, 0x71, 0x82, 0x83, 0x3e, 0xb0, 0x8e, 0x21, 0x79, 0x15, 0xa4, 0xc8, 0x67, 0xf4, 0x31, 0xa1, 0x21, 0x55, 0x08, 0x7a, 0x6a, 0x0d, 0x84, 0xaa, 0x45, 0x17, 0x2d, 0x50, 0x7f, 0x05, 0x9a, 0x4b, 0x0a, 0x78, 0xf3, 0x5b, 0x2a, 0xc7, 0x01, 0x3a, 0xb2, 0x4a, 0xb8, 0x17, 0xbb, 0x10, 0x6f, 0x04, 0xab, 0xce, 0x9b, 0x83, 0xc4, 0x6f, 0xdc, 0x50, 0x3a, 0x09, 0xdd, 0x88, 0xe1, 0x8f, 0x82, 0x6c, 0x9b, 0x45, 0x53, 0x1a, 0xc4, 0xfd, 0x11, 0x6f, 0xc8, 0x4a, 0xf3, 0x79, 0x6b, 0x4a, 0x8b, 0x58, 0x2e, 0x8b, 0xb9, 0xc6, 0xbe, 0x28, 0x33, 0x71, 0xad, 0xa5, 0x02, 0x23, 0x1d, 0x37, 0xfb, 0x44, 0xc8, 0xf2, 0x9b, 0x95, 0x62, 0xfe, 0xe3, 0xdd, 0x0a, 0x8e, 0xcf, 0x09, 0x1d, 0x6a, 0x11, 0xcd, 0x90, 0x28, 0xc4, 0x59, 0xe9, 0xe2, 0x18, 0xfa, 0x06, 0xa4, 0x8d, 0x1b, 0xae, 0xee, 0x77, 0x7f, 0xed, 0xf6, 0x64, 0x3d, 0xfb, 0xd1, 0xba, 0xa1, 0x79, 0xb7, 0x8a, 0xc4, 0x71, 0x8a, 0x52, 0xd9, 0x4d, 0x4c, 0xdf, 0xa0, 0x3f, 0x93, 0x5b, 0x6f, 0x3b, 0xc3, 0x21, 0xed, 0x3f, 0xed, 0xd3, 0x21, 0xb1, 0x12, 0x14, 0x8c, 0xac, 0xf6, 0x8e, 0x73, 0xcb, 0x97, 0x19, 0x38, 0xe5, 0xd6, 0xd7, 0xb3, 0x3b, 0x31, 0xa3, 0x74, 0xdf, 0x88, 0xde, 0x65, 0x57, 0x4b, 0x79, 0xbd, 0x60, 0x04, 0x4b, 0x5a, 0x5a, 0x59, 0xf9, 0x59, 0x08, 0x60, 0xaf, 0x22, 0x6b, 0xc0, 0xcc, 0xba, 0x96, 0x04, 0x32, 0x3e, 0x8a, 0xbf, 0x37, 0x81, 0x96, 0x63, 0x0a, 0x44, 0xdd, 0xde, 0x63, 0xd4, 0x39, 0xb2, 0x79, 0x85, 0xea, 0x81, 0xbd, 0xae, 0x97, 0x4e, 0x02, 0x98, 0x07, 0xb7, 0x5f, 0xcd, 0x7c, 0x15, 0x9c, 0x39, 0xdd, 0xf1, 0x4b, 0xfd, 0xe7, 0xde, 0xe1, 0x2d, 0x9c, 0xd1, 0x41, 0x90, 0x77, 0x5c, 0xa2, 0xcb, 0x64, 0x99, 0x6e, 0x8a, 0x16, 0xd0, 0xea, 0x69, 0x64, 0xb5, 0xfd, 0x48, 0xfd, 0xd6, 0xe8, 0x5e, 0xc3, 0x56, 0xe2, 0x85, 0xd9, 0x5e, 0xee, 0xcf, 0x3b, 0xf5, 0x48, 0x5d, 0x01, 0x4b, 0xd8, 0x83, 0x76, 0xad, 0x8e, 0x6a, 0x02, 0xab, 0x1e, 0x79, 0x2f, 0x6b, 0x67, 0x85, 0x7f, 0x87, 0xf5, 0x5b, 0x61, 0x5a, 0x22, 0x96, 0x1d, 0xf6, 0x78, 0xc6, 0x2d, 0x2b, 0x87, 0xd8, 0x6f, 0x90, 0xe1, 0x7d, 0x70, 0xaf, 0x76, 0xd3, 0x79, 0x4f, 0x15, 0x2d, 0x37, 0x22, 0x7b, 0xaf, 0x52, 0xaf, 0x32, 0xfa, 0xb9, 0x9f, 0xd2, 0x70, 0xbb, 0x1b, 0xf3, 0x62, 0x09, 0x0f, 0x07, 0xd4, 0xed, 0xbe, 0xe5, 0x4e, 0xef, 0x44, 0xa6, 0x9e, 0x8a, 0x70, 0x05, 0xbb, 0x21, 0x4c, 0x06, 0x67, 0x6b, 0x30, 0x86, 0x50, 0x62, 0x4f, 0x5e, 0xe7, 0xc3, 0x9e, 0xca, 0x1a, 0xec, 0x1f, 0xf8, 0xa6, 0x1d, 0x6f, 0xd7, 0x1b, 0xb5, 0xb0, 0xd0, 0x95, 0xe9, 0x21, 0x28, 0x84, 0x0a, 0xbe, 0x3f, 0xeb, 0x6f, 0x77, 0xb5, 0x09, 0xa7, 0x1e, 0x10, 0x24, 0x85, 0xb6, 0x4c, 0xcf, 0x75, 0xc3, 0xdb, 0x96, 0x88, 0x99, 0x33, 0x7f, 0x60, 0x9b, 0xf4, 0x6b, 0x12, 0xbd, 0x6b, 0x93, 0xb7, 0x38, 0xe0, 0x42, 0x58, 0x21, 0x60, 0xfd, 0xf8, 0x35, 0x38, 0x79, 0x93, 0xb0, 0x37, 0x88, 0x9c, 0x6d, 0x13, 0x8b, 0xf7, 0x20, 0x4b, 0xcb, 0x13, 0x91, 0xc9, 0x14, 0x36, 0x20, 0xdb, 0xee, 0x08, 0x23, 0xef, 0xef, 0xaa, 0xe1, 0xbe, 0x16, 0x9d, 0xe7, 0xc9, 0xd2, 0x2a, 0x23, 0x11, 0xa5, 0x87, 0xdb, 0x46, 0x0c, 0x03, 0x12, 0x60, 0xf6, 0x33, 0x7e, 0x36, 0xa0, 0x32, 0x80, 0x10, 0x0a, 0x68, 0x19, 0xb4, 0xd5, 0xdf, 0x87, 0x04, 0x53, 0x95, 0x2a, 0x04, 0x97, 0x2a, 0x6c, 0x9d, 0x2f, 0x8c, 0x6a, 0x58, 0xb6, 0x6d, 0x75, 0x43, 0x27, 0xb1, 0xe8, 0x1a, 0x95, 0x55, 0xe4, 0x6d, 0x90, 0x19, 0x46, 0x0b, 0x3a, 0x43, 0xa9, 0xfa, 0x19, 0x6e, 0xe2, 0xcf, 0x7b, 0x25, 0x04, 0x31, 0x5f, 0x4c, 0xd1, 0xb2, 0x6b, 0x17, 0x29, 0x2c, 0xe2, 0xae, 0x4f, 0x92, 0xb4, 0xcc, 0xb0, 0x59, 0xc4, 0x25, 0xb9, 0x3e, 0x74, 0xe9, 0x26, 0x9b, 0x4c, 0xb5, 0xbb, 0x0e, 0xc3, 0x76, 0x88, 0xad, 0x16, 0x62, 0x9c, 0x7c, 0xe2, 0x1f, 0xc4, 0xac, 0xf4, 0xba, 0x73, 0xa8, 0xd9, 0xda, 0xa8, 0x30, 0x26, 0xca, 0x54, 0x91, 0x00, 0xaf, 0x8c, 0x87, 0x0d, 0xd2, 0xac, 0x42, 0x5e, 0x1d, 0x4a, 0xba, 0x2e, 0x80, 0x4d, 0x39, 0xf9, 0x4e, 0x53, 0xdd, 0xa6, 0xb8, 0xcf, 0x13, 0x80, 0xa6, 0x21, 0x79, 0xea, 0x09, 0x14, 0x59, 0x46, 0xc9, 0x10, 0x38, 0x0a, 0xdc, 0xc8, 0x27, 0xae, 0x61, 0x5d, 0xca, 0x75, 0x34, 0x8b, 0x7e, 0xec, 0xe2, 0x07, 0x68, 0x40, 0xda, 0xc3, 0x30, 0xcd, 0x4f, 0xdc, 0x09, 0x99, 0xdb, 0xd9, 0x55, 0x37, 0x15, 0x38, 0x7d, 0x67, 0xeb, 0xde, 0x25, 0x12, 0xbc, 0xca, 0x1f, 0x91, 0x55, 0x43, 0xb0, 0x3f, 0x4e, 0x4c, 0xf4, 0x78, 0x92, 0x1a, 0xd9, 0x33, 0xa0, 0x97, 0xb5, 0xcb, 0x6e, 0x50, 0xa9, 0xb7, 0x78, 0x30, 0x28, 0x9a, 0xef, 0x74, 0xe3, 0x20, 0x09, 0x2d, 0xef, 0xbf, 0x18, 0x7c, 0xea, 0x0b, 0x62, 0xa4, 0x3f, 0x0d, 0x02, 0x3a, 0x18, 0xe3, 0xbf, 0x1c, 0x50, 0x1b, 0x0d, 0x87, 0xae, 0x15, 0x88, 0x9a, 0x78, 0x67, 0xad, 0xab, 0xe5, 0xa9, 0x92, 0x52, 0x73, 0x98, 0x7a, 0xe8, 0x8e, 0x4e, 0x12, 0x87, 0x3b, 0xde, 0xfb, 0x49, 0x7f, 0x89, 0xb3, 0x42, 0x0b, 0x70, 0x0c, 0xc5, 0x5e, 0x9a, 0xc6, 0xc6, 0xc7, 0x4a, 0xbd, 0xd0, 0x5f, 0xc0, 0xd0, 0xef, 0xff, 0x5b, 0x45, 0x76, 0x0c, 0x0a, 0x16, 0xaf, 0x4d, 0xe5, 0x9f, 0x0a, 0x69, 0x07, 0x65, 0xf2, 0x35, 0xa8, 0xb0, 0x9c, 0x68, 0x25, 0xfa, 0xa3, 0xfd, 0x5d, 0x43, 0x73, 0x9b, 0xf0, 0x13, 0x78, 0x61, 0x0c, 0xf3, 0xd4, 0x42, 0x2a, 0x32, 0xe8, 0x9b, 0x33, 0xbd, 0x95, 0x60, 0x95, 0x44, 0x99, 0xe4, 0xb8, 0x24, 0xa2, 0x2b, 0x2e, 0xd4, 0xc2, 0x27, 0x80, 0xb5, 0xac, 0xe1, 0x5e, 0xcc, 0x4e, 0xda, 0x13, 0x0b, 0xdf, 0x02, 0xca, 0x0d, 0x71, 0x81, 0xfa, 0x07, 0xcb, 0xb5, 0x1b, 0x6d, 0xa3, 0x60, 0x4e, 0xec, 0xca, 0x99, 0x6b, 0x2d, 0x5a, 0x4f, 0x18, 0x85, 0xfb, 0x70, 0xdd, 0xc1, 0xa3, 0x44, 0x91, 0xa0, 0xaa, 0xca, 0xf4, 0x9d, 0x76, 0xdc, 0xa5, 0x8b, 0x1c, 0x7f, 0x15, 0xa5, 0x51, 0xfb, 0x6d, 0x06, 0xb4, 0x2e, 0x09, 0xb6, 0xc1, 0xdf, 0x28, 0x60, 0x8c, 0x45, 0x74, 0x67, 0x13, 0x0d, 0x96, 0x13, 0xb6, 0xc6, 0xec, 0xab, 0x84, 0xe8, 0x67, 0xba, 0x97, 0x2c, 0xc1, 0x2e, 0xc6, 0x48, 0xd1, 0x6b, 0x1f, 0x51, 0x1d, 0xa3, 0xc5, 0x53, 0x02, 0x91, 0xb1, 0x65, 0xf7, 0x9f, 0x5a, 0x1a, 0xc3, 0x40, 0x29, 0x9d, 0xac, 0x36, 0xff, 0x28, 0x85, 0xb8, 0xdd, 0xb6, 0xbc, 0xb6, 0x86, 0xa8, 0xb2, 0x86, 0x76, 0x0e, 0x03, 0x3a, 0xaa, 0x86, 0x10, 0xa0, 0x77, 0x73, 0x12, 0xc8, 0x5e, 0x67, 0xf7, 0xb8, 0xfb, 0x2d, 0xd9, 0x7f, 0x5f, 0xcc, 0xed, 0x15, 0x15, 0x76, 0xa7, 0xb5, 0x22, 0x69, 0xb8, 0xd3, 0xa1, 0xa6, 0x5e, 0x17, 0x6c, 0x29, 0x0e, 0x96, 0x6b, 0x53, 0xca, 0x26, 0x8a, 0x46, 0xf3, 0x8d, 0xd9, 0x63, 0x3a, 0x18, 0x55, 0x97, 0x49, 0x58, 0x30, 0x26, 0x3b, 0x75, 0x7e, 0x65, 0xe6, 0x87, 0xa8, 0x8f, 0x7e, 0xa3, 0x64, 0xd1, 0xf0, 0x60, 0x39, 0xf9, 0x3a, 0x18, 0x4d, 0x85, 0xd7, 0x7e, 0xa4, 0xaa, 0x95, 0x44, 0x34, 0x45, 0x5a, 0x12, 0xc5, 0xd5, 0x3c, 0x20, 0x5e, 0xad, 0x30, 0x7b, 0xd5, 0x63, 0x28, 0x91, 0x3a, 0x48, 0xfb, 0x9e, 0x7e, 0xfd, 0x86, 0xb3, 0x04, 0x62, 0x23, 0xa7, 0x62, 0xbc, 0x97, 0xbf, 0xfc, 0x4c, 0x6c, 0x1f, 0x05, 0x5f, 0x43, 0x60, 0xb3, 0x05, 0xa8, 0xa9, 0x7e, 0xce, 0x37, 0xf3, 0x16, 0x8b, 0x22, 0xf7, 0x0d, 0xd5, 0x78, 0x01, 0x16, 0xd5, 0xef, 0x41, 0xa0, 0x20, 0x93, 0xe7, 0xd4, 0xf4, 0x42, 0x42, 0x71, 0xf9, 0x0f, 0x93, 0x69, 0xfb, 0xcd, 0x5b, 0x30, 0x4a, 0x70, 0x57, 0x73, 0x19, 0xd7, 0xa5, 0x9b, 0x35, 0x47, 0xcf, 0x21, 0x59, 0x70, 0xcf, 0x39, 0xaa, 0x3d, 0x6e, 0xac, 0x05, 0x26, 0x6a, 0x16, 0x6c, 0x43, 0x34, 0xcf, 0x22, 0x1c, 0x09, 0x39, 0xb2, 0xdd, 0xff, 0x15, 0x09, 0x44, 0x3d, 0x98, 0x3c, 0x8b, 0x82, 0x10, 0x80, 0x95, 0x66, 0xb2, 0x94, 0x6c, 0xc2, 0xe1, 0x17, 0x80, 0x45, 0xa1, 0xc8, 0xa3, 0xf7, 0xbd, 0xd7, 0x2f, 0x00, 0x23, 0x20, 0x28, 0xf2, 0xe1, 0x06, 0xf6, 0xa9, 0x1e, 0xcc, 0x5d, 0x6b, 0x76, 0x9c, 0xac, 0xfb, 0xb2, 0x48, 0x28, 0x23, 0x4b, 0x8b, 0x5f, 0x5f, 0xb2, 0x98, 0xe9, 0x3e, 0x1c, 0x4c, 0xe3, 0x75, 0x6b, 0x2d, 0xb3, 0xb9, 0xa9, 0x2b, 0x68, 0xb3, 0xbd, 0x3f, 0x15, 0x5c, 0xa3, 0xbd, 0x4c, 0x79, 0x9f, 0xad, 0x4f, 0x64, 0x27, 0xf0, 0xf8, 0xa5, 0x39, 0x37, 0x1c, 0xb6, 0x25, 0x3a, 0x46, 0xdf, 0x86, 0x60, 0x08, 0x83, 0x9b, 0x48, 0x48, 0x76, 0xfa, 0x19, 0x9a, 0x7b, 0x2c, 0x7f, 0xe8, 0xa3, 0x6a, 0x09, 0xf4, 0x1c, 0x0a, 0x4b, 0x8b, 0x4e, 0xdb, 0x66, 0xc5, 0x00, 0x06, 0x9f, 0xe0, 0x9a, 0x63, 0xc7, 0xf1, 0x26, 0xee, 0xe8, 0x3f, 0x90, 0xb2, 0x35, 0x90, 0xa7, 0x89, 0x32, 0x7b, 0x4e, 0xbd, 0x79, 0xf1, 0x41, 0xe8, 0xa4, 0xe1, 0xd3, 0x78, 0x88, 0x1c, 0x7d, 0x05, 0xf3, 0x3f, 0xf4, 0x09, 0xec, 0x25, 0x0a, 0xa0, 0x7f, 0x3a, 0x35, 0x0c, 0x8f, 0x99, 0x30, 0x7f, 0x6b, 0x07, 0xac, 0xfc, 0x91, 0x56, 0x1c, 0xb6, 0x5f, 0x1d, 0x6e, 0xd6, 0xf6, 0x20, 0x7e, 0xa3, 0x26, 0x13, 0x13, 0x36, 0x05, 0xb6, 0xfc, 0x04, 0x15, 0xd6, 0x1a, 0x40, 0x56, 0x70, 0x96, 0x9a, 0xac, 0x30, 0x47, 0x37, 0x80, 0x3c, 0x69, 0xcd, 0xf9, 0x67, 0x15, 0x98, 0xb7, 0xd1, 0x03, 0x77, 0x0e, 0xa6, 0x13, 0x9c, 0x3a, 0x95, 0x35, 0x3a, 0xb4, 0x17, 0x19, 0x85, 0x21, 0x79, 0x79, 0xf0, 0xd6, 0x33, 0xbf, 0x46, 0xc1, 0x16, 0xb1, 0x43, 0x89, 0x09, 0xbe, 0xc0, 0xaa, 0x8d, 0x09, 0xcf, 0xbe, 0xcc, 0x6b, 0x31, 0xf4, 0x1a, 0xb0, 0x3b, 0xa9, 0x68, 0x8f, 0x93, 0xec, 0x26, 0xf3, 0xed, 0x1f, 0x18, 0xb6, 0x29, 0x03, 0x68, 0x71, 0x88, 0x38, 0xe9, 0x1f, 0xa0, 0xba, 0xd6, 0x91, 0x3b, 0xe2, 0x91, 0x69, 0x05, 0xfc, 0xfe, 0x0f, 0x6e, 0x0b, 0x76, 0x48, 0xcc, 0x58, 0xe7, 0x84, 0xb1, 0x72, 0x25, 0x32, 0x6d, 0x0b, 0xf1, 0xd6, 0x9d, 0xe5, 0x8c, 0xee, 0x3e, 0x57, 0xdb, 0x51, 0xda, 0x96, 0xc4, 0x97, 0xa5, 0xd9, 0x7c, 0x8c, 0x3a, 0x2c, 0xf0, 0x7c, 0x20, 0x30, 0xb8, 0x27, 0x43, 0x1b, 0x30, 0xd0, 0xcf, 0x5f, 0x6a, 0x87, 0x73, 0x3d, 0x03, 0x07, 0xcd, 0x77, 0x86, 0x99, 0x08, 0x99, 0xae, 0x28, 0x21, 0x5b, 0xfb, 0xb9, 0xd9, 0xcb, 0xf1, 0xc3, 0x8e, 0xaa, 0x33, 0x79, 0x2c, 0x67, 0xd3, 0x02, 0x93, 0xc0, 0x44, 0x01, 0xa1, 0xc8, 0xa4, 0xf7, 0x2c, 0x1f, 0x5d, 0xf4, 0xba, 0x21, 0xf5, 0x13, 0x47, 0xff, 0x86, 0x19, 0x04, 0x7e, 0x8d, 0x58, 0x20, 0xc0, 0xff, 0xa3, 0x44, 0x11, 0xc1, 0x71, 0x7e, 0xac, 0x83, 0x5f, 0x2f, 0xe9, 0xea, 0xab, 0x58, 0xb7, 0x30, 0x5c, 0x5b, 0x55, 0x0f, 0xd3, 0xf8, 0xee, 0x2a, 0x7d, 0xfe, 0xc7, 0x75, 0x93, 0x1c, 0x67, 0x52, 0x98, 0x4b, 0xf8, 0xe5, 0xef, 0xf0, 0xae, 0x74, 0x3a, 0x3a, 0xa2, 0x58, 0x22, 0xf4, 0x7b, 0xe7, 0x22, 0x38, 0x5c, 0x8e, 0x18, 0x79, 0xdc, 0x48, 0x1a, 0x1d, 0xe5, 0x66, 0x9c, 0x00, 0x31, 0x19, 0xfa, 0xab, 0x93, 0x1b, 0x36, 0x3f, 0x48, 0x81, 0x7e, 0x15, 0xee, 0xda, 0x9b, 0x08, 0x0c, 0x71, 0xc8, 0xe1, 0xb5, 0x4d, 0x07, 0x29, 0x3a, 0x62, 0x96, 0x10, 0xb8, 0xeb, 0x7a, 0x61, 0x0f, 0x7d, 0x53, 0x61, 0x7e, 0xff, 0x79, 0x05, 0xc0, 0x8f, 0x8e, 0x93, 0xa9, 0x44, 0x9d, 0x08, 0x55, 0x22, 0x11, 0x70, 0x7d, 0xc9, 0x50, 0xef, 0x7b, 0x13, 0x3c, 0xde, 0x89, 0xed, 0x8d, 0xff, 0x19, 0x18, 0x8c, 0x63, 0xc4, 0xc6, 0x72, 0x4c, 0x54, 0x23, 0x2f, 0xdc, 0x6f, 0x9c, 0xa7, 0xac, 0x29, 0x2b, 0xa3, 0x16, 0x63, 0x10, 0xc9, 0xe0, 0x1e, 0xb0, 0xc6, 0x87, 0xdd, 0xca, 0xf3, 0x8e, 0xc3, 0xbd, 0x78, 0x6b, 0x71, 0x92, 0x0f, 0xf6, 0x70, 0xcf, 0x74, 0xde, 0xf5, 0x0f, 0x3f, 0x9d, 0x89, 0x52, 0xa3, 0xf7, 0xc4, 0x99, 0x9c, 0xe6, 0xf2, 0x50, 0xb3, 0xd8, 0x35, 0x71, 0xb3, 0x9f, 0xb1, 0x2b, 0x5e, 0xcc, 0x09, 0xaf, 0x50, 0x6e, 0xd9, 0x86, 0xba, 0x8b, 0xe4, 0xb5, 0x1c, 0xbe, 0x29, 0x43, 0xf1, 0x4d, 0x73, 0x0e, 0xc4, 0x6a, 0x8d, 0x6d, 0x76, 0x25, 0xf6, 0x69, 0x9e, 0xa6, 0xe3, 0xf6, 0x3d, 0x5c, 0x6c, 0x2e, 0xf9, 0x0b, 0x0e, 0x12, 0xc8, 0x49, 0xfd, 0x6b, 0x5a, 0xfc, 0x1b, 0x36, 0x19, 0x2c, 0x0a, 0xb9, 0x27, 0x55, 0xa4, 0x26, 0xf6, 0x05, 0x2f, 0x9b, 0xef, 0x05, 0x89, 0x22, 0x04, 0xf1, 0xbc, 0x59, 0x6e, 0x2c, 0x13, 0xb7, 0x31, 0x8a, 0x80, 0xdf, 0xe6, 0x2d, 0xa5, 0x15, 0x4e, 0x9e, 0x08, 0xb6, 0xb3, 0x50, 0xa1, 0x04, 0x1c, 0x8c, 0xc6, 0xaf, 0x32, 0x5d, 0xcf, 0x49, 0xe4, 0x96, 0x69, 0x94, 0x7b, 0xdb, 0x18, 0x3c, 0x65, 0x70, 0xc7, 0xda, 0x23, 0x92, 0x0a, 0x99, 0x86, 0xa0, 0xdd, 0x8c, 0xe5, 0x0a, 0xde, 0x3a, 0x98, 0x3f, 0x3f, 0xa1, 0xd1, 0xea, 0x05, 0x92, 0xb0, 0xad, 0x7b, 0x33, 0x8a, 0x71, 0x20, 0xf3, 0x8f, 0xd7, 0x70, 0x95, 0x62, 0xc6, 0x7e, 0xf8, 0xa3, 0xa0, 0x31, 0x1a, 0x34, 0x8b, 0x0f, 0xad, 0x93, 0x2c, 0x3d, 0x74, 0x94, 0x08, 0x67, 0x8d, 0x14, 0x54, 0x76, 0x7d, 0xc4, 0x19, 0xd9, 0x4d, 0x81, 0xe8, 0x5d, 0x56, 0x69, 0xd7, 0x58, 0x4e, 0x0b, 0xf2, 0x86, 0x7a, 0xed, 0x9a, 0x5e, 0x13, 0x48, 0x67, 0xea, 0x7d, 0x94, 0xa2, 0xa1, 0x1c, 0x78, 0xc3, 0x3a, 0xe6, 0x11, 0xc0, 0xcc, 0xee, 0x78, 0x3a, 0xc5, 0x86, 0xbd, 0xde, 0xb1, 0x6b, 0xac, 0x02, 0xc0, 0x8d, 0xc9, 0x6c, 0x81, 0x06, 0xb1, 0x0e, 0x83, 0x73, 0xd8, 0x50, 0xa1, 0x0e, 0x31, 0xa0, 0xe5, 0x9d, 0xb9, 0x1e, 0x03, 0xf3, 0x30, 0x83, 0x16, 0x54, 0xa6, 0x98, 0x28, 0xc8, 0xe0, 0xd5, 0x7d, 0x84, 0x4f, 0x56, 0x9c, 0xbd, 0xb2, 0xba, 0x98, 0xc1, 0x3c, 0xc9, 0x84, 0x60, 0x23, 0xd9, 0x0f, 0x85, 0x14, 0xdf, 0x90, 0xd1, 0x48, 0xd9, 0xf7, 0x3c, 0x34, 0x11, 0x3d, 0x6c, 0x72, 0x52, 0xb5, 0x98, 0xcc, 0x7c, 0x4f, 0x0e, 0x93, 0x64, 0x17, 0x63, 0x5c, 0x09, 0xb3, 0x40, 0x90, 0xbc, 0x5e, 0x3b, 0xe0, 0x8c, 0xc5, 0x15, 0xc6, 0xe6, 0xb3, 0x13, 0x72, 0xdb, 0x7d, 0xc9, 0xb9, 0x01, 0x44, 0xf6, 0x79, 0x3b, 0xc1, 0xe1, 0x42, 0xd2, 0x4e, 0x65, 0xa8, 0xce, 0x92, 0x8c, 0x5b, 0x2a, 0x09, 0xaa, 0x8a, 0x3c, 0x1d, 0xff, 0x68, 0x1b, 0x19, 0xd5, 0x7b, 0x87, 0x56, 0x28, 0xda, 0x53, 0xe5, 0x50, 0xa6, 0xc1, 0xa4, 0xa9, 0xc2, 0xf8, 0xb8, 0x0a, 0xf3, 0x7a, 0x25, 0x24, 0x62, 0xca, 0x8a, 0xa3, 0x57, 0x44, 0xd9, 0x0a, 0x1b, 0x87, 0x31, 0x3f, 0x86, 0x15, 0xd6, 0x09, 0xef, 0xfd, 0xd7, 0xeb, 0x72, 0xbe, 0xf7, 0xd9, 0x67, 0xee, 0xc1, 0xab, 0xda, 0x9e, 0x3e, 0xda, 0x6d, 0x1e, 0x08, 0xa3, 0x36, 0xee, 0x30, 0x5f, 0xff, 0x28, 0xe2, 0xa2, 0xeb, 0x29, 0x29, 0x3b, 0x01, 0x83, 0xa9, 0xec, 0x67, 0xe7, 0x76, 0x8f, 0xcf, 0xe0, 0xc4, 0x3a, 0x34, 0x17, 0xa4, 0xb1, 0x7a, 0xda, 0xa0, 0x22, 0xa1, 0x53, 0x6e, 0xdd, 0x2d, 0x7d, 0xdb, 0x10, 0x3a, 0x10, 0x69, 0x9c, 0x15, 0x02, 0x3c, 0x9e, 0x25, 0xd4, 0xb2, 0x85, 0x07, 0x9b, 0x50, 0xa4, 0x61, 0x52, 0x15, 0xb0, 0x62, 0x08, 0x37, 0xf8, 0x1f, 0xeb, 0x2e, 0x43, 0x64, 0x9f, 0x45, 0x15, 0xab, 0xba, 0xe2, 0xcc, 0x8c, 0x78, 0x13, 0x35, 0x0c, 0xbc, 0x77, 0x43, 0x8f, 0x3d, 0x9b, 0x5f, 0x8f, 0x56, 0xb6, 0x68, 0x7e, 0xd0, 0x00, 0x4f, 0x7d, 0x1b, 0xa5, 0x8d, 0x3d, 0x00, 0xd7, 0x85, 0x69, 0x0d, 0x0e, 0x6d, 0x4d, 0x7a, 0xa3, 0x20, 0x51, 0x89, 0xb9, 0x8a, 0xc5, 0x1f, 0xaa, 0x87, 0x9a, 0x36, 0xa4, 0x65, 0xfc, 0xe7, 0x41, 0xa1, 0x1f, 0xdb, 0xef, 0xbd, 0x0f, 0xc8, 0xa8, 0xed, 0xba, 0x1f, 0x03, 0x95, 0x9a, 0x7b, 0xb9, 0x2b, 0xb6, 0xe9, 0x3c, 0x92, 0x75, 0x26, 0x6f, 0xd0, 0xaf, 0x67, 0x65, 0xf6, 0xb7, 0x51, 0x5d, 0x30, 0x87, 0xa3, 0x9d, 0x4c, 0x3b, 0x87, 0x5d, 0xfd, 0x2e, 0xed, 0x5a, 0x81, 0x06, 0xd3, 0xab, 0xd6, 0x6d, 0xcc, 0xcd, 0x18, 0x3d, 0xab, 0x35, 0x22, 0x7d, 0xed, 0xb3, 0xf4, 0x3f, 0xfc, 0xa0, 0x41, 0xd5, 0xf1, 0xfe, 0x01, 0x35, 0x60, 0x3a, 0x3b, 0x84, 0x15, 0x01, 0xc3, 0x81, 0x89, 0xeb, 0x3f, 0xdb, 0xfe, 0x1c, 0xda, 0xe0, 0xcc, 0x8c, 0xed, 0x89, 0xd9, 0x9e, 0x9b, 0xdd, 0xd9, 0xf9, 0xb0, 0x52, 0x92, 0x94, 0x0a, 0xc3, 0xe9, 0x88, 0x56, 0xca, 0x7a, 0x74, 0xd6, 0xdd, 0x97, 0xb3, 0x2a, 0x44, 0x3f, 0x32, 0xbc, 0x1c, 0x68, 0x67, 0x2a, 0x24, 0x02, 0x47, 0x11, 0xcd, 0x30, 0x04, 0xbd, 0x1e, 0xa6, 0xbd, 0x16, 0x75, 0x14, 0xb6, 0x83, 0x46, 0xa6, 0x56, 0x2a, 0x54, 0xca, 0x3d, 0x6f, 0x99, 0xd9, 0xb3, 0x31, 0xd4, 0x31, 0xc7, 0x7d, 0xfe, 0xe1, 0x55, 0x69, 0xc5, 0xd6, 0x2b, 0x51, 0x48, 0xae, 0x7f, 0x19, 0x34, 0xe6, 0x8c, 0x0c, 0x2d, 0xa4, 0x18, 0x09, 0x20, 0xb7, 0xa9, 0xc7, 0x54, 0x94, 0x7a, 0xd1, 0x0a, 0x56, 0x66, 0x71, 0x60, 0xe0, 0x7f, 0x2f, 0x2b, 0xb4, 0xd2, 0x3e, 0xa6, 0x97, 0x60, 0x25, 0x8e, 0x5f, 0x41, 0x3d, 0xa7, 0x94, 0x5f, 0x7e, 0xc1, 0x66, 0x6d, 0x14, 0xae, 0xff, 0x96, 0x70, 0x5c, 0x07, 0xc7, 0x05, 0xb5, 0xaf, 0x0d, 0xe4, 0xf5, 0xff, 0x8b, 0xf7, 0x06, 0x50, 0x2c, 0xfa, 0xad, 0x27, 0x04, 0xd9, 0x7b, 0x3a, 0xb7, 0x1c, 0x98, 0xd6, 0x09, 0x9c, 0x95, 0x9b, 0x69, 0x53, 0x9d, 0x36, 0xf6, 0x3a, 0x59, 0xcf, 0x64, 0xc9, 0xa9, 0x04, 0xa8, 0xd5, 0x91, 0xc4, 0x4c, 0xac, 0x21, 0xdc, 0xa4, 0xac, 0xf3, 0x56, 0x46, 0x77, 0x92, 0x1c, 0x6f, 0x96, 0x5a, 0xc6, 0x04, 0xf1, 0x4f, 0x4d, 0xd3, 0xd9, 0x06, 0x07, 0xb7, 0x26, 0x99, 0x55, 0xe5, 0x77, 0x84, 0x3b, 0xc1, 0xb1, 0x15, 0x83, 0x91, 0x36, 0x2e, 0x4c, 0x46, 0x5c, 0x26, 0xa5, 0x92, 0x91, 0x62, 0x1b, 0xcc, 0x49, 0xa2, 0xb2, 0xd0, 0x04, 0xc9, 0x33, 0xb2, 0xb0, 0x7c, 0x20, 0xa2, 0x86, 0xb3, 0x69, 0x57, 0xf2, 0xa2, 0x5e, 0x08, 0x7d, 0x8a, 0x27, 0xbb, 0xd8, 0x0c, 0xdc, 0xd9, 0x78, 0x9d, 0xc1, 0xe4, 0x7d, 0xa9, 0x66, 0x84, 0x0a, 0xff, 0xd3, 0x59, 0x86, 0xe1, 0xa4, 0xcb, 0xab, 0xdd, 0x03, 0x8b, 0x8e, 0xda, 0x3c, 0xa9, 0x28, 0x2a, 0xec, 0xd5, 0xb6, 0x66, 0xf9, 0xab, 0x75, 0x91, 0xab, 0xd2, 0x6e, 0x86, 0xd3, 0x9f, 0x25, 0xdd, 0xe7, 0xbd, 0x05, 0xbf, 0xb9, 0x9c, 0x12, 0x9f, 0xcb, 0xbe, 0x18, 0x09, 0x2d, 0x80, 0x46, 0x2a, 0xee, 0xcd, 0x23, 0x26, 0x9a, 0x8a, 0x2a, 0xf3, 0x60, 0x88, 0xed, 0x72, 0x98, 0xaf, 0x8e, 0xf8, 0x1e, 0xcc, 0xe1, 0xab, 0x28, 0x4a, 0x56, 0x94, 0xde, 0xbd, 0x7e, 0x49, 0x31, 0x32, 0xaa, 0x11, 0x5a, 0x66, 0xd4, 0xf1, 0x10, 0x57, 0x2d, 0x43, 0x24, 0xb7, 0x11, 0x07, 0xad, 0x76, 0xf3, 0x67, 0x2c, 0x8e, 0xbb, 0xa5, 0x32, 0x67, 0x1d, 0x3a, 0x71, 0x09, 0x6c, 0xd3, 0x39, 0x22, 0xb5, 0xaf, 0x07, 0xea, 0xa6, 0x99, 0xfe, 0xdc, 0xeb, 0x43, 0x44, 0x2e, 0xc2, 0xb3, 0xa4, 0x68, 0xfc, 0xd1, 0x70, 0x09, 0x28, 0x9c, 0xde, 0x57, 0x99, 0xe2, 0x64, 0x56, 0xde, 0x1f, 0x93, 0xd7, 0x12, 0x33, 0xba, 0xcd, 0xa8, 0x58, 0x68, 0x63, 0xf9, 0xeb, 0xde, 0x05, 0x24, 0x64, 0xdb, 0x34, 0xd5, 0xe0, 0x95, 0xef, 0xb2, 0xb0, 0x4a, 0x03, 0x09, 0xd5, 0xfb, 0x5c, 0x92, 0xdf, 0xca, 0x22, 0x47, 0x39, 0xfa, 0xc3, 0x14, 0xb8, 0x47, 0xfb, 0x3d, 0x63, 0x4a, 0x6d, 0xbf, 0xaa, 0x4e, 0xa0, 0xc7, 0x3d, 0x40, 0xd1, 0x23, 0xda, 0xd9, 0x25, 0xdc, 0x83, 0x86, 0x22, 0xeb, 0x43, 0x81, 0xaf, 0x70, 0xb7, 0xd0, 0x96, 0xef, 0x90, 0xff, 0x90, 0x8e, 0xcd, 0x55, 0x38, 0x4f, 0x7d, 0xa2, 0xa1, 0x24, 0x1b, 0x97, 0xea, 0x07, 0x7c, 0x1f, 0x44, 0x21, 0xc6, 0xb0, 0x08, 0xf8, 0x64, 0x06, 0x24, 0x3a, 0xc0, 0x8f, 0x11, 0x1a, 0x9b, 0x3f, 0x3d, 0xc7, 0x9a, 0xed, 0xcb, 0x65, 0xa3, 0x5c, 0x38, 0x76, 0xf1, 0x5c, 0x38, 0xdf, 0xea, 0x79, 0xdc, 0xa4, 0x83, 0x70, 0xa5, 0x5d, 0x80, 0x68, 0x5b, 0x38, 0x9c, 0xa3, 0xdd, 0xb0, 0x05, 0x05, 0x76, 0x41, 0x92, 0xca, 0x0f, 0x3f, 0xf9, 0xe8, 0x96, 0x30, 0x04, 0x07, 0xef, 0x23, 0xc1, 0xc6, 0xaa, 0x3f, 0xb4, 0xff, 0x0b, 0xb7, 0x11, 0x7f, 0xff, 0xa2, 0xe1, 0xdc, 0x03, 0xb2, 0xf9, 0x80, 0x2b, 0x61, 0xda, 0xa2, 0x28, 0x1d, 0xd4, 0x85, 0x70, 0x81, 0x7b, 0x07, 0xb1, 0xd3, 0x29, 0xb4, 0x7c, 0x53, 0x02, 0x07, 0x9c, 0x3c, 0xdc, 0xf1, 0x01, 0xdd, 0x33, 0x7e, 0xdc, 0x8b, 0xbd, 0x09, 0x78, 0x4c, 0xca, 0x32, 0xc6, 0x32, 0x32, 0x38, 0x71, 0x72, 0x06, 0xf4, 0xce, 0x71, 0x00, 0x3a, 0x6f, 0xda, 0x85, 0xc8, 0x2d, 0x0f, 0x51, 0x85, 0x9f, 0xae, 0x75, 0xf6, 0xbe, 0x68, 0x7f, 0x0d, 0x7a, 0x39, 0x35, 0xb8, 0x51, 0xd3, 0xef, 0x16, 0x0f, 0x07, 0x1e, 0x17, 0x75, 0x3c, 0xa3, 0x0c, 0xb0, 0xea, 0x24, 0xaf, 0xd6, 0x87, 0xc8, 0x8e, 0x1e, 0x98, 0x0f, 0x34, 0x8f, 0xe7, 0x9c, 0x65, 0x65, 0xb7, 0x8b, 0xe0, 0x39, 0x40, 0xd1, 0xc8, 0xdc, 0x12, 0x0a, 0x4d, 0xc4, 0xe2, 0xf6, 0xf9, 0xcc, 0xbd, 0x24, 0x65, 0x34, 0x39, 0xfd, 0x23, 0x43, 0xc3, 0xdc, 0x65, 0x99, 0xdf, 0xc7, 0x09, 0x5a, 0x36, 0xa0, 0x0d, 0xe3, 0x10, 0x19, 0xa4, 0xf6, 0x9c, 0x80, 0xbc, 0x30, 0xe3, 0x9a, 0x85, 0xeb, 0x78, 0x2b, 0x1b, 0x13, 0x06, 0x97, 0x7d, 0xe8, 0xa8, 0xa0, 0x4b, 0x39, 0x42, 0xc7, 0x73, 0xa5, 0xd0, 0x4c, 0xc5, 0x55, 0xd2, 0x09, 0x91, 0x29, 0xf3, 0x7e, 0x06, 0x72, 0xb4, 0x27, 0xca, 0x57, 0x37, 0x9d, 0xcc, 0x32, 0x41, 0xe4, 0x6e, 0xda, 0x9c, 0xa2, 0xe1, 0x3d, 0x02, 0xc3, 0x61, 0x63, 0x7e, 0xba, 0x32, 0x6f, 0xc9, 0x85, 0x81, 0xf1, 0xb6, 0x37, 0xba, 0x45, 0xc0, 0x75, 0x22, 0x23, 0xda, 0xab, 0x3b, 0xc6, 0xcd, 0xa1, 0x74, 0xc3, 0x30, 0x4a, 0x12, 0xa3, 0xf4, 0x71, 0x80, 0x4f, 0x82, 0x0e, 0x3e, 0xef, 0x0c, 0x1d, 0x9a, 0x13, 0x54, 0x5c, 0x27, 0xf5, 0x35, 0x20, 0x6b, 0xb3, 0x5c, 0x5c, 0xeb, 0x30, 0x1a, 0x44, 0x38, 0x77, 0x56, 0x84, 0x7a, 0xbc, 0x38, 0xc5, 0x15, 0x3e, 0xdb, 0x92, 0x79, 0x87, 0xe7, 0x78, 0x9f, 0x80, 0xaa, 0x83, 0x2b, 0xc5, 0x1a, 0xdb, 0x91, 0xc9, 0xef, 0xe5, 0x7a, 0x4d, 0xbb, 0x6e, 0xb3, 0xdc, 0xdc, 0x44, 0x62, 0xbc, 0xe6, 0xf1, 0xad, 0x28, 0xfd, 0xe4, 0xba, 0xf6, 0x05, 0x1c, 0x77, 0x2d, 0x61, 0x96, 0xde, 0xcd, 0x44, 0x0f, 0x10, 0x91, 0x61, 0x93, 0x3a, 0x4f, 0x9d, 0x7f, 0xf6, 0x2a, 0x43, 0x57, 0x21, 0x4a, 0xdf, 0xca, 0xcf, 0x5d, 0xaf, 0x41, 0x53, 0xa7, 0x77, 0x4c, 0xf3, 0x4f, 0xda, 0x48, 0x20, 0x5a, 0x0b, 0x9f, 0xaa, 0x23, 0x4d, 0x12, 0xec, 0xac, 0xed, 0xbf, 0x3d, 0xcc, 0x72, 0x57, 0x36, 0xc5, 0x97, 0x4b, 0x72, 0xc6, 0x03, 0x22, 0xea, 0x43, 0x12, 0x50, 0x8e, 0x58, 0xb9, 0x1a, 0x6e, 0x5a, 0x1e, 0x3a, 0x2f, 0xa1, 0x48, 0x9e, 0xfb, 0x96, 0x5e, 0xa0, 0x9e, 0x80, 0xcc, 0xe4, 0x8a, 0x63, 0x7f, 0x54, 0x6a, 0x44, 0x77, 0xc2, 0x6b, 0x93, 0x73, 0xa0, 0x2e, 0x4b, 0x57, 0x16, 0x3a, 0x0a, 0xd2, 0x33, 0x3e, 0x42, 0x7c, 0x3a, 0x79, 0x09, 0x3d, 0xae, 0xfd, 0x1e, 0x14, 0x56, 0x25, 0x7c, 0xb9, 0x59, 0x37, 0x8d, 0x89, 0x36, 0xdd, 0x25, 0xb4, 0x64, 0x35, 0x2b, 0x6e, 0x09, 0x8c, 0x27, 0x3f, 0x0b, 0x54, 0xe3, 0x4a, 0xf2, 0x7d, 0xca, 0xc0, 0xe0, 0x1a, 0x9e, 0x0b, 0x15, 0xb6, 0x75, 0x0e, 0x56, 0xb0, 0x58, 0x28, 0x90, 0x87, 0x16, 0xcc, 0xc7, 0xfd, 0x3e, 0x4b, 0x56, 0x8d, 0xfb, 0x95, 0x67, 0x5b, 0x0e, 0xa8, 0xce, 0x47, 0xbc, 0x01, 0x0b, 0x05, 0xae, 0x9e, 0xea, 0x69, 0x2f, 0x68, 0x57, 0x3c, 0x09, 0xf1, 0x95, 0x02, 0xbd, 0x38, 0x80, 0x58, 0x72, 0x09, 0x93, 0xc0, 0xe0, 0x32, 0xba, 0x58, 0xd8, 0x17, 0xf1, 0xb1, 0xa6, 0x90, 0x27, 0x75, 0xf1, 0x0a, 0x31, 0x68, 0x18, 0x31, 0x09, 0xa7, 0x41, 0x46, 0xaf, 0xf8, 0xf7, 0x2e, 0x3a, 0x7e, 0xa6, 0x6a, 0x44, 0x8d, 0xf9, 0xd2, 0xbe, 0x60, 0xe9, 0x5c, 0xcb, 0x7b, 0x60, 0xbf, 0xc8, 0xe5, 0x6e, 0xe8, 0x00, 0x08, 0x7b, 0x4a, 0xe3, 0xf2, 0x2b, 0xf0, 0x09, 0xce, 0x63, 0x63, 0x08, 0x42, 0x63, 0x1c, 0x5c, 0x14, 0x0c, 0x86, 0xf5, 0x63, 0x70, 0xfb, 0xac, 0x0d, 0x1e, 0x4e, 0xe5, 0x34, 0x6f, 0x8a, 0xe3, 0xd1, 0xd5, 0x08, 0x89, 0xe2, 0x76, 0x43, 0xcf, 0x8b, 0x4a, 0x6d, 0x9c, 0x7d, 0x08, 0xf1, 0xc2, 0x71, 0x28, 0x58, 0x92, 0x0e, 0x69, 0xcf, 0xba, 0x1a, 0x6a, 0xb2, 0x44, 0x9b, 0x10, 0xf5, 0x3b, 0x00, 0x2f, 0x1e, 0xd1, 0x7e, 0x09, 0x96, 0x47, 0x3c, 0x3f, 0x91, 0xc3, 0x04, 0xab, 0xfe, 0xf0, 0x7c, 0x70, 0x0e, 0xe6, 0x94, 0x3d, 0x57, 0xcc, 0x7f, 0xb0, 0xb1, 0x31, 0xf1, 0xdd, 0x13, 0x3b, 0xa0, 0xc1, 0x62, 0x2c, 0x0d, 0x0f, 0x40, 0x95, 0x26, 0x82, 0x2d, 0x4e, 0xd4, 0x9d, 0x71, 0x2a, 0x67, 0x4a, 0x83, 0xe3, 0x91, 0x86, 0x37, 0x49, 0x79, 0x00, 0x8e, 0x0b, 0xd4, 0xd4, 0xd4, 0x6c, 0x96, 0x3a, 0x32, 0xcb, 0x65, 0xae, 0x0b, 0x95, 0x11, 0xa3, 0xbc, 0x0b, 0x08, 0xb2, 0x8e, 0xa2, 0xeb, 0x6c, 0x7d, 0x81, 0x0c, 0x6b, 0xed, 0x44, 0x08, 0x50, 0x43, 0x2d, 0xa8, 0x3b, 0x85, 0xea, 0x92, 0x54, 0x5d, 0x04, 0x4b, 0x49, 0x11, 0x03, 0xd5, 0xd2, 0x2a, 0x42, 0x6b, 0x0b, 0x14, 0x57, 0x9a, 0x07, 0x8b, 0x1b, 0x56, 0x67, 0x64, 0x3c, 0x60, 0xcf, 0xdc, 0xa6, 0x7b, 0x00, 0x99, 0xe5, 0xc1, 0xfe, 0xba, 0x8b, 0x34, 0x28, 0xf0, 0xab, 0x06, 0x69, 0x82, 0xe6, 0x2d, 0x00, 0x4a, 0x9b, 0x49, 0xec, 0x88, 0x4c, 0xad, 0xf6, 0xef, 0x43, 0xa6, 0xa1, 0x81, 0xe3, 0x27, 0x3b, 0xa1, 0x4b, 0x92, 0xb3, 0xea, 0x41, 0x3b, 0x17, 0x63, 0x21, 0x3b, 0x42, 0x9f, 0xc4, 0xf8, 0xa3, 0xe7, 0xd2, 0x36, 0xe8, 0x65, 0x95, 0xf1, 0xc9, 0xce, 0x81, 0xcd, 0xad, 0xf3, 0x79, 0x4c, 0xe2, 0xe2, 0xb7, 0x04, 0xad, 0xa4, 0x48, 0x6f, 0x64, 0x98, 0xce, 0xca, 0x71, 0xa8, 0xe8, 0xed, 0x8e, 0x5c, 0x4a, 0x8b, 0xdf, 0xcb, 0xcf, 0x5b, 0x7e, 0xca, 0x0c, 0xc4, 0x8f, 0x65, 0x08, 0x58, 0x1a, 0x11, 0xa8, 0x52, 0x16, 0x99, 0x8a, 0x3a, 0xe9, 0xf1, 0x58, 0x1f, 0xb1, 0xcc, 0x74, 0xae, 0xe5, 0xca, 0x7d, 0x3b, 0xbb, 0x2c, 0x06, 0x33, 0xbf, 0xc0, 0xc1, 0x9a, 0xd9, 0xde, 0x24, 0x76, 0xd8, 0xee, 0xc7, 0xc6, 0xc1, 0xeb, 0x8c, 0x37, 0x2f, 0x70, 0x37, 0xd8, 0xa8, 0x9d, 0x7d, 0xe4, 0x81, 0x66, 0xab, 0xb3, 0x69, 0xcd, 0xb9, 0x32, 0x42, 0x3a, 0x3a, 0x14, 0x33, 0x4b, 0xdc, 0x90, 0xfd, 0x70, 0xe0, 0xc9, 0x5d, 0x00, 0xf8, 0x57, 0x39, 0x2a, 0x96, 0x43, 0xe6, 0x1f, 0x0e, 0xb2, 0xa2, 0x9e, 0xc6, 0xc1, 0xf6, 0x12, 0x49, 0xff, 0x57, 0xcb, 0xa7, 0x93, 0xae, 0x5b, 0xf4, 0x48, 0x4d, 0x8c, 0x43, 0x03, 0x39, 0x8d, 0xa0, 0x13, 0xf5, 0x87, 0x53, 0x36, 0x11, 0xd8, 0xa0, 0x5f, 0x72, 0xa1, 0x0e, 0x40, 0xf6, 0xfb, 0x77, 0x77, 0x7e, 0x07, 0x28, 0xf5, 0x16, 0x5b, 0xa2, 0x45, 0x6f, 0xb7, 0x28, 0x7b, 0x26, 0x8a, 0x8c, 0x92, 0xb9, 0x58, 0x2f, 0xc0, 0xc4, 0x6f, 0x79, 0xdc, 0x96, 0x4c, 0x0e, 0xb1, 0x40, 0x3f, 0x51, 0x2e, 0xc4, 0xa6, 0x85, 0x69, 0x8c, 0xae, 0xcc, 0x50, 0x45, 0x79, 0x5b, 0xcb, 0x4b, 0x7f, 0xd1, 0xb3, 0xa7, 0x45, 0xa6, 0x89, 0xbe, 0x5f, 0x70, 0x0e, 0x3c, 0xab, 0x07, 0xcd, 0x75, 0x88, 0xde, 0xd8, 0x3c, 0x98, 0xe9, 0x37, 0x12, 0x7c, 0xc9, 0xd1, 0x07, 0xdb, 0x51, 0xa6, 0x74, 0x57, 0x18, 0x87, 0x7f, 0xc1, 0x84, 0xe8, 0xb4, 0x08, 0xf1, 0x85, 0x1e, 0xb5, 0x4c, 0x11, 0x95, 0x4d, 0x49, 0x95, 0xe5, 0xbf, 0x90, 0xc3, 0xef, 0x26, 0xc7, 0x42, 0xa7, 0x8b, 0xc1, 0x9e, 0xfb, 0xe2, 0x8c, 0x98, 0x54, 0x73, 0xd4, 0x94, 0x60, 0xc3, 0xb6, 0x17, 0x3f, 0x60, 0xaa, 0xe8, 0x2d, 0x56, 0x26, 0xa3, 0xd3, 0xae, 0xf8, 0x42, 0x8f, 0xaa, 0x1d, 0xe2, 0x53, 0x3a, 0x0c, 0x42, 0x26, 0xc1, 0xeb, 0x1b, 0xb2, 0xd1, 0x3b, 0xb6, 0xf4, 0x36, 0xdc, 0xa3, 0x5b, 0xe5, 0xfe, 0xa5, 0xbf, 0x2c, 0x2c, 0x19, 0x0e, 0xdf, 0x15, 0xca, 0xa2, 0x99, 0x12, 0x85, 0xec, 0x96, 0xfc, 0xa7, 0x5d, 0x88, 0xbc, 0x42, 0x37, 0x77, 0x07, 0x59, 0x15, 0x21, 0x99, 0xc8, 0x61, 0x4b, 0x4a, 0x00, 0x6c, 0xd7, 0xb2, 0xca, 0x6b, 0x72, 0x56, 0x21, 0xab, 0xf0, 0x9c, 0x8d, 0xa2, 0x8d, 0x96, 0x56, 0x64, 0x76, 0x97, 0x83, 0x5e, 0x95, 0xe6, 0xaa, 0x10, 0xa4, 0xb6, 0x0f, 0x4b, 0xd8, 0xb9, 0xf2, 0x4d, 0x11, 0xc4, 0x30, 0xf7, 0x33, 0xfe, 0x8d, 0xf1, 0x87, 0x29, 0xd6, 0xa2, 0xbe, 0xa0, 0x45, 0xdd, 0x28, 0xc2, 0x25, 0x33, 0x0e, 0xcb, 0xd4, 0x69, 0xb2, 0xbb, 0xfb, 0x62, 0xf0, 0x7b, 0x28, 0x5c, 0xcc, 0x5c, 0x2c, 0xa6, 0x96, 0x2e, 0x68, 0x91, 0x78, 0xf6, 0x56, 0x8b, 0x0a, 0x61, 0xe8, 0x2e, 0xec, 0xa0, 0x9c, 0x29, 0xfd, 0x50, 0x42, 0x16, 0xff, 0xff, 0xbd, 0x57, 0x82, 0x98, 0x00, 0x36, 0xbd, 0x33, 0x95, 0xb2, 0x08, 0x3b, 0x77, 0xc8, 0xf3, 0x6f, 0x19, 0xb8, 0x8a, 0x09, 0xbe, 0x10, 0xfa, 0x80, 0xdb, 0xb0, 0xa1, 0xed, 0x8e, 0x5b, 0x47, 0x31, 0x35, 0x52, 0x81, 0x16, 0xc1, 0x4c, 0x33, 0x2d, 0x10, 0x29, 0x04, 0x6c, 0xcd, 0x73, 0x18, 0x49, 0x25, 0x54, 0x7e, 0x99, 0x40, 0xcf, 0xa2, 0x7a, 0xc1, 0xb4, 0x9d, 0x0a, 0x71, 0x57, 0x88, 0xdc, 0x96, 0xa9, 0x11, 0x41, 0xd5, 0x4a, 0xb0, 0xb5, 0x3f, 0x7c, 0x82, 0x9f, 0x51, 0xa9, 0x12, 0x6f, 0x33, 0xfb, 0x8f, 0x12, 0x91, 0x15, 0xd1, 0x7b, 0xd3, 0x11, 0x79, 0xf9, 0xc1, 0x9d, 0x53, 0x80, 0x7a, 0x09, 0xfe, 0x46, 0xb7, 0xc9, 0x2c, 0x13, 0xc3, 0xca, 0x63, 0xc1, 0xb8, 0x0f, 0xd2, 0xa3, 0x10, 0x9d, 0x39, 0x4b, 0xd4, 0x99, 0xfe, 0x9a, 0xd3, 0xab, 0xb5, 0xcc, 0x6e, 0x98, 0x5e, 0x02, 0x2d, 0x70, 0xdd, 0xdf, 0x56, 0x55, 0x4c, 0xda, 0x0b, 0x6d, 0x40, 0xb1, 0x54, 0xa5, 0x8f, 0x9d, 0xf4, 0xde, 0xa4, 0xd0, 0x82, 0xff, 0x9d, 0xe6, 0x69, 0x81, 0xa3, 0xb4, 0xe9, 0x35, 0xc0, 0x85, 0x82, 0x62, 0x7b, 0xe7, 0xe9, 0x04, 0x32, 0x5e, 0xc1, 0xf8, 0x8e, 0x48, 0x40, 0x4e, 0x83, 0x6a, 0x57, 0x36, 0xf9, 0xfe, 0x19, 0x29, 0xf5, 0x0c, 0x7b, 0x27, 0x34, 0xbc, 0x28, 0x06, 0x2e, 0x48, 0xb9, 0xac, 0xc7, 0x8d, 0x8d, 0xb5, 0x6b, 0x52, 0x05, 0x99, 0xce, 0x53, 0x05, 0x1e, 0x53, 0xb6, 0x41, 0x8a, 0xdd, 0xa7, 0x67, 0xff, 0x4c, 0xdf, 0x68, 0x57, 0xf2, 0xab, 0x3e, 0xac, 0x23, 0x7f, 0x3e, 0x82, 0x08, 0xc9, 0x88, 0xe9, 0xf4, 0x2b, 0xcf, 0x38, 0x41, 0xa1, 0xd2, 0x6a, 0x99, 0xdd, 0x7b, 0x65, 0xa5, 0xe4, 0x3a, 0xac, 0xca, 0x4c, 0x6e, 0xdc, 0x37, 0x9b, 0x13, 0xc0, 0x7f, 0x03, 0xa7, 0xbf, 0x34, 0x5e, 0x29, 0x01, 0xb9, 0xd1, 0x97, 0x04, 0xcc, 0xe0, 0x8c, 0x7f, 0x0f, 0xe8, 0xb3, 0x30, 0x1a, 0x2f, 0x85, 0x4c, 0x13, 0xc3, 0x82, 0xff, 0xd4, 0x2f, 0x30, 0x65, 0x1c, 0x22, 0xb1, 0x98, 0xa4, 0xe7, 0xf1, 0x74, 0xb8, 0x63, 0xc1, 0x25, 0x51, 0x02, 0xdc, 0x84, 0x46, 0x5f, 0xe9, 0x63, 0x77, 0xec, 0xaa, 0x5f, 0x12, 0xb3, 0x83, 0xba, 0xfd, 0xc7, 0x44, 0xbf, 0x3a, 0x98, 0x85, 0x39, 0xf3, 0xb8, 0xcb, 0x75, 0x0c, 0x51, 0xfc, 0xbf, 0x3e, 0xc7, 0x45, 0x6b, 0xc1, 0xb9, 0x42, 0x2a, 0x4c, 0x70, 0xa7, 0x6c, 0x87, 0xdf, 0x29, 0xbb, 0xeb, 0x0a, 0x9a, 0x90, 0x01, 0xbe, 0x2a, 0x70, 0x44, 0x72, 0x5d, 0x61, 0x1a, 0xe0, 0x2d, 0xa8, 0x4f, 0x6d, 0x40, 0x64, 0x41, 0x34, 0x3a, 0x7e, 0x2c, 0x89, 0xd0, 0xc5, 0xd7, 0x62, 0xd0, 0x1f, 0xe1, 0xab, 0x95, 0x78, 0x24, 0x5d, 0xcf, 0x93, 0x05, 0x94, 0x1e, 0x3e, 0xe6, 0x1c, 0x84, 0xc7, 0xd3, 0x01, 0x77, 0xeb, 0xc6, 0xfc, 0xbf, 0x6e, 0x4d, 0x1d, 0x05, 0x02, 0x59, 0xc8, 0xb4, 0x25, 0x92, 0x1b, 0x4c, 0x6c, 0xae, 0x73, 0xaf, 0xa4, 0x3d, 0x85, 0xb7, 0xc6, 0x39, 0x75, 0x68, 0x8e, 0x22, 0x60, 0xa7, 0x6f, 0xa1, 0x6a, 0x0a, 0x21, 0x15, 0x1d, 0xaf, 0xf5, 0xe8, 0xb8, 0xa6, 0x4d, 0x49, 0x51, 0x9a, 0x70, 0x48, 0x5f, 0x64, 0x1b, 0x66, 0x8e, 0xd7, 0x7d, 0xbf, 0x47, 0xaa, 0xc1, 0x5d, 0x49, 0x21, 0xfa, 0x82, 0xd5, 0xbc, 0x0b, 0xaf, 0x5a, 0xef, 0xfb, 0x27, 0xfc, 0x11, 0xde, 0x1d, 0xd7, 0xcc, 0x6c, 0x97, 0x8d, 0xb2, 0xf2, 0x69, 0x21, 0x08, 0x5d, 0xd2, 0xa8, 0x52, 0x41, 0x1b, 0x33, 0xaa, 0xfa, 0x53, 0xb5, 0xc3, 0x84, 0xb2, 0x14, 0x02, 0xf7, 0x7c, 0x13, 0x99, 0x59, 0x27, 0xc5, 0xc5, 0x2c, 0x51, 0xc3, 0x38, 0x32, 0xab, 0x9e, 0x96, 0x69, 0x07, 0x1a, 0xec, 0x0a, 0x91, 0xf8, 0xa4, 0xb1, 0xa1, 0xf6, 0x1f, 0x70, 0x0c, 0x61, 0xd8, 0x8d, 0x73, 0x0e, 0xa4, 0xcd, 0x29, 0xa6, 0x39, 0x09, 0xba, 0xcf, 0xd6, 0xbb, 0x2c, 0x62, 0x2a, 0x7d, 0x6e, 0xb2, 0x3d, 0x54, 0x5d, 0x97, 0x90, 0x73, 0xc4, 0x94, 0x58, 0xab, 0x0d, 0x42, 0x53, 0x77, 0xbe, 0xcc, 0x9f, 0xdd, 0x23, 0xa9, 0xd3, 0xab, 0x74, 0x07, 0x2d, 0x28, 0xde, 0xfa, 0x7f, 0x9d, 0x85, 0x12, 0x0f, 0x9d, 0x99, 0xa0, 0x96, 0x75, 0xfc, 0x55, 0xae, 0x00, 0x73, 0xb4, 0x71, 0x56, 0x69, 0x27, 0x19, 0x74, 0x40, 0x6b, 0xd2, 0x6f, 0x3c, 0x0c, 0x9d, 0x3d, 0x75, 0x73, 0xdf, 0xde, 0x48, 0x6d, 0x5d, 0x22, 0xfc, 0x1f, 0x8b, 0x68, 0x07, 0x75, 0x39, 0x48, 0x7f, 0x1a, 0x3d, 0xc0, 0xec, 0xf6, 0x03, 0xad, 0x54, 0x9d, 0xbf, 0xe8, 0x2f, 0xf6, 0x76, 0x41, 0xb4, 0xc5, 0x3f, 0xe5, 0x75, 0xf6, 0x0e, 0xb2, 0xe4, 0x49, 0xef, 0x45, 0x5c, 0x03, 0xba, 0x22, 0xde, 0xee, 0xa2, 0x52, 0x01, 0xfa, 0xd0, 0xc4, 0x11, 0x05, 0xec, 0x7b, 0x9b, 0xc5, 0x9a, 0x0d, 0x2f, 0x78, 0xe8, 0x1f, 0x4e, 0x68, 0x28, 0xea, 0x97, 0xd4, 0xc8, 0xd1, 0x5d, 0x5f, 0x95, 0x68, 0x0e, 0x4e, 0x64, 0x50, 0x2e, 0x44, 0xb2, 0xb6, 0xed, 0xd1, 0xe2, 0x10, 0x72, 0xe4, 0xb5, 0xc6, 0x3f, 0xca, 0xd3, 0x65, 0xb5, 0xc6, 0x2a, 0xc0, 0x2e, 0x67, 0xad, 0x42, 0x74, 0x3c, 0x50, 0x02, 0x5c, 0x0d, 0xaf, 0x32, 0x40, 0xf9, 0x7f, 0xfb, 0xae, 0x5a, 0x39, 0xd0, 0xb9, 0x91, 0x68, 0xa4, 0x0e, 0x74, 0xbd, 0xf3, 0xdf, 0xa9, 0x7f, 0x53, 0xc1, 0x4b, 0x90, 0x93, 0x67, 0x4a, 0x92, 0x6b, 0x5b, 0xb0, 0xf3, 0x2f, 0x43, 0xa7, 0xa5, 0x06, 0xea, 0xaa, 0xf8, 0x4f, 0x90, 0x74, 0x45, 0xc0, 0xc1, 0x04, 0xfa, 0x33, 0xfe, 0x28, 0xda, 0x33, 0x9c, 0x50, 0x75, 0x61, 0xf3, 0x2c, 0x2e, 0x35, 0x04, 0xa5, 0xf9, 0xa8, 0x13, 0xdf, 0xc7, 0x74, 0x08, 0x84, 0x9d, 0x19, 0xbc, 0x07, 0xb9, 0x6e, 0xa8, 0x88, 0x9e, 0xe6, 0xf2, 0x1b, 0xb2, 0x09, 0x9c, 0x30, 0xde, 0x9f, 0x78, 0x15, 0xcc, 0x53, 0x2e, 0x0a, 0xf1, 0xb4, 0x82, 0x82, 0x59, 0x89, 0x34, 0x15, 0xca, 0x31, 0xad, 0xc0, 0x47, 0xba, 0x8e, 0xa2, 0xea, 0x74, 0x87, 0x12, 0xf4, 0x58, 0xb5, 0x77, 0xd8, 0x68, 0x7a, 0xcf, 0x0d, 0x9e, 0xf0, 0x40, 0x12, 0xad, 0xe5, 0xd6, 0x07, 0x11, 0xd7, 0x66, 0x81, 0xc7, 0x44, 0xf7, 0x93, 0x21, 0x60, 0xbd, 0x90, 0xd3, 0xc0, 0x2e, 0x1c, 0x2b, 0x4e, 0x41, 0x85, 0xe8, 0x43, 0x86, 0x4a, 0xa0, 0x3b, 0x86, 0xa5, 0xa5, 0xa6, 0x1e, 0xa4, 0xd2, 0x83, 0x6c, 0x2f, 0xe0, 0x82, 0x16, 0x4d, 0xd2, 0x43, 0x89, 0x8d, 0xf9, 0x16, 0x46, 0x18, 0xa6, 0xe2, 0x43, 0xf8, 0x8a, 0xd7, 0xa7, 0x0c, 0x63, 0xda, 0x80, 0xe8, 0xa0, 0xa3, 0x35, 0x78, 0x3a, 0x91, 0xd6, 0x46, 0xbb, 0x0e, 0x3b, 0xc3, 0x16, 0x21, 0x9d, 0xe5, 0xdf, 0xeb, 0x66, 0xd7, 0x83, 0x00, 0x53, 0x5a, 0xf7, 0xbf, 0xaa, 0xeb, 0x14, 0x12, 0xb9, 0xac, 0x86, 0xcd, 0x3a, 0xfb, 0x65, 0xf6, 0xf5, 0x85, 0x05, 0x92, 0xa3, 0x1e, 0x13, 0x44, 0x8b, 0x79, 0x47, 0xc6, 0x2c, 0x77, 0xbf, 0xa1, 0x19, 0x2e, 0xb3, 0xa0, 0xb1, 0x19, 0x27, 0x54, 0x64, 0x57, 0xd9, 0xe9, 0xec, 0x6a, 0x22, 0x67, 0x0e, 0x72, 0xdc, 0x3e, 0x4a, 0x7b, 0x32, 0x47, 0xf8, 0x2e, 0x70, 0x16, 0x07, 0xfb, 0x18, 0x23, 0x63, 0xd1, 0x52, 0x4b, 0xf7, 0xcc, 0x7c, 0x45, 0xde, 0x69, 0x1e, 0x90, 0xeb, 0xa8, 0x49, 0xe8, 0xa5, 0x44, 0x3f, 0x54, 0x68, 0x57, 0xef, 0x17, 0xf6, 0x24, 0x1b, 0x50, 0xac, 0xb6, 0x02, 0x1c, 0xc2, 0x29, 0x9c, 0xf9, 0x2b, 0x4c, 0xba, 0x8d, 0xd1, 0x71, 0x6c, 0x4c, 0xe9, 0x68, 0x70, 0x2f, 0x25, 0x3f, 0x01, 0x19, 0xb9, 0x7f, 0x24, 0xbd, 0x38, 0xb0, 0x02, 0xc6, 0xa7, 0x69, 0xcd, 0x8e, 0x00, 0xbd, 0x8f, 0x60, 0xe0, 0xa7, 0x42, 0x0c, 0x77, 0x0d, 0x42, 0xd7, 0x4d, 0xcd, 0xeb, 0x4a, 0x49, 0x17, 0x4f, 0x28, 0x7c, 0x54, 0x9e, 0x43, 0x1d, 0x54, 0xc6, 0x90, 0x82, 0x6f, 0xde, 0xba, 0xa0, 0x66, 0x22, 0x69, 0x78, 0x12, 0x7d, 0x4d, 0x17, 0xda, 0x1f, 0x9d, 0xd6, 0x21, 0x99, 0xa4, 0x44, 0xcb, 0x29, 0x9b, 0x4f, 0xd3, 0x80, 0xae, 0x36, 0xb4, 0xc4, 0xa2, 0x5c, 0xd8, 0x1e, 0x9b, 0x00, 0xcc, 0x4d, 0x4d, 0x4d, 0xb0, 0xf0, 0xb1, 0xb9, 0x5f, 0xe1, 0xd7, 0x2a, 0xa5, 0x21, 0x7c, 0x04, 0x84, 0xfa, 0x19, 0x62, 0x2f, 0x19, 0x54, 0x6a, 0x15, 0x5e, 0x7f, 0xa8, 0x12, 0x89, 0x93, 0x32, 0xaa, 0xba, 0xc8, 0x79, 0x29, 0x49, 0x69, 0x43, 0xe0, 0xfb, 0x21, 0xda, 0xf4, 0xe8, 0x55, 0xe8, 0xb4, 0xf9, 0xbe, 0x76, 0x44, 0x3a, 0x20, 0xcb, 0x90, 0xb9, 0x74, 0xac, 0x38, 0xe4, 0xab, 0x18, 0xaf, 0xe0, 0xca, 0x02, 0xad, 0x43, 0x50, 0x9c, 0x88, 0x54, 0x37, 0x1b, 0x27, 0x5f, 0x7d, 0x9f, 0x83, 0xd9, 0xce, 0xbd, 0xc2, 0x64, 0xaa, 0xf4, 0xfe, 0xc7, 0x09, 0xd1, 0x40, 0xcb, 0x35, 0x72, 0xb6, 0xd5, 0x78, 0x83, 0x2a, 0x88, 0x4c, 0x17, 0x08, 0x18, 0xcd, 0x08, 0x92, 0xc2, 0x76, 0xf9, 0x1c, 0x88, 0x56, 0x48, 0x72, 0x85, 0x17, 0x77, 0x09, 0x9b, 0x51, 0xf8, 0xb6, 0x6e, 0x3a, 0x83, 0x6a, 0xe4, 0xe7, 0xcc, 0xf0, 0xb8, 0x7a, 0x12, 0x13, 0xa6, 0xd5, 0x6d, 0x89, 0xfe, 0x41, 0x02, 0x58, 0x91, 0x53, 0xd2, 0x94, 0xae, 0xff, 0xb4, 0x23, 0xf6, 0x56, 0xf1, 0x37, 0xf0, 0x75, 0x6b, 0xe2, 0x3b, 0xb2, 0x44, 0x54, 0x07, 0x64, 0xad, 0x33, 0xb4, 0x7c, 0x3e, 0x9a, 0xaa, 0xf1, 0xc0, 0x01, 0xd8, 0xf9, 0x49, 0x13, 0x63, 0x8c, 0xc1, 0x14, 0x14, 0x5a, 0xa6, 0xd5, 0x51, 0x79, 0xe9, 0x1c, 0x84, 0xcb, 0x5b, 0x64, 0x83, 0x0f, 0x02, 0x2e, 0xee, 0x1a, 0x65, 0xca, 0x4b, 0x33, 0x3a, 0xbe, 0xeb, 0xab, 0xaf, 0xac, 0x4c, 0xac, 0x2d, 0x87, 0x68, 0x0c, 0x08, 0x58, 0xb0, 0xa3, 0x61, 0xe5, 0xd8, 0xad, 0xa9, 0x6c, 0x39, 0x6e, 0x87, 0xbe, 0xc5, 0xb1, 0x6b, 0x49, 0xa1, 0xc9, 0xa5, 0x6a, 0x39, 0x75, 0xa7, 0x3e, 0xfb, 0x4d, 0x63, 0x2b, 0x9c, 0xb5, 0x38, 0x03, 0x14, 0x18, 0x4d, 0x12, 0xd2, 0xbf, 0x27, 0xeb, 0x04, 0xe4, 0xd4, 0x18, 0x59, 0x08, 0x4e, 0xe6, 0x49, 0x73, 0xf1, 0x43, 0x0e, 0x73, 0x71, 0xf7, 0xec, 0x1b, 0x27, 0x8a, 0x88, 0xed, 0xaf, 0x9c, 0x1c, 0x90, 0x9e, 0x48, 0xc5, 0x7b, 0x02, 0xc2, 0xf5, 0x38, 0x9f, 0x7f, 0x50, 0x5a, 0x25, 0x93, 0xf1, 0x90, 0x83, 0xf7, 0xab, 0xda, 0x90, 0x29, 0xca, 0x6f, 0xfe, 0xe6, 0x33, 0xb3, 0x81, 0xb9, 0x64, 0xa7, 0x58, 0x92, 0x5f, 0xb1, 0x6d, 0xb6, 0x9d, 0x33, 0x3f, 0xab, 0x4b, 0xf4, 0xc7, 0xca, 0x34, 0x1f, 0xbc, 0x24, 0x3c, 0x40, 0x08, 0xa1, 0xf2, 0x36, 0x36, 0x78, 0xcb, 0x42, 0xf6, 0xb0, 0x59, 0x5b, 0x1f, 0x38, 0xf7, 0xa8, 0x45, 0xa9, 0xf0, 0x8b, 0xce, 0xb8, 0xfc, 0x62, 0x00, 0xbe, 0x74, 0x0c, 0x50, 0x77, 0xe3, 0xfe, 0xe1, 0x87, 0x06, 0xe0, 0x83, 0x13, 0x17, 0x3f, 0x41, 0x79, 0x28, 0xb0, 0x93, 0x96, 0xa3, 0x91, 0x17, 0x0f, 0x2c, 0x3b, 0x8e, 0xa1, 0x60, 0x5b, 0x84, 0xa6, 0x8a, 0xa0, 0xea, 0x83, 0xa1, 0x25, 0x57, 0x5a, 0x18, 0xcc, 0x63, 0xdc, 0x84, 0x56, 0x27, 0xb0, 0x1c, 0x09, 0x1b, 0xf6, 0x8f, 0xe9, 0x2d, 0x06, 0x98, 0x84, 0xaf, 0xef, 0xfd, 0x43, 0x4b, 0xb8, 0xf6, 0x96, 0x15, 0xbd, 0x1e, 0x27, 0xe9, 0x42, 0xa0, 0x25, 0x0e, 0x8c, 0x40, 0xad, 0x27, 0x2a, 0xfa, 0x6d, 0x83, 0x66, 0x34, 0x3d, 0x7d, 0x3b, 0xe0, 0x8e, 0xd3, 0xc0, 0x64, 0xa2, 0x7e, 0xab, 0x45, 0xd9, 0xf2, 0xd7, 0x79, 0xa1, 0x0b, 0x3e, 0xf7, 0x4a, 0x1f, 0xa5, 0x0c, 0x64, 0xcc, 0x20, 0x7b, 0x91, 0x70, 0x1a, 0x6d, 0x47, 0xbb, 0xdb, 0x26, 0xc0, 0x26, 0x78, 0x1e, 0x82, 0xf4, 0xe6, 0x1e, 0xcc, 0x77, 0x76, 0x25, 0x2a, 0x69, 0x45, 0xd3, 0x10, 0x11, 0xee, 0xb3, 0xba, 0x17, 0x97, 0x99, 0x19, 0xf8, 0x1b, 0x12, 0x8a, 0xe8, 0x38, 0x92, 0x61, 0x44, 0xf3, 0x25, 0xa5, 0x2c, 0x83, 0x18, 0xb2, 0x6c, 0xc3, 0x2e, 0xff, 0x5a, 0x84, 0xd7, 0x5e, 0x89, 0x5a, 0x35, 0xdb, 0x27, 0x46, 0xf4, 0x1c, 0xfe, 0x5d, 0x1e, 0x52, 0x86, 0xef, 0xee, 0x55, 0x10, 0x5b, 0x01, 0xd2, 0xae, 0xe4, 0xe6, 0x7b, 0xed, 0x3f, 0x39, 0xd6, 0x2f, 0x44, 0xad, 0xb9, 0x02, 0x89, 0xb0, 0xe2, 0x35, 0xc9, 0xcf, 0x6b, 0x6d, 0x54, 0x18, 0xdd, 0xa0, 0x08, 0x35, 0xf6, 0x39, 0x87, 0x7a, 0xc9, 0xe1, 0x9d, 0x86, 0xda, 0x50, 0x18, 0x0e, 0xec, 0x40, 0x3f, 0x90, 0xef, 0x56, 0xa5, 0x19, 0x74, 0x53, 0x10, 0x3e, 0x40, 0x37, 0x14, 0x5a, 0x0d, 0x82, 0xdf, 0x2a, 0x11, 0x19, 0x95, 0x53, 0x4d, 0xdc, 0x6b, 0x8b, 0xdf, 0xef, 0xfc, 0x6b, 0xee, 0x78, 0x6e, 0x9e, 0x70, 0x3b, 0x4b, 0x8d, 0x5d, 0x7d, 0x19, 0x95, 0x6b, 0x7c, 0x09, 0xaa, 0xda, 0x53, 0x42, 0x5a, 0xd6, 0x0d, 0xf3, 0x89, 0x2e, 0x20, 0xf3, 0x84, 0x70, 0x76, 0x9d, 0x82, 0x90, 0x2a, 0x88, 0x78, 0x2b, 0x59, 0x93, 0x47, 0x5e, 0x1a, 0xd7, 0x32, 0x23, 0xf3, 0x11, 0x19, 0x89, 0xf9, 0x21, 0x33, 0xb2, 0xe2, 0x2f, 0xcf, 0x03, 0xd0, 0x32, 0x53, 0xbe, 0xbe, 0xa0, 0x48, 0xbd, 0x8a, 0xb6, 0x63, 0x39, 0xcc, 0xc7, 0x61, 0xdc, 0xac, 0xc2, 0x05, 0xe6, 0x12, 0x91, 0x6a, 0x0d, 0x4b, 0x22, 0x30, 0x38, 0xd0, 0x51, 0x20, 0x7d, 0x71, 0xa9, 0xfc, 0xd6, 0xfd, 0x78, 0x13, 0x5d, 0xfe, 0x5f, 0xf0, 0xc1, 0xfa, 0x14, 0x99, 0xec, 0x94, 0x7f, 0xc7, 0xd1, 0x1e, 0x6f, 0x7e, 0x0b, 0x0f, 0x31, 0x09, 0x5a, 0x58, 0x93, 0x0c, 0x8b, 0x33, 0xa2, 0x77, 0x32, 0x77, 0xd0, 0x44, 0xdf, 0xe4, 0x9e, 0x76, 0x0b, 0xc6, 0x34, 0xec, 0xf8, 0x04, 0xce, 0x41, 0x34, 0xaf, 0x89, 0x13, 0x49, 0xa9, 0xbc, 0xc1, 0x53, 0xd9, 0x77, 0xca, 0x81, 0xc7, 0xef, 0x65, 0x64, 0x41, 0x8b, 0x2e, 0x28, 0x12, 0xe1, 0x74, 0x33, 0x2d, 0x2f, 0x0c, 0x9e, 0x78, 0xf0, 0x1c, 0x38, 0x97, 0xab, 0x57, 0xfb, 0x80, 0xb8, 0x50, 0xed, 0x3a, 0x60, 0xd0, 0xb3, 0x9f, 0x46, 0x12, 0x25, 0x34, 0x56, 0xd3, 0x31, 0xed, 0x38, 0x46, 0x21, 0x7e, 0xcf, 0xe0, 0x75, 0xfe, 0xfc, 0x9d, 0xc8, 0xfe, 0xc3, 0xe0, 0xf6, 0x22, 0xb0, 0xf5, 0x11, 0x9c, 0x98, 0xac, 0xc0, 0x31, 0xf5, 0x2f, 0x70, 0xbe, 0x8e, 0xed, 0xfe, 0x23, 0xf5, 0x86, 0x07, 0xb3, 0xf8, 0x3d, 0x09, 0xa3, 0xc6, 0x34, 0xa5, 0x47, 0x8d, 0xf4, 0xeb, 0x66, 0x5f, 0x0e, 0xc5, 0x89, 0xba, 0x63, 0x2d, 0x64, 0xcc, 0x42, 0x8a, 0x03, 0xb9, 0xf9, 0x16, 0xe3, 0x91, 0x89, 0x0c, 0xdf, 0x20, 0x39, 0xcb, 0x61, 0x3f, 0xbd, 0x65, 0xbc, 0x5d, 0xef, 0xb8, 0x13, 0xa1, 0x02, 0xb3, 0x32, 0xde, 0x6a, 0x04, 0xb0, 0xfb, 0x7a, 0x56, 0x49, 0xf7, 0xcf, 0x2d, 0xf9, 0xb9, 0xd1, 0x6f, 0xad, 0x7a, 0xa8, 0x77, 0x65, 0x3b, 0xe0, 0xa1, 0xb7, 0x08, 0xe3, 0x0d, 0xff, 0x36, 0x4d, 0x01, 0x05, 0x89, 0xef, 0xb0, 0x0a, 0x23, 0xd6, 0xa9, 0x01, 0x28, 0x5e, 0xc0, 0x5b, 0x91, 0x35, 0xed, 0x30, 0xa8, 0xcd, 0xe1, 0x66, 0x96, 0x52, 0x01, 0x24, 0xc3, 0x32, 0x20, 0xba, 0x46, 0x72, 0xdd, 0x5c, 0xf5, 0x89, 0xac, 0x3c, 0x45, 0x40, 0x71, 0xb9, 0xbc, 0x11, 0x5a, 0x9e, 0x3a, 0x1d, 0xf1, 0xcf, 0x4d, 0xb0, 0xc8, 0xd7, 0x97, 0xd4, 0x5d, 0x8e, 0xb1, 0x13, 0x73, 0x18, 0x9a, 0xe9, 0x73, 0x16, 0xae, 0x62, 0x19, 0x82, 0xf8, 0x6d, 0x66, 0x42, 0x66, 0x4a, 0x7f, 0x04, 0x1d, 0x6e, 0x6e, 0x86, 0x61, 0x4c, 0xbe, 0x4f, 0x4d, 0xae, 0xc7, 0xc9, 0x9a, 0xb6, 0x0f, 0x78, 0x9a, 0x85, 0xf1, 0x05, 0x4b, 0xce, 0x66, 0xea, 0xe0, 0x0b, 0x0d, 0xf7, 0x08, 0x64, 0x2f, 0x12, 0xaa, 0xd2, 0x4c, 0x8e, 0x61, 0x51, 0x0f, 0xe5, 0xd4, 0x91, 0xcd, 0x58, 0x8d, 0x4a, 0xb4, 0x62, 0xca, 0xb6, 0x05, 0xf8, 0x4c, 0x87, 0x1b, 0x4d, 0xa8, 0x57, 0x42, 0x66, 0xea, 0xf7, 0xf0, 0x1b, 0x06, 0x6d, 0x10, 0xca, 0x88, 0xab, 0x1d, 0xad, 0x91, 0x6d, 0xbb, 0xa8, 0x6f, 0x07, 0xb6, 0x84, 0x29, 0xe2, 0xd6, 0xd2, 0x8a, 0x93, 0x5d, 0xbd, 0x16, 0xdd, 0x15, 0xfb, 0x5a, 0x03, 0x94, 0xdd, 0xaa, 0x52, 0x7e, 0xc6, 0x55, 0x87, 0xb8, 0xc3, 0xef, 0xcd, 0x90, 0xb3, 0x49, 0x95, 0xc0, 0x5f, 0xfb, 0x0f, 0x7e, 0x17, 0xcb, 0x7e, 0x4f, 0xaf, 0xfe, 0xee, 0x8d, 0xe1, 0x31, 0x63, 0x1d, 0xe6, 0xb6, 0x92, 0x03, 0xa9, 0x96, 0x5b, 0xa0, 0x36, 0x7d, 0x54, 0xf4, 0x89, 0xd2, 0x56, 0x63, 0xe9, 0x89, 0x73, 0x6b, 0xad, 0x25, 0x53, 0x75, 0xb7, 0x58, 0xf8, 0x1c, 0xf3, 0x4e, 0xda, 0x93, 0xce, 0xf3, 0x67, 0x45, 0x0e, 0x2a, 0x9b, 0x03, 0x25, 0x44, 0x0c, 0xcf, 0xcc, 0x37, 0x42, 0xd8, 0x78, 0xc9, 0x3c, 0xca, 0xd5, 0x63, 0x52, 0x9d, 0xc0, 0x5b, 0x3a, 0x3a, 0xc2, 0x1a, 0x0a, 0x33, 0xb5, 0x07, 0x04, 0x3b, 0xa3, 0xb9, 0x70, 0xac, 0xd4, 0xf7, 0x1d, 0xfd, 0x00, 0x93, 0x23, 0xc9, 0x49, 0xe1, 0xc1, 0x61, 0xe5, 0x95, 0x2a, 0x01, 0x6f, 0x1a, 0x87, 0xad, 0x02, 0xdd, 0x0c, 0xbc, 0xcb, 0x56, 0x9e, 0x58, 0x18, 0x49, 0x4f, 0x07, 0x48, 0x0c, 0x53, 0x00, 0xfa, 0x95, 0xc9, 0xf8, 0x37, 0x44, 0x64, 0x9c, 0xd1, 0x10, 0x7a, 0x90, 0xfd, 0x11, 0x18, 0x45, 0xcd, 0xe5, 0x80, 0x21, 0x7e, 0x8c, 0xca, 0x04, 0x15, 0x3b, 0x52, 0x12, 0xaf, 0x3c, 0x4b, 0x0a, 0x6f, 0xad, 0xbd, 0x6d, 0xde, 0x8e, 0xb3, 0xd7, 0x06, 0x11, 0xcd, 0x9a, 0xde, 0x8c, 0x10, 0xae, 0x3c, 0x96, 0xb6, 0x62, 0x5a, 0x80, 0xf4, 0xb2, 0xc7, 0x79, 0x50, 0x0b, 0x26, 0xad, 0x40, 0x63, 0x17, 0x28, 0x50, 0x06, 0xef, 0x93, 0x7d, 0x81, 0x65, 0x03, 0x47, 0xca, 0x85, 0xce, 0x9f, 0x7e, 0x09, 0xd0, 0xc4, 0xca, 0xc7, 0x78, 0x9f, 0x6b, 0xb6, 0xc0, 0xd0, 0x30, 0xd5, 0x13, 0x9d, 0xb4, 0x60, 0x18, 0xdd, 0x18, 0xab, 0xe1, 0x0e, 0x43, 0x62, 0xb8, 0x04, 0xb5, 0x6c, 0xba, 0xe2, 0x33, 0xf6, 0x05, 0x5c, 0xee, 0xd2, 0xd2, 0x72, 0x43, 0xb8, 0x81, 0x16, 0xc6, 0x5e, 0xe0, 0xa9, 0xb3, 0xc4, 0xde, 0x26, 0xaf, 0x16, 0x90, 0xef, 0x9a, 0x4c, 0xb0, 0x89, 0xa2, 0x08, 0x17, 0xa9, 0xa8, 0xc8, 0xb8, 0x55, 0x19, 0x51, 0x85, 0x8f, 0x34, 0xfd, 0x59, 0xd5, 0xb9, 0x98, 0xab, 0xcd, 0x58, 0x71, 0x7e, 0x3c, 0x9e, 0x28, 0xb7, 0xb1, 0x6b, 0x50, 0x37, 0x17, 0xb5, 0x84, 0x52, 0xd6, 0x83, 0x80, 0x26, 0x59, 0xbd, 0x81, 0x9a, 0xe5, 0x64, 0x1b, 0x3f, 0x11, 0xf4, 0x79, 0x08, 0xfe, 0x3c, 0xc4, 0x8f, 0xc9, 0xfc, 0x37, 0x6b, 0x73, 0xc4, 0xdd, 0xf6, 0x80, 0x45, 0xbd, 0x85, 0x75, 0x74, 0x17, 0xbd, 0x91, 0xe8, 0xf3, 0x7e, 0x44, 0xb3, 0xf0, 0x1b, 0x66, 0x39, 0x87, 0xe8, 0x52, 0xb8, 0x28, 0x02, 0x7e, 0x71, 0xa8, 0x05, 0xe6, 0x22, 0xd6, 0xea, 0xc3, 0xfe, 0x29, 0x9d, 0x06, 0xfc, 0xfa, 0x78, 0x32, 0xc5, 0xff, 0x2b, 0x2c, 0x9e, 0xb1, 0x14, 0xe5, 0x7c, 0x25, 0x29, 0x33, 0x8f, 0xab, 0x42, 0x91, 0xc1, 0xd1, 0xcf, 0x7e, 0xe7, 0x0a, 0xcb, 0xc0, 0xce, 0x96, 0x29, 0x91, 0x30, 0xe0, 0x03, 0x80, 0xdf, 0x34, 0xd6, 0xd0, 0x0d, 0xcb, 0xd0, 0x60, 0x26, 0x41, 0x56, 0x8d, 0x57, 0x61, 0xb2, 0x11, 0xe4, 0xa4, 0xd9, 0xcb, 0x45, 0x8a, 0xc0, 0x83, 0x29, 0xb9, 0x5d, 0xf4, 0xec, 0x6d, 0x94, 0xf7, 0x83, 0x95, 0xb0, 0x2c, 0x9f, 0x22, 0x83, 0xac, 0xdc, 0xb0, 0x97, 0xee, 0x1b, 0x52, 0x27, 0x47, 0x66, 0x06, 0xeb, 0x5c, 0x4c, 0xd1, 0x8b, 0x4c, 0x77, 0x7f, 0x99, 0x53, 0x3e, 0xed, 0x5c, 0x51, 0xf4, 0x66, 0x11, 0x6a, 0x2f, 0x3f, 0xb0, 0xb1, 0x75, 0x13, 0xc0, 0x4c, 0xbb, 0x9b, 0xd5, 0x19, 0xe0, 0x5f, 0x8c, 0x41, 0x63, 0x43, 0x59, 0x3f, 0xe5, 0xc4, 0x5e, 0x17, 0x96, 0x68, 0x6c, 0x6b, 0x22, 0x2a, 0x32, 0x3c, 0xc4, 0xe9, 0xc0, 0x60, 0x72, 0xc0, 0x92, 0x2b, 0x75, 0x6d, 0x94, 0xb0, 0x00, 0x98, 0x90, 0xe7, 0x9a, 0xcb, 0x8f, 0x04, 0x8b, 0x4a, 0xef, 0xa8, 0x11, 0x73, 0x2d, 0xae, 0xfa, 0xfb, 0xcd, 0x17, 0x96, 0xe4, 0xf9, 0x4b, 0x9f, 0x05, 0xfc, 0x79, 0x73, 0x62, 0x5b, 0x18, 0x4e, 0x7f, 0x70, 0x2b, 0x47, 0x96, 0x37, 0xa4, 0x3f, 0x39, 0x0e, 0xdb, 0x1c, 0x46, 0xf1, 0xc1, 0x5b, 0x16, 0x13, 0xb7, 0x89, 0xbf, 0x5c, 0xad, 0xe0, 0x8f, 0xf9, 0xa4, 0x28, 0xd4, 0xc7, 0x09, 0x49, 0xf2, 0x9b, 0xe8, 0xd3, 0x93, 0x47, 0x29, 0xf7, 0x35, 0x65, 0x1e, 0x0c, 0x28, 0x50, 0x69, 0xa1, 0x60, 0xd3, 0xcf, 0x86, 0x7d, 0xb4, 0x49, 0x32, 0x17, 0x3e, 0x90, 0x7e, 0x82, 0xcd, 0x7e, 0x44, 0x7d, 0xd3, 0x43, 0x74, 0x4b, 0xd5, 0xc9, 0x88, 0x51, 0x1b, 0xe8, 0xfa, 0xb8, 0xea, 0x83, 0xa1, 0x95, 0x0b, 0xf3, 0x07, 0x78, 0xf3, 0x20, 0xad, 0x36, 0x7a, 0xe5, 0xff, 0x97, 0x81, 0x53, 0xfe, 0xc9, 0x3a, 0x85, 0xf0, 0x54, 0xa8, 0x39, 0xf5, 0x90, 0x16, 0xf8, 0xf2, 0x3d, 0xd2, 0xfe, 0x8e, 0x31, 0xfd, 0xa9, 0x50, 0xb2, 0x6f, 0xe9, 0xfa, 0x41, 0x09, 0x3a, 0x93, 0x71, 0x3c, 0x12, 0xfd, 0x6c, 0x1e, 0xd0, 0x78, 0xa6, 0x9e, 0x22, 0xa1, 0x3a, 0x13, 0x30, 0xfd, 0xea, 0x16, 0xe7, 0x26, 0xfc, 0xfd, 0x1f, 0x30, 0xf4, 0x67, 0xa7, 0x60, 0x6d, 0x90, 0x34, 0x9c, 0x80, 0x20, 0xff, 0xbd, 0xe3, 0x4a, 0x4d, 0xb9, 0xc5, 0x85, 0xda, 0x30, 0xff, 0x41, 0x35, 0xbb, 0x5c, 0x3e, 0x7d, 0x49, 0x28, 0x8f, 0x29, 0x47, 0x62, 0x39, 0xe7, 0x0a, 0xa3, 0x17, 0x6d, 0xbf, 0xb2, 0x52, 0x5b, 0x7a, 0x48, 0x42, 0x3c, 0xef, 0xa6, 0x8a, 0x09, 0xaf, 0xc2, 0x5a, 0x5a, 0x95, 0x6e, 0x1c, 0xcf, 0x7d, 0x8c, 0xb8, 0xc5, 0x7b, 0xe7, 0x2e, 0xbf, 0xc1, 0x2b, 0xf6, 0x20, 0x8c, 0x89, 0xeb, 0x60, 0x35, 0x63, 0xdd, 0xb3, 0xfe, 0x80, 0xd0, 0xf1, 0x20, 0xce, 0x2f, 0x5f, 0x27, 0xb0, 0x54, 0x6f, 0x7d, 0x48, 0x9d, 0x07, 0x47, 0xca, 0xd4, 0x6c, 0x17, 0xcb, 0xd7, 0x07, 0x82, 0x4a, 0x29, 0xc2, 0x12, 0x50, 0x33, 0xf9, 0x89, 0x7a, 0x51, 0x8d, 0x79, 0xa0, 0x55, 0xbd, 0xb8, 0xec, 0xf4, 0x91, 0xc0, 0xa1, 0x35, 0xe8, 0x2a, 0x35, 0x29, 0xe0, 0xb5, 0x17, 0xc5, 0x06, 0x3a, 0x78, 0x93, 0x63, 0x4e, 0xbd, 0x37, 0x6f, 0x00, 0xd5, 0x60, 0xe3, 0x3e, 0x29, 0xb7, 0x0b, 0xb1, 0xfb, 0xdf, 0x2c, 0x44, 0xba, 0xdb, 0xe3, 0x32, 0x64, 0xc2, 0x7a, 0x6a, 0x46, 0xc5, 0xfb, 0x7b, 0xba, 0x67, 0x98, 0x40, 0x44, 0xf3, 0xce, 0x9a, 0x4c, 0xff, 0x0c, 0x78, 0x89, 0x4c, 0x11, 0x06, 0x78, 0x25, 0x7f, 0x3b, 0x7b, 0x60, 0xc2, 0xa4, 0x25, 0x4e, 0x51, 0x8c, 0xf4, 0xd1, 0x6a, 0xf3, 0x93, 0x1a, 0x1c, 0x05, 0xfc, 0x94, 0x1c, 0x0d, 0x45, 0xfd, 0xb9, 0x1c, 0x70, 0x09, 0xa7, 0x3b, 0x2b, 0xdc, 0xc6, 0x6c, 0xa3, 0x77, 0x8c, 0x25, 0x21, 0xfd, 0x7d, 0xa9, 0x41, 0x50, 0x3c, 0x90, 0x80, 0x5a, 0x2f, 0x1a, 0x50, 0xf0, 0xcc, 0xb1, 0x23, 0x4e, 0xf6, 0x5d, 0x61, 0xac, 0x2b, 0xdc, 0xb7, 0x9e, 0x33, 0xa2, 0x24, 0x5d, 0x0c, 0xd5, 0xcd, 0x45, 0x58, 0xb5, 0x85, 0xa4, 0x5e, 0xa3, 0x09, 0xe2, 0x09, 0x8c, 0x04, 0x1a, 0x53, 0x5f, 0xe7, 0x42, 0x7f, 0xbb, 0xc1, 0xf8, 0x8d, 0xb5, 0x8a, 0xc7, 0xda, 0x13, 0x23, 0xbd, 0x50, 0xd3, 0xa8, 0x44, 0xa0, 0x48, 0x36, 0x85, 0x22, 0x63, 0xd2, 0x47, 0x28, 0xa4, 0xe2, 0x30, 0x3c, 0x50, 0x35, 0xc8, 0xca, 0x1a, 0xef, 0x44, 0xb9, 0xef, 0x9c, 0x36, 0x17, 0x80, 0x53, 0xab, 0x0e, 0xfa, 0x9e, 0x9b, 0x13, 0xfe, 0x97, 0x13, 0x73, 0x4e, 0x03, 0xc6, 0xbe, 0x0a, 0x35, 0x46, 0xf3, 0xfc, 0xc6, 0x91, 0x8b, 0x25, 0x1b, 0x95, 0xee, 0xae, 0xa5, 0x59, 0xbf, 0x4a, 0x23, 0xfc, 0xa4, 0x1f, 0x19, 0x24, 0xc8, 0x41, 0xe6, 0x3d, 0x43, 0xde, 0xfd, 0x73, 0x2d, 0x23, 0x2f, 0xf9, 0x98, 0x45, 0x91, 0x9c, 0xfc, 0xb9, 0xb9, 0x49, 0x61, 0x2d, 0xd3, 0x8f, 0x15, 0x21, 0x48, 0x89, 0x87, 0x51, 0x72, 0xe2, 0xc5, 0x3a, 0x9c, 0x51, 0xd2, 0xb7, 0x41, 0x4e, 0xed, 0xc1, 0xc2, 0x00, 0x8a, 0xb1, 0x01, 0x1b, 0x69, 0xce, 0x75, 0xba, 0x7c, 0x79, 0xd2, 0xa0, 0xc1, 0xe5, 0xe9, 0xe1, 0xbc, 0xd5, 0x29, 0xbc, 0x0d, 0x3d, 0x39, 0xb3, 0x85, 0x7d, 0xab, 0x93, 0x41, 0xb8, 0xc1, 0xa2, 0x40, 0x65, 0x10, 0x88, 0x5f, 0x8b, 0x99, 0xf9, 0x90, 0x2c, 0x87, 0x82, 0xd3, 0xff, 0xcd, 0x44, 0x99, 0x9f, 0xe1, 0x2c, 0x8e, 0xe3, 0x7e, 0x07, 0xa8, 0x69, 0xd2, 0x73, 0x78, 0x3f, 0xc7, 0x4e, 0x09, 0x15, 0x03, 0xb6, 0x45, 0x70, 0xc1, 0xf0, 0x1c, 0x62, 0x1c, 0x60, 0xef, 0xee, 0x67, 0xe7, 0x11, 0xe8, 0x5e, 0x74, 0x05, 0xf9, 0xf0, 0x70, 0x6e, 0x69, 0xdd, 0x35, 0x58, 0x7c, 0x7e, 0xea, 0xcb, 0xc8, 0x06, 0x74, 0x3a, 0xaa, 0x88, 0xe1, 0x03, 0xc6, 0xf1, 0xae, 0xd7, 0xfc, 0xdc, 0x50, 0x57, 0x25, 0x0a, 0x25, 0x8d, 0x10, 0x2c, 0x56, 0x1f, 0xdf, 0x67, 0xc7, 0x15, 0xc7, 0x43, 0x0f, 0xeb, 0xf9, 0x93, 0x10, 0x31, 0xf5, 0xa7, 0x56, 0x10, 0x3f, 0x14, 0xbd, 0xcd, 0x1d, 0x7c, 0xb8, 0xf5, 0x8e, 0xa5, 0x29, 0xbf, 0xb4, 0x34, 0x55, 0x7b, 0x00, 0xc4, 0x62, 0x32, 0x63, 0xce, 0x39, 0xbd, 0x33, 0xb9, 0x39, 0x33, 0x0b, 0xe3, 0x88, 0xb2, 0x6c, 0x68, 0xb5, 0x74, 0x34, 0x0e, 0x6e, 0x31, 0xb3, 0x92, 0xa0, 0x45, 0x4f, 0x3d, 0x58, 0xe1, 0x3c, 0x81, 0x4f, 0x7f, 0xc5, 0x31, 0xca, 0xa9, 0x95, 0x44, 0x3e, 0xb2, 0x25, 0x07, 0x84, 0xc3, 0x92, 0x7b, 0x7f, 0x24, 0x09, 0xe8, 0xdf, 0xbf, 0x21, 0xb4, 0xb8, 0x00, 0x60, 0xf6, 0xc2, 0x18, 0x97, 0x2b, 0x6c, 0x33, 0x18, 0x45, 0xc4, 0x3c, 0xd9, 0xec, 0xdf, 0xed, 0xa5, 0xb9, 0xac, 0xfc, 0x2a, 0xdc, 0x3b, 0x2c, 0x74, 0x25, 0xa3, 0x7a, 0x9d, 0xd3, 0xa5, 0x7a, 0xb3, 0x60, 0x3c, 0x0e, 0x71, 0xc0, 0xd1, 0xbf, 0x3e, 0x07, 0xe1, 0x90, 0x99, 0x42, 0x01, 0x47, 0x35, 0x25, 0xcc, 0x1d, 0xf7, 0x30, 0x48, 0x5b, 0x42, 0x1c, 0xce, 0xb3, 0xb9, 0x21, 0x97, 0x9e, 0x63, 0x45, 0x25, 0xdf, 0xd2, 0x5f, 0x95, 0x1c, 0x15, 0x98, 0x14, 0x7e, 0xda, 0x68, 0x88, 0xaf, 0xd6, 0xd4, 0x12, 0xa9, 0x52, 0xfc, 0x60, 0x28, 0x8e, 0xc5, 0x83, 0xb5, 0x85, 0x45, 0x55, 0x90, 0x02, 0xd7, 0xe1, 0x7d, 0xa8, 0xd8, 0x8f, 0xa3, 0x3c, 0xec, 0xfb, 0x22, 0xa0, 0xf4, 0x6c, 0x98, 0x91, 0xa9, 0x6d, 0xb4, 0xde, 0x7a, 0xf6, 0x8c, 0xfe, 0x5d, 0xed, 0x28, 0x8a, 0xf1, 0x36, 0x72, 0x02, 0xba, 0x91, 0x82, 0xd5, 0x47, 0x37, 0xd3, 0xb2, 0x7c, 0x8f, 0x9e, 0x67, 0x26, 0x7a, 0x24, 0xa7, 0xcb, 0x8f, 0xfa, 0x94, 0x65, 0xb4, 0x53, 0x9d, 0xae, 0x51, 0x4f, 0x1e, 0x8f, 0x92, 0x95, 0x82, 0x35, 0x4f, 0x29, 0xea, 0x77, 0xe4, 0xfa, 0x13, 0xdd, 0x1f, 0xe3, 0xc4, 0x4a, 0x05, 0xf1, 0x53, 0xcd, 0x73, 0x5c, 0x2d, 0x90, 0x85, 0xff, 0xe9, 0xcd, 0xa5, 0x9d, 0xf5, 0x48, 0x26, 0x27, 0x10, 0x0f, 0x8a, 0x36, 0x60, 0x18, 0x65, 0xa6, 0xb1, 0xcc, 0x3c, 0x7f, 0x23, 0x6e, 0xde, 0x9d, 0xf0, 0x5f, 0x09, 0x93, 0x22, 0x24, 0x7c, 0xbf, 0x08, 0xcc, 0xf5, 0x6a, 0xd7, 0x23, 0xf4, 0xee, 0x85, 0x8e, 0x36, 0xb5, 0x2c, 0x79, 0xd3, 0xda, 0xb2, 0x76, 0x13, 0x7d, 0x2e, 0x94, 0xff, 0x03, 0x3c, 0x54, 0x66, 0x9d, 0x1b, 0x6f, 0x5d, 0x0c, 0xf0, 0x34, 0xe2, 0xe3, 0x0c, 0xb2, 0x0a, 0xdd, 0x63, 0xdd, 0xcb, 0x2a, 0x9b, 0xb1, 0x5f, 0xec, 0xcc, 0x48, 0x4e, 0xdf, 0x1a, 0x8e, 0x73, 0x76, 0x6e, 0x8a, 0x7a, 0x08, 0x90, 0xab, 0xed, 0x7d, 0x0b, 0x76, 0x64, 0xba, 0x92, 0x25, 0xd9, 0xb6, 0xa9, 0x11, 0x29, 0x82, 0xa0, 0x3c, 0xe3, 0x12, 0xd8, 0x5d, 0x74, 0x50, 0x91, 0xe7, 0xc3, 0xe1, 0xc5, 0x31, 0x8c, 0x47, 0x04, 0x11, 0x70, 0x30, 0x08, 0x97, 0x67, 0xf4, 0xac, 0x51, 0x22, 0xe6, 0x65, 0x21, 0x05, 0x1d, 0xf0, 0xa1, 0xc4, 0x56, 0x9a, 0xff, 0xb9, 0xd5, 0xd7, 0xb9, 0x98, 0xaa, 0xec, 0x5d, 0x89, 0xd5, 0x3f, 0x43, 0x62, 0xcb, 0x7c, 0xe0, 0x9e, 0xc5, 0xf5, 0x78, 0x8a, 0x63, 0x57, 0xb5, 0xc7, 0x83, 0x8b, 0x08, 0x0e, 0x5c, 0xf8, 0x78, 0x0f, 0xb7, 0x09, 0xce, 0x86, 0x15, 0x11, 0xd0, 0x26, 0x81, 0x95, 0xf5, 0x14, 0x19, 0x03, 0xa4, 0x8f, 0xda, 0xf7, 0x4f, 0x23, 0x60, 0x0b, 0xcb, 0xfa, 0x04, 0xbb, 0x05, 0x86, 0xbd, 0x17, 0xb7, 0xd7, 0x90, 0x3e, 0x6d, 0xe2, 0x7e, 0xc4, 0x3c, 0xa6, 0x1c, 0x5d, 0x76, 0x2a, 0x8f, 0xb0, 0xfe, 0x78, 0x7d, 0xf6, 0x67, 0xc4, 0x2d, 0x2e, 0x68, 0x75, 0x5c, 0xce, 0xd1, 0xa7, 0xc8, 0xf7, 0xef, 0x34, 0xfd, 0x1c, 0x53, 0x94, 0x5f, 0x7a, 0x0b, 0xd2, 0x1b, 0xba, 0xb3, 0xfe, 0xdb, 0x2c, 0x24, 0xdc, 0xce, 0xc2, 0x82, 0x3d, 0x69, 0xb1, 0x45, 0x20, 0x8e, 0x94, 0x00, 0xb0, 0xc8, 0x13, 0x8c, 0x08, 0x92, 0x90, 0xed, 0x2d, 0xcf, 0xc8, 0xd7, 0xd1, 0xe4, 0x1c, 0xad, 0x4f, 0x4d, 0xf8, 0xdc, 0x50, 0x5c, 0xdb, 0x05, 0x43, 0x06, 0xc7, 0x19, 0x1e, 0x81, 0xa3, 0x73, 0x9a, 0xd2, 0xe3, 0xcb, 0x08, 0xca, 0xd3, 0xd4, 0x2a, 0xf3, 0x2e, 0x14, 0x80, 0x2c, 0x81, 0x08, 0xd2, 0xde, 0x65, 0xbe, 0x48, 0xdf, 0x7c, 0x8d, 0x02, 0x9c, 0x3e, 0xc1, 0x9d, 0x85, 0x28, 0xb3, 0xea, 0x5b, 0x99, 0x90, 0x30, 0x43, 0x25, 0xe5, 0x65, 0x67, 0x5f, 0x65, 0xdc, 0x76, 0x9e, 0x66, 0xae, 0x4e, 0x2e, 0x08, 0x3e, 0xd8, 0xbf, 0x55, 0x7c, 0xb1, 0x1a, 0x05, 0xaf, 0xb0, 0x53, 0xe9, 0xdd, 0xe1, 0x94, 0x9e, 0x86, 0xe9, 0x6d, 0x3f, 0xf4, 0x0e, 0xf9, 0xd2, 0x11, 0xe1, 0x30, 0x42, 0x82, 0x3b, 0x29, 0xab, 0xc9, 0x76, 0x9b, 0x14, 0xc2, 0x6e, 0x9c, 0x0d, 0x12, 0xa7, 0x4e, 0x30, 0x92, 0x15, 0x3e, 0x25, 0xa5, 0xd7, 0x2d, 0xa6, 0x28, 0xcc, 0x08, 0x29, 0x02, 0xf2, 0xb5, 0x64, 0x55, 0x11, 0x00, 0xa1, 0xce, 0x26, 0x27, 0x18, 0xa8, 0xbb, 0xcf, 0x03, 0x22, 0x0c, 0x99, 0x34, 0xa5, 0x04, 0xac, 0xd8, 0x79, 0xbd, 0x43, 0xcc, 0x3c, 0xf5, 0x5d, 0x00, 0x12, 0x4d, 0xc6, 0x1a, 0x92, 0xc2, 0x37, 0x86, 0xea, 0xe6, 0x0d, 0x67, 0x96, 0xfe, 0xcc, 0xdb, 0xcb, 0x44, 0x45, 0x87, 0xa5, 0xd6, 0xec, 0x0b, 0x57, 0x6d, 0xb6, 0xdf, 0xe1, 0x44, 0x3f, 0x84, 0xbc, 0xd9, 0xb0, 0x49, 0x5b, 0xb6, 0xfa, 0x12, 0xb3, 0x3e, 0x73, 0xbf, 0x6d, 0x7b, 0x09, 0x68, 0xf6, 0x69, 0xfc, 0xa0, 0x93, 0x50, 0x34, 0xdd, 0xc7, 0x13, 0x97, 0xa2, 0xe4, 0x14, 0x75, 0x9a, 0xe1, 0xb4, 0xcb, 0xf1, 0xd2, 0x2e, 0xa6, 0x45, 0x82, 0x82, 0xd0, 0x08, 0xd0, 0xd5, 0x0f, 0x87, 0xc1, 0xf8, 0x03, 0x9e, 0xbb, 0x0a, 0x67, 0x59, 0xbc, 0xec, 0xd4, 0xf9, 0x51, 0x88, 0x6b, 0xf3, 0xbd, 0xa1, 0x56, 0x13, 0xac, 0x21, 0x75, 0x92, 0xd9, 0xc6, 0x5b, 0xaf, 0x4a, 0xb8, 0xaa, 0xa4, 0x4e, 0x3e, 0xca, 0x98, 0xc9, 0x8d, 0xab, 0xb7, 0x52, 0x5e, 0x67, 0xb5, 0xea, 0xa1, 0x9e, 0xd0, 0x05, 0x84, 0x57, 0xb7, 0x92, 0x57, 0xdd, 0xcc, 0xe7, 0x37, 0x14, 0xd9, 0x28, 0x97, 0x87, 0xff, 0x2f, 0x0a, 0xf7, 0x57, 0x79, 0x19, 0x60, 0x7f, 0x61, 0x2d, 0x96, 0x69, 0x36, 0x16, 0x35, 0x33, 0xb2, 0xde, 0x17, 0xb1, 0xa1, 0xcc, 0x87, 0xa6, 0x55, 0xc3, 0x6b, 0xa3, 0x5d, 0x04, 0x5e, 0xbc, 0xc9, 0x12, 0x21, 0x6d, 0xee, 0xd7, 0x20, 0x69, 0x57, 0x3a, 0xca, 0xc2, 0xe4, 0xd4, 0x8f, 0x14, 0xc1, 0xa7, 0xec, 0x24, 0xe9, 0xba, 0x5d, 0xfa, 0x84, 0x1b, 0xfb, 0x6e, 0xa5, 0x1a, 0xd5, 0xf3, 0x98, 0xcc, 0xe3, 0xb6, 0x3b, 0x79, 0x1f, 0xbc, 0x9d, 0xa2, 0xd2, 0x63, 0x9c, 0x74, 0xa1, 0x34, 0x96, 0x82, 0x35, 0xfc, 0x06, 0x27, 0x2e, 0x77, 0x50, 0xd6, 0x5f, 0x26, 0xd8, 0x9f, 0xd3, 0x0d, 0x2b, 0xe7, 0xde, 0x4b, 0xe4, 0x34, 0xb8, 0x4d, 0x2b, 0x9e, 0x7f, 0xd4, 0xf8, 0x66, 0x82, 0x92, 0x95, 0x62, 0x7a, 0x0c, 0x2e, 0x21, 0x2f, 0xb8, 0x4a, 0x17, 0xeb, 0xa4, 0x9d, 0xac, 0x19, 0x13, 0x9d, 0x60, 0xb7, 0x1a, 0x29, 0xcf, 0x8f, 0x7c, 0x56, 0xe8, 0x57, 0x8a, 0x4a, 0xd6, 0xf7, 0x93, 0x39, 0x38, 0xc9, 0xbb, 0xb5, 0x36, 0xfe, 0x14, 0xf3, 0x8a, 0xd1, 0x8d, 0x42, 0x18, 0x05, 0xe3, 0xa9, 0x7f, 0xa7, 0xac, 0x82, 0x21, 0x47, 0x32, 0xda, 0x04, 0x5a, 0x0c, 0x15, 0x55, 0xde, 0x85, 0xd6, 0xcd, 0x41, 0x93, 0x92, 0x0e, 0x32, 0xf7, 0x0d, 0x62, 0x95, 0x73, 0x0f, 0x81, 0xbe, 0x8c, 0x15, 0xa2, 0x27, 0x6b, 0x9f, 0xb2, 0xd8, 0xc0, 0x47, 0x05, 0xc5, 0xbc, 0xb9, 0xb1, 0x68, 0x96, 0x54, 0x16, 0xf0, 0xfd, 0x7e, 0xb0, 0x40, 0x3e, 0x0f, 0xb4, 0x12, 0x66, 0x49, 0x8a, 0x12, 0xfc, 0xed, 0xe5, 0xfd, 0x7c, 0x1d, 0xab, 0x0a, 0xe0, 0xb7, 0x47, 0x10, 0x5f, 0x9a, 0x3a, 0x43, 0x5c, 0x30, 0xd6, 0x4f, 0xd1, 0x4a, 0x0b, 0x58, 0x76, 0x27, 0xb8, 0x4d, 0x34, 0x93, 0xe8, 0x6f, 0x91, 0x96, 0x61, 0x3b, 0xf0, 0xd4, 0xb1, 0x6b, 0x18, 0x42, 0x4b, 0xbe, 0x50, 0x0a, 0x9c, 0xc4, 0x3e, 0x71, 0x6c, 0xef, 0x5f, 0x19, 0x02, 0x78, 0x3b, 0x2b, 0x7c, 0x7f, 0xd8, 0x88, 0x6a, 0xe4, 0xd4, 0x72, 0x83, 0x60, 0x85, 0xc0, 0x0e, 0xb4, 0xa9, 0x09, 0xc9, 0xe0, 0xb6, 0x51, 0xd9, 0x25, 0x05, 0x30, 0x31, 0x22, 0x7a, 0x2b, 0x3c, 0x00, 0x83, 0xf2, 0xff, 0xa9, 0xd3, 0x9e, 0x80, 0xed, 0x46, 0xff, 0x46, 0x0c, 0x20, 0xb2, 0x1c, 0x29, 0xf6, 0xdf, 0xc4, 0x12, 0xd3, 0x4e, 0xc6, 0xa2, 0xac, 0xe2, 0x46, 0x07, 0x84, 0x35, 0xd1, 0x94, 0xe5, 0xda, 0x15, 0x78, 0x8e, 0x3b, 0xc4, 0x34, 0xf9, 0xe9, 0xaa, 0xbf, 0x87, 0x97, 0xdc, 0x4b, 0x94, 0xe1, 0x29, 0x77, 0x54, 0xa3, 0x44, 0xc2, 0x91, 0x52, 0x6c, 0xbf, 0xad, 0x5e, 0xf1, 0x7b, 0x44, 0xd9, 0xe9, 0x9a, 0x0e, 0x90, 0xa9, 0x8a, 0x63, 0x08, 0x4f, 0x2f, 0xb2, 0x8c, 0x63, 0x24, 0x4b, 0xee, 0x9f, 0xb6, 0x59, 0xd7, 0x14, 0x5d, 0xc0, 0x3d, 0x0d, 0x7b, 0x7e, 0x5e, 0xa7, 0x71, 0x63, 0x7f, 0x23, 0x45, 0x1e, 0x61, 0xcf, 0xca, 0xb8, 0x06, 0x3f, 0x15, 0x03, 0xf0, 0x86, 0xd7, 0x94, 0x5b, 0x24, 0x55, 0xf6, 0xec, 0xb6, 0x43, 0x26, 0x8c, 0x57, 0x19, 0x5f, 0x95, 0x9e, 0x96, 0x0b, 0x07, 0x7c, 0xfe, 0xbc, 0xe0, 0x21, 0x10, 0x87, 0xe5, 0xfc, 0x4d, 0xc5, 0x0b, 0x7e, 0x21, 0x28, 0x1d, 0xa0, 0xd8, 0x82, 0xc8, 0xb5, 0xab, 0x9e, 0xa9, 0x92, 0x27, 0xdf, 0xc1, 0x03, 0x5d, 0xde, 0x4a, 0x64, 0xae, 0xb2, 0x5d, 0x00, 0x52, 0x58, 0xf0, 0xba, 0x37, 0x8a, 0x31, 0xf7, 0xa4, 0xb0, 0x06, 0xda, 0x69, 0xd9, 0xa3, 0x0a, 0xba, 0x32, 0x9a, 0xba, 0x72, 0xe4, 0x49, 0xb7, 0x57, 0x51, 0xf3, 0x07, 0xb5, 0x54, 0x73, 0x59, 0xa8, 0xa0, 0x53, 0x94, 0x10, 0x8b, 0xad, 0x7b, 0x29, 0x2d, 0x84, 0x34, 0x64, 0x8b, 0x54, 0x7a, 0x61, 0xb2, 0x40, 0x39, 0x5c, 0x0b, 0xb9, 0x50, 0xac, 0xca, 0x74, 0x9c, 0x4d, 0x6d, 0x5b, 0x5a, 0x11, 0x92, 0x64, 0xf3, 0x71, 0x4f, 0x68, 0xee, 0x5e, 0x94, 0xc7, 0xe2, 0xa6, 0x98, 0x6a, 0x22, 0x5f, 0x1b, 0x43, 0x0e, 0x32, 0x61, 0xf3, 0x5a, 0xf6, 0x49, 0x40, 0xc0, 0xab, 0x7e, 0x3b, 0xa7, 0x08, 0xb5, 0xa8, 0x2d, 0xb9, 0x35, 0x10, 0xef, 0xce, 0x1a, 0x64, 0x61, 0x46, 0xfb, 0x02, 0x7e, 0x72, 0x11, 0x38, 0x02, 0xf4, 0x0d, 0x14, 0xfd, 0xc8, 0xd3, 0x32, 0xa9, 0xf0, 0x50, 0xef, 0x25, 0x7e, 0x8c, 0x92, 0xfb, 0xaf, 0x19, 0xad, 0x69, 0x54, 0xcd, 0xcb, 0x58, 0x52, 0xc8, 0x8d, 0x95, 0x91, 0x78, 0x31, 0x0d, 0x48, 0x01, 0x9a, 0x5c, 0x32, 0xec, 0xb3, 0xb5, 0x81, 0x60, 0xf6, 0x5d, 0x39, 0xe1, 0x18, 0xd4, 0x47, 0xfb, 0xb0, 0x1f, 0x48, 0x28, 0xa1, 0xbb, 0x46, 0xae, 0x9b, 0x81, 0xf5, 0xee, 0x30, 0xf3, 0x85, 0x81, 0x40, 0x89, 0x53, 0x41, 0x42, 0xa5, 0x2f, 0xf6, 0xb0, 0x9d, 0x6d, 0x90, 0x7e, 0xb7, 0x91, 0x86, 0x3a, 0xe4, 0xf1, 0xea, 0x84, 0x87, 0xfd, 0xf8, 0x5a, 0xe5, 0x9d, 0xad, 0x05, 0xd3, 0x32, 0x2d, 0x52, 0xb9, 0xee, 0xab, 0x71, 0x8c, 0xbd, 0x32, 0x3f, 0xa4, 0xe7, 0x93, 0xdf, 0x19, 0x38, 0x5c, 0x17, 0x64, 0x22, 0x68, 0xe6, 0xfe, 0xef, 0x28, 0xfe, 0x35, 0x1a, 0xc9, 0xf6, 0x0f, 0x28, 0x4b, 0x69, 0xe4, 0xb1, 0xfb, 0x71, 0x72, 0x0e, 0xce, 0xa3, 0x2e, 0xc4, 0x66, 0xb6, 0xdc, 0x5b, 0x2e, 0xb2, 0xea, 0xd3, 0xfe, 0x18, 0xc2, 0xbc, 0x98, 0xb7, 0xae, 0x2f, 0x57, 0x52, 0x3f, 0x73, 0x9e, 0x7a, 0x4e, 0xb5, 0x19, 0xe8, 0x53, 0xf3, 0x20, 0x50, 0xc1, 0xcf, 0x2b, 0x95, 0xa9, 0x3a, 0xeb, 0xf4, 0x3b, 0x63, 0x1d, 0xb8, 0x00, 0x34, 0x6c, 0xfb, 0x45, 0x66, 0xcb, 0xec, 0x65, 0xfe, 0xc9, 0x71, 0x31, 0xe7, 0xe8, 0xc3, 0xa6, 0x97, 0x09, 0x88, 0xca, 0xcb, 0x3b, 0xea, 0x27, 0x5e, 0x68, 0xad, 0x5a, 0x7a, 0xa9, 0x78, 0xb2, 0x62, 0x7d, 0x1e, 0xad, 0x1c, 0xf0, 0x86, 0xca, 0xd6, 0xc8, 0x5f, 0xeb, 0x68, 0xbe, 0x0a, 0xcb, 0x32, 0x14, 0xe7, 0xcd, 0x15, 0xcf, 0xe6, 0xe4, 0x50, 0xdc, 0x95, 0xb5, 0xbd, 0xd1, 0x65, 0x57, 0x88, 0x5c, 0xc3, 0xad, 0x54, 0x54, 0xba, 0xcb, 0xd7, 0x33, 0x4a, 0xe8, 0x8c, 0xa4, 0x2d, 0xb2, 0xd6, 0xaf, 0x90, 0x1d, 0x7c, 0x84, 0x89, 0x47, 0x44, 0x8e, 0x71, 0x08, 0xc2, 0xab, 0x8e, 0xd3, 0x92, 0x1c, 0xf7, 0xa6, 0xb5, 0xd6, 0x36, 0x84, 0x94, 0x47, 0x64, 0xfd, 0xfb, 0xe5, 0x42, 0x89, 0x50, 0xa7, 0xf8, 0x0d, 0x27, 0x42, 0x15, 0xc8, 0xfd, 0x8d, 0x9e, 0x7a, 0x83, 0xd7, 0xfb, 0x61, 0x6a, 0xab, 0x08, 0x84, 0x28, 0x48, 0xfe, 0x3e, 0x39, 0x48, 0xd5, 0x16, 0xd0, 0x9f, 0xbd, 0x7d, 0x19, 0x01, 0xd5, 0x49, 0x83, 0xcd, 0x89, 0x44, 0xdb, 0x51, 0x88, 0x2f, 0xbd, 0x24, 0x20, 0x2c, 0xa7, 0xc7, 0x70, 0xba, 0x03, 0x43, 0x4a, 0xbd, 0x97, 0x0b, 0x93, 0x7a, 0x09, 0xe8, 0x4f, 0xbb, 0x07, 0x79, 0x14, 0x72, 0x69, 0xe3, 0x42, 0xe3, 0x16, 0x06, 0xac, 0x14, 0xd5, 0xe5, 0x82, 0x8b, 0x94, 0x1d, 0xb0, 0xb0, 0xf2, 0xcd, 0x74, 0x58, 0x90, 0x59, 0x3c, 0x33, 0x19, 0x1a, 0xfa, 0xe6, 0x88, 0x5e, 0x22, 0xa4, 0x7c, 0x09, 0xd3, 0x98, 0xed, 0xcc, 0x69, 0xbd, 0xe0, 0x68, 0x61, 0xfc, 0x8d, 0x53, 0x94, 0x47, 0xa0, 0x8b, 0x95, 0xd4, 0xf6, 0xf8, 0x0f, 0xe2, 0xbd, 0xf3, 0xb7, 0xdc, 0x13, 0x3a, 0x60, 0xbc, 0xf2, 0x4e, 0x07, 0x5a, 0xd3, 0xe0, 0x88, 0x43, 0x48, 0xab, 0x4b, 0xf6, 0xb2, 0x27, 0x65, 0x82, 0x46, 0x26, 0x9e, 0x6f, 0xab, 0xdc, 0x9c, 0x80, 0x8d, 0x19, 0x8e, 0x0a, 0x9d, 0xb9, 0x51, 0xeb, 0x3d, 0xd7, 0x6b, 0x7e, 0x23, 0x96, 0x73, 0x00, 0xc4, 0xbf, 0x74, 0x6d, 0xd6, 0x1d, 0xd3, 0xea, 0x8f, 0xc9, 0x0d, 0xd6, 0x38, 0x3b, 0x4e, 0x0b, 0x4a, 0x0e, 0xaa, 0x86, 0x7d, 0x06, 0xab, 0xb6, 0xe0, 0x49, 0xcf, 0xd6, 0xc0, 0x5c, 0x26, 0x1b, 0x3e, 0xaa, 0xdf, 0x26, 0xf4, 0x2f, 0x69, 0xd9, 0x31, 0x97, 0xe8, 0xfd, 0xcc, 0x3b, 0xd1, 0x75, 0x7e, 0x15, 0xaa, 0xd3, 0xe2, 0xea, 0x9c, 0x3b, 0x5f, 0x23, 0x27, 0x45, 0x3a, 0x43, 0xef, 0x07, 0x68, 0x7c, 0xa5, 0x96, 0x0a, 0x4e, 0x52, 0x5a, 0x08, 0x30, 0xcb, 0x47, 0xa9, 0x6b, 0xdd, 0xb6, 0x21, 0x1b, 0xa6, 0x6e, 0x36, 0xa4, 0x02, 0xe0, 0x43, 0xe4, 0xb4, 0x66, 0xc7, 0x63, 0x46, 0xb0, 0x13, 0x88, 0xd0, 0x92, 0x72, 0xb9, 0xe7, 0xc1, 0xc7, 0xbc, 0xd3, 0xc6, 0xe9, 0xdd, 0x56, 0x67, 0x6e, 0x0a, 0x51, 0x6b, 0x3c, 0xd7, 0x3a, 0x54, 0xa6, 0x1e, 0x0a, 0x14, 0xa7, 0xa7, 0xa9, 0x2a, 0xcd, 0x7b, 0x9f, 0x5c, 0x40, 0x06, 0xe9, 0xee, 0x85, 0x15, 0x41, 0xdd, 0xb4, 0x60, 0x2d, 0xab, 0x56, 0x29, 0x9a, 0xd2, 0x32, 0x41, 0x66, 0x73, 0xa2, 0x4f, 0x50, 0x17, 0x5a, 0xd4, 0xd1, 0x8a, 0xf4, 0x60, 0x56, 0x49, 0xf5, 0x2d, 0xf9, 0xc4, 0xfd, 0x62, 0x9f, 0xf7, 0x50, 0xe6, 0xc4, 0xc5, 0x3e, 0x39, 0x58, 0xbb, 0xc5, 0xd2, 0xea, 0x8b, 0x8b, 0xaf, 0xc2, 0x3d, 0xd7, 0xb3, 0x6b, 0xcf, 0x09, 0xf0, 0xf6, 0x5e, 0x44, 0x87, 0x48, 0x2a, 0xe4, 0x82, 0x66, 0x16, 0x4b, 0x64, 0x22, 0x59, 0x62, 0x65, 0x1b, 0x7d, 0x6b, 0x63, 0xf3, 0x0d, 0x8f, 0x77, 0x66, 0x02, 0x67, 0xc4, 0xcb, 0x90, 0x23, 0x48, 0x4f, 0x9c, 0x31, 0x28, 0x39, 0x5f, 0x16, 0x7e, 0x4d, 0x3c, 0x59, 0xc6, 0x09, 0x56, 0x11, 0xdf, 0xd9, 0x02, 0x50, 0x42, 0x8b, 0x09, 0x7a, 0xd0, 0x06, 0xe1, 0xb4, 0xda, 0x48, 0x78, 0x4c, 0x51, 0x04, 0xac, 0x5a, 0x80, 0x2c, 0xd8, 0x7f, 0xff, 0x72, 0xc8, 0x36, 0x27, 0x54, 0x7a, 0xde, 0x55, 0xae, 0x41, 0xf0, 0x77, 0x8e, 0xb6, 0x56, 0x10, 0x08, 0xee, 0x8c, 0xa0, 0x8a, 0x69, 0xa4, 0x3d, 0x33, 0x0e, 0xa1, 0x5b, 0x31, 0x8c, 0xa6, 0x04, 0x9e, 0x7d, 0xfb, 0x2a, 0xeb, 0xb3, 0xf3, 0xb6, 0x1d, 0x82, 0x55, 0xc5, 0x5b, 0x12, 0xc5, 0x5f, 0xa6, 0x50, 0x8a, 0xa2, 0x5c, 0x18, 0x35, 0x65, 0xa9, 0x7b, 0x94, 0x48, 0x2d, 0xbf, 0x7c, 0x4b, 0x95, 0x91, 0x01, 0xa2, 0xc4, 0x44, 0x44, 0xef, 0xe2, 0x1a, 0x62, 0x0b, 0x44, 0xaf, 0x7a, 0xb4, 0x1c, 0xee, 0x55, 0x39, 0x54, 0xc0, 0xe7, 0x1d, 0x85, 0x19, 0x39, 0x73, 0x42, 0xa9, 0x5c, 0x08, 0xd4, 0xc9, 0xd9, 0xd9, 0x5b, 0xc8, 0x21, 0x92, 0x04, 0x82, 0xfd, 0x47, 0x33, 0xc6, 0xe0, 0x38, 0x76, 0xc9, 0xe4, 0xcc, 0xa5, 0x8e, 0xd3, 0x95, 0xda, 0x51, 0x10, 0xf4, 0xcc, 0x9e, 0x4d, 0x67, 0x6d, 0xc2, 0xc3, 0x4d, 0x43, 0x68, 0x2f, 0x0a, 0x72, 0x02, 0xa8, 0x67, 0x0e, 0x55, 0x72, 0xc4, 0xb6, 0x84, 0xfa, 0xab, 0x45, 0x5e, 0x4c, 0x15, 0xa9, 0xd7, 0x83, 0xc2, 0x97, 0xf1, 0x84, 0xfd, 0xff, 0xcb, 0x4b, 0xe2, 0xa8, 0xdd, 0x30, 0xa0, 0x1e, 0x27, 0xdb, 0x13, 0x3c, 0xf7, 0xf6, 0xbc, 0xf7, 0xec, 0x94, 0x32, 0x10, 0xf6, 0x5a, 0x0d, 0x66, 0xfd, 0xd5, 0x5b, 0xf3, 0x31, 0x7c, 0x56, 0xe3, 0x8f, 0xe2, 0xfd, 0x20, 0x69, 0xbd, 0x17, 0x77, 0x01, 0x0d, 0x2a, 0xe0, 0xf5, 0x6d, 0x06, 0x16, 0x17, 0xa0, 0xa6, 0x3a, 0x4b, 0x9c, 0xc2, 0xcd, 0x0c, 0x60, 0x3d, 0xc3, 0xf8, 0x5b, 0xb4, 0x59, 0xa6, 0x0c, 0x5d, 0x06, 0x94, 0x38, 0xed, 0x00, 0x27, 0x43, 0x4f, 0xd2, 0x7d, 0x2c, 0xad, 0xca, 0x03, 0x9c, 0x3d, 0x3a, 0x37, 0xc4, 0x13, 0xeb, 0x30, 0xa3, 0xc3, 0x51, 0x97, 0xa3, 0xfc, 0x73, 0x2b, 0xca, 0x2b, 0xf5, 0x36, 0x4a, 0x8a, 0x02, 0x62, 0xee, 0x48, 0x0c, 0x84, 0x92, 0x1f, 0x56, 0xdf, 0x99, 0x19, 0x8e, 0x25, 0x2b, 0x80, 0x91, 0xe4, 0xae, 0x2d, 0xc4, 0xbb, 0xb2, 0x3b, 0x6a, 0x28, 0x34, 0x75, 0x09, 0xc0, 0x57, 0x4c, 0x2b, 0x71, 0xf4, 0x17, 0x6c, 0x92, 0x2b, 0x22, 0x4f, 0x59, 0x48, 0x68, 0xe4, 0x68, 0xf5, 0xb8, 0x7d, 0xbe, 0x98, 0xed, 0x78, 0xc1, 0xc6, 0x1d, 0x95, 0x3f, 0x55, 0x31, 0x98, 0x87, 0x1e, 0xe8, 0xba, 0x83, 0x9a, 0xf5, 0xb0, 0x41, 0x22, 0xc7, 0x0b, 0x3d, 0xf7, 0xcd, 0x1d, 0x2c, 0x95, 0xf3, 0xe0, 0x9c, 0xae, 0x24, 0x21, 0xc3, 0xb2, 0xed, 0x0a, 0xe5, 0xda, 0x80, 0xd7, 0x4b, 0xb1, 0x26, 0x7b, 0x92, 0x4e, 0xda, 0xc0, 0x1a, 0x68, 0x06, 0x5a, 0x1c, 0x2a, 0x14, 0xfe, 0x40, 0x90, 0x02, 0x2f, 0x51, 0xe7, 0x8c, 0xfc, 0x69, 0x4b, 0x7e, 0xd8, 0x71, 0xc6, 0xe2, 0x73, 0xd1, 0x66, 0x7c, 0x0b, 0x0c, 0xd7, 0x0f, 0x21, 0x6a, 0xae, 0xe9, 0xeb, 0x4c, 0x80, 0x85, 0x20, 0xec, 0x1a, 0xee, 0x77, 0xdf, 0x84, 0x3b, 0x78, 0x1f, 0x72, 0x1d, 0x42, 0xbf, 0xe7, 0x61, 0x56, 0x48, 0x1c, 0x00, 0x64, 0xee, 0x0b, 0x9d, 0x5f, 0xa8, 0xf4, 0x1c, 0xca, 0xef, 0x77, 0xea, 0x9c, 0x58, 0xc1, 0x54, 0xb2, 0x7a, 0xa7, 0xf4, 0x9d, 0xfd, 0xa0, 0xe7, 0x61, 0x78, 0xb4, 0xd2, 0xc6, 0xa9, 0xeb, 0xe8, 0x78, 0x93, 0x75, 0x2d, 0x8a, 0x94, 0x9a, 0x5a, 0xe0, 0x1f, 0x61, 0x9f, 0xe5, 0x61, 0x47, 0x91, 0xd5, 0xc4, 0x52, 0xd4, 0x76, 0x06, 0x0b, 0xeb, 0x5a, 0x04, 0x95, 0xd5, 0x97, 0xcc, 0x4b, 0x3f, 0x0f, 0x7b, 0xb8, 0xc2, 0xa2, 0xf2, 0x78, 0x6a, 0xde, 0xc6, 0x77, 0xc1, 0x87, 0x44, 0x4f, 0x64, 0x3a, 0x2d, 0xfc, 0x53, 0xe1, 0x4f, 0x46, 0x7a, 0x8c, 0x90, 0x3f, 0x3c, 0xb8, 0xa7, 0x68, 0xc5, 0x26, 0xc2, 0x35, 0xcc, 0xcf, 0x24, 0x08, 0xc5, 0xe6, 0xe9, 0x48, 0x5e, 0xbf, 0x22, 0xde, 0xdb, 0x6a, 0x5a, 0x83, 0xb6, 0x2a, 0xd2, 0xd7, 0xb0, 0x0d, 0xef, 0xbd, 0xd8, 0x95, 0x3a, 0xc9, 0x5a, 0xac, 0x3a, 0xc6, 0x87, 0xe5, 0x5b, 0x96, 0x20, 0x99, 0x24, 0x82, 0x36, 0x22, 0xdf, 0xa7, 0x71, 0xc2, 0xb2, 0x58, 0xa5, 0x48, 0x17, 0xb7, 0x8f, 0x63, 0x83, 0xbf, 0x81, 0x6f, 0xfe, 0xb6, 0x12, 0x55, 0x41, 0x5e, 0x83, 0x1f, 0x38, 0x6e, 0x80, 0x6c, 0x90, 0xa7, 0x3a, 0x0e, 0x68, 0x29, 0x4b, 0xcb, 0xce, 0xde, 0xb3, 0xea, 0x36, 0x18, 0xe7, 0xa5, 0xc9, 0x0c, 0x1a, 0x70, 0x10, 0xc7, 0xeb, 0x2a, 0x01, 0x54, 0x37, 0x65, 0x57, 0x8c, 0xbd, 0x81, 0xe5, 0x6a, 0x80, 0x30, 0xf7, 0x0e, 0x85, 0x3e, 0x3e, 0x37, 0x87, 0xac, 0x40, 0x90, 0x01, 0xa7, 0x98, 0xe5, 0x6e, 0x7b, 0x82, 0x13, 0x73, 0xb7, 0xd0, 0xe8, 0x41, 0xea, 0xe3, 0x76, 0x07, 0x25, 0x7c, 0xc8, 0x7c, 0x8a, 0x0f, 0xf2, 0x93, 0x3c, 0x80, 0x69, 0xd9, 0x7b, 0xc8, 0xeb, 0x05, 0x17, 0x96, 0xd8, 0x6c, 0x4c, 0x89, 0x9f, 0x89, 0x47, 0x7a, 0xb4, 0xef, 0xec, 0x0f, 0x6f, 0xa9, 0xca, 0x19, 0x2d, 0x52, 0xa1, 0xc3, 0xd3, 0xee, 0x5a, 0x9a, 0x79, 0x25, 0x6f, 0xa9, 0xb3, 0xbc, 0x4f, 0x7b, 0x3f, 0x88, 0xad, 0x36, 0xe9, 0xdc, 0x25, 0xea, 0xbd, 0xd0, 0xcd, 0x4c, 0x76, 0x8c, 0x7e, 0x4d, 0xef, 0xbd, 0x8f, 0x39, 0xc2, 0x28, 0xe1, 0x3f, 0x2e, 0x46, 0xa1, 0xb6, 0x97, 0xe7, 0x8f, 0x5f, 0x23, 0xee, 0xc8, 0x76, 0x12, 0x03, 0x4a, 0xd2, 0xdb, 0x82, 0x69, 0x7a, 0xdc, 0x99, 0x19, 0x76, 0xfe, 0x31, 0x09, 0xcc, 0xbf, 0x8f, 0x70, 0x35, 0xff, 0x39, 0xac, 0x5c, 0x8d, 0x13, 0xf2, 0x74, 0x20, 0x2f, 0x7f, 0xab, 0x9c, 0xed, 0xdc, 0x5f, 0x15, 0xe1, 0x65, 0xb7, 0x22, 0xf7, 0x17, 0x17, 0x20, 0xe2, 0xa7, 0x7d, 0xd1, 0x0f, 0x88, 0xe1, 0x27, 0xbc, 0x64, 0x8d, 0xad, 0xe0, 0xc4, 0xe0, 0x64, 0x02, 0x1e, 0x08, 0xf3, 0x9d, 0x10, 0xfa, 0xea, 0x23, 0xea, 0x85, 0x45, 0x7c, 0xf1, 0x83, 0xab, 0xcd, 0x97, 0xaf, 0xf8, 0x96, 0x56, 0x7c, 0xb6, 0x54, 0x64, 0x7c, 0x45, 0xbf, 0xc5, 0x35, 0xba, 0xa9, 0x66, 0x27, 0x78, 0x24, 0xfe, 0x16, 0xf1, 0xc5, 0x21, 0x57, 0x4a, 0x7f, 0x7c, 0x43, 0x18, 0xc3, 0x98, 0xf7, 0x03, 0x3f, 0xfb, 0x0d, 0xb9, 0xcf, 0x9f, 0x61, 0x5c, 0x04, 0x39, 0xad, 0x12, 0xb2, 0xdb, 0x27, 0x64, 0x2f, 0x0e, 0x5f, 0x56, 0x50, 0xe1, 0x6a, 0x17, 0xd0, 0xb2, 0xf4, 0x1c, 0x45, 0x98, 0x92, 0x9e, 0x9b, 0xa5, 0x14, 0x00, 0xa0, 0x5d, 0x84, 0x9c, 0x8a, 0x3e, 0xe5, 0xaa, 0xa0, 0x11, 0x28, 0xcd, 0xe7, 0xf9, 0x6e, 0x67, 0x8d, 0x76, 0xc5, 0xe4, 0x08, 0x35, 0x90, 0xd3, 0xbf, 0xb7, 0x74, 0x87, 0x8f, 0xe8, 0x5a, 0x61, 0x8d, 0x72, 0xbf, 0x6a, 0x77, 0x9c, 0x3c, 0x78, 0x6d, 0xf0, 0xb2, 0x7b, 0x8e, 0xf0, 0x45, 0x34, 0xf4, 0x16, 0x7b, 0x1d, 0x5c, 0x5c, 0x84, 0x08, 0x0c, 0x44, 0xbe, 0xd4, 0xb9, 0x93, 0x28, 0x04, 0x4c, 0x00, 0xf4, 0x5b, 0xb0, 0x1c, 0x73, 0x69, 0x5e, 0x4d, 0x7c, 0x40, 0x1c, 0xf7, 0x92, 0x66, 0xaa, 0xb9, 0x70, 0xd5, 0x2a, 0x0d, 0x12, 0x8d, 0xef, 0x40, 0x3c, 0x95, 0x2c, 0xb0, 0x30, 0x4d, 0x1e, 0x86, 0xd4, 0x4d, 0xb7, 0xa5, 0x1a, 0x08, 0xc7, 0x1d, 0x24, 0x09, 0x32, 0x60, 0x24, 0x71, 0xdf, 0xb8, 0xc2, 0x82, 0x5a, 0x24, 0x61, 0x1e, 0x43, 0x4b, 0x49, 0x89, 0x92, 0xea, 0xa9, 0x77, 0x5a, 0x31, 0x54, 0x52, 0xd0, 0x76, 0xb6, 0xcc, 0x11, 0x13, 0xcd, 0xa0, 0x16, 0xe5, 0xc4, 0xb8, 0x61, 0x04, 0xc1, 0x50, 0x34, 0xf0, 0x95, 0x3a, 0x95, 0xdd, 0x01, 0x06, 0x4e, 0x14, 0x00, 0xdc, 0xdc, 0x30, 0x51, 0xe7, 0xdb, 0xc0, 0xbe, 0x75, 0x12, 0x1e, 0x90, 0x61, 0xc5, 0x2e, 0xcc, 0x74, 0x2f, 0xa5, 0xf3, 0xfb, 0xeb, 0xe3, 0xf1, 0xe8, 0x3d, 0x54, 0xe0, 0x4d, 0xb1, 0x7c, 0x75, 0x6b, 0x83, 0x71, 0x84, 0xcc, 0xab, 0xef, 0x3c, 0xec, 0x8e, 0x34, 0xb5, 0x8a, 0xe7, 0xf0, 0x20, 0x41, 0x38, 0xb2, 0x0d, 0x4c, 0x5d, 0x20, 0x3c, 0x2c, 0xdd, 0xf0, 0xc0, 0xe6, 0x36, 0xe4, 0xb7, 0x3e, 0xa0, 0x34, 0x71, 0xa6, 0x4e, 0x3d, 0x0d, 0x3f, 0x94, 0xb7, 0x27, 0x72, 0x85, 0x8b, 0x2c, 0x91, 0x9e, 0x5a, 0x2e, 0x36, 0x00, 0xe1, 0x64, 0xe1, 0x2c, 0x4a, 0xe9, 0xec, 0x07, 0xa6, 0x5e, 0x86, 0x01, 0xc4, 0x87, 0x0b, 0xb5, 0xaf, 0xc2, 0xe2, 0x8b, 0x08, 0x31, 0xd7, 0xc1, 0xee, 0x80, 0x7f, 0x1f, 0x74, 0xbd, 0x97, 0xff, 0x34, 0xc9, 0x70, 0x64, 0x2b, 0x0c, 0x56, 0x21, 0x6b, 0xc5, 0x11, 0xd6, 0x7d, 0x8f, 0xfa, 0x29, 0xfa, 0x8f, 0xfd, 0xa3, 0xdf, 0xaf, 0x5e, 0xa9, 0xca, 0x21, 0x92, 0xa0, 0x5b, 0x50, 0x21, 0x95, 0xcb, 0xee, 0x29, 0xb9, 0x89, 0xdf, 0xc6, 0x02, 0x35, 0x68, 0x9c, 0x8c, 0xbf, 0x62, 0xe9, 0x2d, 0x2c, 0x7e, 0xd1, 0xa6, 0x6a, 0x6e, 0xc4, 0xec, 0x5f, 0x55, 0x35, 0xd6, 0x95, 0xcb, 0xf4, 0x45, 0x0b, 0x0b, 0x11, 0x78, 0x85, 0x30, 0xb3, 0xd8, 0xfe, 0x77, 0xe8, 0x46, 0x22, 0xd0, 0x72, 0xee, 0x69, 0x34, 0x9d, 0x0a, 0x5f, 0xc3, 0xfc, 0xb8, 0xcc, 0xde, 0x7d, 0x37, 0xc7, 0x9c, 0x70, 0x1f, 0x65, 0x24, 0x8c, 0xca, 0x80, 0xc6, 0x79, 0xf9, 0xfe, 0x9a, 0xe8, 0x2a, 0x3b, 0xc8, 0x86, 0x3c, 0xed, 0x2d, 0x20, 0x53, 0x26, 0x7a, 0xf5, 0x2f, 0x4c, 0x7f, 0x4b, 0xa7, 0x10, 0x45, 0xdd, 0x25, 0x7e, 0x12, 0x1c, 0x9f, 0x69, 0x29, 0x88, 0x43, 0x60, 0xde, 0x55, 0xa4, 0xc9, 0x43, 0x12, 0xc9, 0x5e, 0xf7, 0xff, 0xf6, 0x54, 0xd9, 0x8b, 0x23, 0xa4, 0x92, 0xcd, 0xb6, 0x33, 0xc7, 0xbc, 0x2c, 0x57, 0xcc, 0x43, 0x23, 0x74, 0x9a, 0x6c, 0x12, 0x48, 0xe3, 0x8f, 0x64, 0xf7, 0x2c, 0x39, 0x1b, 0x5c, 0x13, 0x71, 0x53, 0x7a, 0x77, 0x87, 0xe5, 0x17, 0x10, 0x61, 0x1e, 0xb8, 0x71, 0x6a, 0x49, 0x52, 0x3c, 0x69, 0xb3, 0x1e, 0xa3, 0x65, 0xf6, 0xe3, 0xf0, 0xaa, 0x8e, 0x13, 0x7e, 0xba, 0xea, 0x15, 0x03, 0x22, 0x4e, 0x07, 0x91, 0x2b, 0x6d, 0x1d, 0x68, 0x2e, 0x27, 0x7e, 0xf8, 0x4f, 0xb6, 0x98, 0xaa, 0xa2, 0x67, 0x49, 0x36, 0x1c, 0x1e, 0xbb, 0xf1, 0x2b, 0x55, 0x6b, 0xde, 0x7b, 0x02, 0x12, 0xea, 0xd4, 0xac, 0xe3, 0x2c, 0x86, 0x22, 0xac, 0x7f, 0x3a, 0xd9, 0x0d, 0xd0, 0x78, 0x1f, 0xf7, 0xc9, 0xf6, 0x05, 0x48, 0x75, 0x1b, 0x83, 0x9a, 0xa8, 0x2d, 0x08, 0xb9, 0x4d, 0x39, 0xcd, 0x01, 0xa2, 0xc0, 0x95, 0xab, 0xe5, 0x76, 0xe3, 0xd6, 0x89, 0xef, 0xb8, 0xe6, 0x33, 0x5a, 0x4e, 0x46, 0x89, 0xa4, 0x8b, 0xc3, 0xed, 0xf7, 0x1c, 0xde, 0x16, 0xc4, 0xfd, 0xcf, 0x76, 0x1d, 0xb1, 0xb4, 0xf5, 0x5a, 0xd8, 0xa4, 0x2d, 0xad, 0xd1, 0x65, 0x32, 0x6f, 0x3a, 0xac, 0xf0, 0x8c, 0x87, 0x27, 0x2e, 0x71, 0x46, 0xa0, 0xf6, 0x50, 0xd9, 0x21, 0xe2, 0x14, 0xb0, 0xf3, 0x73, 0x36, 0xb6, 0x2b, 0xa1, 0x80, 0x0c, 0x26, 0x66, 0x02, 0xab, 0x8e, 0x49, 0xb3, 0xdf, 0x5e, 0xf0, 0x5e, 0x96, 0x38, 0x4a, 0x81, 0x98, 0x18, 0xed, 0x74, 0x33, 0xd4, 0xa7, 0x81, 0x57, 0x88, 0x16, 0x08, 0x5b, 0x2a, 0xcd, 0x7b, 0x21, 0x16, 0x99, 0x2b, 0xb4, 0x57, 0xcb, 0xef, 0x21, 0xca, 0xaa, 0x26, 0x67, 0x6f, 0xd4, 0x12, 0xb2, 0x71, 0xf8, 0x94, 0x06, 0x43, 0x2d, 0xc8, 0x41, 0xb0, 0x65, 0x04, 0xd8, 0x03, 0x55, 0xe6, 0x24, 0xf9, 0x34, 0x5e, 0xd4, 0x83, 0xc6, 0x05, 0xe6, 0x24, 0x61, 0xec, 0xac, 0x72, 0x2b, 0xbe, 0x14, 0x68, 0xf9, 0x35, 0x59, 0x63, 0x7a, 0xad, 0xa5, 0x19, 0x97, 0xf5, 0xe8, 0xba, 0xce, 0x5c, 0xfb, 0x47, 0x86, 0xc2, 0x69, 0x79, 0xfd, 0xe3, 0x9f, 0x06, 0x92, 0xc2, 0x06, 0xea, 0x26, 0x2e, 0x44, 0x63, 0x81, 0x4f, 0x7c, 0xcd, 0x3b, 0xc0, 0x46, 0x57, 0x98, 0xa0, 0xea, 0x85, 0xf2, 0x02, 0xed, 0xbf, 0x52, 0xfd, 0xb7, 0xb1, 0x71, 0x8f, 0x44, 0x51, 0x2e, 0xce, 0x42, 0xb1, 0xf3, 0xf8, 0x55, 0xea, 0xb6, 0xf9, 0x6e, 0x6c, 0x3c, 0x82, 0x0b, 0x5d, 0x92, 0xbf, 0x7e, 0xd7, 0x43, 0x06, 0xbe, 0x48, 0x78, 0xf1, 0xc4, 0x72, 0x43, 0xa9, 0x67, 0x4d, 0x64, 0x1e, 0x33, 0x0f, 0xf2, 0x92, 0x63, 0x00, 0x78, 0xd1, 0xf8, 0x54, 0xea, 0x1d, 0x9d, 0xf6, 0x87, 0xe3, 0x6b, 0x81, 0x8a, 0x6b, 0xc1, 0xd8, 0x23, 0x6f, 0x54, 0x08, 0x4d, 0x7b, 0x7b, 0x9c, 0x62, 0x49, 0x50, 0xf8, 0x75, 0x99, 0x92, 0x88, 0x2c, 0x4a, 0x3b, 0x17, 0x94, 0x2a, 0xb2, 0xef, 0x3f, 0xaa, 0xc6, 0xc7, 0x5b, 0x5a, 0xc3, 0xf6, 0x0e, 0x08, 0x2c, 0xd8, 0x87, 0xb3, 0x6c, 0x63, 0xdd, 0x19, 0x0e, 0x3c, 0xd8, 0x0c, 0xc6, 0x5f, 0x91, 0x20, 0xa8, 0x28, 0xb0, 0xd6, 0xc3, 0xd2, 0xac, 0xec, 0x13, 0x9a, 0x41, 0x25, 0x47, 0x82, 0x82, 0xa8, 0x3e, 0xbf, 0xfb, 0xde, 0x2a, 0xc4, 0x40, 0x08, 0x5c, 0xe7, 0x04, 0x9b, 0xc9, 0x37, 0x1c, 0xca, 0x86, 0x82, 0x5b, 0xb4, 0x95, 0xbe, 0x68, 0x48, 0xaf, 0x81, 0xcb, 0xd1, 0x68, 0x84, 0x60, 0xd9, 0xf5, 0xe4, 0x12, 0x34, 0x8c, 0x31, 0xd4, 0x41, 0xf9, 0x3f, 0xc4, 0x33, 0x7a, 0x6e, 0x84, 0xa8, 0x8d, 0x7d, 0x42, 0x61, 0xb6, 0x3f, 0x68, 0x7c, 0xc1, 0xfd, 0xbd, 0x2f, 0x3f, 0xd8, 0x95, 0xe5, 0x94, 0xd9, 0x73, 0xe2, 0x82, 0x67, 0x9a, 0x0c, 0xcb, 0x92, 0x0d, 0xe5, 0xbe, 0x2a, 0x20, 0x9c, 0x15, 0xa4, 0x02, 0xc9, 0xdc, 0x04, 0x3e, 0x68, 0xe1, 0x0a, 0xa5, 0xae, 0x98, 0xf7, 0xc3, 0x20, 0x8c, 0x6a, 0x28, 0x4d, 0xcf, 0xb3, 0x6f, 0x63, 0x6c, 0xc2, 0x55, 0x3c, 0xed, 0x0f, 0xe2, 0xd7, 0x83, 0x94, 0x75, 0xb8, 0xd7, 0xc1, 0x73, 0xd8, 0x71, 0x61, 0xa6, 0xe9, 0x88, 0x67, 0x4a, 0xd8, 0x7e, 0x55, 0xc7, 0x4b, 0x40, 0x08, 0x75, 0x09, 0xb3, 0xd3, 0x30, 0x91, 0x98, 0x8f, 0x0f, 0xf3, 0x46, 0xb0, 0xbb, 0x36, 0xc1, 0x5c, 0xfd, 0xbe, 0x40, 0x59, 0xdb, 0xbd, 0x28, 0x3e, 0x2a, 0x34, 0xcd, 0x3f, 0x78, 0xa2, 0x17, 0xe3, 0x02, 0x48, 0x15, 0xd8, 0x30, 0x83, 0xfa, 0xc8, 0xea, 0x20, 0x6d, 0xb4, 0xfd, 0xb7, 0x1e, 0xd3, 0x98, 0x73, 0x0d, 0x13, 0x52, 0x68, 0x48, 0xa6, 0x52, 0x17, 0x6c, 0x8f, 0x1c, 0x77, 0xea, 0x52, 0x8d, 0x3f, 0x6a, 0x2f, 0xd6, 0x42, 0xe2, 0x06, 0xb8, 0xa0, 0xe0, 0x30, 0xc4, 0xd5, 0x42, 0x55, 0x56, 0x65, 0x46, 0xbc, 0x19, 0x19, 0x8a, 0x5f, 0x9c, 0xf4, 0xcf, 0x56, 0xa2, 0x64, 0xa7, 0x6a, 0x42, 0x36, 0x1c, 0x7d, 0x43, 0x57, 0xc9, 0x2d, 0xb1, 0xe9, 0xdb, 0x3c, 0xf4, 0xf4, 0xdb, 0x5c, 0xc4, 0x17, 0x2c, 0xf4, 0xf4, 0xf4, 0xbe, 0x4c, 0x7f, 0x47, 0xac, 0xe3, 0x24, 0x63, 0xff, 0xe4, 0xe0, 0xa5, 0x62, 0x02, 0xcf, 0x1c, 0xfc, 0xdb, 0x7f, 0x81, 0x84, 0x1b, 0x4a, 0x76, 0x3c, 0xb1, 0xa2, 0x24, 0x32, 0x1b, 0xce, 0x0a, 0xf6, 0x11, 0x40, 0x3b, 0x61, 0x03, 0x9f, 0xbd, 0x95, 0x54, 0xc8, 0x6b, 0x26, 0xae, 0x15, 0x83, 0x83, 0xef, 0x0c, 0x52, 0x3a, 0x6f, 0xd4, 0x05, 0x04, 0xa3, 0x2c, 0x7b, 0x6b, 0x3f, 0x59, 0xe2, 0x28, 0x33, 0x32, 0x21, 0xa1, 0x66, 0x6a, 0x59, 0x0b, 0x74, 0x57, 0x75, 0x6c, 0x74, 0x25, 0xc4, 0xf2, 0x87, 0x1d, 0xfe, 0x7f, 0x01, 0x9f, 0x9c, 0x36, 0x40, 0x5e, 0x01, 0x7d, 0xd3, 0xc9, 0xd6, 0xcf, 0x5a, 0x47, 0xeb, 0xf2, 0x1e, 0x3f, 0x7d, 0x3c, 0x03, 0xa7, 0xba, 0x69, 0x81, 0xcf, 0xe5, 0x95, 0x61, 0x91, 0xd4, 0x4b, 0xad, 0xc3, 0x37, 0x97, 0xa6, 0x60, 0xcb, 0x15, 0x87, 0xbc, 0x0f, 0x91, 0xef, 0x70, 0xa8, 0xb9, 0x5d, 0x94, 0x8d, 0x9e, 0xc5, 0x9a, 0xa0, 0x9a, 0xe2, 0x71, 0xa4, 0x30, 0x41, 0x26, 0xfd, 0x63, 0x1a, 0xc4, 0xd9, 0x07, 0xdc, 0xf6, 0x7c, 0xbc, 0x67, 0x13, 0x4f, 0xc1, 0x95, 0x36, 0x5b, 0x9a, 0x14, 0x47, 0x75, 0x4e, 0xaf, 0xec, 0xc3, 0x0b, 0x62, 0xac, 0x9c, 0x65, 0xfd, 0x7d, 0x67, 0xbd, 0xb8, 0xac, 0xc7, 0x1f, 0x87, 0x84, 0x54, 0xda, 0x65, 0xc2, 0x8d, 0x95, 0xf2, 0x6e, 0x15, 0xff, 0xd6, 0x99, 0xad, 0x85, 0xc3, 0x9e, 0x62, 0x1a, 0x53, 0x9a, 0xa4, 0x86, 0x5d, 0x3d, 0x8b, 0xb3, 0x8c, 0x41, 0xbd, 0x85, 0x61, 0xc3, 0xe7, 0x95, 0xbf, 0x64, 0x9e, 0xbf, 0x4c, 0xf1, 0xca, 0x8d, 0xa4, 0x5e, 0xa3, 0xc2, 0x1a, 0x98, 0x66, 0x7a, 0x3b, 0xc9, 0xfb, 0xb1, 0x31, 0x2a, 0xb2, 0xa7, 0xfc, 0x9b, 0x6b, 0xb7, 0xf0, 0xd5, 0x0f, 0xc5, 0x4c, 0x2f, 0x2d, 0xc7, 0xfe, 0x7c, 0xc4, 0xe2, 0x4b, 0xf5, 0x97, 0xf2, 0x38, 0x5b, 0xad, 0x86, 0xed, 0x8b, 0xaf, 0xa2, 0x7e, 0x21, 0x10, 0x6b, 0x09, 0x0b, 0x3c, 0x35, 0x4d, 0xf6, 0x30, 0x94, 0xb6, 0x17, 0xb2, 0xe1, 0x15, 0xc3, 0x53, 0x6e, 0x2d, 0xf5, 0x48, 0x09, 0xed, 0x82, 0xaa, 0x6a, 0x09, 0x7b, 0xc0, 0x1d, 0x06, 0xa4, 0x0d, 0x81, 0xf8, 0x6d, 0xc8, 0x41, 0xc4, 0x04, 0x30, 0x71, 0x9a, 0x70, 0xbb, 0xd0, 0x01, 0x0f, 0x37, 0x19, 0xfd, 0x8a, 0x21, 0x57, 0x33, 0x50, 0x10, 0x31, 0x21, 0xdf, 0x44, 0x6a, 0xed, 0x70, 0xa1, 0xbf, 0xae, 0xdf, 0xc4, 0x38, 0x3f, 0x9d, 0x02, 0xfd, 0x8b, 0xbd, 0x52, 0x9b, 0xf5, 0x82, 0x12, 0xca, 0xee, 0xe5, 0xe5, 0xcd, 0x5f, 0x87, 0x50, 0x8e, 0x3d, 0x89, 0xdc, 0x72, 0x55, 0x83, 0x7f, 0x80, 0x25, 0xe4, 0x94, 0x81, 0xe0, 0xb5, 0x51, 0x7f, 0x11, 0xd6, 0x16, 0x2d, 0x9c, 0x4c, 0xa1, 0x8d, 0x2e, 0x10, 0xa9, 0xb5, 0x9c, 0xcc, 0xe9, 0xc2, 0xee, 0x10, 0x97, 0x02, 0x1a, 0xf6, 0x38, 0x86, 0x77, 0xfb, 0x10, 0xb9, 0x58, 0x34, 0x59, 0xe5, 0x37, 0xd0, 0x85, 0x4d, 0xc7, 0x87, 0x40, 0x08, 0xda, 0x53, 0xa5, 0x4b, 0xbb, 0x6f, 0x3b, 0x7c, 0x76, 0x98, 0x0f, 0xf7, 0xfc, 0x50, 0x27, 0xde, 0xbb, 0xb2, 0xcc, 0x6c, 0x9e, 0xdb, 0xc8, 0xb4, 0xf2, 0xd8, 0x33, 0x7b, 0xb3, 0xfe, 0xdb, 0x93, 0xf4, 0x26, 0x35, 0x87, 0x88, 0x16, 0x0d, 0xe3, 0x66, 0x41, 0x12, 0xad, 0xbb, 0x29, 0x47, 0x2c, 0x8e, 0x10, 0x92, 0xa8, 0xc0, 0x07, 0x08, 0xba, 0xa4, 0xc0, 0x96, 0xa2, 0xa6, 0x48, 0x5f, 0x99, 0xe8, 0x07, 0x2a, 0xb0, 0xa5, 0x8e, 0x87, 0x08, 0x23, 0x26, 0xf4, 0x59, 0x9f, 0x8a, 0x0a, 0xcc, 0x70, 0xb8, 0xe6, 0x25, 0x07, 0x97, 0xf2, 0x69, 0xac, 0x4b, 0xd0, 0x23, 0x66, 0x27, 0x35, 0x3c, 0x55, 0x6d, 0xd1, 0xe2, 0x74, 0x8d, 0xdc, 0x74, 0xf5, 0xb5, 0xd9, 0x66, 0x81, 0xa6, 0xa7, 0x35, 0x43, 0x2b, 0x7b, 0x39, 0x95, 0xee, 0x61, 0x80, 0x1d, 0xcf, 0x5c, 0xc2, 0x4a, 0xdd, 0x45, 0xcb, 0x94, 0x66, 0x92, 0xf7, 0xf2, 0x5c, 0x9c, 0x1c, 0xea, 0xb2, 0x5c, 0x35, 0x72, 0x28, 0xbc, 0x2e, 0xd1, 0x44, 0x2d, 0x6f, 0x26, 0x91, 0xa1, 0xba, 0x84, 0xff, 0xe0, 0x9f, 0xa9, 0x74, 0xf2, 0xca, 0x9b, 0xe0, 0xd0, 0x2f, 0x93, 0x76, 0x8b, 0x3b, 0x11, 0x59, 0xdf, 0x0b, 0x1a, 0x6f, 0x3f, 0x88, 0xdb, 0xb0, 0x20, 0xa6, 0xd1, 0xe6, 0x87, 0x47, 0xa9, 0x9c, 0xce, 0xaa, 0x13, 0x8c, 0x0d, 0x44, 0xa1, 0x07, 0xb7, 0xdb, 0x00, 0x0e, 0xbc, 0x32, 0x41, 0x51, 0x81, 0x9d, 0x1f, 0xee, 0xe2, 0x20, 0x58, 0x25, 0x2d, 0x7c, 0x39, 0x94, 0xe9, 0xb5, 0x34, 0x18, 0x05, 0x93, 0x48, 0xda, 0xc1, 0x7f, 0xa0, 0x55, 0xf2, 0x58, 0xb4, 0x1b, 0x7a, 0x0f, 0x29, 0x27, 0x5c, 0x42, 0x16, 0xe3, 0xa1, 0xc5, 0xc2, 0x36, 0x00, 0xe1, 0x8a, 0xd2, 0x45, 0x2b, 0x21, 0xcd, 0xe2, 0x35, 0xdb, 0x8b, 0x96, 0xa0, 0xc3, 0x7b, 0xdd, 0xe8, 0xd8, 0x42, 0x53, 0x32, 0xca, 0x81, 0x27, 0xb4, 0x7f, 0x80, 0x26, 0x77, 0x41, 0xcd, 0xaf, 0x54, 0xc2, 0xb3, 0x01, 0x7f, 0x12, 0x0f, 0x54, 0xc3, 0xda, 0xa8, 0x50, 0xa5, 0x57, 0xbe, 0xe5, 0xd9, 0xc1, 0xc0, 0x39, 0x34, 0x9b, 0x06, 0x86, 0x8d, 0xb9, 0xb5, 0x6b, 0x00, 0xf1, 0x38, 0x18, 0xf0, 0xe1, 0x55, 0x50, 0xf9, 0x87, 0x7c, 0xaf, 0x27, 0x32, 0x27, 0xf8, 0xcc, 0x98, 0x3b, 0xb5, 0x32, 0x3b, 0x51, 0xf5, 0xd3, 0xf3, 0x1d, 0x86, 0xc4, 0x7a, 0xe1, 0xac, 0xba, 0x6e, 0x2f, 0xbf, 0x48, 0xf0, 0x6a, 0x46, 0xcc, 0x48, 0x6d, 0xef, 0xfb, 0xf8, 0x99, 0xe4, 0x3c, 0xa5, 0x5f, 0xee, 0xb6, 0x53, 0x1e, 0x30, 0xef, 0x29, 0xc5, 0xde, 0x76, 0x3f, 0x26, 0x62, 0x4b, 0xd0, 0x61, 0x7b, 0xf9, 0xb3, 0x2e, 0x3a, 0x77, 0xa2, 0x9d, 0xa5, 0x43, 0x1d, 0xa2, 0x80, 0x7c, 0x96, 0x9b, 0x94, 0x10, 0xe4, 0x2a, 0x03, 0x64, 0xce, 0x32, 0x44, 0x83, 0xb4, 0x2c, 0x96, 0x41, 0xbf, 0x64, 0x62, 0x31, 0x6f, 0x02, 0x30, 0x57, 0x4c, 0x5a, 0xe1, 0xb5, 0x58, 0xeb, 0x1f, 0x74, 0xc8, 0xc5, 0x51, 0xab, 0x5b, 0x68, 0x4b, 0xbd, 0x85, 0xfd, 0x20, 0xe6, 0x54, 0x0a, 0x46, 0x59, 0x90, 0x17, 0x8e, 0xdc, 0xfa, 0xa1, 0x16, 0xa8, 0x46, 0x5b, 0x7d, 0x53, 0xdf, 0xa6, 0x7a, 0xa4, 0x96, 0x73, 0xb1, 0xea, 0xc7, 0x5e, 0x79, 0xf0, 0x5b, 0x78, 0x2f, 0xfb, 0x49, 0xa4, 0xb6, 0xa6, 0x80, 0x6b, 0x61, 0x7c, 0x27, 0xb7, 0x7b, 0x3e, 0x5b, 0x20, 0x34, 0x84, 0xe7, 0xeb, 0xc7, 0x5d, 0x25, 0xbe, 0x69, 0x82, 0xcc, 0x74, 0x15, 0x64, 0x70, 0x59, 0x87, 0xf5, 0x37, 0x08, 0x2f, 0x8b, 0xc0, 0x61, 0xb3, 0x05, 0x37, 0x0c, 0xc4, 0x5b, 0x49, 0xa0, 0x6e, 0xb6, 0x9e, 0x97, 0x66, 0x62, 0xf0, 0xeb, 0xb1, 0x86, 0x17, 0x88, 0xe0, 0x61, 0xc1, 0x2b, 0x11, 0x55, 0x76, 0xaf, 0xc4, 0x7f, 0xc2, 0x74, 0x05, 0xc6, 0xc7, 0xa6, 0x0a, 0x11, 0x78, 0x72, 0x62, 0x78, 0x43, 0x91, 0xda, 0x9b, 0xfa, 0x7a, 0x1d, 0x3b, 0x7e, 0x66, 0x7e, 0x62, 0x05, 0xee, 0x97, 0x90, 0x8c, 0xca, 0xe5, 0x00, 0xdd, 0x40, 0x65, 0xa7, 0x83, 0xf0, 0x92, 0xa7, 0x1f, 0xec, 0x56, 0x9e, 0xdd, 0x58, 0x2a, 0x52, 0x2d, 0x26, 0x86, 0xa4, 0x86, 0x27, 0xc5, 0x1a, 0x1f, 0x82, 0xcd, 0x98, 0xf3, 0x28, 0x8f, 0xdb, 0xcd, 0xc4, 0xb5, 0x9f, 0x13, 0x90, 0x44, 0x14, 0x2f, 0xdf, 0x7f, 0xc0, 0x85, 0xe2, 0xcd, 0x20, 0x76, 0xdd, 0xee, 0x16, 0xa0, 0x09, 0x2a, 0x8d, 0xa3, 0x69, 0x67, 0x34, 0xc9, 0x07, 0x58, 0xf6, 0xad, 0x34, 0x25, 0xa4, 0x38, 0x26, 0x9c, 0xbb, 0x93, 0xfb, 0x46, 0x13, 0x63, 0x5d, 0x10, 0x64, 0xa9, 0x38, 0xd8, 0xf7, 0xb4, 0x16, 0x33, 0x57, 0x03, 0xe5, 0xb1, 0xc5, 0x7a, 0xc9, 0x79, 0xa4, 0xb6, 0x74, 0xa1, 0xae, 0x93, 0xd1, 0x45, 0xdd, 0x33, 0x3d, 0x67, 0x50, 0xb6, 0x8b, 0x56, 0x5a, 0x8f, 0x95, 0x4f, 0x7c, 0x1c, 0x3f, 0x3b, 0x44, 0xd0, 0xd0, 0x1a, 0x81, 0xdc, 0x54, 0x17, 0x3c, 0x95, 0x06, 0xe4, 0xaf, 0x1e, 0x6a, 0xde, 0x9a, 0xb4, 0x91, 0x21, 0xa5, 0x52, 0x1f, 0x99, 0xef, 0x4f, 0x96, 0x77, 0xc2, 0x8b, 0x9e, 0xd7, 0x7a, 0x9a, 0x4b, 0x1c, 0x61, 0x22, 0x42, 0x0f, 0x71, 0xc4, 0xf2, 0xe5, 0xdf, 0x7a, 0x1f, 0xab, 0x35, 0xb4, 0x6e, 0xcb, 0x98, 0x0a, 0xf9, 0x81, 0xbe, 0x7c, 0xc5, 0x2e, 0xec, 0xf9, 0x8b, 0xcd, 0x16, 0x59, 0x3d, 0x81, 0x8b, 0x4d, 0xa9, 0x57, 0x77, 0x15, 0x63, 0x69, 0x17, 0x22, 0xc6, 0xd5, 0xce, 0x39, 0x1a, 0xec, 0xda, 0x46, 0x41, 0x74, 0x38, 0x7b, 0xe3, 0x9a, 0x04, 0x91, 0x6f, 0x6e, 0x5b, 0x2d, 0xfc, 0xf8, 0x6a, 0x99, 0x7a, 0x49, 0x2e, 0xb3, 0xf3, 0xde, 0xde, 0x4e, 0xc6, 0x7b, 0x95, 0xc5, 0x83, 0x46, 0xe1, 0x62, 0x85, 0x37, 0xf9, 0x5f, 0xba, 0xe1, 0x55, 0x50, 0x32, 0xb3, 0x0d, 0xfd, 0xf6, 0xcf, 0xed, 0x03, 0x99, 0x40, 0x4a, 0x94, 0x4c, 0xa3, 0x5e, 0x19, 0x5f, 0xbc, 0x85, 0xdb, 0xce, 0xef, 0x67, 0xbc, 0xa6, 0x4f, 0xc6, 0x01, 0xbe, 0xc0, 0xb5, 0xc7, 0x7b, 0x2d, 0x1b, 0x53, 0x6c, 0x9e, 0xa5, 0xc9, 0x9c, 0x96, 0x57, 0x9a, 0xd0, 0x61, 0xa2, 0x2c, 0x24, 0xec, 0xb0, 0xaa, 0x99, 0x35, 0xa4, 0x70, 0x6e, 0x9b, 0x1b, 0xe1, 0xc4, 0xaf, 0x02, 0xad, 0x23, 0x13, 0x65, 0x14, 0xf4, 0xc0, 0xb8, 0x09, 0xfe, 0x37, 0x1b, 0x65, 0x65, 0x6f, 0x98, 0xb3, 0x42, 0x5b, 0x6c, 0x6e, 0xec, 0x25, 0xac, 0xd5, 0x81, 0xf7, 0x50, 0x5b, 0x39, 0xf2, 0xea, 0x71, 0x40, 0x5f, 0x5d, 0xcf, 0x4f, 0x7a, 0xd0, 0xa0, 0xfd, 0x0a, 0x99, 0x39, 0xc2, 0xb9, 0xb0, 0xbf, 0x20, 0x4f, 0xfc, 0x1f, 0x84, 0xbc, 0x78, 0x1b, 0xb2, 0xae, 0x0c, 0xa1, 0xf7, 0x83, 0x30, 0x56, 0xde, 0x82, 0xaa, 0x5d, 0xe5, 0x4a, 0xa1, 0x48, 0xe1, 0xb8, 0xb1, 0xd1, 0x23, 0xbd, 0xa8, 0x25, 0xc2, 0x3e, 0x74, 0x54, 0xfc, 0x55, 0x4d, 0xc8, 0x31, 0x9c, 0x59, 0xe6, 0x45, 0x6c, 0xce, 0x90, 0x24, 0x13, 0xf1, 0xed, 0x82, 0x0f, 0xa8, 0x35, 0x9a, 0xb7, 0x5a, 0x78, 0xd9, 0x62, 0x28, 0xed, 0x47, 0xd6, 0x56, 0x4a, 0xf4, 0x04, 0x96, 0xc9, 0x35, 0x21, 0xd8, 0xc7, 0xf4, 0xb3, 0x8c, 0x7c, 0x3b, 0x1c, 0xb7, 0xdb, 0x36, 0x63, 0x79, 0xe5, 0x89, 0xc6, 0x04, 0xe4, 0x4d, 0xf0, 0x50, 0xe5, 0x32, 0xc4, 0xa3, 0x09, 0x6e, 0xc3, 0x99, 0x39, 0x31, 0xab, 0x93, 0x66, 0x48, 0x4d, 0x96, 0xcc, 0x4a, 0xcb, 0x4b, 0xd7, 0x00, 0x4f, 0xa7, 0xad, 0xbb, 0x10, 0x14, 0xdd, 0x8f, 0x63, 0x23, 0x07, 0x2b, 0x2b, 0xad, 0x0c, 0x6d, 0xf1, 0x3b, 0x46, 0xc7, 0xf3, 0x6b, 0x24, 0x1c, 0x9c, 0x22, 0x17, 0xee, 0xfb, 0xb0, 0xbe, 0x27, 0x07, 0x06, 0x2f, 0x7b, 0x0c, 0x52, 0x0e, 0x30, 0x6d, 0xcd, 0x7c, 0x58, 0x86, 0x76, 0xff, 0x51, 0x5d, 0x97, 0x3f, 0x45, 0xeb, 0xf8, 0x24, 0x98, 0x4c, 0x04, 0x2b, 0x83, 0xec, 0x40, 0x98, 0x7f, 0x4d, 0xc0, 0xcf, 0x47, 0xff, 0x27, 0xa1, 0xcc, 0x09, 0x78, 0xf9, 0x9c, 0x20, 0xb7, 0x58, 0x1c, 0xc1, 0xbb, 0x87, 0x71, 0x3d, 0x4d, 0xbc, 0x51, 0x04, 0x75, 0xea, 0x31, 0x50, 0xf7, 0xaf, 0xfb, 0x4b, 0x05, 0x16, 0xa7, 0xea, 0xeb, 0x04, 0xfb, 0x97, 0xd3, 0xfa, 0x35, 0x8c, 0xd3, 0x65, 0xb6, 0x42, 0x3c, 0x05, 0x27, 0x04, 0x1b, 0xe8, 0x08, 0xc3, 0x8e, 0xe5, 0x8d, 0xd3, 0x9b, 0xdc, 0xe3, 0xda, 0x41, 0x37, 0x5f, 0x1e, 0xf2, 0x75, 0xa4, 0xcc, 0x27, 0xb4, 0x2b, 0xcc, 0xfb, 0x84, 0xa8, 0x3b, 0x87, 0x16, 0xa2, 0x31, 0xcb, 0x3b, 0xbf, 0xae, 0xea, 0x17, 0xed, 0xa9, 0x41, 0x37, 0x33, 0xb5, 0xaf, 0x4a, 0x71, 0x45, 0x07, 0x5f, 0x5c, 0x6d, 0x41, 0x41, 0x44, 0x4e, 0xaf, 0xa5, 0x4a, 0x32, 0x51, 0x56, 0x78, 0xb6, 0xcc, 0x75, 0x35, 0x22, 0x4e, 0x2e, 0x5b, 0x61, 0xb8, 0x2f, 0xd4, 0xb7, 0xab, 0xb0, 0xfe, 0x49, 0x46, 0x34, 0x37, 0xae, 0xd5, 0xc5, 0xe5, 0xde, 0xd4, 0x96, 0x3c, 0x71, 0xac, 0x5a, 0x0e, 0x7c, 0xe2, 0x24, 0x6f, 0xb2, 0xaf, 0x10, 0x01, 0x2c, 0x72, 0x69, 0x56, 0xc2, 0xa4, 0xce, 0x6e, 0xd6, 0x66, 0x4d, 0xeb, 0xde, 0x2f, 0x2f, 0x0e, 0x93, 0xed, 0x37, 0x2c, 0xd8, 0x89, 0x8e, 0x18, 0xe5, 0x27, 0x07, 0xbe, 0xdd, 0x60, 0x3a, 0x54, 0x6b, 0xb5, 0x7d, 0x9c, 0xc6, 0x7e, 0xb0, 0x80, 0x40, 0x86, 0x89, 0xc0, 0xe3, 0xf8, 0x75, 0xb1, 0x07, 0x38, 0x26, 0xde, 0x6c, 0x6e, 0xee, 0x5a, 0x1c, 0x1d, 0x55, 0x81, 0x53, 0x1d, 0x78, 0x91, 0x75, 0x23, 0xf0, 0x32, 0x5a, 0xc5, 0xe6, 0x08, 0x8e, 0x77, 0x77, 0xe8, 0x4e, 0x08, 0xf4, 0x75, 0x61, 0x90, 0xd9, 0xa6, 0xff, 0xfa, 0x9e, 0xfb, 0x60, 0x1f, 0xdf, 0x28, 0x72, 0xee, 0x24, 0xbf, 0xf1, 0x96, 0x68, 0x5e, 0x4f, 0xa5, 0x5e, 0xf1, 0x8f, 0x63, 0x6a, 0x39, 0xa0, 0x40, 0xb1, 0x43, 0x0a, 0x6c, 0x1d, 0xdf, 0x7e, 0xe6, 0x38, 0x02, 0xaa, 0x78, 0x9f, 0xb9, 0x32, 0x11, 0xda, 0xec, 0xdf, 0x22, 0x00, 0x5e, 0xba, 0x6c, 0xb1, 0xda, 0x31, 0x3e, 0x19, 0x34, 0x85, 0xc8, 0x32, 0xfa, 0x04, 0x57, 0x1a, 0xa3, 0xaf, 0xcc, 0xa9, 0x39, 0xb0, 0x4c, 0x47, 0xc9, 0x4f, 0x66, 0xe1, 0x4b, 0xdc, 0x5e, 0x6f, 0xb9, 0x1c, 0x25, 0x70, 0x25, 0x35, 0x98, 0xf9, 0xfd, 0x20, 0x8c, 0xf1, 0x8f, 0x2e, 0x14, 0x6e, 0x11, 0xa4, 0x37, 0x51, 0x12, 0x09, 0x53, 0xe2, 0x4e, 0x3b, 0x36, 0x78, 0xfa, 0x52, 0xaa, 0x06, 0x6b, 0x0c, 0x95, 0x81, 0xa2, 0x76, 0x83, 0xa2, 0xa6, 0x02, 0xcb, 0x2c, 0xc4, 0x8e, 0x37, 0x9c, 0x1c, 0x36, 0x36, 0xea, 0xf8, 0x04, 0xd6, 0xc2, 0xbe, 0x20, 0x4d, 0x37, 0xcc, 0x32, 0x78, 0xff, 0x02, 0x62, 0x7b, 0x59, 0xcc, 0xb4, 0x4b, 0x98, 0x34, 0xc4, 0xea, 0xb3, 0xc4, 0xb1, 0x06, 0xbe, 0xa1, 0x27, 0x15, 0x95, 0xf8, 0x45, 0x0a, 0xcc, 0x45, 0x97, 0x2c, 0xed, 0x12, 0xba, 0x64, 0xbc, 0x3f, 0xce, 0x76, 0x14, 0xce, 0x1b, 0xc1, 0x37, 0xdf, 0xc7, 0x3a, 0xe4, 0x1c, 0x22, 0xeb, 0x99, 0x37, 0x07, 0x32, 0xff, 0xde, 0xd3, 0xe7, 0x28, 0x13, 0x1c, 0x91, 0xa7, 0x16, 0xce, 0xcd, 0x92, 0x32, 0x30, 0x9f, 0xa1, 0xad, 0xe5, 0x3e, 0xa9, 0x51, 0xcb, 0xef, 0x58, 0xe3, 0x35, 0x21, 0xf3, 0x27, 0xb5, 0x15, 0x45, 0x6c, 0xf6, 0xa0, 0x16, 0x32, 0x85, 0x63, 0x01, 0x9a, 0x88, 0x98, 0xb6, 0x01, 0xaf, 0x28, 0xca, 0x12, 0xc0, 0x8c, 0x4a, 0xf7, 0xf9, 0xc2, 0x02, 0xda, 0x12, 0x24, 0x23, 0xf6, 0xad, 0xd7, 0x39, 0xdd, 0xc6, 0x2b, 0x3a, 0x5d, 0xd0, 0x3f, 0x6e, 0xd2, 0xc5, 0x19, 0xc6, 0x0d, 0x51, 0xf8, 0x2f, 0xf3, 0xec, 0x43, 0xc9, 0x6b, 0x53, 0x8a, 0x2c, 0x16, 0x47, 0x26, 0x2c, 0xf4, 0xd8, 0x22, 0xb5, 0xda, 0x90, 0x64, 0xcd, 0xd1, 0xd0, 0x38, 0xb2, 0xeb, 0x80, 0x6a, 0x0a, 0x7a, 0x96, 0x2a, 0xec, 0xc4, 0xca, 0x28, 0xb1, 0x53, 0xf1, 0xa8, 0xdc, 0x8b, 0xac, 0x15, 0xbe, 0xef, 0x90, 0x1a, 0x70, 0x4a, 0xf1, 0xe8, 0x68, 0x8c, 0xf7, 0xcd, 0x9a, 0x3d, 0xe8, 0x3a, 0x6f, 0x81, 0x67, 0xb1, 0x9d, 0x3a, 0x52, 0xa4, 0xe2, 0xab, 0x26, 0x9d, 0x1d, 0x51, 0x02, 0x5e, 0x02, 0x8e, 0x74, 0x41, 0xc2, 0x9a, 0xdc, 0xb2, 0x3b, 0xee, 0x1b, 0xe3, 0x81, 0x11, 0xae, 0xdf, 0xaf, 0x03, 0x1d, 0x7f, 0xa1, 0x13, 0x9e, 0x96, 0xf2, 0x3a, 0x89, 0xdf, 0xf0, 0xe9, 0xa2, 0x46, 0x12, 0x12, 0x26, 0x07, 0xaa, 0xf3, 0xd6, 0x9c, 0xd3, 0x1c, 0x97, 0x4a, 0xe0, 0xa9, 0x16, 0xfd, 0x62, 0x7d, 0x92, 0x08, 0x49, 0x81, 0x5c, 0x98, 0x41, 0xaa, 0x57, 0x37, 0xb4, 0x5f, 0xfa, 0x3b, 0xd1, 0xe9, 0xb1, 0x90, 0xc8, 0xf3, 0x0d, 0x38, 0xbc, 0xf7, 0x6d, 0xd4, 0x27, 0x93, 0x94, 0xa9, 0x41, 0xfe, 0x92, 0xa9, 0x3b, 0x5c, 0x2d, 0xaf, 0xb5, 0x68, 0xcc, 0x02, 0x3a, 0x15, 0xb9, 0x80, 0x3e, 0x3d, 0xb6, 0x0d, 0xfe, 0x3a, 0xcc, 0x93, 0x9b, 0x4f, 0xec, 0x6c, 0x5a, 0x8c, 0xd0, 0xb5, 0x63, 0x70, 0x0b, 0x4e, 0x9e, 0x96, 0x41, 0x00, 0xe7, 0xcb, 0x90, 0x53, 0xb2, 0x51, 0x73, 0xdc, 0x2b, 0x82, 0x81, 0xdb, 0x9e, 0x58, 0x9d, 0x87, 0xaf, 0x55, 0xc8, 0x56, 0xfa, 0x04, 0xa7, 0xba, 0xef, 0x38, 0x9a, 0x52, 0x27, 0x65, 0xd0, 0xd0, 0x74, 0xda, 0x70, 0x60, 0x4b, 0x7d, 0x9d, 0x25, 0xce, 0x25, 0x19, 0x45, 0x86, 0x5a, 0x3d, 0x2a, 0x56, 0xfd, 0x1e, 0x30, 0xd8, 0x6a, 0xce, 0x45, 0x66, 0x43, 0x3f, 0xcf, 0x99, 0xd7, 0xdc, 0xfd, 0x8c, 0x97, 0xb3, 0x3f, 0x03, 0x73, 0x7c, 0xe3, 0x56, 0x11, 0x39, 0xb1, 0xf6, 0xdf, 0xfc, 0x3b, 0x17, 0x84, 0x80, 0xbc, 0x08, 0xd4, 0xf6, 0xa4, 0xfc, 0xc1, 0x53, 0x5c, 0xce, 0xbb, 0x1d, 0xff, 0x76, 0x90, 0x64, 0x97, 0xde, 0xd7, 0x43, 0xe2, 0xab, 0x15, 0x4e, 0xd0, 0xc0, 0xe5, 0xb4, 0xae, 0x25, 0xdf, 0x9f, 0x96, 0x3f, 0x3d, 0xb9, 0x8c, 0xf4, 0x84, 0x36, 0x0a, 0x10, 0x80, 0x1c, 0x30, 0xde, 0x4f, 0xbc, 0x01, 0x24, 0x0b, 0x95, 0xdd, 0x1d, 0x76, 0x65, 0x61, 0x46, 0xa6, 0x4e, 0x82, 0x34, 0x82, 0x53, 0x8e, 0xb8, 0x4c, 0xc1, 0xe7, 0xac, 0x1c, 0x93, 0x0b, 0x61, 0xe5, 0x8c, 0x71, 0x91, 0x44, 0x45, 0xad, 0x0e, 0xaa, 0xeb, 0xa2, 0x42, 0x41, 0x31, 0xfc, 0x66, 0xfa, 0x8a, 0x10, 0xf9, 0x88, 0x61, 0xce, 0xc0, 0xdc, 0xbb, 0x61, 0xfe, 0xdb, 0x1a, 0xee, 0x2f, 0x49, 0x2b, 0x27, 0x5b, 0x91, 0x20, 0x53, 0xe0, 0xd7, 0xda, 0x08, 0x94, 0x8b, 0xf5, 0x37, 0x31, 0xc9, 0xa6, 0xc4, 0x58, 0x3e, 0x98, 0xa5, 0x42, 0x41, 0xcc, 0xeb, 0x82, 0xbe, 0x32, 0x78, 0x53, 0xf7, 0xe9, 0x1a, 0x53, 0xa9, 0x61, 0x2a, 0x2d, 0x8a, 0x90, 0xcb, 0x7f, 0x40, 0x55, 0x39, 0x17, 0x70, 0x7c, 0x47, 0x92, 0x8c, 0xde, 0xfd, 0x7f, 0xae, 0x74, 0xc0, 0xb6, 0x19, 0x39, 0x21, 0x5b, 0x07, 0x97, 0xc7, 0xc1, 0xce, 0x36, 0x33, 0x3d, 0xe1, 0x92, 0x89, 0x09, 0xe0, 0x34, 0xfb, 0xa6, 0x00, 0xcf, 0x13, 0x57, 0x74, 0x82, 0x30, 0x1f, 0xe4, 0x4a, 0x66, 0x99, 0xc2, 0xc9, 0x16, 0x53, 0xa9, 0xb6, 0x3e, 0x4d, 0x8e, 0x02, 0x94, 0xa1, 0x05, 0x60, 0x39, 0x46, 0xcc, 0x73, 0x9f, 0x87, 0x87, 0xf9, 0x60, 0x77, 0x20, 0x0e, 0x00, 0xd4, 0xeb, 0xe9, 0x8f, 0x5c, 0xa0, 0x5c, 0x87, 0x84, 0xc9, 0xee, 0x9c, 0x68, 0x54, 0xd5, 0xff, 0xca, 0xd3, 0xcb, 0xe5, 0x97, 0x41, 0x47, 0x62, 0x6a, 0x78, 0x1b, 0xc2, 0x24, 0xca, 0x83, 0x4d, 0x08, 0x85, 0x20, 0xe7, 0x04, 0x15, 0xd5, 0xca, 0x08, 0x49, 0x05, 0x6f, 0x2c, 0x74, 0xc6, 0x5b, 0xc2, 0x1c, 0x98, 0xeb, 0x23, 0x77, 0xc1, 0x82, 0x1e, 0xdb, 0x44, 0x42, 0xee, 0x47, 0x35, 0x55, 0x25, 0xe0, 0xfa, 0x4e, 0x21, 0x5a, 0xf9, 0xf6, 0xc0, 0x46, 0x29, 0xe1, 0xc4, 0x5e, 0x7a, 0x1b, 0x6c, 0xed, 0x81, 0x55, 0x12, 0xe9, 0x6c, 0xac, 0xf2, 0x55, 0x72, 0xbf, 0xf9, 0x0c, 0x4c, 0x9c, 0x00, 0xe5, 0x81, 0xe1, 0x13, 0xdb, 0x5b, 0xdd, 0x9c, 0x67, 0xff, 0x16, 0x14, 0x81, 0x49, 0xfb, 0x3d, 0x40, 0xa0, 0x28, 0x5c, 0xb5, 0xd0, 0xbc, 0x55, 0x01, 0xd8, 0x31, 0x08, 0x3b, 0xd7, 0x4b, 0x09, 0x31, 0x2b, 0x2a, 0x02, 0x5a, 0x95, 0x11, 0x36, 0xbb, 0x78, 0x1e, 0xc9, 0x0e, 0x4e, 0x4a, 0xdd, 0x66, 0x2c, 0xa6, 0x3d, 0x1e, 0x80, 0x36, 0xb9, 0x6c, 0x02, 0x54, 0x0b, 0x14, 0xbc, 0x68, 0x4f, 0x4e, 0xae, 0x29, 0x74, 0x1a, 0x7a, 0x09, 0x63, 0x87, 0x6e, 0xef, 0x46, 0x46, 0xc0, 0x3e, 0x28, 0xf8, 0xc8, 0x9e, 0xae, 0xd2, 0x88, 0x4b, 0x91, 0x00, 0x95, 0x51, 0xdc, 0xbd, 0x76, 0xbe, 0x64, 0x0a, 0xe1, 0x19, 0x93, 0xeb, 0xde, 0xfe, 0xd6, 0x53, 0xec, 0x1d, 0x36, 0x50, 0x05, 0x9e, 0x5c, 0x2d, 0x58, 0x89, 0x33, 0x80, 0x43, 0x21, 0xa3, 0x39, 0x90, 0x5c, 0x51, 0x72, 0x4c, 0xa8, 0xec, 0x06, 0xcf, 0x99, 0x35, 0xb2, 0x8c, 0x02, 0x5c, 0x0d, 0x21, 0x55, 0x0b, 0x4f, 0x29, 0xb3, 0xf7, 0x2b, 0x19, 0x17, 0x82, 0x67, 0xb1, 0x63, 0xf6, 0xbf, 0x9d, 0x0a, 0x4e, 0x6d, 0x48, 0x7b, 0x28, 0x4b, 0x79, 0x85, 0x34, 0xe2, 0xeb, 0xdb, 0x1d, 0x55, 0xa0, 0x4e, 0x27, 0x0a, 0xf1, 0xc7, 0x92, 0x79, 0x82, 0x81, 0xbf, 0xfa, 0x60, 0x9d, 0x16, 0x2e, 0xdf, 0x07, 0xbe, 0x37, 0x94, 0xd3, 0xb0, 0xbf, 0xc3, 0x26, 0xae, 0x77, 0xc7, 0x70, 0x4a, 0x60, 0x4d, 0x61, 0x07, 0x83, 0x8a, 0x11, 0xad, 0xd5, 0xd1, 0x3a, 0xb8, 0xb4, 0x4f, 0x0c, 0xcc, 0x05, 0xa0, 0xaf, 0xd6, 0xe7, 0x77, 0x93, 0xd9, 0x4f, 0x20, 0xe6, 0xc7, 0x4f, 0x82, 0x7f, 0x44, 0xa4, 0xf7, 0x65, 0x40, 0x14, 0x11, 0xac, 0xda, 0x57, 0xa5, 0x6e, 0xdf, 0x9f, 0xa7, 0xb6, 0x34, 0x4f, 0x21, 0x1e, 0x07, 0x8a, 0x0d, 0x06, 0x9a, 0xe4, 0xbb, 0xbd, 0x68, 0xc2, 0xf9, 0xd9, 0x10, 0xbe, 0x21, 0x08, 0x3e, 0xaf, 0xe0, 0xe7, 0x1d, 0xfe, 0x15, 0x16, 0x76, 0x1d, 0x53, 0xcf, 0xb8, 0xf5, 0xd9, 0x59, 0x40, 0xe0, 0x0a, 0x2c, 0x36, 0x4f, 0x11, 0xa4, 0x18, 0xe9, 0x87, 0xee, 0xf2, 0xa7, 0x2a, 0xd4, 0xef, 0xcf, 0x8d, 0xd5, 0xe6, 0x78, 0x42, 0x70, 0x49, 0xd4, 0x7c, 0x26, 0xcf, 0x0c, 0x33, 0xc1, 0xf4, 0x4c, 0x35, 0x39, 0x8f, 0x8e, 0xe7, 0x8a, 0xf7, 0xa0, 0x6a, 0xe5, 0x5b, 0x2f, 0x34, 0x0c, 0x80, 0xbb, 0x8c, 0xd4, 0xa8, 0x44, 0x5e, 0xc4, 0x1e, 0x5d, 0xd9, 0x12, 0x02, 0x9b, 0x95, 0x25, 0xe4, 0xa0, 0x02, 0xce, 0xe6, 0xcb, 0x75, 0xee, 0xe4, 0xd3, 0xa6, 0x35, 0x14, 0x25, 0x07, 0x7d, 0x7a, 0xda, 0x58, 0xd5, 0x97, 0x68, 0x5a, 0xf4, 0x00, 0x11, 0xa0, 0xc7, 0x74, 0x69, 0xdf, 0x83, 0xab, 0xb4, 0xd4, 0xbb, 0xb3, 0x7d, 0xc8, 0xa2, 0x9a, 0xcf, 0x1f, 0x02, 0x4e, 0xfa, 0x3f, 0x0b, 0xcc, 0x7e, 0xba, 0x74, 0x73, 0xa2, 0x58, 0x40, 0x9b, 0x9a, 0xd2, 0xd5, 0x5f, 0x63, 0x88, 0x19, 0xf4, 0x11, 0x1f, 0xa6, 0x7c, 0x23, 0xca, 0xc2, 0x2e, 0xeb, 0x99, 0x8f, 0xf4, 0x16, 0xda, 0x60, 0xd9, 0x6b, 0xab, 0x9e, 0x0a, 0x7a, 0x5f, 0x78, 0xe3, 0x9d, 0x7f, 0x72, 0xc7, 0xe6, 0x82, 0x6d, 0x6e, 0x67, 0xb1, 0x76, 0x41, 0x2a, 0x51, 0x9c, 0xb5, 0xff, 0x7a, 0x25, 0x1c, 0xa0, 0x9e, 0x47, 0x12, 0xdf, 0x6c, 0x39, 0x31, 0x57, 0x92, 0x6e, 0xf7, 0x8a, 0x04, 0xe7, 0x28, 0x3a, 0xf7, 0x38, 0x3a, 0xb3, 0x4b, 0x8f, 0xf6, 0xfd, 0x12, 0x20, 0xf8, 0x5b, 0x10, 0xd6, 0x42, 0x1d, 0x57, 0xfa, 0x6f, 0xc8, 0xa0, 0x44, 0x9b, 0xee, 0x0d, 0xf8, 0xe5, 0xa2, 0x92, 0x14, 0x21, 0x06, 0x63, 0x11, 0x4e, 0xdd, 0x0f, 0x87, 0x81, 0x11, 0x91, 0xd9, 0x0d, 0xe8, 0xb0, 0xe3, 0xda, 0x25, 0x5a, 0x77, 0x88, 0xb0, 0x67, 0xea, 0x57, 0x70, 0x9b, 0x81, 0x03, 0x96, 0x76, 0x61, 0x52, 0x73, 0x3b, 0x03, 0x82, 0x77, 0x2a, 0xec, 0xa2, 0x4b, 0xfd, 0xf8, 0x2d, 0x12, 0x47, 0x06, 0x53, 0xb3, 0x85, 0xcd, 0x63, 0xbc, 0x4a, 0x69, 0xe4, 0x54, 0x4f, 0x55, 0xa1, 0x8d, 0x7a, 0x21, 0xab, 0x83, 0xc0, 0x30, 0x79, 0xbd, 0xc6, 0xc4, 0x94, 0x9f, 0x7a, 0xb3, 0xcf, 0xdd, 0x5c, 0x3d, 0x37, 0x97, 0xdf, 0x99, 0xac, 0xe9, 0x75, 0xbf, 0x95, 0x07, 0x0a, 0x56, 0xbb, 0x09, 0x0c, 0x56, 0x9d, 0xad, 0x07, 0xc8, 0x3e, 0xca, 0x5e, 0x31, 0xd0, 0xc9, 0x78, 0x3b, 0x0d, 0x81, 0x6e, 0x72, 0x2a, 0x29, 0x7a, 0x2a, 0x16, 0x70, 0xe6, 0x3c, 0x5c, 0xb9, 0xb3, 0x6d, 0x72, 0x88, 0xe4, 0xb6, 0x00, 0xb3, 0xf1, 0x88, 0xab, 0xf5, 0x97, 0xb4, 0xaf, 0x03, 0xd2, 0x54, 0x97, 0x82, 0xce, 0xe9, 0xaf, 0x52, 0xf6, 0x72, 0xf5, 0x4b, 0x74, 0xfb, 0x63, 0xf3, 0x9d, 0x56, 0x51, 0x01, 0xc1, 0xa0, 0x45, 0x0b, 0x85, 0xbc, 0x53, 0x3e, 0x75, 0x8a, 0xa6, 0x1c, 0x69, 0x1a, 0x31, 0x99, 0x66, 0x10, 0x41, 0x1e, 0xbe, 0x32, 0x98, 0x25, 0x6d, 0x63, 0x74, 0x47, 0xe6, 0xaf, 0x58, 0x76, 0xf4, 0x7f, 0x33, 0x12, 0x7e, 0x23, 0x83, 0xd9, 0x9d, 0x09, 0x60, 0xe5, 0x75, 0x94, 0xa5, 0x66, 0xe9, 0x72, 0x01, 0x5f, 0xe8, 0x1e, 0xef, 0x48, 0x9d, 0x2d, 0x2e, 0xc8, 0xda, 0x77, 0xb7, 0xec, 0x43, 0x5e, 0x0e, 0x32, 0x73, 0xd4, 0x4b, 0x8b, 0x47, 0x98, 0x34, 0x47, 0x66, 0xf1, 0x0c, 0xf7, 0xa0, 0xfe, 0x13, 0xe5, 0xfe, 0x7e, 0x52, 0x46, 0x57, 0xee, 0xd1, 0x70, 0xef, 0x9d, 0xfb, 0x4b, 0x9f, 0x51, 0xab, 0xb4, 0x23, 0x5c, 0x83, 0x52, 0x18, 0x69, 0xb8, 0x91, 0x0e, 0x77, 0x4d, 0x70, 0xf0, 0x14, 0x52, 0xa8, 0x6b, 0x0a, 0xe6, 0x00, 0xd5, 0x16, 0x63, 0x72, 0x2a, 0x84, 0xcc, 0x5c, 0x03, 0x46, 0x3b, 0xda, 0xdf, 0x90, 0x1c, 0x6b, 0xda, 0xc7, 0x4b, 0x29, 0x8c, 0x22, 0x39, 0xbf, 0xde, 0x05, 0x25, 0xa8, 0x5c, 0xb6, 0xfb, 0x32, 0xc0, 0x45, 0x66, 0xbc, 0xeb, 0xbb, 0xb7, 0x58, 0xe3, 0x40, 0x5b, 0x2a, 0x1f, 0x29, 0x57, 0xfd, 0x86, 0xd0, 0x7e, 0xd0, 0x11, 0x36, 0xb5, 0x20, 0x8b, 0x0c, 0xc7, 0x3c, 0x53, 0x33, 0x54, 0xee, 0xeb, 0x2d, 0x11, 0x64, 0xcf, 0xbe, 0x35, 0x87, 0xfe, 0x43, 0xcb, 0x26, 0x14, 0xf9, 0xe6, 0x53, 0x61, 0x9e, 0xf2, 0x02, 0xb1, 0xf7, 0x60, 0x98, 0x42, 0x77, 0x46, 0xb6, 0x58, 0xb0, 0xaf, 0xdb, 0x08, 0xae, 0x08, 0xbb, 0x3d, 0x45, 0x64, 0xa7, 0x8c, 0x6c, 0xe9, 0xcc, 0xa0, 0xe6, 0x88, 0xf1, 0x0f, 0x06, 0xb1, 0x23, 0x29, 0x97, 0x99, 0x17, 0x7a, 0xc3, 0xe6, 0xff, 0xcb, 0xf7, 0xdf, 0x4e, 0x49, 0xcd, 0x45, 0x21, 0x83, 0xe4, 0xf0, 0x64, 0x7c, 0x9a, 0xf8, 0x3c, 0x63, 0x5f, 0x92, 0x20, 0x1b, 0x01, 0xd8, 0x77, 0xd4, 0x03, 0x31, 0x48, 0x2a, 0x43, 0xe5, 0x96, 0xd3, 0x73, 0xfe, 0x19, 0x9b, 0x42, 0xe2, 0xc5, 0x59, 0x4d, 0x4b, 0x16, 0x35, 0x31, 0x65, 0x7b, 0x92, 0xeb, 0x1f, 0x59, 0xdc, 0x9c, 0x6b, 0xc3, 0x12, 0x49, 0xca, 0x4d, 0x8d, 0xb4, 0x49, 0xcb, 0xb6, 0x68, 0x05, 0xa8, 0xcd, 0x50, 0x1c, 0x2e, 0x79, 0xa5, 0xb7, 0xe3, 0xd9, 0x2f, 0x5c, 0x25, 0xf4, 0x4c, 0x7b, 0x0f, 0x86, 0xa3, 0x41, 0xaf, 0xe6, 0x44, 0x0e, 0xa2, 0x0a, 0xf8, 0x65, 0xec, 0x30, 0xc2, 0x45, 0x4c, 0xb4, 0x48, 0x7c, 0xda, 0xa8, 0xd5, 0x70, 0x29, 0x86, 0x7a, 0xdf, 0x5b, 0xb3, 0x51, 0x2e, 0x59, 0x0d, 0xdb, 0x44, 0x2b, 0xcc, 0xe3, 0xee, 0x6e, 0xab, 0xff, 0x6e, 0x47, 0xdf, 0x03, 0x1d, 0x90, 0xda, 0x90, 0xf7, 0xad, 0xf3, 0xa6, 0x68, 0x3a, 0x8c, 0xfb, 0x4b, 0x4d, 0x66, 0x6c, 0x10, 0x36, 0x20, 0x10, 0x34, 0x77, 0x7d, 0x33, 0x62, 0x13, 0x34, 0x73, 0x7e, 0x61, 0x24, 0x3c, 0x6c, 0xc3, 0xd1, 0x5b, 0x5e, 0xc9, 0x37, 0xa0, 0x11, 0xff, 0x46, 0x75, 0x62, 0x17, 0x92, 0x69, 0xaf, 0x73, 0x08, 0xb9, 0x0d, 0x07, 0x13, 0xd5, 0x04, 0xd4, 0x2c, 0xa7, 0x33, 0x4d, 0x08, 0x82, 0x64, 0x5f, 0xb8, 0xc6, 0xb6, 0x27, 0xbb, 0x5f, 0x9a, 0x89, 0x9d, 0x33, 0x9f, 0x3b, 0xff, 0xf2, 0xc3, 0x47, 0xb9, 0x5e, 0xd6, 0x2f, 0x43, 0x8d, 0x92, 0xe4, 0xf5, 0xcf, 0xa4, 0x70, 0xba, 0xaf, 0x40, 0xd1, 0x35, 0xb6, 0x7d, 0xdb, 0xf9, 0x0d, 0x61, 0x58, 0x6d, 0x2b, 0xbe, 0x30, 0xad, 0xd1, 0xbf, 0x44, 0x34, 0xa3, 0xb9, 0x18, 0xe9, 0x03, 0xfa, 0xd6, 0xde, 0xf9, 0xe2, 0x43, 0x88, 0xf6, 0x5e, 0x18, 0xb6, 0x19, 0xa0, 0xdb, 0xec, 0xd9, 0xbb, 0xe7, 0x6d, 0xc9, 0x7f, 0xac, 0x12, 0x1b, 0x32, 0xb4, 0x70, 0xe9, 0x57, 0xa7, 0xc6, 0x82, 0x03, 0x09, 0xb5, 0xb3, 0x15, 0x25, 0xe9, 0x8e, 0xe9, 0xb3, 0xbf, 0x1a, 0x5c, 0x2d, 0x5f, 0x3c, 0x6e, 0x55, 0x74, 0x00, 0x84, 0x42, 0x86, 0x11, 0x8f, 0x11, 0x34, 0xe1, 0x61, 0x5f, 0xba, 0x9f, 0x06, 0x37, 0xa0, 0x8c, 0x4d, 0x89, 0xf1, 0x90, 0x5c, 0x3f, 0x0b, 0xfc, 0xf5, 0xa9, 0x42, 0x5b, 0xcf, 0xf3, 0x11, 0x5e, 0x81, 0x07, 0x10, 0x63, 0x9e, 0x8f, 0x83, 0x0a, 0x0f, 0x25, 0x20, 0x6f, 0x45, 0x46, 0xb3, 0x2e, 0xe0, 0x5e, 0x6a, 0xe8, 0x33, 0x21, 0xeb, 0xf1, 0xbb, 0x4f, 0xaa, 0xc8, 0xd8, 0xa6, 0xc7, 0xd1, 0xec, 0x73, 0x91, 0x1a, 0xc3, 0x66, 0x03, 0xc4, 0x7d, 0xab, 0x31, 0x3b, 0x57, 0xf4, 0x5b, 0xf8, 0x90, 0x7c, 0xec, 0x95, 0xef, 0xa7, 0x6e, 0x88, 0x51, 0xdb, 0x7c, 0xa0, 0xb0, 0xcf, 0xbe, 0x11, 0x9c, 0xcd, 0x03, 0x35, 0x52, 0xbd, 0x95, 0xb2, 0x98, 0xf1, 0x4f, 0xe8, 0xcb, 0x09, 0x0b, 0xaa, 0x1d, 0xa6, 0x54, 0xeb, 0x52, 0x54, 0x99, 0xe4, 0x86, 0x46, 0xdf, 0x45, 0xe0, 0x13, 0x20, 0x73, 0xe8, 0x07, 0x61, 0xdf, 0x12, 0xaa, 0x69, 0xa9, 0xf4, 0x1d, 0x9f, 0x6d, 0x20, 0x22, 0xb4, 0x62, 0xeb, 0x68, 0x64, 0xfb, 0xa8, 0x57, 0x94, 0xbe, 0x7f, 0xf3, 0x89, 0x40, 0xb8, 0x95, 0x17, 0x17, 0x80, 0xf7, 0x68, 0xa4, 0x16, 0xe6, 0x4e, 0x5a, 0xf9, 0xeb, 0xdd, 0x76, 0xe6, 0x29, 0xc7, 0xfb, 0x45, 0xb0, 0x7a, 0xeb, 0xc8, 0xf2, 0x6c, 0x2a, 0x94, 0x1e, 0xb6, 0x08, 0x9e, 0x71, 0x3d, 0x1a, 0x99, 0x6b, 0x07, 0xaf, 0x5f, 0xe9, 0x01, 0x4b, 0xd7, 0xd0, 0x5f, 0x7f, 0xac, 0x5b, 0x10, 0x12, 0xac, 0x79, 0x89, 0x20, 0x4e, 0xc8, 0xdc, 0xe6, 0x40, 0x7b, 0x5a, 0x21, 0xe8, 0x06, 0x0b, 0xf0, 0x72, 0xaa, 0x34, 0x38, 0x4d, 0x2f, 0xc6, 0xae, 0x35, 0xb4, 0x04, 0xa5, 0x8f, 0x0a, 0x4e, 0xd3, 0x4c, 0x17, 0x4d, 0x70, 0x49, 0x62, 0x92, 0x95, 0xa6, 0xfb, 0x32, 0x70, 0xb1, 0x0d, 0xe8, 0x27, 0xaf, 0xee, 0xbf, 0xcb, 0x16, 0x38, 0x7c, 0x81, 0x8e, 0xc4, 0x6c, 0xcb, 0xe9, 0xf5, 0x64, 0xdd, 0xb4, 0x79, 0x4c, 0x0e, 0x49, 0x06, 0x0b, 0xcd, 0xa3, 0x62, 0x7f, 0x3a, 0xde, 0xdb, 0x4b, 0x76, 0xed, 0x4a, 0xe7, 0xe6, 0x4b, 0x29, 0x20, 0x17, 0xc7, 0x70, 0x99, 0x3d, 0xde, 0x3b, 0x23, 0x52, 0xc2, 0x3e, 0x4c, 0x1b, 0xfe, 0xf9, 0x42, 0xd3, 0x92, 0xa4, 0xc8, 0xae, 0x72, 0xf2, 0x9e, 0xab, 0x4b, 0x0e, 0xb0, 0xda, 0x68, 0xc6, 0xba, 0xed, 0x47, 0x0f, 0x81, 0xca, 0x5b, 0x24, 0xa9, 0xd3, 0x39, 0x62, 0xea, 0x33, 0x76, 0xac, 0xad, 0x2c, 0x79, 0x01, 0x87, 0x0e, 0x60, 0x19, 0x86, 0xde, 0x96, 0x92, 0x24, 0x23, 0x90, 0x3c, 0x3f, 0x98, 0xc0, 0xd7, 0x3e, 0xde, 0xc0, 0x3b, 0x18, 0xbb, 0x53, 0x95, 0xc5, 0xf9, 0x17, 0xf5, 0x76, 0x56, 0x80, 0x70, 0x89, 0x26, 0x94, 0x8b, 0xfd, 0x7e, 0xa3, 0xdd, 0x96, 0x16, 0x43, 0x06, 0xfc, 0x14, 0x19, 0x64, 0x38, 0xcf, 0x95, 0x5f, 0xad, 0x59, 0xb4, 0xeb, 0xa9, 0xae, 0x39, 0xef, 0x33, 0x6b, 0x8e, 0x14, 0xe6, 0x8d, 0x4f, 0x94, 0x53, 0xb5, 0xd8, 0xd9, 0x43, 0x24, 0x2a, 0x64, 0xd0, 0x28, 0x04, 0x44, 0xeb, 0x74, 0x48, 0x09, 0x64, 0x33, 0xf1, 0x44, 0x2d, 0x2d, 0xf4, 0xc9, 0xbd, 0x50, 0xf3, 0x69, 0x6d, 0xb5, 0x99, 0xce, 0x56, 0x0e, 0xc9, 0x3f, 0x65, 0x16, 0xbc, 0x7a, 0xeb, 0x0b, 0xc6, 0x88, 0xc7, 0x8f, 0x3c, 0x2b, 0xbe, 0x13, 0x73, 0x43, 0x5d, 0x3a, 0xdf, 0x96, 0xb8, 0x82, 0x42, 0x4a, 0xf7, 0xf4, 0x60, 0x3b, 0xd3, 0x60, 0x38, 0x64, 0xa5, 0x97, 0xd6, 0xd8, 0x41, 0x8e, 0x53, 0x9c, 0x88, 0x13, 0x8a, 0x4e, 0x27, 0x85, 0x60, 0x60, 0x44, 0x2f, 0x59, 0x4a, 0x8e, 0xb2, 0x20, 0xc8, 0x8e, 0x6c, 0x7a, 0x45, 0x76, 0x26, 0x71, 0x09, 0x0a, 0xf3, 0x09, 0x04, 0x45, 0xab, 0x72, 0x58, 0x9d, 0xe5, 0x9f, 0x22, 0xef, 0x77, 0x4f, 0xce, 0xba, 0x84, 0x56, 0xbd, 0xa1, 0x08, 0xd1, 0x2e, 0x8b, 0x6e, 0x82, 0x12, 0x42, 0x5f, 0x9c, 0x5e, 0x1b, 0x00, 0xf0, 0x01, 0xfd, 0xdf, 0xb4, 0x32, 0x38, 0x28, 0x4e, 0x54, 0x87, 0xb0, 0xc6, 0xaf, 0x35, 0xaf, 0x79, 0x31, 0x32, 0xb1, 0x5b, 0xe4, 0xe1, 0xf5, 0xf7, 0x7a, 0x10, 0x7c, 0x49, 0xee, 0x71, 0x99, 0x75, 0x28, 0xfc, 0x0d, 0x60, 0xb8, 0xb2, 0xad, 0xc5, 0x9d, 0x83, 0xeb, 0x8c, 0x86, 0x2f, 0x7a, 0x87, 0xa8, 0x20, 0x66, 0x7f, 0x25, 0x52, 0xe4, 0xef, 0xae, 0xfa, 0xb3, 0xd1, 0x96, 0xc5, 0x92, 0xcc, 0xa0, 0xca, 0x6e, 0xb6, 0x67, 0x51, 0x79, 0x0e, 0xd1, 0x2b, 0x86, 0xf9, 0xdc, 0x05, 0xeb, 0x4d, 0xb9, 0xc5, 0xbf, 0x6e, 0xac, 0x23, 0xcf, 0xe4, 0x72, 0xd9, 0x97, 0x32, 0xbd, 0x8f, 0x4b, 0xd0, 0xe7, 0xae, 0x54, 0xb9, 0x8f, 0xea, 0x55, 0x57, 0x5b, 0x82, 0xe5, 0x49, 0xed, 0x89, 0xad, 0x0a, 0xfc, 0x44, 0x43, 0x63, 0x64, 0xcf, 0x48, 0x80, 0x04, 0x95, 0xdf, 0xf0, 0xf7, 0x0c, 0xe4, 0x37, 0xd4, 0xbf, 0x95, 0x45, 0x85, 0x84, 0xc5, 0x23, 0x44, 0xaf, 0x52, 0x47, 0xd1, 0x91, 0x93, 0x46, 0x29, 0xda, 0xae, 0x94, 0x7b, 0xe0, 0x60, 0x06, 0xfb, 0x7e, 0x1e, 0x44, 0xf5, 0xe1, 0x68, 0x56, 0x1a, 0x29, 0x3e, 0x31, 0xf2, 0x19, 0xb4, 0xf4, 0x8d, 0x0b, 0x82, 0xee, 0xc9, 0xa8, 0x81, 0xcc, 0x45, 0x3c, 0x95, 0xb7, 0x53, 0x86, 0xb4, 0xee, 0x87, 0xda, 0xe3, 0xbf, 0x69, 0xfe, 0x66, 0xd8, 0xe6, 0x1b, 0x2b, 0x73, 0x5d, 0xf8, 0xec, 0x04, 0x28, 0x8f, 0xd5, 0x04, 0xc4, 0x18, 0x49, 0xc3, 0x63, 0x09, 0x16, 0x1d, 0x90, 0xc4, 0x0a, 0x40, 0xb7, 0xec, 0xd7, 0x93, 0x12, 0xe5, 0x84, 0xa4, 0x44, 0x13, 0x1d, 0x6b, 0x74, 0x52, 0x55, 0x9a, 0x37, 0x8c, 0x84, 0x8f, 0x39, 0x47, 0x90, 0x56, 0xbd, 0xc8, 0xb9, 0xae, 0x04, 0xf2, 0xd4, 0x07, 0xcb, 0xae, 0xd9, 0xac, 0xd1, 0xce, 0xdf, 0x42, 0xde, 0x49, 0x3d, 0xc0, 0x0d, 0x6d, 0xc5, 0x69, 0x60, 0xa9, 0xaa, 0xa0, 0x1d, 0xf5, 0x1f, 0x7f, 0xa2, 0x4a, 0x57, 0x2a, 0x82, 0x83, 0x7e, 0xe9, 0xb1, 0x7f, 0x2b, 0x6d, 0x63, 0xb7, 0x89, 0xc6, 0xc4, 0xbd, 0x60, 0xc9, 0x0f, 0x03, 0x18, 0x8f, 0x7c, 0x47, 0x76, 0xb6, 0xfe, 0x2c, 0xb7, 0xf2, 0xcf, 0x94, 0xae, 0x06, 0x39, 0x76, 0x57, 0x21, 0x38, 0xc0, 0x6e, 0x80, 0x66, 0x8c, 0x5c, 0x9c, 0x12, 0xc0, 0x1e, 0x2e, 0x2c, 0xb1, 0xed, 0xa1, 0xdf, 0xb1, 0x7f, 0x5d, 0x0d, 0x1f, 0xd7, 0x03, 0xb1, 0xa8, 0x6e, 0x71, 0x15, 0x60, 0x2e, 0x04, 0x6e, 0x1e, 0xbf, 0x3f, 0xa8, 0xb5, 0x32, 0xf1, 0x20, 0xa0, 0x2e, 0xee, 0x76, 0xa6, 0xa5, 0x58, 0x11, 0x21, 0x79, 0xd6, 0x48, 0xbc, 0x68, 0x74, 0xc4, 0xea, 0xb2, 0xae, 0x36, 0x99, 0x82, 0x74, 0x9b, 0xcd, 0xa9, 0x21, 0x23, 0x06, 0x5c, 0x8a, 0x7a, 0x3e, 0xac, 0xfd, 0x5e, 0x00, 0xf4, 0x75, 0xec, 0xd5, 0x99, 0x90, 0xb2, 0x29, 0x98, 0xc5, 0x1c, 0x9a, 0x80, 0x78, 0xd2, 0xf3, 0x31, 0x9f, 0x58, 0xef, 0x5b, 0x3d, 0x25, 0x39, 0x55, 0xa9, 0xe1, 0xc3, 0xdd, 0x26, 0xae, 0xdf, 0xf2, 0xea, 0xe1, 0x1b, 0x71, 0xb7, 0xb1, 0x77, 0x98, 0x9f, 0x92, 0xa7, 0xd1, 0x17, 0x5d, 0xde, 0x86, 0x4b, 0xca, 0x86, 0xf1, 0xb8, 0x94, 0x36, 0xef, 0xb6, 0x20, 0x1d, 0x8d, 0x65, 0xa7, 0x50, 0xfb, 0xa0, 0xbd, 0x14, 0xbd, 0x71, 0xcf, 0xdd, 0x7e, 0xab, 0xf3, 0xff, 0xde, 0x09, 0x52, 0x18, 0x48, 0x21, 0xe6, 0x75, 0xcd, 0xbb, 0xa4, 0x6a, 0xf2, 0xbc, 0x8e, 0x6d, 0x29, 0x3d, 0x1d, 0x16, 0xb5, 0x48, 0x35, 0x82, 0xb2, 0x60, 0x60, 0xce, 0x60, 0x28, 0x2a, 0x5b, 0x78, 0x5f, 0xeb, 0x1b, 0x91, 0x9d, 0x69, 0x7c, 0xd6, 0xe1, 0xdc, 0xf0, 0xfd, 0xd1, 0x0e, 0xf2, 0x41, 0xe0, 0x32, 0x7d, 0x9a, 0xd0, 0x62, 0xf4, 0x01, 0x9b, 0x49, 0xa6, 0x32, 0xd7, 0x6f, 0x05, 0x40, 0x26, 0xcb, 0xf4, 0xcb, 0xb3, 0x16, 0xb0, 0x93, 0x91, 0xa3, 0x25, 0x5b, 0xcf, 0x27, 0xf9, 0x9a, 0x91, 0xe7, 0x9b, 0x6b, 0x00, 0xad, 0xc5, 0x5e, 0xc2, 0xe5, 0x4e, 0x14, 0x55, 0x83, 0xd4, 0x7d, 0x34, 0x34, 0x14, 0x6b, 0xef, 0x4e, 0x4f, 0xfd, 0xa3, 0x88, 0x61, 0x1a, 0x64, 0xb3, 0xcc, 0x5f, 0xef, 0xfc, 0x3e, 0xc1, 0x5a, 0x75, 0x31, 0xad, 0x77, 0x91, 0xae, 0x69, 0x1d, 0x69, 0xa1, 0x5b, 0x8a, 0x51, 0x41, 0x40, 0x1e, 0xcb, 0xe0, 0xb3, 0x68, 0x84, 0xb0, 0x50, 0x54, 0xd0, 0x9a, 0x28, 0x34, 0x08, 0x21, 0x20, 0x43, 0x2c, 0xd0, 0x43, 0x79, 0x12, 0x79, 0xe5, 0x9c, 0x0d, 0x22, 0x89, 0x06, 0xf7, 0x41, 0x27, 0x98, 0xca, 0x0f, 0xf0, 0x02, 0x54, 0xac, 0x52, 0x79, 0x07, 0xf1, 0x91, 0x94, 0xdb, 0x66, 0x93, 0x32, 0x54, 0x10, 0x76, 0x45, 0x5c, 0xbc, 0xba, 0x90, 0x5a, 0xa9, 0x64, 0x47, 0xa7, 0x14, 0xca, 0x49, 0xe4, 0x07, 0xb4, 0x57, 0x5d, 0xf7, 0x41, 0x6e, 0x74, 0x81, 0xcd, 0xa5, 0xa0, 0xbd, 0x17, 0x02, 0xa7, 0x80, 0x3c, 0x39, 0xda, 0xfb, 0xa9, 0xf7, 0x96, 0x9a, 0xdf, 0xd1, 0xe6, 0xe7, 0xe8, 0xb9, 0x4e, 0xe1, 0xf1, 0x5a, 0xfc, 0x22, 0x7b, 0xbd, 0xb2, 0xa7, 0x95, 0x15, 0x97, 0xce, 0x9e, 0xb2, 0xe0, 0x77, 0xd8, 0xea, 0xb5, 0x50, 0x05, 0xf2, 0x5b, 0x93, 0xf9, 0xca, 0x99, 0x5b, 0x2b, 0x16, 0x07, 0x2d, 0xb2, 0x90, 0x86, 0x3f, 0x90, 0xf2, 0xb3, 0x41, 0xa0, 0x3c, 0x93, 0xd1, 0x72, 0x4c, 0xa5, 0x5e, 0xe3, 0x85, 0x68, 0xce, 0x25, 0x1f, 0xe3, 0x7e, 0xdc, 0x30, 0xf7, 0x61, 0x46, 0xff, 0xa1, 0x43, 0x07, 0xe2, 0x3e, 0x67, 0x3f, 0x1d, 0x2d, 0xf2, 0x62, 0xed, 0x35, 0x4b, 0x35, 0x3e, 0xb5, 0x16, 0x49, 0xce, 0x4f, 0x70, 0xef, 0x58, 0x4c, 0x30, 0xc0, 0xb6, 0x61, 0x2a, 0xe6, 0xd7, 0x9b, 0x96, 0xd7, 0x8e, 0x8d, 0xdf, 0xb6, 0xf9, 0xa2, 0xf0, 0x99, 0x9b, 0xb9, 0x7c, 0x12, 0x56, 0xee, 0x04, 0x61, 0xd3, 0xf3, 0x3e, 0xcf, 0x9e, 0xf6, 0xad, 0x08, 0x45, 0x74, 0xc7, 0x6d, 0x74, 0xfb, 0x21, 0xbe, 0x45, 0xdf, 0x9f, 0x3d, 0xee, 0x8b, 0xa4, 0xb1, 0xc8, 0x93, 0xb2, 0xed, 0x19, 0x0a, 0xf3, 0x49, 0x81, 0xd0, 0x02, 0xad, 0xb5, 0xf3, 0x09, 0x48, 0xcc, 0xe8, 0x36, 0x17, 0xd1, 0x4c, 0x0c, 0xe0, 0x83, 0x57, 0x8d, 0x26, 0xa8, 0x3d, 0xc5, 0x53, 0x09, 0x60, 0x72, 0xfa, 0x6b, 0xbd, 0x52, 0x55, 0x7a, 0x10, 0x7e, 0x53, 0xb0, 0xeb, 0x4f, 0x14, 0x0a, 0x1a, 0xcf, 0xb4, 0xeb, 0x2c, 0x74, 0x47, 0x01, 0x1e, 0x48, 0xc8, 0xdd, 0xee, 0x99, 0xfd, 0x9b, 0x45, 0x11, 0xb3, 0x59, 0x0b, 0xa7, 0x26, 0x79, 0xf8, 0x0f, 0x74, 0xbd, 0x64, 0x3d, 0x28, 0xf6, 0x7f, 0x98, 0x0f, 0x98, 0xb1, 0xd5, 0xdc, 0xd1, 0x75, 0x8f, 0xd9, 0xc2, 0xbd, 0x24, 0xe8, 0xf8, 0xf1, 0x14, 0x13, 0xf5, 0x47, 0x54, 0x01, 0x42, 0x07, 0xdf, 0x41, 0x81, 0x98, 0xa3, 0x8d, 0xdb, 0xfd, 0x90, 0xd5, 0x97, 0x49, 0xb9, 0x41, 0x1d, 0x0b, 0x9b, 0xad, 0x8b, 0xcb, 0x7c, 0xd0, 0xdd, 0x2f, 0xd1, 0x0e, 0x17, 0xed, 0x9f, 0xfb, 0xa5, 0x17, 0xc5, 0x83, 0xfc, 0x39, 0xd3, 0x73, 0x50, 0xc4, 0x31, 0x25, 0xb9, 0xb7, 0x75, 0x52, 0xcd, 0x18, 0x04, 0xa7, 0x6b, 0x4e, 0xa3, 0xe8, 0x32, 0x38, 0x4e, 0x4e, 0xe9, 0xac, 0xc8, 0xac, 0xa0, 0xac, 0xcb, 0x18, 0x57, 0x44, 0x20, 0x01, 0x97, 0xea, 0xfd, 0x61, 0xdd, 0x9d, 0x0c, 0x4a, 0xb2, 0xd6, 0x1c, 0x9b, 0x41, 0x9e, 0xab, 0x57, 0x8d, 0xa2, 0x0e, 0x70, 0xa4, 0x46, 0xba, 0x44, 0x78, 0x91, 0x75, 0x3b, 0x58, 0xe2, 0x22, 0x59, 0xff, 0xd9, 0x7e, 0x80, 0x5f, 0xc6, 0x70, 0x45, 0x55, 0x3a, 0x90, 0x51, 0x8f, 0x6b, 0xc0, 0x53, 0xe9, 0x1c, 0xa6, 0x1f, 0x83, 0xc8, 0x52, 0x60, 0x1b, 0x90, 0x2c, 0x5b, 0x65, 0x97, 0x4b, 0x9c, 0xf8, 0xbc, 0xc8, 0xa2, 0x59, 0xf2, 0x12, 0x95, 0x25, 0xe0, 0xae, 0x14, 0x3c, 0x22, 0xf9, 0xc0, 0x6d, 0xfd, 0x69, 0x0d, 0x82, 0x8e, 0x4b, 0x3b, 0x43, 0x2b, 0xd0, 0x86, 0x45, 0x8b, 0x4d, 0xac, 0xb1, 0x41, 0xfb, 0x18, 0xb1, 0x13, 0x98, 0x96, 0xa3, 0xa2, 0x09, 0xf6, 0x93, 0xb9, 0x4d, 0x0a, 0xa3, 0xb6, 0xe1, 0x5b, 0x00, 0xf2, 0x3f, 0x3d, 0x02, 0x52, 0x82, 0x03, 0x35, 0x1c, 0x62, 0x53, 0x91, 0x4e, 0xf8, 0x80, 0xc9, 0x5f, 0xa9, 0x8b, 0xe8, 0x91, 0xe1, 0x2d, 0x0e, 0xc2, 0x7c, 0xac, 0x53, 0x50, 0x75, 0x0c, 0x17, 0xe2, 0x92, 0xda, 0xa6, 0xa7, 0xe0, 0x63, 0x50, 0x43, 0x95, 0x58, 0x11, 0xca, 0xe1, 0x39, 0x2c, 0x3c, 0xed, 0x4d, 0xfe, 0x86, 0xce, 0x7f, 0x5b, 0xf9, 0xbc, 0xd1, 0xb3, 0xbe, 0x49, 0x7b, 0xfc, 0x5b, 0xd3, 0xf2, 0xd0, 0xfd, 0xf1, 0x8b, 0x56, 0x96, 0x10, 0xd2, 0x06, 0x2f, 0xed, 0x1e, 0x11, 0x57, 0x71, 0x71, 0xd3, 0x4c, 0x26, 0x7f, 0x4b, 0x1b, 0x7e, 0x9d, 0x40, 0x21, 0x2b, 0xc3, 0x9b, 0x87, 0x32, 0x20, 0xdb, 0x37, 0xb6, 0x76, 0xc5, 0x5c, 0x3a, 0x23, 0xab, 0x1b, 0x2a, 0xe6, 0x5e, 0x0e, 0x06, 0x8b, 0x8a, 0xcc, 0xc5, 0x1c, 0xc0, 0x02, 0xee, 0x81, 0x07, 0x64, 0x99, 0x42, 0xcb, 0xe8, 0x43, 0xfc, 0xd1, 0x97, 0xb3, 0xd3, 0xc1, 0xc3, 0xe0, 0xab, 0xb6, 0x54, 0x2a, 0x5e, 0x19, 0x78, 0x8b, 0xa4, 0x33, 0x22, 0x41, 0x33, 0x50, 0xbb, 0xad, 0x1c, 0x71, 0x9c, 0x89, 0x8a, 0x94, 0xc6, 0xd3, 0xcd, 0x33, 0xb9, 0x8a, 0xbf, 0x1a, 0xc0, 0x34, 0x32, 0xfb, 0x47, 0x24, 0x85, 0x2c, 0x0e, 0xee, 0x4d, 0xe4, 0x3d, 0x01, 0xab, 0x36, 0x0e, 0x63, 0x69, 0xbb, 0x92, 0xc7, 0x81, 0xcd, 0xa1, 0xeb, 0x27, 0xce, 0xd5, 0x81, 0xfd, 0xb4, 0xd9, 0xc7, 0xfe, 0xe9, 0xbb, 0xff, 0xbd, 0xac, 0x6a, 0x5d, 0xce, 0x96, 0xc8, 0xc3, 0x5b, 0x7b, 0x32, 0x88, 0x18, 0xdb, 0xf8, 0x82, 0x47, 0x21, 0xb3, 0x30, 0x3c, 0xbd, 0xbc, 0x99, 0xd6, 0xc5, 0x04, 0xef, 0xfe, 0x8d, 0x19, 0x92, 0xa0, 0x78, 0xea, 0x4c, 0x5b, 0xd5, 0xa8, 0x43, 0x01, 0x6e, 0xaa, 0xa2, 0x09, 0xc1, 0x35, 0xdb, 0x64, 0xc1, 0xb6, 0xf5, 0x51, 0x6d, 0xf5, 0x76, 0x15, 0x72, 0x4c, 0xfb, 0x1a, 0x0a, 0xb6, 0x6f, 0xc6, 0xf2, 0x47, 0xa7, 0x77, 0x01, 0xd7, 0x1b, 0x0b, 0x52, 0xad, 0xc0, 0xc0, 0x82, 0xc3, 0x4c, 0x2e, 0xb2, 0xd4, 0x70, 0xef, 0xbc, 0xd3, 0xa1, 0x3a, 0xfd, 0xca, 0x93, 0x25, 0x72, 0x39, 0xc3, 0xc1, 0xbb, 0x50, 0x8a, 0xed, 0x31, 0xc6, 0xf3, 0xa7, 0x07, 0x9b, 0xa6, 0xa8, 0xed, 0x96, 0x30, 0x5b, 0xe5, 0x9c, 0x2a, 0x67, 0x87, 0x65, 0xee, 0xa3, 0x99, 0xc7, 0x73, 0x53, 0x55, 0x8f, 0x4d, 0x55, 0x9c, 0x71, 0xe8, 0x10, 0x05, 0x0a, 0x26, 0x26, 0xe5, 0x88, 0x0a, 0xd1, 0x52, 0x8e, 0x05, 0x10, 0x9e, 0xcf, 0x52, 0x21, 0x71, 0x1b, 0x64, 0x51, 0xcf, 0xe5, 0x64, 0x92, 0x82, 0x4e, 0x03, 0x3b, 0xa7, 0x85, 0xaa, 0xcb, 0x81, 0x0a, 0xc2, 0xd1, 0xea, 0xe4, 0x5a, 0x54, 0x79, 0xa7, 0xe2, 0x65, 0x18, 0x86, 0xdf, 0xe5, 0xed, 0x0e, 0xb0, 0xd0, 0x16, 0x7e, 0xa6, 0x9b, 0x27, 0xdb, 0x93, 0x84, 0xa3, 0xdc, 0xae, 0x48, 0x57, 0x6b, 0x10, 0x3a, 0x6b, 0x64, 0x1a, 0x48, 0xee, 0x2e, 0x78, 0xd9, 0x7c, 0x85, 0xbf, 0x69, 0xad, 0xfa, 0x13, 0xc7, 0xe1, 0xac, 0xa2, 0x1b, 0x82, 0xc9, 0x2c, 0xd1, 0xdf, 0x55, 0x82, 0x98, 0x15, 0x11, 0x10, 0x39, 0xc5, 0xf1, 0x03, 0xe3, 0xc1, 0x7b, 0x2f, 0x28, 0x1e, 0xb9, 0x04, 0xa8, 0xc8, 0x8e, 0x41, 0xaf, 0x28, 0x84, 0x55, 0xb4, 0x43, 0xcf, 0xe2, 0xba, 0x2e, 0x16, 0x07, 0xbf, 0x5a, 0x3c, 0xe7, 0x4b, 0x2f, 0xd4, 0x34, 0xef, 0x5f, 0x33, 0x8a, 0x55, 0x3e, 0x32, 0x49, 0x5c, 0x86, 0xf2, 0x30, 0x61, 0x58, 0x70, 0x0c, 0x9b, 0xfd, 0x69, 0x7a, 0x1b, 0x36, 0x8a, 0xaa, 0x9a, 0xe6, 0x0e, 0xcd, 0xf4, 0xad, 0xb6, 0xe1, 0xf0, 0xc8, 0x71, 0xee, 0x39, 0x58, 0xac, 0xaa, 0x46, 0xf6, 0x2c, 0xd2, 0x8c, 0x1a, 0x4c, 0x8c, 0x67, 0xcf, 0x47, 0x2f, 0xb9, 0x45, 0x43, 0x69, 0x00, 0x2e, 0x87, 0x13, 0xf8, 0xa6, 0x35, 0xaa, 0x0b, 0x04, 0xad, 0x9e, 0xe4, 0x1f, 0x28, 0x34, 0xe8, 0xfd, 0x09, 0x2b, 0x6f, 0xac, 0xc7, 0x45, 0xde, 0xd3, 0x3e, 0xb5, 0xe9, 0x36, 0xfe, 0x6b, 0xb6, 0x16, 0x74, 0x42, 0x0b, 0x46, 0x40, 0x12, 0x27, 0x53, 0x74, 0x14, 0x08, 0x70, 0x9d, 0x50, 0xec, 0x47, 0xc9, 0x5a, 0x8a, 0xa8, 0x23, 0x72, 0x60, 0x8d, 0x1c, 0xad, 0x16, 0xfc, 0xfa, 0x43, 0x32, 0xd3, 0x09, 0x5c, 0xdb, 0xfa, 0x78, 0x4d, 0x2d, 0xb9, 0xef, 0xd3, 0x09, 0x22, 0x6c, 0x6b, 0x52, 0x9b, 0xd5, 0x40, 0x78, 0xa3, 0x25, 0x51, 0xaa, 0x1c, 0x4e, 0x62, 0x05, 0x43, 0x24, 0x97, 0xa6, 0x09, 0x83, 0x3f, 0x53, 0x13, 0xa2, 0x9d, 0xe1, 0xed, 0x14, 0xe0, 0xeb, 0x4e, 0x24, 0x64, 0x7e, 0x34, 0x02, 0x33, 0x69, 0xca, 0x6b, 0x43, 0xfd, 0xff, 0xda, 0xcf, 0x2b, 0x86, 0x81, 0x34, 0x69, 0xd1, 0x3c, 0xae, 0xa5, 0x1e, 0x41, 0xcc, 0x58, 0xe6, 0x13, 0xed, 0x05, 0x19, 0xdb, 0xc2, 0xe8, 0x23, 0xdf, 0x7c, 0x96, 0x15, 0x3d, 0xcb, 0x36, 0x2a, 0x0b, 0x3b, 0xd6, 0x1b, 0xba, 0xba, 0xba, 0x30, 0x54, 0x57, 0x2d, 0x20, 0xb6, 0x53, 0x88, 0x6b, 0xed, 0x3d, 0x51, 0x38, 0xb1, 0x0e, 0x59, 0x7f, 0x0e, 0xdc, 0x32, 0xf6, 0x41, 0x4a, 0x46, 0xdf, 0x21, 0x29, 0xdb, 0x26, 0xc9, 0xeb, 0xe8, 0xb1, 0x7a, 0xe1, 0xa1, 0x6d, 0x02, 0x70, 0xc1, 0x88, 0x10, 0x3b, 0x70, 0xcb, 0x9f, 0x2e, 0xc9, 0x91, 0xd0, 0x8a, 0x61, 0x9a, 0x34, 0x6d, 0x07, 0x7f, 0x3c, 0xd4, 0x5a, 0x9d, 0x38, 0x45, 0xe7, 0xa8, 0x8b, 0x33, 0x04, 0xde, 0x26, 0x73, 0xa8, 0x7d, 0xf4, 0x5f, 0x3c, 0x2a, 0xe6, 0x5d, 0x8c, 0x55, 0xc7, 0xdf, 0x2b, 0xb0, 0x18, 0xae, 0x45, 0x4a, 0x83, 0xb9, 0x5e, 0xd4, 0xf5, 0xda, 0x4b, 0x4b, 0xac, 0x4b, 0x87, 0x47, 0x3b, 0xcc, 0x3a, 0x05, 0x56, 0x3e, 0x30, 0xb7, 0x25, 0xd9, 0x2d, 0xe9, 0xb0, 0x71, 0x11, 0x92, 0x1d, 0x76, 0x63, 0xea, 0xb9, 0x16, 0xd0, 0xec, 0xe5, 0xfd, 0x11, 0x0d, 0xae, 0x00, 0x69, 0x62, 0x66, 0x95, 0x30, 0xc9, 0xcc, 0xa4, 0xd6, 0x7e, 0x4f, 0x81, 0xb7, 0xf3, 0xe7, 0x9d, 0xa7, 0xf8, 0xf8, 0xf7, 0x0c, 0x7f, 0x5e, 0x6a, 0x15, 0x49, 0xb3, 0x1c, 0x3f, 0xa5, 0xaf, 0xea, 0x79, 0xb3, 0x59, 0x12, 0x48, 0xea, 0xa6, 0x0d, 0x6a, 0x8d, 0xe8, 0xae, 0xb5, 0xde, 0x5b, 0xd8, 0x31, 0xbd, 0x0e, 0xa8, 0x24, 0xe4, 0x18, 0x54, 0x7b, 0xc3, 0x6e, 0xc2, 0x03, 0x57, 0x31, 0xd2, 0x31, 0x22, 0xf6, 0x71, 0xa0, 0x72, 0xcb, 0x28, 0x45, 0xdd, 0xe3, 0xaa, 0x42, 0xb9, 0x30, 0x32, 0xe5, 0x61, 0xd5, 0xfa, 0x85, 0x4d, 0x7a, 0xce, 0x27, 0x60, 0x0a, 0x54, 0x93, 0x02, 0x4d, 0xcc, 0x98, 0x30, 0x76, 0x5b, 0x99, 0x33, 0x9a, 0x91, 0x97, 0x1d, 0xe6, 0x2f, 0xe9, 0x1f, 0xb8, 0xe3, 0xda, 0x4d, 0x23, 0xda, 0xe0, 0x8e, 0xf2, 0x76, 0x99, 0x89, 0x68, 0xe0, 0x58, 0x4d, 0xaa, 0xbf, 0xed, 0x48, 0x14, 0xda, 0x43, 0x2c, 0x76, 0xf5, 0xd2, 0x06, 0xd6, 0xb5, 0xc4, 0x70, 0xe4, 0x50, 0x44, 0x7a, 0x52, 0x71, 0xd0, 0x53, 0x1a, 0x3e, 0x4c, 0xe8, 0x31, 0xfe, 0xda, 0xa3, 0x9b, 0x19, 0x57, 0x93, 0x12, 0x2d, 0x27, 0x2d, 0x89, 0xfa, 0xb1, 0x28, 0xf1, 0xba, 0x84, 0x04, 0x72, 0xe7, 0xad, 0xde, 0x70, 0x09, 0x14, 0x13, 0xa9, 0x6c, 0x8e, 0x47, 0x0a, 0xb5, 0xf2, 0x0d, 0x56, 0x22, 0xb4, 0xa3, 0xbe, 0x3f, 0x43, 0x07, 0x2d, 0x50, 0x7d, 0x54, 0x02, 0x74, 0x30, 0xe6, 0xcd, 0x99, 0xd5, 0x17, 0x3b, 0x56, 0x88, 0x3b, 0x3e, 0xd1, 0xd3, 0x42, 0xd8, 0xb3, 0xc2, 0x87, 0x4c, 0xc8, 0x8a, 0xb9, 0x66, 0xa6, 0xf1, 0x26, 0x02, 0xf3, 0x07, 0xe9, 0x9b, 0x87, 0xf1, 0x30, 0xca, 0x9c, 0xa2, 0x07, 0x07, 0xde, 0xcd, 0xc3, 0x5f, 0xc8, 0xe7, 0x58, 0x6a, 0x70, 0x90, 0xc0, 0x48, 0xfa, 0x0d, 0x4d, 0x64, 0xde, 0x50, 0xef, 0x61, 0xc4, 0x93, 0x01, 0x34, 0xd5, 0x32, 0x2b, 0xe9, 0x84, 0x6c, 0x30, 0x06, 0x9b, 0x9e, 0x73, 0x34, 0xd4, 0x6b, 0x03, 0xe1, 0x3d, 0x24, 0xbe, 0xc8, 0x8e, 0xcb, 0x66, 0xdf, 0x70, 0x94, 0x98, 0x26, 0x7a, 0xa5, 0xcb, 0x31, 0x95, 0x66, 0x5a, 0xb2, 0xfd, 0xcc, 0xd7, 0xc2, 0xa7, 0x61, 0xf9, 0x3c, 0x19, 0xab, 0x6a, 0x1c, 0xe8, 0x32, 0x8e, 0x78, 0x40, 0x78, 0xe4, 0xc4, 0xfc, 0x5a, 0x9d, 0xf6, 0x3a, 0xe5, 0x39, 0x11, 0xa5, 0x53, 0xaa, 0x8d, 0xc8, 0x80, 0x4b, 0x95, 0x7e, 0xd5, 0x9b, 0x1a, 0xa3, 0x64, 0x4a, 0x27, 0x3b, 0xe1, 0xac, 0xaf, 0xf0, 0x4d, 0x96, 0x3f, 0xdc, 0xd3, 0xd6, 0xd0, 0x61, 0x08, 0x8a, 0xf0, 0x9f, 0x79, 0x68, 0x06, 0x04, 0xe6, 0xf6, 0xda, 0x7e, 0x0e, 0xf7, 0x26, 0x7e, 0x06, 0xac, 0xb4, 0xed, 0xcf, 0xf1, 0xb3, 0x97, 0x4d, 0x25, 0xa1, 0x58, 0xca, 0xd4, 0x90, 0x66, 0x7c, 0x9a, 0xef, 0x05, 0x13, 0x19, 0x92, 0x60, 0x21, 0xc3, 0x5c, 0x3c, 0x37, 0x3d, 0xc9, 0x0f, 0x5b, 0x90, 0xd0, 0x1d, 0xb7, 0x93, 0xf6, 0xc7, 0x28, 0xe5, 0x18, 0xeb, 0xd9, 0xd6, 0xe2, 0xa8, 0x7a, 0x1c, 0x5a, 0x18, 0x81, 0xcb, 0xcc, 0x24, 0x1a, 0xc2, 0x17, 0x31, 0x65, 0x69, 0xa4, 0xe4, 0x56, 0xc8, 0xf7, 0x45, 0x6e, 0xa3, 0x03, 0xd1, 0x92, 0xee, 0x2b, 0x8e, 0xc6, 0x1a, 0x21, 0x75, 0x89, 0x7b, 0xf1, 0xda, 0x5d, 0x81, 0x8f, 0x1d, 0xbd, 0x27, 0x7c, 0x84, 0x47, 0xe0, 0xdb, 0x19, 0xd8, 0x1d, 0x50, 0xe8, 0x85, 0x3e, 0x3f, 0x5b, 0x76, 0x52, 0x98, 0xf4, 0xce, 0xe1, 0xad, 0xdc, 0x0e, 0x8e, 0x30, 0x89, 0x27, 0x18, 0xaf, 0x9e, 0x4c, 0x9b, 0x8c, 0xb6, 0x9b, 0x19, 0x58, 0x8e, 0x80, 0xc5, 0x41, 0xa4, 0x6a, 0xf7, 0x24, 0xb6, 0xe3, 0xfb, 0x84, 0x21, 0x42, 0xd9, 0xb8, 0x5e, 0x02, 0xec, 0xf5, 0x9f, 0xaf, 0xaa, 0xd0, 0xa5, 0x7f, 0x3c, 0x89, 0x06, 0xa4, 0x63, 0x9d, 0xce, 0x64, 0xfc, 0xd2, 0x03, 0x5a, 0xe4, 0x11, 0x60, 0x80, 0x28, 0x34, 0x2f, 0x93, 0xe5, 0x48, 0xa9, 0x36, 0x99, 0xa2, 0x8f, 0xde, 0xb6, 0xee, 0x5c, 0xf8, 0x6e, 0x3e, 0xa4, 0x11, 0x6f, 0x99, 0x4c, 0x52, 0x2d, 0xf2, 0x1e, 0x4e, 0xf4, 0x41, 0x6b, 0xe1, 0xf6, 0x0d, 0x36, 0x02, 0x85, 0x13, 0xa0, 0x38, 0x94, 0x4c, 0xe4, 0xa6, 0xc0, 0x73, 0x09, 0x10, 0x17, 0x21, 0x93, 0xf0, 0x15, 0x3d, 0xc9, 0x45, 0x76, 0x24, 0x74, 0xae, 0x5f, 0x9d, 0x54, 0xa7, 0x3d, 0x69, 0xa8, 0x64, 0xf2, 0x9c, 0xfa, 0xa7, 0x1f, 0x87, 0x7b, 0xdd, 0x9c, 0xa9, 0xa8, 0xc8, 0xa7, 0xd8, 0x84, 0xd1, 0xfe, 0x4a, 0x7b, 0x89, 0x0e, 0x76, 0x2e, 0xf2, 0x65, 0x48, 0x33, 0x35, 0xa1, 0x39, 0x52, 0xc9, 0x34, 0x57, 0x4e, 0x77, 0xca, 0xd4, 0xc5, 0xd3, 0xad, 0x5e, 0x23, 0x44, 0x6d, 0x8f, 0x32, 0x7d, 0x46, 0xf5, 0xd1, 0x67, 0x7a, 0xa4, 0x79, 0x02, 0x18, 0x1c, 0xe9, 0xc8, 0xea, 0xe3, 0x27, 0xe1, 0x53, 0x2e, 0x5e, 0x2a, 0xa2, 0xb8, 0x94, 0xaa, 0x67, 0xbd, 0xd3, 0xcb, 0x33, 0xe6, 0x48, 0xc6, 0x22, 0x95, 0x89, 0x2f, 0x50, 0xa9, 0xcb, 0xc5, 0x36, 0xff, 0xd6, 0x4a, 0x30, 0x69, 0x53, 0xa0, 0xb6, 0xbb, 0x1b, 0xe0, 0xf1, 0x4b, 0x37, 0x2e, 0x48, 0xc5, 0x49, 0x94, 0x29, 0xfa, 0x35, 0xe1, 0x02, 0xa9, 0xb2, 0xf7, 0x5f, 0x43, 0xdf, 0x2c, 0xf7, 0x2f, 0xbf, 0xf6, 0xc1, 0x34, 0x95, 0x27, 0x04, 0xb8, 0xe9, 0xa5, 0xbc, 0x8a, 0x47, 0xe1, 0xd5, 0xa3, 0x51, 0xa6, 0x0a, 0x8e, 0x1b, 0xf3, 0x7c, 0x41, 0xd0, 0xb2, 0x5f, 0xc3, 0x67, 0x1a, 0xb4, 0x0f, 0x9e, 0xfd, 0xb7, 0x9a, 0x84, 0xd8, 0x09, 0xc2, 0x76, 0x10, 0xfe, 0xd4, 0x06, 0x86, 0xa7, 0xf1, 0xcc, 0xa7, 0xde, 0xf2, 0x4b, 0xee, 0x0e, 0x60, 0x31, 0x1c, 0x08, 0xc2, 0x13, 0x69, 0xaa, 0xde, 0xe0, 0x42, 0x17, 0x1b, 0xe9, 0x21, 0x35, 0xfc, 0xab, 0x05, 0xf1, 0xbc, 0xfd, 0xfb, 0xf1, 0xdb, 0xc0, 0xc0, 0xec, 0x47, 0x9b, 0x18, 0x1a, 0x72, 0xe6, 0xd6, 0xcf, 0x94, 0x63, 0xac, 0xbb, 0x32, 0x08, 0x60, 0xa8, 0x02, 0x2c, 0x77, 0x3b, 0xf6, 0x8e, 0x4f, 0xd9, 0x3b, 0x24, 0x2c, 0xa9, 0x3b, 0xb2, 0xcb, 0x06, 0x61, 0x13, 0xa7, 0x5f, 0x7b, 0xf4, 0x10, 0x4d, 0xbe, 0x38, 0x31, 0x7f, 0xde, 0x29, 0xa3, 0x7b, 0x44, 0x1c, 0x10, 0x45, 0xc1, 0x94, 0x3b, 0x05, 0xfd, 0x0e, 0x4d, 0xc6, 0x7b, 0xab, 0x28, 0x0c, 0xc8, 0xe3, 0x5c, 0x38, 0x72, 0x3b, 0x34, 0xb7, 0x9a, 0x9c, 0xb5, 0x91, 0x14, 0x23, 0x12, 0x50, 0xfe, 0x22, 0x4f, 0x52, 0x54, 0xab, 0x2b, 0x6d, 0xc1, 0xb0, 0x9e, 0x00, 0xf5, 0x2c, 0x2f, 0x90, 0x61, 0xd3, 0x64, 0x20, 0x53, 0xff, 0xf6, 0xaa, 0x70, 0x33, 0xf3, 0xa7, 0xe8, 0x9a, 0x8f, 0xf1, 0xf7, 0x83, 0xd5, 0xe8, 0xf0, 0x38, 0x8f, 0x92, 0x60, 0xd6, 0xf9, 0x79, 0xc2, 0x7d, 0x25, 0xe6, 0x4b, 0xb4, 0x83, 0x13, 0xd2, 0x3a, 0xf4, 0xbf, 0xe1, 0x76, 0x83, 0xe0, 0x06, 0xaa, 0xc5, 0xea, 0x5d, 0x0c, 0x61, 0xca, 0xef, 0xa1, 0x99, 0xd0, 0x9f, 0x7d, 0x7e, 0xd8, 0x79, 0xed, 0x59, 0x85, 0xc0, 0xeb, 0xed, 0x65, 0x96, 0x25, 0x79, 0x51, 0xde, 0xa0, 0x2f, 0x7e, 0x34, 0x8b, 0xb5, 0x60, 0x74, 0x08, 0x49, 0x38, 0xc7, 0x21, 0x83, 0xef, 0xb9, 0xf4, 0x8b, 0x21, 0x84, 0x52, 0x33, 0x38, 0x99, 0x6f, 0x01, 0x3f, 0xe5, 0x4d, 0xbc, 0x37, 0x28, 0x65, 0x09, 0x26, 0x37, 0xe0, 0xcd, 0x0f, 0x6c, 0x6a, 0x9b, 0xc7, 0x63, 0x9e, 0xd5, 0xcf, 0x8f, 0x81, 0xf7, 0xe5, 0xc6, 0x6a, 0xa1, 0xfb, 0xc5, 0xe9, 0xf9, 0x41, 0xb3, 0x63, 0x3a, 0x6d, 0x44, 0x87, 0x6e, 0x57, 0x0c, 0x77, 0xc7, 0x8d, 0x48, 0x6e, 0x0c, 0xdf, 0xb0, 0xd0, 0x5c, 0x7e, 0x82, 0xa3, 0xac, 0xed, 0x91, 0x59, 0x6f, 0x9d, 0x95, 0xa9, 0x47, 0xe4, 0x5a, 0x4c, 0x56, 0x71, 0x05, 0x87, 0xf6, 0xac, 0xfe, 0xd6, 0x75, 0xcc, 0x47, 0x51, 0xd1, 0x49, 0x30, 0xb8, 0xe6, 0x04, 0xfa, 0xbd, 0x2d, 0x7e, 0x28, 0xc6, 0xf4, 0xc3, 0xd8, 0x85, 0xc0, 0x89, 0x59, 0xfc, 0xdd, 0x33, 0xd5, 0x1e, 0xc3, 0xb6, 0x2c, 0xa5, 0xdc, 0x30, 0xfe, 0xa7, 0x3d, 0xc1, 0xc0, 0x1d, 0xdf, 0x35, 0xc8, 0x7d, 0x27, 0x16, 0xbb, 0x9c, 0x31, 0x94, 0xd0, 0xde, 0xbb, 0x63, 0xb3, 0xb2, 0x74, 0xa3, 0xc4, 0x41, 0x57, 0xf5, 0xf5, 0xc2, 0x0e, 0xb1, 0xf1, 0x2e, 0xd4, 0x7c, 0xe4, 0x1f, 0xd7, 0x84, 0xbe, 0x2e, 0x9a, 0xd1, 0x2a, 0xc4, 0xe3, 0xbd, 0xd9, 0xc6, 0xcf, 0xe9, 0x69, 0xc4, 0xcb, 0xc9, 0x11, 0xb8, 0x1d, 0x14, 0xb1, 0x57, 0x85, 0x75, 0xf8, 0x5d, 0xcc, 0xe8, 0x61, 0x4d, 0x4f, 0x5b, 0xe0, 0x3a, 0x8d, 0x44, 0x93, 0xf5, 0x1f, 0xfe, 0xbd, 0x0a, 0x7a, 0xf4, 0x1c, 0x01, 0xfb, 0x2d, 0x5f, 0x53, 0x75, 0xc8, 0x9a, 0x1f, 0xa6, 0xb7, 0xaa, 0xa3, 0xa7, 0x1e, 0x52, 0x58, 0x00, 0x03, 0xea, 0x90, 0x82, 0x9a, 0x87, 0xff, 0x9f, 0xe4, 0xcd, 0xe1, 0x95, 0x2e, 0x54, 0x3f, 0xaa, 0xfe, 0x75, 0xbd, 0xcc, 0x4f, 0x0d, 0x9e, 0x75, 0xb3, 0xc7, 0xe2, 0x47, 0x9f, 0xae, 0x4a, 0xc3, 0x1c, 0x1a, 0x6a, 0xcd, 0xcc, 0x30, 0x4f, 0x4c, 0xd0, 0x80, 0xd4, 0xcb, 0x2e, 0xbf, 0x06, 0x2a, 0x83, 0x03, 0x23, 0x86, 0x46, 0x76, 0x5b, 0x1f, 0xda, 0xab, 0x82, 0xbe, 0xc5, 0xd6, 0xf6, 0x3f, 0x23, 0x2b, 0xd7, 0x75, 0x48, 0x13, 0x73, 0x93, 0xb3, 0x30, 0x54, 0xf7, 0x5d, 0x86, 0xc0, 0x6d, 0x45, 0x8c, 0xb7, 0xad, 0x22, 0xc7, 0x2c, 0xef, 0x51, 0x66, 0xeb, 0x84, 0xc6, 0xc4, 0xe9, 0xa2, 0x8d, 0x9d, 0x2a, 0x51, 0xe1, 0x5b, 0x39, 0xdf, 0x7a, 0x47, 0x62, 0xdc, 0x9b, 0x0d, 0x76, 0xf1, 0x73, 0x5b, 0x78, 0xf5, 0xb8, 0xa8, 0x6f, 0x80, 0xe7, 0x3a, 0xb5, 0xfc, 0xac, 0x18, 0xe7, 0x71, 0xe3, 0xa0, 0x1c, 0x2f, 0x09, 0x5c, 0x7d, 0x2f, 0xed, 0xb5, 0x56, 0x79, 0xa5, 0x12, 0x6e, 0x69, 0x5d, 0x61, 0x34, 0x05, 0x46, 0x21, 0x8d, 0xc7, 0x1a, 0x56, 0x8b, 0x9a, 0xcc, 0x4c, 0x5c, 0x1c, 0x95, 0xf4, 0x60, 0x80, 0xc7, 0xbc, 0x4e, 0x9e, 0x35, 0x89, 0x38, 0x15, 0xeb, 0x72, 0x70, 0x6c, 0x5a, 0x85, 0xb2, 0x7b, 0xe5, 0x82, 0xa0, 0x8a, 0xd3, 0x9f, 0x5f, 0xbb, 0x38, 0x9b, 0x15, 0xb0, 0xd9, 0xbb, 0x3f, 0x22, 0xa4, 0xfa, 0xe4, 0x63, 0x8b, 0x8d, 0x12, 0xb5, 0xfc, 0xf5, 0x36, 0x1b, 0x5d, 0x19, 0x77, 0xd2, 0x46, 0x7a, 0xb5, 0xfe, 0x3d, 0x21, 0xb3, 0x6d, 0x0e, 0x59, 0xa9, 0x51, 0x3d, 0xb7, 0xe7, 0x80, 0xae, 0xf5, 0x06, 0xa9, 0x18, 0x73, 0xbc, 0xb7, 0x8b, 0xdb, 0xec, 0x1f, 0x48, 0x73, 0x27, 0x88, 0x09, 0x82, 0xb6, 0x55, 0xd3, 0xe3, 0x51, 0xac, 0x60, 0xd6, 0x4d, 0xe9, 0xc2, 0xe4, 0xfd, 0x19, 0xad, 0x08, 0x45, 0xe1, 0x55, 0x71, 0x5c, 0x88, 0xe5, 0x3c, 0x03, 0x03, 0x46, 0x1b, 0x56, 0xbc, 0x9d, 0x0d, 0x33, 0x4b, 0x05, 0xbf, 0xf7, 0xfa, 0x0b, 0xed, 0xb2, 0xe2, 0x78, 0x9c, 0x36, 0x1a, 0x8f, 0xc9, 0x05, 0x33, 0x4a, 0xfe, 0xe2, 0x38, 0x64, 0x23, 0x18, 0x5a, 0xff, 0xdc, 0x42, 0x10, 0x00, 0xb6, 0x44, 0xfe, 0x1d, 0xc1, 0xd4, 0x33, 0x07, 0xdd, 0x4f, 0xa4, 0xa8, 0xef, 0x2d, 0xb0, 0xd1, 0xd7, 0x5c, 0x82, 0x60, 0x67, 0x21, 0xeb, 0xef, 0xd8, 0xa0, 0xa6, 0xb4, 0xe2, 0x8c, 0xc5, 0xd7, 0x77, 0x95, 0xb7, 0x34, 0x24, 0xf2, 0x7d, 0x9c, 0xd4, 0x16, 0x3b, 0x20, 0x6e, 0xc6, 0x15, 0x6f, 0x43, 0x98, 0x9c, 0x3c, 0x2c, 0x1b, 0x4a, 0xc1, 0x71, 0xc7, 0xa3, 0x94, 0xbb, 0x5b, 0x9a, 0x9e, 0xea, 0x8e, 0xc6, 0xaa, 0xc2, 0x3d, 0x91, 0x0e, 0xc4, 0xcd, 0x94, 0xaa, 0xc3, 0x46, 0xc6, 0x62, 0x40, 0x2d, 0x92, 0xe0, 0x2d, 0x0d, 0x7d, 0xb6, 0x85, 0x11, 0x7e, 0x46, 0xfe, 0x89, 0x49, 0xee, 0x73, 0x4e, 0x32, 0x87, 0x19, 0x5e, 0xec, 0x01, 0xac, 0x63, 0x0b, 0x17, 0x2b, 0x42, 0x0f, 0x5f, 0x22, 0x1b, 0x3d, 0x4b, 0x5f, 0x78, 0xac, 0x09, 0x68, 0x2d, 0x9f, 0x30, 0xf0, 0x06, 0x9f, 0x27, 0xe6, 0x59, 0xe0, 0x23, 0x8f, 0x46, 0x6b, 0xbf, 0x89, 0x21, 0x57, 0xa8, 0x2f, 0x8e, 0x6d, 0x76, 0x58, 0x0e, 0x4c, 0x9f, 0x02, 0x08, 0x8e, 0x1f, 0xff, 0x7f, 0x4d, 0x8f, 0xbc, 0x49, 0x66, 0x3e, 0xd8, 0x96, 0x54, 0xa3, 0x3f, 0x0b, 0xfd, 0x90, 0x79, 0x16, 0xb8, 0xcc, 0x3b, 0xa6, 0x6b, 0x56, 0x69, 0x55, 0x92, 0xa5, 0x12, 0x27, 0xa1, 0x07, 0x20, 0x05, 0x19, 0x39, 0x95, 0xbb, 0xea, 0x41, 0xba, 0xbe, 0x23, 0x0a, 0xf3, 0x2b, 0xa5, 0x1f, 0xce, 0xb1, 0xda, 0x44, 0xdc, 0xa9, 0x6a, 0x91, 0x25, 0x94, 0x8e, 0x2b, 0x14, 0xea, 0x2b, 0xbb, 0x32, 0x3a, 0xc8, 0xd1, 0x9a, 0x6a, 0x37, 0xc2, 0xcc, 0xcb, 0xb3, 0xfd, 0x51, 0xd1, 0x45, 0x3e, 0xf1, 0x26, 0xc2, 0x9e, 0xc9, 0x20, 0x7a, 0x95, 0x2f, 0x0a, 0x21, 0x90, 0xe2, 0xff, 0x83, 0x3f, 0x7a, 0x1d, 0xf2, 0x02, 0x0b, 0xcd, 0x19, 0xbb, 0x33, 0x35, 0x11, 0x8c, 0xde, 0x42, 0xe8, 0x7c, 0x60, 0x56, 0xba, 0xc4, 0x9b, 0x17, 0x4f, 0x4a, 0x89, 0x46, 0x6f, 0xee, 0x2b, 0x82, 0x51, 0x10, 0x9f, 0x0d, 0x3e, 0x91, 0xd6, 0xfb, 0x8f, 0x46, 0x4a, 0xf8, 0x69, 0xcb, 0x53, 0x43, 0x52, 0x05, 0x26, 0xaf, 0xb1, 0x55, 0x1e, 0x86, 0x8f, 0x1c, 0xb0, 0xbd, 0x46, 0x39, 0x85, 0xf2, 0x17, 0x29, 0x34, 0x84, 0x32, 0xfb, 0x76, 0x76, 0x33, 0x00, 0x80, 0x4c, 0xaf, 0x6e, 0x38, 0xf2, 0x3e, 0x72, 0xf7, 0x9e, 0x47, 0x13, 0xe0, 0x53, 0xfb, 0x7b, 0x45, 0x4d, 0xd6, 0x1b, 0x43, 0xbd, 0x80, 0x5b, 0x24, 0x99, 0xe9, 0xdd, 0xe8, 0xc6, 0xbd, 0x78, 0xfa, 0xfb, 0x47, 0xbe, 0xc4, 0x8f, 0x59, 0x66, 0x2b, 0x79, 0xf7, 0x24, 0xf4, 0xba, 0x27, 0xf4, 0x8d, 0xad, 0x1e, 0x2f, 0x42, 0x76, 0x73, 0x39, 0x38, 0x3f, 0x8b, 0xee, 0x3e, 0x57, 0x06, 0x6d, 0x02, 0x49, 0xf1, 0x03, 0xb2, 0xf5, 0x93, 0xff, 0x68, 0xc9, 0x84, 0x49, 0x05, 0xc2, 0x7f, 0x13, 0x17, 0xd7, 0xd0, 0xb0, 0x65, 0x2d, 0x1a, 0xc3, 0xf4, 0x0d, 0x81, 0x4f, 0xd6, 0xfe, 0xeb, 0xa5, 0xc9, 0x64, 0xd4, 0xe7, 0x00, 0x0c, 0xfb, 0x00, 0xf1, 0xfd, 0x1b, 0xf7, 0x1c, 0x83, 0xcf, 0x6f, 0xaf, 0xdb, 0x1b, 0x61, 0x55, 0x37, 0x42, 0xc0, 0xd8, 0xb5, 0x88, 0x9f, 0x44, 0x74, 0x2f, 0x90, 0x39, 0x8f, 0x0b, 0xdc, 0x0d, 0xf6, 0x8e, 0xfd, 0xa4, 0x36, 0x77, 0x95, 0xda, 0xcf, 0xc5, 0xb2, 0xb0, 0x5b, 0xe9, 0x58, 0xf5, 0xce, 0x83, 0x32, 0x9b, 0x36, 0xa2, 0xdd, 0x99, 0xb9, 0xb7, 0x61, 0x2c, 0xe7, 0x88, 0xc2, 0xd4, 0x4b, 0x2b, 0xe8, 0x74, 0xe9, 0xa0, 0x2a, 0x00, 0x20, 0xff, 0x15, 0x6c, 0x3b, 0x59, 0xa7, 0x9d, 0x64, 0x33, 0x84, 0x56, 0x42, 0xc6, 0xd3, 0x4c, 0x54, 0xbc, 0xff, 0x83, 0x4f, 0xc8, 0xea, 0x00, 0xf0, 0x78, 0x63, 0xf5, 0x02, 0x92, 0x53, 0x03, 0x8e, 0x7d, 0x1f, 0x3f, 0x46, 0x90, 0xd7, 0x5c, 0xcc, 0x39, 0x69, 0xc5, 0x27, 0x9c, 0x30, 0xe8, 0xa4, 0xda, 0xdb, 0x99, 0x2d, 0x4c, 0x4f, 0x3b, 0x8e, 0x03, 0xfc, 0x55, 0x4d, 0x23, 0xe8, 0x65, 0x51, 0xe5, 0x9b, 0xe4, 0x81, 0x3a, 0xb5, 0x25, 0x68, 0xcf, 0x1c, 0x8a, 0x4c, 0xcf, 0xda, 0x9f, 0x89, 0x09, 0xfd, 0xfd, 0x86, 0xb5, 0xfd, 0x9a, 0xa2, 0x7a, 0x99, 0x35, 0xda, 0x7f, 0xeb, 0x20, 0x57, 0x23, 0xbb, 0x54, 0x4c, 0xc4, 0x7a, 0x79, 0xc2, 0x30, 0x05, 0xa8, 0xd8, 0x3e, 0x7b, 0xfb, 0x6c, 0xa3, 0x4b, 0xdd, 0xa7, 0x6c, 0x83, 0x60, 0x45, 0x57, 0x0e, 0x46, 0x53, 0x27, 0xed, 0x10, 0x6d, 0x42, 0x37, 0x87, 0x81, 0xe1, 0x4a, 0x56, 0xc1, 0x91, 0xd8, 0xbf, 0x65, 0xc1, 0xe8, 0x8f, 0x3d, 0x99, 0xbc, 0x41, 0x94, 0x99, 0xc8, 0x99, 0xbe, 0x36, 0x63, 0xae, 0x29, 0x4a, 0xbb, 0x84, 0x3d, 0x32, 0x50, 0xac, 0x76, 0xd6, 0x24, 0xfc, 0x73, 0xc6, 0xdc, 0xcf, 0xbd, 0x2f, 0xd7, 0x5e, 0xc3, 0x25, 0x63, 0xd9, 0xc2, 0x92, 0xe1, 0x38, 0x0c, 0x6c, 0x7d, 0xbc, 0xd0, 0xdb, 0xdd, 0x1f, 0x47, 0xae, 0x92, 0xd7, 0xb5, 0x9e, 0x23, 0x8f, 0x97, 0x23, 0x4d, 0x1c, 0xa7, 0x49, 0x3d, 0x3b, 0xa5, 0xd5, 0xb6, 0x0b, 0xae, 0x5e, 0x38, 0x45, 0x0e, 0x97, 0x18, 0x31, 0x84, 0x0a, 0x50, 0x93, 0xa2, 0x53, 0x39, 0xb5, 0x17, 0xb1, 0xbe, 0xa6, 0xf1, 0xab, 0x9c, 0x99, 0x84, 0x31, 0x1b, 0x92, 0xa9, 0x4a, 0xbe, 0xdc, 0x21, 0xee, 0xa5, 0xe4, 0x85, 0x8d, 0xf4, 0x7b, 0xc9, 0xda, 0xd6, 0x6e, 0xba, 0xda, 0x27, 0x3d, 0x39, 0xe6, 0xf9, 0xb3, 0x61, 0x1e, 0xbb, 0x3e, 0x76, 0x2f, 0x27, 0x55, 0x91, 0x79, 0x4e, 0x17, 0xe5, 0xf9, 0x1f, 0xef, 0x66, 0xfc, 0x91, 0x4a, 0x12, 0x11, 0x86, 0x01, 0x36, 0x70, 0x8d, 0xda, 0xf4, 0x58, 0xae, 0x17, 0x94, 0x59, 0x7b, 0xce, 0xe1, 0x9c, 0x03, 0x5e, 0x98, 0xdb, 0xac, 0x95, 0x0a, 0xad, 0xbd, 0x53, 0xa6, 0xea, 0xf2, 0x04, 0x18, 0x03, 0xf6, 0xe7, 0xb0, 0x69, 0x33, 0x8a, 0xce, 0x8e, 0x35, 0x34, 0x0e, 0xb5, 0x86, 0x11, 0x65, 0x49, 0xa9, 0x31, 0x61, 0x14, 0x3f, 0x1b, 0x32, 0xe5, 0x5c, 0xc1, 0x0e, 0x94, 0xd7, 0x9a, 0xbd, 0x5e, 0xdb, 0x93, 0x58, 0xbe, 0x8a, 0x8e, 0xbc, 0x25, 0x5b, 0xe1, 0x8c, 0x9b, 0x39, 0xd2, 0x66, 0x07, 0xb3, 0x6e, 0x43, 0x17, 0x12, 0xd7, 0x91, 0x68, 0xb4, 0x69, 0x45, 0xfa, 0xf9, 0xe4, 0x2b, 0x5d, 0xc2, 0x55, 0xa9, 0x72, 0x70, 0x45, 0x65, 0x52, 0xa3, 0x1c, 0x55, 0xeb, 0xbf, 0xe6, 0x60, 0x6c, 0x73, 0xcf, 0x70, 0xe8, 0xa8, 0xa8, 0x57, 0xdb, 0xb4, 0x0b, 0x88, 0x6f, 0xea, 0x6c, 0x2d, 0x0b, 0x09, 0x65, 0x85, 0xd3, 0x17, 0x1a, 0x27, 0x3b, 0xe5, 0x1f, 0x36, 0xcd, 0x58, 0xb1, 0x34, 0xde, 0x5f, 0xc2, 0x26, 0xeb, 0x1c, 0x3e, 0x91, 0x41, 0x6d, 0xd8, 0xd7, 0xa6, 0x45, 0x4b, 0x8c, 0xf8, 0xd7, 0x37, 0x5a, 0xf5, 0x7a, 0xa0, 0xd0, 0x4b, 0x2a, 0x56, 0x8f, 0xe6, 0x55, 0x27, 0xed, 0xa7, 0x1a, 0xd2, 0x1f, 0x7d, 0x1b, 0x32, 0x9e, 0x8a, 0x85, 0xcd, 0x91, 0x24, 0x2a, 0x2c, 0xfa, 0x1a, 0x84, 0x87, 0xa0, 0x0b, 0x02, 0x1d, 0x15, 0x34, 0x69, 0x70, 0xd3, 0xc7, 0x47, 0x73, 0xe9, 0xcc, 0x7b, 0xc1, 0xa4, 0x00, 0x6d, 0xfb, 0xab, 0x8e, 0xcd, 0x5a, 0xc8, 0x07, 0x50, 0x23, 0x9d, 0x62, 0x09, 0x77, 0x74, 0xc4, 0x05, 0x2b, 0x38, 0xba, 0x3e, 0x04, 0xce, 0x1d, 0xbb, 0x7e, 0x35, 0x48, 0x7e, 0x8e, 0xbb, 0x43, 0xb5, 0xde, 0x33, 0x4e, 0x61, 0x39, 0x22, 0x03, 0xf4, 0xb2, 0x4d, 0x72, 0xce, 0x90, 0x3f, 0x9b, 0x54, 0x41, 0xac, 0x47, 0x6b, 0xfc, 0x60, 0xee, 0xa4, 0xa4, 0x71, 0xe6, 0x7c, 0x0a, 0xe8, 0xbf, 0x5e, 0x02, 0x38, 0xde, 0x41, 0x1b, 0xfa, 0x3e, 0x65, 0xc9, 0x28, 0xe2, 0x32, 0xb8, 0x91, 0x0f, 0x50, 0x4e, 0xc9, 0x9a, 0x46, 0x05, 0xfa, 0xcb, 0x9b, 0x4d, 0x28, 0xc4, 0x32, 0x37, 0xb1, 0x37, 0xe6, 0x85, 0x47, 0xaa, 0x54, 0xaa, 0xb5, 0x81, 0x5a, 0x54, 0xcc, 0x7f, 0x21, 0x99, 0xbd, 0x97, 0x56, 0x0b, 0x58, 0x45, 0xbd, 0x2a, 0x9a, 0x3d, 0x24, 0x6a, 0xca, 0xb3, 0xee, 0x42, 0x49, 0x45, 0xcc, 0x42, 0x3c, 0xc8, 0x71, 0xe8, 0x05, 0x63, 0x5b, 0xe9, 0x13, 0xa9, 0x55, 0xa5, 0x5c, 0xd2, 0x60, 0x80, 0x74, 0x0d, 0x00, 0x49, 0xd1, 0x3b, 0x6f, 0x47, 0xf3, 0xe9, 0x4b, 0x64, 0x1c, 0x2a, 0x47, 0xbc, 0x66, 0x87, 0x1b, 0x33, 0x98, 0x0f, 0x93, 0xd1, 0xcd, 0xe1, 0x8f, 0x93, 0x8f, 0x4e, 0xa2, 0xd3, 0x1c, 0x42, 0x4d, 0x38, 0xc6, 0xd0, 0x00, 0xba, 0x8b, 0xa6, 0x39, 0x5b, 0x4c, 0x3c, 0x82, 0x9d, 0x1f, 0x5e, 0x65, 0x0a, 0x51, 0x54, 0x58, 0xf5, 0x90, 0x2c, 0x4b, 0x03, 0xf2, 0xbc, 0x61, 0x87, 0x0e, 0x72, 0x96, 0x74, 0xb8, 0x38, 0x77, 0x68, 0x32, 0x6f, 0x5c, 0x91, 0xd2, 0x8e, 0xcb, 0xb4, 0x37, 0xe5, 0xfc, 0xa5, 0x84, 0x4f, 0xa1, 0x12, 0xbc, 0xdd, 0x38, 0x32, 0x71, 0xe0, 0xd0, 0x74, 0x85, 0xc7, 0x3f, 0xcc, 0xce, 0x81, 0xbf, 0x93, 0x4f, 0xf8, 0x4a, 0xba, 0x15, 0xfe, 0x3b, 0xe0, 0x71, 0x73, 0xcb, 0x31, 0xe0, 0xb9, 0x48, 0xc0, 0xff, 0xd3, 0xf5, 0xbc, 0x96, 0xef, 0x9c, 0xd4, 0xd6, 0xc5, 0xd0, 0x38, 0x17, 0xfa, 0x71, 0x4f, 0x88, 0x45, 0xc1, 0xc1, 0x41, 0x3d, 0xf0, 0x59, 0x7f, 0x1b, 0x2b, 0x77, 0x43, 0x15, 0x76, 0xb2, 0x4f, 0x9e, 0x35, 0x32, 0x48, 0x46, 0x16, 0x9a, 0x6a, 0xb6, 0xc0, 0x66, 0xdc, 0xa0, 0xf1, 0xa2, 0x3f, 0xb7, 0x33, 0x84, 0xd0, 0x66, 0x1c, 0x88, 0xcd, 0x98, 0xe7, 0xd2, 0x11, 0x69, 0x24, 0x89, 0x18, 0x69, 0x54, 0xc1, 0x43, 0x1d, 0x27, 0xd9, 0x75, 0x75, 0x0e, 0xe1, 0x52, 0xc1, 0xb3, 0x4f, 0x69, 0x90, 0x20, 0xcc, 0x25, 0x8d, 0xa9, 0xfa, 0x00, 0x40, 0xf7, 0x2f, 0x32, 0x91, 0x9a, 0x3c, 0x4f, 0xa7, 0x6a, 0xf7, 0x7f, 0x53, 0x63, 0xb0, 0x29, 0xb2, 0xfb, 0x47, 0x6b, 0xb4, 0x58, 0xe3, 0xef, 0xa4, 0xf6, 0xd9, 0x17, 0x93, 0x5f, 0xef, 0x90, 0x44, 0xd5, 0x9f, 0x32, 0x70, 0xe3, 0xa1, 0x3e, 0xa0, 0xa4, 0x17, 0xcf, 0x88, 0x20, 0x17, 0xbb, 0xc3, 0x6f, 0x84, 0xbf, 0x92, 0x85, 0x84, 0xcd, 0x6d, 0x3e, 0x9b, 0xa1, 0xb3, 0xcb, 0xc4, 0xf0, 0x4e, 0x12, 0xdc, 0xb1, 0x88, 0x53, 0x1c, 0x79, 0x62, 0x21, 0x0a, 0x35, 0xc1, 0xb7, 0x2d, 0xd0, 0x67, 0xc7, 0x36, 0x76, 0xb4, 0xac, 0x4f, 0x14, 0xee, 0x78, 0xbd, 0x2c, 0xa1, 0x62, 0x4d, 0x4d, 0xb9, 0x25, 0x9e, 0x5e, 0xe8, 0x26, 0xdc, 0xf7, 0x69, 0x88, 0x2e, 0x05, 0xc9, 0xc0, 0x04, 0x88, 0x33, 0xe4, 0xf1, 0xac, 0x92, 0x1f, 0xb9, 0xa2, 0xf8, 0xab, 0xc8, 0xbb, 0x8a, 0x04, 0x53, 0x10, 0x8e, 0x8f, 0x4f, 0x22, 0xb6, 0x34, 0xf0, 0x25, 0x42, 0x0d, 0x0a, 0x87, 0xec, 0xa3, 0x68, 0xf8, 0x10, 0x01, 0x30, 0x18, 0x15, 0xda, 0x91, 0xa9, 0xd4, 0xff, 0xed, 0xa4, 0xff, 0xf6, 0x78, 0xca, 0xd7, 0x4b, 0x27, 0x0d, 0xf3, 0xe9, 0x5f, 0x36, 0x9d, 0x59, 0x16, 0xa4, 0x04, 0xef, 0xec, 0x7d, 0x01, 0x0a, 0x39, 0xa5, 0x4b, 0x80, 0x68, 0xb3, 0xb4, 0x00, 0xcf, 0xbd, 0xd0, 0xcf, 0x09, 0xf2, 0x7c, 0xe6, 0x3b, 0xaa, 0xf2, 0xfa, 0xc3, 0xfb, 0x94, 0x68, 0x13, 0x0f, 0xf0, 0x1b, 0xe1, 0xce, 0x77, 0xa2, 0x1f, 0x41, 0xb4, 0x9a, 0x40, 0x1d, 0x90, 0x0d, 0x22, 0x64, 0xef, 0x0f, 0xcd, 0x95, 0x11, 0x45, 0x22, 0x27, 0x3c, 0xd7, 0x57, 0xaf, 0x09, 0xab, 0xa8, 0xe5, 0x06, 0x54, 0x07, 0x4f, 0xbb, 0xd4, 0x83, 0x3b, 0xc4, 0x10, 0xaf, 0x75, 0x5e, 0x17, 0x7d, 0x69, 0xc4, 0x36, 0x36, 0x4a, 0x15, 0x2e, 0x01, 0x62, 0xdb, 0x2f, 0x92, 0xb2, 0x99, 0xed, 0x07, 0xad, 0xc1, 0x4a, 0x56, 0xa4, 0x8e, 0x10, 0x11, 0x06, 0xcc, 0xe4, 0x37, 0xb0, 0x5c, 0x77, 0xd8, 0x48, 0xf3, 0x5f, 0xf7, 0x71, 0xa0, 0xfb, 0x70, 0x84, 0x3f, 0x8a, 0x60, 0xf9, 0x1c, 0x17, 0xf7, 0x02, 0x9b, 0xe3, 0x70, 0x43, 0x8a, 0xba, 0xdd, 0xb4, 0xfe, 0xa7, 0xb2, 0x70, 0x1b, 0xdf, 0xd3, 0x77, 0x53, 0x63, 0xa2, 0x42, 0x29, 0x58, 0x05, 0xa8, 0xde, 0x86, 0x7a, 0xf4, 0xd9, 0x0e, 0xb9, 0xb1, 0x94, 0xdf, 0xa6, 0x3c, 0x6e, 0x88, 0x28, 0xed, 0x71, 0x15, 0x96, 0xb6, 0xde, 0xfe, 0xa5, 0x83, 0xd3, 0xf8, 0xe0, 0xd0, 0xd2, 0x2b, 0x66, 0xf1, 0x11, 0x1e, 0x3e, 0xaa, 0xea, 0x84, 0xbc, 0xe8, 0xe9, 0x3f, 0xfe, 0x62, 0x4c, 0x94, 0x76, 0xe7, 0x4a, 0x1e, 0x3f, 0xfb, 0x9b, 0x49, 0x82, 0xcc, 0xd9, 0xaa, 0xcb, 0x17, 0x8b, 0xa0, 0x63, 0x71, 0x82, 0x6f, 0xaa, 0xb9, 0x46, 0x26, 0x23, 0x2c, 0xab, 0x99, 0xcc, 0x33, 0xd6, 0x48, 0xa6, 0x3d, 0x08, 0xde, 0x04, 0x39, 0xbc, 0x35, 0x0c, 0x22, 0xcd, 0x16, 0x9c, 0xd5, 0x12, 0xe1, 0x2b, 0xc6, 0x9e, 0xf8, 0x76, 0xef, 0xb8, 0x29, 0xd3, 0xf2, 0x46, 0x3f, 0xb3, 0x03, 0x50, 0x3c, 0xe2, 0x3f, 0xd6, 0xa2, 0x74, 0x7e, 0xa7, 0xd1, 0x20, 0x43, 0x79, 0x2d, 0x39, 0x03, 0x20, 0x4b, 0x3f, 0xb1, 0x07, 0xe9, 0xe1, 0x59, 0x36, 0x37, 0xdc, 0x26, 0x34, 0x9e, 0x43, 0xfc, 0xab, 0xf7, 0xe4, 0xe4, 0xc7, 0xd6, 0x73, 0x8d, 0x54, 0x60, 0x54, 0xf2, 0x85, 0xac, 0x44, 0xb7, 0x9d, 0xec, 0x04, 0x14, 0x29, 0xef, 0x56, 0x9f, 0x1c, 0x44, 0x0e, 0x9f, 0x37, 0x3b, 0xe5, 0xdb, 0x70, 0xbe, 0xa7, 0xb2, 0x66, 0x69, 0x73, 0x4d, 0x19, 0xf0, 0x91, 0xe3, 0xcd, 0x07, 0x58, 0x84, 0x63, 0x7f, 0x89, 0x0f, 0x85, 0x41, 0xe9, 0x5d, 0x6b, 0xb7, 0x92, 0x24, 0x54, 0xbc, 0xd2, 0x37, 0xec, 0x1f, 0x40, 0x75, 0xa1, 0x36, 0xbb, 0x51, 0xf3, 0xc0, 0xe1, 0xc0, 0xc8, 0xfc, 0x78, 0x3d, 0x36, 0x89, 0xd2, 0x02, 0xed, 0xe8, 0x08, 0xba, 0x53, 0xb7, 0x42, 0x03, 0x41, 0x91, 0xa2, 0x6c, 0x1c, 0x78, 0x7b, 0x18, 0xab, 0xe4, 0x5c, 0x4a, 0x84, 0xc5, 0xaf, 0xe5, 0x5e, 0xa8, 0xa4, 0x8a, 0x77, 0x4c, 0xcf, 0x87, 0x87, 0xd6, 0xcd, 0x46, 0xf6, 0x48, 0x47, 0xf6, 0x6a, 0x47, 0x53, 0xdc, 0xa4, 0xea, 0x90, 0x6a, 0xd0, 0x7b, 0x72, 0x0e, 0x60, 0x80, 0x41, 0xac, 0xdd, 0x0d, 0x98, 0xa2, 0x95, 0xf4, 0x00, 0xaf, 0x65, 0x10, 0x00, 0x34, 0xc6, 0xbd, 0xb2, 0x1f, 0x63, 0x18, 0xfe, 0xd1, 0xba, 0xd7, 0x50, 0xdf, 0xa0, 0x5a, 0x02, 0x4b, 0xd2, 0x36, 0xfc, 0x96, 0xd5, 0x22, 0x09, 0x68, 0x75, 0x30, 0xad, 0x6c, 0xd0, 0x4b, 0xe0, 0x74, 0xa9, 0x30, 0x24, 0x40, 0xa5, 0xb5, 0x75, 0x69, 0x1a, 0x3a, 0x56, 0x3e, 0xe7, 0xe9, 0x96, 0xf6, 0xcc, 0x11, 0x7f, 0x2a, 0x5d, 0xa1, 0x3c, 0x6a, 0xec, 0xb9, 0x5b, 0xef, 0x6b, 0xd1, 0x78, 0xb1, 0x77, 0x5e, 0xfe, 0x5c, 0x00, 0xac, 0x0f, 0x8d, 0x8d, 0x60, 0x9d, 0xfe, 0xd6, 0xc4, 0x3b, 0xd9, 0xda, 0x6b, 0xc8, 0x00, 0x77, 0x85, 0xd3, 0x46, 0x31, 0x9c, 0x66, 0xd9, 0x36, 0x55, 0xaa, 0xd3, 0x8c, 0xbe, 0x4f, 0xe7, 0xd4, 0xd2, 0x40, 0x2e, 0x67, 0xa9, 0x81, 0x77, 0x65, 0x4c, 0x01, 0x31, 0x77, 0x2e, 0x9b, 0x03, 0xa0, 0x81, 0x54, 0x3d, 0xd4, 0x32, 0xf2, 0x69, 0x68, 0x60, 0xfd, 0x6b, 0xef, 0xcd, 0xac, 0x14, 0x89, 0xdb, 0x10, 0xa1, 0x89, 0xb2, 0x54, 0x5a, 0xd7, 0xb8, 0x99, 0x92, 0x19, 0xfe, 0xd1, 0xe6, 0x5e, 0xf1, 0xfe, 0xac, 0x94, 0x6b, 0x97, 0xc2, 0x1f, 0xa0, 0x85, 0x91, 0xe1, 0x67, 0xb4, 0x09, 0x88, 0xee, 0xbf, 0x29, 0x66, 0x30, 0x09, 0x64, 0x37, 0x8c, 0x09, 0x3b, 0x5c, 0xee, 0x78, 0x30, 0x87, 0x28, 0x7f, 0x67, 0x93, 0xe9, 0x07, 0x7e, 0xb7, 0xde, 0xe3, 0xcb, 0xb4, 0x67, 0xa9, 0x27, 0x8f, 0x99, 0x50, 0xf5, 0x4d, 0x11, 0x7e, 0x68, 0x61, 0xc3, 0xa9, 0xe4, 0x1d, 0x8d, 0xe7, 0x8e, 0x25, 0x90, 0x4d, 0xaf, 0xd7, 0xe0, 0xf5, 0xb6, 0x53, 0xea, 0xad, 0x4d, 0xc6, 0x95, 0x24, 0x35, 0xb5, 0xf6, 0xc9, 0x08, 0xd1, 0x3c, 0x8f, 0x63, 0x0e, 0x87, 0x6a, 0x1a, 0x0e, 0x47, 0x78, 0x57, 0x19, 0xf8, 0xb6, 0x61, 0x91, 0x45, 0x69, 0x3b, 0x10, 0x63, 0xce, 0x62, 0x86, 0x94, 0xc5, 0xad, 0x5c, 0x5f, 0x31, 0x22, 0x08, 0xe3, 0x18, 0x02, 0x68, 0x72, 0x93, 0x00, 0xc3, 0x0d, 0x2b, 0x52, 0xc8, 0x48, 0xa6, 0xdd, 0xdc, 0x7d, 0xf5, 0x51, 0x1b, 0x99, 0xe3, 0x37, 0xf9, 0x30, 0x03, 0x75, 0x3b, 0x75, 0x79, 0xbd, 0x98, 0x0f, 0xb9, 0xe4, 0x7e, 0x4e, 0x9b, 0xa8, 0x9a, 0xc8, 0x26, 0x82, 0x37, 0x14, 0x08, 0x5b, 0xb4, 0x5e, 0xa1, 0x01, 0x99, 0x6e, 0xdf, 0x6c, 0x24, 0x9d, 0x54, 0xda, 0x11, 0x85, 0x78, 0x29, 0xab, 0x8f, 0x3c, 0x15, 0x5f, 0x9f, 0xcb, 0x71, 0xdd, 0x70, 0xfb, 0xfb, 0xc2, 0x82, 0xcc, 0x90, 0x70, 0x4d, 0xd4, 0x5e, 0x1e, 0xf8, 0xe9, 0x16, 0x9a, 0x5a, 0xb8, 0xfb, 0x2c, 0xd2, 0xdc, 0xf3, 0xb5, 0x62, 0xa2, 0xae, 0xf0, 0xe3, 0x37, 0xac, 0x0b, 0xcc, 0x46, 0x20, 0x4d, 0x2e, 0xaa, 0x11, 0x9f, 0x22, 0xa3, 0x86, 0x5b, 0xff, 0x03, 0x65, 0x04, 0x98, 0xed, 0xd4, 0x12, 0x53, 0x56, 0xbd, 0x3a, 0x9e, 0x82, 0xe5, 0x14, 0x9e, 0x8c, 0xc0, 0x6a, 0xfc, 0xce, 0x9f, 0x82, 0xc0, 0x74, 0x18, 0x59, 0xd7, 0xd4, 0x99, 0xb8, 0xd6, 0x10, 0x16, 0xa6, 0xe5, 0xa6, 0x1c, 0x51, 0x5d, 0xd9, 0xc8, 0x52, 0x11, 0x40, 0x9d, 0xfd, 0xfa, 0x3b, 0x6e, 0x09, 0x94, 0x1e, 0x00, 0x3d, 0x0b, 0xf6, 0xbd, 0x8d, 0x4b, 0x83, 0xd0, 0xae, 0xe4, 0xfb, 0xa0, 0x28, 0x95, 0xd6, 0x22, 0xae, 0x88, 0xbb, 0x31, 0xbf, 0xfd, 0x03, 0xee, 0x23, 0x8c, 0x18, 0x9d, 0x3c, 0x6b, 0xfc, 0xeb, 0x03, 0x38, 0x84, 0xe3, 0xbd, 0x77, 0xb5, 0x26, 0xe5, 0xc5, 0xc7, 0xf7, 0x0a, 0x01, 0x79, 0x08, 0xa7, 0x72, 0x74, 0x31, 0xac, 0xf6, 0xda, 0x88, 0x72, 0x41, 0xc7, 0x06, 0xd2, 0x69, 0xe9, 0x92, 0x0e, 0xc1, 0x36, 0x45, 0x67, 0xa0, 0xdd, 0xc1, 0x8d, 0x7b, 0x25, 0xc5, 0x34, 0x20, 0x65, 0x11, 0xe4, 0x2b, 0xd6, 0x43, 0x4f, 0x36, 0xfb, 0x26, 0x23, 0x0f, 0xe1, 0x37, 0xc6, 0xf3, 0xa5, 0x4b, 0x83, 0x5d, 0x99, 0xb6, 0xb2, 0xac, 0x22, 0xaf, 0x8c, 0xc5, 0x33, 0x1c, 0x56, 0x2c, 0xa5, 0xcd, 0x9b, 0x19, 0xe9, 0x95, 0xf1, 0xc4, 0x90, 0x5f, 0xc5, 0xd9, 0x1b, 0xa0, 0x4c, 0x0b, 0x97, 0x2a, 0xbe, 0xcc, 0xfe, 0x85, 0xec, 0x72, 0x60, 0xcd, 0xfc, 0xd5, 0xcf, 0xb4, 0x02, 0x8f, 0x1f, 0xa1, 0x54, 0x9c, 0x53, 0x9f, 0x75, 0x52, 0xb4, 0xd8, 0xbb, 0x64, 0x4a, 0xfa, 0x11, 0x47, 0xbf, 0xa3, 0xc8, 0xe6, 0xe6, 0xbe, 0x1d, 0xdd, 0xd0, 0x98, 0xcf, 0xd5, 0x90, 0x58, 0xd8, 0x78, 0x78, 0x6b, 0xfc, 0xc1, 0x4d, 0x35, 0x48, 0xef, 0xdd, 0xd4, 0x03, 0xb2, 0xdd, 0x1b, 0xb5, 0x89, 0x19, 0x39, 0x19, 0x88, 0x85, 0xe8, 0xba, 0x6e, 0x46, 0x7b, 0x62, 0x6b, 0x54, 0xd3, 0x71, 0x10, 0xae, 0xec, 0xd6, 0x43, 0x46, 0x87, 0xda, 0xc7, 0x00, 0x94, 0xad, 0xfd, 0xa1, 0x3c, 0xa5, 0xff, 0xa9, 0xc9, 0xcf, 0x59, 0xd3, 0x97, 0xd1, 0x53, 0x0a, 0x1c, 0x86, 0xc3, 0x3a, 0x64, 0xeb, 0xac, 0x42, 0xac, 0xa3, 0xcb, 0x3d, 0xaa, 0xac, 0x31, 0x38, 0x2e, 0x4d, 0x3d, 0xaa, 0x4b, 0x2a, 0x62, 0x3a, 0xd2, 0xfe, 0xdb, 0xfe, 0xc5, 0xb3, 0x31, 0xfe, 0x2f, 0x35, 0x68, 0xb1, 0xfc, 0x30, 0xb4, 0x90, 0x0f, 0x65, 0x86, 0x28, 0x8b, 0x29, 0xd7, 0x44, 0x50, 0x0f, 0x43, 0xda, 0xcd, 0x98, 0x1e, 0x6a, 0xec, 0x78, 0x47, 0xe3, 0x9d, 0x5d, 0x76, 0x96, 0x1e, 0x3b, 0x3c, 0x93, 0x1e, 0x73, 0x3b, 0xe0, 0xf6, 0xf7, 0x63, 0x93, 0x3d, 0x63, 0x59, 0x8e, 0x81, 0xc3, 0x30, 0x7a, 0xf5, 0xbd, 0xec, 0xc3, 0xdb, 0x06, 0x7a, 0x8e, 0x5b, 0xd1, 0x05, 0x88, 0x27, 0x41, 0xd6, 0xc2, 0x56, 0x02, 0x58, 0x7e, 0x51, 0x1a, 0x3b, 0xec, 0xbe, 0x76, 0x7f, 0x2e, 0xb3, 0x5f, 0x8f, 0xaf, 0xdf, 0x96, 0x72, 0xfa, 0x35, 0x05, 0x50, 0x09, 0x2c, 0x0b, 0x3a, 0x8d, 0x9c, 0x1a, 0x18, 0xd3, 0x0c, 0x35, 0x35, 0xd0, 0xd6, 0x60, 0x3e, 0x71, 0x0d, 0x2d, 0x6f, 0xb7, 0xd4, 0xee, 0x00, 0x59, 0x58, 0x53, 0x90, 0xcd, 0x31, 0x66, 0x69, 0xd5, 0x09, 0x26, 0x8b, 0x3a, 0x80, 0x54, 0x55, 0xe6, 0xf1, 0x1f, 0x4f, 0x2b, 0xf9, 0xa2, 0x41, 0xbd, 0x1c, 0xe0, 0x36, 0xad, 0x71, 0x68, 0x32, 0xf6, 0x11, 0xf8, 0x48, 0xd1, 0xd6, 0x6d, 0x7e, 0x62, 0x17, 0xeb, 0xa3, 0x5c, 0x77, 0xa7, 0x23, 0x5c, 0xc8, 0xd2, 0x32, 0xb4, 0xad, 0xf2, 0x0c, 0x07, 0xff, 0x7d, 0x86, 0x8c, 0x91, 0x79, 0x71, 0x0a, 0xe8, 0x2a, 0x43, 0xfa, 0xdc, 0xcc, 0x25, 0x4d, 0x72, 0xc8, 0xce, 0x6b, 0x8a, 0x6e, 0x00, 0x07, 0x00, 0x83, 0x29, 0x50, 0xec, 0x99, 0x30, 0x4e, 0x4d, 0xea, 0xa6, 0x14, 0x5f, 0x11, 0x47, 0xa1, 0x65, 0xa5, 0xf6, 0x11, 0xb3, 0x12, 0xaa, 0xe5, 0xfb, 0x83, 0x62, 0xf4, 0x29, 0x19, 0x10, 0xcf, 0x99, 0x01, 0xcd, 0x80, 0xef, 0x97, 0x23, 0x0c, 0x95, 0xc0, 0xbd, 0xcd, 0xf4, 0x96, 0x62, 0xc2, 0x91, 0x8d, 0xfb, 0x3a, 0xac, 0x0a, 0x01, 0x0e, 0xa3, 0xa6, 0xb0, 0xe6, 0xef, 0x3a, 0xe3, 0xe4, 0xd2, 0x68, 0xd7, 0x0c, 0x72, 0xca, 0x94, 0xad, 0xc7, 0x47, 0x23, 0xcf, 0x15, 0xd0, 0xa6, 0x4f, 0x79, 0x66, 0xb5, 0x87, 0xa6, 0x5e, 0x2e, 0x94, 0x93, 0x44, 0x1f, 0x32, 0xc5, 0x2d, 0xf2, 0x47, 0x67, 0x2c, 0x16, 0x80, 0x2a, 0xac, 0x0c, 0x0f, 0x94, 0x4b, 0xa9, 0xd9, 0xb4, 0x07, 0xda, 0xef, 0x5f, 0x8e, 0xd3, 0xec, 0x08, 0x2b, 0x85, 0x66, 0xd2, 0x4f, 0x61, 0x53, 0x97, 0x55, 0xda, 0x91, 0xea, 0x15, 0x85, 0x5a, 0x5e, 0x78, 0x2a, 0xb8, 0x2e, 0x3b, 0x82, 0x4b, 0xd8, 0x1c, 0x4d, 0xed, 0xb5, 0xdd, 0xa1, 0xf0, 0x91, 0x73, 0x26, 0xc0, 0xa9, 0x28, 0x49, 0xda, 0xd7, 0x15, 0x1f, 0x81, 0xf7, 0xdb, 0x48, 0x49, 0x57, 0x83, 0x9b, 0x87, 0x5d, 0xab, 0xbf, 0x9b, 0x15, 0x4f, 0x21, 0xe4, 0xb9, 0x2a, 0x15, 0xfd, 0x9c, 0x77, 0x71, 0x70, 0x5c, 0xb2, 0x48, 0xf1, 0x6e, 0x4d, 0x93, 0x5a, 0x30, 0x78, 0x40, 0x24, 0xdd, 0x22, 0x18, 0xff, 0xc8, 0x18, 0x97, 0xc5, 0x17, 0xe1, 0x11, 0x94, 0xd7, 0x3e, 0x47, 0xd5, 0xa4, 0xcc, 0x34, 0xe3, 0x22, 0x96, 0x07, 0xe7, 0x2e, 0x84, 0xa6, 0x69, 0x7c, 0x97, 0xfb, 0x89, 0xe8, 0xea, 0x18, 0xcd, 0xe1, 0x95, 0x4d, 0x2e, 0x8d, 0xbe, 0xeb, 0xc1, 0x83, 0x69, 0xb2, 0xc5, 0xce, 0x72, 0x65, 0x50, 0x02, 0xea, 0xce, 0x57, 0x33, 0xc7, 0xcb, 0xe9, 0x04, 0x59, 0x22, 0x0e, 0xac, 0xb9, 0xf0, 0xf6, 0x7a, 0xb9, 0x00, 0x17, 0x0a, 0xd7, 0x7c, 0x31, 0xfc, 0x35, 0x39, 0x43, 0x11, 0x8f, 0x91, 0xed, 0x2c, 0xde, 0x7d, 0xce, 0x28, 0xae, 0xc0, 0xb4, 0x63, 0x80, 0x91, 0xe4, 0x61, 0xd5, 0x12, 0x7f, 0x3b, 0x82, 0x88, 0x02, 0x9e, 0xda, 0xa7, 0xfc, 0x99, 0x4a, 0xa3, 0x0b, 0x8b, 0xfd, 0x59, 0x94, 0x03, 0xde, 0xb0, 0x52, 0x90, 0xa6, 0xda, 0xee, 0xa6, 0x54, 0x7c, 0xb1, 0xca, 0x45, 0xed, 0x5a, 0xf0, 0xc8, 0xcc, 0xb6, 0x5f, 0x41, 0x8c, 0xbb, 0x5a, 0x29, 0x21, 0x60, 0x4b, 0x9e, 0x8a, 0x97, 0x88, 0xb5, 0xbe, 0x59, 0x95, 0x72, 0x4e, 0x68, 0x5f, 0x72, 0x6e, 0xec, 0x46, 0x88, 0x42, 0x34, 0xa0, 0x28, 0x48, 0x00, 0xac, 0x94, 0x7a, 0x47, 0x75, 0x2e, 0xf1, 0x9f, 0x84, 0x74, 0x99, 0x62, 0x6d, 0xfb, 0x2b, 0xaa, 0x5b, 0xd8, 0xfe, 0x8c, 0xca, 0x57, 0xb2, 0xf4, 0xfd, 0x83, 0x54, 0xb6, 0xd4, 0x5c, 0x06, 0x47, 0xa1, 0xb7, 0x13, 0xaa, 0x24, 0x93, 0xf8, 0xe0, 0xa8, 0xcf, 0x14, 0xba, 0xa1, 0x88, 0xea, 0x35, 0xba, 0xfa, 0x15, 0xc0, 0x1b, 0x18, 0xfd, 0x32, 0xeb, 0x9a, 0x01, 0xf9, 0x05, 0x0f, 0x9e, 0xa0, 0x8a, 0xa9, 0xf9, 0xb5, 0x89, 0x89, 0xb2, 0x8b, 0x42, 0xf3, 0x6f, 0xaf, 0x2f, 0xb5, 0x69, 0xf1, 0x8c, 0xf5, 0x5f, 0xf3, 0xc8, 0x5b, 0xd5, 0xa6, 0x08, 0xe4, 0x33, 0xe1, 0x28, 0xf2, 0xcb, 0xaa, 0xce, 0x12, 0x86, 0x21, 0xb9, 0x14, 0x98, 0x36, 0xbd, 0xdc, 0xd2, 0xd8, 0x87, 0x4f, 0xbb, 0xab, 0xfd, 0x6a, 0xe0, 0x9e, 0xae, 0x21, 0x42, 0xf3, 0x9f, 0xfb, 0xd8, 0xc8, 0x90, 0x77, 0x07, 0x78, 0x1d, 0xbb, 0x63, 0xa0, 0x17, 0x46, 0x16, 0xd8, 0x94, 0x77, 0x89, 0x23, 0x0c, 0xc7, 0xf9, 0xf3, 0x41, 0xb6, 0x98, 0x1c, 0xc8, 0xd7, 0x79, 0x38, 0x26, 0xe1, 0x0e, 0xf6, 0xb7, 0xa7, 0x77, 0xcc, 0x24, 0x3b, 0x6d, 0x15, 0x95, 0xcb, 0x6f, 0x9b, 0x51, 0xa0, 0x9b, 0xe6, 0x5e, 0x0c, 0x65, 0x62, 0xb9, 0x12, 0xca, 0x66, 0x1e, 0x35, 0x3e, 0x23, 0x3f, 0x39, 0xe3, 0x6f, 0x80, 0x64, 0x3d, 0x08, 0x84, 0x50, 0xf2, 0x39, 0xb3, 0xa7, 0x34, 0xa5, 0x4d, 0x4a, 0x35, 0x14, 0x11, 0x72, 0xbf, 0xf8, 0xcc, 0x74, 0x6a, 0x3e, 0x46, 0xac, 0xa3, 0x85, 0x89, 0xb0, 0xaf, 0xd9, 0x1d, 0x50, 0x87, 0xf8, 0x27, 0xf3, 0x01, 0xeb, 0xde, 0xc8, 0x69, 0x8a, 0x71, 0x0d, 0xd1, 0x7c, 0xa3, 0xbe, 0x73, 0xa3, 0x04, 0xf2, 0xe1, 0xb8, 0x2a, 0x0c, 0x72, 0xdf, 0xac, 0x45, 0xb1, 0xb5, 0xa5, 0xba, 0xc4, 0x14, 0x54, 0x1a, 0x0b, 0x2a, 0x0d, 0xd9, 0x4b, 0x2a, 0x2d, 0xbf, 0x06, 0x07, 0xfe, 0x3f, 0xf8, 0x3d, 0x50, 0x85, 0x07, 0x66, 0x1f, 0x63, 0xb4, 0x9b, 0xbe, 0x42, 0x55, 0x31, 0x87, 0xc2, 0xeb, 0xdd, 0x71, 0x03, 0xe2, 0xd0, 0x3f, 0x75, 0xa2, 0xee, 0xe8, 0xea, 0x05, 0x51, 0x04, 0x31, 0x3f, 0x40, 0x03, 0xec, 0x71, 0xcd, 0xe6, 0x23, 0x05, 0x1f, 0x7c, 0x18, 0x64, 0x60, 0x92, 0x99, 0xad, 0x9c, 0x3b, 0xeb, 0xe0, 0xee, 0x91, 0x39, 0xd3, 0x8d, 0x54, 0x1e, 0xba, 0x0f, 0x93, 0xce, 0x3a, 0x5c, 0x10, 0x73, 0x37, 0x7a, 0x5d, 0x8b, 0x9e, 0x5e, 0x8a, 0x75, 0x46, 0x03, 0xf0, 0x48, 0x63, 0xee, 0x4d, 0x64, 0x76, 0x69, 0x0c, 0x0e, 0xf0, 0x54, 0x69, 0x5d, 0xd1, 0x33, 0x18, 0x01, 0x73, 0x06, 0x30, 0x6f, 0x1f, 0x68, 0xd6, 0x82, 0x1c, 0xbf, 0x85, 0xeb, 0xcf, 0x73, 0xa9, 0x11, 0xe4, 0xf7, 0x64, 0x02, 0x58, 0x02, 0x00, 0x62, 0xb7, 0x97, 0x82, 0x21, 0x47, 0x1d, 0x47, 0xff, 0x58, 0x7f, 0x2a, 0x7f, 0xb4, 0x50, 0xee, 0x12, 0x26, 0xde, 0x1e, 0xf9, 0x10, 0x79, 0x80, 0x2a, 0x6e, 0xd5, 0x18, 0x90, 0x3d, 0x6d, 0x1e, 0x87, 0x37, 0x47, 0xd0, 0xc8, 0x67, 0xf0, 0x16, 0xa9, 0x48, 0xad, 0x46, 0x8c, 0x73, 0xa9, 0x31, 0x33, 0xc6, 0x7b, 0x3f, 0x06, 0x68, 0xf6, 0xc7, 0x3e, 0x5a, 0x15, 0xd6, 0x8e, 0x09, 0x27, 0x24, 0x9b, 0x49, 0x54, 0x21, 0xd1, 0x36, 0x91, 0x31, 0xe4, 0xd8, 0x7c, 0xf8, 0xe2, 0x4b, 0x3b, 0x27, 0x3f, 0xb8, 0x6c, 0x37, 0x18, 0xa6, 0x62, 0x12, 0x29, 0xec, 0x4c, 0xe5, 0xde, 0x0a, 0x26, 0x4c, 0xef, 0x61, 0xe8, 0xe6, 0xda, 0x1d, 0x1e, 0x17, 0xb9, 0xfe, 0x3c, 0x0b, 0x22, 0xc7, 0x45, 0x40, 0x8a, 0x1c, 0xa2, 0xfb, 0x0f, 0xc6, 0x55, 0x4e, 0x9d, 0x41, 0xcd, 0x6e, 0x32, 0x6d, 0x84, 0xbb, 0xe5, 0xe3, 0xea, 0x89, 0x81, 0x0c, 0x71, 0x99, 0xc5, 0xa3, 0xa1, 0x24, 0x7c, 0x33, 0x00, 0x00, 0x05, 0x95, 0xf7, 0x07, 0x69, 0x61, 0x18, 0xa7, 0xb2, 0xf0, 0x30, 0xb6, 0x57, 0x39, 0xb9, 0x36, 0x35, 0xcd, 0x51, 0xa0, 0x1c, 0x89, 0x3d, 0xa3, 0x81, 0x4b, 0xaa, 0x1b, 0x80, 0x17, 0x50, 0x6f, 0xa4, 0xb5, 0x54, 0x4d, 0xc1, 0xe4, 0x26, 0xe2, 0x8d, 0xd0, 0xda, 0x38, 0xc8, 0xbf, 0xcf, 0x4e, 0x33, 0x52, 0xfa, 0x37, 0x93, 0x60, 0x98, 0x93, 0x39, 0x9c, 0xe6, 0x80, 0xf7, 0x2b, 0xcc, 0x1b, 0xf9, 0xea, 0xef, 0xfd, 0x15, 0xcf, 0x6f, 0x6c, 0x37, 0xdc, 0xa5, 0x92, 0xc0, 0x86, 0x53, 0xd8, 0xaf, 0xa4, 0x3c, 0xb2, 0x2c, 0xcf, 0xd7, 0x2d, 0x8d, 0x6c, 0xb7, 0x7b, 0x63, 0x8b, 0x35, 0xa5, 0x1d, 0x57, 0xec, 0x4b, 0x61, 0x2d, 0xfe, 0x96, 0xd2, 0xfe, 0x6c, 0xfa, 0x27, 0xe5, 0x0b, 0x80, 0xa6, 0x21, 0xdf, 0xe8, 0xf2, 0xfe, 0x49, 0x88, 0x9b, 0xbf, 0x6d, 0x2b, 0x7f, 0xc0, 0x82, 0x57, 0x38, 0x91, 0x31, 0x9f, 0xbc, 0x9f, 0x0b, 0xc0, 0xb0, 0x14, 0x2c, 0x93, 0x74, 0x41, 0x1b, 0x36, 0xb5, 0xe7, 0x7d, 0xe3, 0x5e, 0x1f, 0xcf, 0x3c, 0x7c, 0x08, 0x5a, 0x3d, 0x0a, 0x38, 0x04, 0xa6, 0x21, 0x28, 0x6f, 0x57, 0x66, 0xf6, 0x5f, 0xc3, 0xfe, 0xf8, 0x7f, 0x20, 0x00, 0xc9, 0xfb, 0xf0, 0x83, 0x31, 0xff, 0xf6, 0x22, 0xe0, 0x84, 0x46, 0xa1, 0x02, 0xa9, 0xce, 0x19, 0xf2, 0xce, 0x80, 0x26, 0xda, 0x06, 0xf7, 0x00, 0x8b, 0xab, 0x48, 0x82, 0x0e, 0xe1, 0xfe, 0xae, 0xac, 0x8b, 0xe5, 0x14, 0xfb, 0x01, 0x12, 0x73, 0x91, 0x08, 0xf2, 0x7c, 0x2d, 0x0e, 0xe7, 0xc0, 0x90, 0x60, 0xb9, 0xa1, 0x8e, 0xd0, 0x30, 0x10, 0xd0, 0x51, 0xaa, 0x45, 0xb9, 0x0d, 0x90, 0x90, 0xdc, 0x85, 0x7d, 0xf4, 0xdd, 0x8f, 0x11, 0xed, 0x65, 0x21, 0x2a, 0x87, 0x81, 0x96, 0x3c, 0xd7, 0xa8, 0x86, 0x6a, 0xcb, 0xb9, 0x79, 0xe6, 0xa0, 0xc9, 0xae, 0xa5, 0x4a, 0x05, 0xa5, 0x98, 0xae, 0xd2, 0x27, 0x0a, 0xae, 0x4c, 0x91, 0x95, 0x33, 0xc9, 0x49, 0x1b, 0xb1, 0xfb, 0x81, 0x8b, 0x2b, 0x1b, 0xed, 0xb8, 0xfa, 0x10, 0x6c, 0x16, 0x72, 0x7a, 0x69, 0x33, 0xb4, 0xb4, 0x00, 0x6d, 0xc5, 0x5b, 0x9d, 0x1b, 0x1b, 0xaa, 0xef, 0x69, 0x9b, 0x26, 0xba, 0xb0, 0xf6, 0xd9, 0x53, 0xb4, 0xd7, 0x14, 0x2b, 0x93, 0x4a, 0x23, 0x76, 0x44, 0x9c, 0x68, 0x39, 0x47, 0x35, 0xea, 0x76, 0x50, 0xd5, 0x27, 0xbe, 0xc9, 0x9e, 0x30, 0xa2, 0x93, 0x33, 0xf1, 0xb8, 0x42, 0x7e, 0x0a, 0x76, 0xaa, 0x3a, 0x48, 0x3a, 0x60, 0x40, 0x24, 0xef, 0x15, 0xfa, 0x60, 0x00, 0x95, 0xcd, 0x74, 0x3c, 0x4a, 0x98, 0xe2, 0x66, 0x1c, 0x07, 0x94, 0x2e, 0x45, 0xa2, 0x14, 0x7d, 0xa1, 0x85, 0x09, 0xb6, 0x4f, 0x45, 0xb9, 0x57, 0x5b, 0x4c, 0x1c, 0x26, 0x7b, 0x27, 0xcb, 0xf8, 0x97, 0x40, 0xae, 0x48, 0xc4, 0x09, 0xe4, 0x81, 0x4e, 0x87, 0xab, 0xe4, 0xce, 0x6a, 0xe7, 0x61, 0xb5, 0xae, 0x25, 0x6b, 0x08, 0x4f, 0x3e, 0x4b, 0x4c, 0x0a, 0x4f, 0x2d, 0xa4, 0x52, 0x40, 0x50, 0xf5, 0x21, 0x3e, 0x39, 0xd8, 0x78, 0x74, 0xe3, 0x40, 0x2a, 0x9e, 0xf4, 0xc8, 0x38, 0x86, 0x52, 0x02, 0xba, 0x1b, 0x37, 0x19, 0x14, 0x7b, 0x29, 0x37, 0xf5, 0xf3, 0xaf, 0xdd, 0x4f, 0xec, 0xa5, 0x6f, 0xf6, 0x73, 0x9b, 0x59, 0xec, 0x86, 0x9e, 0x2e, 0xbc, 0x19, 0xc2, 0x68, 0x84, 0xc5, 0x7b, 0xe6, 0x25, 0x68, 0x6d, 0x54, 0x00, 0xf5, 0xbf, 0x92, 0x65, 0x81, 0x22, 0x2c, 0xdf, 0x71, 0x86, 0x3b, 0x90, 0x91, 0x94, 0x4c, 0x23, 0x93, 0x78, 0x4d, 0xee, 0x9e, 0x1d, 0x72, 0xdd, 0x06, 0xc6, 0x00, 0x2f, 0xac, 0xf7, 0x10, 0x0a, 0xdc, 0xa7, 0xbd, 0xdd, 0x4d, 0xcd, 0xf9, 0xf6, 0x76, 0x3c, 0x76, 0x7f, 0xe9, 0xd3, 0x82, 0x80, 0x5b, 0xee, 0xe0, 0x37, 0x99, 0x13, 0x10, 0xa2, 0x2d, 0xb1, 0xaa, 0x5d, 0x6e, 0x90, 0x92, 0x14, 0x80, 0x75, 0xdf, 0x04, 0x25, 0x9c, 0x56, 0xd1, 0x57, 0xce, 0xfc, 0xb0, 0xe7, 0x62, 0xa2, 0x85, 0xb3, 0x2e, 0x84, 0xe5, 0xd2, 0xff, 0x04, 0x07, 0x33, 0x36, 0x89, 0x79, 0x45, 0xe2, 0x95, 0x24, 0xde, 0xf8, 0xd9, 0xa1, 0xd5, 0x0d, 0xfa, 0xdd, 0x0b, 0x4e, 0x0e, 0x65, 0x1e, 0xf4, 0x88, 0x4e, 0xb1, 0xe4, 0xff, 0x05, 0xd5, 0xf0, 0x61, 0x7c, 0x1e, 0x5b, 0x8b, 0x30, 0x42, 0xb0, 0x8d, 0xf3, 0x99, 0x73, 0xa8, 0x67, 0xb0, 0xe4, 0xba, 0x75, 0xd5, 0x64, 0x36, 0xc2, 0x84, 0x82, 0x43, 0xcf, 0x59, 0x72, 0x20, 0x43, 0xdf, 0x0b, 0x11, 0xbe, 0xb3, 0x79, 0x47, 0x7f, 0x3a, 0xf7, 0xf1, 0x5a, 0x8e, 0x71, 0x26, 0x0c, 0x32, 0xbe, 0xb8, 0x30, 0xd3, 0x3d, 0x4f, 0x38, 0xf4, 0x24, 0xb4, 0x4f, 0x80, 0x4a, 0xf9, 0x4a, 0x4f, 0x22, 0x7e, 0x6f, 0xe2, 0xdb, 0xa2, 0x96, 0x49, 0xaf, 0x55, 0x7c, 0x26, 0x18, 0xb8, 0xc0, 0x7e, 0x3c, 0x82, 0x6d, 0x55, 0x6b, 0xb9, 0x8e, 0x6b, 0x14, 0x17, 0xca, 0x65, 0x03, 0x3e, 0xb1, 0xfd, 0x4f, 0x56, 0xd0, 0xc8, 0x8e, 0xaf, 0xe2, 0x76, 0x31, 0x65, 0x8c, 0x62, 0xde, 0x9a, 0xa5, 0x1e, 0xd5, 0x28, 0x46, 0x3b, 0x1e, 0xfb, 0xc7, 0xbf, 0x07, 0xbf, 0x09, 0xba, 0xc1, 0xb9, 0xd5, 0x5a, 0xe9, 0xb1, 0xfd, 0xc3, 0x03, 0x1f, 0x6e, 0xc4, 0x4f, 0xe1, 0x41, 0x36, 0x8a, 0x4e, 0x3a, 0xeb, 0x44, 0xab, 0x00, 0xc4, 0x6a, 0x35, 0xe2, 0x2a, 0xa3, 0xb5, 0x7b, 0xb4, 0x9c, 0x00, 0x85, 0xba, 0x11, 0x5f, 0x9b, 0xc2, 0xeb, 0x0c, 0xfb, 0xa2, 0x36, 0x3b, 0x84, 0x33, 0x7b, 0x6f, 0xfb, 0x2a, 0xd6, 0x47, 0x54, 0xdf, 0x76, 0xff, 0x64, 0x46, 0x41, 0xf7, 0xb0, 0xf2, 0x36, 0xeb, 0xd6, 0x6c, 0x94, 0x1c, 0xe5, 0x0c, 0x26, 0xed, 0xdc, 0xa8, 0x85, 0xdc, 0x85, 0xa9, 0xd2, 0x86, 0x31, 0x6c, 0xe3, 0x6c, 0x9b, 0x6a, 0xd4, 0xb1, 0x9d, 0x1d, 0xd0, 0x41, 0x65, 0x12, 0x43, 0x18, 0x93, 0xa3, 0xfe, 0xc0, 0x6e, 0xe0, 0xcd, 0xb8, 0xb5, 0x2f, 0xf3, 0xc7, 0xaf, 0xc4, 0xaa, 0xfd, 0x71, 0x56, 0xf7, 0x9d, 0x2c, 0x8d, 0x73, 0x79, 0xa3, 0xba, 0xa5, 0x84, 0x53, 0xfa, 0xc2, 0x1c, 0x66, 0xc3, 0x00, 0x1d, 0x43, 0xab, 0xfb, 0x81, 0xd5, 0x92, 0x65, 0x95, 0x9b, 0x23, 0x7c, 0x5f, 0x49, 0xbd, 0x74, 0x55, 0xe5, 0xdb, 0xf8, 0x17, 0x3c, 0xa5, 0x08, 0x0c, 0x9b, 0x87, 0x6f, 0x05, 0x50, 0xf5, 0x12, 0x4a, 0x76, 0x03, 0x23, 0x93, 0xb8, 0x17, 0xbe, 0xcd, 0x70, 0x78, 0xa8, 0x1d, 0x3a, 0xa3, 0x55, 0xc2, 0x12, 0x6c, 0x38, 0x8f, 0x8c, 0x06, 0x23, 0x48, 0x3b, 0x35, 0xe4, 0x60, 0x45, 0xfc, 0x22, 0xe4, 0xb2, 0x03, 0xc9, 0x49, 0x04, 0xe6, 0x21, 0xde, 0x40, 0x02, 0x4e, 0xc2, 0x7f, 0x79, 0x9f, 0x50, 0xab, 0x75, 0xfc, 0x48, 0xb2, 0xdd, 0x2a, 0x85, 0xbe, 0x97, 0xda, 0xb1, 0xf6, 0xef, 0xea, 0xfb, 0x32, 0x70, 0x56, 0xf3, 0xbc, 0x33, 0x18, 0xd6, 0xaa, 0xac, 0xaf, 0x8b, 0x6e, 0x02, 0x08, 0x87, 0x16, 0x03, 0xc2, 0x36, 0x62, 0x56, 0xf2, 0xf4, 0xb6, 0x44, 0x68, 0x99, 0x26, 0x60, 0xfc, 0x30, 0x2d, 0x60, 0x9b, 0x85, 0xd6, 0xa8, 0x0a, 0xf5, 0xcb, 0xdb, 0x51, 0x1b, 0x93, 0x5f, 0xa4, 0x22, 0xd9, 0x8f, 0x48, 0x75, 0x98, 0x7e, 0x66, 0xfc, 0xb4, 0x2f, 0x10, 0xfe, 0xb2, 0xab, 0xa0, 0xb5, 0xc7, 0x89, 0x86, 0x03, 0xb7, 0x96, 0x60, 0x14, 0xb5, 0x41, 0xa7, 0x75, 0x32, 0x63, 0x26, 0x4c, 0x38, 0x4b, 0x5d, 0x56, 0xaf, 0xf9, 0x25, 0x1d, 0xe3, 0x33, 0xf1, 0x8b, 0x77, 0x38, 0xba, 0x88, 0xcc, 0xac, 0x1d, 0x36, 0x91, 0xaf, 0x3c, 0x34, 0xbc, 0x75, 0x79, 0x6e, 0xc4, 0xcd, 0xfc, 0xf1, 0x09, 0xed, 0xa7, 0xf8, 0x5e, 0x20, 0x27, 0x5d, 0x42, 0x95, 0xff, 0x94, 0x69, 0xe9, 0xa4, 0xc5, 0xc0, 0x1a, 0x0d, 0xdc, 0xb7, 0x73, 0xfd, 0x2b, 0x5f, 0x9b, 0xd5, 0xab, 0x60, 0x10, 0x3c, 0xd9, 0x22, 0xde, 0x97, 0xc7, 0xf7, 0xe3, 0xf0, 0x56, 0x78, 0x1f, 0x41, 0x33, 0xa2, 0xd2, 0x8d, 0xaf, 0x2d, 0xa4, 0xce, 0x10, 0x0a, 0x9f, 0xf6, 0xc0, 0xb2, 0x89, 0x33, 0x2f, 0xae, 0x06, 0x68, 0x1a, 0x54, 0x0e, 0xd1, 0x91, 0xc8, 0xdc, 0x6a, 0x8a, 0xd6, 0x41, 0xb2, 0xf2, 0x2e, 0x17, 0x20, 0xf3, 0x22, 0xec, 0xac, 0x94, 0x56, 0x36, 0xf9, 0x3b, 0x8e, 0x2e, 0x3d, 0xc5, 0x2b, 0x62, 0xb8, 0x92, 0xc0, 0x22, 0x75, 0x08, 0x15, 0x50, 0x52, 0xd9, 0xc3, 0xf4, 0x4c, 0x92, 0xe7, 0x31, 0x54, 0xb9, 0xc7, 0xaa, 0xc0, 0x77, 0xfa, 0x56, 0x67, 0x75, 0xc7, 0x34, 0xec, 0x42, 0xc6, 0x87, 0x7e, 0x79, 0x11, 0x43, 0x68, 0xea, 0xbb, 0x5b, 0xe4, 0x94, 0xe8, 0x2a, 0x37, 0x4e, 0x30, 0x1d, 0x51, 0x24, 0x18, 0x4d, 0xa7, 0x8b, 0x7e, 0x57, 0xc9, 0x6b, 0xc3, 0x6d, 0xd6, 0xfa, 0xe6, 0x1d, 0x8e, 0x0c, 0x68, 0x96, 0x0d, 0x02, 0xa0, 0x5a, 0xa0, 0x70, 0x2a, 0xc9, 0xf8, 0x24, 0x29, 0x41, 0xbc, 0x3e, 0xdb, 0x69, 0xa7, 0x05, 0x25, 0x70, 0x22, 0x42, 0x93, 0x85, 0x6b, 0xdb, 0xac, 0xaf, 0x15, 0x97, 0x93, 0x92, 0xb2, 0x97, 0xe3, 0x00, 0x02, 0x12, 0xff, 0xb6, 0x47, 0x6d, 0xc5, 0xd6, 0x07, 0x54, 0x27, 0x41, 0x8f, 0x5e, 0x0e, 0x18, 0x46, 0x1c, 0x02, 0xba, 0x47, 0x2d, 0x0a, 0xb6, 0x14, 0xc1, 0x5d, 0x90, 0xae, 0x82, 0x50, 0xa6, 0x92, 0xd5, 0x81, 0x3e, 0x32, 0x0f, 0x02, 0xa0, 0x93, 0x83, 0x1c, 0x32, 0xb3, 0xee, 0x6f, 0x96, 0xba, 0xe2, 0x6c, 0x1a, 0x7f, 0xf8, 0xac, 0x5f, 0x68, 0x01, 0x55, 0xef, 0x53, 0x9b, 0x01, 0x7a, 0x80, 0xd6, 0x42, 0x6d, 0xfa, 0xb9, 0xc6, 0xd3, 0xb9, 0xcd, 0xb5, 0x41, 0x3d, 0xa3, 0x66, 0x18, 0xf7, 0x5d, 0x9e, 0x34, 0x1c, 0x54, 0x4e, 0xa9, 0xca, 0xc8, 0xb1, 0x55, 0xdf, 0x17, 0xc5, 0xf2, 0x4e, 0xe8, 0xe1, 0xd6, 0x64, 0x78, 0x2b, 0x08, 0x08, 0xa8, 0xb1, 0x5e, 0xa8, 0x9a, 0x77, 0xac, 0x63, 0x4d, 0x5a, 0x6f, 0x19, 0xa1, 0x03, 0x33, 0x77, 0xcc, 0xa8, 0x9c, 0x46, 0x82, 0x95, 0x06, 0xdb, 0xf5, 0x71, 0x0b, 0x1c, 0x16, 0xae, 0x06, 0x0f, 0x27, 0x0a, 0x8a, 0x69, 0xd5, 0xf2, 0x9e, 0x0d, 0xfc, 0x62, 0xa8, 0xfc, 0xc5, 0xd5, 0x2e, 0x92, 0xb3, 0x12, 0xa5, 0x81, 0xc1, 0xa3, 0x44, 0x9f, 0x45, 0xcd, 0x9b, 0x17, 0x6d, 0x64, 0x15, 0xac, 0xec, 0xd1, 0x95, 0x44, 0x30, 0xe4, 0x8e, 0x8a, 0x1d, 0x44, 0x88, 0x33, 0x62, 0xe2, 0x7c, 0xfc, 0xed, 0x74, 0x36, 0xc7, 0x63, 0xf7, 0xf7, 0xaf, 0x89, 0x2c, 0xd9, 0x27, 0x8a, 0x95, 0x00, 0xd1, 0x19, 0x2f, 0x2f, 0xf7, 0xf0, 0xc8, 0xe4, 0x59, 0x58, 0x9d, 0xcf, 0xd3, 0xf5, 0x9a, 0x53, 0xef, 0x1b, 0x61, 0x2f, 0x70, 0x3b, 0x62, 0x81, 0x8d, 0xa3, 0x51, 0x91, 0x13, 0xd5, 0x05, 0x18, 0x52, 0x24, 0x1e, 0x50, 0xe9, 0x2a, 0x82, 0xf4, 0x4a, 0x5c, 0xda, 0x7f, 0xeb, 0xa8, 0x50, 0x50, 0x92, 0x89, 0x11, 0xf5, 0xf0, 0x80, 0x11, 0xf0, 0x7e, 0x74, 0x45, 0x68, 0x45, 0x39, 0x23, 0x7b, 0x39, 0x2f, 0xa3, 0x99, 0xe9, 0x3f, 0x45, 0x55, 0xbb, 0x9a, 0x1e, 0xe1, 0x7c, 0x8b, 0x58, 0x35, 0xd2, 0xe2, 0x6c, 0x2f, 0xe2, 0x13, 0xe6, 0xaa, 0x74, 0xc2, 0x1f, 0x2f, 0x68, 0x6f, 0x6b, 0x7f, 0x4b, 0x2d, 0x66, 0xa8, 0x3b, 0xeb, 0xee, 0x97, 0xd8, 0xfd, 0xd2, 0xde, 0xa5, 0x2c, 0x01, 0x4e, 0x3c, 0x61, 0x55, 0xc1, 0x04, 0xf6, 0xb2, 0xb8, 0xb5, 0x1c, 0x2e, 0x62, 0x18, 0x48, 0xd9, 0x93, 0xc1, 0xc4, 0xd5, 0x0c, 0xc8, 0x71, 0xe7, 0x2e, 0x3e, 0x4f, 0x42, 0x03, 0x2a, 0xc9, 0x8d, 0x16, 0xae, 0x50, 0x47, 0xe0, 0x79, 0x78, 0x28, 0x69, 0x87, 0x49, 0xf5, 0x3a, 0x67, 0xeb, 0x65, 0xeb, 0xe6, 0xd5, 0xe4, 0x7f, 0xd4, 0x0c, 0xef, 0x40, 0xf9, 0x38, 0x9b, 0xc6, 0x27, 0xb0, 0x8c, 0xf0, 0xc1, 0x85, 0x6e, 0x29, 0x81, 0x08, 0xa3, 0x9b, 0x5f, 0x8e, 0xdf, 0xca, 0x70, 0xf3, 0x1e, 0xcc, 0xf6, 0x97, 0x7d, 0x83, 0xd7, 0x50, 0xa8, 0xb6, 0xbc, 0x69, 0x6d, 0x50, 0x3f, 0x17, 0x6e, 0xc8, 0xc8, 0x06, 0x28, 0xb6, 0xf5, 0x7b, 0x78, 0xb5, 0xc6, 0x2f, 0xc7, 0xb1, 0xf4, 0x65, 0x0b, 0x4a, 0xe9, 0xaf, 0x1c, 0x95, 0xed, 0x92, 0x04, 0x01, 0x8e, 0xce, 0xf1, 0x57, 0xc1, 0x2a, 0x22, 0x68, 0x6c, 0x37, 0x53, 0xa3, 0xc7, 0x1c, 0xd8, 0xbc, 0x67, 0x8a, 0x6f, 0x6a, 0xb5, 0x10, 0xf5, 0x21, 0xc8, 0x98, 0x14, 0xd9, 0x5e, 0xfa, 0x33, 0x6f, 0x62, 0x13, 0xb3, 0xf1, 0xb6, 0x04, 0x8c, 0x01, 0x84, 0x97, 0x01, 0x69, 0xb8, 0xfb, 0xda, 0x9b, 0x61, 0x3d, 0x96, 0xcf, 0xd8, 0xe1, 0xa3, 0x07, 0xf2, 0x63, 0xdd, 0x38, 0x40, 0x7e, 0x02, 0xc0, 0x6b, 0xa1, 0xbe, 0x55, 0xe1, 0x18, 0x4d, 0x26, 0xad, 0x8a, 0x14, 0x07, 0x88, 0x54, 0x66, 0x18, 0x78, 0x31, 0xcb, 0x07, 0xac, 0x96, 0xf3, 0x07, 0x1f, 0x6a, 0xb3, 0xd3, 0x8d, 0x2d, 0x65, 0xb2, 0x08, 0x09, 0x4f, 0x1b, 0x41, 0x84, 0xa5, 0x90, 0x8e, 0xf3, 0x21, 0x57, 0x83, 0x43, 0xc5, 0xe9, 0xcd, 0xfb, 0x04, 0x09, 0x6b, 0x6d, 0xfa, 0xc1, 0x97, 0x86, 0x98, 0x42, 0x47, 0xfd, 0x22, 0xc5, 0xf7, 0x8e, 0xdf, 0xb4, 0xd0, 0x69, 0x43, 0xce, 0xbe, 0xf7, 0x9b, 0xee, 0xdf, 0x79, 0x72, 0x4b, 0x0d, 0xc9, 0x25, 0xab, 0x23, 0x0a, 0x90, 0x52, 0x51, 0xf7, 0xa7, 0x06, 0xde, 0xc4, 0x0b, 0x4e, 0x35, 0x34, 0x38, 0x58, 0xd7, 0xc3, 0xbf, 0xf0, 0x1e, 0xd8, 0x7c, 0x72, 0xb2, 0xe5, 0x53, 0xca, 0x13, 0xdd, 0x0d, 0xe2, 0x79, 0xe0, 0x14, 0xc6, 0xd4, 0x5a, 0xb5, 0x20, 0x5a, 0x4c, 0x49, 0xf9, 0x4b, 0xc4, 0x8d, 0xa4, 0xc5, 0x7b, 0xae, 0x45, 0xa1, 0x98, 0x27, 0xac, 0xa5, 0xb7, 0xb1, 0xed, 0x20, 0x10, 0x5a, 0x1f, 0x4a, 0xda, 0x98, 0xcd, 0xba, 0xa3, 0xcc, 0xbb, 0xaf, 0xb5, 0xc7, 0x60, 0x57, 0x67, 0x3e, 0xb5, 0xf7, 0x27, 0x8d, 0x70, 0x11, 0xcf, 0x6f, 0xb1, 0x74, 0x5a, 0xae, 0x86, 0x4a, 0x13, 0xa0, 0x32, 0xe3, 0x7d, 0x9c, 0x20, 0xf6, 0x00, 0x84, 0x42, 0x67, 0x8a, 0x91, 0x81, 0x0e, 0x7d, 0xe9, 0xc7, 0x29, 0x39, 0xfd, 0x83, 0xd5, 0x05, 0xda, 0x4d, 0xfa, 0x4d, 0xb7, 0x34, 0x4c, 0x86, 0xcd, 0x9a, 0x0a, 0x08, 0x7d, 0xe2, 0xe0, 0xcc, 0x56, 0x58, 0x51, 0x75, 0x2f, 0x71, 0x28, 0x06, 0x59, 0x2f, 0x0d, 0x89, 0x1c, 0xb5, 0x4e, 0xd7, 0x06, 0x6a, 0xa4, 0x84, 0x3e, 0x77, 0xb3, 0xea, 0x1a, 0xac, 0x05, 0x55, 0x50, 0xa3, 0xe0, 0x5b, 0xb2, 0x2f, 0x62, 0xfe, 0x2a, 0x3d, 0x85, 0xa2, 0x11, 0x13, 0x82, 0x9d, 0x83, 0xbc, 0x8f, 0x4b, 0x10, 0x2f, 0x85, 0xa8, 0x0d, 0x6e, 0xc4, 0x37, 0x66, 0xc9, 0x70, 0x79, 0x7f, 0xc3, 0xfd, 0x26, 0x61, 0x2f, 0x7a, 0x4c, 0x28, 0xc8, 0xc6, 0xe5, 0xdd, 0x17, 0x60, 0x59, 0x50, 0x01, 0xb7, 0x31, 0x52, 0xb7, 0xc4, 0xd1, 0xf8, 0xaa, 0x63, 0xd6, 0xf6, 0x7f, 0xac, 0x7e, 0x6c, 0xc3, 0x7d, 0x66, 0x77, 0x78, 0x8d, 0xe3, 0x27, 0xd3, 0xac, 0xd1, 0x5b, 0x27, 0x53, 0x9d, 0x11, 0x26, 0xe1, 0xd3, 0xb5, 0x73, 0xa5, 0x17, 0x4c, 0x1f, 0xf2, 0x2a, 0x78, 0x76, 0x6d, 0xc1, 0x80, 0xe9, 0xc7, 0x6e, 0xce, 0xa3, 0x50, 0xf9, 0xd5, 0x07, 0xaa, 0xc9, 0x08, 0x4e, 0x1e, 0x4a, 0x9c, 0x59, 0x57, 0xb5, 0x84, 0x85, 0x79, 0xca, 0x77, 0x00, 0xa9, 0x30, 0x57, 0x4c, 0x1e, 0x0f, 0x16, 0x3e, 0x30, 0xa6, 0x5a, 0x93, 0xe6, 0x2e, 0x6b, 0xf8, 0x51, 0x68, 0x12, 0xf1, 0x46, 0xe5, 0xc6, 0xcf, 0xb0, 0x19, 0xfb, 0x58, 0xf3, 0xff, 0x7d, 0x1f, 0x01, 0xfb, 0xfd, 0x92, 0x76, 0xd6, 0xd6, 0x03, 0xd4, 0x47, 0x70, 0x67, 0xfb, 0x6a, 0x2e, 0xfd, 0x7d, 0x94, 0x81, 0x46, 0xda, 0xd8, 0x6f, 0x92, 0x9e, 0xa0, 0x4b, 0xfb, 0xbe, 0xa8, 0x07, 0x1c, 0xc9, 0xc0, 0x66, 0xaf, 0xb1, 0x3b, 0xb8, 0x5a, 0x27, 0xe9, 0x54, 0x59, 0xa4, 0xeb, 0x92, 0xe3, 0xb7, 0x01, 0x20, 0x7a, 0xe6, 0xc3, 0xa2, 0x5c, 0x94, 0x92, 0xe2, 0x9b, 0x20, 0x66, 0x1f, 0x45, 0x8f, 0xc4, 0x30, 0x2b, 0xdd, 0x97, 0xbf, 0x46, 0xfb, 0x9e, 0x63, 0x49, 0x84, 0x47, 0x78, 0xcd, 0x5c, 0x70, 0x37, 0xa6, 0xd6, 0x11, 0x48, 0xfe, 0x79, 0x7d, 0x3a, 0x84, 0x66, 0x29, 0x2e, 0x78, 0x0f, 0x3d, 0xc8, 0x16, 0xb5, 0x05, 0x86, 0x60, 0x9f, 0x14, 0xd4, 0x3e, 0xcd, 0x89, 0xbd, 0x3c, 0x05, 0xf4, 0xa7, 0x8d, 0x9f, 0x9d, 0x2b, 0x07, 0x87, 0x2a, 0x2e, 0x2e, 0x3c, 0x9f, 0xae, 0x29, 0x8c, 0xf4, 0x4c, 0xa6, 0xf7, 0x7a, 0x9f, 0x66, 0xdf, 0xd3, 0xb9, 0x95, 0x48, 0x9c, 0x72, 0x5d, 0x1a, 0x97, 0xb0, 0xae, 0xef, 0xc1, 0xab, 0x77, 0x25, 0x62, 0x20, 0x3a, 0xa4, 0x23, 0xec, 0x6c, 0x46, 0xe8, 0xde, 0xe9, 0x25, 0x00, 0xe0, 0xd0, 0x0f, 0xe4, 0x75, 0x2b, 0xd6, 0x06, 0xc4, 0xec, 0xe6, 0x64, 0xff, 0xaa, 0x72, 0x3c, 0x1b, 0x53, 0xd2, 0xd9, 0x42, 0xc7, 0x9c, 0x38, 0x79, 0xb5, 0x4b, 0x55, 0x30, 0x65, 0x28, 0xcd, 0x4d, 0x2a, 0x06, 0x73, 0x1b, 0x9b, 0x95, 0xf7, 0x7e, 0x38, 0x4b, 0x02, 0x8e, 0x5c, 0xe7, 0x60, 0x3f, 0x7e, 0xf4, 0xb7, 0x7a, 0x91, 0xb9, 0xbf, 0xa0, 0x8a, 0xd0, 0xc1, 0xce, 0x65, 0x1e, 0x69, 0x59, 0xd3, 0x06, 0x8c, 0xe1, 0xcd, 0xc2, 0xf8, 0x08, 0xf3, 0xb9, 0x35, 0x55, 0xd2, 0xd0, 0xd8, 0x2f, 0x0f, 0xea, 0xa2, 0x42, 0xd6, 0xeb, 0x58, 0x82, 0xa7, 0x7d, 0x1c, 0xd1, 0xfa, 0xad, 0xcb, 0x09, 0x0e, 0xd4, 0xd2, 0x1a, 0x6d, 0x0b, 0xeb, 0x32, 0x29, 0xba, 0xe5, 0x7b, 0xef, 0xea, 0x94, 0x59, 0xe9, 0xcf, 0x9a, 0x13, 0x9a, 0x44, 0x55, 0x17, 0x40, 0xa9, 0x28, 0xdd, 0x6c, 0xd8, 0xa3, 0x28, 0xf0, 0xc8, 0x47, 0x60, 0xa2, 0x5f, 0x72, 0xde, 0x1c, 0x7e, 0xc0, 0x24, 0xf6, 0xc9, 0x85, 0x1f, 0x6f, 0x64, 0xdd, 0x4d, 0xe7, 0x35, 0x0f, 0x29, 0xdf, 0xeb, 0xde, 0x82, 0xff, 0x98, 0x1b, 0xb4, 0x0c, 0x6b, 0x25, 0xc9, 0x28, 0x8c, 0x18, 0x90, 0x98, 0x01, 0x7a, 0xf2, 0x41, 0x2c, 0xd4, 0xdb, 0x19, 0x68, 0xc9, 0xaf, 0x9e, 0x13, 0xf0, 0x6b, 0x30, 0xab, 0x8d, 0x44, 0x0c, 0x4a, 0x08, 0x03, 0x64, 0x1a, 0xa1, 0x88, 0x28, 0x4c, 0xdd, 0x21, 0x8d, 0x6e, 0x38, 0xf8, 0x29, 0x83, 0x67, 0xf9, 0x61, 0xf7, 0x8e, 0xc4, 0x09, 0xee, 0xea, 0x8c, 0xb9, 0x27, 0xad, 0x2d, 0xeb, 0xde, 0xeb, 0xc2, 0x3f, 0xdb, 0xfd, 0xac, 0x80, 0x90, 0x3f, 0x11, 0xd9, 0xcd, 0x6f, 0x84, 0x68, 0xb2, 0x32, 0xd1, 0xab, 0x88, 0x11, 0x3a, 0x50, 0xa5, 0xbe, 0x64, 0xce, 0x08, 0x0f, 0xca, 0x36, 0x83, 0x78, 0xa7, 0x15, 0xe6, 0xfe, 0x58, 0x08, 0x7c, 0x3b, 0xd0, 0x85, 0x72, 0xe3, 0x64, 0x22, 0x6a, 0x87, 0x99, 0xb9, 0x49, 0x33, 0x2a, 0xe9, 0xef, 0x9d, 0x60, 0x42, 0xcb, 0x0c, 0x32, 0x08, 0x5d, 0x50, 0x04, 0xce, 0x3a, 0xb6, 0xb7, 0xb2, 0x85, 0x5e, 0xb8, 0x30, 0x76, 0x07, 0x7c, 0xe2, 0xca, 0x84, 0x8a, 0x50, 0x89, 0xd7, 0x78, 0x22, 0x9d, 0x54, 0x00, 0xa8, 0x75, 0x19, 0x53, 0xfd, 0xb2, 0xc2, 0x71, 0xd1, 0x6c, 0xaa, 0xfc, 0xba, 0x30, 0xce, 0x66, 0x50, 0x1c, 0x59, 0xf3, 0x7b, 0xb4, 0x18, 0x98, 0xc4, 0x42, 0x2c, 0xc5, 0x09, 0xf8, 0x7d, 0x6d, 0xca, 0xa7, 0x49, 0x02, 0x0e, 0x72, 0xbf, 0xa2, 0x7f, 0xa3, 0x33, 0x79, 0xe0, 0x8e, 0x70, 0x38, 0x4a, 0x34, 0xf5, 0x3d, 0xde, 0x37, 0xdb, 0x63, 0x34, 0x9b, 0x12, 0x1f, 0x5b, 0x75, 0x40, 0xe0, 0x6e, 0x48, 0x8c, 0xb2, 0x6f, 0xa3, 0x17, 0x90, 0x86, 0xb3, 0x29, 0x1e, 0x3f, 0xe3, 0x6d, 0x69, 0xe7, 0x56, 0x49, 0x7d, 0x62, 0xb7, 0x49, 0xd5, 0xf9, 0x00, 0xa9, 0x02, 0xd8, 0x5a, 0x68, 0x22, 0x09, 0xe2, 0x67, 0x59, 0xaf, 0x3b, 0x84, 0xb8, 0xfb, 0xc0, 0x69, 0x2c, 0x3c, 0x81, 0x64, 0x87, 0x72, 0x48, 0x32, 0xb3, 0xf7, 0x12, 0x1f, 0xa9, 0x9c, 0x16, 0x2f, 0x28, 0x56, 0x58, 0xfd, 0x0f, 0x9f, 0x7e, 0x51, 0x93, 0xe6, 0x0c, 0x2b, 0xbf, 0x0f, 0x6d, 0xbe, 0x2f, 0xfb, 0xa7, 0x66, 0x41, 0xe8, 0xee, 0xc8, 0x1d, 0xa8, 0x6d, 0x95, 0x5b, 0xdf, 0x83, 0x0f, 0x7f, 0x68, 0x7b, 0x10, 0x7e, 0xc1, 0xae, 0xac, 0xa6, 0xf4, 0x79, 0xc6, 0xe9, 0x20, 0xdd, 0xf4, 0x57, 0xe8, 0x2e, 0xfe, 0xa1, 0x30, 0x68, 0x39, 0xcd, 0xe3, 0x04, 0x1e, 0x53, 0x95, 0xcd, 0xd9, 0x69, 0x8f, 0x1f, 0x06, 0x46, 0x25, 0xc1, 0x93, 0x0c, 0xf8, 0x2d, 0x67, 0x68, 0x04, 0xcd, 0x51, 0x65, 0x81, 0xe4, 0xab, 0x15, 0xc7, 0xb9, 0xd4, 0x43, 0x74, 0xf9, 0xc3, 0xb6, 0x4e, 0x8d, 0x59, 0xe0, 0xae, 0xd7, 0x85, 0x94, 0xf3, 0x47, 0x75, 0xe0, 0xc3, 0xdd, 0xa7, 0x1c, 0xc9, 0xc7, 0xb9, 0x0f, 0x55, 0x37, 0xab, 0xe8, 0x8d, 0x68, 0x82, 0xd7, 0x3d, 0x0f, 0x49, 0xc1, 0x0a, 0x95, 0xf5, 0xe8, 0x46, 0x9c, 0x7a, 0x47, 0xf2, 0xd5, 0xc0, 0xa5, 0x2f, 0x00, 0xa3, 0x0e, 0xb3, 0x00, 0x01, 0x35, 0xef, 0xce, 0x78, 0xf1, 0x1c, 0x07, 0x64, 0xb2, 0xb1, 0xba, 0x12, 0x7e, 0xda, 0xfc, 0xa2, 0x8a, 0x39, 0x44, 0x8d, 0xf6, 0x6d, 0xb3, 0x95, 0x5e, 0x64, 0xd6, 0x82, 0xb1, 0xf7, 0xe3, 0xef, 0x83, 0xa9, 0x66, 0x2d, 0xda, 0xbd, 0xd2, 0x70, 0x6f, 0x18, 0x22, 0xcd, 0x9a, 0xff, 0xec, 0x7a, 0xd9, 0x56, 0x1b, 0x09, 0xb2, 0x20, 0x3d, 0x23, 0xa2, 0x2a, 0x71, 0xc3, 0xeb, 0x49, 0x5b, 0x6f, 0xeb, 0x47, 0xc5, 0x26, 0xe8, 0x57, 0x9d, 0x27, 0x2c, 0xea, 0xc4, 0x2a, 0x2f, 0x42, 0xb6, 0x28, 0x97, 0xad, 0xd4, 0x1f, 0xc4, 0xbc, 0x7b, 0x74, 0x60, 0x67, 0xb2, 0x83, 0xba, 0xa8, 0xa4, 0xe2, 0xea, 0xcc, 0x96, 0xfd, 0x48, 0xd6, 0x4d, 0xad, 0x39, 0x7a, 0x5e, 0x6e, 0xb5, 0x5e, 0x6d, 0x53, 0x25, 0x9c, 0xf2, 0x83, 0x0e, 0x9a, 0x97, 0x17, 0xf9, 0x21, 0x5a, 0x28, 0x9c, 0xa6, 0x65, 0x50, 0xd5, 0x63, 0xaa, 0x08, 0x36, 0x8c, 0xd4, 0xa3, 0x1d, 0xcb, 0x9c, 0x9e, 0xd7, 0x77, 0x95, 0xfc, 0x61, 0x46, 0x4b, 0x8e, 0x38, 0xaa, 0x3b, 0xe5, 0xa0, 0xc2, 0xe5, 0xa2, 0xc6, 0x2a, 0xdc, 0x3c, 0x44, 0x83, 0xaf, 0x81, 0x9b, 0xa2, 0xa6, 0xfb, 0x4b, 0xea, 0x1a, 0xed, 0x30, 0x79, 0xae, 0x8d, 0x2e, 0x0b, 0x0e, 0x7c, 0x62, 0xa7, 0xe4, 0xd8, 0xa8, 0xaa, 0x3a, 0x26, 0x4c, 0xf3, 0xe5, 0xe1, 0x6e, 0xf1, 0x89, 0xf2, 0x92, 0x2e, 0xf6, 0x9d, 0x47, 0x8d, 0x9f, 0x76, 0x0e, 0x00, 0x9e, 0x6a, 0x1c, 0x14, 0x66, 0x97, 0xc9, 0xf0, 0x1b, 0xfb, 0xe0, 0x57, 0x6e, 0x8c, 0x73, 0x10, 0x70, 0xe3, 0x27, 0xae, 0xb4, 0x36, 0xc4, 0x1d, 0x86, 0xf8, 0x68, 0xe3, 0x3d, 0xcb, 0xc8, 0xd2, 0x29, 0xdd, 0x76, 0x64, 0x4d, 0x36, 0x72, 0xfc, 0xfb, 0x7c, 0xa9, 0x7c, 0xd8, 0x8b, 0x8b, 0x39, 0xad, 0x91, 0x4e, 0x25, 0xa7, 0xbc, 0xb2, 0x0c, 0x44, 0x98, 0x2a, 0x53, 0xbc, 0x58, 0x7c, 0xc4, 0xff, 0xf6, 0xb8, 0x5f, 0x5b, 0x60, 0x29, 0x22, 0xfe, 0x39, 0x5f, 0x89, 0xdf, 0xbf, 0x17, 0x1a, 0xa0, 0x3e, 0x6a, 0x8c, 0x81, 0x8d, 0x0f, 0x29, 0x26, 0x97, 0xf6, 0xa5, 0x3b, 0xcb, 0x41, 0x52, 0x57, 0xd9, 0xb9, 0x6a, 0x41, 0xe9, 0x33, 0x34, 0x7a, 0x1b, 0x8a, 0x8a, 0x46, 0x27, 0xe3, 0xc8, 0xdd, 0x1b, 0x98, 0x39, 0x7e, 0xfd, 0x48, 0xa6, 0xd6, 0xa5, 0xc9, 0x13, 0x5c, 0xcc, 0x08, 0x80, 0xd9, 0xa0, 0x76, 0x0d, 0x43, 0x2a, 0x90, 0xfa, 0xb1, 0xf7, 0x34, 0x6c, 0x0c, 0x1e, 0x4e, 0x28, 0x31, 0x36, 0x09, 0x48, 0x95, 0x56, 0x10, 0x8e, 0x54, 0x39, 0xed, 0xe8, 0x2f, 0xfc, 0xbf, 0x97, 0xc2, 0x9f, 0x8e, 0xd6, 0x4b, 0xbd, 0x64, 0x37, 0x7a, 0x3b, 0x11, 0xd0, 0xe1, 0xe1, 0x05, 0x9a, 0xf3, 0x6d, 0x6b, 0xbe, 0xf7, 0x49, 0x07, 0x3e, 0x29, 0x34, 0x52, 0xcc, 0xe7, 0x87, 0xf2, 0x74, 0xe0, 0xfb, 0xb6, 0xbf, 0xbc, 0xa3, 0x49, 0xf4, 0x90, 0x25, 0x71, 0x7b, 0x40, 0x45, 0x7f, 0x29, 0x3f, 0x39, 0x5d, 0x52, 0x0d, 0x6a, 0x60, 0xcc, 0xf1, 0x91, 0x45, 0x51, 0xcc, 0xad, 0xc4, 0x85, 0x62, 0x4a, 0x7d, 0xed, 0x15, 0x2d, 0x99, 0x69, 0x7f, 0x9c, 0xcb, 0x70, 0xfd, 0xe3, 0xad, 0xc8, 0xe0, 0x95, 0x1e, 0xf3, 0x84, 0x11, 0x69, 0xce, 0xeb, 0x3e, 0x1c, 0x10, 0xd8, 0xd0, 0xcb, 0x31, 0xb5, 0x85, 0x5f, 0xe8, 0xc5, 0xb5, 0xe0, 0xeb, 0x59, 0x02, 0xbf, 0x33, 0x0c, 0xae, 0xc0, 0xf7, 0x9b, 0xc5, 0xd0, 0x29, 0x4f, 0x79, 0x57, 0x4e, 0x72, 0xbe, 0xdf, 0xcf, 0xdc, 0x18, 0xe2, 0x10, 0x1b, 0x99, 0x2d, 0x74, 0x2b, 0x15, 0x44, 0x46, 0xc1, 0xe5, 0x39, 0x0b, 0xad, 0x50, 0xc1, 0x4f, 0xf3, 0xe3, 0x3d, 0xde, 0x0a, 0x35, 0xec, 0xfd, 0xc5, 0x39, 0x90, 0x05, 0x3d, 0x6f, 0x35, 0x75, 0x3e, 0xca, 0x60, 0x43, 0xd9, 0x75, 0xda, 0x22, 0xf7, 0x68, 0xad, 0x7b, 0x98, 0xf0, 0xba, 0xd9, 0x82, 0x89, 0x0b, 0xf4, 0x4f, 0xbc, 0x9d, 0x64, 0x4d, 0x89, 0x8c, 0x8b, 0xc3, 0x69, 0xd2, 0xfe, 0x87, 0x12, 0xd1, 0x67, 0xb9, 0x40, 0x1a, 0xfe, 0x4f, 0x79, 0x7d, 0xa0, 0xed, 0xcf, 0x86, 0xb0, 0xea, 0xac, 0xf8, 0x17, 0xf4, 0x3e, 0xfa, 0x19, 0x03, 0x32, 0x6c, 0xbd, 0xed, 0x3d, 0x88, 0xcb, 0x58, 0x8c, 0xd9, 0xd4, 0xe9, 0xf8, 0x32, 0x0a, 0xa9, 0xe4, 0x9c, 0x0f, 0xb9, 0xed, 0xa9, 0x80, 0x07, 0x48, 0xeb, 0x77, 0x06, 0x81, 0xda, 0x7c, 0x2e, 0x70, 0x72, 0x0b, 0x10, 0x2a, 0xd8, 0xe7, 0x4e, 0xef, 0x6d, 0x7b, 0xc2, 0x9c, 0xa9, 0xf2, 0xb3, 0x9c, 0x3d, 0x18, 0x43, 0xc9, 0x04, 0x62, 0x3f, 0x7e, 0x5d, 0x6c, 0xf0, 0x42, 0x48, 0x1d, 0x89, 0xe5, 0x70, 0x3c, 0xbd, 0x85, 0x6c, 0x31, 0xac, 0xa9, 0xb4, 0xbe, 0x50, 0x8a, 0xfc, 0x69, 0xcf, 0x34, 0x6c, 0x86, 0xf6, 0x28, 0x25, 0x37, 0x4d, 0x6b, 0x60, 0x10, 0x3d, 0xb2, 0x50, 0xa2, 0x21, 0xeb, 0xcb, 0x7a, 0xda, 0x8b, 0xbe, 0x6a, 0xea, 0x12, 0xe7, 0xdc, 0xfc, 0x65, 0x12, 0xee, 0xe2, 0x44, 0xca, 0xea, 0xb0, 0x4c, 0xe4, 0xed, 0x00, 0x18, 0x57, 0x8b, 0xb2, 0xea, 0x48, 0x00, 0x78, 0xd1, 0x89, 0x9a, 0x44, 0x6d, 0x34, 0xb8, 0x75, 0xf3, 0x01, 0xad, 0x3f, 0xd9, 0x2c, 0x23, 0x5f, 0xc7, 0x5f, 0x6a, 0x19, 0x90, 0xe1, 0x6f, 0x21, 0xd0, 0x21, 0x81, 0x87, 0x12, 0x1a, 0x58, 0xdb, 0x67, 0x5e, 0x73, 0xbb, 0x7f, 0x24, 0x0c, 0x9d, 0xec, 0xdd, 0xd1, 0x70, 0xd9, 0x23, 0xbe, 0x9c, 0xfd, 0x85, 0x4f, 0x62, 0x84, 0x06, 0xb8, 0xc9, 0xfd, 0x2e, 0xa9, 0xba, 0x41, 0x9b, 0x66, 0xf3, 0x84, 0x73, 0x38, 0x90, 0x41, 0x94, 0x63, 0xd6, 0x4e, 0xb3, 0xf9, 0x6d, 0x82, 0x96, 0x66, 0xc4, 0x5d, 0xad, 0x14, 0xd7, 0x6e, 0xda, 0xf9, 0xbf, 0x8b, 0x77, 0xe1, 0x73, 0xdb, 0xca, 0x3d, 0x31, 0x62, 0x18, 0xe4, 0xe8, 0xa2, 0x4d, 0x60, 0x0e, 0x04, 0xe0, 0x5e, 0x2b, 0x90, 0x7d, 0x6f, 0x5e, 0x0e, 0x1f, 0xd6, 0x59, 0x6b, 0x08, 0x6c, 0x82, 0x0f, 0x13, 0x8d, 0xc2, 0xa7, 0x0b, 0x83, 0x29, 0x33, 0x4a, 0xaf, 0x98, 0xc8, 0x54, 0x44, 0x8a, 0x28, 0x84, 0xc5, 0xa8, 0x15, 0x15, 0x0d, 0x62, 0x41, 0x76, 0x3e, 0xdd, 0x0f, 0x07, 0xe1, 0x4a, 0x1b, 0x37, 0xce, 0x7c, 0xe6, 0x37, 0xaf, 0xae, 0xf7, 0xae, 0xf8, 0xad, 0x17, 0x30, 0x66, 0xd3, 0xe8, 0x6c, 0xaa, 0x27, 0x90, 0x1f, 0x69, 0x97, 0xa6, 0x30, 0x6f, 0x84, 0xd1, 0xf8, 0xda, 0xd9, 0x4d, 0xda, 0x0e, 0x27, 0xe4, 0x64, 0x85, 0x2d, 0x71, 0x27, 0xaa, 0x60, 0x5f, 0xbf, 0x05, 0x0c, 0x61, 0xa6, 0xae, 0x0f, 0x93, 0x6b, 0xbd, 0x30, 0x03, 0x8c, 0xf0, 0xb8, 0x3f, 0x7f, 0x47, 0x34, 0x31, 0x79, 0xc9, 0x8d, 0x01, 0x9c, 0xb5, 0x06, 0x0e, 0xf8, 0xe6, 0x3e, 0xda, 0x94, 0x6e, 0x4f, 0xd0, 0xbf, 0xa2, 0x69, 0xac, 0x81, 0x47, 0x24, 0x71, 0xfb, 0x5c, 0xd3, 0xb0, 0x40, 0x34, 0xe2, 0x2e, 0xa7, 0xa1, 0x30, 0xd9, 0x06, 0x42, 0x0c, 0xec, 0x5f, 0x5e, 0xd1, 0x79, 0xde, 0x88, 0x62, 0x5e, 0x8b, 0x8f, 0x91, 0x29, 0x41, 0x9f, 0x82, 0xee, 0xf3, 0x88, 0x09, 0xef, 0x2e, 0xd3, 0x86, 0x32, 0x2f, 0x9f, 0x94, 0x02, 0x08, 0xd9, 0xa3, 0x11, 0xd8, 0x5a, 0x2c, 0x7c, 0x48, 0x32, 0x35, 0xc0, 0x27, 0xa9, 0xb1, 0xd7, 0x63, 0xef, 0x61, 0xa4, 0x46, 0x54, 0xa1, 0xa1, 0x45, 0x2a, 0xc2, 0x68, 0xd2, 0x8a, 0x4b, 0x7a, 0x08, 0x74, 0x5f, 0xf5, 0xb8, 0xa0, 0x02, 0xfd, 0xfb, 0xbc, 0x7c, 0x63, 0xd3, 0x7c, 0x05, 0x13, 0x92, 0x4a, 0xd4, 0x38, 0x3f, 0x1f, 0x81, 0x59, 0x97, 0x41, 0xd7, 0xc9, 0xf2, 0xee, 0xc6, 0xf9, 0x4a, 0x8f, 0x31, 0x01, 0x57, 0x0c, 0x4d, 0x0f, 0x59, 0xd1, 0x7f, 0x23, 0x3c, 0x08, 0xa9, 0x81, 0xd0, 0xb6, 0x58, 0x52, 0x45, 0x69, 0x7f, 0xd1, 0x76, 0x27, 0x63, 0x63, 0xc0, 0xba, 0xcb, 0xb4, 0xf2, 0xa6, 0xf4, 0xfd, 0xa7, 0x2f, 0xc5, 0x01, 0xb3, 0x49, 0x4b, 0x69, 0xf1, 0x75, 0x55, 0xf4, 0x90, 0x35, 0xc5, 0x83, 0x8e, 0x9b, 0xaf, 0x03, 0x77, 0x23, 0x8b, 0x89, 0xa5, 0xc8, 0x35, 0x4b, 0xce, 0xb9, 0xb0, 0x1c, 0x39, 0x92, 0x32, 0x26, 0xe3, 0x71, 0x60, 0x21, 0x14, 0xcf, 0x22, 0xad, 0xc1, 0xc1, 0xde, 0x6a, 0x0a, 0x87, 0xcb, 0x91, 0x6a, 0x2a, 0x27, 0x85, 0xea, 0x2f, 0x77, 0xb5, 0x21, 0x49, 0x91, 0xed, 0x05, 0x52, 0xd1, 0x87, 0x9f, 0xaa, 0xd9, 0x18, 0x7f, 0xf3, 0xf6, 0xca, 0x59, 0x31, 0x46, 0x5a, 0x1f, 0x9d, 0x90, 0xbd, 0x41, 0x94, 0x1d, 0x37, 0xd9, 0xd5, 0x2f, 0xf2, 0x32, 0xc8, 0x5c, 0xbe, 0xf2, 0x2d, 0xdd, 0x9d, 0x3d, 0xc8, 0x50, 0x4d, 0x1e, 0xcf, 0x82, 0x0b, 0x35, 0x95, 0x38, 0xdb, 0x80, 0x63, 0x3e, 0x78, 0x96, 0xaf, 0x99, 0xe2, 0x4e, 0x01, 0x22, 0x18, 0x0b, 0x81, 0x28, 0xee, 0x7d, 0x01, 0x85, 0x9f, 0x20, 0x87, 0x87, 0x9b, 0x2a, 0x05, 0xa3, 0x3e, 0xc2, 0x0e, 0x9e, 0x6e, 0x68, 0x3a, 0x40, 0x3c, 0xff, 0xa0, 0xbf, 0x8a, 0x94, 0xaa, 0x4f, 0xd7, 0x43, 0x7c, 0xa8, 0x58, 0x2e, 0x6a, 0xd9, 0x5f, 0xa3, 0x1f, 0x77, 0x27, 0x6d, 0x03, 0xa5, 0x6c, 0x34, 0x3c, 0x96, 0x53, 0xec, 0x99, 0xff, 0xc8, 0xc2, 0x52, 0xd6, 0xca, 0x38, 0xef, 0x58, 0x21, 0xf9, 0xca, 0x67, 0xfa, 0x12, 0x57, 0x1c, 0xb1, 0xf0, 0xfc, 0x32, 0x11, 0xf6, 0x48, 0xb1, 0x79, 0xa4, 0x9e, 0xce, 0xdc, 0x73, 0x46, 0x4a, 0x5c, 0x18, 0xcb, 0x07, 0x71, 0x40, 0x8d, 0x9f, 0x5b, 0x49, 0x0d, 0x39, 0x8e, 0x64, 0x21, 0xe7, 0xcc, 0xa1, 0x02, 0x20, 0x0e, 0xc7, 0x63, 0x3a, 0xc2, 0xa3, 0x99, 0x6f, 0x34, 0x7c, 0x39, 0x1e, 0xed, 0x42, 0x2e, 0xbd, 0x29, 0x86, 0x20, 0x5d, 0x70, 0xec, 0x97, 0xc4, 0xd1, 0x76, 0xe9, 0x57, 0xd0, 0x8f, 0x4a, 0xb0, 0xc4, 0x62, 0x00, 0x1e, 0x3d, 0xa2, 0x8c, 0xe4, 0xee, 0x97, 0x69, 0x19, 0xa0, 0x09, 0x14, 0x54, 0x9a, 0x12, 0x4c, 0x10, 0xfc, 0xbd, 0xea, 0xab, 0xc0, 0x2a, 0xbf, 0x9f, 0xfb, 0x49, 0xa5, 0x6c, 0x49, 0x08, 0x8d, 0x69, 0xd8, 0x92, 0xd5, 0x39, 0x79, 0x9d, 0xe6, 0x9c, 0x70, 0xe6, 0x20, 0xe0, 0x40, 0x16, 0xf2, 0xd7, 0x98, 0x0f, 0xb0, 0xd9, 0xb1, 0x18, 0x7b, 0xfa, 0xc4, 0xbe, 0x0b, 0xd0, 0x06, 0xc1, 0x6c, 0xcd, 0x9e, 0x92, 0xee, 0x8b, 0xfc, 0xaa, 0x66, 0x2c, 0xa3, 0x06, 0x08, 0xfb, 0xe7, 0x13, 0xae, 0xa7, 0x95, 0xc2, 0x4c, 0x67, 0x7e, 0x8e, 0x1d, 0x93, 0x0e, 0x85, 0xfd, 0x16, 0x66, 0xe7, 0xc4, 0xbe, 0xe2, 0x8b, 0x2f, 0x3c, 0x65, 0xe3, 0x83, 0x9e, 0xf3, 0x80, 0x4a, 0xe7, 0x1b, 0x48, 0x1c, 0xc5, 0xe9, 0xd6, 0x1b, 0x7f, 0x8e, 0xe1, 0xa1, 0x8b, 0xdc, 0xfe, 0x6f, 0xcf, 0xe7, 0xe7, 0xad, 0x57, 0xd8, 0x09, 0x67, 0x56, 0x12, 0x52, 0xe9, 0xb9, 0xbd, 0x5a, 0xa9, 0x91, 0x39, 0xe6, 0x74, 0x78, 0x72, 0x02, 0x2d, 0x71, 0x0f, 0x57, 0x99, 0x84, 0x0e, 0x81, 0x9b, 0xd6, 0x9e, 0xa0, 0x1a, 0x09, 0x60, 0x1d, 0xf3, 0x51, 0xb7, 0x50, 0x34, 0x3c, 0x6c, 0xdf, 0x60, 0x31, 0x3a, 0x06, 0x63, 0x68, 0xa6, 0xf6, 0x17, 0xc1, 0xed, 0x65, 0x85, 0x4e, 0x47, 0xd9, 0xb0, 0x69, 0x8c, 0x61, 0xaf, 0x69, 0xaa, 0xbc, 0x47, 0xa0, 0x25, 0x51, 0xb9, 0x97, 0x32, 0xb9, 0xe2, 0xbc, 0xf1, 0x14, 0x90, 0x4b, 0x7b, 0xa3, 0xc1, 0xba, 0xff, 0x59, 0x74, 0x1d, 0xd1, 0x3a, 0x10, 0x1f, 0x14, 0xaa, 0x09, 0xc1, 0x47, 0x41, 0x1c, 0x2e, 0x19, 0x8b, 0x8a, 0xa9, 0x31, 0xea, 0xe0, 0x7f, 0xd5, 0xc0, 0x1a, 0xad, 0x6c, 0x95, 0xa1, 0xd1, 0xe1, 0xb2, 0x02, 0x9b, 0x4b, 0xef, 0x7f, 0x2b, 0x47, 0xb0, 0x67, 0x96, 0x6b, 0x2b, 0xa1, 0xec, 0x71, 0x09, 0x27, 0x67, 0x04, 0x35, 0x4a, 0x81, 0xc7, 0xa2, 0x06, 0x4c, 0xde, 0xec, 0x2f, 0x93, 0x6c, 0x72, 0x54, 0xfa, 0x32, 0x19, 0xcf, 0x3b, 0x2c, 0x71, 0x3e, 0xdf, 0xb4, 0x54, 0xf7, 0xd4, 0x45, 0x22, 0x86, 0xd7, 0x41, 0xab, 0x2c, 0x0f, 0x5f, 0xb0, 0xe0, 0x90, 0x5c, 0x78, 0x56, 0x91, 0x34, 0x36, 0x3e, 0x7c, 0x60, 0xdd, 0x7e, 0x67, 0x21, 0xb2, 0x4e, 0x61, 0x91, 0xd7, 0xeb, 0xa7, 0x62, 0xb6, 0x47, 0x4a, 0xd8, 0x05, 0x7e, 0xf2, 0x96, 0x71, 0x55, 0x1c, 0xd7, 0xfa, 0xe1, 0x66, 0x31, 0x6c, 0x37, 0x32, 0x49, 0xe7, 0x46, 0xba, 0x5b, 0x32, 0x6f, 0xdd, 0xdb, 0x11, 0x02, 0x43, 0xa2, 0x6f, 0x0d, 0x5f, 0xc0, 0x23, 0xa2, 0x15, 0xa0, 0x8b, 0x76, 0x41, 0x2b, 0x9b, 0xf9, 0xe8, 0xb6, 0xdd, 0x07, 0xe1, 0x23, 0x68, 0x57, 0x4a, 0xfe, 0x47, 0xbe, 0x19, 0x4a, 0x31, 0xaf, 0x74, 0xaf, 0xca, 0x40, 0x4c, 0xf0, 0x1c, 0xbc, 0xc1, 0x9d, 0x0a, 0xf9, 0x4d, 0x0a, 0x2a, 0xad, 0xec, 0x0a, 0x3e, 0x45, 0xfd, 0xa1, 0xe9, 0xa5, 0x59, 0x6e, 0x47, 0x9d, 0xe1, 0xc8, 0xdf, 0x21, 0x92, 0xb9, 0xeb, 0x24, 0xe0, 0x14, 0x00, 0x51, 0x42, 0x24, 0x2f, 0x37, 0xf7, 0x0c, 0x6f, 0xda, 0x4d, 0xa0, 0x1b, 0x84, 0x97, 0x10, 0x2f, 0xd7, 0xe4, 0x49, 0x3d, 0x2f, 0x63, 0x24, 0x2b, 0xb5, 0x1f, 0x63, 0xad, 0xf4, 0x0a, 0x61, 0x01, 0x45, 0x55, 0xfa, 0x61, 0xd5, 0x15, 0x3e, 0x93, 0xf8, 0xe1, 0x8e, 0xdd, 0x0e, 0x4f, 0x62, 0xcb, 0xe4, 0xf9, 0xdb, 0x59, 0x62, 0xcf, 0x96, 0x6c, 0xbb, 0x16, 0xf0, 0xb5, 0xab, 0x47, 0xf0, 0x62, 0xbf, 0x66, 0x97, 0xd0, 0x97, 0xf7, 0xbf, 0xbd, 0xfc, 0x6a, 0x06, 0xac, 0x43, 0x33, 0x3d, 0x19, 0x3a, 0x70, 0xec, 0xf3, 0x7d, 0x5d, 0xd4, 0x29, 0x93, 0x58, 0xb4, 0xf1, 0x84, 0xb2, 0xa3, 0x56, 0xb1, 0x57, 0x93, 0x75, 0xa0, 0x68, 0xf5, 0x74, 0xed, 0xab, 0xbc, 0x30, 0xaf, 0x8e, 0x81, 0x7c, 0x11, 0x00, 0x07, 0xde, 0xa7, 0xc1, 0x2d, 0xcd, 0x4e, 0xaf, 0xf1, 0x1e, 0x8a, 0xec, 0x5f, 0x96, 0x06, 0x04, 0x80, 0xc3, 0x49, 0x54, 0x60, 0x96, 0xc6, 0xda, 0xac, 0x82, 0xe5, 0xa6, 0x8d, 0x1a, 0x89, 0x15, 0x70, 0xcc, 0xd2, 0x3b, 0xa3, 0x58, 0x54, 0xa1, 0x92, 0xeb, 0x27, 0x0f, 0xcb, 0xc1, 0x45, 0x08, 0x9c, 0xd7, 0x71, 0x27, 0xe2, 0x0e, 0x01, 0x3e, 0xff, 0xd3, 0xb4, 0x20, 0x30, 0xdb, 0x1e, 0x59, 0x95, 0xc5, 0x28, 0x3b, 0xe5, 0x30, 0x0e, 0xb4, 0x63, 0xc7, 0xdc, 0x33, 0x83, 0x4e, 0x06, 0x0c, 0x4b, 0x13, 0xce, 0xfc, 0x5e, 0xeb, 0x72, 0xc7, 0x9b, 0x59, 0xbe, 0xb7, 0x24, 0x16, 0x01, 0x74, 0xa5, 0xe2, 0x76, 0xb8, 0x88, 0x62, 0x4d, 0x27, 0x95, 0xec, 0x88, 0x2a, 0x62, 0xaf, 0xeb, 0x58, 0x18, 0xb9, 0x6b, 0x17, 0x2c, 0x85, 0x77, 0x67, 0x09, 0x41, 0x25, 0x5f, 0x8c, 0xb9, 0xfe, 0xa1, 0x5e, 0x2f, 0x4b, 0x0c, 0x75, 0x2f, 0xfa, 0x5c, 0x5b, 0x8a, 0xf3, 0x2d, 0x3d, 0xfa, 0x2b, 0xf2, 0xf3, 0x9b, 0x8b, 0xc4, 0x3b, 0x67, 0xa0, 0x99, 0x56, 0x4d, 0x38, 0xac, 0xcb, 0x07, 0x0c, 0x23, 0x6f, 0xd6, 0xe1, 0x59, 0xbb, 0x0a, 0x15, 0x47, 0x73, 0xe6, 0x1c, 0x42, 0x59, 0x98, 0xae, 0x1b, 0xc3, 0xbf, 0x70, 0x7e, 0x96, 0x82, 0xab, 0x8b, 0x76, 0x58, 0x65, 0xe9, 0x60, 0x3b, 0x56, 0x03, 0x90, 0xa3, 0x62, 0x2c, 0x21, 0xaf, 0x7e, 0xaa, 0x24, 0xd4, 0x90, 0x7a, 0x3e, 0x8e, 0x17, 0x76, 0x3d, 0x7e, 0xcc, 0x9d, 0x57, 0x1e, 0xa3, 0x93, 0x4e, 0xe7, 0x48, 0xb6, 0x23, 0x3e, 0xf2, 0x97, 0xa5, 0x51, 0xeb, 0x6b, 0x53, 0x09, 0x3b, 0xf2, 0xfc, 0x5f, 0x8a, 0x38, 0xbb, 0xb7, 0x90, 0x25, 0xc4, 0x08, 0x36, 0x0e, 0x8b, 0xb4, 0xab, 0x17, 0xfe, 0x58, 0xf1, 0xf9, 0x69, 0x0b, 0x09, 0x05, 0xb9, 0xc1, 0xa8, 0x04, 0xbd, 0x2e, 0x89, 0x88, 0x87, 0xfe, 0x64, 0x4f, 0xd2, 0x27, 0xee, 0x8d, 0xd4, 0xba, 0xa8, 0x6f, 0x77, 0x61, 0x15, 0xd3, 0x8b, 0x25, 0x8f, 0x7c, 0x1e, 0x5f, 0x88, 0x87, 0x35, 0x2c, 0xe3, 0xc4, 0xea, 0x7e, 0xab, 0x0c, 0x49, 0xe9, 0xa3, 0x30, 0x91, 0x8c, 0xd5, 0x74, 0xee, 0x81, 0x91, 0x8d, 0x24, 0xac, 0x98, 0x69, 0x7f, 0x77, 0xe5, 0x42, 0xf7, 0xc9, 0xd2, 0x41, 0x6d, 0x95, 0xb2, 0x5d, 0x57, 0xe1, 0x38, 0xa3, 0xb4, 0xb6, 0x56, 0x78, 0x3c, 0xd8, 0xd6, 0xf8, 0x13, 0xa9, 0xd9, 0x36, 0x6b, 0x89, 0xe3, 0xd6, 0xce, 0x56, 0xec, 0x63, 0x98, 0x7f, 0x7e, 0xc7, 0x9b, 0x92, 0x97, 0xc2, 0xf5, 0xd8, 0x05, 0xbd, 0x7a, 0xa6, 0x63, 0x66, 0xec, 0x0a, 0x75, 0x91, 0x18, 0x08, 0xa4, 0x63, 0xbd, 0x03, 0x9c, 0x05, 0xce, 0x94, 0x5a, 0x8d, 0x07, 0xb8, 0x0e, 0x05, 0xda, 0x7d, 0xbf, 0x23, 0xca, 0x33, 0x96, 0xaa, 0x96, 0x48, 0xcb, 0x9c, 0x3d, 0x0b, 0xc1, 0x66, 0xbe, 0x06, 0xe3, 0xfb, 0x64, 0x4d, 0x1a, 0xd0, 0x22, 0x60, 0xb6, 0x2c, 0x34, 0x3a, 0x37, 0x8c, 0x2a, 0x90, 0x7f, 0xc5, 0xa9, 0x44, 0x10, 0xbf, 0x93, 0xbd, 0x9b, 0xda, 0xfd, 0x9a, 0x92, 0x7f, 0x6a, 0x49, 0x72, 0x37, 0xc5, 0xa8, 0x54, 0x49, 0x17, 0x50, 0x60, 0x67, 0x83, 0x98, 0x13, 0x28, 0x36, 0xf2, 0x5a, 0xb9, 0xfb, 0x31, 0x12, 0x53, 0x93, 0x62, 0x25, 0xdc, 0xca, 0xc5, 0x55, 0x21, 0xc5, 0xd7, 0x47, 0x9c, 0xd2, 0x37, 0x0b, 0xe5, 0xd6, 0x9f, 0x99, 0xe7, 0x38, 0x57, 0xbd, 0x5f, 0x03, 0xe8, 0x2a, 0xf4, 0x41, 0xe5, 0x9f, 0xf8, 0x3e, 0xbc, 0x5e, 0x4d, 0x3d, 0xa3, 0x42, 0x03, 0xd2, 0xab, 0x33, 0xdd, 0xfd, 0xaa, 0xa0, 0xa9, 0x0b, 0xd5, 0x1a, 0x06, 0x68, 0x8d, 0xee, 0x27, 0x86, 0x57, 0xe7, 0x75, 0xf2, 0x50, 0x00, 0x91, 0x03, 0xa1, 0xb2, 0xb8, 0xb8, 0xe7, 0x70, 0xcf, 0x50, 0x57, 0xc8, 0x7a, 0x0b, 0x9d, 0x39, 0x0b, 0x50, 0x9f, 0xf7, 0x49, 0x1f, 0xd0, 0xb2, 0x2c, 0xde, 0x64, 0x4e, 0x28, 0xdb, 0x04, 0x6b, 0xaf, 0x73, 0x71, 0x31, 0xd7, 0x73, 0x6e, 0x85, 0x5f, 0xa8, 0xbd, 0xc8, 0x39, 0x80, 0x51, 0x94, 0x4e, 0xec, 0x34, 0xa2, 0xe1, 0x1d, 0xfb, 0xf5, 0xb4, 0x70, 0x30, 0xe7, 0x21, 0xee, 0x02, 0xb8, 0x0a, 0x20, 0x93, 0x2a, 0x0f, 0x3a, 0xef, 0x33, 0xeb, 0xa6, 0x4f, 0x6d, 0xa9, 0x5b, 0x00, 0x61, 0x38, 0x22, 0x43, 0xd9, 0x1b, 0x12, 0x3e, 0x18, 0x61, 0xa2, 0x5c, 0x19, 0xde, 0xb1, 0x86, 0x04, 0xe5, 0x0f, 0x89, 0x87, 0xe4, 0xf5, 0xb4, 0x33, 0xd6, 0xc7, 0xd9, 0x58, 0x45, 0x11, 0x0d, 0xc4, 0xee, 0x7a, 0xe8, 0x0d, 0xff, 0x7b, 0xdd, 0x30, 0x5a, 0x75, 0xab, 0x6b, 0xa6, 0xb4, 0x2f, 0xcb, 0x2e, 0x97, 0x46, 0x0f, 0x52, 0x82, 0x8f, 0xe1, 0x30, 0xac, 0xdc, 0x90, 0xf7, 0xc4, 0x4b, 0x03, 0xf4, 0x2f, 0xac, 0x17, 0xad, 0xcf, 0xf7, 0xa5, 0x7b, 0x79, 0x65, 0xcf, 0x59, 0x7e, 0xc0, 0x39, 0xf4, 0x61, 0x70, 0xb4, 0xe7, 0xb8, 0xbd, 0x4b, 0x7f, 0x53, 0x9f, 0x34, 0x7b, 0xc9, 0x36, 0x3e, 0xe9, 0xb1, 0xe6, 0xd7, 0xe1, 0xee, 0xb7, 0xba, 0xfe, 0x07, 0xae, 0xfd, 0x82, 0xbe, 0x6c, 0xbb, 0x69, 0x1d, 0x65, 0xc2, 0x7b, 0x7a, 0x43, 0x56, 0x0f, 0x51, 0x1f, 0x1e, 0x5c, 0x1d, 0x09, 0x1c, 0x53, 0xfe, 0xda, 0x70, 0xb8, 0x1c, 0x48, 0x79, 0xe7, 0x2f, 0x84, 0xb7, 0x28, 0x6e, 0xcc, 0xec, 0xc4, 0xc6, 0xd1, 0xeb, 0xc1, 0x39, 0x18, 0x59, 0x97, 0x80, 0x0f, 0xab, 0xab, 0x71, 0x5a, 0x25, 0xd6, 0xda, 0xcb, 0x12, 0xc8, 0xf3, 0xd7, 0xe9, 0xe8, 0xc4, 0x3a, 0x63, 0x82, 0xf2, 0x9f, 0xee, 0x22, 0x2a, 0x6e, 0xe2, 0xcd, 0x2e, 0xaa, 0x85, 0x7d, 0xb0, 0x69, 0xde, 0x5e, 0xd4, 0x4e, 0xc1, 0xc4, 0xb9, 0xfd, 0xb0, 0x35, 0x06, 0xcd, 0xf4, 0x8b, 0x00, 0xc1, 0xdd, 0x30, 0x8b, 0x0c, 0xed, 0x9d, 0x80, 0xb5, 0xde, 0x46, 0x30, 0x82, 0x15, 0xa7, 0x08, 0xc8, 0x85, 0x39, 0x1f, 0xd8, 0xc0, 0xc3, 0x6c, 0x4c, 0xca, 0xaa, 0xd8, 0xc5, 0xce, 0x36, 0x33, 0x90, 0x04, 0xae, 0x14, 0xd3, 0xc7, 0xaa, 0xb5, 0x5e, 0x0f, 0x92, 0x34, 0x75, 0x35, 0x87, 0x9c, 0xc1, 0x68, 0x04, 0x77, 0xb0, 0x35, 0xc0, 0x51, 0x7e, 0x8d, 0x87, 0x8d, 0x03, 0xdb, 0xb4, 0xa8, 0x9f, 0x41, 0xd7, 0x4f, 0xe4, 0x9c, 0x75, 0x2b, 0x5f, 0x91, 0x60, 0x3f, 0xcc, 0xc7, 0x72, 0x94, 0xf6, 0x1b, 0x2c, 0x23, 0x29, 0x5a, 0xd1, 0x77, 0x8b, 0x3c, 0x60, 0xbe, 0xa8, 0xff, 0xf6, 0x9d, 0xd9, 0xe5, 0x41, 0x34, 0x03, 0x3b, 0x5a, 0x05, 0xc1, 0xc6, 0xf4, 0x1f, 0xac, 0x39, 0xd6, 0x77, 0xaf, 0xd8, 0x8f, 0x73, 0xb6, 0x7c, 0x04, 0xd9, 0xa9, 0xb9, 0xb3, 0xd2, 0x47, 0x7d, 0xbb, 0xcf, 0x19, 0xa8, 0xbd, 0xe7, 0xd3, 0x6d, 0xf4, 0xdc, 0x76, 0x23, 0xff, 0x2d, 0x3b, 0xdf, 0xbe, 0xc4, 0x0d, 0x06, 0x8e, 0x81, 0xd0, 0x80, 0xad, 0x7d, 0x3e, 0xf8, 0x2f, 0x54, 0x08, 0x7a, 0xe2, 0x3d, 0x3f, 0x0e, 0xb2, 0x2a, 0xfb, 0xc4, 0xd0, 0x1c, 0x4d, 0x05, 0x01, 0xeb, 0xe4, 0x47, 0xc2, 0xa5, 0xf9, 0x2b, 0xa7, 0x93, 0xc5, 0x45, 0x8d, 0x44, 0x8e, 0x0e, 0x0b, 0xbe, 0x0f, 0xbd, 0xe3, 0xeb, 0x84, 0x25, 0x4a, 0xf7, 0x3b, 0x09, 0xc1, 0x35, 0xb8, 0xfb, 0xb9, 0xd7, 0xc3, 0x7e, 0x5c, 0x92, 0x00, 0x57, 0x93, 0xda, 0x95, 0xcd, 0x8b, 0x7f, 0x55, 0x8e, 0x6d, 0xd0, 0xfc, 0x63, 0x2a, 0x08, 0x59, 0xc1, 0xbb, 0xaa, 0xf9, 0x5f, 0x4a, 0xa3, 0x1b, 0x41, 0x29, 0x98, 0xaf, 0x4f, 0x41, 0x91, 0x13, 0x9a, 0x5d, 0x7d, 0x0c, 0xe9, 0xdf, 0xa4, 0xec, 0x8d, 0x58, 0x33, 0x41, 0xef, 0xd6, 0x86, 0x27, 0x1e, 0xac, 0x14, 0xdc, 0xe3, 0x48, 0x42, 0xa7, 0x8a, 0xfe, 0x76, 0x5f, 0xb5, 0x5e, 0xf0, 0x8f, 0x7a, 0x1d, 0x8d, 0x39, 0x72, 0x8c, 0x19, 0x10, 0xa7, 0x7c, 0xd3, 0x3d, 0x1f, 0xd7, 0xc1, 0xde, 0x11, 0x6c, 0x02, 0xdb, 0x27, 0x84, 0xe0, 0xd4, 0xe9, 0x1b, 0x69, 0x73, 0x4c, 0x01, 0xa8, 0x5f, 0xed, 0x09, 0xfc, 0x7c, 0x5e, 0x1a, 0xf7, 0x4e, 0xa8, 0xbc, 0x3c, 0x63, 0x83, 0x98, 0xa7, 0x78, 0x61, 0x2f, 0x17, 0x6b, 0xf5, 0x4b, 0xe5, 0x2c, 0x1d, 0x7c, 0x9c, 0x76, 0x40, 0x39, 0x7b, 0x31, 0xd3, 0xfe, 0xe1, 0x18, 0x5b, 0xaa, 0xf6, 0x9d, 0x8a, 0x4f, 0x21, 0xbf, 0x9d, 0x27, 0x6b, 0x10, 0x27, 0x55, 0x6a, 0xd6, 0x88, 0xf4, 0x26, 0xee, 0xb0, 0xd7, 0x03, 0x24, 0x08, 0xb4, 0x39, 0x0d, 0xd0, 0xd0, 0x1e, 0xef, 0x35, 0xaa, 0x5a, 0xd8, 0x8f, 0xfb, 0x1b, 0x18, 0x65, 0x45, 0xcb, 0x1b, 0x51, 0x10, 0x27, 0x50, 0xc4, 0x0c, 0x29, 0xd2, 0xac, 0xbb, 0xc9, 0xbe, 0x4e, 0x63, 0xbe, 0x6b, 0x49, 0xea, 0xb3, 0x87, 0x4a, 0x66, 0x71, 0xe1, 0x24, 0xef, 0x47, 0x5c, 0x2d, 0x4c, 0x8f, 0x7c, 0xf0, 0xe2, 0x59, 0x78, 0x6b, 0xe3, 0x9c, 0x6b, 0xd8, 0x19, 0x74, 0xe6, 0x12, 0xa3, 0x65, 0xda, 0x85, 0x13, 0xd7, 0x62, 0x70, 0x51, 0x74, 0x53, 0x18, 0x30, 0xcf, 0xa0, 0xb7, 0x60, 0x98, 0xb5, 0x98, 0x2d, 0xc9, 0x55, 0x83, 0x6b, 0xe9, 0x2a, 0x4a, 0x50, 0x9c, 0xdc, 0xde, 0xf6, 0x3e, 0x68, 0x64, 0x6b, 0xc6, 0x45, 0x59, 0x69, 0x0a, 0x8b, 0x47, 0x33, 0x64, 0x32, 0xc8, 0x8a, 0x4c, 0x9e, 0xff, 0xa5, 0x67, 0x77, 0x0a, 0x78, 0xd8, 0x09, 0x7c, 0x6c, 0x97, 0xe2, 0x37, 0x01, 0xdf, 0xb9, 0x9d, 0x9d, 0x70, 0x2e, 0x0b, 0x0b, 0x5b, 0xad, 0x92, 0x38, 0x29, 0x12, 0xe9, 0x42, 0x7b, 0x7c, 0x34, 0x7e, 0x19, 0x9b, 0xbb, 0x97, 0x6c, 0x6e, 0xd3, 0xac, 0x27, 0x2a, 0xa6, 0xda, 0x14, 0xab, 0x44, 0xf1, 0xa7, 0x42, 0x3d, 0xaa, 0xc0, 0x93, 0xae, 0x43, 0xdf, 0x9f, 0xea, 0x92, 0xcc, 0x36, 0xb0, 0x01, 0x2f, 0xc4, 0xaa, 0x63, 0x68, 0x7a, 0x8e, 0xb1, 0x4f, 0x15, 0x43, 0x01, 0x6f, 0x55, 0xa9, 0x2e, 0x35, 0x92, 0xbf, 0xf5, 0x3c, 0xe4, 0x22, 0xa3, 0x87, 0x72, 0x05, 0x7a, 0xc3, 0xcf, 0x31, 0xfc, 0x16, 0x39, 0x10, 0x02, 0x41, 0xb6, 0xc1, 0xbb, 0x49, 0x0f, 0x22, 0x93, 0x4a, 0xb2, 0x5c, 0x53, 0x33, 0x11, 0xa9, 0xd6, 0xcf, 0x21, 0x4d, 0x30, 0x8c, 0xf6, 0xd0, 0x37, 0xd6, 0xbf, 0x53, 0x25, 0x64, 0x29, 0xa9, 0x77, 0x3c, 0x27, 0x05, 0x2d, 0x78, 0x02, 0xa2, 0xba, 0x7c, 0x92, 0xd6, 0xf3, 0x0e, 0x56, 0x42, 0x0f, 0xa5, 0xc6, 0x15, 0x77, 0xde, 0x0f, 0xd2, 0x87, 0x32, 0x31, 0xec, 0x52, 0x85, 0xec, 0x88, 0x5c, 0x51, 0x9b, 0x4c, 0xef, 0xbe, 0x75, 0x96, 0xa4, 0x82, 0x08, 0x95, 0xef, 0x4a, 0x07, 0x6d, 0x5c, 0xb6, 0x99, 0xaa, 0xd1, 0x05, 0x61, 0x91, 0x91, 0x8f, 0x6b, 0x14, 0xa6, 0xb7, 0xf9, 0x23, 0xf2, 0x3e, 0x32, 0x8d, 0xbe, 0x72, 0x96, 0x5b, 0xf8, 0x97, 0x12, 0x1d, 0x77, 0x07, 0x38, 0x84, 0x95, 0xc2, 0x3d, 0x87, 0x3c, 0x7f, 0x57, 0x32, 0x68, 0xb4, 0x94, 0x86, 0xa5, 0xb1, 0xae, 0x6c, 0x5b, 0x92, 0x1c, 0xdb, 0x15, 0xfb, 0xc9, 0x39, 0x4a, 0x4c, 0xcf, 0xdf, 0x7f, 0x7b, 0x71, 0x9a, 0xd5, 0x8b, 0x38, 0x29, 0x69, 0xd0, 0xe0, 0x30, 0x4d, 0xd2, 0x0c, 0xb6, 0x2c, 0x58, 0x1d, 0x9b, 0x02, 0xdc, 0x1a, 0xb6, 0x1e, 0x17, 0xd1, 0xb3, 0x61, 0xb5, 0x19, 0xcb, 0xb7, 0xd7, 0x3f, 0x7c, 0xca, 0xce, 0x08, 0xe0, 0x76, 0x2a, 0x05, 0xb5, 0xfe, 0x40, 0x29, 0x86, 0x79, 0x0c, 0x0a, 0xc1, 0x71, 0x0f, 0x7e, 0x33, 0x81, 0x25, 0x2a, 0x5b, 0xf1, 0x70, 0xf5, 0x7c, 0xae, 0xea, 0xc9, 0x38, 0x91, 0xac, 0xb1, 0xae, 0xe9, 0xb8, 0xeb, 0x30, 0x8d, 0xe0, 0x5f, 0x58, 0x98, 0x38, 0xbd, 0xc7, 0xa0, 0x6f, 0xcf, 0xf0, 0xfa, 0x64, 0xd5, 0x30, 0x73, 0xd8, 0xfc, 0xb6, 0xc2, 0x74, 0x3d, 0xbd, 0xfa, 0xa2, 0x64, 0x3f, 0x6a, 0x01, 0xa6, 0x4c, 0x73, 0xb6, 0x43, 0x20, 0xd3, 0x88, 0x80, 0x4c, 0x9a, 0x32, 0xb6, 0x4d, 0xf4, 0xf3, 0xfd, 0x10, 0xa8, 0x10, 0x54, 0x80, 0xd0, 0xfc, 0x43, 0xfe, 0x15, 0xb6, 0x66, 0x79, 0xad, 0xb5, 0x13, 0x1a, 0xc0, 0xb1, 0x86, 0xb0, 0x83, 0xe3, 0xdd, 0xee, 0x18, 0x78, 0xe1, 0x45, 0x7c, 0x9d, 0x8b, 0xdc, 0xbb, 0x35, 0xde, 0x27, 0x05, 0x5f, 0xc8, 0x2f, 0x51, 0xe6, 0x1b, 0xf4, 0x7c, 0x10, 0x5e, 0x85, 0xe9, 0xfc, 0x05, 0x48, 0x72, 0x04, 0xdc, 0x3a, 0xd9, 0x11, 0x88, 0x71, 0xa2, 0xda, 0x1e, 0xb2, 0xb9, 0xc9, 0x72, 0xe0, 0xf7, 0xfa, 0x20, 0x6a, 0x53, 0xd6, 0xd3, 0xab, 0xfa, 0x86, 0x5e, 0x49, 0x6f, 0x20, 0x1b, 0x47, 0xe0, 0xa4, 0x5f, 0x4b, 0x90, 0x11, 0x7c, 0xd2, 0xc2, 0x92, 0xed, 0xaa, 0xb0, 0x14, 0x0b, 0x5b, 0x8d, 0x36, 0xb1, 0x8a, 0x1c, 0xe8, 0x08, 0xac, 0x71, 0xa1, 0xb3, 0x64, 0x4d, 0xf2, 0x4c, 0x29, 0x23, 0x0c, 0x0c, 0x80, 0xae, 0xd2, 0xc3, 0x23, 0x23, 0xae, 0x70, 0xc7, 0xb8, 0xba, 0x04, 0x85, 0xc2, 0xca, 0x81, 0xc4, 0x13, 0x14, 0xc5, 0xaa, 0x5e, 0xfa, 0x94, 0x87, 0x08, 0xf8, 0xce, 0x1a, 0x0b, 0x67, 0x74, 0x91, 0xe0, 0xec, 0x62, 0x84, 0xf3, 0x1f, 0xa9, 0xae, 0x0d, 0x22, 0x97, 0x43, 0x5d, 0x71, 0xf2, 0xa4, 0xbd, 0x0f, 0xc6, 0x21, 0xef, 0x1d, 0x50, 0x06, 0xe4, 0x60, 0x08, 0x1b, 0x5b, 0x0c, 0xf8, 0xd7, 0x4b, 0x0c, 0x71, 0x89, 0x66, 0xec, 0xcd, 0x9e, 0x7f, 0x3b, 0x6d, 0x51, 0x85, 0x18, 0xe0, 0x5e, 0xcf, 0x99, 0xf5, 0xa8, 0xd4, 0x50, 0x77, 0x0b, 0x52, 0xb8, 0xde, 0xc7, 0xfa, 0x8e, 0x7c, 0x94, 0x73, 0x44, 0x11, 0x1c, 0xb2, 0x48, 0x89, 0xe8, 0xc3, 0xa7, 0xd7, 0xdc, 0x46, 0x99, 0x7e, 0xb3, 0x1a, 0x7f, 0x76, 0x76, 0x07, 0x56, 0x9f, 0x92, 0xad, 0xe0, 0x34, 0x44, 0xdf, 0xf9, 0x0a, 0xc4, 0xbb, 0xf6, 0x50, 0x15, 0x5e, 0x91, 0x54, 0x0a, 0x84, 0x13, 0xca, 0x72, 0xf8, 0x68, 0x97, 0xd9, 0x94, 0x27, 0x43, 0x15, 0xdc, 0x0f, 0x85, 0x6f, 0x1f, 0x5b, 0x15, 0x84, 0x98, 0xed, 0x99, 0x4e, 0x51, 0xa9, 0x2f, 0xaf, 0x8e, 0xf4, 0xdf, 0x23, 0x1c, 0xd9, 0x6e, 0x4a, 0x1d, 0xe5, 0x77, 0xd0, 0x69, 0xac, 0x6f, 0x50, 0x7e, 0x5b, 0xd5, 0xa6, 0x68, 0x32, 0x53, 0x61, 0x25, 0x85, 0x40, 0x28, 0xfa, 0x36, 0x7f, 0x79, 0x1b, 0xa3, 0x1f, 0x95, 0x97, 0xcd, 0x02, 0xe8, 0x5e, 0x27, 0xe0, 0xe9, 0x27, 0xcd, 0x2c, 0x4d, 0xac, 0x70, 0x23, 0xfc, 0x55, 0x6a, 0xf8, 0x5c, 0xf5, 0x2f, 0x61, 0xd0, 0xb2, 0x31, 0xa8, 0xa4, 0xbd, 0xcc, 0x38, 0xe2, 0x20, 0x26, 0x09, 0xf4, 0x1e, 0xec, 0x11, 0x63, 0x41, 0xaa, 0x34, 0xc3, 0xb6, 0xe2, 0x7d, 0x2e, 0x9f, 0xba, 0xdc, 0x41, 0x2f, 0x06, 0x93, 0xb7, 0xfd, 0xc1, 0x57, 0x5a, 0x3e, 0x79, 0x10, 0xe4, 0x12, 0xbd, 0x28, 0xa8, 0x95, 0x28, 0x59, 0x1c, 0x87, 0x41, 0x2f, 0xfe, 0x67, 0x2e, 0x8a, 0xcf, 0x16, 0xc5, 0x7b, 0x59, 0xfc, 0xd7, 0x1b, 0xd8, 0x95, 0x1a, 0x56, 0x95, 0x23, 0xa8, 0xd6, 0x53, 0xce, 0x8d, 0xc4, 0xfd, 0xfe, 0xfc, 0x86, 0x3b, 0x5c, 0x9f, 0x8f, 0x93, 0x98, 0xfe, 0x44, 0x2d, 0x9e, 0xcd, 0x7b, 0xa9, 0xde, 0x26, 0x6c, 0x27, 0xbc, 0x6d, 0xd3, 0x35, 0xe3, 0xd1, 0x78, 0x78, 0x7d, 0x92, 0x2a, 0xdb, 0xd0, 0x45, 0xd6, 0x52, 0x2b, 0xae, 0x4a, 0xa3, 0x98, 0x00, 0xa0, 0xc2, 0xa2, 0x2b, 0xa1, 0xf0, 0x06, 0x1b, 0x8d, 0x84, 0x37, 0x03, 0x54, 0x64, 0x3d, 0x7a, 0xce, 0x8e, 0x6c, 0x02, 0x78, 0xd9, 0xe3, 0xbe, 0x99, 0x75, 0xfd, 0x3f, 0xc7, 0x41, 0x10, 0x33, 0x75, 0x95, 0xbc, 0x8c, 0xc8, 0x26, 0x28, 0x01, 0xae, 0x99, 0x38, 0x94, 0x54, 0x39, 0xf6, 0x15, 0x0f, 0x25, 0x89, 0x4a, 0xa0, 0xae, 0x5c, 0xce, 0x27, 0x3e, 0xf2, 0xda, 0x98, 0x98, 0x0b, 0x1d, 0xa3, 0xda, 0x07, 0xb3, 0xb0, 0x59, 0x45, 0x9c, 0x74, 0xf5, 0x48, 0xc0, 0xc2, 0x49, 0x87, 0x73, 0x2d, 0xf3, 0x05, 0xb0, 0xcb, 0x5a, 0x71, 0x4a, 0xe0, 0xf7, 0x7a, 0xb2, 0xd7, 0x06, 0xa4, 0x2a, 0xc4, 0xa5, 0x7d, 0x64, 0xdf, 0x35, 0xc5, 0x6c, 0x89, 0x28, 0xbf, 0xde, 0x45, 0x0b, 0x62, 0xe1, 0xbc, 0xb8, 0x7a, 0x16, 0x24, 0xed, 0x4a, 0x86, 0x9a, 0xdc, 0x1e, 0x82, 0xdd, 0xc9, 0xb9, 0xd4, 0x9d, 0xcc, 0x54, 0x00, 0x89, 0x5e, 0xc4, 0x28, 0x43, 0x6c, 0xef, 0x7c, 0x01, 0x0e, 0x32, 0xc6, 0x71, 0x92, 0xd6, 0xe8, 0x85, 0x0e, 0x0a, 0xf6, 0xf7, 0xcf, 0x79, 0xe2, 0xc3, 0x2a, 0x16, 0x54, 0xb9, 0xa9, 0xe5, 0xea, 0xea, 0xde, 0xd5, 0xe4, 0x51, 0x93, 0x1a, 0x0a, 0x0e, 0x0a, 0x53, 0x19, 0x31, 0x99, 0x57, 0xfa, 0x8d, 0xa3, 0x56, 0x5a, 0xf1, 0xec, 0xcd, 0x0b, 0xae, 0xf9, 0x47, 0x1f, 0xff, 0x78, 0x86, 0x39, 0x4d, 0xf4, 0x05, 0x1f, 0xc9, 0xf0, 0x2c, 0xc6, 0xdc, 0x10, 0xa2, 0x70, 0x51, 0x40, 0x31, 0x4d, 0xa6, 0x9d, 0x55, 0xc5, 0x0b, 0x06, 0x23, 0x1e, 0x56, 0xd2, 0x90, 0x1d, 0xa9, 0xab, 0xbe, 0x89, 0x52, 0x97, 0x6c, 0xb5, 0x5f, 0x24, 0xab, 0x84, 0xdf, 0x10, 0xff, 0xea, 0x70, 0x93, 0xb3, 0xd5, 0x76, 0xc9, 0x7a, 0xcc, 0x63, 0x96, 0x00, 0xf7, 0x80, 0x0c, 0xdf, 0xe8, 0x82, 0x78, 0x25, 0xef, 0xbb, 0xd5, 0xdb, 0xb2, 0x5f, 0xd5, 0xba, 0xfe, 0x65, 0xa4, 0x1c, 0x0c, 0x0c, 0x47, 0x1a, 0x9c, 0x29, 0xbe, 0x60, 0xec, 0x04, 0xd7, 0x23, 0x84, 0x37, 0x1c, 0x72, 0xf9, 0x47, 0xe3, 0x7b, 0x34, 0x8d, 0xb4, 0xb9, 0xeb, 0x29, 0x5f, 0x9f, 0x67, 0x13, 0x44, 0x88, 0x5d, 0x91, 0x66, 0x5a, 0x53, 0x8b, 0x08, 0x6f, 0x21, 0xe3, 0xf2, 0x2c, 0xb4, 0x2c, 0xb8, 0x93, 0x18, 0x6a, 0x4d, 0xf4, 0x71, 0x1a, 0x4b, 0xf1, 0xb4, 0xf8, 0xd2, 0xc9, 0xb8, 0xc5, 0x20, 0xef, 0x12, 0x94, 0x79, 0x17, 0x21, 0x1c, 0x17, 0x85, 0xe8, 0x93, 0x11, 0x6f, 0xec, 0x7c, 0xcc, 0x71, 0xaa, 0x39, 0xa7, 0x64, 0xe5, 0xb5, 0xb8, 0xe5, 0x00, 0xb4, 0xd1, 0x1e, 0x48, 0x5f, 0x4b, 0xa5, 0xee, 0x02, 0x51, 0x59, 0xd4, 0x16, 0xf6, 0xe1, 0x86, 0x9c, 0x44, 0xf3, 0x72, 0xf5, 0xd4, 0xdd, 0xc9, 0xaf, 0x35, 0x58, 0x89, 0x8e, 0x80, 0xe1, 0xb9, 0x6e, 0xd5, 0xaf, 0xf1, 0x3a, 0x86, 0xb9, 0xb0, 0xaf, 0x44, 0xcc, 0x22, 0x85, 0xaa, 0x64, 0x98, 0xaf, 0x4e, 0xd6, 0x8c, 0x78, 0x70, 0x2d, 0x9d, 0xc0, 0x63, 0xc7, 0x32, 0xfa, 0x90, 0xaf, 0xc4, 0x81, 0x98, 0x7f, 0x29, 0x5b, 0xc8, 0xb4, 0x60, 0xaa, 0x1f, 0x65, 0x43, 0x53, 0xce, 0x17, 0x94, 0x97, 0x2c, 0x7a, 0xea, 0xdf, 0xb0, 0x3c, 0x4a, 0x34, 0x30, 0x42, 0x6f, 0x35, 0xf2, 0x11, 0x8b, 0x29, 0x7a, 0x7f, 0x4e, 0xd8, 0x23, 0xe4, 0xa0, 0x1c, 0xdb, 0x5a, 0x7a, 0x44, 0x69, 0xbd, 0x9c, 0xbd, 0x3d, 0x7f, 0x99, 0x2e, 0xea, 0x2f, 0xbc, 0xf3, 0x2e, 0x61, 0xcf, 0x9b, 0x9c, 0xf9, 0x51, 0x22, 0x90, 0xfd, 0x85, 0x6d, 0x39, 0x37, 0x95, 0x82, 0x2e, 0x05, 0xe3, 0x3b, 0x17, 0x4d, 0x26, 0x0e, 0xc5, 0xf1, 0x80, 0x09, 0xc1, 0x3b, 0xaa, 0x96, 0x21, 0x1b, 0x46, 0x2f, 0xcf, 0xab, 0xbe, 0x2d, 0xa2, 0xe7, 0x29, 0x1c, 0xfe, 0x4a, 0xe2, 0xf1, 0x42, 0x0a, 0x29, 0x0b, 0x37, 0xf8, 0xa0, 0x98, 0x20, 0x46, 0xd6, 0xde, 0xc2, 0x84, 0xc8, 0x29, 0x0f, 0x87, 0xde, 0xf1, 0xad, 0xff, 0x7b, 0xeb, 0xe5, 0x84, 0x1b, 0x6a, 0x87, 0x91, 0x40, 0x82, 0xf7, 0x61, 0x32, 0xb0, 0x1d, 0x32, 0xf2, 0x69, 0xeb, 0xcf, 0x80, 0xd0, 0xb4, 0x70, 0xc5, 0x25, 0xff, 0xe0, 0x43, 0x38, 0xa3, 0x5e, 0x1e, 0x44, 0x1c, 0x01, 0x1a, 0x66, 0x8f, 0xa5, 0x52, 0x8c, 0xb8, 0x4f, 0x8b, 0x82, 0x4a, 0x19, 0xb7, 0x87, 0x43, 0x12, 0xde, 0x24, 0x2d, 0x52, 0xa3, 0x78, 0xe2, 0x7f, 0xca, 0x6d, 0xe0, 0x6f, 0x9d, 0x7f, 0x47, 0x9a, 0x1c, 0xe9, 0xe6, 0xbd, 0x3e, 0x13, 0x6c, 0x0b, 0x2c, 0x0b, 0xce, 0xa1, 0x63, 0x45, 0x16, 0x9d, 0x16, 0x53, 0xbc, 0x33, 0xed, 0xcb, 0xa7, 0x71, 0xdd, 0x22, 0x67, 0xe4, 0x1c, 0x90, 0x8d, 0xd1, 0xcd, 0xa6, 0xb5, 0xe3, 0xdd, 0xfa, 0x21, 0x33, 0x59, 0x77, 0x4c, 0xf3, 0xc5, 0xab, 0x3f, 0x9e, 0x3c, 0x19, 0x54, 0xc2, 0xf6, 0x09, 0xd4, 0x76, 0xcc, 0x0b, 0xc9, 0x00, 0x19, 0xab, 0x07, 0xb8, 0xa1, 0x7e, 0x62, 0x9a, 0x5c, 0x57, 0xbd, 0xc5, 0xa9, 0xd7, 0x70, 0x5a, 0xa9, 0x77, 0xaa, 0x0a, 0x64, 0xbe, 0xd2, 0x5e, 0x1d, 0xb3, 0xc4, 0x2b, 0x82, 0xba, 0x28, 0x81, 0x45, 0x08, 0x6d, 0xd3, 0x8e, 0x79, 0x6b, 0xd8, 0xd2, 0x31, 0x61, 0xd2, 0xbd, 0xcf, 0xe5, 0xc3, 0x45, 0x99, 0x2c, 0x7f, 0x80, 0xb1, 0x39, 0x8b, 0xb0, 0xbb, 0x62, 0x3a, 0x22, 0xb4, 0x84, 0xb5, 0xbb, 0x99, 0xd8, 0x1c, 0x55, 0x86, 0x53, 0xfc, 0x28, 0xc1, 0x7d, 0x49, 0x0e, 0xf4, 0x27, 0xff, 0x40, 0x94, 0xe1, 0xef, 0x7e, 0x20, 0x17, 0x30, 0x3b, 0x03, 0x7b, 0xc3, 0x57, 0xec, 0xf7, 0x53, 0xc5, 0xc2, 0xc8, 0x08, 0xae, 0xc0, 0x30, 0x57, 0x11, 0xd6, 0xd6, 0x5f, 0xbe, 0x27, 0x93, 0x6c, 0xf1, 0xe8, 0xa4, 0xca, 0x5d, 0xb4, 0x3f, 0xde, 0x8d, 0xce, 0x85, 0x0b, 0x13, 0xe8, 0x55, 0x33, 0x02, 0x11, 0xdb, 0xb8, 0x35, 0x70, 0x97, 0x49, 0xf4, 0xad, 0x4e, 0x07, 0x1b, 0x2e, 0x17, 0x7e, 0xee, 0xc5, 0xf4, 0x6f, 0x9d, 0x7e, 0x47, 0x58, 0x41, 0x12, 0xca, 0x0c, 0x5b, 0x6f, 0x02, 0xc3, 0x11, 0x96, 0x1c, 0x28, 0xde, 0x2b, 0x70, 0xe5, 0x8b, 0xaa, 0xe3, 0x1d, 0xce, 0xa7, 0x1c, 0xa6, 0xaf, 0xd9, 0x50, 0x20, 0x6c, 0xaf, 0x63, 0x5c, 0xc6, 0x3a, 0xf1, 0x6a, 0x08, 0x54, 0xf9, 0xd5, 0xa2, 0xd8, 0x88, 0x51, 0x19, 0x48, 0xcd, 0xae, 0x72, 0xc2, 0x09, 0x8d, 0xcc, 0xdc, 0x39, 0x37, 0xca, 0x34, 0xeb, 0xb5, 0x0a, 0x74, 0xf2, 0xd7, 0x10, 0x81, 0xd4, 0x4c, 0xfb, 0xf9, 0x84, 0xdd, 0xb4, 0xf9, 0x17, 0x94, 0x7b, 0xe7, 0x2a, 0x02, 0x98, 0x02, 0xa9, 0xe2, 0x5b, 0x89, 0xd5, 0xc3, 0x12, 0x11, 0x5a, 0x25, 0x5c, 0xcb, 0xdc, 0x9a, 0xe7, 0x8b, 0x61, 0x2f, 0x00, 0xf0, 0xaa, 0x11, 0xae, 0xc2, 0xdb, 0xe5, 0xa4, 0xbe, 0x08, 0x8e, 0xea, 0xb2, 0x56, 0x4d, 0x00, 0xf1, 0x95, 0xe9, 0x75, 0xe2, 0x55, 0x24, 0xb5, 0xd7, 0x6c, 0xd3, 0xa0, 0x92, 0xf2, 0x09, 0xdb, 0xf7, 0xa4, 0x07, 0xec, 0xf8, 0x5c, 0xe2, 0x00, 0x09, 0x9a, 0x33, 0x1c, 0xeb, 0x37, 0x17, 0xd1, 0x49, 0x63, 0xf4, 0x0f, 0x8b, 0x86, 0xfe, 0x6b, 0xc2, 0x06, 0xe6, 0x95, 0xa7, 0xc3, 0xd5, 0x70, 0xc0, 0xc1, 0x33, 0x36, 0x9b, 0xa8, 0xa9, 0x23, 0xd5, 0xfa, 0x10, 0xc3, 0x58, 0x2f, 0x64, 0x52, 0x49, 0xde, 0xe4, 0x5c, 0xe1, 0x84, 0xda, 0x12, 0xfa, 0x0a, 0xf2, 0xf2, 0x3d, 0x93, 0xdd, 0x3b, 0x17, 0x54, 0x15, 0x2d, 0x95, 0xb9, 0xab, 0x2f, 0x4c, 0xa8, 0x1b, 0x14, 0x18, 0x35, 0xb4, 0xe7, 0x46, 0x69, 0x50, 0x41, 0xba, 0xad, 0x34, 0x7e, 0x01, 0x81, 0xa4, 0xb3, 0xcf, 0x20, 0xdf, 0x61, 0x8f, 0x48, 0x22, 0x66, 0x23, 0x44, 0x39, 0xa7, 0x44, 0x40, 0x45, 0x36, 0xf4, 0xd6, 0xba, 0x52, 0x4c, 0x81, 0xd4, 0xe5, 0xda, 0x7a, 0x3b, 0xae, 0x79, 0x2d, 0x0d, 0xcb, 0xa6, 0xb5, 0x9c, 0xe6, 0xda, 0xeb, 0xfd, 0x96, 0xd1, 0xe2, 0xd7, 0x48, 0xcb, 0xa4, 0x1b, 0x37, 0x54, 0x38, 0xab, 0xb9, 0xde, 0x1f, 0xd6, 0xbd, 0x61, 0x89, 0x82, 0x16, 0xda, 0xbc, 0x86, 0x2a, 0x77, 0xe0, 0x3e, 0x4e, 0xec, 0xe2, 0x0e, 0x91, 0x2e, 0x9c, 0xbc, 0xc6, 0x0c, 0x1d, 0xc8, 0xe2, 0x36, 0x45, 0x48, 0x75, 0x01, 0xfc, 0xf7, 0xbc, 0xe1, 0x46, 0x19, 0x46, 0x0e, 0xf9, 0x7d, 0x35, 0x1c, 0xa2, 0x7c, 0x54, 0x38, 0xd3, 0x70, 0x74, 0xea, 0x81, 0x5e, 0x23, 0xa0, 0xb7, 0x40, 0x72, 0x60, 0x3b, 0x55, 0xc9, 0x57, 0xef, 0x89, 0x41, 0xc8, 0x85, 0xf4, 0x4a, 0xfc, 0x41, 0x60, 0x2d, 0xcc, 0xc8, 0x50, 0xe9, 0x15, 0x6f, 0xce, 0xa8, 0x5d, 0xf8, 0x5a, 0xdc, 0x45, 0x05, 0x4a, 0x90, 0x78, 0x78, 0xb3, 0x2e, 0xf3, 0x56, 0x02, 0x58, 0xe3, 0xd0, 0x08, 0xc9, 0x42, 0x5e, 0xf9, 0x84, 0xb7, 0x5e, 0xaa, 0xba, 0xfd, 0x19, 0x55, 0xef, 0x70, 0x5d, 0x8d, 0xbf, 0x1d, 0x51, 0x7d, 0xb7, 0x7f, 0x1c, 0x10, 0x7b, 0x5b, 0x91, 0x1e, 0x7f, 0xbf, 0xc7, 0x34, 0x29, 0x4d, 0xb9, 0xcd, 0xe7, 0xdc, 0xe4, 0x22, 0x5b, 0xd6, 0x48, 0xb7, 0xaa, 0xce, 0xe7, 0x0c, 0x18, 0x6d, 0x5f, 0xe3, 0xdf, 0x37, 0x32, 0xb1, 0xcf, 0x51, 0xc9, 0xf5, 0x2e, 0xc3, 0xa7, 0x77, 0x37, 0xa3, 0x49, 0xdb, 0x93, 0xee, 0x69, 0x5b, 0xb2, 0xf2, 0xe7, 0x36, 0x05, 0x4e, 0xec, 0x3a, 0x43, 0x18, 0xcc, 0xdf, 0xa3, 0x76, 0xb6, 0x71, 0xf3, 0xf0, 0x88, 0xc8, 0x2a, 0xbb, 0x6f, 0x06, 0xdc, 0x55, 0x49, 0xef, 0xcf, 0x84, 0x14, 0xd2, 0x88, 0x12, 0x7f, 0xa0, 0xbd, 0x91, 0x20, 0xb2, 0x8d, 0x3b, 0xd0, 0xf5, 0xed, 0xd7, 0x72, 0x22, 0x0a, 0xbd, 0x29, 0x9e, 0xab, 0xb1, 0xac, 0x33, 0xb1, 0x9b, 0xab, 0x02, 0x8e, 0x98, 0xe5, 0x46, 0xd6, 0xbc, 0x6e, 0x03, 0x1e, 0x04, 0xb7, 0xfd, 0x4f, 0xcd, 0x6e, 0x14, 0xca, 0x0b, 0xac, 0xa4, 0x8b, 0xa3, 0x9f, 0x1a, 0xe7, 0x0a, 0x26, 0xe0, 0xa5, 0x54, 0x98, 0x46, 0x6c, 0x1e, 0x87, 0x72, 0xc7, 0xfb, 0x25, 0x18, 0xc3, 0x22, 0xe3, 0xa9, 0x34, 0xd3, 0xef, 0x82, 0x3a, 0xc3, 0x44, 0x2f, 0x22, 0x96, 0x5b, 0x73, 0x38, 0x1e, 0x81, 0xe2, 0xef, 0x59, 0x77, 0x01, 0xd7, 0x06, 0xd8, 0x5f, 0xff, 0x85, 0x82, 0xa4, 0x77, 0x09, 0xb5, 0x26, 0x12, 0x4e, 0x6f, 0x87, 0xcd, 0x33, 0x6d, 0x90, 0x94, 0xa8, 0x71, 0x89, 0xc2, 0xcb, 0x7e, 0xf3, 0x34, 0x25, 0x08, 0x89, 0xf1, 0xd5, 0xc2, 0x2d, 0x9c, 0x4f, 0xdc, 0x14, 0x67, 0x8d, 0xcc, 0x6b, 0x45, 0xbf, 0x15, 0x0f, 0x3f, 0x98, 0x46, 0x70, 0x30, 0x29, 0x42, 0x36, 0x32, 0x12, 0x73, 0x1a, 0x45, 0xa4, 0xbb, 0x83, 0xb5, 0x90, 0xa3, 0x78, 0x5f, 0xaf, 0x00, 0xfc, 0x97, 0xad, 0xbe, 0x40, 0x2d, 0x31, 0x63, 0x65, 0x56, 0xfa, 0x14, 0x27, 0x49, 0x16, 0xea, 0xaa, 0x4e, 0x41, 0x20, 0x00, 0xe8, 0x72, 0x5f, 0x68, 0x62, 0x26, 0x41, 0x53, 0x1b, 0xe0, 0x4c, 0x8f, 0x88, 0x0c, 0xf5, 0xcb, 0xf6, 0x7d, 0x00, 0x93, 0x08, 0xfa, 0xc3, 0xab, 0xff, 0x03, 0x5e, 0xdb, 0x00, 0xbf, 0x96, 0xb5, 0xf3, 0x5d, 0x59, 0xbc, 0x90, 0x70, 0xbd, 0x4d, 0xa7, 0x33, 0xab, 0x1c, 0xcd, 0x12, 0x97, 0x86, 0x10, 0xc4, 0x37, 0xfc, 0x01, 0xc3, 0x97, 0x8d, 0xad, 0x84, 0x61, 0xf0, 0xec, 0x2b, 0xfa, 0xd4, 0x75, 0x09, 0x6b, 0x7d, 0x4b, 0x7b, 0x5d, 0x7c, 0x9b, 0x60, 0x27, 0x42, 0xa9, 0x8b, 0xe3, 0x7e, 0xe1, 0x91, 0xa0, 0xa5, 0xf8, 0xaf, 0x62, 0x44, 0x53, 0xe4, 0xaa, 0xe8, 0x30, 0xa7, 0x45, 0xf6, 0xc2, 0x22, 0xa4, 0xbc, 0xf0, 0x9c, 0x9c, 0x12, 0x57, 0xcc, 0x99, 0x03, 0xd6, 0x8c, 0x7b, 0x97, 0xe5, 0x04, 0xac, 0xfb, 0xf9, 0x5c, 0x75, 0x9b, 0x51, 0xb5, 0x44, 0x0b, 0xde, 0x66, 0xf5, 0xa4, 0xa1, 0x04, 0x44, 0xc0, 0x2f, 0xe3, 0xa1, 0x0f, 0x71, 0xcb, 0x81, 0x36, 0xbf, 0xe8, 0x5c, 0x9c, 0xe8, 0x13, 0xf3, 0xe8, 0xc0, 0xcb, 0x84, 0xe4, 0x61, 0x3d, 0x12, 0x20, 0x21, 0x70, 0x39, 0x06, 0xc4, 0x7a, 0x4b, 0xd1, 0x1d, 0xe8, 0x7c, 0x1d, 0x87, 0x57, 0x0e, 0xd9, 0x09, 0x72, 0x7a, 0x2e, 0x32, 0xf0, 0x91, 0x3e, 0x0f, 0xcd, 0xc2, 0xbb, 0xb7, 0x5e, 0x6d, 0xa8, 0x6a, 0x13, 0xf9, 0x64, 0x61, 0x0f, 0x44, 0xa6, 0x40, 0x82, 0xf8, 0x2e, 0xec, 0x30, 0x11, 0x18, 0x21, 0x86, 0xd6, 0x33, 0x54, 0x2e, 0xba, 0x28, 0x93, 0xf6, 0xbb, 0x1f, 0x69, 0xc5, 0xd5, 0x1f, 0x9b, 0x53, 0x12, 0xf7, 0x64, 0x64, 0x61, 0x28, 0xfa, 0xba, 0xa2, 0xc6, 0x98, 0x9c, 0x02, 0x09, 0x36, 0xa0, 0x6e, 0xef, 0xa8, 0x13, 0x8f, 0x18, 0x8d, 0x90, 0x07, 0xfd, 0x6b, 0x48, 0x27, 0xff, 0x52, 0x8c, 0x5d, 0x1c, 0xc2, 0x87, 0x72, 0xa1, 0x67, 0xa2, 0x82, 0xb6, 0xec, 0x96, 0x03, 0xf4, 0x5c, 0xfd, 0x3f, 0xf7, 0xd3, 0x34, 0xb0, 0x35, 0x41, 0x68, 0x72, 0x9f, 0xc9, 0x8c, 0x6f, 0x0e, 0x7c, 0xf4, 0x5b, 0x65, 0xe3, 0xfd, 0x52, 0x07, 0x25, 0x68, 0x75, 0x5d, 0xe9, 0x51, 0x0a, 0x6c, 0xa0, 0xf5, 0x9c, 0x81, 0x18, 0xf0, 0x79, 0xbe, 0xbe, 0x69, 0x1c, 0x8b, 0x9f, 0x1b, 0xb0, 0xe3, 0x09, 0xac, 0x7a, 0x0b, 0x9c, 0xf8, 0xe5, 0x2c, 0x1d, 0xa8, 0x32, 0x5b, 0x0a, 0x61, 0x6c, 0xe1, 0x2a, 0x5b, 0x9a, 0x51, 0x19, 0xf5, 0x3f, 0x23, 0x33, 0x73, 0xa3, 0x0d, 0xe3, 0xf6, 0x4f, 0xc8, 0x98, 0x08, 0x4e, 0x94, 0x3f, 0xf7, 0xcb, 0x12, 0x4f, 0xf1, 0x8b, 0xea, 0x45, 0xbf, 0x0d, 0x54, 0xf3, 0x09, 0xd4, 0x69, 0xe9, 0x9c, 0xb7, 0xe6, 0x82, 0xe5, 0x95, 0x70, 0x8d, 0x85, 0x6e, 0x06, 0xda, 0x7d, 0x8f, 0x0c, 0x39, 0xda, 0xfe, 0xd5, 0x72, 0x39, 0xbd, 0x55, 0xa1, 0x8f, 0x4e, 0x77, 0x20, 0x4d, 0x26, 0x35, 0x07, 0x95, 0xe4, 0xbf, 0xf8, 0x79, 0x77, 0x9d, 0xa6, 0x88, 0x32, 0x53, 0x13, 0x5e, 0xf0, 0x59, 0x8b, 0x32, 0x89, 0xd7, 0x2f, 0x56, 0xda, 0x78, 0xe7, 0xb1, 0x8f, 0xad, 0xb7, 0x50, 0xf1, 0x5e, 0x56, 0x13, 0x78, 0x34, 0x52, 0x55, 0xe8, 0xdc, 0x78, 0xb6, 0x02, 0xe4, 0xd8, 0x6d, 0xff, 0x95, 0xda, 0x60, 0x23, 0xe7, 0xea, 0x31, 0xbb, 0x83, 0xfb, 0xbf, 0x6d, 0xd4, 0xf1, 0x74, 0xbe, 0x76, 0xa4, 0xa7, 0x62, 0x7b, 0x25, 0x97, 0x97, 0x58, 0x8e, 0xeb, 0xfa, 0xea, 0x66, 0x25, 0x02, 0x09, 0xc7, 0x95, 0x24, 0x2c, 0xe2, 0x7e, 0xf9, 0xdb, 0xf5, 0x96, 0x90, 0x42, 0xb3, 0x7c, 0x47, 0x5e, 0x11, 0xc7, 0xdf, 0x5a, 0x5f, 0x76, 0xa9, 0x93, 0xc2, 0x41, 0x9f, 0x85, 0xac, 0x5c, 0xcc, 0xe8, 0x97, 0x38, 0x12, 0x51, 0x81, 0xda, 0x54, 0x1b, 0xab, 0xd9, 0xae, 0xed, 0xec, 0x66, 0xa6, 0xa4, 0xc1, 0x8e, 0x12, 0x7e, 0xdd, 0xff, 0xc0, 0x71, 0x30, 0xea, 0xcb, 0xfc, 0xaa, 0x2f, 0x6c, 0x2b, 0x40, 0xb8, 0xf2, 0xda, 0x3e, 0xeb, 0x67, 0xa8, 0xda, 0x28, 0xfe, 0xd4, 0x60, 0x29, 0xd5, 0xfa, 0xea, 0x60, 0xb6, 0xe2, 0x79, 0x6a, 0xf6, 0x3e, 0x45, 0x69, 0x54, 0x42, 0xb5, 0x81, 0xf0, 0x45, 0xde, 0x36, 0xaf, 0x0c, 0xc8, 0x5f, 0x09, 0x3b, 0x27, 0x5a, 0xba, 0xdb, 0xfa, 0x1d, 0xbc, 0x00, 0xbf, 0xb5, 0x66, 0x06, 0x3e, 0x2c, 0x73, 0x75, 0x85, 0xa1, 0x7d, 0x05, 0xc6, 0xcc, 0xc7, 0x7a, 0xa7, 0x2d, 0xd6, 0x9c, 0xf4, 0xa2, 0x72, 0x1c, 0x5b, 0x7b, 0xcd, 0x26, 0x02, 0xf0, 0xec, 0x46, 0x7a, 0xbe, 0xa4, 0x5f, 0xac, 0xbb, 0x20, 0xf4, 0x89, 0x7c, 0x7b, 0x8e, 0x53, 0x9d, 0x73, 0x8d, 0x32, 0xc4, 0xb9, 0xb1, 0x99, 0xe6, 0x9e, 0xab, 0x2c, 0x9b, 0x61, 0x6f, 0x24, 0x55, 0x94, 0x9f, 0x3a, 0xd7, 0x3c, 0xe4, 0xc6, 0x6e, 0x01, 0x41, 0x8f, 0xf8, 0x2a, 0x44, 0x47, 0x12, 0x8b, 0x65, 0x43, 0xf4, 0x57, 0xfd, 0x7f, 0xd0, 0xa8, 0x89, 0x30, 0xd2, 0x01, 0xd5, 0x0c, 0xa0, 0x0d, 0x6b, 0x40, 0xb0, 0x24, 0xd8, 0x86, 0xdf, 0xed, 0x79, 0x39, 0xf3, 0xca, 0x48, 0xae, 0x42, 0x20, 0x03, 0x17, 0xa8, 0x9c, 0x85, 0x1a, 0x57, 0x39, 0x5c, 0x10, 0x82, 0x2d, 0xb0, 0x90, 0x4a, 0xf0, 0x54, 0x90, 0x7f, 0x19, 0x88, 0x33, 0x1a, 0xe5, 0x51, 0xeb, 0xae, 0x71, 0x24, 0x2d, 0x83, 0x2b, 0xf9, 0x94, 0x45, 0x06, 0x0b, 0xd6, 0x47, 0xaf, 0xd2, 0xc9, 0xea, 0x77, 0xaa, 0xeb, 0x5c, 0x0b, 0x12, 0x77, 0x78, 0xce, 0xe5, 0x46, 0x1f, 0xd6, 0x46, 0x57, 0x3d, 0xba, 0xe5, 0x4e, 0xb8, 0x65, 0xc3, 0xc4, 0x32, 0x80, 0x3c, 0xa0, 0x02, 0x81, 0x1e, 0x8d, 0x2d, 0x10, 0x20, 0x4a, 0x1a, 0x0b, 0x27, 0x13, 0x97, 0x8b, 0x8b, 0x58, 0xce, 0x45, 0x37, 0xc5, 0x85, 0xe2, 0x2d, 0x6c, 0x80, 0xfe, 0xe7, 0xb9, 0x0e, 0x58, 0x0e, 0x43, 0x60, 0x51, 0x7c, 0xa8, 0xbe, 0x73, 0xce, 0xef, 0xd9, 0x77, 0x89, 0x8d, 0xc2, 0xb3, 0x56, 0xe8, 0x73, 0xc5, 0x0e, 0x3d, 0xda, 0x79, 0x97, 0x1d, 0x91, 0x22, 0xa5, 0x21, 0xa6, 0xe3, 0xb7, 0x98, 0x99, 0x6f, 0x6a, 0x31, 0xc5, 0x7b, 0xf5, 0x63, 0x1b, 0x8b, 0x02, 0x2a, 0x47, 0x02, 0xb3, 0x7c, 0x36, 0x5f, 0x2d, 0x3e, 0xfd, 0x35, 0xae, 0xa6, 0xea, 0x5e, 0x1d, 0x60, 0xe3, 0xb9, 0x61, 0x65, 0xfd, 0xcf, 0x45, 0xcd, 0x95, 0x50, 0xc9, 0x91, 0xdf, 0x00, 0x75, 0x98, 0x47, 0xf0, 0xab, 0x90, 0x8c, 0xad, 0xf9, 0x2b, 0xcb, 0x68, 0x07, 0x4c, 0x39, 0x23, 0x57, 0xd8, 0xc5, 0xdb, 0x78, 0xb7, 0x29, 0x73, 0xa7, 0x12, 0xf2, 0xbd, 0xdc, 0xa0, 0x1e, 0xd7, 0xd8, 0x03, 0x25, 0x10, 0x35, 0x04, 0x84, 0xb4, 0x7e, 0xeb, 0xa0, 0xa0, 0x27, 0x53, 0x77, 0x68, 0x1a, 0x2f, 0x15, 0x20, 0x5c, 0x72, 0x06, 0xce, 0x6b, 0xc8, 0x9e, 0x8b, 0xc3, 0x48, 0xed, 0x8d, 0x61, 0x4b, 0x94, 0xd7, 0x72, 0x24, 0x87, 0x6a, 0x96, 0xe6, 0x97, 0xa6, 0x8b, 0xea, 0x68, 0xaa, 0x67, 0x19, 0xdb, 0x09, 0x75, 0x77, 0x28, 0x33, 0x5d, 0xfc, 0x01, 0xc3, 0x60, 0x54, 0x9e, 0x18, 0xf6, 0xa3, 0x5a, 0x78, 0x2b, 0x56, 0x2c, 0xee, 0x00, 0xd2, 0x5c, 0xd9, 0x21, 0x76, 0x93, 0x3e, 0x91, 0x0f, 0x15, 0x2a, 0xae, 0xc9, 0x86, 0x02, 0x5e, 0x37, 0xfe, 0xaa, 0xf5, 0xac, 0xe7, 0xf3, 0xc7, 0x5e, 0xd8, 0xb2, 0x91, 0xef, 0xc0, 0xde, 0xb3, 0x97, 0x8f, 0x5d, 0x2b, 0x26, 0x45, 0x72, 0xe4, 0x86, 0x86, 0x6f, 0x70, 0x94, 0x23, 0x4b, 0x13, 0x9d, 0x54, 0x9a, 0xda, 0xed, 0xe3, 0xef, 0xbc, 0x27, 0x5d, 0xdd, 0x77, 0x2c, 0xe6, 0x08, 0xfa, 0x3f, 0x8b, 0x5f, 0x09, 0xa5, 0x19, 0x22, 0x20, 0xae, 0x51, 0xb1, 0x63, 0xf5, 0xe3, 0xf0, 0x05, 0xcf, 0x20, 0x97, 0x7a, 0xe6, 0x0b, 0xed, 0x5d, 0x4d, 0xc4, 0x59, 0x95, 0x34, 0xe8, 0xa2, 0xef, 0x33, 0x5a, 0x0f, 0x88, 0xea, 0x89, 0x0d, 0xed, 0xe0, 0xdf, 0xbf, 0xdd, 0xc0, 0xba, 0xfc, 0xac, 0xb0, 0xc0, 0xf4, 0xe4, 0x9a, 0x2f, 0xbb, 0x9f, 0xa3, 0xab, 0x47, 0x89, 0x5f, 0x1e, 0x9c, 0x90, 0x4b, 0xb1, 0xb8, 0xb1, 0xc8, 0x5a, 0xd8, 0x78, 0xe0, 0xd9, 0x6c, 0x87, 0x15, 0x30, 0xb8, 0xe2, 0x72, 0x71, 0x0a, 0xde, 0x26, 0x3a, 0xcb, 0x27, 0x39, 0xb0, 0x99, 0x1c, 0xfc, 0xb0, 0x33, 0xe7, 0x24, 0xf3, 0xcc, 0x5b, 0x49, 0x85, 0xea, 0x60, 0x10, 0x7b, 0x16, 0x03, 0xf5, 0x16, 0x3f, 0xe1, 0xcc, 0x19, 0xf5, 0xb6, 0x63, 0xb8, 0x56, 0xc6, 0xad, 0x35, 0xb5, 0x99, 0xdb, 0xee, 0x90, 0x9b, 0x76, 0xd8, 0x59, 0x6c, 0x4e, 0xb9, 0x57, 0x9c, 0x84, 0x7e, 0xdb, 0xa5, 0xa8, 0xc2, 0xbc, 0x11, 0xc8, 0x41, 0xe8, 0x80, 0x94, 0x30, 0xb6, 0xe2, 0x11, 0xaa, 0xe8, 0x2a, 0x89, 0x52, 0xe6, 0x69, 0x5c, 0x53, 0x57, 0x21, 0x16, 0xc3, 0xbf, 0x53, 0xe6, 0xd8, 0x17, 0x78, 0x95, 0x51, 0x80, 0x1c, 0x6e, 0x32, 0x11, 0xe9, 0x0b, 0x74, 0x55, 0x42, 0x54, 0x8c, 0x7a, 0x42, 0xae, 0x45, 0x54, 0x04, 0xd3, 0x95, 0xa1, 0x11, 0x6e, 0xbc, 0x6c, 0xbf, 0x7d, 0x44, 0xe2, 0x1f, 0x1d, 0x22, 0x09, 0x02, 0xaa, 0x26, 0x5c, 0x83, 0xbd, 0x42, 0x53, 0xb8, 0xeb, 0xc8, 0xae, 0xb0, 0x9e, 0x27, 0xbe, 0x0e, 0x9c, 0x3f, 0x96, 0x63, 0x8e, 0x3d, 0x1e, 0xc5, 0x79, 0x02, 0x8d, 0xf5, 0x9b, 0x06, 0x9a, 0xaf, 0xa8, 0x72, 0xaf, 0x0b, 0x97, 0x05, 0xa4, 0x77, 0x6e, 0x48, 0x32, 0xeb, 0x73, 0xd5, 0x8a, 0xae, 0x43, 0x09, 0xeb, 0xcc, 0x40, 0x74, 0xef, 0x8b, 0x1f, 0x34, 0xbe, 0x1e, 0x0c, 0x12, 0x98, 0x89, 0x09, 0x09, 0x95, 0x5a, 0xa9, 0xcc, 0x61, 0x93, 0xf1, 0x39, 0x27, 0x70, 0x5a, 0x87, 0x24, 0x96, 0x16, 0x9c, 0xf0, 0x12, 0x16, 0x6e, 0x60, 0x99, 0x6d, 0xff, 0x48, 0x73, 0x87, 0x1a, 0xc9, 0xdb, 0x2b, 0xfa, 0x6a, 0x88, 0x28, 0xe4, 0x0b, 0x7b, 0x71, 0x91, 0xc3, 0xc2, 0x7e, 0x7d, 0x40, 0x38, 0x95, 0xc5, 0x64, 0x86, 0x93, 0x24, 0x77, 0x65, 0xe9, 0xd5, 0x2c, 0x61, 0x2a, 0xc4, 0x74, 0x39, 0x6c, 0x69, 0xa7, 0xe3, 0x10, 0x24, 0x95, 0x81, 0xaf, 0x49, 0x1d, 0x57, 0x36, 0x52, 0x3d, 0x01, 0x7a, 0x7c, 0x44, 0xf1, 0x19, 0x2f, 0x14, 0xe3, 0x94, 0x26, 0x84, 0x70, 0x71, 0x43, 0xeb, 0x25, 0x77, 0x82, 0x5a, 0xf6, 0xeb, 0xfd, 0xa8, 0x84, 0x03, 0x07, 0x3d, 0xad, 0x71, 0x47, 0x39, 0x81, 0x83, 0x7a, 0xea, 0x39, 0x6e, 0xff, 0x40, 0xbe, 0xa8, 0x84, 0xb5, 0xd8, 0xaa, 0x69, 0xf4, 0x24, 0xe2, 0x6c, 0x31, 0x18, 0xb7, 0xf1, 0x0c, 0x19, 0x31, 0x6c, 0x94, 0x52, 0x11, 0xa3, 0x3a, 0xb1, 0x30, 0x0e, 0x6b, 0x43, 0x26, 0x13, 0xa1, 0xd9, 0xd2, 0x20, 0x37, 0xd8, 0xb7, 0x37, 0xa2, 0xdb, 0x7d, 0x20, 0xd5, 0xc3, 0xe0, 0xe7, 0x7c, 0x0e, 0x74, 0xbd, 0xf8, 0xdf, 0x38, 0xce, 0x7e, 0xd6, 0xbb, 0xfb, 0x06, 0xfa, 0xff, 0x9c, 0xaa, 0x8f, 0x56, 0xd6, 0x03, 0xf5, 0x8b, 0xe8, 0xf0, 0x1b, 0x50, 0xc3, 0xfd, 0x9e, 0x3c, 0x88, 0xfb, 0x3b, 0x46, 0x31, 0x07, 0x71, 0x71, 0xa2, 0x4a, 0xde, 0x6c, 0x17, 0x7e, 0x71, 0x2c, 0x62, 0x13, 0x6b, 0x2b, 0xd7, 0xed, 0xdd, 0xfc, 0xf6, 0x22, 0x21, 0x20, 0x59, 0x78, 0x61, 0x43, 0x2c, 0xe5, 0x1a, 0xff, 0x82, 0x20, 0xb0, 0x15, 0xaa, 0x90, 0xa2, 0xff, 0xdb, 0xc4, 0x61, 0x25, 0xee, 0xe1, 0x57, 0x88, 0xdf, 0x89, 0xce, 0x04, 0xd2, 0xff, 0x49, 0xf3, 0x56, 0x30, 0x7c, 0xa2, 0xfa, 0x74, 0x50, 0x50, 0x3e, 0x08, 0xb0, 0xf9, 0x4f, 0xb7, 0xa1, 0xd2, 0xae, 0xa5, 0x4c, 0xa3, 0x6b, 0xc2, 0xb3, 0xdc, 0xcd, 0x57, 0xb7, 0xda, 0x58, 0x81, 0xd1, 0xd4, 0x4f, 0xcb, 0xc4, 0x4e, 0x6a, 0x5e, 0x26, 0x7d, 0xef, 0x99, 0xa2, 0x55, 0xf2, 0x0b, 0x94, 0x0b, 0x01, 0x61, 0x01, 0x4b, 0xad, 0xf5, 0x85, 0x8b, 0x6f, 0x45, 0xab, 0xde, 0x20, 0x12, 0x0c, 0x3e, 0x67, 0xea, 0x36, 0xb6, 0x0e, 0x30, 0xd6, 0xca, 0x68, 0xcd, 0x31, 0xbf, 0xc6, 0x22, 0xb7, 0x6d, 0xb4, 0x63, 0xe7, 0xe7, 0xe9, 0x0f, 0x25, 0x17, 0xfe, 0xf9, 0x1b, 0xc2, 0x6a, 0xc5, 0xae, 0x57, 0x8c, 0xf8, 0x60, 0x9b, 0xda, 0x4f, 0x96, 0x25, 0x64, 0x62, 0xae, 0xe3, 0x31, 0x92, 0xe1, 0x4a, 0xe0, 0x29, 0x36, 0xe7, 0x7f, 0xc1, 0xb1, 0xe6, 0xd1, 0xbc, 0x16, 0xd2, 0x39, 0x6a, 0x24, 0x96, 0x51, 0x97, 0xcf, 0xd9, 0x80, 0xcd, 0x1b, 0x9a, 0x39, 0x02, 0x5c, 0xfa, 0x03, 0x99, 0xe6, 0x97, 0xc8, 0xf0, 0x78, 0x55, 0x15, 0xcf, 0xab, 0x04, 0x23, 0xda, 0xfe, 0xbb, 0x27, 0xde, 0x7a, 0x84, 0xcb, 0x7b, 0xb2, 0x78, 0xc0, 0x10, 0xa4, 0x66, 0x72, 0xe4, 0xbc, 0xb0, 0xd0, 0xf7, 0x9d, 0xb9, 0x87, 0xa8, 0xcd, 0x7e, 0x6c, 0xd7, 0x41, 0x5f, 0x11, 0x04, 0x14, 0x9b, 0xcd, 0x98, 0xad, 0x93, 0x07, 0x63, 0x8f, 0xf7, 0x5a, 0xa2, 0x04, 0x05, 0xf0, 0xa5, 0xdc, 0x54, 0x01, 0x1a, 0x76, 0x30, 0x59, 0xab, 0x27, 0x5a, 0x98, 0xe2, 0xb6, 0x92, 0x86, 0xe0, 0x02, 0x56, 0xe8, 0x9d, 0x16, 0xd9, 0xb1, 0x3a, 0x6b, 0x49, 0x97, 0x96, 0xe3, 0x53, 0x45, 0x97, 0x6d, 0x94, 0xd5, 0x5b, 0x1d, 0xc0, 0xc7, 0x3d, 0xaf, 0x92, 0xd4, 0x90, 0x6b, 0x5c, 0x76, 0x8a, 0xe6, 0x7c, 0x1e, 0x8a, 0x86, 0x41, 0xfa, 0x13, 0xe0, 0x8c, 0x09, 0x12, 0x66, 0x26, 0x0c, 0x95, 0xab, 0x20, 0x84, 0xd2, 0x0e, 0x9f, 0x37, 0x72, 0x8e, 0x3e, 0x1e, 0x66, 0x34, 0x25, 0xbb, 0xb3, 0x29, 0x9c, 0x70, 0xb4, 0xb9, 0x03, 0xd7, 0x35, 0x80, 0x06, 0xe6, 0xe8, 0xf9, 0x6e, 0xdf, 0x6d, 0x6c, 0xd9, 0x2a, 0x12, 0xa4, 0xf3, 0xef, 0x49, 0xb6, 0x73, 0xe8, 0x46, 0x74, 0xa1, 0x92, 0x8c, 0xcb, 0x26, 0x70, 0xfa, 0xb2, 0x86, 0x2a, 0x8f, 0xd5, 0x99, 0x1f, 0xb8, 0xf7, 0x7d, 0x5c, 0xec, 0x07, 0xed, 0xd2, 0x2e, 0xe0, 0xd2, 0x41, 0xa6, 0x46, 0x25, 0x98, 0x8f, 0xe1, 0x0f, 0xf9, 0x28, 0x98, 0x0e, 0xfa, 0x8f, 0xe6, 0x4d, 0x55, 0xcf, 0x58, 0x7e, 0x36, 0xd0, 0x29, 0x07, 0x4f, 0x50, 0x55, 0x38, 0xf9, 0x80, 0x94, 0x09, 0x3c, 0xa5, 0x5c, 0x3c, 0x9f, 0xb7, 0x6c, 0xbe, 0xbe, 0xb8, 0x53, 0xcd, 0x84, 0x56, 0xec, 0xc9, 0xa7, 0x18, 0x62, 0x7d, 0x7d, 0xa8, 0x7a, 0x6f, 0xe6, 0x2f, 0xc1, 0xaf, 0x33, 0x05, 0xac, 0xb0, 0xae, 0x67, 0xbd, 0xe3, 0xd9, 0xc1, 0x10, 0x84, 0xe2, 0x03, 0x4b, 0x77, 0xfa, 0xe0, 0x70, 0xab, 0xe7, 0xe0, 0x99, 0x93, 0x47, 0x2b, 0x0b, 0x74, 0x11, 0x98, 0xbf, 0xb1, 0x38, 0xba, 0x6a, 0x1a, 0x0a, 0xe7, 0x3f, 0x43, 0x59, 0x14, 0xe4, 0x1a, 0x99, 0x50, 0x52, 0xee, 0x47, 0xee, 0x47, 0x00, 0xf3, 0x7c, 0xe0, 0xc0, 0x64, 0x1a, 0xa0, 0xe6, 0x5c, 0xac, 0x70, 0xb8, 0xa0, 0xfa, 0x13, 0xbe, 0x3f, 0x19, 0xab, 0x7a, 0x3c, 0x66, 0xf8, 0x37, 0xc8, 0xac, 0x42, 0x49, 0xc1, 0xe9, 0xd8, 0x9b, 0x2c, 0xf1, 0x17, 0xa0, 0x8d, 0x3b, 0x6b, 0x70, 0xa7, 0x9e, 0x2b, 0x41, 0x64, 0x38, 0x1e, 0x57, 0xbb, 0xd8, 0xea, 0x8c, 0x82, 0xda, 0x2b, 0x0a, 0xf1, 0xf7, 0x96, 0xe4, 0x12, 0x07, 0x57, 0x1c, 0x67, 0xb1, 0xa8, 0x5e, 0xea, 0xde, 0x1c, 0x84, 0xf8, 0x5f, 0x49, 0x14, 0x81, 0x1a, 0x19, 0xfb, 0x4b, 0xac, 0x53, 0x6d, 0x76, 0x5d, 0xe9, 0x71, 0xcf, 0x29, 0xec, 0xae, 0xa4, 0xf3, 0x91, 0xe7, 0xf1, 0x63, 0x02, 0xf0, 0x7e, 0x22, 0x31, 0xfa, 0x9e, 0x90, 0x39, 0x76, 0xc3, 0x2d, 0x2b, 0x3f, 0x42, 0x8d, 0x5d, 0x98, 0xaa, 0x89, 0xc4, 0x04, 0x35, 0xda, 0xe5, 0x0e, 0x60, 0x0f, 0x29, 0xda, 0xe2, 0x48, 0x8a, 0xae, 0xcd, 0xed, 0x82, 0x5a, 0x9e, 0xa7, 0x2c, 0x51, 0xf5, 0xe6, 0xe8, 0x50, 0xb6, 0x68, 0x25, 0xa2, 0x56, 0xe0, 0x04, 0xc4, 0x3b, 0x54, 0x0d, 0xd5, 0x08, 0x0c, 0xfc, 0xc5, 0x0e, 0xb3, 0xfe, 0x0f, 0x16, 0x65, 0x4f, 0xb9, 0x43, 0x17, 0x67, 0xd6, 0xbb, 0xb3, 0x79, 0xa7, 0xd1, 0x40, 0x90, 0x16, 0x8c, 0x8c, 0xb5, 0xfc, 0x53, 0x08, 0x68, 0xc1, 0x61, 0xab, 0x39, 0x21, 0xfe, 0xd6, 0xbb, 0x2c, 0x3f, 0xd5, 0xac, 0xa9, 0x19, 0x3c, 0x51, 0x1c, 0xbc, 0x0e, 0x7c, 0x34, 0x07, 0xa9, 0xc6, 0x49, 0xb1, 0x27, 0x55, 0x59, 0x00, 0xb4, 0xf9, 0xa2, 0x49, 0xeb, 0x6a, 0x89, 0xcc, 0x97, 0x51, 0x4f, 0x3a, 0x3f, 0xb9, 0xa0, 0x87, 0x7d, 0xf7, 0x25, 0x50, 0x27, 0xd1, 0x4c, 0xc9, 0x0e, 0x05, 0xef, 0x65, 0x0f, 0x00, 0x68, 0x29, 0xa0, 0xb2, 0xe3, 0x20, 0x1a, 0xa6, 0x15, 0x32, 0x0c, 0x82, 0x95, 0xd4, 0xa9, 0x06, 0xdb, 0xb5, 0x3a, 0x65, 0xbb, 0xe1, 0x4a, 0x84, 0x1c, 0xa1, 0x5a, 0x9c, 0xbd, 0xc9, 0xa8, 0xbe, 0x08, 0xe4, 0x13, 0x5e, 0x5f, 0x91, 0xf8, 0x0d, 0x44, 0x81, 0xb0, 0x5e, 0x40, 0x6e, 0x40, 0x0c, 0x3d, 0xfa, 0xa2, 0xac, 0x0a, 0xbf, 0x6f, 0x1c, 0xbb, 0x6f, 0xaf, 0xfc, 0xfa, 0x13, 0x7a, 0x6f, 0x5a, 0xaa, 0x04, 0x2f, 0x31, 0xb2, 0x06, 0x77, 0xae, 0x4d, 0x5b, 0xba, 0x51, 0xd1, 0x2d, 0xdd, 0xb9, 0x15, 0x0d, 0x1a, 0x9e, 0xd5, 0xde, 0xee, 0x39, 0x18, 0x60, 0x11, 0xe7, 0x12, 0x98, 0x5f, 0x2f, 0x9a, 0xd2, 0xf8, 0x36, 0xf6, 0x93, 0xa3, 0x00, 0x06, 0x8f, 0x0d, 0xbc, 0x4d, 0xfe, 0x31, 0xd4, 0x97, 0x06, 0x89, 0xb5, 0x4a, 0xea, 0xe1, 0x51, 0xb9, 0x53, 0x9a, 0x68, 0x43, 0x6f, 0x47, 0x5b, 0xc2, 0x26, 0x2e, 0xf9, 0x94, 0xdc, 0x5c, 0x03, 0xad, 0x2e, 0x57, 0x98, 0x1e, 0x3c, 0x7a, 0xa4, 0xb2, 0x3c, 0x66, 0xe7, 0x12, 0xf2, 0xd6, 0x72, 0x85, 0x5c, 0x43, 0xc0, 0x44, 0xac, 0x4d, 0xe7, 0xbc, 0x5b, 0x83, 0xbe, 0x3d, 0x03, 0x25, 0x23, 0xb3, 0x5f, 0xe3, 0x4a, 0xd7, 0x3e, 0xfe, 0xbf, 0x95, 0xf9, 0x96, 0x6b, 0x70, 0xb2, 0xa4, 0x1c, 0xda, 0x5f, 0xe8, 0xa1, 0x2b, 0x00, 0x76, 0x87, 0x0f, 0xf8, 0x98, 0xb3, 0x1e, 0x2a, 0xee, 0xf7, 0x1b, 0x61, 0x17, 0x23, 0xae, 0x54, 0x15, 0xf0, 0x1c, 0xe3, 0xb9, 0x48, 0x43, 0xb6, 0xb3, 0x24, 0x9a, 0xed, 0xb9, 0xd3, 0xdd, 0x86, 0xf7, 0xb2, 0xf8, 0xf2, 0xf3, 0x68, 0xdb, 0x27, 0x33, 0xd8, 0x24, 0xf8, 0xc2, 0xf3, 0x29, 0x2b, 0x8c, 0xa6, 0xa8, 0xba, 0x06, 0x80, 0x7f, 0xc8, 0xf5, 0xf2, 0x4f, 0x38, 0xf7, 0x6d, 0x44, 0x70, 0x24, 0x67, 0x67, 0xad, 0x2b, 0x1b, 0x7b, 0x60, 0xc7, 0xfb, 0xad, 0x67, 0xea, 0xa2, 0xcb, 0xb1, 0xd1, 0xf5, 0x2b, 0xb9, 0xb6, 0x1f, 0xd1, 0x73, 0x6c, 0xfb, 0x1e, 0xc0, 0x8b, 0xe2, 0xd9, 0xeb, 0xb0, 0x9b, 0x4d, 0x4a, 0x1a, 0xe0, 0x70, 0x97, 0x7d, 0x17, 0xd1, 0x34, 0x05, 0x9d, 0x95, 0x73, 0xc4, 0x4e, 0x31, 0x80, 0xc3, 0xae, 0xdf, 0x08, 0xd5, 0xda, 0xdf, 0x4e, 0xbc, 0xb4, 0x91, 0x23, 0x61, 0x16, 0xa7, 0x74, 0x4e, 0xbb, 0x31, 0x01, 0x0f, 0x92, 0xe9, 0x29, 0x9d, 0xc7, 0x9c, 0xd9, 0x82, 0x8c, 0x43, 0xe6, 0x2d, 0xfb, 0xc9, 0x5f, 0x2f, 0x7d, 0x01, 0x3e, 0x38, 0xb1, 0x89, 0x95, 0x01, 0x02, 0xb3, 0xfb, 0xd1, 0x99, 0xc8, 0x1a, 0x38, 0x9d, 0x89, 0x68, 0x8a, 0x88, 0x75, 0x58, 0x02, 0x61, 0xc5, 0x0a, 0x59, 0x52, 0x1f, 0x4d, 0xd1, 0xc2, 0x4e, 0x1e, 0x9a, 0x38, 0x45, 0x98, 0xf5, 0x76, 0x07, 0x49, 0x06, 0x9a, 0x9b, 0xfb, 0x1a, 0x87, 0xf0, 0xde, 0x27, 0x57, 0x95, 0x7a, 0xb4, 0xe1, 0xaa, 0xad, 0xda, 0xa9, 0xc8, 0x85, 0x80, 0x07, 0x31, 0xe5, 0x2f, 0xc9, 0xb6, 0xb5, 0x5f, 0x5d, 0xef, 0x27, 0x24, 0x6e, 0xce, 0xcc, 0xef, 0xa1, 0x52, 0x3e, 0x9f, 0x4f, 0x2d, 0xc7, 0x33, 0x65, 0x70, 0xfa, 0x49, 0x74, 0xbe, 0x37, 0x8e, 0x3d, 0x40, 0x59, 0x6c, 0x6b, 0xd3, 0x30, 0xf1, 0x1b, 0x59, 0x55, 0x86, 0x8d, 0x2e, 0x2b, 0x65, 0x02, 0x94, 0x45, 0xe3, 0x73, 0x8f, 0x32, 0x78, 0x18, 0x1b, 0x57, 0x60, 0x46, 0x1f, 0xe5, 0x57, 0x6c, 0x14, 0x11, 0xe0, 0x73, 0x91, 0xa7, 0xc8, 0xec, 0x5a, 0x51, 0x6a, 0xaf, 0x43, 0x76, 0x2f, 0x2f, 0x35, 0x91, 0xb9, 0x47, 0x5e, 0x5b, 0xdb, 0x4e, 0x7a, 0xc5, 0x8a, 0xd7, 0x8b, 0x8f, 0x35, 0x4e, 0xa0, 0x00, 0xd9, 0x31, 0x84, 0xf7, 0xa5, 0xfa, 0x34, 0x9b, 0xf9, 0x6f, 0xab, 0xa1, 0x21, 0x59, 0x37, 0xa2, 0xd0, 0x1f, 0x2c, 0x37, 0xcf, 0x77, 0x0a, 0x44, 0xcb, 0x0d, 0x82, 0xca, 0x61, 0xd3, 0xf5, 0xcf, 0xf4, 0x63, 0x03, 0xfc, 0x82, 0xfa, 0xf7, 0x21, 0xb1, 0x4e, 0x48, 0x01, 0xba, 0x4a, 0x15, 0x31, 0xb3, 0xe9, 0xf6, 0xa3, 0xe0, 0x4d, 0xe0, 0x14, 0x95, 0x8d, 0x0d, 0x60, 0xfc, 0x93, 0x6a, 0xd0, 0x85, 0xdb, 0xfc, 0xd3, 0xef, 0x8f, 0xc7, 0xe0, 0xc1, 0x09, 0xec, 0xbc, 0x3f, 0x21, 0x10, 0x32, 0x25, 0x02, 0xe5, 0x10, 0x9f, 0xc5, 0x0a, 0xbb, 0x53, 0xec, 0x84, 0x07, 0xc9, 0x86, 0x76, 0xd7, 0x3f, 0xad, 0x29, 0x59, 0x25, 0x9c, 0x2a, 0x13, 0xb8, 0xf0, 0xf0, 0xfe, 0xd1, 0xb6, 0x7a, 0xc2, 0xe9, 0x05, 0x4b, 0x56, 0x0b, 0x3a, 0x76, 0xb1, 0xfd, 0xff, 0x98, 0xa7, 0xce, 0x4a, 0x48, 0xc1, 0x23, 0xef, 0x70, 0x53, 0x4c, 0x5b, 0xf4, 0xca, 0x69, 0x11, 0x5a, 0x83, 0x6c, 0x55, 0x5b, 0xa0, 0x93, 0x99, 0xf0, 0x80, 0x89, 0x69, 0xdc, 0xc2, 0xd1, 0xe4, 0x9b, 0xa4, 0xf1, 0x35, 0xcf, 0x4d, 0xfc, 0xdf, 0x7d, 0xcf, 0xf4, 0xc4, 0xf2, 0xf0, 0xe2, 0x45, 0x97, 0x1a, 0x0d, 0x1e, 0x48, 0x94, 0x79, 0x71, 0x4e, 0xd2, 0x2b, 0x52, 0x3d, 0xf0, 0x99, 0x45, 0x2f, 0xcc, 0x04, 0x8b, 0x2f, 0xfe, 0xee, 0x04, 0x44, 0x68, 0xc8, 0xd6, 0x55, 0xca, 0xb0, 0xcc, 0xd9, 0xa0, 0xd6, 0x88, 0x55, 0xae, 0x6b, 0x37, 0x10, 0x37, 0xef, 0xdc, 0xeb, 0xb6, 0x1d, 0xbe, 0x06, 0x86, 0x22, 0x72, 0xc8, 0x5e, 0x82, 0x60, 0x6c, 0x52, 0x60, 0xe6, 0x8c, 0xf6, 0x05, 0xe8, 0x70, 0xa7, 0x9c, 0x6d, 0xdd, 0x1d, 0x4c, 0xc0, 0xe7, 0x52, 0xad, 0xe6, 0x01, 0x80, 0x86, 0xb9, 0xc6, 0x2e, 0xfa, 0x67, 0xf9, 0x56, 0xfe, 0x2f, 0x85, 0x0f, 0x88, 0xdb, 0xd8, 0x78, 0x3d, 0xeb, 0x43, 0x0f, 0xb2, 0x94, 0x76, 0x9e, 0x97, 0x17, 0x25, 0x2a, 0x37, 0xba, 0x4a, 0x8f, 0x11, 0x1d, 0x8e, 0x3f, 0x49, 0x74, 0xc7, 0xa4, 0x07, 0xa2, 0xdc, 0x39, 0xe9, 0x87, 0x6e, 0x88, 0xf2, 0x8e, 0x85, 0xc9, 0x15, 0xa8, 0x44, 0x75, 0x3b, 0xa6, 0xab, 0xa8, 0x1b, 0xb7, 0xaf, 0xd3, 0x41, 0x9f, 0x61, 0x2b, 0xe5, 0x8c, 0xc9, 0x59, 0x13, 0xf2, 0xca, 0xf0, 0x38, 0x80, 0x53, 0x05, 0x0a, 0xde, 0xeb, 0x49, 0x1d, 0xda, 0xaf, 0xc4, 0x9b, 0x40, 0x0a, 0x82, 0x08, 0xc6, 0x1d, 0x91, 0x79, 0xb2, 0x18, 0xfe, 0xea, 0xf9, 0x29, 0xf9, 0x78, 0x3a, 0xe8, 0x8c, 0xca, 0x96, 0x1b, 0x10, 0x58, 0x1d, 0xfb, 0xdb, 0xe5, 0x0b, 0x1f, 0xf0, 0x34, 0xfe, 0x76, 0xf8, 0xce, 0x05, 0xa3, 0xe2, 0x9e, 0x77, 0x42, 0x0f, 0xdb, 0x38, 0x9d, 0xe7, 0x19, 0xd6, 0x11, 0xc1, 0x96, 0x56, 0xe1, 0xbc, 0xa5, 0x63, 0xd2, 0x1f, 0xc7, 0x71, 0xc5, 0x44, 0xa9, 0x06, 0x03, 0x76, 0x98, 0xd5, 0x6c, 0xd0, 0xdd, 0x45, 0x13, 0x9f, 0xbc, 0x0c, 0x11, 0x3d, 0xee, 0xec, 0x48, 0x16, 0x63, 0xf6, 0x05, 0x0c, 0x5f, 0x55, 0xbc, 0xfc, 0x1f, 0x0a, 0xfe, 0xcd, 0x28, 0x7e, 0x4c, 0xe7, 0x88, 0x6b, 0x9f, 0x0c, 0xe1, 0x6c, 0x2d, 0x07, 0x00, 0x46, 0x47, 0x37, 0x2b, 0x80, 0xd5, 0xe7, 0xa5, 0x3b, 0xdb, 0x73, 0x7c, 0x91, 0xa0, 0x6f, 0x15, 0xfc, 0x38, 0x6e, 0x8f, 0xc7, 0x82, 0xfe, 0x79, 0x4a, 0x25, 0xa1, 0xf6, 0xa8, 0x1d, 0x8f, 0xa1, 0x42, 0x90, 0x0a, 0x48, 0xa9, 0x21, 0xb3, 0x49, 0x24, 0x6b, 0xcb, 0x96, 0x81, 0x70, 0x87, 0x1f, 0x38, 0x58, 0x46, 0x3f, 0x7b, 0x3b, 0xcb, 0x36, 0x99, 0xa6, 0x45, 0xcd, 0x6c, 0xc1, 0x8f, 0x6a, 0xf0, 0xed, 0xfe, 0x4a, 0x2c, 0xbd, 0x3d, 0x27, 0x61, 0x62, 0x07, 0xbe, 0x50, 0x18, 0x21, 0x1c, 0xd0, 0x06, 0x2b, 0x56, 0xd1, 0x21, 0xd2, 0x03, 0xab, 0xc2, 0xbe, 0xb1, 0xe2, 0x45, 0x11, 0x50, 0x57, 0xb6, 0x2a, 0xe0, 0x7d, 0x9d, 0x49, 0xc2, 0xc6, 0x07, 0xba, 0xf5, 0x91, 0x2b, 0xc2, 0x99, 0x83, 0x73, 0xdc, 0xa0, 0x0a, 0x9a, 0x0f, 0xde, 0xeb, 0x6f, 0xd1, 0x72, 0x1e, 0xeb, 0x19, 0x79, 0xaa, 0x96, 0xe2, 0xc3, 0xec, 0xa9, 0x55, 0x17, 0xfb, 0x9e, 0x51, 0x48, 0xf7, 0x2e, 0xf7, 0xfc, 0x58, 0xe4, 0xcb, 0xbe, 0x4f, 0x42, 0x15, 0x90, 0x3c, 0x91, 0x15, 0x68, 0x45, 0xc2, 0x9e, 0x0d, 0x0e, 0x91, 0x41, 0x7e, 0x7f, 0x69, 0x9b, 0x8b, 0xfd, 0x93, 0xfd, 0x89, 0xce, 0xf3, 0xca, 0x06, 0x14, 0xf0, 0x2a, 0x1a, 0xfc, 0x84, 0x07, 0xb9, 0x27, 0x07, 0xfa, 0xa1, 0x04, 0x8a, 0xe2, 0x81, 0x1a, 0x1f, 0x94, 0x18, 0x3b, 0x12, 0xed, 0x8d, 0x87, 0x2a, 0x2d, 0xe7, 0xb7, 0x1d, 0x83, 0x36, 0x2d, 0x14, 0x33, 0xe3, 0x89, 0x34, 0x15, 0x87, 0xc6, 0xe4, 0x71, 0x3c, 0x45, 0xd0, 0xf7, 0x8d, 0xb5, 0xd0, 0xf0, 0x29, 0x3e, 0x15, 0x80, 0x4b, 0xd7, 0x26, 0x18, 0x95, 0x21, 0xad, 0xbf, 0x9e, 0x28, 0xc4, 0xdd, 0x15, 0xf7, 0xf8, 0x7d, 0x92, 0xa5, 0xe8, 0xbb, 0xad, 0x5d, 0xc7, 0xff, 0x92, 0xfe, 0xe1, 0x76, 0x52, 0xb4, 0xab, 0x4a, 0x14, 0x4e, 0xa2, 0xd4, 0xd0, 0xa3, 0x60, 0xb5, 0x3f, 0xeb, 0x74, 0xd1, 0x89, 0xc7, 0x78, 0x2b, 0x49, 0x12, 0x75, 0xdf, 0xc6, 0x41, 0x05, 0xd0, 0x84, 0x99, 0xbd, 0xe2, 0xbb, 0x16, 0xfa, 0x90, 0x96, 0xce, 0x88, 0xa7, 0x0e, 0xff, 0x93, 0xb1, 0xb1, 0x81, 0x96, 0xfa, 0x17, 0xf5, 0xe0, 0x58, 0x1a, 0x7d, 0xb3, 0xeb, 0x40, 0x9b, 0xf7, 0xb2, 0x2d, 0x9d, 0x88, 0xe9, 0x6e, 0x85, 0xc4, 0x18, 0xc3, 0xd5, 0xc7, 0xe4, 0xdb, 0x63, 0x2d, 0x96, 0xc8, 0x91, 0x48, 0x53, 0xdd, 0xd1, 0x71, 0xd8, 0x90, 0x3b, 0x53, 0x24, 0x96, 0x11, 0xa1, 0x18, 0x7d, 0x06, 0x2a, 0x72, 0x1f, 0x8e, 0x53, 0xfe, 0xf5, 0xf3, 0x80, 0x36, 0xd3, 0xfd, 0xe7, 0x44, 0x1b, 0x92, 0x81, 0x53, 0x69, 0xc9, 0x19, 0x1d, 0x25, 0x0b, 0x75, 0xf9, 0x1f, 0x6d, 0x1e, 0x57, 0x26, 0x20, 0xe0, 0x35, 0xd4, 0x1d, 0xd7, 0x4c, 0xf4, 0x6c, 0x76, 0xcd, 0xf5, 0x7e, 0x3b, 0x30, 0x5d, 0x26, 0x57, 0x53, 0x60, 0xcb, 0x7f, 0x2d, 0xa8, 0xa9, 0x71, 0x2f, 0xbe, 0xed, 0xec, 0x06, 0xb6, 0xaf, 0x75, 0x8f, 0x99, 0x8e, 0x21, 0x62, 0x22, 0x59, 0x40, 0xa9, 0xdf, 0xfa, 0xd5, 0x4a, 0x81, 0x37, 0x37, 0xea, 0x37, 0x4c, 0xc6, 0x1a, 0xdc, 0x04, 0x09, 0xed, 0x14, 0x3d, 0xc7, 0x5e, 0x5e, 0xb7, 0x50, 0x2d, 0xd4, 0x8d, 0x44, 0x9b, 0x44, 0x47, 0x7e, 0xc8, 0xc4, 0xcc, 0x9c, 0x65, 0xb2, 0x09, 0xe7, 0x7a, 0x42, 0xdc, 0x74, 0xd2, 0xed, 0xa8, 0x7b, 0x87, 0x8f, 0x93, 0x78, 0x47, 0x12, 0x79, 0x8d, 0x3a, 0xe0, 0x83, 0x05, 0x75, 0x50, 0xea, 0xdb, 0x7d, 0x23, 0xc3, 0xc0, 0x83, 0x40, 0x87, 0x79, 0x20, 0xdb, 0x5b, 0x9d, 0xa4, 0xad, 0x1c, 0x45, 0xa1, 0x19, 0x27, 0x2e, 0x7e, 0x13, 0xb3, 0xef, 0xf2, 0xb7, 0x77, 0x39, 0x26, 0x65, 0xc9, 0x08, 0x4e, 0xef, 0x6c, 0x50, 0xd9, 0xeb, 0x6f, 0xd5, 0xe1, 0xc7, 0xe0, 0xe4, 0x4d, 0xe2, 0x5a, 0xbd, 0x27, 0xa6, 0x11, 0xcf, 0x73, 0x2e, 0xba, 0x4f, 0x0f, 0x51, 0x63, 0x1a, 0x8c, 0xc2, 0x29, 0x8f, 0x1d, 0x66, 0xb0, 0xaf, 0xf2, 0xf6, 0x23, 0x05, 0xf2, 0xe5, 0xd3, 0x6b, 0x26, 0x23, 0xbb, 0xf4, 0x68, 0x78, 0x84, 0x8d, 0x3f, 0x64, 0x21, 0x03, 0xac, 0x6c, 0xf3, 0xab, 0x35, 0x47, 0x4c, 0x53, 0xb8, 0xd8, 0x09, 0xb0, 0x3e, 0x60, 0xf4, 0xff, 0xa5, 0x62, 0x8e, 0x32, 0x34, 0x08, 0xce, 0xe3, 0xbb, 0x1e, 0xfb, 0x9c, 0xb5, 0x14, 0xe5, 0xe0, 0x7d, 0x91, 0x2d, 0xf9, 0x9f, 0x09, 0xa2, 0xb0, 0x00, 0x51, 0x41, 0x45, 0x3f, 0x94, 0xaa, 0x98, 0x11, 0xb6, 0x19, 0xea, 0xd0, 0x3a, 0x41, 0x8e, 0x63, 0x08, 0x7c, 0x8f, 0x2e, 0xce, 0xab, 0xef, 0x0b, 0xaa, 0xdd, 0xeb, 0xa2, 0xa6, 0xe1, 0x55, 0x9a, 0xa4, 0x98, 0xfa, 0xdb, 0xc2, 0xb9, 0x58, 0xb3, 0x90, 0xd9, 0x19, 0x54, 0x64, 0xa6, 0xde, 0x95, 0x96, 0xa7, 0xa4, 0x1d, 0x33, 0xb2, 0x29, 0x3e, 0xea, 0x95, 0x9a, 0x24, 0x63, 0x06, 0xea, 0x9f, 0x88, 0x0c, 0xfa, 0x8b, 0x0f, 0x6d, 0x41, 0x6b, 0xf7, 0x4e, 0x43, 0x49, 0xac, 0xdc, 0x57, 0xbe, 0x52, 0x10, 0x99, 0xd8, 0x83, 0xe9, 0x6d, 0x6e, 0x43, 0x4b, 0x86, 0xc5, 0xdc, 0xa4, 0x21, 0x82, 0x85, 0xdf, 0x62, 0xe3, 0x00, 0x06, 0x97, 0x00, 0xb2, 0x56, 0x77, 0x67, 0x0d, 0x57, 0x6d, 0x2f, 0x6a, 0xc7, 0xe2, 0xdd, 0x75, 0x14, 0xc9, 0x04, 0x31, 0x95, 0xa6, 0xe0, 0xf7, 0x24, 0x3a, 0xed, 0x26, 0xf6, 0x7c, 0x50, 0x3b, 0xb4, 0xc3, 0x0c, 0x95, 0x9d, 0xea, 0x46, 0x7d, 0xb3, 0xca, 0x3c, 0x16, 0x73, 0x67, 0x1c, 0xfc, 0x87, 0xf9, 0x6a, 0x30, 0xf9, 0x7c, 0x6e, 0xed, 0xfb, 0x45, 0xc7, 0x58, 0x58, 0x28, 0x89, 0xa8, 0x8d, 0x98, 0x58, 0x3c, 0x1d, 0x82, 0x59, 0x3e, 0xf9, 0x94, 0x9e, 0x87, 0x2d, 0x2d, 0xc9, 0x80, 0xa9, 0xde, 0xe0, 0x06, 0x36, 0x2c, 0x1e, 0x1b, 0xba, 0xc5, 0x20, 0x9d, 0x74, 0x65, 0x41, 0x94, 0x76, 0x6e, 0xe3, 0x0b, 0x88, 0xb5, 0x0f, 0xcc, 0x73, 0x89, 0x74, 0x9c, 0x43, 0x6a, 0x0b, 0x44, 0xe1, 0x16, 0xd7, 0xc0, 0xd4, 0xbe, 0xab, 0x59, 0xbf, 0xe8, 0x9f, 0x91, 0xa6, 0x30, 0x44, 0x42, 0xf1, 0xf2, 0x6a, 0xe9, 0x52, 0x6f, 0xb0, 0x22, 0x05, 0xd6, 0x6f, 0xff, 0x6f, 0x84, 0xf5, 0xa3, 0x6e, 0x4a, 0x75, 0x65, 0xfd, 0xb3, 0x66, 0xcf, 0xb2, 0x50, 0xc8, 0x3d, 0x58, 0xa5, 0xcd, 0x64, 0x44, 0x5a, 0x5a, 0x29, 0xc4, 0x1e, 0x7b, 0x79, 0x94, 0x03, 0x72, 0x5c, 0x6b, 0x44, 0x32, 0x3a, 0x3f, 0x56, 0xac, 0xbb, 0xae, 0x93, 0xd6, 0xd9, 0x36, 0x52, 0x01, 0x4a, 0xb9, 0x69, 0x84, 0x12, 0x5a, 0x7b, 0xcc, 0x0f, 0xf3, 0x91, 0x69, 0x43, 0x3d, 0x61, 0x05, 0x6f, 0x17, 0x65, 0xcf, 0xce, 0xc6, 0xc9, 0xab, 0xc4, 0xdb, 0xec, 0x4c, 0x91, 0xf4, 0xea, 0x29, 0xf4, 0x71, 0x3a, 0xd6, 0xef, 0x75, 0x7e, 0xca, 0x79, 0x1c, 0x06, 0x97, 0x99, 0x74, 0xf3, 0xec, 0x89, 0x23, 0x2a, 0x54, 0xdc, 0x20, 0xd4, 0x13, 0x00, 0x38, 0x1b, 0x1a, 0xd4, 0x62, 0x23, 0x0f, 0x0c, 0x5f, 0x57, 0x06, 0x28, 0xf1, 0x5a, 0xe9, 0x07, 0xd5, 0x0c, 0x75, 0x29, 0x94, 0x4d, 0x48, 0x4b, 0x95, 0x9b, 0xa9, 0x33, 0x89, 0x12, 0x6b, 0xe4, 0x0a, 0x89, 0x28, 0x3e, 0x96, 0xbf, 0xb8, 0x81, 0x75, 0xbd, 0xe9, 0xdd, 0x74, 0xab, 0x94, 0x12, 0x65, 0x0d, 0x7c, 0x65, 0x1b, 0x63, 0x6c, 0x1d, 0xc9, 0x08, 0x42, 0xdf, 0x49, 0x69, 0x96, 0x0d, 0x61, 0x71, 0x24, 0x83, 0xca, 0x1e, 0xbd, 0x51, 0xb0, 0x19, 0x83, 0xd9, 0xcd, 0x20, 0xaa, 0x2f, 0xec, 0x9e, 0x53, 0x43, 0xfc, 0xea, 0x99, 0x84, 0x33, 0x02, 0x67, 0xef, 0x12, 0x5d, 0xcc, 0x3f, 0xf1, 0x86, 0xab, 0x7d, 0x24, 0xdd, 0xfc, 0xd8, 0x81, 0xf7, 0x27, 0xea, 0xef, 0xf7, 0x5d, 0x3e, 0x08, 0xb7, 0x1a, 0xb9, 0xf8, 0xce, 0x97, 0xa8, 0xb8, 0x88, 0x9a, 0xa1, 0x32, 0xa7, 0x27, 0x59, 0xcd, 0xc4, 0x64, 0xdc, 0xb4, 0xcc, 0x45, 0x5d, 0xa4, 0xd1, 0x33, 0x5a, 0x05, 0x4c, 0xc9, 0x62, 0x48, 0x8d, 0x8c, 0x9d, 0x78, 0x96, 0x6c, 0xaf, 0x4b, 0xf6, 0xe0, 0x7e, 0x55, 0x4b, 0xdf, 0x75, 0x70, 0x91, 0xb7, 0xb1, 0x4f, 0x8b, 0xaa, 0x86, 0x7f, 0x6c, 0x1d, 0xeb, 0xa0, 0x05, 0xcd, 0xf4, 0xe7, 0x22, 0x3a, 0xdb, 0xd4, 0xdd, 0x4a, 0xa3, 0x2f, 0xe7, 0x09, 0xff, 0xa5, 0xf3, 0x40, 0x77, 0x27, 0x6e, 0xbf, 0x79, 0x50, 0xed, 0x5f, 0x33, 0xd2, 0xc8, 0x78, 0xdf, 0x59, 0xa9, 0xab, 0xe3, 0x2c, 0xc0, 0xd5, 0x6e, 0x3c, 0x31, 0xa7, 0x63, 0x40, 0xcf, 0x93, 0x99, 0xd3, 0x8d, 0xa4, 0x05, 0x13, 0x9e, 0xbc, 0x33, 0xbd, 0x7d, 0xda, 0x5b, 0x26, 0xe8, 0x13, 0x23, 0x3c, 0x25, 0x44, 0xf1, 0x4a, 0x6c, 0x55, 0xaa, 0x2a, 0x40, 0x8b, 0x7b, 0x87, 0x66, 0x8a, 0xad, 0x6d, 0x3d, 0x37, 0x67, 0xb9, 0x69, 0x2a, 0xe7, 0x79, 0x72, 0x7a, 0xfa, 0x22, 0xc8, 0x96, 0x12, 0x57, 0xfa, 0xa0, 0x63, 0x3e, 0x6f, 0x1c, 0x3c, 0x29, 0x1e, 0xe4, 0xbb, 0xcb, 0x78, 0xc5, 0xee, 0x0b, 0x27, 0xce, 0xb0, 0xb2, 0xf7, 0x19, 0x83, 0xdb, 0x20, 0x6a, 0xc8, 0x0c, 0x46, 0x7c, 0x5d, 0x41, 0x06, 0xc3, 0xc1, 0xe9, 0x8f, 0x3e, 0x4e, 0x2e, 0xa2, 0x9b, 0xe1, 0xa1, 0xea, 0xfd, 0x75, 0x3f, 0xa2, 0xba, 0x43, 0xb7, 0x57, 0x94, 0xb1, 0xcd, 0xf8, 0x96, 0x16, 0xf2, 0xe5, 0x65, 0x12, 0xea, 0x54, 0xab, 0x93, 0x5c, 0x54, 0x52, 0x08, 0x5b, 0xd3, 0x47, 0x45, 0xb1, 0x11, 0xbc, 0xec, 0xf7, 0x47, 0x9a, 0x91, 0x3b, 0x7a, 0x0b, 0x72, 0x86, 0x5a, 0xc8, 0x1d, 0xef, 0xb4, 0xff, 0xd8, 0x48, 0x1d, 0x9f, 0x97, 0xcc, 0x84, 0x7f, 0x93, 0x4f, 0xca, 0xbc, 0x9d, 0xc0, 0x49, 0x31, 0x72, 0x37, 0x5e, 0x07, 0xbb, 0x00, 0x14, 0xaa, 0xef, 0xc6, 0x5f, 0x2f, 0x50, 0x8f, 0x68, 0xdb, 0x5e, 0xf4, 0x4b, 0x18, 0xe3, 0x53, 0x4b, 0x33, 0xfe, 0xa4, 0xf7, 0x0e, 0xe7, 0x45, 0x87, 0xc7, 0x7b, 0x3e, 0x1e, 0xf5, 0x50, 0x07, 0x7c, 0x8c, 0xd4, 0x8e, 0xfb, 0xc8, 0x4c, 0x26, 0x33, 0x8a, 0xe4, 0xea, 0xb9, 0xec, 0x5d, 0x14, 0xd4, 0xa7, 0xcd, 0xba, 0x41, 0x84, 0x9d, 0x14, 0x47, 0x77, 0xab, 0x97, 0xc0, 0x27, 0xb4, 0x73, 0xd1, 0xd4, 0xde, 0x79, 0xee, 0x74, 0xa7, 0xee, 0x92, 0xa6, 0xaf, 0x39, 0xc7, 0xd7, 0x86, 0xca, 0xcc, 0x27, 0x40, 0x64, 0x27, 0x46, 0x74, 0xbc, 0xf3, 0xc2, 0x25, 0x43, 0x0d, 0x73, 0x4c, 0x9a, 0x1d, 0xc4, 0x1a, 0x4e, 0x0a, 0xb6, 0xb9, 0x17, 0x9e, 0xc9, 0x7e, 0x4c, 0x18, 0x13, 0x3b, 0xf0, 0xb1, 0xe1, 0x3b, 0x3d, 0x42, 0x03, 0xf3, 0x83, 0x47, 0x6b, 0x95, 0xc9, 0x03, 0x5e, 0xaa, 0xb6, 0xbb, 0x33, 0x40, 0x5a, 0x7c, 0x45, 0xad, 0x09, 0x59, 0xf5, 0xfe, 0x6d, 0x2a, 0x04, 0xb2, 0x54, 0x78, 0x8f, 0x29, 0x1d, 0x15, 0xc1, 0x1a, 0x06, 0x96, 0xb5, 0xb9, 0x21, 0x11, 0xc3, 0xe9, 0xc7, 0x7b, 0xc5, 0xc1, 0x1e, 0x18, 0x3d, 0x85, 0x9c, 0x28, 0xc2, 0xc2, 0x2e, 0x2d, 0xdd, 0x54, 0x17, 0x56, 0x78, 0x86, 0x81, 0x6e, 0x83, 0x9c, 0x4f, 0x32, 0x76, 0x2f, 0xf4, 0x5f, 0xea, 0xf0, 0x7e, 0xdf, 0xea, 0x8b, 0x34, 0xcb, 0x4f, 0x09, 0xdf, 0x29, 0x4b, 0xd5, 0x00, 0x54, 0x43, 0x4c, 0x40, 0x9e, 0x23, 0x2e, 0xcf, 0xad, 0x83, 0x85, 0xa0, 0x42, 0xef, 0xcc, 0x55, 0xac, 0xd5, 0x46, 0xb7, 0xc4, 0x50, 0x09, 0xef, 0x01, 0x72, 0xbc, 0x48, 0x51, 0x8e, 0xda, 0xec, 0xad, 0xae, 0x80, 0xac, 0xf6, 0xdc, 0x77, 0x45, 0xa2, 0x40, 0xc2, 0x0e, 0x8a, 0x66, 0x08, 0x1b, 0x9a, 0xd7, 0x63, 0xee, 0x3d, 0x1b, 0xe6, 0xdf, 0xfa, 0xcc, 0x77, 0x35, 0xdc, 0xd3, 0x29, 0x9c, 0x24, 0x03, 0xb6, 0x42, 0xa2, 0x93, 0xd5, 0xfc, 0xbc, 0x13, 0x73, 0x3d, 0x6b, 0x8b, 0xe8, 0xb1, 0x07, 0xb3, 0x65, 0xa0, 0x61, 0x1a, 0x17, 0x4d, 0x06, 0x1a, 0x90, 0x79, 0x29, 0x9f, 0xdb, 0xc0, 0xb4, 0x9b, 0xe7, 0x83, 0x03, 0xc2, 0xb2, 0xc9, 0x54, 0x4f, 0xaf, 0x79, 0x10, 0x83, 0xbf, 0x42, 0x2a, 0x9a, 0x77, 0x97, 0x3b, 0x5b, 0x96, 0xb2, 0xf5, 0x74, 0x75, 0x14, 0xa2, 0xf3, 0x93, 0xec, 0xba, 0x49, 0x7f, 0x6d, 0x76, 0xc8, 0x13, 0x7d, 0x97, 0x68, 0x74, 0x4b, 0x42, 0xed, 0x83, 0xd2, 0x64, 0x96, 0xf1, 0x8b, 0xd3, 0x54, 0xbd, 0x1f, 0x89, 0x6e, 0xa8, 0x97, 0x8a, 0x1b, 0x5c, 0xed, 0x1e, 0x8b, 0x99, 0x8e, 0xe0, 0xcc, 0x02, 0x51, 0x2b, 0x7f, 0xa7, 0xe0, 0x7a, 0x41, 0xa6, 0xb1, 0xd9, 0x50, 0x47, 0x47, 0x0f, 0xcc, 0x1b, 0x22, 0x61, 0x22, 0x11, 0x0b, 0xe1, 0x6b, 0xb0, 0x0d, 0x2b, 0x12, 0xf6, 0x26, 0x92, 0x00, 0x9c, 0x2f, 0x48, 0xba, 0x07, 0x78, 0xec, 0x1d, 0x51, 0xa9, 0xe9, 0x14, 0xb8, 0x6a, 0xcd, 0x7c, 0xf5, 0x52, 0xee, 0xff, 0x47, 0x61, 0x40, 0x99, 0x12, 0x31, 0xf8, 0xe4, 0xfd, 0x47, 0x99, 0xba, 0xe6, 0x4b, 0xd2, 0x86, 0x8e, 0xcb, 0x51, 0x91, 0x15, 0xe5, 0x93, 0x09, 0x8e, 0xb2, 0xff, 0xce, 0xea, 0xbd, 0x19, 0x21, 0x09, 0xb5, 0xf6, 0xc6, 0x49, 0x90, 0x50, 0x2f, 0x39, 0x14, 0xa1, 0x13, 0xb3, 0x96, 0x1d, 0x2d, 0xd0, 0xb6, 0x48, 0x19, 0xc6, 0xd1, 0x23, 0x93, 0xca, 0xa8, 0xb5, 0x26, 0x3b, 0x34, 0x3f, 0x61, 0x6c, 0x03, 0x52, 0xf8, 0x8c, 0xd7, 0x04, 0xc2, 0xa4, 0x92, 0x2c, 0x38, 0xfe, 0x3f, 0xb7, 0xf3, 0xb6, 0x57, 0x0d, 0x9f, 0x06, 0xc0, 0x32, 0x00, 0xf0, 0x4e, 0x46, 0x9c, 0xba, 0x88, 0x85, 0x31, 0x1d, 0x7f, 0x5c, 0x81, 0x54, 0x8a, 0x3f, 0x4d, 0x47, 0xce, 0xab, 0x2c, 0xe9, 0x76, 0x21, 0xb3, 0x80, 0x71, 0x56, 0x03, 0x12, 0x06, 0x4d, 0xd4, 0x76, 0x64, 0xa0, 0x8c, 0xc6, 0xb0, 0xdd, 0x81, 0xd6, 0x6d, 0x34, 0x1b, 0xf9, 0x97, 0xe9, 0xaa, 0x7e, 0x2c, 0xc1, 0x12, 0x58, 0x38, 0x26, 0xbe, 0x1d, 0xa9, 0xa0, 0x16, 0xec, 0xc5, 0xcf, 0x74, 0xcd, 0xbf, 0x6a, 0x59, 0xdf, 0x78, 0x8e, 0xc1, 0x57, 0xf5, 0xaa, 0x8d, 0x5e, 0x67, 0x1a, 0x24, 0x02, 0x5f, 0xca, 0xea, 0x89, 0xda, 0xd9, 0xad, 0x7a, 0x7c, 0x22, 0x53, 0x27, 0x15, 0xa4, 0x83, 0x83, 0x22, 0xf7, 0xa8, 0x55, 0xf4, 0x33, 0x43, 0x1e, 0x65, 0xf6, 0x74, 0x80, 0x15, 0x04, 0x6c, 0x11, 0x98, 0x10, 0xbe, 0xfc, 0x0f, 0x5e, 0x81, 0xfb, 0x47, 0x9d, 0xc0, 0x39, 0x57, 0x20, 0x52, 0x5e, 0xa3, 0x84, 0xb3, 0x33, 0xf0, 0x2e, 0x16, 0x62, 0x3a, 0x90, 0x1b, 0xd9, 0x24, 0x7a, 0x95, 0x75, 0xe1, 0x4f, 0xe7, 0x5d, 0xb1, 0x25, 0x63, 0xf8, 0x0c, 0x33, 0x22, 0xcb, 0xe0, 0xe3, 0x9b, 0x25, 0x97, 0x24, 0x8a, 0x13, 0xc8, 0x06, 0xb7, 0xfc, 0x59, 0xfb, 0x6e, 0x36, 0xa9, 0x0f, 0xd9, 0x21, 0x26, 0xad, 0x3d, 0x3c, 0x7d, 0xcd, 0xbc, 0xa9, 0xc0, 0xc6, 0xdd, 0xd7, 0xee, 0x95, 0xfd, 0x4e, 0xb8, 0xdc, 0x62, 0xfa, 0x44, 0x8e, 0xe7, 0xe2, 0x78, 0x74, 0xd2, 0x9a, 0x64, 0x9f, 0xfb, 0xa1, 0xf6, 0xc7, 0x7e, 0x2f, 0x08, 0xe2, 0x75, 0xc8, 0x49, 0xa7, 0x6d, 0x3d, 0x66, 0x0b, 0x50, 0xfc, 0x62, 0x6e, 0x3d, 0x0c, 0x1e, 0xea, 0x3f, 0x5a, 0x45, 0x90, 0xec, 0xe8, 0xf9, 0x53, 0xef, 0x76, 0x84, 0x0b, 0xff, 0xcd, 0x24, 0x1e, 0x64, 0x18, 0xc0, 0xd2, 0xf4, 0x11, 0xa0, 0xe1, 0x1a, 0x7b, 0xec, 0xd6, 0xe8, 0x33, 0x6a, 0x76, 0xb1, 0xd6, 0x6f, 0x29, 0xf1, 0x08, 0x7b, 0xa0, 0xdf, 0x54, 0x94, 0xfd, 0x02, 0x8f, 0x42, 0x79, 0x0b, 0xf1, 0x35, 0xca, 0xba, 0x20, 0x19, 0x9a, 0x89, 0x6e, 0x27, 0x87, 0xd7, 0x4c, 0x89, 0x87, 0x28, 0x41, 0x2c, 0xe1, 0x58, 0xf6, 0x84, 0x67, 0xcb, 0xbc, 0x9d, 0x9e, 0x63, 0x67, 0xbb, 0x0a, 0x8b, 0x0a, 0xaa, 0x0c, 0x90, 0xf8, 0x55, 0x05, 0xc4, 0x67, 0x9a, 0x27, 0x1f, 0x92, 0xd0, 0xe1, 0xd1, 0x3f, 0xc5, 0xe4, 0xfc, 0xe0, 0x00, 0xf8, 0x97, 0xb3, 0xc3, 0x09, 0xb6, 0x2a, 0x21, 0xe9, 0xe1, 0xad, 0xf2, 0x53, 0x30, 0x6b, 0x49, 0x38, 0x1b, 0x19, 0xa1, 0xf7, 0xb8, 0xe1, 0x0c, 0x16, 0x4a, 0xf6, 0x6c, 0x61, 0x60, 0x7c, 0x04, 0xf8, 0xb2, 0xca, 0x21, 0x4e, 0x4b, 0x88, 0x36, 0x57, 0xda, 0xd8, 0xc5, 0xc5, 0xfd, 0x68, 0x59, 0x74, 0x40, 0x2a, 0x68, 0x69, 0x1e, 0x96, 0x43, 0x49, 0xc3, 0xdc, 0xae, 0xd0, 0x19, 0x92, 0xb3, 0x0f, 0x9f, 0x47, 0xb1, 0x08, 0x63, 0x92, 0x17, 0xdf, 0xda, 0xa0, 0xec, 0x2f, 0x90, 0xe5, 0x91, 0xef, 0x29, 0xd7, 0x3c, 0x23, 0x3f, 0xf8, 0x4b, 0xda, 0xad, 0x1b, 0xf4, 0x82, 0x72, 0xd9, 0x82, 0x17, 0x7c, 0x82, 0xaf, 0x46, 0x21, 0xfb, 0x19, 0x85, 0x83, 0x3b, 0x30, 0x98, 0x38, 0x48, 0x07, 0x97, 0x49, 0x18, 0x9c, 0x3b, 0x93, 0x19, 0xef, 0xba, 0x60, 0xdf, 0x27, 0xd7, 0x2d, 0x1f, 0xdc, 0x07, 0xfe, 0xe2, 0x56, 0x81, 0xe8, 0xda, 0x95, 0x57, 0x83, 0x2c, 0xec, 0x0d, 0xa1, 0xbf, 0x9e, 0x5a, 0xc5, 0xb7, 0x40, 0xb5, 0xcd, 0xc4, 0x6e, 0xfd, 0xf1, 0x87, 0x78, 0x98, 0x4d, 0xb4, 0x2b, 0x8e, 0xee, 0x05, 0x41, 0xe0, 0xdd, 0x48, 0xe2, 0x5b, 0xae, 0x83, 0xd9, 0x1d, 0x6a, 0x12, 0x64, 0x49, 0x35, 0x2f, 0xcb, 0x88, 0x80, 0xea, 0xed, 0x3a, 0x25, 0x1d, 0x53, 0x7a, 0x35, 0x92, 0x85, 0x57, 0xd4, 0x8d, 0x4c, 0x82, 0xd5, 0x56, 0x2b, 0xa9, 0x5b, 0xfd, 0xb7, 0x87, 0xe2, 0x09, 0x8d, 0x80, 0x6e, 0x9f, 0x20, 0x23, 0x05, 0x9e, 0x64, 0xf2, 0xfb, 0x73, 0x70, 0xae, 0x62, 0xf7, 0x3c, 0xc6, 0x48, 0x1e, 0x30, 0xc5, 0x85, 0x6d, 0x16, 0xca, 0x14, 0xfd, 0xe7, 0x7b, 0xee, 0x1c, 0x1f, 0x8b, 0x52, 0xd0, 0x81, 0xd9, 0x0d, 0x3d, 0xbe, 0xec, 0x27, 0xd2, 0xb3, 0x55, 0xbd, 0x43, 0xed, 0x6a, 0x17, 0x57, 0x13, 0x6c, 0x39, 0x89, 0x41, 0xe1, 0xd3, 0x12, 0xbd, 0xda, 0x84, 0x94, 0x32, 0x25, 0xb7, 0x63, 0x96, 0x5d, 0x68, 0x10, 0x59, 0x15, 0xe7, 0x36, 0x8f, 0x7b, 0x61, 0x09, 0xe2, 0xfc, 0xdf, 0x50, 0xfe, 0xfa, 0x4c, 0xd7, 0xde, 0xd1, 0xe6, 0xfc, 0x6d, 0x61, 0xce, 0xc3, 0xaf, 0x00, 0xcd, 0xce, 0x54, 0x05, 0x97, 0x62, 0xf2, 0x69, 0xe5, 0x85, 0x3f, 0xe1, 0xb6, 0xfe, 0xfb, 0xd6, 0x6f, 0xbd, 0xed, 0x60, 0xaa, 0x87, 0x7c, 0xa6, 0xb1, 0x05, 0xf3, 0x9e, 0x9a, 0x88, 0x95, 0xa9, 0x5b, 0x07, 0x4a, 0x74, 0x88, 0x63, 0x04, 0x11, 0x5f, 0x9e, 0x8e, 0x22, 0xbf, 0xb8, 0x80, 0x1d, 0x55, 0xe7, 0x05, 0x6a, 0xb1, 0xdb, 0xf7, 0xb9, 0x26, 0x3e, 0x37, 0x94, 0xd9, 0xb8, 0x25, 0x0b, 0x56, 0x8b, 0x42, 0x77, 0xd7, 0x30, 0xf9, 0x1d, 0x3f, 0x58, 0xec, 0xd9, 0xd9, 0xc4, 0x8d, 0xc2, 0xe0, 0xb5, 0x6b, 0xaf, 0x3f, 0x94, 0x06, 0x4d, 0x72, 0x12, 0xc4, 0x77, 0xc5, 0xfb, 0x07, 0x07, 0xd3, 0x71, 0x0d, 0x98, 0xe4, 0x4f, 0x3c, 0xda, 0x75, 0xa8, 0xb0, 0x53, 0x87, 0x2c, 0xec, 0x1e, 0xe9, 0xb2, 0xfc, 0x8f, 0x8a, 0xa0, 0xbe, 0x0f, 0x40, 0xe2, 0xf4, 0xe7, 0x21, 0xf9, 0x7c, 0x7a, 0x4d, 0xc0, 0x27, 0x53, 0xe3, 0xe1, 0x89, 0x60, 0x3d, 0x66, 0x66, 0x8e, 0xb1, 0xe0, 0xfe, 0x09, 0xba, 0x54, 0xff, 0x08, 0xe0, 0x11, 0x10, 0x5c, 0x48, 0x12, 0x40, 0x8e, 0x47, 0x79, 0xcd, 0x84, 0x63, 0x55, 0xfd, 0x66, 0xcc, 0x15, 0xd4, 0xcf, 0x24, 0x86, 0xc5, 0xc3, 0x38, 0x2b, 0xd3, 0xba, 0xde, 0x40, 0xff, 0xe3, 0x75, 0xac, 0x7a, 0x3b, 0x4e, 0x1c, 0xe6, 0xdb, 0x2d, 0x9b, 0x64, 0xa9, 0x71, 0xee, 0xa9, 0x42, 0xbb, 0xf1, 0x19, 0xe6, 0x99, 0x61, 0xa5, 0x7e, 0x63, 0xc9, 0x53, 0xd9, 0xe6, 0x77, 0x0a, 0xcb, 0xe8, 0xac, 0x5e, 0x8d, 0xf1, 0x67, 0x47, 0xa4, 0xc1, 0xed, 0x8b, 0x6e, 0x83, 0x4d, 0x05, 0x31, 0xc3, 0x6b, 0xbe, 0x2d, 0xc4, 0x54, 0x0d, 0x4a, 0x24, 0x3e, 0xa6, 0xe2, 0xec, 0xb0, 0x5d, 0xad, 0x2e, 0xe9, 0x2d, 0x33, 0x2f, 0xf7, 0x4c, 0x1e, 0x17, 0x91, 0x68, 0xbf, 0xe0, 0x99, 0xae, 0xda, 0x8f, 0x72, 0xe6, 0x53, 0x2b, 0xef, 0x7f, 0xe4, 0x4c, 0x89, 0xc0, 0x67, 0xf9, 0x6f, 0xf3, 0x15, 0x35, 0x2e, 0x27, 0xe4, 0xa5, 0x79, 0x56, 0xce, 0x9c, 0xd5, 0xd1, 0xdc, 0x62, 0x3f, 0x38, 0xe3, 0x27, 0x12, 0x1b, 0xc1, 0x45, 0x30, 0x70, 0x9f, 0x2a, 0x24, 0xf0, 0x80, 0xd0, 0x99, 0x8d, 0x55, 0xc9, 0x59, 0xe7, 0xca, 0x4a, 0x72, 0xae, 0x55, 0xa4, 0xfb, 0xae, 0x14, 0xec, 0x37, 0xcc, 0x85, 0x54, 0xe1, 0xcc, 0x68, 0xb7, 0x4b, 0x38, 0x94, 0x32, 0x5b, 0x1b, 0xc7, 0x84, 0x27, 0xde, 0x14, 0x86, 0x3b, 0xc4, 0x2f, 0x9d, 0xb0, 0x24, 0xed, 0x8b, 0x87, 0xe5, 0x55, 0x14, 0x46, 0x79, 0x78, 0x09, 0x48, 0xf8, 0xc0, 0x3e, 0xe6, 0xb6, 0x74, 0x54, 0x0d, 0xe4, 0xe9, 0x5b, 0xd5, 0xa3, 0x0f, 0xff, 0x0b, 0x83, 0xb3, 0xf9, 0x8d, 0xc5, 0x23, 0xb8, 0x03, 0x1c, 0x16, 0xbc, 0xdd, 0xea, 0x41, 0x56, 0xce, 0x5b, 0x0f, 0x02, 0x56, 0x31, 0x92, 0x04, 0x88, 0x9c, 0x4a, 0x00, 0xd3, 0x89, 0x7c, 0x7d, 0x3f, 0x36, 0x8e, 0xfc, 0xf3, 0xf7, 0x5d, 0x61, 0x47, 0xf9, 0x2a, 0xd7, 0x55, 0xf9, 0x84, 0xeb, 0x7e, 0x40, 0x74, 0xb3, 0x29, 0x65, 0x92, 0x63, 0x5a, 0x50, 0x86, 0x5d, 0x8e, 0x00, 0x90, 0x04, 0x04, 0xd2, 0x28, 0x9a, 0x29, 0x47, 0x32, 0x81, 0x58, 0x51, 0x62, 0x1c, 0x03, 0xeb, 0xfd, 0x0d, 0x0d, 0x82, 0x47, 0x09, 0xc3, 0x0b, 0x7d, 0x2c, 0xc5, 0x8e, 0x1a, 0xca, 0xa5, 0x0c, 0xc0, 0xfd, 0x4f, 0x84, 0xfd, 0xbb, 0x7c, 0xb4, 0xc2, 0xb7, 0xae, 0x29, 0x64, 0x5d, 0x2a, 0x1d, 0x83, 0x33, 0x96, 0x9b, 0x91, 0x69, 0xcb, 0x59, 0x1e, 0xaf, 0xd2, 0x15, 0xd9, 0xc9, 0x02, 0xa3, 0x70, 0xb8, 0x11, 0x94, 0xdd, 0x46, 0x90, 0xf0, 0x79, 0xb4, 0x76, 0xbf, 0xa2, 0xa3, 0x99, 0x1f, 0x23, 0x58, 0x5f, 0xa9, 0x8a, 0xa7, 0xce, 0x01, 0x31, 0x4f, 0x6a, 0xa5, 0x78, 0xd4, 0x56, 0x68, 0x4f, 0xb9, 0xd4, 0x9a, 0x75, 0x2a, 0x83, 0x1d, 0xaa, 0xd1, 0xfb, 0x11, 0xe9, 0xc2, 0xb1, 0xe4, 0xd8, 0x92, 0x5d, 0x43, 0x33, 0x93, 0x89, 0xea, 0x6b, 0x3c, 0x48, 0x48, 0x39, 0x71, 0xf2, 0x92, 0xac, 0xb7, 0x65, 0xf4, 0x0b, 0xd4, 0x66, 0x78, 0xb1, 0x68, 0xca, 0x02, 0xe9, 0xe5, 0x71, 0x53, 0xba, 0x38, 0x75, 0xd1, 0x9f, 0x64, 0xae, 0x14, 0x93, 0xf1, 0xe1, 0xab, 0x7a, 0x1b, 0x82, 0x5e, 0x8a, 0x19, 0x2a, 0x6a, 0x8e, 0xc3, 0x94, 0x21, 0x33, 0xf7, 0xc6, 0xdd, 0x33, 0xa9, 0x35, 0x1c, 0x22, 0x9f, 0xf7, 0x82, 0xca, 0xd1, 0x7a, 0x90, 0xa4, 0xbe, 0x54, 0xd8, 0xfa, 0x08, 0xdd, 0xf0, 0xc0, 0x41, 0xf5, 0x88, 0x89, 0x1d, 0xe7, 0x01, 0x75, 0x6f, 0x5b, 0x99, 0x9b, 0x58, 0xb2, 0xd6, 0xc3, 0x36, 0x71, 0x0c, 0x1e, 0x8a, 0xdc, 0xc5, 0x13, 0x0c, 0x1b, 0xbf, 0x26, 0x9a, 0x2e, 0x27, 0x6a, 0x02, 0xa6, 0x95, 0x19, 0xe4, 0x4a, 0x5e, 0xfe, 0x8c, 0xb0, 0xe4, 0xd7, 0x28, 0xe1, 0x5a, 0xf7, 0x51, 0x0f, 0x03, 0x64, 0xa1, 0x82, 0x19, 0x15, 0x88, 0x51, 0xc5, 0x83, 0xe2, 0x1d, 0xa0, 0x76, 0x18, 0xa1, 0x3f, 0xc4, 0xa9, 0xe9, 0x06, 0x72, 0xdf, 0x02, 0x2b, 0xa5, 0xb6, 0x9d, 0x9f, 0xd8, 0xc2, 0xb0, 0x4c, 0x35, 0x9f, 0x4e, 0x62, 0xe1, 0xe8, 0x69, 0x35, 0xc7, 0xc3, 0xe4, 0xcb, 0x7e, 0x69, 0xdc, 0xfe, 0xff, 0xf9, 0xc7, 0xc2, 0x68, 0x23, 0x09, 0x92, 0xa1, 0x28, 0xdc, 0xaa, 0xd0, 0x34, 0x34, 0x76, 0x9a, 0x7a, 0xd7, 0x89, 0xaf, 0xf3, 0xfd, 0xc3, 0x65, 0xc4, 0x84, 0x3c, 0x20, 0xa4, 0x82, 0xd6, 0x6e, 0xa7, 0x57, 0x6b, 0x01, 0x0e, 0xb5, 0x02, 0x4e, 0x20, 0x48, 0xbd, 0xf0, 0x2f, 0xc8, 0xa4, 0xc4, 0xe1, 0xcf, 0x38, 0x33, 0x8f, 0xe2, 0xb5, 0x9d, 0xb7, 0x91, 0x5a, 0x89, 0x46, 0x6e, 0x8a, 0xd9, 0xc6, 0xc4, 0x6e, 0x8e, 0x39, 0x2a, 0xdd, 0x08, 0x94, 0x4f, 0xd2, 0x16, 0x1a, 0xf9, 0xab, 0x00, 0x61, 0xb4, 0x8f, 0x28, 0xda, 0x76, 0x27, 0xb9, 0x84, 0x76, 0x87, 0x81, 0x8f, 0x71, 0xf2, 0x77, 0x95, 0x04, 0xfb, 0x09, 0xed, 0x53, 0x51, 0x13, 0x7c, 0x64, 0xcf, 0xf4, 0xdb, 0x8f, 0xbd, 0x05, 0x22, 0x90, 0x66, 0x8c, 0xb6, 0xf5, 0xcc, 0xa8, 0xd2, 0x03, 0x6d, 0x6f, 0x0c, 0x3e, 0x24, 0x7d, 0x0f, 0x76, 0xa0, 0x15, 0xa5, 0xd7, 0x9a, 0x3c, 0x94, 0x1d, 0xab, 0x88, 0x45, 0x45, 0x05, 0xe2, 0xab, 0x96, 0x95, 0x1b, 0x9e, 0x23, 0xf7, 0xa7, 0xc5, 0x8c, 0x7f, 0x0a, 0xc2, 0xe9, 0x17, 0xf7, 0xe9, 0x49, 0x8d, 0x23, 0xdf, 0xea, 0x1e, 0x29, 0xdb, 0x87, 0xc1, 0x11, 0x5a, 0x58, 0x25, 0xa4, 0x21, 0xb4, 0x52, 0xd8, 0xeb, 0xda, 0x46, 0xb1, 0xe6, 0x5e, 0x77, 0xb6, 0x61, 0x60, 0xc0, 0x22, 0x5d, 0xd3, 0x1b, 0xb0, 0x51, 0xfc, 0xb8, 0xbf, 0x53, 0x6b, 0x72, 0x77, 0xff, 0x4c, 0x52, 0x1b, 0xa2, 0xab, 0x56, 0x1b, 0x1e, 0xaf, 0x4d, 0x3f, 0x1f, 0x12, 0xe5, 0x6c, 0x90, 0x2f, 0x63, 0x75, 0x5e, 0xc2, 0x9c, 0x24, 0x13, 0x0e, 0x25, 0xbe, 0x3f, 0x38, 0x70, 0x15, 0x55, 0xb2, 0x73, 0x05, 0xba, 0x61, 0xe6, 0x25, 0xed, 0xbc, 0x7c, 0xc8, 0xd8, 0xe8, 0x8d, 0xc9, 0xf3, 0xf3, 0x2b, 0xa0, 0x44, 0x31, 0xf3, 0x34, 0x88, 0x56, 0x5c, 0x02, 0x60, 0x25, 0x11, 0x98, 0xd6, 0x6e, 0xea, 0x34, 0x79, 0xfe, 0xfa, 0xf5, 0x5d, 0x19, 0xc9, 0xb3, 0x8b, 0x49, 0x5d, 0x66, 0x12, 0xde, 0x47, 0x53, 0x0a, 0x47, 0xb6, 0xf8, 0x86, 0x72, 0xb7, 0x4b, 0xcf, 0x02, 0xae, 0xf6, 0x1a, 0xcb, 0x94, 0x0e, 0x53, 0xda, 0xb2, 0xff, 0x28, 0x0f, 0x26, 0xbc, 0xfb, 0x9a, 0xcd, 0x5b, 0xf8, 0x17, 0xb0, 0x75, 0xf3, 0x43, 0xaf, 0xdb, 0xae, 0x9d, 0x82, 0xb9, 0xd1, 0x37, 0xe6, 0x89, 0x84, 0x8a, 0x8e, 0x77, 0x26, 0x8e, 0x02, 0xc3, 0x5c, 0x47, 0x1e, 0x65, 0x22, 0xff, 0xc6, 0x8f, 0x38, 0x0b, 0x40, 0xef, 0x90, 0x6e, 0xfe, 0xa1, 0x89, 0xd6, 0x84, 0x3a, 0x5d, 0x2a, 0xad, 0xdb, 0x7a, 0xe5, 0x0f, 0x01, 0x6e, 0xfb, 0x85, 0xe5, 0x44, 0xec, 0x6c, 0x5d, 0x98, 0x1d, 0xe9, 0x0d, 0x56, 0xf0, 0x00, 0x12, 0xe9, 0x1b, 0xca, 0xdb, 0x65, 0x49, 0x40, 0x80, 0x15, 0x84, 0x63, 0xf6, 0xff, 0x66, 0x81, 0x96, 0xe7, 0xec, 0xcb, 0x53, 0x94, 0x5c, 0x96, 0x0d, 0x28, 0xd5, 0x9d, 0xd9, 0x0e, 0xef, 0x38, 0x9d, 0x72, 0x42, 0x43, 0x71, 0x34, 0x67, 0x85, 0x5a, 0xf4, 0xf5, 0xe4, 0x5c, 0xc3, 0xde, 0x36, 0x5e, 0xde, 0x97, 0x80, 0xc4, 0x7f, 0xc7, 0x03, 0x1f, 0x56, 0xcd, 0x6f, 0x89, 0x06, 0xdd, 0xa9, 0x16, 0x5f, 0x8d, 0xf4, 0x38, 0x8c, 0x88, 0xbe, 0xa9, 0xea, 0x0d, 0x56, 0xbc, 0xd1, 0xc6, 0x4a, 0x7e, 0xbb, 0xcd, 0x13, 0x57, 0x2d, 0x40, 0x9e, 0xe9, 0xe3, 0xc7, 0xd2, 0x92, 0xc2, 0x23, 0xad, 0xd8, 0xb9, 0xe2, 0x87, 0xb6, 0x12, 0x2c, 0x07, 0x5a, 0xbe, 0xb2, 0x37, 0x0f, 0x66, 0xda, 0x1a, 0x91, 0xa3, 0xda, 0x24, 0xb2, 0x68, 0xc0, 0xde, 0x90, 0x91, 0xc4, 0x85, 0xa9, 0x28, 0x94, 0x21, 0xca, 0x24, 0x40, 0x1f, 0x09, 0xf0, 0x95, 0x87, 0xcd, 0x22, 0x57, 0x4e, 0xfd, 0xc2, 0x69, 0x48, 0xa8, 0xd1, 0x31, 0xcb, 0xd2, 0x79, 0xea, 0x6b, 0xc8, 0xd7, 0xe5, 0xad, 0xfc, 0x77, 0xb2, 0x2b, 0xc1, 0xcc, 0x1f, 0x52, 0x02, 0x11, 0x96, 0xa9, 0xe9, 0x60, 0x80, 0x1d, 0xbf, 0x40, 0xb5, 0xd3, 0x9f, 0xd9, 0x03, 0x19, 0x53, 0x05, 0x76, 0x5b, 0x69, 0x9f, 0x5d, 0x6e, 0x0b, 0xf6, 0x50, 0xcc, 0x76, 0xa6, 0x63, 0x23, 0x7b, 0xb4, 0x10, 0x47, 0x45, 0xf1, 0xa2, 0x45, 0x25, 0x74, 0xc8, 0xf5, 0x58, 0xa3, 0xc8, 0xe8, 0xd0, 0x74, 0x7b, 0x76, 0x8a, 0x55, 0x4a, 0x94, 0xe0, 0xdb, 0x50, 0x97, 0x17, 0xe9, 0x75, 0x09, 0xe6, 0x7d, 0x4b, 0x39, 0x61, 0x8c, 0x59, 0x8e, 0x44, 0x32, 0xec, 0xd6, 0xcc, 0x67, 0x6b, 0xa9, 0x61, 0xb9, 0x81, 0xbc, 0xdb, 0x86, 0xa3, 0x3d, 0x10, 0x95, 0xe4, 0x46, 0x7a, 0x3b, 0x06, 0x33, 0x28, 0x0f, 0xf7, 0xbe, 0x1f, 0x2c, 0x49, 0x9a, 0xeb, 0x12, 0xeb, 0x9d, 0x27, 0x84, 0x38, 0x81, 0xe0, 0xcf, 0x96, 0x1e, 0x0f, 0x21, 0x14, 0xc9, 0xe3, 0x68, 0xc6, 0x22, 0x83, 0x5c, 0x22, 0xf0, 0x93, 0xca, 0x33, 0xfb, 0x93, 0x50, 0xba, 0x57, 0x16, 0x24, 0x34, 0x1e, 0x66, 0xe1, 0x8b, 0x4a, 0x1e, 0x7c, 0xc4, 0x79, 0xf6, 0x1c, 0x1c, 0x90, 0x8f, 0xaf, 0xac, 0xb4, 0xb9, 0xa6, 0x8b, 0xbc, 0xd6, 0x9b, 0x2e, 0x53, 0x6c, 0x89, 0x25, 0xcb, 0x61, 0x0f, 0xa9, 0x03, 0xd8, 0x5a, 0xbd, 0xf5, 0x27, 0xe5, 0x94, 0x38, 0x51, 0xd3, 0x50, 0x18, 0x31, 0xfa, 0x9f, 0x53, 0x4f, 0x2f, 0xc7, 0x95, 0xe1, 0x65, 0xc7, 0xd6, 0x9f, 0x7e, 0xcd, 0x83, 0x14, 0xd5, 0xf2, 0x38, 0x2a, 0x80, 0x61, 0xf4, 0xce, 0x3c, 0xab, 0x4f, 0x98, 0x54, 0x48, 0x6c, 0xc9, 0x52, 0x0a, 0xc7, 0x96, 0x7e, 0x95, 0xd0, 0xd8, 0x0e, 0x3f, 0xe0, 0x88, 0x3e, 0x5b, 0xe6, 0x1d, 0x03, 0xb5, 0xf5, 0x8d, 0x02, 0x6a, 0x27, 0xd5, 0x40, 0x7e, 0xe8, 0xd4, 0x0a, 0xd4, 0xf2, 0xee, 0xc5, 0xe4, 0x16, 0x9a, 0xcc, 0xc6, 0x1e, 0x9a, 0xc0, 0xfa, 0xe1, 0xec, 0xc1, 0x8e, 0x97, 0xe5, 0xf2, 0x1a, 0xae, 0x50, 0x74, 0x29, 0x2b, 0x1a, 0x86, 0xfd, 0xef, 0xda, 0xfd, 0xd6, 0x66, 0x79, 0x84, 0xc8, 0x64, 0x0a, 0x78, 0x0c, 0x70, 0xda, 0x92, 0x54, 0x94, 0x1c, 0xb2, 0x4c, 0x28, 0xdc, 0x05, 0xe5, 0xce, 0x46, 0xa3, 0xf3, 0xde, 0x58, 0x48, 0x92, 0x3b, 0x99, 0x33, 0xb4, 0x76, 0xd6, 0x29, 0xc3, 0x77, 0xac, 0xbf, 0xcb, 0xb4, 0xc8, 0x00, 0x1b, 0x7c, 0x31, 0xb4, 0x19, 0x51, 0xbf, 0x12, 0xce, 0x39, 0xb6, 0xed, 0x1c, 0x79, 0x71, 0x25, 0xa1, 0x2a, 0x77, 0x32, 0x89, 0x62, 0xfd, 0x39, 0x4e, 0xd3, 0x15, 0xc4, 0x37, 0xcd, 0x38, 0x9d, 0x27, 0x00, 0xac, 0xdb, 0x86, 0x23, 0x22, 0x6d, 0x24, 0x42, 0xf1, 0x82, 0x7c, 0x97, 0xda, 0x02, 0x47, 0x7e, 0xc1, 0x84, 0x0d, 0xb2, 0x5f, 0x41, 0x1c, 0x76, 0x67, 0xdb, 0xf8, 0x56, 0xdb, 0x06, 0xdf, 0xf5, 0x07, 0xc5, 0x75, 0xbf, 0xe9, 0x07, 0x73, 0x24, 0xac, 0xce, 0x1c, 0x5c, 0x7b, 0x38, 0xbf, 0x5e, 0x1c, 0xf0, 0x20, 0x7d, 0x53, 0x4d, 0xfa, 0x5a, 0x96, 0x06, 0x86, 0xee, 0x38, 0x17, 0x9b, 0x48, 0x8d, 0xce, 0x1e, 0x98, 0x59, 0x32, 0xab, 0xf1, 0xbe, 0x0e, 0x66, 0x3f, 0x38, 0xf1, 0x5d, 0x8c, 0xa5, 0x3b, 0xbf, 0x31, 0x85, 0x28, 0x91, 0x02, 0x2a, 0xed, 0x06, 0x63, 0xed, 0x10, 0x24, 0x7c, 0x3c, 0x25, 0xbd, 0x1e, 0x45, 0x38, 0xd1, 0x71, 0xa8, 0x68, 0xca, 0x51, 0x2e, 0x8c, 0xa5, 0xec, 0x39, 0xb7, 0x3b, 0x5c, 0x1a, 0x1f, 0xc7, 0xc7, 0x48, 0xbd, 0x28, 0x2a, 0xbc, 0x24, 0xa6, 0x12, 0xbe, 0xd4, 0x14, 0x05, 0xb1, 0xbe, 0x43, 0x5a, 0x4e, 0x58, 0xc9, 0x6e, 0xb9, 0x89, 0x7a, 0x45, 0x69, 0x37, 0x4f, 0x6c, 0xd1, 0xc7, 0xf6, 0x43, 0x78, 0x8d, 0x53, 0x04, 0xba, 0xc1, 0xb7, 0x80, 0xae, 0xe0, 0xcc, 0x90, 0x76, 0xe5, 0xc9, 0x2c, 0x26, 0x0f, 0x92, 0x22, 0xe4, 0x43, 0x1e, 0xf3, 0xac, 0x22, 0x2c, 0x3d, 0x02, 0x57, 0x86, 0x1c, 0xad, 0x50, 0x70, 0xd3, 0xc1, 0x94, 0xd4, 0x46, 0x1b, 0xa0, 0x49, 0x09, 0xae, 0x02, 0x48, 0x33, 0x8c, 0x3d, 0x99, 0x10, 0x97, 0xe9, 0x43, 0x93, 0x4c, 0x9a, 0xf5, 0xe4, 0xa0, 0x8d, 0x9c, 0xdc, 0xaf, 0x1e, 0xf3, 0x20, 0xdd, 0xfe, 0x95, 0xb3, 0xaf, 0xed, 0x26, 0xe5, 0xef, 0xdd, 0x0d, 0x2b, 0x78, 0x1f, 0x66, 0x9f, 0x11, 0x6c, 0xa7, 0x24, 0xed, 0x25, 0xb9, 0x9d, 0xef, 0xdc, 0x67, 0x80, 0x92, 0xa2, 0xe9, 0xc6, 0x40, 0x28, 0x5c, 0x1d, 0x1f, 0xc1, 0x2d, 0x9f, 0xfa, 0x93, 0xd3, 0x98, 0x6f, 0x1b, 0x92, 0xb8, 0x7f, 0xf8, 0xe1, 0x27, 0x1e, 0x46, 0x2c, 0x08, 0x60, 0xd5, 0xbb, 0xed, 0x9d, 0x83, 0x03, 0xae, 0xdc, 0x47, 0xf8, 0x43, 0x12, 0xf8, 0x8c, 0xad, 0x33, 0x3d, 0x4f, 0xfd, 0x6f, 0xa2, 0x26, 0x5f, 0x80, 0xd6, 0x54, 0x67, 0xd4, 0xcf, 0x95, 0x8f, 0x08, 0x6b, 0x6b, 0xe7, 0xfb, 0x1f, 0x1f, 0x5a, 0x0b, 0x62, 0xf6, 0x84, 0xa1, 0xc1, 0x6d, 0x9b, 0x66, 0x5c, 0x50, 0xb1, 0x86, 0xf5, 0x9e, 0x3d, 0x4c, 0x42, 0xeb, 0x32, 0x42, 0x75, 0x72, 0x17, 0x40, 0x22, 0xab, 0x4e, 0xc2, 0xbd, 0x06, 0xf3, 0xbb, 0x60, 0xf2, 0x0c, 0x7a, 0x50, 0xb8, 0x78, 0x54, 0xf4, 0x07, 0xb5, 0x0b, 0x14, 0xab, 0x05, 0x2e, 0x5f, 0x9d, 0x88, 0x1f, 0xdd, 0x4f, 0xe7, 0x3b, 0x26, 0x4b, 0x69, 0x39, 0x58, 0x2d, 0x55, 0xf6, 0x44, 0x61, 0xef, 0x24, 0x5a, 0x5f, 0xe3, 0x0f, 0x47, 0xf6, 0xb1, 0x78, 0x73, 0x5d, 0xbe, 0x40, 0x01, 0x07, 0x9b, 0x1f, 0x8a, 0x65, 0x14, 0x63, 0x5d, 0x3e, 0x15, 0x34, 0xae, 0x37, 0xdf, 0xb9, 0xf4, 0x98, 0x66, 0xca, 0xa5, 0x61, 0x01, 0x6e, 0xb1, 0xe8, 0x2a, 0x4a, 0x9b, 0x81, 0x76, 0x44, 0xde, 0x7b, 0xa6, 0xb0, 0xdf, 0xe9, 0x05, 0x87, 0xa8, 0x6e, 0xcd, 0xe2, 0x2d, 0x42, 0xca, 0x44, 0x49, 0x1a, 0x40, 0x03, 0x8d, 0x29, 0xb7, 0xd2, 0x19, 0x80, 0x04, 0xea, 0xfb, 0x12, 0x72, 0x52, 0xb8, 0x40, 0xe1, 0xce, 0x2e, 0xf8, 0xda, 0xa4, 0x9f, 0xc9, 0xa7, 0xc9, 0x82, 0x83, 0x58, 0x63, 0xaf, 0xc0, 0xa3, 0x4b, 0x57, 0x94, 0xe9, 0x07, 0x92, 0xf8, 0x99, 0xc7, 0xe8, 0x46, 0xe3, 0x3f, 0x33, 0x69, 0xa8, 0xdb, 0x38, 0xbc, 0x1c, 0xa8, 0x8f, 0x89, 0x43, 0x52, 0xee, 0x8a, 0x15, 0xc6, 0xda, 0x6b, 0xfc, 0xb8, 0x43, 0xb6, 0x23, 0x12, 0x2c, 0xbb, 0xd9, 0xee, 0xe2, 0xe8, 0xe7, 0xf7, 0xbf, 0x36, 0xb0, 0xc7, 0x08, 0x6f, 0xf2, 0x61, 0x4b, 0x69, 0x19, 0x2b, 0xa6, 0x89, 0x7f, 0x07, 0x2b, 0x42, 0x32, 0x15, 0x60, 0x1b, 0x2c, 0x90, 0xcd, 0x2f, 0x55, 0xde, 0x70, 0x31, 0x85, 0x0c, 0x0b, 0xed, 0x15, 0x0e, 0xa8, 0x60, 0xc6, 0x9f, 0x9c, 0xbb, 0x57, 0xb1, 0xc5, 0x43, 0x49, 0x01, 0x32, 0xad, 0xdb, 0xf7, 0x0c, 0xf3, 0x96, 0x44, 0x89, 0xf8, 0x43, 0xe8, 0xb6, 0x1e, 0x2b, 0x49, 0xfa, 0xfe, 0x22, 0x9f, 0x07, 0x38, 0x06, 0x69, 0x58, 0x01, 0x3a, 0xc8, 0x18, 0xc7, 0x47, 0x79, 0x12, 0x8f, 0x53, 0xac, 0xf0, 0x5f, 0x76, 0x44, 0x75, 0x50, 0x57, 0xd2, 0x7b, 0x89, 0xe0, 0xe5, 0xd9, 0xfb, 0x4e, 0xca, 0xcf, 0x5c, 0x25, 0xd1, 0x92, 0xa3, 0x8f, 0xd5, 0x2c, 0x35, 0xed, 0x19, 0x23, 0xcc, 0x01, 0xd3, 0xe2, 0x37, 0x08, 0x28, 0xf3, 0x39, 0x61, 0x94, 0xaa, 0x01, 0xa9, 0x8f, 0x50, 0x02, 0xc7, 0x07, 0x3b, 0xee, 0x62, 0xd7, 0xb9, 0x97, 0x5c, 0xf7, 0xdf, 0xf2, 0x06, 0x39, 0x8e, 0x66, 0x02, 0x91, 0xf7, 0x50, 0x75, 0xb7, 0x64, 0xaa, 0x7a, 0xad, 0x33, 0xae, 0x93, 0x85, 0x4e, 0x91, 0x72, 0x74, 0xe2, 0x59, 0x17, 0xb2, 0xd9, 0xe8, 0xc3, 0x16, 0xc9, 0xa6, 0xf8, 0xd0, 0xf1, 0x67, 0xd0, 0x6b, 0xd4, 0xca, 0x0c, 0x23, 0x00, 0xe4, 0xf4, 0x02, 0xe4, 0x5f, 0xf9, 0xbd, 0xcb, 0xe9, 0x09, 0x54, 0xb0, 0xdf, 0x4e, 0xa7, 0x3d, 0x26, 0xab, 0x4d, 0xe2, 0x35, 0xeb, 0x2a, 0xe5, 0x4b, 0xa4, 0x1c, 0x87, 0xc8, 0x6b, 0xca, 0x86, 0x0c, 0xf7, 0x19, 0x54, 0x98, 0x5e, 0x3f, 0x0f, 0xf9, 0x09, 0x39, 0xad, 0xe9, 0xc8, 0x17, 0xe1, 0x68, 0x81, 0x40, 0x3d, 0x30, 0xf9, 0xae, 0x64, 0x7d, 0xea, 0x5b, 0x1f, 0x59, 0xa2, 0x21, 0xf4, 0xb1, 0xa7, 0xc7, 0x57, 0x57, 0x55, 0xe0, 0x0c, 0x1c, 0x78, 0x9e, 0xe7, 0xd2, 0x4c, 0xd6, 0xe3, 0xf9, 0x10, 0x66, 0xc7, 0xd0, 0x50, 0x56, 0x88, 0xdb, 0x87, 0x84, 0xbd, 0xc8, 0x74, 0x8d, 0xe6, 0x49, 0x30, 0x42, 0x3b, 0xd2, 0xec, 0xb9, 0xe9, 0xa4, 0xa5, 0xa5, 0xc6, 0xd8, 0x93, 0x5b, 0x13, 0x9a, 0x4f, 0xd8, 0xab, 0xfc, 0x8a, 0xf3, 0x94, 0xca, 0x72, 0x6b, 0xce, 0xa4, 0x9a, 0x34, 0xde, 0xb1, 0xfa, 0x20, 0x2e, 0xb1, 0x5c, 0xa9, 0x60, 0x3e, 0x57, 0x03, 0x2d, 0x31, 0x97, 0xe1, 0xae, 0x5b, 0x10, 0xae, 0xbb, 0x5c, 0x08, 0x33, 0x02, 0xb2, 0x35, 0xbb, 0x3e, 0xe5, 0x01, 0x9d, 0x96, 0xf5, 0xb1, 0xbb, 0x79, 0x58, 0xc2, 0x3b, 0x52, 0x3f, 0x91, 0xf9, 0x0b, 0x9c, 0x9b, 0xa8, 0x41, 0xfb, 0x4a, 0xe5, 0x42, 0x49, 0x0d, 0x2b, 0x91, 0x25, 0xb2, 0x25, 0xa9, 0x37, 0x07, 0x80, 0x75, 0x37, 0xa1, 0x73, 0x38, 0xee, 0xea, 0x45, 0x3c, 0x17, 0x46, 0x34, 0xaa, 0xb2, 0x34, 0xfe, 0x8c, 0x42, 0xcd, 0x79, 0x14, 0x96, 0xaf, 0x26, 0x4d, 0xa1, 0xca, 0x75, 0x9d, 0xbe, 0x0f, 0xb1, 0x25, 0x56, 0xe6, 0xec, 0x5d, 0x7e, 0x26, 0x04, 0x6f, 0xd4, 0x2a, 0xd0, 0x50, 0x95, 0x38, 0x2d, 0x0b, 0x8d, 0x9e, 0x8d, 0x46, 0x88, 0xc6, 0x39, 0x80, 0xc2, 0xdf, 0x85, 0xd0, 0x61, 0x7b, 0xc9, 0xfe, 0x26, 0x02, 0x2c, 0xde, 0xa8, 0x2b, 0x86, 0xa1, 0xd5, 0x52, 0x50, 0xaf, 0xdc, 0xf3, 0xcf, 0x25, 0x7e, 0xfb, 0xf4, 0xb0, 0xe8, 0x1c, 0x85, 0x70, 0xa7, 0x39, 0x26, 0xe5, 0xac, 0xa8, 0x2f, 0xc7, 0x1e, 0x46, 0x7f, 0xc4, 0x15, 0x53, 0x9b, 0xa4, 0x84, 0xc2, 0x0d, 0xd8, 0xe5, 0x91, 0x5e, 0x5e, 0xeb, 0x2f, 0x0e, 0x6f, 0xc2, 0xc1, 0xf1, 0x8a, 0x48, 0x51, 0x8a, 0x0b, 0x0c, 0x10, 0x6c, 0x86, 0xba, 0x1a, 0xa5, 0xa0, 0x27, 0x7f, 0x3f, 0x4a, 0xae, 0x55, 0x06, 0x96, 0xed, 0x3a, 0xa1, 0x6c, 0xb5, 0x06, 0xa2, 0x2f, 0x45, 0xaa, 0x23, 0xc0, 0x55, 0xa5, 0x80, 0x06, 0x7c, 0x90, 0x42, 0x85, 0xb6, 0x80, 0x48, 0xbe, 0x6f, 0xdc, 0x41, 0xaf, 0x34, 0x04, 0x7b, 0x4a, 0xa2, 0x05, 0x97, 0x3f, 0xdf, 0xe1, 0x44, 0x27, 0x1f, 0x03, 0x3a, 0xf8, 0xfb, 0xbe, 0xd2, 0xba, 0xf7, 0x72, 0xba, 0x97, 0x63, 0x8c, 0xa0, 0x10, 0xae, 0xe6, 0x8e, 0x2b, 0x45, 0xff, 0xd4, 0x0d, 0xa9, 0x77, 0xe4, 0x8b, 0x3e, 0x13, 0x90, 0x9e, 0xf9, 0x7a, 0x2a, 0x28, 0x08, 0x85, 0x33, 0xef, 0x39, 0x9f, 0x4b, 0x8a, 0xc5, 0xfa, 0x36, 0xf2, 0x4e, 0x81, 0x45, 0x9e, 0x96, 0x40, 0xd7, 0x32, 0xb5, 0xd1, 0x09, 0x7d, 0x1e, 0x7a, 0x0e, 0x05, 0xf6, 0x2a, 0xd6, 0xc5, 0xb9, 0x8a, 0xaa, 0xda, 0xac, 0x48, 0x7a, 0x04, 0x97, 0x8a, 0x39, 0x48, 0x7b, 0xb6, 0x57, 0xca, 0x2a, 0x7b, 0xc5, 0x90, 0xfd, 0xc1, 0xd1, 0xe2, 0x8b, 0xb0, 0x86, 0x77, 0xe2, 0x74, 0xce, 0x95, 0x67, 0x88, 0x9f, 0x8e, 0x58, 0x5d, 0x81, 0x6c, 0xc1, 0x26, 0xd5, 0xaf, 0x37, 0xb1, 0x34, 0xf6, 0x06, 0x44, 0xb7, 0xa2, 0x9e, 0x40, 0x3b, 0x67, 0xd4, 0x63, 0xb0, 0x40, 0xa6, 0xf4, 0x84, 0x7c, 0xc1, 0xae, 0x2a, 0x7f, 0x1a, 0x1b, 0xc5, 0xbb, 0x34, 0xf9, 0xd1, 0x88, 0x57, 0x28, 0x03, 0x0e, 0x52, 0x76, 0xec, 0xef, 0x45, 0xcc, 0x68, 0xe0, 0x19, 0x92, 0x87, 0x29, 0x1c, 0x57, 0x2f, 0xe0, 0x70, 0x8e, 0xad, 0x3d, 0xa6, 0x2b, 0x73, 0xb8, 0xc9, 0x75, 0x3c, 0x04, 0x9a, 0x5a, 0x9c, 0x1c, 0x77, 0x53, 0x0f, 0x5c, 0x59, 0xa2, 0xea, 0x80, 0xf6, 0x70, 0x0e, 0x56, 0x91, 0x9a, 0x0a, 0x46, 0xd6, 0xb0, 0x18, 0x88, 0x81, 0x01, 0x82, 0x56, 0x8d, 0x44, 0x20, 0xf9, 0xf3, 0x0a, 0xa1, 0x6f, 0x13, 0x8f, 0xe0, 0x10, 0x2d, 0xa2, 0xd2, 0xf6, 0xf1, 0x5d, 0xa3, 0xb7, 0x3c, 0x2a, 0x39, 0xb5, 0xe1, 0xf5, 0x53, 0x7a, 0xd1, 0x23, 0xab, 0xe0, 0x58, 0x9a, 0x5b, 0x48, 0x98, 0x6b, 0xbb, 0x93, 0x98, 0x41, 0x82, 0x4c, 0x3c, 0x1a, 0x52, 0x2b, 0x52, 0x2c, 0x39, 0x2a, 0x3d, 0x37, 0xb2, 0x2a, 0xc9, 0xd7, 0xce, 0xf1, 0x27, 0x85, 0xdd, 0x0d, 0x21, 0xd9, 0x80, 0xbc, 0xd2, 0x87, 0xdd, 0xce, 0xe8, 0xff, 0xc6, 0xfe, 0x49, 0x6b, 0xae, 0xc1, 0x30, 0xc4, 0x7c, 0x79, 0x12, 0x47, 0x5a, 0xe2, 0x83, 0x30, 0x25, 0x67, 0xa0, 0xc4, 0x58, 0xc3, 0x63, 0x5b, 0xc3, 0x34, 0x07, 0x82, 0xe1, 0xb3, 0xe9, 0x9d, 0xbe, 0xe7, 0x3e, 0x19, 0xe5, 0x6a, 0x43, 0x17, 0x20, 0xd6, 0x40, 0xcb, 0xc3, 0xac, 0xe2, 0x88, 0x7f, 0xfe, 0x9f, 0xe5, 0xdd, 0xac, 0xa7, 0x31, 0x1b, 0x7a, 0x60, 0xd6, 0x76, 0xed, 0x88, 0x11, 0x84, 0x68, 0x3e, 0x10, 0xce, 0x6b, 0xa0, 0x3d, 0x85, 0xf5, 0xf2, 0xa7, 0xbf, 0x6f, 0x56, 0xc9, 0x4b, 0xcb, 0x1e, 0xa1, 0xf9, 0xac, 0x3f, 0x08, 0xa5, 0x8e, 0xe4, 0x3f, 0x1d, 0xb5, 0x32, 0x54, 0x3d, 0xbe, 0xa5, 0x09, 0x22, 0x8d, 0xf1, 0xcd, 0x18, 0x41, 0x85, 0x9e, 0x64, 0xd4, 0xb7, 0x8a, 0x34, 0x1e, 0x2a, 0xf5, 0x95, 0x4a, 0x10, 0xda, 0x96, 0x2b, 0x39, 0x8a, 0xae, 0xf3, 0x3b, 0x80, 0x00, 0xd6, 0x80, 0xca, 0x25, 0xae, 0x99, 0x6b, 0x3e, 0x1f, 0x60, 0xb3, 0x59, 0xe9, 0xa2, 0x9a, 0xe1, 0xfa, 0x2b, 0x16, 0x76, 0x73, 0xe3, 0x09, 0xff, 0xd3, 0xa4, 0xec, 0x74, 0x8e, 0x53, 0x95, 0xdd, 0xc8, 0x8f, 0xf0, 0x22, 0x39, 0x17, 0x7b, 0x99, 0x39, 0x4b, 0xe0, 0xe8, 0x3b, 0xf8, 0x5c, 0x98, 0x2c, 0x15, 0x35, 0xb3, 0x0b, 0xd6, 0xb6, 0xfe, 0x95, 0x35, 0x4f, 0x31, 0x73, 0x02, 0xb6, 0x6c, 0xc6, 0x5e, 0xa9, 0xab, 0xdf, 0x09, 0x4d, 0xc4, 0x85, 0x01, 0xcb, 0xc9, 0x35, 0x2d, 0x4e, 0x22, 0x80, 0x15, 0x66, 0xab, 0xaa, 0x6d, 0xc3, 0x3b, 0x74, 0xdf, 0xdb, 0xb2, 0x13, 0xb0, 0x6e, 0xb3, 0xdd, 0x8a, 0xbb, 0x14, 0x4a, 0x4c, 0xad, 0x3a, 0xe4, 0xc4, 0x0f, 0x86, 0xdd, 0x3d, 0x4f, 0x82, 0xe8, 0xf2, 0xf2, 0x03, 0x0e, 0xc5, 0xcd, 0xa8, 0xf3, 0xe9, 0x77, 0x82, 0x93, 0x11, 0x86, 0xcc, 0x81, 0x86, 0x8e, 0x4a, 0x06, 0x4b, 0x95, 0x63, 0xc1, 0x1d, 0xd0, 0x2a, 0x2c, 0x4e, 0x7c, 0x45, 0x71, 0x07, 0x3d, 0xe9, 0xa6, 0xb6, 0x20, 0xd9, 0x63, 0x6c, 0x03, 0x22, 0xf4, 0x76, 0x90, 0x83, 0xc5, 0x84, 0x23, 0x64, 0x89, 0x09, 0x53, 0x75, 0xbd, 0xd7, 0x54, 0x6c, 0xa0, 0x73, 0x20, 0x50, 0xc4, 0x70, 0x15, 0xfa, 0x19, 0xa5, 0x1b, 0xfd, 0x18, 0x56, 0x11, 0xd9, 0xb7, 0x52, 0x19, 0xe4, 0xb2, 0x77, 0xff, 0x61, 0xe2, 0xab, 0x66, 0x18, 0x33, 0x7e, 0x1d, 0xe9, 0x79, 0x8a, 0xab, 0xbb, 0x0f, 0xc6, 0x9f, 0xb6, 0xdd, 0x6d, 0x4c, 0xbe, 0xae, 0x00, 0x87, 0x88, 0x89, 0xe5, 0xae, 0x91, 0xd3, 0xb0, 0x03, 0xbe, 0xc0, 0xf7, 0x05, 0x53, 0x81, 0xef, 0x47, 0x43, 0xc3, 0x5d, 0x30, 0x68, 0xa9, 0x17, 0xbf, 0x0d, 0x66, 0x04, 0xd8, 0x8e, 0x39, 0xbf, 0xec, 0x6f, 0x87, 0x51, 0xe4, 0xbf, 0xc6, 0x54, 0xfe, 0x25, 0x86, 0xe5, 0x12, 0x91, 0x86, 0xde, 0xc5, 0x27, 0x15, 0x24, 0xe7, 0xad, 0xaf, 0x9b, 0x46, 0xf5, 0xde, 0x05, 0x52, 0x38, 0x63, 0x4a, 0x17, 0x00, 0x6d, 0x6d, 0xf3, 0xfd, 0x58, 0x80, 0x2d, 0x38, 0x99, 0xa9, 0x6b, 0x45, 0x8f, 0xcb, 0x09, 0x3c, 0x60, 0x7f, 0x8f, 0xcb, 0x9b, 0x7a, 0x09, 0xa4, 0x18, 0xa9, 0x35, 0x15, 0x7d, 0x3a, 0xaf, 0x11, 0x75, 0x00, 0xbf, 0x74, 0x5a, 0xa8, 0xbe, 0x8c, 0x32, 0xef, 0x0e, 0x44, 0x3d, 0x9c, 0x33, 0xff, 0x7c, 0xc8, 0xf6, 0x4d, 0xf1, 0x24, 0x84, 0x9a, 0x91, 0x6c, 0x31, 0x27, 0xb9, 0x54, 0x0c, 0xc1, 0x1a, 0x13, 0x13, 0x7b, 0x59, 0x4d, 0x97, 0x8d, 0x4f, 0xd4, 0xb7, 0xf3, 0xf2, 0xc3, 0xf3, 0xad, 0xb4, 0x97, 0x02, 0x67, 0x08, 0xe2, 0x3d, 0xd2, 0xc8, 0x66, 0x6d, 0xe1, 0x22, 0x07, 0x3d, 0x52, 0xa1, 0xda, 0x53, 0xc5, 0x5c, 0x0f, 0x24, 0xd0, 0x4d, 0x1a, 0xb5, 0x6a, 0x8e, 0x8f, 0x6e, 0x9b, 0x6d, 0xf7, 0xd4, 0x5c, 0x69, 0x4c, 0x71, 0x8a, 0xc9, 0x77, 0x1f, 0xe5, 0x24, 0xab, 0xc0, 0x0e, 0x8c, 0x38, 0x60, 0xdd, 0x4c, 0x23, 0xf8, 0x27, 0x8d, 0x7b, 0xe0, 0xd0, 0xdb, 0xce, 0x00, 0x2b, 0x18, 0x11, 0xd3, 0x0d, 0x81, 0x07, 0x4c, 0x96, 0x65, 0xd7, 0x91, 0xef, 0x91, 0x86, 0xda, 0x40, 0xed, 0x78, 0xcb, 0xad, 0xd5, 0x53, 0x82, 0x55, 0xca, 0x8b, 0x15, 0xb6, 0x7d, 0x8a, 0x99, 0x48, 0x36, 0x5f, 0xbf, 0xbf, 0x20, 0xc0, 0x49, 0x9e, 0xd3, 0x53, 0xe8, 0x06, 0xc7, 0x99, 0x18, 0xbb, 0x7f, 0x38, 0x95, 0xf2, 0x86, 0x7a, 0x7c, 0x7f, 0x3b, 0xa1, 0x4a, 0x63, 0xb6, 0xa2, 0xc8, 0x9e, 0x1d, 0x82, 0x51, 0x1c, 0x83, 0xd3, 0xc9, 0x10, 0xfd, 0xac, 0x53, 0xf6, 0x0b, 0x9a, 0x8e, 0x8c, 0x6e, 0x52, 0x13, 0xba, 0xb0, 0xd2, 0xb2, 0xb2, 0xf6, 0x00, 0x02, 0x67, 0x52, 0xb4, 0xca, 0xfe, 0x53, 0xb2, 0x68, 0x14, 0x34, 0x99, 0x33, 0x9d, 0xf6, 0xd9, 0xd8, 0x7d, 0x97, 0xea, 0x13, 0xb7, 0x96, 0xf5, 0x1c, 0xce, 0x36, 0x46, 0x1a, 0x11, 0xf4, 0xe9, 0x20, 0x31, 0x77, 0x66, 0x68, 0x34, 0x04, 0x3d, 0xa9, 0x74, 0xa7, 0x7f, 0x60, 0xcc, 0x3a, 0x55, 0x3d, 0xd3, 0xfa, 0x40, 0x26, 0xa8, 0x95, 0x97, 0xf2, 0x48, 0x95, 0xd2, 0x5f, 0x82, 0x7a, 0x73, 0x12, 0x41, 0x88, 0xc0, 0x7b, 0xe7, 0xab, 0xaa, 0x76, 0x82, 0x80, 0xbd, 0x20, 0x76, 0x7a, 0xc4, 0x10, 0x4a, 0x2f, 0x12, 0x8b, 0x44, 0x8d, 0x13, 0x54, 0x7a, 0xd2, 0x6c, 0xa3, 0xdf, 0x51, 0xfb, 0x73, 0x58, 0x17, 0xc9, 0xc4, 0xc0, 0xec, 0x6c, 0x5e, 0x5e, 0xf3, 0x0c, 0xa5, 0x48, 0x73, 0xca, 0x0d, 0x6f, 0x85, 0x58, 0xaa, 0x0b, 0x40, 0x9c, 0xd0, 0xd4, 0x6b, 0x97, 0x6e, 0x07, 0x1a, 0xa6, 0x35, 0x12, 0x8a, 0xfb, 0xee, 0xe7, 0xdc, 0x27, 0x9b, 0x5e, 0xa9, 0x9d, 0x88, 0xa6, 0xa9, 0xc3, 0x6b, 0xc4, 0xbb, 0x07, 0xf8, 0xb6, 0x7e, 0x33, 0x3e, 0xbc, 0x57, 0x06, 0x9e, 0xca, 0x50, 0xca, 0x87, 0xe0, 0x82, 0x43, 0x40, 0xe3, 0x1b, 0x86, 0x57, 0xd6, 0xa8, 0x9e, 0x99, 0x1d, 0xf7, 0x3e, 0x14, 0x5e, 0x56, 0x10, 0x1f, 0xc8, 0x89, 0x84, 0x09, 0xbf, 0x98, 0x54, 0xa2, 0xe8, 0xf2, 0xa2, 0x49, 0xd3, 0x73, 0x79, 0xb2, 0xac, 0x6b, 0x01, 0x9d, 0xd5, 0xa9, 0xea, 0x46, 0x3c, 0x9f, 0x18, 0xee, 0xb7, 0x33, 0x61, 0xb6, 0x6b, 0xaf, 0xde, 0x99, 0xc4, 0xf6, 0xa0, 0x96, 0xe3, 0x7f, 0x2d, 0x77, 0x06, 0x1a, 0x29, 0x12, 0x6d, 0x21, 0xf8, 0x68, 0xea, 0x55, 0x29, 0xd6, 0xd1, 0x42, 0xf7, 0x92, 0x87, 0xb8, 0x62, 0x76, 0xf0, 0x04, 0x41, 0xdf, 0x57, 0x18, 0x03, 0xc4, 0xbf, 0x77, 0x15, 0xc6, 0x55, 0x83, 0x3a, 0x85, 0x27, 0x67, 0xc1, 0x82, 0x5b, 0x34, 0x9a, 0x6e, 0xf4, 0xba, 0xac, 0x53, 0x55, 0x51, 0x09, 0x2d, 0xcc, 0xce, 0xbb, 0xa2, 0xaa, 0x9d, 0xec, 0x8e, 0x68, 0x35, 0x00, 0xdb, 0x54, 0xef, 0xca, 0x5c, 0x60, 0xfb, 0x6a, 0xb6, 0x6d, 0xe7, 0xd4, 0x5e, 0xce, 0x0b, 0xfe, 0x6a, 0xe8, 0x4e, 0x2e, 0x81, 0x2b, 0x42, 0x66, 0xd6, 0x10, 0x1e, 0x14, 0xb9, 0xcb, 0x1c, 0x18, 0x81, 0xcf, 0xbd, 0xec, 0xd3, 0x80, 0x3b, 0x17, 0x40, 0x4d, 0x64, 0xa4, 0xf3, 0x11, 0x82, 0xc3, 0x11, 0x87, 0x68, 0x37, 0x95, 0xd6, 0x7c, 0xc2, 0x40, 0xf1, 0x07, 0xa1, 0x70, 0x09, 0x41, 0xed, 0x1a, 0xe9, 0x03, 0x41, 0xee, 0x02, 0xed, 0xe6, 0x89, 0xc2, 0xfc, 0xc1, 0x8e, 0x55, 0x6a, 0xcd, 0xb4, 0x09, 0x3d, 0x4d, 0x64, 0xf9, 0x17, 0xaf, 0x7d, 0x45, 0x36, 0x8d, 0xec, 0x66, 0xf0, 0x00, 0xc1, 0x11, 0xf9, 0x0f, 0x9e, 0x7a, 0xfb, 0x49, 0xb5, 0xb1, 0xac, 0xe8, 0xd5, 0x9f, 0xc4, 0xba, 0x18, 0x38, 0x92, 0x8d, 0x20, 0x3c, 0xdc, 0x26, 0x23, 0xa7, 0xdc, 0xb5, 0xec, 0xfe, 0x61, 0x28, 0xb8, 0xbf, 0xcb, 0x55, 0xb0, 0x56, 0xc8, 0xd0, 0xf7, 0x24, 0x5d, 0x87, 0x77, 0x08, 0x52, 0x09, 0x6f, 0x52, 0xdc, 0x46, 0xd3, 0xa6, 0x0a, 0x92, 0xb6, 0x5d, 0x54, 0x75, 0x3f, 0x0b, 0x1c, 0x53, 0x46, 0x01, 0x3e, 0x07, 0xa6, 0xf6, 0xfe, 0x8b, 0x0d, 0xda, 0x9a, 0x99, 0x0e, 0xf3, 0x08, 0xcd, 0x30, 0x2f, 0x28, 0x53, 0x3e, 0x3d, 0x8f, 0x09, 0xcc, 0xdf, 0xd9, 0xc5, 0x9e, 0xf7, 0xd4, 0x98, 0x66, 0xa0, 0xf9, 0xab, 0x6a, 0x26, 0x3e, 0x52, 0x44, 0xc6, 0xcc, 0xf0, 0x61, 0xa2, 0xa1, 0xd6, 0xc2, 0x00, 0x0d, 0x27, 0x48, 0x3f, 0xae, 0xf4, 0x21, 0xa7, 0xc6, 0xab, 0x02, 0x67, 0x24, 0x6e, 0x68, 0x49, 0x42, 0x7b, 0xb8, 0x41, 0xb1, 0x6f, 0xba, 0x6b, 0xfa, 0xde, 0xc5, 0xfb, 0xd4, 0xfa, 0xd6, 0x70, 0xa6, 0x29, 0xc7, 0xd6, 0xfe, 0xa5, 0x82, 0xb8, 0xea, 0x21, 0x81, 0xcd, 0x4c, 0xd3, 0xe4, 0xcc, 0xd8, 0x3f, 0x4c, 0x23, 0xe5, 0x83, 0x3e, 0xf0, 0x0d, 0x3a, 0xed, 0x8f, 0x8b, 0x65, 0x71, 0xc4, 0xa1, 0x29, 0xfc, 0x3f, 0x55, 0x9f, 0x51, 0x9b, 0xf0, 0x36, 0xaa, 0x82, 0xe5, 0x58, 0xa6, 0xa3, 0xe0, 0x02, 0x09, 0xa8, 0xd6, 0x9a, 0xa9, 0xe5, 0x1f, 0xb6, 0x5a, 0x54, 0xeb, 0x9b, 0xf1, 0xc1, 0x34, 0x99, 0x2f, 0xb3, 0x7c, 0x44, 0x38, 0xf0, 0x8a, 0x3c, 0x19, 0x78, 0x99, 0xe5, 0x11, 0x4f, 0x7d, 0x09, 0xad, 0x4c, 0xcc, 0xa5, 0x84, 0xe0, 0x63, 0x36, 0xc0, 0x0b, 0x50, 0xab, 0x04, 0xfa, 0x2c, 0x18, 0xf2, 0xc2, 0xe3, 0xe6, 0x8e, 0x80, 0xa5, 0x3c, 0x14, 0x11, 0x8a, 0x83, 0x3e, 0xa7, 0xc2, 0xd7, 0x13, 0x63, 0x9c, 0x44, 0x85, 0x21, 0xa6, 0x6c, 0x47, 0x4a, 0x0d, 0x52, 0x39, 0x91, 0x2a, 0x92, 0xe9, 0x49, 0x2d, 0x2f, 0x40, 0x05, 0x83, 0xcd, 0x56, 0x60, 0x78, 0xfd, 0xb3, 0xbe, 0x90, 0xee, 0x7e, 0x21, 0xe3, 0x85, 0xc1, 0xbd, 0x81, 0x43, 0xd8, 0x09, 0xa2, 0x94, 0x50, 0xf3, 0x9e, 0xe4, 0x06, 0x31, 0xe7, 0xf8, 0x07, 0xe8, 0x2e, 0xd7, 0xf1, 0x29, 0xb6, 0x51, 0x27, 0x96, 0x2f, 0xbc, 0x8a, 0x83, 0x5e, 0x22, 0xd0, 0x39, 0x7c, 0x9a, 0x9a, 0x02, 0xe7, 0x5b, 0x07, 0xe9, 0x9b, 0x9d, 0x88, 0x51, 0x02, 0xe6, 0xb5, 0x91, 0xbc, 0x89, 0x96, 0xe9, 0x1f, 0x62, 0x73, 0xd8, 0x69, 0x55, 0x37, 0x46, 0x69, 0xec, 0x18, 0x33, 0xa0, 0xe9, 0xaa, 0x17, 0xa1, 0x60, 0xbd, 0x38, 0x98, 0x18, 0x9c, 0x97, 0xb4, 0xe0, 0xda, 0x24, 0x9a, 0x1c, 0x1a, 0xeb, 0x75, 0x17, 0x25, 0x88, 0x8b, 0xf6, 0x97, 0x77, 0x4a, 0xe0, 0x73, 0x39, 0x48, 0x55, 0x13, 0x7d, 0xe5, 0xe1, 0xb7, 0x9d, 0x25, 0x1e, 0x80, 0x7c, 0x3c, 0x2c, 0x0f, 0xc7, 0x1c, 0x59, 0xbc, 0x85, 0x4d, 0x31, 0x32, 0x54, 0x13, 0x91, 0xa2, 0x35, 0x86, 0x44, 0xdc, 0xe6, 0xc4, 0xcc, 0x02, 0x8d, 0x85, 0x27, 0xa1, 0x38, 0xe1, 0xf8, 0x3c, 0xb8, 0x6a, 0x21, 0x39, 0xc7, 0x99, 0x33, 0x32, 0xe4, 0xc4, 0x98, 0x87, 0xac, 0xd6, 0xc3, 0x5a, 0xa1, 0x6b, 0x53, 0x8f, 0x1e, 0x50, 0x55, 0xd6, 0x1c, 0x2e, 0x48, 0xfb, 0xc9, 0xaf, 0xbb, 0xf6, 0xc7, 0x7d, 0xb1, 0x6c, 0x9d, 0xbf, 0x97, 0x8b, 0xbf, 0x35, 0x59, 0xc4, 0x7f, 0x6e, 0x39, 0xa5, 0xd0, 0x20, 0x9f, 0x25, 0x66, 0xf1, 0x77, 0x0c, 0xaa, 0xca, 0xa6, 0x8e, 0x60, 0x80, 0xe7, 0x19, 0x5b, 0xc2, 0x41, 0x7e, 0x3c, 0x9f, 0xee, 0xe3, 0x90, 0x15, 0x3e, 0xcc, 0x4b, 0x8b, 0x10, 0xc6, 0x21, 0x0d, 0x00, 0xac, 0xbf, 0x63, 0xeb, 0x25, 0xa9, 0x32, 0xf7, 0x5d, 0xb4, 0x1c, 0xab, 0xc1, 0xec, 0x40, 0x27, 0x3e, 0x71, 0x42, 0x5f, 0xf8, 0x3c, 0x48, 0x49, 0x0b, 0x7a, 0xec, 0x5b, 0x41, 0xa2, 0xc5, 0x6f, 0x9f, 0x43, 0x77, 0xce, 0xfb, 0x57, 0xf9, 0x98, 0x93, 0x9c, 0x15, 0xbe, 0x0d, 0x2f, 0xef, 0x74, 0x90, 0x56, 0xfe, 0xc6, 0x37, 0x00, 0x0c, 0x50, 0x70, 0x21, 0x26, 0xf7, 0xfe, 0xef, 0xe0, 0x3f, 0x08, 0x87, 0x79, 0xb9, 0x7e, 0xa7, 0xa1, 0xc0, 0x02, 0x05, 0x65, 0xd0, 0x88, 0xb9, 0xbc, 0x1e, 0x94, 0xb0, 0x6b, 0xf7, 0x50, 0xce, 0x4b, 0xd7, 0x65, 0x08, 0x24, 0xed, 0xd5, 0x69, 0xf6, 0xd1, 0x1a, 0x1c, 0x36, 0x82, 0x9e, 0x1f, 0x9d, 0x95, 0x89, 0xa8, 0xd6, 0x7b, 0x9d, 0x57, 0x35, 0x4d, 0xe2, 0xad, 0x9a, 0xb0, 0x53, 0x46, 0xd4, 0x59, 0x79, 0x08, 0xe5, 0xf7, 0x65, 0x97, 0xab, 0xd3, 0x24, 0x77, 0xde, 0x51, 0x08, 0x91, 0xec, 0x35, 0xfe, 0x90, 0xe8, 0xac, 0xc9, 0x39, 0xda, 0x73, 0xdb, 0x82, 0xc6, 0x31, 0x03, 0x9b, 0x42, 0x6c, 0xef, 0x3d, 0x84, 0x27, 0xe3, 0xd3, 0xee, 0x69, 0xd3, 0x54, 0x8d, 0xff, 0xa2, 0x85, 0x17, 0xfb, 0x7b, 0x44, 0xbb, 0x20, 0x0b, 0xdf, 0x46, 0xa2, 0x2f, 0xf5, 0x64, 0x25, 0xcb, 0xb8, 0xa1, 0x3d, 0xa4, 0xb9, 0x57, 0x05, 0x31, 0x6d, 0x4f, 0xc9, 0x1b, 0x81, 0xde, 0x57, 0xd6, 0xd8, 0x55, 0x62, 0x0a, 0x63, 0x39, 0x79, 0xf4, 0x89, 0xaa, 0xbf, 0xce, 0x08, 0x30, 0xc8, 0x46, 0xa7, 0x3e, 0x17, 0x2f, 0xed, 0x0a, 0xc8, 0xcc, 0xe8, 0xb7, 0xd9, 0xb5, 0xb7, 0xc2, 0x5e, 0x0e, 0x4f, 0x43, 0xdc, 0x8f, 0xaa, 0x5d, 0x10, 0x92, 0xe4, 0xa3, 0xe5, 0x4d, 0xf0, 0x21, 0x02, 0x30, 0xb4, 0x6a, 0x35, 0xf1, 0x8f, 0xa5, 0x31, 0xe0, 0xdc, 0x34, 0x0e, 0x9b, 0xc2, 0x56, 0x6c, 0x4f, 0x80, 0x09, 0x66, 0x60, 0x4e, 0xd5, 0x46, 0xdd, 0xf1, 0x21, 0x4a, 0x06, 0xf1, 0x4a, 0xb8, 0xf6, 0xc3, 0x53, 0x9a, 0xf2, 0x0b, 0x37, 0xd6, 0x7a, 0x4d, 0x4b, 0xb7, 0x7e, 0x78, 0x59, 0xfb, 0xd1, 0x86, 0x91, 0x7a, 0x27, 0xf2, 0x21, 0x8e, 0x1d, 0x9b, 0xdd, 0x98, 0x1f, 0x05, 0x8b, 0xb6, 0xfa, 0x8e, 0xdf, 0xa0, 0xe0, 0x08, 0x0e, 0x24, 0x34, 0xd7, 0x31, 0x4c, 0x91, 0xe7, 0x6e, 0xc0, 0x3e, 0xcb, 0xd9, 0x15, 0x59, 0xd0, 0x7e, 0x87, 0x3d, 0x43, 0xc5, 0xca, 0x65, 0xff, 0x94, 0x62, 0xf4, 0x57, 0xe3, 0x40, 0xca, 0x77, 0xe2, 0x85, 0xf8, 0x84, 0xa6, 0x50, 0xce, 0x30, 0xb8, 0x7b, 0x35, 0xb6, 0xd4, 0x6e, 0x8b, 0xd3, 0x5c, 0x59, 0x16, 0x7b, 0x37, 0x20, 0xfb, 0x1f, 0x7b, 0x27, 0xb0, 0x98, 0xd1, 0xaf, 0x5d, 0x62, 0x3f, 0xb6, 0xda, 0x4e, 0x39, 0x22, 0x8d, 0x3d, 0x51, 0x61, 0xb9, 0x63, 0x2c, 0xa4, 0xb8, 0x59, 0x3f, 0x0e, 0xa8, 0x45, 0x96, 0x93, 0x7f, 0x22, 0xe8, 0x5c, 0xb9, 0xeb, 0x51, 0xee, 0xd8, 0x76, 0x01, 0x9d, 0x24, 0x29, 0xb8, 0x9f, 0xd2, 0xd2, 0x2f, 0xaf, 0x1c, 0xe8, 0xdd, 0xed, 0x11, 0x0f, 0xa6, 0x68, 0x3c, 0x2a, 0xab, 0x01, 0x2f, 0xe1, 0xca, 0xe0, 0xb9, 0xac, 0xd1, 0x45, 0x7f, 0xb7, 0x41, 0xa4, 0xc3, 0xe9, 0x62, 0x12, 0x5a, 0xf8, 0x98, 0x2e, 0x26, 0xff, 0x46, 0x52, 0xb0, 0x76, 0x69, 0xcd, 0x7a, 0x29, 0xfb, 0x0f, 0x98, 0x05, 0x44, 0xd2, 0x5a, 0x32, 0xe0, 0x84, 0xdc, 0x38, 0xe9, 0x95, 0x57, 0xc4, 0xfe, 0x59, 0x2c, 0xb9, 0x37, 0x20, 0x13, 0x99, 0x82, 0xe4, 0xc4, 0x00, 0x0f, 0xba, 0x3e, 0xff, 0x2f, 0xe9, 0x74, 0xaa, 0x36, 0x17, 0x87, 0xda, 0x51, 0x2d, 0x14, 0x88, 0x04, 0x15, 0xfd, 0xe0, 0xa1, 0x08, 0x92, 0x98, 0x8a, 0xb1, 0x57, 0x22, 0x31, 0xe6, 0x01, 0x81, 0x6b, 0xbd, 0xf7, 0xb7, 0xb6, 0xdf, 0x67, 0xd8, 0x57, 0x66, 0xb5, 0x16, 0x33, 0x46, 0x9a, 0x4f, 0x58, 0xeb, 0x0a, 0xe5, 0xb6, 0x00, 0x44, 0x81, 0xfb, 0x33, 0x4c, 0x4a, 0x83, 0x96, 0xa0, 0x53, 0x16, 0xa9, 0x26, 0xa1, 0x43, 0xce, 0xc0, 0x8c, 0x73, 0x1f, 0xef, 0x89, 0x30, 0x97, 0xf1, 0xa1, 0x21, 0x48, 0x3f, 0xc8, 0x6a, 0xa8, 0x32, 0x23, 0x84, 0x29, 0xcb, 0xe0, 0xa3, 0x30, 0x52, 0x66, 0xe4, 0xce, 0x0c, 0xf6, 0x91, 0x8c, 0x6b, 0xd8, 0xde, 0x80, 0x1f, 0xbc, 0x31, 0x00, 0xcf, 0x84, 0xbd, 0x3a, 0xb2, 0xaa, 0x65, 0x5f, 0x56, 0x80, 0xba, 0x21, 0xa3, 0x5c, 0x81, 0x3b, 0x78, 0x57, 0x6b, 0x00, 0xf3, 0xcb, 0x8c, 0xef, 0xe3, 0x91, 0xc6, 0x58, 0x54, 0xba, 0xcd, 0x9b, 0x6e, 0xdd, 0x56, 0x7c, 0x53, 0xd7, 0x3b, 0x79, 0x64, 0xe0, 0xfc, 0xd7, 0xa7, 0x46, 0x57, 0xe5, 0x92, 0x87, 0xcc, 0x2e, 0xa1, 0x7f, 0xe5, 0xe1, 0x7a, 0xff, 0x52, 0x6d, 0xf8, 0x34, 0x5c, 0x92, 0x9d, 0xcc, 0xd4, 0x3d, 0x51, 0x79, 0x29, 0x1f, 0x01, 0x2a, 0x99, 0x44, 0x3a, 0x6b, 0x84, 0x3b, 0xe3, 0xc8, 0x21, 0x0f, 0xf1, 0xd2, 0xd5, 0x5a, 0xd1, 0xa5, 0x58, 0x8e, 0xff, 0x4f, 0x60, 0xa3, 0x15, 0x13, 0x48, 0x43, 0x63, 0xd6, 0xb1, 0x2d, 0x06, 0x1c, 0x96, 0xa5, 0xbd, 0x43, 0xee, 0x3e, 0x7d, 0xfe, 0x06, 0x36, 0xa6, 0x99, 0x9d, 0x96, 0xff, 0xba, 0x1d, 0xfe, 0xb1, 0xfc, 0xa0, 0xc8, 0xf0, 0xec, 0x65, 0x50, 0x99, 0xbb, 0xa2, 0x5b, 0x1c, 0xf3, 0x1f, 0xd4, 0xba, 0x7f, 0x52, 0xeb, 0x60, 0x93, 0x1c, 0x94, 0xd7, 0xc4, 0xcd, 0x27, 0xbb, 0xe7, 0xee, 0xda, 0xb0, 0x17, 0x64, 0x56, 0xb7, 0x74, 0x2c, 0x03, 0xf5, 0x8e, 0x5e, 0xea, 0x24, 0xba, 0x2f, 0x1b, 0x37, 0xfd, 0xba, 0xa6, 0xbc, 0x0f, 0x7d, 0x0d, 0x9c, 0xcf, 0xb9, 0x54, 0xfa, 0x03, 0x42, 0x37, 0x05, 0x49, 0x71, 0x45, 0x65, 0x6b, 0x69, 0xfc, 0xd2, 0xf9, 0x53, 0x2b, 0xbc, 0x8b, 0x6f, 0x69, 0x9e, 0x8d, 0xad, 0x93, 0x14, 0xb7, 0xc0, 0x4b, 0xee, 0x8f, 0x95, 0x8a, 0x0d, 0x3b, 0xa3, 0x8f, 0x68, 0x51, 0xc8, 0x43, 0xf7, 0x70, 0xb2, 0x9b, 0xcc, 0xf7, 0xa6, 0xa7, 0x34, 0xa2, 0xc9, 0x99, 0xc7, 0x14, 0x46, 0x0a, 0x5e, 0x4d, 0x64, 0x0b, 0x66, 0x0f, 0xd8, 0xd5, 0x4f, 0x08, 0xa5, 0x95, 0x96, 0x61, 0xd3, 0x55, 0xf4, 0x33, 0x7f, 0xa6, 0xf3, 0x55, 0x14, 0xd2, 0x4d, 0xce, 0x5d, 0xc2, 0x5b, 0x12, 0x52, 0xec, 0x73, 0x2e, 0x39, 0x75, 0x5d, 0xa7, 0x46, 0x17, 0x0b, 0x13, 0x94, 0x6f, 0x21, 0x4b, 0xd1, 0xd4, 0xfc, 0x42, 0xfa, 0x22, 0x02, 0x16, 0xe3, 0xb3, 0x29, 0xbc, 0x2f, 0x15, 0x68, 0xa7, 0x73, 0xfb, 0x8f, 0x87, 0xee, 0x05, 0x94, 0x86, 0x7f, 0x1a, 0xbc, 0xa9, 0xcc, 0x22, 0x24, 0x4c, 0xd8, 0x5f, 0xb8, 0xe7, 0x05, 0x04, 0xe0, 0x69, 0x20, 0x2f, 0x0b, 0xf7, 0x6d, 0xc8, 0xa2, 0xd9, 0x5f, 0x64, 0xf9, 0x2e, 0xdb, 0x51, 0xa9, 0x84, 0x12, 0xb9, 0x91, 0x90, 0xb0, 0xa5, 0xfa, 0x9a, 0x7e, 0x86, 0xc0, 0x58, 0x28, 0xf9, 0x7f, 0x8a, 0x96, 0x3e, 0xf0, 0xfc, 0xe6, 0x36, 0xad, 0x7a, 0x10, 0x46, 0x30, 0xe1, 0xcb, 0x8b, 0xd3, 0x10, 0xdc, 0x9b, 0xcd, 0x36, 0xe5, 0x3b, 0xc0, 0xfc, 0xc5, 0xa7, 0x5f, 0x44, 0x94, 0xf6, 0x94, 0x7d, 0xcd, 0x0a, 0x18, 0xed, 0x66, 0x06, 0x63, 0xa0, 0x30, 0xd6, 0x89, 0x53, 0x26, 0x80, 0x51, 0x82, 0x0e, 0x7e, 0xa8, 0xf1, 0x6a, 0x4e, 0x6a, 0x2c, 0x58, 0x2f, 0xcc, 0xd9, 0x19, 0x92, 0x54, 0xad, 0xe2, 0xa3, 0x6a, 0x87, 0x9f, 0x1c, 0x54, 0x89, 0x2a, 0xaf, 0xd0, 0x37, 0xd8, 0xbb, 0xe4, 0x5d, 0x4a, 0x54, 0x50, 0x8e, 0xcc, 0x47, 0x46, 0x2c, 0x41, 0xbe, 0x81, 0xca, 0xf9, 0xcc, 0xd8, 0xff, 0x52, 0x20, 0x58, 0x4f, 0xe3, 0x4f, 0xad, 0xc1, 0x4d, 0xad, 0xf2, 0xb5, 0xf8, 0xd6, 0x94, 0x98, 0x2e, 0xb1, 0xed, 0x8f, 0xfc, 0x53, 0x81, 0x66, 0x86, 0x8e, 0xa0, 0x95, 0x75, 0xb0, 0x2a, 0x05, 0xe2, 0x91, 0xa4, 0xf1, 0x73, 0x42, 0xc5, 0x8c, 0x6c, 0x56, 0xb6, 0x57, 0x3d, 0xaf, 0x0f, 0x4b, 0xa3, 0xd7, 0x1c, 0x18, 0x68, 0x1f, 0x99, 0x31, 0xbb, 0x42, 0xdc, 0xd8, 0x7d, 0xe7, 0x0e, 0x27, 0x3a, 0x95, 0x1a, 0x2e, 0x7c, 0xd9, 0x08, 0x32, 0x5c, 0xea, 0xbe, 0x2a, 0x9b, 0xc1, 0xb1, 0x64, 0xa5, 0xf8, 0x2a, 0x2d, 0x10, 0xc5, 0xbf, 0xcb, 0x61, 0x3b, 0x73, 0x71, 0x2a, 0x96, 0xfe, 0xd3, 0xf5, 0xaf, 0x39, 0xdd, 0xb7, 0x9b, 0x1b, 0x15, 0xbb, 0x43, 0xb0, 0x78, 0x51, 0xe5, 0xef, 0x0a, 0xca, 0x50, 0x98, 0xa4, 0x38, 0xad, 0x68, 0x1d, 0xb2, 0x11, 0xdd, 0x14, 0xa8, 0x4f, 0x1b, 0xd4, 0x79, 0xe3, 0x25, 0xbe, 0xe1, 0x07, 0x85, 0x7d, 0xc0, 0x8b, 0xd5, 0x8f, 0xc3, 0xfb, 0x25, 0x79, 0xb7, 0x84, 0xf4, 0x65, 0x52, 0x73, 0xd1, 0x71, 0xd0, 0xaf, 0x52, 0x5e, 0x31, 0x2b, 0x4a, 0xa6, 0x55, 0x1c, 0xc7, 0xe8, 0x27, 0xb6, 0x0c, 0xc3, 0x45, 0x21, 0x1a, 0xb0, 0x68, 0x30, 0x63, 0xef, 0x5d, 0xdc, 0x69, 0x24, 0xa9, 0x8f, 0x9c, 0x54, 0xf9, 0xaf, 0x1a, 0xae, 0x18, 0x04, 0xc3, 0x4c, 0x63, 0x70, 0xac, 0x6e, 0xfc, 0x9a, 0x56, 0xf3, 0x50, 0xd1, 0x90, 0x78, 0x9a, 0xac, 0x82, 0x58, 0x5c, 0x19, 0x59, 0x70, 0x75, 0x0f, 0x9d, 0xab, 0x2e, 0x20, 0x2a, 0xa1, 0x31, 0x60, 0xf0, 0xeb, 0xdc, 0xc7, 0x50, 0x4a, 0x41, 0x99, 0x22, 0xe6, 0xfc, 0x5c, 0x42, 0xde, 0x7a, 0x4b, 0xe8, 0xd5, 0xe7, 0x48, 0x15, 0x4f, 0xe8, 0xb4, 0x77, 0x05, 0x70, 0xe5, 0x0b, 0x9c, 0xaa, 0xa0, 0xb0, 0x0e, 0x54, 0x7b, 0x20, 0x35, 0x19, 0xe3, 0xc4, 0x54, 0xf5, 0x4f, 0xb0, 0xbd, 0xb0, 0xfd, 0x46, 0x5a, 0x30, 0x78, 0xc9, 0x0d, 0x8f, 0x98, 0x8a, 0x40, 0x49, 0xb7, 0x37, 0x3f, 0xee, 0xf5, 0x89, 0x6b, 0x73, 0xfa, 0xf6, 0xfe, 0xe3, 0xe9, 0xd4, 0x8f, 0x56, 0x07, 0x8f, 0x11, 0x40, 0x9f, 0xbf, 0x1c, 0x4b, 0x26, 0x45, 0x58, 0x32, 0xf6, 0x9b, 0xfa, 0x34, 0x61, 0x9f, 0x45, 0x18, 0x45, 0xad, 0xd9, 0x8f, 0xa3, 0x8a, 0x3a, 0x81, 0x66, 0xd4, 0x3e, 0x2e, 0xb4, 0xa0, 0x88, 0x71, 0x7f, 0xfa, 0x21, 0xcb, 0xd7, 0xa6, 0x8d, 0x11, 0x2a, 0xf6, 0xe1, 0x90, 0x40, 0x7b, 0xa7, 0x34, 0x04, 0x3d, 0x85, 0x45, 0x14, 0x01, 0xac, 0x30, 0x51, 0xcb, 0x5e, 0x72, 0xbe, 0xcd, 0x86, 0xd5, 0x58, 0x1f, 0x58, 0x32, 0xcb, 0x6b, 0xd2, 0x1a, 0xde, 0x25, 0x18, 0x2a, 0x0c, 0x82, 0x35, 0x3c, 0xee, 0x78, 0x40, 0x22, 0xfd, 0xb5, 0x07, 0x79, 0x7f, 0xc1, 0x83, 0x0a, 0xb1, 0x26, 0x69, 0x3f, 0xb1, 0x48, 0x06, 0xf3, 0x0e, 0x57, 0x2b, 0x37, 0x5a, 0x44, 0x0f, 0x74, 0x10, 0x03, 0xe8, 0xf8, 0x4d, 0xb8, 0x5c, 0x7a, 0x35, 0x09, 0x85, 0x60, 0x69, 0x8e, 0xb6, 0x58, 0x1b, 0x56, 0xcd, 0x1e, 0xee, 0xe8, 0x3a, 0x0d, 0x8d, 0xc8, 0x95, 0x08, 0x6e, 0x51, 0x65, 0xa4, 0xe8, 0xc5, 0xbd, 0xa1, 0x15, 0x2d, 0x3e, 0x18, 0xb3, 0x3f, 0x3e, 0xcd, 0xe1, 0x64, 0x02, 0x11, 0x38, 0xf4, 0x66, 0x96, 0x38, 0x19, 0x25, 0xe6, 0x66, 0x39, 0x34, 0x51, 0xbd, 0xb2, 0xe4, 0xed, 0x71, 0x41, 0x80, 0x8f, 0x04, 0x35, 0xa8, 0x97, 0x39, 0x72, 0x4a, 0xc1, 0xf0, 0x4c, 0xf8, 0x28, 0x15, 0xcb, 0xc1, 0x82, 0x4f, 0x9a, 0xa7, 0x54, 0xb6, 0x42, 0x6b, 0xfb, 0x56, 0xb5, 0x3d, 0xcf, 0xab, 0x0d, 0x00, 0xb0, 0xc7, 0x2e, 0x5b, 0xf0, 0xa1, 0xe4, 0x9c, 0xd8, 0xc0, 0xca, 0x4f, 0x36, 0x85, 0x02, 0x54, 0x2b, 0x30, 0x75, 0xf0, 0x83, 0xb6, 0x68, 0x51, 0x11, 0xe6, 0xef, 0xb9, 0x7c, 0xaa, 0x5c, 0x54, 0xd0, 0x34, 0xa2, 0x84, 0x61, 0xf0, 0x13, 0xd1, 0x3a, 0x1b, 0xf7, 0xbd, 0x6a, 0xe0, 0x72, 0xdf, 0x48, 0x59, 0xf5, 0x8e, 0x6d, 0x93, 0xd4, 0x37, 0x39, 0xa9, 0x7d, 0xdb, 0xb8, 0x0b, 0x79, 0xed, 0x71, 0x1d, 0x60, 0x5d, 0x72, 0xda, 0x8b, 0x17, 0x68, 0x93, 0x1f, 0xa7, 0x3b, 0x18, 0x30, 0x76, 0xf0, 0x4a, 0x1c, 0xbf, 0x1d, 0x22, 0xc3, 0x3e, 0x69, 0x3f, 0xf5, 0x96, 0x9c, 0x5d, 0xf6, 0x41, 0x0e, 0x23, 0x69, 0x8b, 0xa6, 0x75, 0x5a, 0x0b, 0xa4, 0x77, 0x85, 0x4d, 0x3d, 0xee, 0x25, 0x83, 0xd9, 0x88, 0xe1, 0x15, 0x6b, 0x97, 0xe9, 0x8b, 0x87, 0x66, 0x30, 0xc7, 0x52, 0x43, 0xd4, 0x10, 0x9a, 0x3f, 0x3c, 0x76, 0x69, 0x53, 0x50, 0xee, 0x4b, 0xf6, 0xe9, 0x9e, 0x0f, 0x76, 0x66, 0xc7, 0xc7, 0x06, 0xfb, 0xcd, 0xa0, 0xd4, 0x53, 0x4a, 0x2c, 0x4f, 0x09, 0x42, 0x2b, 0xcc, 0x06, 0x8e, 0xcc, 0x74, 0x36, 0xaa, 0xa2, 0x8f, 0xee, 0x0f, 0xc1, 0x35, 0x6f, 0xe8, 0x77, 0xa3, 0xde, 0xfc, 0xf2, 0x2e, 0x42, 0xb1, 0xb9, 0x0c, 0x7b, 0x95, 0x17, 0xbb, 0x9d, 0xf5, 0x7f, 0xa5, 0xfd, 0x3e, 0x2a, 0x5b, 0xab, 0x4e, 0x36, 0x8d, 0x46, 0x0b, 0x67, 0xf6, 0xba, 0xa2, 0x3c, 0x98, 0x84, 0xe0, 0x99, 0x55, 0x65, 0x15, 0x61, 0x70, 0x14, 0xd2, 0x79, 0x12, 0x10, 0xba, 0x19, 0xc6, 0x5a, 0x56, 0xf7, 0x5d, 0x34, 0x85, 0x69, 0x87, 0xec, 0x42, 0xef, 0xc5, 0xd1, 0x34, 0x66, 0x64, 0xf2, 0x53, 0x4b, 0x76, 0x37, 0x00, 0x53, 0xdb, 0x14, 0x46, 0x48, 0xfe, 0x45, 0xfb, 0x0a, 0x13, 0x66, 0xfb, 0x51, 0x36, 0xc5, 0xd6, 0xea, 0x83, 0x71, 0x05, 0x1b, 0x91, 0x9d, 0x7d, 0x7d, 0x5f, 0x47, 0xd0, 0x15, 0xaa, 0x71, 0x48, 0x0b, 0x77, 0x67, 0x17, 0xa6, 0x0d, 0xf1, 0x2b, 0xc5, 0x58, 0x2e, 0x53, 0x8c, 0x07, 0xf2, 0x71, 0x87, 0x94, 0x83, 0xb3, 0xa3, 0x39, 0x5f, 0x35, 0x58, 0x30, 0xfb, 0xfb, 0x9d, 0x9d, 0x1a, 0x18, 0x3d, 0x84, 0x2d, 0xc1, 0xb8, 0x57, 0x8c, 0x2e, 0xe0, 0x01, 0x14, 0x37, 0xa9, 0x6f, 0x64, 0x1f, 0x09, 0x75, 0x65, 0x78, 0x30, 0x7c, 0x70, 0x09, 0xf5, 0x3a, 0xe6, 0xb8, 0xb0, 0x86, 0x68, 0xcf, 0x23, 0xf8, 0xfd, 0xfc, 0x3e, 0xe4, 0x94, 0xeb, 0x21, 0x2d, 0x4d, 0x5b, 0x31, 0xbc, 0xa8, 0xf4, 0x74, 0xf6, 0x41, 0x70, 0x54, 0x54, 0x66, 0xb0, 0x4e, 0x82, 0x7f, 0x77, 0xb3, 0xb3, 0x36, 0xd1, 0x40, 0x40, 0xfb, 0xf6, 0x34, 0xc1, 0x63, 0x7b, 0xa7, 0x2d, 0xde, 0x70, 0x1f, 0xe6, 0x9c, 0xdc, 0x0b, 0x77, 0x78, 0x3e, 0x3e, 0x96, 0x48, 0x14, 0xfc, 0x97, 0x47, 0x95, 0x9a, 0x76, 0xe4, 0xcf, 0x1a, 0x85, 0x50, 0xbe, 0x38, 0x78, 0xe8, 0x6a, 0x90, 0xb6, 0xe2, 0x1b, 0x89, 0x64, 0xb8, 0x29, 0x4b, 0x95, 0xe1, 0x22, 0x75, 0x29, 0xad, 0x48, 0xb3, 0x5f, 0x60, 0x83, 0xd9, 0xf6, 0x62, 0xa8, 0x25, 0x12, 0x2a, 0xa5, 0xb0, 0xb4, 0xe6, 0x96, 0x9f, 0x0d, 0xbe, 0x61, 0x2e, 0x53, 0x1a, 0x16, 0x70, 0x42, 0x0d, 0x36, 0x1a, 0x3e, 0x63, 0xc3, 0x41, 0x32, 0xed, 0x71, 0x6d, 0x55, 0x1f, 0xc6, 0xc0, 0x19, 0x22, 0x01, 0x05, 0x54, 0x86, 0x2a, 0x22, 0x4d, 0xa6, 0x71, 0x3c, 0x81, 0xd2, 0x88, 0x0d, 0x6e, 0xaf, 0xba, 0xfe, 0x7c, 0x82, 0xe6, 0x08, 0xe9, 0x0a, 0x0f, 0xa6, 0x22, 0x17, 0xac, 0x54, 0xd7, 0x1e, 0xe0, 0xa0, 0x6c, 0xa6, 0x9c, 0x71, 0xbb, 0x0e, 0xac, 0x22, 0x04, 0x86, 0xc0, 0x9a, 0x91, 0x3b, 0x13, 0xac, 0xec, 0x1a, 0x0f, 0x4a, 0x92, 0xd9, 0x48, 0xe5, 0x5d, 0x7a, 0x5b, 0xbc, 0xec, 0x37, 0xb3, 0x35, 0x91, 0x1b, 0x3a, 0x7a, 0xfa, 0xd1, 0xcf, 0x36, 0x43, 0xef, 0x8b, 0xef, 0x56, 0xe8, 0xa0, 0x4a, 0x26, 0x28, 0xb6, 0xf3, 0x79, 0x94, 0x52, 0xf4, 0x55, 0xe3, 0x53, 0xf7, 0xd6, 0x31, 0x87, 0x53, 0x26, 0x3a, 0x55, 0xf9, 0x6f, 0x17, 0x0b, 0xb3, 0x74, 0xa4, 0x6c, 0x31, 0x28, 0x39, 0x21, 0x55, 0x3f, 0x3a, 0xa8, 0x65, 0xfc, 0x64, 0x8c, 0x31, 0xde, 0x48, 0x2f, 0xc0, 0x9c, 0x49, 0xbd, 0x27, 0xec, 0x59, 0xaa, 0xc7, 0x26, 0xca, 0x3e, 0xe3, 0xa1, 0x5b, 0x2c, 0x13, 0x98, 0x79, 0x04, 0x54, 0xd7, 0xd3, 0x46, 0x5a, 0x73, 0xfe, 0x4c, 0x60, 0xf6, 0x4a, 0xff, 0x66, 0x9a, 0x4f, 0x6b, 0xd1, 0x29, 0x12, 0xca, 0x22, 0x8c, 0x45, 0x0d, 0xe9, 0x9c, 0xfc, 0x65, 0x75, 0xd8, 0x11, 0x89, 0x13, 0xb0, 0x2f, 0xf7, 0xa1, 0xc7, 0x23, 0xdf, 0xdc, 0x0e, 0x9a, 0xc8, 0xb5, 0x30, 0xe9, 0x0f, 0x6f, 0x8c, 0xfe, 0x76, 0x14, 0xcf, 0x7b, 0x6a, 0x4b, 0xce, 0xec, 0x25, 0xba, 0x94, 0xdd, 0xee, 0x14, 0x55, 0x3b, 0xb8, 0x3c, 0xf6, 0xf4, 0xa2, 0x18, 0x19, 0x5a, 0x38, 0x61, 0xf9, 0x72, 0x50, 0xa0, 0x2d, 0x2c, 0x43, 0xb4, 0xe7, 0x9b, 0xec, 0x6f, 0x3e, 0x05, 0x82, 0x8d, 0xbe, 0xd8, 0xcb, 0x4e, 0x51, 0x1a, 0x84, 0x2c, 0xa1, 0xa7, 0xd8, 0x53, 0xc5, 0xd7, 0x41, 0x57, 0x25, 0x73, 0x99, 0x40, 0x46, 0xde, 0x91, 0xbe, 0x33, 0xb6, 0x32, 0x99, 0xe5, 0xc7, 0xef, 0x61, 0x45, 0x78, 0xba, 0xdf, 0x63, 0x77, 0x66, 0x1c, 0x01, 0x3f, 0x95, 0x12, 0x78, 0x0d, 0xfa, 0xa6, 0x0b, 0x6f, 0xd6, 0x35, 0x02, 0xf9, 0x50, 0x20, 0x88, 0xa7, 0x96, 0x98, 0x9d, 0xc1, 0xf5, 0x56, 0xb3, 0xb0, 0x85, 0x75, 0x4a, 0x4d, 0x98, 0x82, 0xd2, 0xda, 0x8d, 0x5e, 0x51, 0x7f, 0xef, 0x90, 0x4c, 0xd5, 0x51, 0xdd, 0x63, 0x31, 0x95, 0xe8, 0xa3, 0x48, 0x8a, 0xdc, 0xb9, 0x7a, 0xc6, 0xa9, 0x37, 0x2b, 0x52, 0xc5, 0xdb, 0xdc, 0x81, 0x23, 0x90, 0xff, 0xd4, 0xb6, 0x81, 0x4e, 0x9e, 0x83, 0xfb, 0xd3, 0x0d, 0xc4, 0x50, 0x44, 0x40, 0xf5, 0x54, 0xa0, 0x1e, 0x91, 0x9e, 0xc4, 0xb6, 0x2b, 0xc6, 0x4a, 0xaf, 0x12, 0x42, 0x5c, 0xd1, 0xda, 0xfb, 0x80, 0x80, 0x65, 0xd2, 0x1c, 0x2e, 0x02, 0xfd, 0xe3, 0x15, 0xb8, 0xe1, 0xee, 0xd0, 0xa3, 0xfa, 0x8d, 0x2f, 0x84, 0x29, 0x37, 0x28, 0x0a, 0x3f, 0x74, 0x68, 0x02, 0xea, 0x31, 0xa2, 0xf8, 0xd8, 0x1c, 0xff, 0x1b, 0x71, 0x5f, 0x0e, 0x37, 0x4c, 0x2a, 0xd8, 0x76, 0x3f, 0x12, 0xc1, 0x91, 0xc8, 0x5d, 0xb7, 0x17, 0xe6, 0xee, 0xaa, 0xe9, 0x66, 0xe0, 0x82, 0xcc, 0x7e, 0xf6, 0x4c, 0xe3, 0xaf, 0x38, 0xa4, 0x31, 0xb9, 0x57, 0x42, 0x1a, 0x70, 0x70, 0x41, 0xa3, 0x4f, 0x70, 0x46, 0xc7, 0x74, 0xa0, 0xd9, 0x82, 0x3b, 0x15, 0xf1, 0x9e, 0x70, 0xe2, 0xb0, 0x03, 0x81, 0x25, 0xa1, 0x22, 0xd7, 0x83, 0x43, 0x5f, 0xd8, 0x31, 0xf2, 0x2f, 0x0e, 0xc4, 0xf3, 0x9f, 0xd6, 0xd1, 0xcd, 0xf0, 0xfd, 0x1f, 0x89, 0x9a, 0x32, 0x26, 0x7b, 0x44, 0x51, 0xfe, 0xf5, 0xe9, 0xca, 0x05, 0x91, 0x92, 0x67, 0xf0, 0x41, 0xc5, 0x48, 0xc3, 0x3e, 0x94, 0xcc, 0x55, 0xad, 0x9e, 0x92, 0x06, 0x57, 0xc9, 0x8c, 0xf9, 0xc6, 0x98, 0x91, 0xa8, 0x4c, 0xa6, 0x9e, 0xa1, 0x1e, 0x4b, 0x93, 0x49, 0xc3, 0xf8, 0x43, 0x0d, 0x92, 0x94, 0xcb, 0x37, 0x07, 0xe7, 0x98, 0x62, 0x02, 0xda, 0x68, 0xd0, 0x89, 0x8a, 0xbd, 0xc9, 0x4e, 0x35, 0x74, 0x58, 0xb0, 0x8a, 0xe7, 0x6f, 0xe0, 0xd1, 0x55, 0x95, 0x9b, 0xd2, 0xee, 0x70, 0x61, 0xd2, 0x0c, 0x79, 0x66, 0x17, 0x30, 0xcd, 0x95, 0x7b, 0x3e, 0x5b, 0x0d, 0x2d, 0x5a, 0x4c, 0x5f, 0x76, 0x6b, 0xee, 0x40, 0xd3, 0x04, 0xfe, 0x0a, 0x96, 0xa5, 0xfe, 0x34, 0x3d, 0xdc, 0xa4, 0x72, 0xb5, 0xe1, 0x13, 0xb5, 0x9e, 0x88, 0x80, 0x42, 0xb9, 0x09, 0xf5, 0xbe, 0x44, 0xd3, 0xd5, 0x8e, 0xa2, 0xce, 0xfe, 0x93, 0x34, 0x66, 0x48, 0xad, 0x75, 0xbf, 0xf7, 0xd6, 0xc4, 0x0c, 0xab, 0x3a, 0xa4, 0x50, 0x2c, 0x5b, 0x5e, 0x18, 0xf0, 0x90, 0x34, 0x79, 0x15, 0x40, 0x4b, 0x95, 0x59, 0x6f, 0xfa, 0x7c, 0x6e, 0xb6, 0x08, 0x49, 0xb5, 0xec, 0x3f, 0xdf, 0xc6, 0x67, 0xb1, 0x25, 0x98, 0x60, 0xf9, 0x14, 0xa6, 0x59, 0x7c, 0x4b, 0xd4, 0x7c, 0x7f, 0xa1, 0xcc, 0xe2, 0xef, 0x10, 0x8a, 0x11, 0xde, 0xd5, 0xf7, 0x7d, 0xc9, 0xd4, 0x99, 0xb0, 0xa9, 0xeb, 0xf1, 0x6e, 0x4e, 0x9f, 0xee, 0x31, 0xbe, 0xa8, 0x11, 0x65, 0xc2, 0x90, 0x91, 0x1e, 0x4c, 0x97, 0xae, 0x15, 0x58, 0xa0, 0x13, 0xd6, 0xe1, 0x1c, 0x44, 0x85, 0xb6, 0x52, 0x87, 0xfa, 0xb1, 0x67, 0xa1, 0x7b, 0x20, 0x6f, 0x87, 0x32, 0xf8, 0x74, 0xfc, 0x4d, 0xab, 0x6e, 0x46, 0x4a, 0xf2, 0x25, 0x10, 0xc4, 0xef, 0xa5, 0x80, 0x80, 0x29, 0xb5, 0x36, 0x49, 0xe3, 0x8b, 0xc4, 0x8f, 0xed, 0xef, 0x55, 0xa6, 0x1d, 0x11, 0x9a, 0x38, 0x31, 0x42, 0x42, 0xad, 0x33, 0x3f, 0x94, 0xd5, 0x12, 0x05, 0x7f, 0x5d, 0x38, 0xde, 0xec, 0x0b, 0xf1, 0x90, 0x7e, 0xd7, 0x0a, 0xa6, 0x1f, 0x52, 0x78, 0x52, 0x2c, 0xb4, 0xd4, 0x8d, 0x34, 0x24, 0x2c, 0x18, 0x93, 0x01, 0x8a, 0x9a, 0x05, 0x36, 0x2f, 0x75, 0xf5, 0xe2, 0x1d, 0x91, 0xe5, 0x5a, 0x22, 0x15, 0xd5, 0x28, 0x59, 0x6f, 0x57, 0x99, 0x85, 0x7e, 0x48, 0x56, 0x72, 0xe1, 0x85, 0xd6, 0x47, 0xfc, 0xfd, 0xae, 0x72, 0x64, 0x16, 0x98, 0xf5, 0xae, 0xa1, 0x8c, 0x79, 0x7a, 0x65, 0x89, 0x1a, 0xaf, 0x7a, 0x3c, 0x9a, 0xa9, 0x28, 0x48, 0xe4, 0x19, 0x83, 0x0f, 0xaa, 0x53, 0xc0, 0x05, 0x7a, 0xd4, 0x7d, 0x1a, 0x81, 0xa7, 0xc0, 0x8d, 0x9e, 0xd0, 0x28, 0xdc, 0x00, 0xbb, 0x10, 0x49, 0x12, 0x01, 0x19, 0x3f, 0xa1, 0xa5, 0x24, 0xeb, 0x2b, 0x34, 0x9d, 0x5d, 0x28, 0x49, 0x88, 0x67, 0xd1, 0x84, 0x06, 0x2a, 0x6e, 0xfe, 0x34, 0x90, 0x0d, 0xbf, 0x0f, 0x19, 0xca, 0x6f, 0xe3, 0x4a, 0x74, 0xcf, 0xe2, 0x2e, 0xc0, 0xb8, 0xbf, 0x89, 0x90, 0xf3, 0x79, 0xdb, 0x4f, 0xba, 0x99, 0x37, 0xaa, 0x28, 0x24, 0x47, 0x22, 0xa0, 0xaf, 0xcd, 0xad, 0x4c, 0xf4, 0xec, 0x90, 0xbf, 0x3d, 0xf3, 0x03, 0x57, 0xb8, 0x79, 0xdf, 0xcf, 0x1c, 0x00, 0x62, 0xaa, 0x18, 0xa1, 0x25, 0xf5, 0xce, 0x96, 0x1a, 0x9d, 0x9a, 0x71, 0x2d, 0xf1, 0x0e, 0x83, 0x0b, 0x7a, 0xb5, 0xfc, 0xc2, 0x5a, 0x64, 0xe4, 0x6c, 0x3e, 0x9f, 0xec, 0x79, 0x9b, 0xc0, 0x1c, 0xc1, 0x71, 0xee, 0x03, 0xe1, 0xc5, 0xbf, 0xc4, 0x11, 0x8e, 0xc1, 0x44, 0x62, 0x58, 0xdf, 0xd4, 0x27, 0x86, 0x1d, 0x52, 0xd7, 0x79, 0xc9, 0xec, 0xaa, 0xd0, 0xe3, 0xcb, 0x14, 0x8a, 0x6f, 0xf9, 0x00, 0x44, 0x3c, 0xac, 0x5c, 0x97, 0xc6, 0xc8, 0x90, 0xb9, 0x35, 0x7b, 0xfe, 0x78, 0xc9, 0x7c, 0x2a, 0xcb, 0xcb, 0xaf, 0x66, 0xbb, 0xd9, 0x5d, 0x15, 0xa9, 0x07, 0x4e, 0xb6, 0xbe, 0x8a, 0xc7, 0xc7, 0xee, 0x1a, 0x27, 0x4d, 0x37, 0x5a, 0x94, 0xdc, 0x08, 0xb8, 0x39, 0xcc, 0x27, 0xac, 0x12, 0xe3, 0x52, 0x81, 0x5d, 0xd1, 0x02, 0xfa, 0xe9, 0xdc, 0x58, 0xcb, 0x02, 0x49, 0xcf, 0xad, 0x5b, 0xd3, 0x67, 0xc7, 0xc5, 0xeb, 0x18, 0xe9, 0x12, 0x2f, 0x35, 0xda, 0x89, 0x67, 0x15, 0x02, 0x0e, 0x55, 0x44, 0xd7, 0x02, 0x47, 0x8c, 0xac, 0x66, 0x73, 0x0c, 0x67, 0xbe, 0xe1, 0x72, 0xf5, 0xa7, 0xd2, 0x94, 0x64, 0x5d, 0x5c, 0x0a, 0xe2, 0x14, 0xc7, 0x4f, 0x77, 0xb1, 0xed, 0x36, 0x53, 0xca, 0xb9, 0xbe, 0x90, 0x35, 0x3f, 0x00, 0x29, 0x2d, 0x38, 0xb7, 0x13, 0xad, 0x68, 0x33, 0x9c, 0x56, 0x15, 0x2e, 0xd5, 0x04, 0x82, 0x63, 0x2b, 0x5b, 0xfa, 0x9a, 0x0d, 0xa6, 0x31, 0x50, 0x2e, 0x3d, 0x62, 0xb1, 0x5c, 0x88, 0xe2, 0x9c, 0x5c, 0xd9, 0xf9, 0x82, 0xa2, 0x2c, 0xfb, 0x3b, 0x60, 0x45, 0xdf, 0x8e, 0x14, 0x05, 0x5d, 0xbf, 0xda, 0x9f, 0x0e, 0xfb, 0x05, 0x03, 0x7d, 0x71, 0x6c, 0xf9, 0xe0, 0xc3, 0xc0, 0x4a, 0x18, 0x47, 0x53, 0xcd, 0x4f, 0x16, 0x96, 0x10, 0xf7, 0xa7, 0xdf, 0x82, 0x44, 0xff, 0x49, 0xd3, 0xb7, 0x5e, 0xdc, 0x4f, 0x18, 0xb9, 0x57, 0x3b, 0x35, 0xdd, 0x88, 0xe5, 0x44, 0x73, 0x5f, 0x78, 0x12, 0x30, 0x7c, 0x01, 0x14, 0x9f, 0x0d, 0x2c, 0xe8, 0x9b, 0x30, 0x21, 0xe8, 0x8f, 0x16, 0x3a, 0x67, 0x8f, 0x27, 0x3e, 0xbe, 0x8e, 0xd4, 0xfa, 0x7a, 0x20, 0xf4, 0xd9, 0x01, 0x41, 0xcb, 0x10, 0x2b, 0xc5, 0xd7, 0x9e, 0x07, 0xa8, 0xbd, 0x94, 0x6f, 0x34, 0x02, 0x44, 0x3a, 0x76, 0xbe, 0xfa, 0x5f, 0xff, 0x32, 0x1c, 0xcd, 0x66, 0xf5, 0x8d, 0xc1, 0x4c, 0xb6, 0x7d, 0x97, 0x16, 0xdb, 0xa6, 0x49, 0x49, 0x01, 0xc0, 0x56, 0x13, 0xb1, 0xc4, 0xa2, 0xb8, 0x31, 0xce, 0xdc, 0x61, 0x07, 0x35, 0xe9, 0x07, 0xb2, 0x99, 0xa3, 0xdc, 0x07, 0x31, 0x2e, 0xa6, 0x76, 0xfb, 0x67, 0x22, 0x33, 0x99, 0x76, 0x11, 0x5b, 0xc1, 0x90, 0xc5, 0xd6, 0x6e, 0x42, 0x33, 0x38, 0x5d, 0x6f, 0x47, 0xce, 0xec, 0x15, 0xd7, 0x0d, 0x31, 0xe2, 0xae, 0x47, 0x7f, 0xad, 0x6b, 0xfd, 0x1c, 0x07, 0x70, 0xec, 0xc2, 0x95, 0xa9, 0x03, 0xc3, 0x39, 0x84, 0x1e, 0xe6, 0xc4, 0xf4, 0x5f, 0xd9, 0x4b, 0xf6, 0x35, 0x48, 0x72, 0x82, 0x5a, 0xe8, 0x63, 0x21, 0x51, 0x9c, 0x88, 0x90, 0x73, 0x13, 0x3c, 0x7a, 0x13, 0xdd, 0x19, 0x97, 0x84, 0xc5, 0x36, 0x7e, 0x7d, 0xeb, 0xa0, 0xd4, 0x23, 0xa0, 0xd1, 0xae, 0x44, 0x0f, 0x7b, 0x9e, 0xdf, 0x3f, 0x56, 0x00, 0x79, 0x87, 0xc7, 0x24, 0x11, 0x47, 0x74, 0x63, 0x65, 0x60, 0x2d, 0x41, 0xc8, 0x4f, 0x8b, 0x81, 0xfb, 0xf6, 0xad, 0x4c, 0x4d, 0x82, 0x8b, 0xe8, 0x83, 0x49, 0xc2, 0x93, 0x4e, 0x75, 0xe7, 0xd2, 0xe1, 0x2b, 0xee, 0x75, 0x57, 0x00, 0xcd, 0x3f, 0xd7, 0xf3, 0xbf, 0xf1, 0xb4, 0x8a, 0xae, 0xd1, 0x0f, 0x0a, 0x8b, 0xe6, 0x81, 0xe6, 0x66, 0xf9, 0x32, 0x25, 0x4d, 0x75, 0xa3, 0xd0, 0xe5, 0x8d, 0x6d, 0x83, 0xf1, 0xea, 0x61, 0xf2, 0xdf, 0x0b, 0xad, 0xd8, 0x9f, 0x19, 0xfd, 0xcb, 0x1a, 0x84, 0x0f, 0x63, 0x15, 0x0c, 0xe0, 0x7f, 0x5d, 0x52, 0x2d, 0xb9, 0x1b, 0x59, 0x5c, 0x18, 0x35, 0x67, 0x83, 0x71, 0xa6, 0x7e, 0xcc, 0x27, 0x49, 0x1e, 0x28, 0x34, 0x79, 0x1a, 0x93, 0x0c, 0xea, 0x8f, 0x51, 0x7c, 0x69, 0x6a, 0x7b, 0xa5, 0x96, 0x67, 0x45, 0x61, 0x38, 0xf2, 0x6a, 0xad, 0xb7, 0xf3, 0xf1, 0x12, 0x0f, 0x74, 0x0c, 0x3a, 0xb3, 0xbe, 0x4a, 0xb3, 0x93, 0xa4, 0xdb, 0x24, 0xe8, 0x01, 0x17, 0xb5, 0x19, 0x3d, 0x2b, 0xfa, 0x24, 0x1b, 0xf8, 0x61, 0x5f, 0x61, 0x0c, 0xb4, 0xf6, 0x50, 0x53, 0x21, 0x81, 0x00, 0xdd, 0x28, 0xf8, 0x59, 0x41, 0xec, 0x2f, 0x74, 0xb9, 0xb5, 0x8a, 0x00, 0xe7, 0x11, 0x4b, 0xe6, 0x2c, 0x8d, 0x29, 0x74, 0x5b, 0x09, 0xfb, 0xc9, 0x5a, 0xb2, 0x27, 0x8c, 0x02, 0x68, 0xb0, 0xcf, 0xa4, 0x23, 0xd9, 0xbc, 0x17, 0x9c, 0x45, 0x88, 0x70, 0x13, 0x21, 0xba, 0x79, 0x78, 0xf4, 0xe0, 0x5a, 0xf6, 0x01, 0x25, 0xab, 0x18, 0xd8, 0xf2, 0xcd, 0xf4, 0x75, 0x96, 0xac, 0xb7, 0x76, 0x4e, 0x30, 0x9b, 0x23, 0x33, 0xe1, 0x87, 0x66, 0x51, 0x1a, 0x7b, 0x1b, 0x4f, 0xa1, 0xb2, 0x77, 0xe1, 0x00, 0x7d, 0xcb, 0x70, 0x45, 0xbc, 0xc4, 0xa8, 0x85, 0xb8, 0xe5, 0x37, 0x0a, 0x6f, 0xc7, 0xec, 0xd7, 0xe6, 0xc4, 0xeb, 0x6f, 0x90, 0xef, 0x6a, 0x65, 0xef, 0xd4, 0x74, 0x3c, 0x5d, 0x76, 0xc8, 0xba, 0x66, 0x15, 0x0d, 0x22, 0x1f, 0x95, 0x16, 0x2f, 0x8e, 0x59, 0x8d, 0xea, 0x31, 0x07, 0x84, 0x06, 0xeb, 0x5e, 0xc9, 0xb8, 0x4d, 0xfe, 0x4c, 0x58, 0x59, 0xae, 0x06, 0xc9, 0xd3, 0x80, 0x8d, 0xb1, 0x90, 0xd9, 0x42, 0x1d, 0x4d, 0x0b, 0xf7, 0xa4, 0xa5, 0x4b, 0x69, 0x5b, 0xb4, 0x9e, 0xed, 0x37, 0x93, 0xdc, 0x32, 0x77, 0x4d, 0x21, 0x5e, 0xde, 0x96, 0x78, 0xb4, 0xcc, 0xfa, 0x8a, 0x3b, 0x45, 0x19, 0x06, 0x7f, 0x44, 0x34, 0x21, 0x2a, 0xf7, 0x1b, 0x28, 0x30, 0xf7, 0x46, 0x05, 0x8b, 0x3f, 0xbe, 0x79, 0xaf, 0xfd, 0xf7, 0xbb, 0x79, 0x4d, 0x2d, 0x35, 0x1e, 0x07, 0xbf, 0x92, 0xb8, 0xae, 0xaa, 0x92, 0x6f, 0xd2, 0x46, 0xbc, 0x76, 0xa8, 0x16, 0x21, 0x2f, 0x27, 0x78, 0x35, 0xf4, 0xdb, 0x76, 0x31, 0x2a, 0x0d, 0x19, 0xff, 0x29, 0xf3, 0xbc, 0x58, 0x73, 0xd9, 0x50, 0x70, 0xfc, 0x35, 0xaa, 0xf2, 0xef, 0x14, 0xb5, 0x1f, 0x72, 0x02, 0xf3, 0x36, 0x7e, 0x4c, 0xe5, 0x9b, 0x09, 0x0a, 0xa4, 0x73, 0xbf, 0xb3, 0x7e, 0x2c, 0x26, 0x6f, 0x99, 0x6d, 0x9f, 0x09, 0x7f, 0xf7, 0xc7, 0x7c, 0x2a, 0x7c, 0x2f, 0xef, 0x48, 0x3a, 0xce, 0x97, 0x7f, 0x97, 0x81, 0x08, 0x0f, 0xd9, 0x29, 0xc4, 0xa6, 0x4a, 0xab, 0x23, 0x19, 0x27, 0xdf, 0xfc, 0xa8, 0x19, 0x08, 0xbc, 0xa8, 0xc7, 0x7f, 0xfb, 0x58, 0x3f, 0x2c, 0x0a, 0x6e, 0x2a, 0xca, 0x5d, 0xf6, 0xd2, 0x5c, 0x39, 0xb4, 0xe0, 0x8d, 0x90, 0xac, 0xb8, 0x5b, 0xa9, 0x40, 0xca, 0x1e, 0x30, 0x1e, 0x69, 0xfd, 0x4f, 0x29, 0x90, 0x05, 0xf2, 0x82, 0x63, 0x4e, 0xbb, 0x47, 0x0b, 0x37, 0x54, 0x58, 0x87, 0x71, 0xab, 0xe9, 0x89, 0xbc, 0xa8, 0x53, 0xfe, 0x72, 0x82, 0x91, 0x49, 0x6d, 0x20, 0x76, 0xb8, 0x28, 0xb8, 0xc0, 0xd0, 0xdf, 0xd0, 0xfe, 0xff, 0x19, 0xa7, 0x4f, 0xa9, 0x15, 0x72, 0x1b, 0xf3, 0x11, 0xd9, 0x61, 0x67, 0x30, 0xe2, 0xb6, 0x7b, 0x17, 0x21, 0x6b, 0xca, 0x23, 0x0d, 0xfe, 0xac, 0x3c, 0x43, 0xb4, 0xb0, 0x38, 0xef, 0x0e, 0x32, 0x79, 0x1d, 0x4f, 0x37, 0xe8, 0xf3, 0x1d, 0xd7, 0xfb, 0xda, 0x4c, 0xcf, 0x74, 0xbb, 0xda, 0xa3, 0x44, 0x0d, 0x4f, 0x28, 0x19, 0x11, 0x1c, 0x75, 0x69, 0xf3, 0x6d, 0x66, 0x58, 0x86, 0xdc, 0xd6, 0xb8, 0x75, 0x9d, 0x39, 0xa2, 0xb6, 0xd6, 0xe7, 0x5f, 0x28, 0x2a, 0xe4, 0x85, 0xf9, 0xc3, 0x67, 0x43, 0xec, 0x9e, 0xef, 0x09, 0xa1, 0x00, 0xf2, 0x1a, 0xb2, 0xb3, 0x01, 0xe8, 0xb8, 0x66, 0xde, 0xf2, 0x6f, 0x18, 0x02, 0xe4, 0x0d, 0x80, 0x4f, 0xdd, 0xcc, 0x8d, 0x80, 0xfa, 0xef, 0x9f, 0xdc, 0xe0, 0x7d, 0xea, 0x3b, 0x41, 0x2b, 0x13, 0x7c, 0x45, 0x07, 0x11, 0xa9, 0xae, 0x5f, 0x1e, 0x9b, 0xa1, 0x20, 0x3a, 0xfe, 0x09, 0x92, 0xae, 0x29, 0x8f, 0xa5, 0x17, 0x80, 0x84, 0x2c, 0x95, 0xa7, 0xf2, 0x70, 0xcb, 0x6f, 0x68, 0x53, 0x2a, 0xa3, 0xde, 0x2a, 0xaf, 0xd5, 0x53, 0x1c, 0x8d, 0xf4, 0xda, 0xe5, 0xc1, 0x32, 0xbc, 0x1b, 0x7e, 0xcb, 0x4f, 0x54, 0x7c, 0x94, 0x15, 0xe1, 0x91, 0x91, 0x9a, 0x0b, 0xe6, 0xe7, 0xad, 0xf0, 0xd7, 0x7a, 0xf2, 0x14, 0x2f, 0x84, 0x01, 0x06, 0xca, 0x5a, 0x67, 0x8f, 0xfa, 0x40, 0x84, 0x48, 0xd6, 0x2d, 0xbc, 0x04, 0x93, 0x07, 0x34, 0x1b, 0xf2, 0xc9, 0x8d, 0xe4, 0x10, 0xc9, 0x8b, 0xd1, 0x24, 0x27, 0xf4, 0x2d, 0xff, 0xc1, 0x1f, 0x9e, 0x8e, 0xac, 0xf7, 0xb8, 0xcd, 0x03, 0xc0, 0x0d, 0x7b, 0xec, 0x8c, 0x75, 0x86, 0x73, 0x71, 0x0a, 0xb4, 0xe7, 0x38, 0xb7, 0x2b, 0xb0, 0xac, 0x7b, 0x83, 0x46, 0xeb, 0xb4, 0x12, 0x52, 0x90, 0xb7, 0x51, 0x4b, 0x8f, 0xa9, 0xad, 0x2b, 0x47, 0x16, 0x82, 0xee, 0x68, 0x92, 0x58, 0x33, 0xd4, 0xef, 0xed, 0xe0, 0xf8, 0x5b, 0x32, 0x9b, 0x0c, 0xe1, 0x80, 0x99, 0x48, 0x42, 0x95, 0xb0, 0x32, 0x7d, 0x25, 0x94, 0x2c, 0x77, 0xbf, 0x46, 0x65, 0x34, 0x0f, 0x23, 0x59, 0x87, 0xfe, 0x09, 0xca, 0x3a, 0x2f, 0x9c, 0x09, 0x87, 0x03, 0xa7, 0x72, 0x8d, 0x24, 0x87, 0x1d, 0xd3, 0x9b, 0x88, 0x80, 0x14, 0xe3, 0x12, 0x27, 0x76, 0x00, 0x2a, 0xff, 0x61, 0x91, 0xc0, 0x82, 0xa5, 0x5b, 0x96, 0xa2, 0xe0, 0x42, 0x80, 0x52, 0xfe, 0x29, 0xb6, 0x53, 0x13, 0x17, 0xb0, 0xf9, 0xfd, 0xf7, 0x28, 0x92, 0x61, 0x7b, 0x71, 0x51, 0xdc, 0x83, 0xb4, 0x9a, 0xcb, 0x50, 0x38, 0x64, 0xcc, 0xb1, 0xd4, 0x8b, 0x85, 0x4b, 0xf2, 0x08, 0x5b, 0x94, 0x56, 0xc6, 0x72, 0x9d, 0x7e, 0x9e, 0xd3, 0xc0, 0xc7, 0x8f, 0x72, 0x77, 0xd1, 0xf5, 0x4f, 0x3b, 0x40, 0x45, 0x50, 0x6e, 0x3b, 0x70, 0x0d, 0x43, 0xc3, 0x42, 0x5b, 0x6a, 0x46, 0xcb, 0x8b, 0x70, 0xca, 0x0f, 0xc3, 0xc0, 0x04, 0x4b, 0x92, 0xd4, 0x31, 0x4f, 0x88, 0xcf, 0x9e, 0x78, 0x1a, 0xad, 0x11, 0x23, 0xdc, 0x5a, 0xb4, 0x80, 0x63, 0x18, 0x51, 0x81, 0x60, 0xa5, 0x0e, 0x4c, 0x78, 0xcd, 0x9b, 0x05, 0xde, 0xb1, 0xde, 0x6b, 0x9e, 0x48, 0x63, 0x55, 0x3c, 0x0c, 0x79, 0x52, 0x43, 0x25, 0xcb, 0x69, 0x32, 0x1b, 0x75, 0xa8, 0xf1, 0x72, 0xe3, 0x83, 0xae, 0x61, 0x07, 0x14, 0xee, 0x1f, 0x38, 0xb1, 0xa2, 0x78, 0x83, 0x3c, 0xb2, 0x3c, 0xcf, 0x2a, 0x4e, 0x08, 0x56, 0xfc, 0x00, 0xbc, 0x45, 0x9f, 0x61, 0x04, 0x94, 0x61, 0xf8, 0xe9, 0x03, 0xc9, 0x55, 0x51, 0xe0, 0xaf, 0x65, 0x52, 0x7d, 0x20, 0xd7, 0xca, 0x91, 0x52, 0x09, 0x09, 0x42, 0xc6, 0xbd, 0x83, 0x65, 0xd8, 0x50, 0x07, 0xfe, 0xfd, 0x94, 0x81, 0xa9, 0xea, 0x91, 0x99, 0xb7, 0x95, 0x5d, 0xe4, 0x50, 0x0d, 0xb2, 0xdb, 0xd4, 0x68, 0x37, 0x0e, 0xcd, 0xe6, 0xa1, 0x92, 0xe4, 0xe1, 0x49, 0xad, 0xe9, 0x5f, 0x58, 0xc8, 0xfc, 0x51, 0x9a, 0x70, 0xfd, 0xa4, 0x9d, 0x48, 0x24, 0x72, 0x8b, 0x8e, 0xae, 0x13, 0x98, 0xa9, 0x81, 0x0b, 0x93, 0xe6, 0x74, 0x5d, 0x45, 0xa0, 0x84, 0x8e, 0x97, 0x29, 0x97, 0xc1, 0xde, 0x75, 0x01, 0x75, 0xea, 0x3e, 0x33, 0x48, 0x5c, 0x03, 0xb1, 0x89, 0xf4, 0x93, 0xe1, 0xd3, 0xb2, 0xa2, 0x8b, 0xa9, 0x48, 0x5c, 0x69, 0x26, 0xd0, 0x56, 0x2a, 0xbe, 0xa5, 0x90, 0xe7, 0x0b, 0x78, 0x38, 0x6e, 0xa4, 0x8c, 0x49, 0xeb, 0x0c, 0x2e, 0xe6, 0x10, 0xaa, 0x9a, 0x2e, 0x26, 0xdd, 0xb8, 0x76, 0xc0, 0xab, 0x67, 0x66, 0x24, 0xc2, 0x6d, 0xd2, 0x3b, 0xe5, 0x9a, 0x9d, 0x84, 0xe9, 0x56, 0x88, 0xbf, 0x6b, 0xe2, 0xe1, 0x48, 0xb0, 0x95, 0xc0, 0xe6, 0xbd, 0x86, 0x02, 0x85, 0x1e, 0x1a, 0xfc, 0x17, 0x4a, 0x77, 0x73, 0xf6, 0xcd, 0xcf, 0x37, 0xf4, 0xa7, 0x82, 0x7c, 0x68, 0xab, 0xe7, 0xc5, 0xda, 0xe4, 0xcf, 0x4e, 0x33, 0xe1, 0x0b, 0x4d, 0x8d, 0x9d, 0x36, 0xdb, 0x93, 0xc8, 0xe8, 0x5d, 0xf2, 0x7f, 0x04, 0xcb, 0xbb, 0x13, 0x41, 0x3d, 0x4c, 0x92, 0x63, 0x91, 0x76, 0xdd, 0xfd, 0xdb, 0xc0, 0x2b, 0x4b, 0xa4, 0x44, 0xd1, 0x6f, 0xff, 0x29, 0xaf, 0x88, 0x1e, 0x40, 0x46, 0x2b, 0x5a, 0x89, 0xd6, 0x15, 0x9d, 0xfe, 0x77, 0xd0, 0xb9, 0x24, 0x82, 0x37, 0xe1, 0x43, 0x3b, 0xe0, 0x96, 0xeb, 0xe2, 0x81, 0x5b, 0xcb, 0xc7, 0x79, 0x24, 0xf9, 0x56, 0x87, 0x52, 0xf1, 0x8e, 0x39, 0x2d, 0x8a, 0xaf, 0xd5, 0x21, 0x34, 0x5d, 0x55, 0x04, 0x10, 0xb7, 0xf5, 0x01, 0xd4, 0x7c, 0x9d, 0x1e, 0x34, 0x56, 0xb3, 0xef, 0xbb, 0xf0, 0x67, 0x16, 0x79, 0x2c, 0xc2, 0xb9, 0x6c, 0x8a, 0xd7, 0x8e, 0x9a, 0x48, 0x89, 0xe0, 0x85, 0x62, 0xa8, 0xd3, 0xb3, 0x7d, 0xb0, 0x44, 0x1c, 0x5a, 0x0c, 0x22, 0x09, 0xd2, 0x19, 0x74, 0x5a, 0x19, 0x38, 0x51, 0xeb, 0x48, 0x63, 0xb0, 0x00, 0x0d, 0xc4, 0xd6, 0x44, 0x83, 0x78, 0x3a, 0x43, 0x9d, 0x51, 0xac, 0x0a, 0xa7, 0xe8, 0x5d, 0xb3, 0xa9, 0x2d, 0x4b, 0xe3, 0xc1, 0x68, 0xdd, 0xbb, 0x21, 0x49, 0xb8, 0xde, 0x01, 0x86, 0x07, 0x5c, 0xd5, 0x2a, 0xa5, 0xc8, 0x32, 0x4f, 0xec, 0x66, 0xf8, 0x66, 0x21, 0x43, 0x49, 0xe1, 0x9b, 0xdb, 0xcd, 0x61, 0xab, 0xfb, 0xae, 0x17, 0xaa, 0xa9, 0x7c, 0xb2, 0x27, 0x45, 0x47, 0xa9, 0xbb, 0xa3, 0xa2, 0x21, 0xd0, 0xa7, 0x04, 0xaa, 0x70, 0x77, 0xae, 0x0f, 0x8f, 0x3e, 0x47, 0xa5, 0xb8, 0xef, 0xde, 0x61, 0xcb, 0xb8, 0x71, 0xc7, 0xaf, 0x15, 0xfc, 0xcf, 0x65, 0xe5, 0xe1, 0x21, 0x49, 0x69, 0x77, 0x5e, 0x1e, 0xc3, 0xa7, 0xf1, 0x12, 0x14, 0xbe, 0xe3, 0xa9, 0xb1, 0xe9, 0xc9, 0x92, 0x86, 0xb9, 0x60, 0x32, 0x7c, 0xf6, 0xf0, 0xe8, 0xbf, 0xae, 0x1d, 0x58, 0x9e, 0x6b, 0x0d, 0xd5, 0xd9, 0x3e, 0x42, 0x57, 0x69, 0xb5, 0xd5, 0xe6, 0x22, 0x2c, 0x12, 0x8e, 0xe1, 0xd1, 0x57, 0xff, 0xaa, 0x7a, 0xb2, 0x9c, 0x27, 0x81, 0x6d, 0x87, 0xd2, 0xbc, 0xa6, 0xa0, 0x95, 0xc5, 0xa5, 0x3d, 0x5d, 0xcf, 0xc9, 0x23, 0xc9, 0xa9, 0xb4, 0x07, 0xf1, 0x64, 0xef, 0x1f, 0x7a, 0xb1, 0x22, 0x31, 0x22, 0x68, 0xc0, 0x54, 0x96, 0x39, 0x1c, 0xb3, 0xfb, 0x87, 0x60, 0xa0, 0x4b, 0xcd, 0xe4, 0xb9, 0x2d, 0xf5, 0xaf, 0xb8, 0x1a, 0xe0, 0x4e, 0xed, 0x1c, 0x64, 0x0b, 0xb2, 0xc6, 0xa2, 0xf9, 0xf1, 0x90, 0x9d, 0xfe, 0x92, 0x45, 0x95, 0x0c, 0x24, 0xe1, 0x44, 0x3e, 0xe1, 0x1a, 0xab, 0x04, 0x48, 0x97, 0xd7, 0x83, 0x7b, 0x81, 0x12, 0xa9, 0x5d, 0xe3, 0xe3, 0xbf, 0x97, 0xd6, 0x99, 0x51, 0x3d, 0xcb, 0xd8, 0xed, 0x6c, 0x2e, 0x67, 0xf7, 0x90, 0x77, 0xf5, 0xf8, 0x5e, 0x34, 0x4c, 0xa5, 0xe8, 0xfd, 0x11, 0xf0, 0x96, 0xc8, 0xf3, 0x83, 0x5e, 0x7a, 0x01, 0xfe, 0x42, 0x5a, 0xa0, 0xeb, 0xd1, 0x02, 0x18, 0x58, 0xc1, 0xf0, 0xc1, 0xc9, 0x19, 0x64, 0x18, 0xd6, 0xa3, 0x10, 0x00, 0x9c, 0x07, 0xcf, 0x01, 0x2a, 0x8e, 0x97, 0xf5, 0xbc, 0x46, 0x5f, 0xc8, 0x14, 0xa1, 0xb0, 0x80, 0xd6, 0x43, 0xd3, 0xb6, 0x1f, 0x22, 0xf3, 0x8c, 0x72, 0x1f, 0xbb, 0x19, 0x82, 0xfe, 0xc1, 0x0f, 0x1a, 0x4e, 0x59, 0xbb, 0xf7, 0x8c, 0x71, 0xbc, 0xa8, 0x12, 0x31, 0xf9, 0xcf, 0xd9, 0x26, 0xf1, 0xa2, 0xc2, 0x55, 0x2d, 0xc3, 0xe1, 0x2d, 0x88, 0xa1, 0x2c, 0x5a, 0xbf, 0x2c, 0xec, 0xc3, 0x1d, 0x41, 0x4b, 0xa6, 0xb7, 0x9a, 0x34, 0x7d, 0x1e, 0x7e, 0x0e, 0x57, 0x6f, 0x99, 0xc7, 0x15, 0xcc, 0xa9, 0x76, 0x11, 0x9f, 0x82, 0xbc, 0x1a, 0x8c, 0x83, 0x33, 0x55, 0x9e, 0x13, 0x85, 0x46, 0xbb, 0xf1, 0xd1, 0x8a, 0xf6, 0xde, 0xff, 0xe6, 0x70, 0x0d, 0x2d, 0x63, 0x56, 0xda, 0x3c, 0x63, 0x47, 0x91, 0xb2, 0xaf, 0x43, 0xf3, 0x86, 0x3c, 0xf1, 0x34, 0x37, 0x13, 0xf9, 0x60, 0x50, 0x95, 0xf7, 0xce, 0x6e, 0x55, 0xda, 0xff, 0x1f, 0xe6, 0x8c, 0x15, 0xea, 0xe4, 0xe2, 0xc3, 0xcd, 0x7b, 0x93, 0x65, 0xfc, 0x1e, 0xc7, 0xb3, 0xe1, 0x6d, 0xd7, 0xf6, 0xb0, 0x38, 0x77, 0x9d, 0xfc, 0x01, 0xce, 0x7e, 0xf0, 0xe0, 0xc2, 0xf6, 0x28, 0xb2, 0x33, 0xa2, 0xd8, 0x7c, 0x93, 0x39, 0x15, 0x43, 0x7c, 0x3b, 0x9d, 0x5b, 0x50, 0xe1, 0x06, 0xec, 0xfd, 0x2b, 0xd6, 0xb6, 0xe9, 0xbe, 0xbd, 0x74, 0xe0, 0x1d, 0x76, 0x4a, 0x3d, 0x7d, 0xb5, 0xa7, 0x24, 0x6f, 0x52, 0x84, 0x95, 0xef, 0x57, 0xe8, 0x2b, 0xa2, 0x69, 0x5e, 0x2c, 0x1e, 0x68, 0xe5, 0x10, 0x46, 0x15, 0x75, 0x81, 0x7b, 0x70, 0x10, 0x37, 0xa0, 0xb8, 0x05, 0x3c, 0x7f, 0x71, 0x33, 0xb9, 0x12, 0xae, 0x6a, 0xc8, 0xcc, 0x97, 0xf9, 0x5e, 0x90, 0xcc, 0x29, 0xcb, 0x50, 0x29, 0xb5, 0x3d, 0x21, 0xeb, 0x3b, 0x7c, 0x70, 0xff, 0x9a, 0xa0, 0x2c, 0x4e, 0xab, 0xa6, 0x25, 0x93, 0x7f, 0x48, 0xa0, 0xdd, 0x75, 0xfa, 0x9a, 0x16, 0xae, 0xdc, 0x8e, 0x92, 0x72, 0x2d, 0x57, 0x60, 0x80, 0x37, 0x25, 0xb3, 0xba, 0x62, 0xa0, 0x47, 0x1d, 0x66, 0x2a, 0xa9, 0x51, 0x14, 0xd5, 0x96, 0xb2, 0x3a, 0x61, 0x8a, 0xc7, 0x8d, 0xb7, 0xcd, 0x17, 0xca, 0x74, 0x9d, 0x9c, 0x2e, 0x45, 0x68, 0x04, 0x66, 0x21, 0x3b, 0xe9, 0xb0, 0xb2, 0xde, 0x8b, 0xbb, 0xee, 0xc1, 0x5d, 0xa1, 0x1c, 0x14, 0x10, 0xbd, 0x64, 0x72, 0x43, 0xb4, 0x21, 0x43, 0x0e, 0xdc, 0xb7, 0x73, 0x45, 0x90, 0x67, 0xd2, 0xee, 0x4b, 0x9e, 0x9c, 0xe2, 0xec, 0x2a, 0xd9, 0x7a, 0x33, 0xd5, 0x67, 0xb0, 0xc0, 0x42, 0xef, 0xbe, 0xa7, 0x9f, 0x49, 0x9a, 0x7b, 0x9b, 0xfb, 0xa4, 0x42, 0x0c, 0xbf, 0x77, 0x7a, 0x3d, 0x8f, 0x5e, 0xf0, 0x86, 0x26, 0x9d, 0xf4, 0xd4, 0xbf, 0xc7, 0x1a, 0x94, 0x84, 0xda, 0xc8, 0x1a, 0x2c, 0x22, 0x5a, 0xc5, 0x8d, 0x91, 0x4c, 0x22, 0x70, 0xfb, 0xec, 0x11, 0x13, 0xdd, 0x38, 0x72, 0xb3, 0xc9, 0x6b, 0x29, 0xd5, 0x16, 0xc4, 0xc8, 0x30, 0xc1, 0x17, 0xe9, 0x97, 0x51, 0xc4, 0x88, 0xd6, 0x27, 0x60, 0x64, 0x0b, 0x74, 0x9c, 0xf3, 0x4e, 0xc5, 0xa4, 0x89, 0x32, 0x2d, 0xf0, 0x5f, 0xe4, 0x9c, 0xb4, 0x3c, 0xee, 0xa5, 0x5c, 0x98, 0x4b, 0x2f, 0x5a, 0x60, 0x5a, 0xd4, 0xa5, 0x9b, 0xae, 0x1d, 0xcc, 0x9a, 0x2f, 0xc5, 0xa1, 0x74, 0x10, 0x9b, 0x82, 0xfa, 0xfa, 0xf5, 0x3a, 0x3b, 0x0c, 0x4e, 0x72, 0xc2, 0x10, 0x99, 0x28, 0xd9, 0x60, 0x7b, 0x2b, 0xdc, 0xc1, 0xb9, 0x83, 0x5d, 0x0e, 0xe5, 0x2d, 0x3e, 0xc4, 0x85, 0xbc, 0x7e, 0x29, 0x59, 0x32, 0xd3, 0x97, 0x25, 0x63, 0x1f, 0x51, 0xe9, 0x2d, 0x71, 0xf2, 0xa0, 0x89, 0x0b, 0xcd, 0xdf, 0x5b, 0x68, 0x73, 0x77, 0x45, 0x6e, 0xb4, 0x60, 0x80, 0x07, 0x2a, 0x40, 0x97, 0x58, 0xef, 0x0b, 0x6a, 0x10, 0x12, 0x7a, 0xbf, 0x2c, 0xcc, 0xe8, 0x00, 0x03, 0x08, 0xdf, 0xe2, 0xfc, 0xd2, 0x00, 0xe6, 0xc7, 0x65, 0xec, 0x72, 0x16, 0x04, 0xcc, 0x8b, 0x8d, 0xe9, 0x67, 0x16, 0xc2, 0x57, 0x63, 0x96, 0x84, 0x73, 0xb3, 0xc5, 0xe5, 0xcd, 0x2c, 0x0c, 0x7b, 0x1c, 0xf8, 0xf3, 0xe2, 0x5f, 0xf3, 0x00, 0x4e, 0x08, 0xf8, 0x3b, 0xd6, 0x02, 0xdd, 0x07, 0x43, 0xf1, 0xaf, 0x24, 0x02, 0x6e, 0x1f, 0x3e, 0xb8, 0xf5, 0xc6, 0xa6, 0x5c, 0x47, 0x61, 0x0f, 0x5f, 0x22, 0x48, 0x12, 0xf6, 0xd5, 0xe7, 0xdb, 0x7c, 0x0a, 0x82, 0x8c, 0x96, 0x7d, 0xa7, 0xf1, 0xad, 0x08, 0x2d, 0x85, 0x7f, 0x7d, 0xd4, 0xff, 0xed, 0x6e, 0xc9, 0x72, 0x30, 0x66, 0xec, 0x77, 0x03, 0x60, 0x82, 0xd2, 0x85, 0xbb, 0x4d, 0xe4, 0xee, 0x47, 0xfb, 0x51, 0xaa, 0x87, 0x59, 0xa7, 0x7f, 0x2b, 0xe2, 0xd6, 0x60, 0x07, 0x52, 0x3d, 0x13, 0x39, 0x9c, 0x86, 0x2f, 0x69, 0x0d, 0x76, 0xfa, 0x9a, 0x2e, 0x93, 0xe9, 0x03, 0xad, 0xa1, 0x63, 0xd4, 0x84, 0xb1, 0xa1, 0x33, 0x1f, 0x28, 0x43, 0xd7, 0x46, 0xa7, 0xb9, 0x38, 0x57, 0x29, 0xee, 0xd8, 0xff, 0xf7, 0x57, 0x44, 0x68, 0x08, 0x8c, 0xbc, 0xc0, 0xff, 0x2a, 0xe4, 0xfd, 0x47, 0x27, 0x64, 0x7f, 0x1b, 0xa9, 0xce, 0xb5, 0x4f, 0x91, 0xa5, 0x14, 0x2c, 0x8f, 0xaa, 0x51, 0x32, 0x14, 0xa3, 0x20, 0xde, 0x4f, 0x64, 0x73, 0xf7, 0xe1, 0x91, 0x8a, 0x7b, 0x4a, 0xdc, 0x9b, 0xb8, 0xe3, 0x3f, 0x31, 0xed, 0x99, 0xe5, 0x69, 0x8d, 0x91, 0x8a, 0xd7, 0x7f, 0x07, 0xc9, 0x0f, 0xbb, 0x1a, 0x72, 0x2b, 0x7c, 0x78, 0xe5, 0xa4, 0x9d, 0x83, 0x49, 0xc7, 0xc8, 0x50, 0xeb, 0x05, 0x2e, 0x4c, 0xb1, 0x57, 0x57, 0xc2, 0x84, 0x3e, 0x51, 0x44, 0x8f, 0x41, 0xc8, 0x59, 0xe4, 0xfd, 0x68, 0x4c, 0x2f, 0xaf, 0x15, 0xf5, 0x95, 0x59, 0xf3, 0x7a, 0xe4, 0x62, 0x01, 0xd4, 0xf1, 0x32, 0x6b, 0x96, 0xbe, 0x27, 0xf5, 0x20, 0xe4, 0x50, 0x33, 0xa6, 0x34, 0x1f, 0xb4, 0x21, 0xc6, 0xd8, 0xf5, 0xb5, 0x06, 0xe1, 0xf2, 0x17, 0x25, 0x99, 0xa7, 0x25, 0x8a, 0x08, 0x17, 0x5e, 0x9a, 0xf1, 0x69, 0x2d, 0xeb, 0x86, 0x0e, 0xf2, 0x0f, 0x63, 0xbe, 0x85, 0xdb, 0x0c, 0xf6, 0x3d, 0xa8, 0x32, 0xce, 0x21, 0xc8, 0xc9, 0x33, 0xc9, 0xde, 0x9a, 0x9c, 0x29, 0x65, 0x34, 0xa8, 0xd8, 0x82, 0x9f, 0x22, 0xbe, 0x6b, 0x9e, 0x6d, 0x93, 0x5a, 0x52, 0xcf, 0x63, 0xb8, 0x96, 0x31, 0xad, 0xa3, 0x9c, 0x95, 0x05, 0x20, 0xc7, 0x25, 0x0d, 0x8c, 0x1b, 0xb3, 0x40, 0x8a, 0x53, 0xd7, 0xfb, 0x33, 0x8f, 0x46, 0x85, 0xb9, 0xc3, 0x55, 0xfd, 0x06, 0x0f, 0x87, 0xc7, 0xc7, 0x46, 0xe7, 0x9b, 0x63, 0x5c, 0x00, 0xa2, 0x3b, 0x05, 0xe6, 0x0c, 0xc8, 0xea, 0x48, 0x34, 0xfd, 0x43, 0x9a, 0xc2, 0xa8, 0xe6, 0x12, 0x96, 0xa9, 0xb2, 0x5d, 0x6f, 0x66, 0x8b, 0x1a, 0x8c, 0x54, 0x24, 0xd4, 0x7a, 0xd5, 0x2e, 0xb3, 0x00, 0xd7, 0x5e, 0xba, 0x46, 0xea, 0x95, 0xa8, 0x71, 0x9f, 0x9c, 0x4a, 0xd0, 0x8c, 0xaf, 0x26, 0xcf, 0x2f, 0x7e, 0x44, 0xa9, 0x20, 0x35, 0x5f, 0x41, 0xfe, 0x67, 0x03, 0x2d, 0x1d, 0x37, 0x04, 0x07, 0x23, 0x00, 0x59, 0x61, 0x05, 0xce, 0xc4, 0x40, 0x02, 0x6f, 0xa3, 0x17, 0x97, 0xe5, 0xac, 0x38, 0x71, 0xf9, 0xec, 0xed, 0x0b, 0xa4, 0x14, 0x57, 0xcb, 0xc4, 0x6c, 0xbb, 0xa9, 0xa9, 0x74, 0x17, 0xc2, 0xc5, 0x65, 0x7d, 0xad, 0xd8, 0x03, 0x08, 0x9d, 0x7f, 0x98, 0x3e, 0xf4, 0x98, 0x15, 0xed, 0x61, 0x48, 0xf6, 0xdd, 0xd9, 0xa5, 0x01, 0xc6, 0xd7, 0x53, 0xd6, 0x17, 0xdd, 0xc1, 0xab, 0x63, 0x10, 0xbe, 0xd4, 0xdf, 0x23, 0x5a, 0x91, 0x67, 0xa2, 0x3a, 0xbf, 0x13, 0x37, 0xaf, 0xb7, 0x18, 0xe8, 0xec, 0xcf, 0x01, 0xbf, 0x98, 0xe7, 0x3a, 0x10, 0xcf, 0xb4, 0x65, 0xc3, 0xa6, 0xa3, 0x49, 0x29, 0xbf, 0xf4, 0xe2, 0x9f, 0x97, 0xab, 0xf0, 0x32, 0x25, 0xfa, 0xd0, 0x05, 0x0f, 0xee, 0xb9, 0x93, 0xf8, 0x3b, 0x79, 0xa0, 0xdc, 0xa6, 0x65, 0x0e, 0x56, 0x4a, 0x9c, 0xcf, 0x0a, 0x4b, 0xe4, 0x5f, 0x72, 0x51, 0xf5, 0xaf, 0xd8, 0xb8, 0xa4, 0xb0, 0xd7, 0x27, 0x48, 0x24, 0x8c, 0xa0, 0x82, 0xc4, 0x00, 0x73, 0xe4, 0xd8, 0x54, 0x48, 0x98, 0x3b, 0x98, 0x68, 0x26, 0x9a, 0xb3, 0x0c, 0xba, 0xd8, 0x9c, 0x9d, 0x8a, 0x04, 0x95, 0x7a, 0x13, 0x51, 0x75, 0xf3, 0x7c, 0xa9, 0x51, 0x34, 0xe4, 0x12, 0x87, 0xdf, 0xa3, 0x78, 0xbe, 0xd6, 0xe5, 0x20, 0x76, 0xb7, 0xd0, 0x83, 0xe9, 0xb6, 0x3d, 0x57, 0x46, 0x00, 0xa5, 0xd9, 0xf9, 0xa0, 0x3d, 0x18, 0xb4, 0x34, 0x1e, 0x7d, 0x3a, 0x47, 0xc7, 0x4d, 0x32, 0xc0, 0xfc, 0x37, 0x47, 0x78, 0x49, 0xa2, 0xa8, 0xb1, 0x30, 0xc3, 0x6c, 0xb1, 0xbd, 0x5d, 0x60, 0x32, 0xf7, 0xdf, 0x51, 0x8b, 0x47, 0xcf, 0x0a, 0x1f, 0xde, 0x1f, 0xc7, 0x6d, 0xb0, 0xe1, 0x43, 0x9d, 0x07, 0x8c, 0x43, 0x8c, 0xa6, 0x6b, 0x3d, 0xd4, 0xb9, 0x77, 0x30, 0xb3, 0x0f, 0xae, 0x83, 0x80, 0x6a, 0x55, 0xe3, 0x6c, 0xc6, 0xee, 0x09, 0x10, 0xf8, 0x13, 0xc0, 0xed, 0x7a, 0xb5, 0x5b, 0xc6, 0x6f, 0x5f, 0x28, 0xa1, 0x16, 0xc3, 0xe9, 0x58, 0xe8, 0x48, 0x4d, 0xfb, 0xdf, 0xd9, 0x24, 0xca, 0x3a, 0x90, 0x4b, 0x80, 0x43, 0xa4, 0x3a, 0x1e, 0x86, 0x2a, 0x68, 0xbf, 0x7b, 0x0b, 0xb6, 0x92, 0xdf, 0x0f, 0xfa, 0x60, 0x7c, 0x3d, 0x53, 0x47, 0x64, 0xd6, 0x73, 0x03, 0xe4, 0x67, 0x02, 0x87, 0xfc, 0xa8, 0xee, 0xb6, 0x95, 0x1d, 0xd8, 0x95, 0xef, 0x75, 0xb1, 0xad, 0xd8, 0x5f, 0x11, 0x6e, 0x87, 0x5b, 0x12, 0xc9, 0x39, 0x67, 0x83, 0xce, 0x89, 0x60, 0x68, 0x53, 0x6f, 0x91, 0x08, 0xa8, 0x0c, 0x71, 0xdb, 0x67, 0xe0, 0xbf, 0xe8, 0xc6, 0xba, 0x87, 0x66, 0xd3, 0x1d, 0xa8, 0xba, 0xdc, 0x58, 0x0c, 0x0d, 0x99, 0x39, 0x82, 0x83, 0x38, 0xd6, 0x05, 0xa5, 0xaf, 0x03, 0x8d, 0x69, 0xb0, 0x44, 0x5a, 0xfd, 0x37, 0xc0, 0x9d, 0x72, 0x49, 0x74, 0x03, 0xe6, 0x78, 0x71, 0xbc, 0x47, 0xb1, 0xb3, 0xc1, 0x48, 0x83, 0x8d, 0x24, 0x2e, 0xe9, 0x37, 0x47, 0x1d, 0x8b, 0x94, 0xe2, 0x7c, 0xf8, 0x2c, 0x93, 0x2b, 0xe1, 0x3a, 0x5c, 0xbc, 0xa4, 0xab, 0xc0, 0xc3, 0xb2, 0x20, 0x7d, 0x32, 0x2f, 0x4a, 0x7c, 0x91, 0xf4, 0x79, 0xd8, 0x21, 0x79, 0x59, 0x0a, 0x79, 0x87, 0x9d, 0xdd, 0xf6, 0xbf, 0xd8, 0xc0, 0xf5, 0x67, 0xe2, 0x49, 0xaf, 0xbc, 0xd9, 0x45, 0x1f, 0x17, 0x66, 0xe9, 0x61, 0x0a, 0xb7, 0x35, 0x87, 0x56, 0xcf, 0xc9, 0x03, 0xfd, 0x5c, 0x28, 0xd8, 0xe5, 0xb2, 0xc7, 0xc6, 0x6c, 0xc5, 0x4a, 0x6e, 0x2e, 0xe7, 0xe9, 0xe5, 0x39, 0xc3, 0x4e, 0x0e, 0x91, 0xe3, 0xd0, 0x9f, 0x54, 0xa8, 0xa7, 0xf3, 0x98, 0x95, 0x1c, 0x7b, 0x61, 0xc2, 0x06, 0x21, 0x8c, 0x5b, 0xea, 0x19, 0x4d, 0x38, 0xda, 0x14, 0xca, 0x81, 0x29, 0x67, 0x0b, 0xca, 0xd1, 0xf2, 0xe9, 0x98, 0xd9, 0xaf, 0x17, 0xbe, 0x83, 0x61, 0x0e, 0xf1, 0x58, 0x94, 0xb6, 0xa4, 0x58, 0xaa, 0x08, 0x6c, 0x82, 0xc3, 0xb2, 0x2f, 0xa4, 0x74, 0x26, 0x6e, 0xb2, 0x83, 0xeb, 0x68, 0x4d, 0x19, 0xf5, 0x75, 0x0a, 0xf1, 0x05, 0x00, 0x00, 0x55, 0xd6, 0x6c, 0x20, 0xb9, 0x9f, 0x3f, 0xa0, 0x19, 0x90, 0x76, 0x91, 0x64, 0x71, 0xf5, 0xaa, 0x47, 0xf4, 0x67, 0x10, 0xf1, 0xf2, 0xcf, 0x6a, 0x28, 0xd8, 0x40, 0xb7, 0x3a, 0x7a, 0x4e, 0xc6, 0xe0, 0x6d, 0xeb, 0xd7, 0xe7, 0x60, 0x68, 0x50, 0x7b, 0xdd, 0x87, 0x68, 0xf7, 0x4b, 0x9b, 0x54, 0xe3, 0x59, 0xd6, 0xa9, 0x01, 0x5a, 0xc8, 0xc3, 0x86, 0x50, 0xbb, 0xb8, 0x94, 0xd9, 0x86, 0x00, 0x90, 0x22, 0x79, 0x6a, 0x12, 0x4d, 0xa6, 0xb0, 0x02, 0xd8, 0xdb, 0x4d, 0x61, 0xe8, 0x12, 0xb8, 0xf0, 0x92, 0xa1, 0x51, 0xb7, 0x14, 0x68, 0xc8, 0x8a, 0x96, 0x0a, 0xb3, 0x7f, 0xc1, 0xeb, 0x74, 0x89, 0xda, 0xf5, 0xe2, 0x40, 0x40, 0xd6, 0x36, 0x85, 0x5f, 0x68, 0xed, 0xe9, 0xe8, 0x44, 0x91, 0x52, 0xb0, 0x33, 0xf2, 0x8e, 0x53, 0xe1, 0xce, 0xcf, 0xc6, 0x2f, 0xf8, 0x00, 0x2a, 0x52, 0x66, 0xb7, 0x87, 0x9d, 0x4e, 0x3d, 0xfa, 0x8d, 0x12, 0x38, 0x00, 0xcd, 0x9a, 0x01, 0x39, 0x88, 0xa7, 0x04, 0xc4, 0x8b, 0xe7, 0xda, 0xd8, 0x05, 0x04, 0x88, 0x98, 0xd1, 0x78, 0xfa, 0x6a, 0x4d, 0xc4, 0xc0, 0x10, 0xd4, 0xb2, 0x34, 0xee, 0x35, 0x8c, 0x00, 0xf8, 0x46, 0x82, 0x95, 0x7a, 0x7f, 0x12, 0x73, 0x68, 0x85, 0x76, 0x5c, 0xdd, 0x08, 0x29, 0x2f, 0xac, 0xbb, 0xa9, 0xca, 0xd4, 0xec, 0xbd, 0x4b, 0x10, 0x74, 0x29, 0xe9, 0xc5, 0xb2, 0xe1, 0xb0, 0xa4, 0xc2, 0xd7, 0xd1, 0x0a, 0xaf, 0x69, 0xbe, 0xa0, 0x09, 0x7a, 0x0b, 0xc8, 0xe4, 0xf0, 0x07, 0xd3, 0x5e, 0x18, 0x64, 0xa0, 0xea, 0x19, 0x89, 0x5b, 0x1f, 0x87, 0xe8, 0xc6, 0x29, 0xf3, 0x25, 0x68, 0x2f, 0x02, 0x72, 0x73, 0x2e, 0xe9, 0x24, 0x8c, 0x15, 0xf5, 0x97, 0x64, 0x00, 0x64, 0x3a, 0x6c, 0xfc, 0xb8, 0xda, 0x56, 0x58, 0xf8, 0x6b, 0x84, 0x2a, 0xfb, 0x82, 0x90, 0x6c, 0x90, 0x28, 0x6c, 0x5c, 0xd1, 0x4e, 0x05, 0x25, 0xa6, 0xed, 0xdd, 0x03, 0x09, 0x8a, 0xb6, 0x15, 0x09, 0xa7, 0x64, 0xaa, 0xd8, 0x08, 0xd0, 0x8a, 0x17, 0xaf, 0xe4, 0x6c, 0x11, 0x5b, 0x06, 0x98, 0x7f, 0x95, 0x40, 0x00, 0xbc, 0xb0, 0x38, 0x39, 0x68, 0xfd, 0x38, 0xd1, 0x71, 0xcd, 0x0b, 0x15, 0x39, 0xc4, 0xb2, 0x5a, 0x92, 0x70, 0xc1, 0x9a, 0xca, 0xc4, 0xb5, 0x53, 0x8e, 0x10, 0x00, 0x0e, 0xa3, 0x05, 0xe7, 0xbf, 0x07, 0xe4, 0xb2, 0x91, 0xc0, 0x8c, 0xf9, 0x80, 0x6e, 0x8a, 0x44, 0xe0, 0x9b, 0x00, 0x4b, 0x3d, 0x7c, 0x5e, 0x44, 0x47, 0xf5, 0x7c, 0x2c, 0x42, 0x6c, 0xd4, 0xd7, 0xb6, 0x82, 0x18, 0x78, 0x79, 0xe4, 0xeb, 0x80, 0x72, 0xf9, 0x67, 0xfa, 0x53, 0xff, 0x14, 0x6b, 0xee, 0x5a, 0xbb, 0xc1, 0xa5, 0xc7, 0xad, 0x47, 0xca, 0x0f, 0xee, 0x97, 0xe5, 0x6c, 0xd5, 0xdd, 0x44, 0x33, 0xee, 0x28, 0xb8, 0x70, 0x4e, 0x73, 0xb0, 0x4d, 0xd7, 0xfd, 0x05, 0xd6, 0xbd, 0x70, 0xd3, 0x1e, 0xbc, 0x33, 0xec, 0xc8, 0x2c, 0xea, 0x6a, 0xa6, 0x3d, 0x59, 0x43, 0x56, 0xba, 0x6a, 0x0a, 0x69, 0x96, 0x60, 0xc2, 0x26, 0x8d, 0xea, 0xe8, 0x3c, 0xce, 0x0b, 0xb0, 0xfc, 0x9a, 0xe9, 0x13, 0x12, 0xfe, 0x10, 0xe2, 0xad, 0xdd, 0x4b, 0x04, 0xcb, 0x0c, 0x2b, 0xff, 0xed, 0x00, 0xa3, 0x9e, 0xa6, 0x6f, 0x84, 0x35, 0x5a, 0xd1, 0x5a, 0x80, 0x06, 0xda, 0x51, 0x35, 0x80, 0xb3, 0x42, 0x12, 0xdc, 0x80, 0x4c, 0x02, 0xda, 0x1c, 0x8b, 0xa4, 0xb9, 0xaf, 0x83, 0xe6, 0x03, 0x33, 0x96, 0x0f, 0xf1, 0x57, 0x47, 0xbe, 0xc7, 0x69, 0xe0, 0x16, 0x29, 0xc9, 0x81, 0xd0, 0x1d, 0xb0, 0x34, 0x34, 0x6c, 0x54, 0x0a, 0x1c, 0x4f, 0xb2, 0x59, 0x98, 0xa7, 0x80, 0xf3, 0x1b, 0x91, 0x1b, 0xbb, 0x16, 0xa3, 0x39, 0x78, 0x91, 0xed, 0x68, 0x7b, 0x8a, 0x27, 0xd2, 0x74, 0xf5, 0x1a, 0x9d, 0x3b, 0xfd, 0x7c, 0x46, 0xcd, 0x3d, 0x79, 0xa7, 0xa1, 0xd0, 0xd6, 0xf5, 0xfe, 0x00, 0xd5, 0x98, 0x3f, 0x59, 0xe9, 0x5d, 0x34, 0x5b, 0x68, 0xee, 0x01, 0x57, 0xde, 0xce, 0xe5, 0xda, 0x49, 0xe9, 0x91, 0x66, 0x98, 0xc7, 0xde, 0xa3, 0x2f, 0x11, 0xf4, 0x46, 0x1b, 0x18, 0xbf, 0xa3, 0x0b, 0xc8, 0xf7, 0xfa, 0x0f, 0x2d, 0x46, 0x2f, 0x91, 0x73, 0xfb, 0xef, 0xa1, 0x79, 0xfa, 0xa2, 0xea, 0x9b, 0x68, 0x86, 0xea, 0x77, 0xe9, 0xdb, 0x6d, 0x9d, 0xac, 0x8e, 0x72, 0x6e, 0xe0, 0xe4, 0xda, 0x50, 0x94, 0x5d, 0x62, 0x10, 0x80, 0x04, 0x47, 0x11, 0x4f, 0x46, 0x41, 0xdf, 0x39, 0x85, 0x04, 0xc5, 0x30, 0x5c, 0xa8, 0x56, 0x88, 0x79, 0x63, 0x99, 0xc9, 0xca, 0x90, 0x42, 0x61, 0x1d, 0x89, 0x20, 0x51, 0x2f, 0x13, 0xc3, 0x68, 0x73, 0x54, 0x4e, 0xa9, 0x9c, 0x0f, 0xd7, 0xce, 0xad, 0x50, 0x70, 0x7b, 0xff, 0x93, 0xce, 0xf5, 0x94, 0xd2, 0x85, 0x5a, 0x2c, 0x2c, 0x3a, 0x20, 0x92, 0x12, 0x52, 0x31, 0x82, 0xa6, 0x64, 0xf1, 0x62, 0xb3, 0x82, 0x2e, 0x78, 0xbf, 0x4c, 0x3d, 0x45, 0x26, 0x78, 0x6b, 0x85, 0x2e, 0xb4, 0xe3, 0x6a, 0x1f, 0x1e, 0x18, 0x18, 0x9a, 0x61, 0xbf, 0x2c, 0x7b, 0xc3, 0x53, 0x9f, 0x0c, 0x5b, 0xad, 0x7c, 0xf6, 0xc9, 0xd8, 0x8f, 0x2e, 0x86, 0x36, 0x8b, 0x0c, 0x8f, 0xdf, 0xf2, 0xe0, 0x80, 0x30, 0xcd, 0x3a, 0x10, 0xf6, 0xb1, 0x46, 0x2f, 0x4a, 0x38, 0x93, 0xa4, 0x6b, 0x96, 0x80, 0x83, 0x4f, 0xe9, 0xc1, 0xb8, 0x4a, 0x32, 0xa7, 0x1c, 0xc6, 0xd8, 0x3b, 0x66, 0x44, 0x6e, 0xb1, 0x89, 0x97, 0xab, 0xaf, 0xb6, 0x00, 0xa6, 0xfb, 0x29, 0x84, 0xd2, 0xcd, 0x5e, 0x23, 0x20, 0xf0, 0x02, 0x01, 0xe7, 0xf5, 0xa9, 0xb7, 0x23, 0x84, 0x07, 0x37, 0xd5, 0xde, 0x49, 0x6d, 0x14, 0x22, 0xaa, 0x16, 0x83, 0x40, 0xbb, 0xde, 0xcd, 0x25, 0xca, 0xe0, 0x46, 0x39, 0x30, 0x16, 0xd2, 0xf6, 0xdf, 0xf3, 0x10, 0x54, 0x34, 0x6a, 0xcb, 0x9f, 0xb0, 0xe6, 0x5c, 0x04, 0x40, 0xef, 0x44, 0xbc, 0xd3, 0x2a, 0xaf, 0xf5, 0x3c, 0x43, 0x95, 0x7b, 0xe9, 0x8e, 0xb6, 0x5e, 0x7f, 0x55, 0xd0, 0x97, 0x9d, 0xd9, 0xca, 0x37, 0xd2, 0x14, 0x90, 0xce, 0xa8, 0x51, 0x75, 0xd2, 0xbb, 0xe5, 0x9d, 0xa1, 0x1c, 0x5e, 0x16, 0xc4, 0x6f, 0xe7, 0xd1, 0x30, 0x2a, 0x01, 0x21, 0xc3, 0x18, 0x28, 0x41, 0xb6, 0x99, 0xa9, 0xd2, 0x37, 0x70, 0x1d, 0x36, 0x71, 0xf3, 0xbe, 0xfa, 0x25, 0x41, 0x20, 0x35, 0xa0, 0x29, 0xd9, 0x8b, 0x36, 0xf2, 0xe9, 0x20, 0x7f, 0xc3, 0x14, 0xaa, 0xe2, 0x11, 0xa5, 0x43, 0x10, 0x8d, 0xd8, 0x09, 0x81, 0x55, 0x1d, 0x08, 0x83, 0x3b, 0xb7, 0x3b, 0xe8, 0xb5, 0xa7, 0xd8, 0x1e, 0x7b, 0x98, 0xdd, 0x1a, 0x62, 0x65, 0xb9, 0xb5, 0xc8, 0x2a, 0x73, 0x24, 0x1f, 0x32, 0x3b, 0x14, 0x1f, 0x1d, 0x29, 0x42, 0x41, 0xe9, 0x7a, 0xee, 0xbc, 0x2f, 0x73, 0xab, 0xba, 0x26, 0x5c, 0xb0, 0x37, 0x49, 0xb1, 0xb1, 0xf4, 0x7f, 0x27, 0x52, 0x5b, 0xb0, 0xcd, 0x74, 0xe8, 0x22, 0xcd, 0xc1, 0x47, 0x42, 0xac, 0xa5, 0xfc, 0x4c, 0x91, 0xde, 0xa8, 0xe5, 0x56, 0x41, 0xe8, 0xb6, 0x06, 0x99, 0xd3, 0xce, 0x35, 0xe2, 0xad, 0x5b, 0x66, 0x6f, 0xfb, 0x81, 0xfd, 0x57, 0x48, 0xd2, 0xa4, 0x15, 0xc3, 0x7d, 0x4b, 0x0e, 0x51, 0xf1, 0x93, 0x38, 0x47, 0xdc, 0xd6, 0x17, 0xe8, 0x7c, 0x53, 0x55, 0x40, 0x88, 0x98, 0x4f, 0x8d, 0x68, 0x83, 0x90, 0x3e, 0xa2, 0xe7, 0x18, 0xe9, 0x8c, 0x22, 0xd1, 0x49, 0x55, 0xe4, 0x5d, 0x48, 0xdb, 0xba, 0x00, 0x00, 0xc1, 0x06, 0x62, 0x20, 0x4f, 0x66, 0x6b, 0x45, 0xcf, 0x5e, 0x06, 0xa8, 0xc9, 0x68, 0xa7, 0xc3, 0x25, 0x32, 0x7a, 0x96, 0x5c, 0x0e, 0xdd, 0xb5, 0xb3, 0x52, 0x29, 0x70, 0x7d, 0xb0, 0xae, 0x9e, 0xbb, 0x9f, 0x5f, 0x3d, 0x43, 0x3e, 0xa5, 0x40, 0x4d, 0x03, 0x1f, 0x3f, 0x22, 0xeb, 0x6e, 0x84, 0x87, 0x9f, 0xc3, 0x04, 0x07, 0x73, 0x3a, 0x63, 0xc8, 0x5b, 0x18, 0x92, 0xba, 0xac, 0x2a, 0x86, 0x95, 0xff, 0x5b, 0xce, 0xe7, 0x36, 0x1c, 0xab, 0xd8, 0xed, 0x7b, 0xe4, 0x0e, 0x79, 0x43, 0xa1, 0x2f, 0xc0, 0x60, 0x8d, 0x3c, 0x6f, 0x4e, 0x5f, 0xa8, 0xa5, 0x48, 0x62, 0xe3, 0xf5, 0x04, 0x03, 0x01, 0x7a, 0x3a, 0x18, 0xad, 0x53, 0xcd, 0xfd, 0x02, 0xce, 0x2e, 0xc8, 0xa8, 0x90, 0x2c, 0xe9, 0x22, 0x55, 0x2f, 0x83, 0xfe, 0x46, 0x3d, 0x17, 0x21, 0x14, 0x2a, 0x22, 0x25, 0xf7, 0xc5, 0x46, 0xd9, 0x37, 0x8e, 0x6f, 0x6d, 0xd8, 0x42, 0xfa, 0x68, 0x56, 0xd5, 0x7f, 0xe8, 0x1b, 0xa8, 0x73, 0xeb, 0x6b, 0xf7, 0x7f, 0xbf, 0xca, 0x59, 0xa4, 0x35, 0x50, 0x21, 0xd2, 0x7d, 0x0e, 0x36, 0x65, 0xf8, 0x6f, 0x22, 0x2c, 0xd2, 0xdb, 0x6f, 0xe8, 0xc1, 0x1d, 0x6b, 0xeb, 0x63, 0x8c, 0x13, 0x8b, 0x16, 0x2e, 0x57, 0xeb, 0x87, 0x60, 0x52, 0xf5, 0xc9, 0x56, 0x21, 0xd2, 0x4d, 0x44, 0xac, 0x9d, 0x84, 0x9a, 0xd8, 0x0e, 0x64, 0xc2, 0xda, 0x18, 0xfa, 0x32, 0x5f, 0x3e, 0x61, 0x19, 0xf6, 0x1b, 0xc7, 0x2d, 0xbd, 0xda, 0x8b, 0xd4, 0xb1, 0x7f, 0x8c, 0xd3, 0x3d, 0xd4, 0x69, 0xad, 0xc5, 0xed, 0x84, 0x19, 0xf9, 0xbe, 0xe4, 0xac, 0x5e, 0x7b, 0xb4, 0x38, 0xf8, 0xb1, 0x2c, 0x28, 0xe5, 0xa3, 0x7d, 0x81, 0x0c, 0xe5, 0x6a, 0xd7, 0x23, 0x9f, 0xdc, 0x97, 0xa5, 0xe6, 0x09, 0xfc, 0x3c, 0x12, 0xee, 0xb4, 0xee, 0xfc, 0x92, 0x00, 0x17, 0x27, 0x1e, 0x7a, 0xee, 0x4f, 0x39, 0x40, 0xa3, 0x69, 0x63, 0x07, 0x49, 0x4a, 0xbd, 0xe2, 0x72, 0x85, 0x7f, 0x90, 0xf1, 0x37, 0xbc, 0xf9, 0xf5, 0xed, 0xb7, 0x0c, 0xde, 0x87, 0x14, 0xb5, 0x8a, 0x36, 0x9a, 0x17, 0x1c, 0xa1, 0xef, 0xe3, 0xd7, 0x37, 0x1b, 0x54, 0xb6, 0x22, 0x94, 0xfc, 0x66, 0xc8, 0xa2, 0xc3, 0xed, 0x7a, 0x70, 0x34, 0x25, 0x29, 0x0e, 0x52, 0xa2, 0x86, 0x61, 0xcd, 0x5e, 0x71, 0x05, 0x76, 0x5e, 0x93, 0x4f, 0xa2, 0xd5, 0x2f, 0xea, 0x54, 0xfa, 0x6f, 0x51, 0xa9, 0xda, 0x95, 0x7e, 0x2f, 0x9b, 0x69, 0x81, 0xcb, 0xa3, 0x94, 0x63, 0x17, 0x8c, 0x6e, 0x78, 0x40, 0xc8, 0x54, 0x54, 0xa6, 0x18, 0xaa, 0x0c, 0x60, 0x57, 0xe7, 0xa2, 0x34, 0xc3, 0x82, 0x3a, 0x21, 0x8d, 0xf6, 0xf9, 0xf9, 0x05, 0x28, 0xbc, 0x96, 0x4f, 0xc1, 0xd0, 0xcb, 0x58, 0xe0, 0x20, 0xb3, 0xc6, 0x3f, 0xcb, 0xc8, 0xe2, 0xc0, 0x1b, 0x8f, 0x9f, 0x20, 0x33, 0x87, 0x3c, 0x57, 0x00, 0x6c, 0x15, 0xb3, 0x41, 0x46, 0xd9, 0x53, 0x36, 0xdd, 0x3f, 0xd5, 0xea, 0x99, 0x66, 0x9e, 0x18, 0x6f, 0xa3, 0xcc, 0x04, 0xbc, 0xfc, 0xcf, 0x61, 0xd3, 0xd1, 0xbd, 0x03, 0xec, 0x10, 0xa8, 0x5f, 0xc2, 0xb9, 0xd6, 0x22, 0x42, 0xfa, 0xda, 0xcc, 0x30, 0xf6, 0xae, 0x05, 0x26, 0xef, 0x87, 0x48, 0x4f, 0x6f, 0xc2, 0x21, 0xdd, 0x87, 0x4b, 0x7f, 0xab, 0x65, 0xad, 0x21, 0xfe, 0x50, 0x98, 0x95, 0xb7, 0x62, 0x8a, 0xc9, 0xdc, 0xda, 0x6e, 0x84, 0x4f, 0x3c, 0x39, 0x0e, 0x42, 0x67, 0x6d, 0x8f, 0x5a, 0x39, 0x3b, 0x5d, 0xe0, 0xc5, 0xf1, 0x17, 0x06, 0xa2, 0x09, 0x96, 0x7d, 0xfe, 0xc4, 0xce, 0xf5, 0x9f, 0x04, 0x15, 0x61, 0x54, 0x95, 0x93, 0xcc, 0x18, 0xb8, 0xc6, 0x8a, 0x38, 0x42, 0xbc, 0xee, 0xa0, 0x02, 0x50, 0x36, 0xee, 0xb0, 0x8a, 0x93, 0x2e, 0x5c, 0x6e, 0x70, 0xa3, 0x3b, 0x16, 0x14, 0x27, 0x45, 0x3e, 0x27, 0x09, 0x93, 0xc8, 0x1b, 0xb4, 0xaa, 0x2d, 0x00, 0x37, 0xc7, 0x81, 0x5a, 0xb5, 0xca, 0x52, 0xbc, 0x67, 0xc4, 0xc8, 0xd3, 0x66, 0x2d, 0xe7, 0x72, 0xbe, 0x15, 0xd3, 0xb3, 0x58, 0x1e, 0x1b, 0x52, 0xef, 0x59, 0x1a, 0x8b, 0x45, 0xa4, 0xbe, 0x59, 0xfc, 0xbb, 0xac, 0x76, 0x97, 0xb8, 0x4c, 0x0e, 0xfc, 0xc4, 0xd3, 0x76, 0x5a, 0x60, 0x11, 0xbc, 0xf4, 0x7a, 0x73, 0x05, 0xd2, 0x83, 0x09, 0x65, 0x3d, 0x54, 0x3a, 0x93, 0x65, 0xd8, 0x7d, 0xd6, 0x22, 0x32, 0x9f, 0x12, 0x3d, 0x4e, 0xeb, 0xb8, 0x75, 0xc0, 0x76, 0x9b, 0x20, 0x9c, 0xec, 0x68, 0xb8, 0x31, 0xdb, 0x54, 0xc9, 0x61, 0xf3, 0x66, 0xa3, 0x99, 0xd0, 0xf4, 0xfc, 0xba, 0x99, 0xaa, 0xe4, 0x85, 0x74, 0x41, 0x2f, 0x53, 0x63, 0x3e, 0x35, 0x77, 0x3e, 0xb1, 0xfa, 0x53, 0xff, 0x5e, 0x45, 0x6f, 0x7d, 0x24, 0x79, 0x48, 0x75, 0x60, 0x6f, 0xf1, 0x51, 0x7c, 0xc3, 0x9e, 0x1b, 0x29, 0x74, 0x68, 0x4e, 0xd5, 0x67, 0x6e, 0xcc, 0xd6, 0xd7, 0xbb, 0xb3, 0xb9, 0x0b, 0x44, 0x28, 0x25, 0xce, 0x26, 0x58, 0xf3, 0x06, 0x15, 0x6e, 0xac, 0x59, 0xb9, 0x47, 0x37, 0x3b, 0xe6, 0xfc, 0xcd, 0x84, 0xba, 0xbd, 0x0c, 0xb3, 0x41, 0xdc, 0xcb, 0xa1, 0xb8, 0x71, 0xfb, 0x34, 0x98, 0x7a, 0x1a, 0xc8, 0x5c, 0xdc, 0xa7, 0xb9, 0xc7, 0xe9, 0xbf, 0x69, 0x30, 0x64, 0xd9, 0x6a, 0x1c, 0x7a, 0xbe, 0x32, 0x73, 0xd9, 0x57, 0xb4, 0xcb, 0x66, 0x63, 0x97, 0x9f, 0xc6, 0x36, 0x57, 0xbb, 0xd5, 0x23, 0xc3, 0x4b, 0x0f, 0xde, 0x3b, 0x10, 0x66, 0x64, 0xb0, 0x4c, 0x13, 0x83, 0xdc, 0x35, 0x70, 0xf2, 0x04, 0x15, 0x1a, 0x75, 0x03, 0xf4, 0x7c, 0x02, 0x50, 0xa2, 0xf5, 0x82, 0x8f, 0x7a, 0xe7, 0x46, 0xa3, 0x6e, 0xdd, 0xbf, 0x71, 0x62, 0xe2, 0xad, 0x59, 0x81, 0xa4, 0x25, 0xfc, 0x2e, 0xf6, 0x25, 0x6c, 0xc9, 0x85, 0x73, 0x45, 0x27, 0xba, 0xa9, 0xf4, 0xb0, 0xe4, 0x20, 0x40, 0x97, 0x6c, 0x14, 0xd8, 0x06, 0x27, 0x05, 0xf4, 0x79, 0x89, 0x58, 0xb2, 0x65, 0x44, 0xf3, 0x1d, 0xab, 0xe9, 0xd2, 0xbb, 0x45, 0x2e, 0xf7, 0x56, 0xf2, 0x40, 0x6b, 0xbf, 0x07, 0xf6, 0x97, 0x0b, 0xba, 0xf9, 0xe3, 0x74, 0x55, 0x7a, 0x2a, 0xdc, 0x71, 0xd4, 0xc1, 0xc8, 0x1e, 0x07, 0x18, 0xe4, 0x5c, 0x52, 0x72, 0xbe, 0x13, 0x8c, 0x6b, 0x1c, 0x92, 0xd5, 0x3c, 0xfe, 0x74, 0x65, 0x6e, 0xaa, 0x7e, 0x9b, 0xb1, 0xc5, 0xcd, 0x57, 0x37, 0x6d, 0x4d, 0x6b, 0xe9, 0x39, 0xa8, 0x69, 0xf0, 0x47, 0xcf, 0xac, 0x6b, 0x7a, 0xb3, 0xe7, 0x1f, 0x7e, 0xe5, 0x57, 0xb1, 0xc7, 0x4f, 0x00, 0xd7, 0x5a, 0xc9, 0x37, 0x5a, 0x20, 0x8f, 0xb1, 0x16, 0x14, 0x88, 0xe7, 0xf0, 0xe5, 0x70, 0xf1, 0xbd, 0x2a, 0xa3, 0x30, 0x82, 0x0d, 0xf6, 0xf2, 0x45, 0x68, 0xd6, 0x83, 0xd0, 0x2b, 0xec, 0xcb, 0xf6, 0xf2, 0x25, 0x67, 0x00, 0xc6, 0x83, 0x75, 0x71, 0x7e, 0x00, 0xa5, 0x3c, 0xae, 0x8b, 0xd8, 0x1b, 0xb8, 0xd7, 0x59, 0xcd, 0x11, 0x2a, 0x1b, 0x59, 0x86, 0x0a, 0x05, 0xb4, 0x08, 0x91, 0xde, 0x5d, 0xd2, 0xd6, 0x9e, 0x3c, 0xc4, 0x7d, 0xc2, 0x6d, 0xbf, 0x3f, 0x3a, 0x39, 0x3d, 0xed, 0x54, 0x91, 0xe8, 0x34, 0x0c, 0xcb, 0x48, 0x59, 0x4d, 0x40, 0x31, 0xd9, 0xf1, 0xa4, 0xde, 0xfe, 0xf6, 0x83, 0x55, 0x14, 0x95, 0xa3, 0x72, 0x59, 0xf4, 0x28, 0x9b, 0xc6, 0x81, 0x26, 0xe9, 0xf9, 0xeb, 0xb1, 0x8b, 0x16, 0xec, 0xf2, 0x7c, 0x4a, 0xe5, 0xee, 0x05, 0x1e, 0x1b, 0x84, 0xaa, 0x83, 0x1b, 0x84, 0xcd, 0xd7, 0x80, 0x27, 0x7a, 0xe7, 0x55, 0x7c, 0x97, 0xf8, 0x5b, 0x99, 0x07, 0x1d, 0x57, 0x83, 0x46, 0x5c, 0x94, 0x01, 0x15, 0xbc, 0x19, 0xac, 0x22, 0xd7, 0x45, 0x36, 0x30, 0x2e, 0xe2, 0x08, 0xf4, 0x1b, 0xb4, 0x8d, 0x78, 0x3e, 0x4d, 0x4f, 0x15, 0xcd, 0x15, 0xac, 0x90, 0x37, 0xdb, 0x22, 0xbb, 0xe5, 0xf5, 0xcf, 0x91, 0x8f, 0x7d, 0x60, 0x32, 0x94, 0x39, 0x0f, 0x09, 0x1d, 0x8c, 0x53, 0x4f, 0xd0, 0x6e, 0x9f, 0xbd, 0xc8, 0xc3, 0xa5, 0xd8, 0x6f, 0x47, 0x04, 0x12, 0x34, 0xc5, 0xf6, 0x21, 0x48, 0xb8, 0xa2, 0xe2, 0xcd, 0xc3, 0x16, 0x11, 0xf2, 0x30, 0x6a, 0x53, 0x00, 0xa1, 0xd8, 0x89, 0xcf, 0xb2, 0x54, 0x19, 0x23, 0x04, 0x5e, 0xfb, 0x69, 0x4e, 0x7b, 0x5f, 0x0d, 0xfd, 0x32, 0x56, 0x43, 0xf6, 0x2e, 0x5d, 0xf1, 0xb2, 0xeb, 0x5f, 0x3d, 0xc2, 0x02, 0x4d, 0x78, 0x28, 0x0d, 0x0f, 0x76, 0xab, 0x39, 0x7c, 0x43, 0x30, 0xd8, 0x2b, 0xb0, 0xb2, 0xdd, 0x12, 0xc5, 0xc7, 0x33, 0x70, 0x7d, 0x9d, 0x94, 0x15, 0xe2, 0x05, 0x10, 0xef, 0x90, 0x60, 0xab, 0x30, 0x0f, 0x58, 0xa4, 0xfd, 0xbc, 0x7d, 0x39, 0xd5, 0xba, 0xcf, 0x65, 0x7d, 0xb9, 0x24, 0x24, 0xed, 0xdd, 0x9b, 0xc7, 0xe4, 0x99, 0x2f, 0xd4, 0x95, 0x85, 0x2c, 0x48, 0x61, 0x64, 0xd5, 0x2e, 0x39, 0x32, 0x16, 0xc1, 0xb4, 0x23, 0xd7, 0x1a, 0x82, 0xbf, 0xa2, 0x89, 0x35, 0x79, 0x52, 0x92, 0xd7, 0x5f, 0x36, 0xeb, 0x36, 0xdf, 0x8b, 0x72, 0x98, 0xe2, 0xca, 0xea, 0x35, 0xc5, 0xb7, 0xde, 0x76, 0x3e, 0xae, 0xe2, 0xaf, 0x93, 0x7d, 0x71, 0xf7, 0x7c, 0x20, 0x4a, 0xde, 0x8c, 0xed, 0x10, 0xab, 0x19, 0xc1, 0xbe, 0x46, 0xdb, 0x10, 0x3e, 0x71, 0xaf, 0x39, 0x34, 0xfa, 0x45, 0x10, 0xe4, 0xcd, 0x12, 0xc1, 0xf7, 0x9c, 0x72, 0x93, 0xe0, 0x4b, 0x75, 0x46, 0xe0, 0x75, 0x0b, 0x87, 0x4d, 0xbc, 0x48, 0x2c, 0x11, 0x00, 0xcb, 0xa2, 0x18, 0x0d, 0x49, 0x03, 0x39, 0x4d, 0x13, 0xd2, 0xa0, 0xd3, 0xb2, 0x5e, 0xb1, 0x74, 0xba, 0x14, 0x70, 0x63, 0x7c, 0x32, 0xc3, 0xd5, 0x23, 0x3e, 0x4f, 0x0e, 0x77, 0xc0, 0x3c, 0x75, 0x5a, 0x50, 0x0f, 0xd6, 0xa6, 0x27, 0x61, 0x57, 0x1b, 0x70, 0xac, 0xa0, 0xf3, 0x61, 0x79, 0xd8, 0x97, 0xc1, 0x81, 0xd0, 0x71, 0xba, 0x6c, 0xfd, 0xc7, 0x4f, 0x7b, 0xb4, 0x01, 0x20, 0x63, 0x07, 0x6c, 0xbc, 0x3c, 0x18, 0x80, 0x1a, 0xa0, 0xcd, 0xec, 0xab, 0xc5, 0x93, 0x45, 0x32, 0x36, 0x61, 0x3e, 0xd5, 0xcc, 0xf1, 0x34, 0x70, 0x0d, 0xbd, 0x4f, 0xdf, 0x44, 0x5f, 0xf8, 0x05, 0xcf, 0xcd, 0x6d, 0x6c, 0xec, 0xc7, 0x99, 0xef, 0x9f, 0xfc, 0xfa, 0xb7, 0xa3, 0xb4, 0xec, 0x4f, 0x80, 0x75, 0x9e, 0x3e, 0xfd, 0xa3, 0x57, 0xa9, 0x19, 0x1d, 0x71, 0x84, 0x2d, 0xa0, 0x04, 0xad, 0x22, 0x84, 0x33, 0x84, 0xf7, 0xc0, 0x62, 0xf0, 0xc3, 0x37, 0x4b, 0x2e, 0xc9, 0x28, 0x4b, 0x84, 0x1b, 0x4d, 0x46, 0xf7, 0x33, 0x8a, 0x19, 0x58, 0x8e, 0x4d, 0x5e, 0xfa, 0xe8, 0x20, 0xb7, 0x7f, 0xd8, 0xbf, 0xb6, 0x80, 0x3c, 0x12, 0x16, 0x73, 0x42, 0x31, 0xfd, 0x4c, 0x41, 0x91, 0x39, 0x39, 0xf5, 0x03, 0xbd, 0x28, 0x18, 0x1e, 0xb7, 0xe8, 0x2f, 0xb7, 0xd5, 0xb2, 0xf3, 0xf6, 0xf8, 0x3c, 0x8a, 0xf8, 0xb9, 0x88, 0x3b, 0xf1, 0xb4, 0x43, 0x57, 0x14, 0x8e, 0x7d, 0x25, 0xf5, 0x23, 0xa1, 0x86, 0xc3, 0x1a, 0x7d, 0x8b, 0x40, 0x9c, 0xf3, 0x68, 0xea, 0x10, 0xb2, 0x45, 0x93, 0x10, 0x7d, 0xaa, 0x63, 0x5f, 0xeb, 0x20, 0xdc, 0x61, 0x34, 0x3e, 0xaa, 0xf1, 0xfb, 0xe6, 0x12, 0x88, 0x15, 0xe7, 0x69, 0xb1, 0xbd, 0xd0, 0x1c, 0xb6, 0xb4, 0xd4, 0x3e, 0x27, 0x02, 0x32, 0xfe, 0xed, 0x3e, 0xe6, 0x81, 0x79, 0xf7, 0xf3, 0xab, 0x33, 0x2b, 0xe9, 0x54, 0xad, 0x86, 0x82, 0x86, 0x52, 0xed, 0x72, 0xf6, 0x75, 0xca, 0xe2, 0xc5, 0xf2, 0x49, 0xcc, 0x1c, 0x22, 0x60, 0x39, 0x44, 0x87, 0x3f, 0x0e, 0xa5, 0x39, 0x3d, 0xdf, 0xf5, 0x0d, 0x22, 0x30, 0xfe, 0x47, 0xe4, 0x79, 0xa4, 0x51, 0x98, 0x5c, 0xa1, 0xa0, 0x63, 0xd4, 0xae, 0x33, 0xc7, 0x88, 0x12, 0x73, 0x53, 0xec, 0x11, 0xb4, 0xa6, 0xee, 0x5d, 0xe9, 0x7b, 0x21, 0xff, 0x2b, 0xcb, 0xfa, 0x1d, 0x62, 0xcf, 0xf8, 0x3b, 0x2a, 0x14, 0xe3, 0x59, 0x7b, 0x76, 0xa5, 0x4f, 0xe0, 0x50, 0x59, 0x4e, 0x92, 0xf5, 0x09, 0x17, 0xff, 0xa9, 0xf9, 0x24, 0xe2, 0x94, 0x84, 0x45, 0x80, 0xa2, 0x0c, 0x7d, 0xa4, 0x48, 0x12, 0x3d, 0xa3, 0xe5, 0x09, 0x49, 0xf9, 0x1e, 0xfa, 0xc1, 0xa3, 0x23, 0x31, 0x95, 0x2d, 0x75, 0x13, 0x13, 0x2d, 0xac, 0x82, 0x9d, 0xbd, 0xc3, 0x45, 0x0c, 0xbe, 0xad, 0x8b, 0xf0, 0x4b, 0xbd, 0x5f, 0xf2, 0x5f, 0xa2, 0xfb, 0x98, 0xd5, 0xbd, 0x36, 0xb0, 0xf8, 0x09, 0xde, 0x0c, 0xc7, 0x67, 0xc1, 0x27, 0x9f, 0xe5, 0x60, 0xb7, 0x70, 0x8f, 0xbf, 0xf5, 0xef, 0x50, 0x49, 0xa1, 0x49, 0x25, 0x3d, 0x6b, 0xe9, 0x69, 0x4f, 0xee, 0x23, 0x94, 0xac, 0xfa, 0xe5, 0x10, 0x78, 0x34, 0xf8, 0xc6, 0x97, 0x20, 0xf2, 0x36, 0x86, 0x10, 0x32, 0x87, 0x27, 0x9d, 0xd3, 0xb1, 0x01, 0xcd, 0xaf, 0x61, 0x08, 0xab, 0x0f, 0x62, 0x5d, 0xf8, 0x10, 0xe1, 0x3b, 0x00, 0x4b, 0x7a, 0xdb, 0x10, 0xba, 0x1e, 0x3a, 0xbe, 0xd1, 0x47, 0xe8, 0x37, 0xde, 0x13, 0x92, 0x5f, 0x4a, 0x83, 0x24, 0x76, 0xf2, 0x83, 0x36, 0x22, 0x95, 0xb9, 0xde, 0xfa, 0xe3, 0x96, 0x75, 0x32, 0x0b, 0x39, 0xb5, 0xfa, 0x9a, 0x30, 0x9e, 0x79, 0x8d, 0xc8, 0x97, 0x73, 0x8b, 0xd8, 0x60, 0xfa, 0x2f, 0xbb, 0x99, 0x54, 0xeb, 0x8b, 0x49, 0x24, 0x4e, 0x8c, 0x12, 0x22, 0xd5, 0xde, 0xc8, 0x4f, 0x65, 0x20, 0xd2, 0xfe, 0xc5, 0x4e, 0x65, 0x1a, 0x87, 0x22, 0x73, 0x63, 0xc4, 0x6c, 0xb5, 0x7f, 0xdd, 0x67, 0x54, 0x7d, 0x0c, 0x3e, 0x10, 0x92, 0x63, 0xb4, 0x4a, 0xd7, 0xc3, 0x5c, 0x65, 0x9a, 0x65, 0x05, 0xf9, 0xd0, 0x78, 0xed, 0xbd, 0x64, 0x11, 0x54, 0xc9, 0xa0, 0x88, 0xd5, 0xfe, 0x23, 0x60, 0x66, 0x90, 0x19, 0x2c, 0xc1, 0xd6, 0x45, 0xbe, 0xbb, 0x33, 0xbf, 0xa4, 0xbc, 0x0d, 0xb5, 0xce, 0x9d, 0xc1, 0xe3, 0x17, 0x84, 0xfc, 0xa1, 0x63, 0x0b, 0xf7, 0x89, 0x52, 0x70, 0xf9, 0x0b, 0x39, 0x7e, 0x21, 0x8d, 0x6e, 0x24, 0x8e, 0xdd, 0xd6, 0xea, 0x41, 0x94, 0x0e, 0x02, 0xf6, 0xc9, 0x77, 0x77, 0x97, 0x61, 0xd5, 0x86, 0x55, 0xb6, 0xda, 0x0e, 0x48, 0x2a, 0xac, 0xf7, 0x77, 0xd0, 0xf9, 0x02, 0x47, 0xba, 0xb6, 0x4c, 0x7d, 0x4e, 0x6a, 0x9e, 0xd1, 0x67, 0xb2, 0x74, 0x32, 0xfb, 0x84, 0xb0, 0x06, 0xf4, 0x9c, 0x0b, 0xde, 0x89, 0x78, 0x87, 0xc1, 0x45, 0x91, 0x7d, 0x1b, 0x53, 0x86, 0xb2, 0xd1, 0x5f, 0x67, 0xea, 0x71, 0x25, 0x69, 0x64, 0xf7, 0x39, 0x9d, 0xa4, 0x35, 0x9b, 0xf5, 0x13, 0xc6, 0xbf, 0xda, 0x88, 0xff, 0x7e, 0x2e, 0x75, 0xfc, 0x67, 0x4e, 0xba, 0x0f, 0x85, 0x97, 0xe7, 0x8c, 0x6d, 0x7c, 0x1f, 0x4a, 0xba, 0xd6, 0x31, 0x4e, 0x50, 0x5b, 0x34, 0x2a, 0xa3, 0x2f, 0x25, 0x5b, 0xc2, 0x51, 0xdd, 0x2b, 0x52, 0x7e, 0x5f, 0xd6, 0xbb, 0x9a, 0x1d, 0x45, 0xc0, 0x80, 0x66, 0x82, 0x25, 0x02, 0xe4, 0x96, 0x94, 0xfc, 0xc3, 0xc0, 0xe1, 0xa1, 0x6c, 0x12, 0xbb, 0xd3, 0xc8, 0xf7, 0x7e, 0xe4, 0x73, 0x12, 0x98, 0x10, 0xfb, 0xbb, 0xb0, 0xa3, 0x7e, 0xcb, 0x03, 0xa0, 0xdc, 0xc7, 0xc2, 0x4d, 0xd9, 0x72, 0x73, 0x2b, 0xb5, 0xda, 0x7d, 0x3c, 0xcc, 0x7c, 0x6b, 0xa6, 0xea, 0x1c, 0x98, 0x33, 0x55, 0x4d, 0x81, 0xa3, 0x28, 0xc3, 0x2c, 0xfd, 0xe1, 0x3a, 0xba, 0xb6, 0x58, 0xab, 0xe4, 0xab, 0x51, 0xc7, 0x85, 0x09, 0xed, 0x52, 0x53, 0x58, 0xd6, 0x7b, 0x63, 0xfe, 0x9c, 0x11, 0x0d, 0xfb, 0x20, 0x67, 0xa4, 0x52, 0xbd, 0x8d, 0x97, 0x45, 0xae, 0x04, 0x0e, 0x66, 0xec, 0xb0, 0x8b, 0xa2, 0xdd, 0x9c, 0x44, 0xa3, 0x98, 0xdd, 0x57, 0x34, 0x0d, 0x65, 0xb8, 0x2e, 0x50, 0xd5, 0x60, 0x47, 0x7f, 0xcb, 0xd5, 0xac, 0xba, 0x2b, 0x21, 0xa5, 0x55, 0x7d, 0x77, 0xf7, 0x2d, 0x52, 0xf8, 0x0a, 0xd0, 0x7e, 0x3c, 0x7a, 0xad, 0x93, 0xc1, 0x1a, 0xcc, 0xea, 0xc1, 0x25, 0x1c, 0x31, 0x5a, 0x62, 0x15, 0x95, 0xbd, 0xc8, 0x61, 0xb3, 0xf5, 0x75, 0x96, 0x65, 0xad, 0x1f, 0x3c, 0x25, 0x06, 0xaa, 0x04, 0x43, 0x08, 0xf8, 0xc4, 0x31, 0x2d, 0x36, 0x49, 0x11, 0xcf, 0x02, 0xdf, 0xf0, 0x88, 0xde, 0x9a, 0x85, 0xe6, 0xdc, 0x81, 0x9d, 0x96, 0xb3, 0x82, 0x94, 0x3c, 0x44, 0x6d, 0xc1, 0xa9, 0x61, 0x80, 0x0c, 0x26, 0x6b, 0xfd, 0x06, 0x79, 0x51, 0xcc, 0xe5, 0xfe, 0x43, 0xa8, 0xc3, 0x46, 0xde, 0x64, 0xeb, 0xd9, 0x50, 0x49, 0x39, 0x2f, 0x0a, 0xe2, 0x7b, 0x64, 0x1b, 0xcd, 0x1e, 0xd9, 0x10, 0xf9, 0x17, 0x5d, 0xe4, 0x72, 0xaa, 0x83, 0xeb, 0x78, 0x50, 0x5f, 0x4b, 0xe4, 0xa8, 0x39, 0xc0, 0xd6, 0xb5, 0x74, 0x8e, 0xa4, 0xfb, 0x0e, 0xc5, 0xdb, 0x49, 0xfc, 0xd3, 0xa0, 0xc3, 0x6e, 0xcb, 0x71, 0x6d, 0xac, 0x26, 0x0e, 0xc9, 0x11, 0x1f, 0x26, 0x47, 0xf5, 0x10, 0x34, 0xd9, 0x7a, 0x8b, 0x78, 0x40, 0x54, 0x7f, 0x01, 0x9b, 0x85, 0xe8, 0x16, 0x7a, 0xe9, 0xb5, 0x43, 0x87, 0x33, 0x48, 0x3e, 0x53, 0x10, 0x3c, 0xa4, 0x0f, 0x38, 0xab, 0x52, 0x21, 0xb3, 0xba, 0xb5, 0xbf, 0x7c, 0x53, 0x49, 0x15, 0xf1, 0xe7, 0xf9, 0x5b, 0x20, 0xb3, 0xb2, 0xe6, 0x29, 0x19, 0x35, 0x97, 0x8f, 0x0f, 0xa5, 0x4f, 0xf3, 0xba, 0x72, 0x62, 0xd1, 0xc9, 0x7c, 0x5f, 0x3d, 0xd4, 0xe6, 0x9e, 0xe3, 0xe4, 0x7c, 0xb5, 0x33, 0x80, 0xf3, 0x72, 0x35, 0xfa, 0xbd, 0xa1, 0xab, 0xb3, 0x27, 0x02, 0x8d, 0x08, 0x7b, 0xc2, 0x19, 0x35, 0x90, 0x45, 0x8e, 0xd7, 0xab, 0xf0, 0xd1, 0x3a, 0x6b, 0xa9, 0xf2, 0xd6, 0x08, 0x47, 0x1b, 0xc6, 0xc3, 0x25, 0x2f, 0xd8, 0x93, 0x6a, 0x8e, 0x99, 0x99, 0xe5, 0x7e, 0x3c, 0xdd, 0xae, 0xc7, 0x7a, 0x0b, 0xc5, 0x34, 0xcc, 0x3c, 0xa0, 0xf9, 0xea, 0x4d, 0xcf, 0x34, 0x29, 0xa2, 0x2b, 0xd8, 0x9b, 0x27, 0xe4, 0x31, 0x05, 0x4a, 0x02, 0xab, 0x2e, 0x9a, 0x5b, 0x5e, 0xfe, 0xac, 0x1e, 0x60, 0xae, 0x84, 0xe8, 0x7a, 0x1b, 0x61, 0xac, 0xc8, 0x8d, 0x85, 0xbc, 0x99, 0x3f, 0xc7, 0x6a, 0x43, 0x7e, 0x1e, 0x02, 0xf1, 0x8e, 0x27, 0x7d, 0xbc, 0x65, 0xac, 0x4d, 0xcc, 0x9b, 0x0a, 0x5f, 0x1e, 0xf4, 0xc2, 0x73, 0x48, 0x4f, 0x2c, 0x08, 0x68, 0x08, 0x63, 0x5b, 0xb4, 0xb4, 0x53, 0x29, 0x5c, 0x1a, 0x6f, 0x63, 0xf9, 0xd5, 0xfe, 0x5e, 0xa3, 0x17, 0x8c, 0x2e, 0xee, 0x10, 0x51, 0x60, 0xd2, 0x43, 0x1a, 0x1a, 0xdf, 0x07, 0xd2, 0x3a, 0xc3, 0x94, 0xb4, 0xd2, 0x48, 0x34, 0xa6, 0xc6, 0xee, 0xe6, 0xd0, 0x96, 0xac, 0x85, 0xfb, 0x1d, 0x39, 0x6e, 0x0d, 0x0d, 0x1d, 0x60, 0x60, 0x3a, 0x78, 0xbd, 0x28, 0xdd, 0xe9, 0x88, 0x06, 0x6b, 0x09, 0x3d, 0x1c, 0x42, 0xe0, 0xef, 0x2e, 0x16, 0x7c, 0x1e, 0x2d, 0xa4, 0x80, 0x84, 0x60, 0xc8, 0x35, 0xa3, 0x39, 0x37, 0x8f, 0x45, 0x39, 0x0a, 0x30, 0x80, 0x51, 0xab, 0xab, 0x2a, 0x25, 0x00, 0xf4, 0x7a, 0x3e, 0xa7, 0x19, 0xd7, 0x9c, 0x14, 0xd2, 0xb1, 0x0b, 0xcb, 0xa3, 0xc6, 0xe2, 0x95, 0x5a, 0xec, 0x45, 0x8d, 0xfa, 0x36, 0xd1, 0xa0, 0x63, 0xf7, 0x03, 0xe4, 0xfb, 0xc8, 0xbc, 0x18, 0x51, 0x3b, 0x32, 0xc6, 0x4d, 0xdc, 0xc6, 0x5b, 0x11, 0x58, 0x39, 0xa6, 0x17, 0xe2, 0x9f, 0xbb, 0x58, 0x1d, 0x7f, 0xe5, 0x20, 0x8f, 0x90, 0x98, 0xbb, 0x2e, 0x9c, 0x09, 0x72, 0x8a, 0xfd, 0x63, 0x00, 0x44, 0xde, 0x03, 0xe1, 0xd7, 0xdf, 0xfb, 0x71, 0x70, 0x5b, 0xcc, 0x74, 0x85, 0x12, 0x99, 0x92, 0xc3, 0x02, 0xe3, 0x91, 0x16, 0x8d, 0xba, 0xcf, 0xb6, 0x95, 0xf6, 0xdf, 0xff, 0x8a, 0xce, 0xaf, 0x2b, 0x86, 0x38, 0x81, 0xbb, 0xe5, 0x71, 0x29, 0xfd, 0x8d, 0xcf, 0x2d, 0xc9, 0x53, 0xbf, 0xd9, 0x37, 0xec, 0x8b, 0xa2, 0x7d, 0x47, 0x47, 0x0f, 0x86, 0x6a, 0x5f, 0x55, 0xc6, 0xeb, 0x8c, 0x61, 0x98, 0x08, 0x73, 0x81, 0x33, 0x30, 0xe9, 0xd1, 0x14, 0x70, 0x18, 0xfc, 0xcd, 0x34, 0xd4, 0xfa, 0xd6, 0xb4, 0x10, 0x30, 0xce, 0xd8, 0x7b, 0x2e, 0x30, 0x8c, 0x62, 0x67, 0xf7, 0x73, 0x28, 0xc2, 0xb3, 0x77, 0xaf, 0xa4, 0x33, 0x2a, 0x10, 0xa6, 0x28, 0x2b, 0x5c, 0x16, 0x20, 0x0b, 0xdc, 0xbf, 0x19, 0x06, 0x9d, 0x17, 0xb4, 0x20, 0x75, 0x0c, 0xa3, 0x22, 0x18, 0x60, 0x1b, 0xe7, 0x42, 0x07, 0x9c, 0xfd, 0x6f, 0xb6, 0xe7, 0x50, 0x1f, 0xe0, 0x71, 0xe4, 0x5b, 0xfb, 0x24, 0xe9, 0x15, 0x3c, 0x2e, 0x58, 0x9d, 0x3f, 0xd6, 0x48, 0x0e, 0x31, 0x77, 0x33, 0xf4, 0x08, 0x33, 0x53, 0xff, 0x52, 0x16, 0x9e, 0xa2, 0xaf, 0x73, 0xf2, 0x20, 0x6d, 0x1b, 0x34, 0x46, 0xa4, 0xea, 0x71, 0xd1, 0xd4, 0x87, 0x11, 0xc6, 0x32, 0x28, 0xaf, 0xff, 0xb4, 0xb7, 0x38, 0xf6, 0xcb, 0x7a, 0x37, 0x80, 0xf7, 0x25, 0x8b, 0x1b, 0x8a, 0x72, 0x14, 0xe0, 0x32, 0x60, 0x96, 0x02, 0xd1, 0x03, 0xba, 0x95, 0x79, 0x01, 0x7c, 0x95, 0xef, 0x2a, 0xf8, 0xae, 0x12, 0x79, 0x27, 0x22, 0x3b, 0xdc, 0x56, 0x64, 0x5f, 0x40, 0xe0, 0x23, 0x22, 0x90, 0x7b, 0x35, 0x57, 0x6e, 0x2d, 0x7a, 0xf8, 0xf3, 0x30, 0x3c, 0x27, 0x1c, 0x8b, 0x35, 0x3a, 0x57, 0x49, 0xdb, 0x22, 0x58, 0x63, 0xd2, 0xaf, 0xa9, 0xd9, 0x25, 0x7c, 0x75, 0x11, 0xf9, 0xa7, 0x80, 0x53, 0x69, 0x47, 0x57, 0xe8, 0x4c, 0x67, 0xa3, 0x9d, 0x08, 0x77, 0x46, 0x36, 0x7a, 0x19, 0x03, 0x86, 0xdf, 0x36, 0x74, 0x44, 0x2a, 0x59, 0x16, 0x12, 0x1d, 0xe0, 0x0b, 0x86, 0xb2, 0x26, 0x97, 0xb9, 0x9d, 0x15, 0x5c, 0xcb, 0x64, 0xb1, 0x48, 0xfa, 0x91, 0x18, 0x57, 0x67, 0x05, 0x16, 0xfa, 0x64, 0x4e, 0xaf, 0x7d, 0xfe, 0xd9, 0x8d, 0x0f, 0x64, 0x57, 0x62, 0xac, 0x3b, 0xc9, 0xd4, 0x3c, 0xc9, 0x74, 0x50, 0x37, 0x00, 0x31, 0xd8, 0xc9, 0x2b, 0xa7, 0x3c, 0xf3, 0x1f, 0xf3, 0xe7, 0x39, 0xe8, 0x07, 0x77, 0x14, 0xd5, 0xb5, 0xdf, 0x07, 0x85, 0x5c, 0x03, 0x0d, 0xa9, 0xb9, 0x2c, 0x23, 0xdf, 0x20, 0xd7, 0x00, 0x64, 0xef, 0xf9, 0xe7, 0xee, 0x6f, 0x08, 0x46, 0xda, 0xb1, 0xd4, 0x72, 0x19, 0xad, 0x9e, 0x2a, 0xa2, 0x32, 0x7f, 0x59, 0x2a, 0x87, 0x47, 0xdb, 0x56, 0x5c, 0x85, 0x4a, 0x2e, 0xa6, 0x11, 0xe4, 0x27, 0xfb, 0x04, 0x61, 0xb3, 0xc6, 0x35, 0x2c, 0xa6, 0x3c, 0xb3, 0xf7, 0xf6, 0xae, 0x16, 0x30, 0xae, 0x1e, 0x94, 0x1e, 0x81, 0x8f, 0xd1, 0xbb, 0x40, 0x44, 0x7a, 0x68, 0xe5, 0x6c, 0xf2, 0xf4, 0x7d, 0xcd, 0x55, 0xcf, 0x8e, 0x3f, 0xd3, 0x02, 0x89, 0x5e, 0x14, 0x71, 0x15, 0xd0, 0x10, 0xe1, 0x23, 0xab, 0xee, 0x8b, 0xad, 0x1c, 0x27, 0xc2, 0xd5, 0x74, 0xf7, 0xc8, 0x4b, 0x98, 0xfb, 0xac, 0x58, 0xdc, 0x9e, 0x5f, 0xad, 0x5d, 0x2d, 0xc4, 0xe6, 0x70, 0xe8, 0x9e, 0x96, 0xb0, 0xed, 0x28, 0x64, 0x08, 0x34, 0x37, 0xe4, 0x11, 0xe0, 0xd7, 0xd0, 0x84, 0xa0, 0x4b, 0xb2, 0x50, 0x03, 0xfe, 0x92, 0x75, 0x55, 0x33, 0x82, 0x1e, 0x74, 0x73, 0x93, 0x3b, 0xf1, 0x8d, 0x8b, 0x35, 0x9f, 0xac, 0x3d, 0x3c, 0xa9, 0x54, 0xe7, 0xbe, 0x13, 0xbc, 0xc1, 0x6b, 0x91, 0xd4, 0x64, 0xbd, 0x43, 0x22, 0x76, 0x8d, 0x22, 0x97, 0x5a, 0xd0, 0xb9, 0x64, 0x17, 0x7b, 0x95, 0x14, 0x67, 0x81, 0x14, 0xec, 0x1d, 0xac, 0x60, 0x39, 0x5d, 0x90, 0x67, 0x2d, 0xd8, 0x6e, 0x09, 0xbf, 0xa7, 0x50, 0x46, 0xf8, 0xe1, 0xd2, 0x7a, 0xbd, 0x6e, 0xe0, 0xbc, 0xa3, 0xbf, 0x60, 0x7b, 0x6f, 0xdf, 0x0d, 0x8c, 0x2e, 0xd6, 0x15, 0xf5, 0x8e, 0x76, 0x80, 0xad, 0x1d, 0x94, 0x6f, 0xcc, 0x1e, 0x54, 0x8f, 0xb1, 0xd6, 0x38, 0x4e, 0xfa, 0x0a, 0xea, 0x32, 0xef, 0xc0, 0xf1, 0xf9, 0x79, 0x54, 0xaa, 0x80, 0x6c, 0x77, 0x30, 0xc7, 0xa9, 0xd4, 0x5d, 0x28, 0x5d, 0x40, 0x07, 0x01, 0xa7, 0xa3, 0x86, 0x09, 0x77, 0x9e, 0x28, 0x21, 0x9f, 0xdd, 0xa6, 0xd9, 0x71, 0x5b, 0x11, 0x65, 0x9c, 0x45, 0x36, 0x4a, 0x9b, 0xb1, 0x52, 0x01, 0xd5, 0x8d, 0x45, 0x9a, 0x49, 0x93, 0x28, 0xef, 0x5f, 0x55, 0xa4, 0xd1, 0x13, 0xd8, 0xf1, 0x6b, 0x75, 0x09, 0xb4, 0xd5, 0x56, 0x6a, 0x22, 0x68, 0xa3, 0x9d, 0x4f, 0x4e, 0xba, 0x01, 0xf0, 0xf2, 0x59, 0xa6, 0x39, 0x49, 0x32, 0xc0, 0xca, 0xd4, 0xcf, 0x82, 0x55, 0x0d, 0x24, 0xa3, 0xda, 0x4f, 0xab, 0x86, 0x43, 0x69, 0xfc, 0xad, 0xc2, 0x2b, 0x54, 0xa6, 0x49, 0x19, 0x4c, 0x9e, 0x4f, 0x0e, 0x28, 0xad, 0xcf, 0x63, 0xc8, 0x82, 0x1d, 0x5d, 0x6f, 0x8e, 0x53, 0x8c, 0xcd, 0x98, 0x16, 0x49, 0x45, 0x8e, 0xc0, 0xc2, 0x89, 0xc6, 0x5f, 0xb3, 0x75, 0x9f, 0xf5, 0xdf, 0xeb, 0x09, 0x24, 0xcf, 0x94, 0x52, 0x50, 0x94, 0xf9, 0x3e, 0xb1, 0xea, 0xf4, 0x9c, 0x5f, 0x82, 0xeb, 0xbd, 0x44, 0xd6, 0xba, 0xe0, 0x9a, 0xb1, 0x63, 0xde, 0x09, 0xf7, 0x14, 0xd6, 0x0c, 0x8f, 0x6f, 0x40, 0xdd, 0x14, 0x5e, 0xbf, 0x4e, 0xf0, 0xfa, 0xe9, 0xd0, 0x3c, 0x81, 0x6c, 0x89, 0x75, 0x3f, 0x22, 0xff, 0x45, 0x33, 0xde, 0x57, 0x8b, 0x64, 0xb1, 0x9a, 0x72, 0x8e, 0xfa, 0xba, 0x2e, 0xba, 0x18, 0xbe, 0x46, 0x87, 0x56, 0x68, 0xa0, 0xe4, 0xe9, 0xc1, 0x56, 0xbd, 0x03, 0x98, 0xb0, 0x85, 0x6b, 0x79, 0x2b, 0x2c, 0xde, 0x8b, 0x44, 0xcb, 0x2d, 0xd6, 0x6b, 0xd6, 0x5b, 0x63, 0x9e, 0xb8, 0xef, 0xa8, 0x62, 0x72, 0xc8, 0x39, 0xad, 0x66, 0xef, 0x4d, 0x27, 0x85, 0x9c, 0x21, 0x3d, 0x15, 0xbf, 0xcf, 0xd4, 0xd4, 0xbc, 0x3e, 0x10, 0x6f, 0x60, 0xf6, 0x34, 0xee, 0x66, 0xa4, 0x75, 0x80, 0x8d, 0x23, 0x46, 0xcd, 0x55, 0x2d, 0x28, 0x06, 0xcc, 0x79, 0x6b, 0x20, 0xe5, 0x9b, 0x47, 0xae, 0x26, 0xad, 0x1c, 0x12, 0x18, 0xf1, 0x36, 0xab, 0x62, 0x05, 0x5e, 0x67, 0x42, 0x55, 0x97, 0x49, 0x3e, 0x92, 0xd9, 0xd7, 0x8d, 0x21, 0x70, 0x49, 0xc7, 0xb0, 0x3e, 0x59, 0x1a, 0x07, 0x62, 0xb5, 0xa0, 0x18, 0xbf, 0xc0, 0xad, 0xd0, 0x06, 0x60, 0x75, 0xf8, 0x1e, 0xa7, 0x29, 0xc0, 0x0e, 0x9e, 0xbb, 0xc3, 0x62, 0x09, 0x70, 0x6f, 0x57, 0x00, 0x69, 0xb3, 0x49, 0x2f, 0xc7, 0xc0, 0x58, 0x5e, 0x12, 0xbf, 0x85, 0x00, 0xec, 0xcc, 0x5c, 0x9a, 0x00, 0x92, 0xa9, 0x88, 0xa3, 0x51, 0x7a, 0x17, 0xe2, 0x53, 0x50, 0x3d, 0x70, 0x73, 0x6a, 0xa5, 0xbb, 0x2c, 0xa8, 0x24, 0x6b, 0xcf, 0x98, 0xc5, 0xc3, 0x18, 0xa0, 0x16, 0x20, 0x98, 0x2b, 0xdc, 0xb1, 0xae, 0xcb, 0x92, 0xb9, 0xa6, 0x7f, 0x75, 0x4d, 0xa5, 0x17, 0xbd, 0x96, 0xc8, 0xc4, 0xca, 0xb8, 0x0e, 0x2c, 0xec, 0x06, 0x90, 0x53, 0x0f, 0xf4, 0x4a, 0x5f, 0x19, 0x36, 0x8b, 0xb9, 0xac, 0x14, 0x4e, 0x1f, 0xba, 0x01, 0x9b, 0x57, 0x1f, 0x41, 0x59, 0x1d, 0x8b, 0x17, 0x3a, 0x4f, 0xf0, 0x7b, 0xea, 0xff, 0x5c, 0x9c, 0xf9, 0xa4, 0x4a, 0xd0, 0xd0, 0x08, 0x40, 0x52, 0x07, 0xed, 0xc1, 0xcf, 0xf0, 0x12, 0xc5, 0x8c, 0xc2, 0x2b, 0xf7, 0xd9, 0x49, 0xf0, 0x88, 0x7f, 0x01, 0x27, 0x83, 0xcc, 0x9b, 0x64, 0xc1, 0xf4, 0x1d, 0x37, 0x84, 0xea, 0x8e, 0xbf, 0x5f, 0x0d, 0xed, 0x5b, 0x17, 0xc2, 0x93, 0x09, 0x2a, 0xa2, 0x50, 0x9d, 0xa1, 0xdd, 0x5a, 0x73, 0x41, 0xf8, 0x50, 0xf5, 0x67, 0x4b, 0xd2, 0x1b, 0xbf, 0xe4, 0xf5, 0x5d, 0x47, 0x7e, 0x70, 0x53, 0xa3, 0x72, 0xe8, 0x8a, 0x6f, 0xf2, 0x27, 0x53, 0xe1, 0xbe, 0x5b, 0xd8, 0xe8, 0x61, 0x0e, 0x3d, 0xf5, 0x82, 0x42, 0x77, 0x6e, 0x12, 0xcf, 0x99, 0xba, 0x5b, 0x34, 0x63, 0xd6, 0xb6, 0xf5, 0x61, 0x8d, 0xc1, 0x8b, 0x2d, 0x07, 0x58, 0x52, 0xf5, 0xb8, 0x33, 0x40, 0x45, 0x5f, 0x67, 0xc5, 0x34, 0xe7, 0xa8, 0xfa, 0x99, 0xdc, 0x7c, 0x9e, 0x19, 0x54, 0x72, 0x57, 0xa5, 0xa8, 0x4d, 0xb9, 0x19, 0x65, 0x3b, 0x23, 0x4f, 0xf6, 0x4c, 0x37, 0xbd, 0xa3, 0x81, 0x4f, 0x3c, 0x46, 0x79, 0x17, 0xe0, 0xb1, 0x43, 0x37, 0x0e, 0xd1, 0xa2, 0xc6, 0xc6, 0x8f, 0xf3, 0x86, 0x2b, 0x2e, 0xf3, 0x85, 0x0a, 0xff, 0xfc, 0xf3, 0x61, 0x13, 0xb5, 0x98, 0x0d, 0xb7, 0x9a, 0x5e, 0x13, 0xaf, 0x6e, 0x99, 0xcc, 0x24, 0xbd, 0x95, 0x76, 0xbc, 0x7e, 0x2b, 0x44, 0x63, 0x78, 0x23, 0x1b, 0x1e, 0x65, 0x76, 0xc8, 0xfb, 0xaf, 0xe5, 0x1c, 0x79, 0xb8, 0x67, 0x5c, 0xb0, 0xf0, 0xdd, 0x37, 0xb7, 0xce, 0xe8, 0x70, 0x59, 0xfb, 0xdf, 0x71, 0x56, 0x0d, 0xa7, 0x6c, 0x5a, 0xc1, 0x8f, 0x4e, 0xab, 0x2e, 0x25, 0x35, 0xe5, 0x1b, 0x68, 0x46, 0x57, 0x61, 0x3c, 0x8b, 0x6e, 0xc4, 0xe7, 0x53, 0xb1, 0x40, 0xdb, 0x0b, 0x79, 0x83, 0x35, 0x81, 0x1e, 0x60, 0x3d, 0x4c, 0xb6, 0xcc, 0x95, 0xb3, 0xb9, 0x27, 0x45, 0xa5, 0x23, 0x4d, 0xa8, 0x3e, 0xec, 0x86, 0x34, 0xfb, 0x99, 0x66, 0x82, 0x3d, 0xab, 0x6d, 0x82, 0x5c, 0x79, 0xa4, 0x92, 0x2a, 0x49, 0xc7, 0xa9, 0x8f, 0x9f, 0x4c, 0xac, 0xcf, 0x8a, 0xd2, 0xe9, 0x44, 0xd3, 0x91, 0x5a, 0x3f, 0x9d, 0xde, 0xbc, 0xfb, 0x85, 0x80, 0xbd, 0xc6, 0x0a, 0xa8, 0xc9, 0x63, 0x73, 0xfa, 0x6c, 0xc4, 0xfc, 0x62, 0xb7, 0x33, 0xa2, 0x16, 0x0a, 0xdf, 0x1b, 0x5f, 0x2d, 0x3a, 0x17, 0xc5, 0x90, 0xf3, 0x73, 0x74, 0x45, 0xfa, 0x86, 0xd6, 0xa8, 0xcc, 0x37, 0x0f, 0x95, 0x99, 0x65, 0xf3, 0xd2, 0x55, 0x2e, 0x93, 0x4a, 0x17, 0x55, 0x23, 0x24, 0x96, 0x27, 0x7f, 0xe8, 0x70, 0x61, 0x99, 0xac, 0x83, 0x4f, 0xe4, 0x99, 0xc4, 0x44, 0x63, 0x28, 0x66, 0xe8, 0xc7, 0x26, 0x8d, 0x85, 0x34, 0xa2, 0x7e, 0x17, 0x67, 0x38, 0xa4, 0x1e, 0xc4, 0xdd, 0x58, 0x58, 0xe4, 0xd4, 0x2f, 0xeb, 0x24, 0x91, 0x9e, 0x6c, 0x71, 0x51, 0x19, 0x7b, 0xc8, 0xe0, 0x04, 0xda, 0x82, 0xb9, 0x7e, 0xcd, 0xa8, 0xfa, 0xd5, 0x2f, 0xe2, 0x13, 0xe6, 0x41, 0x84, 0x66, 0xb3, 0x28, 0xba, 0x37, 0x8f, 0xd0, 0xe4, 0xf8, 0x7b, 0x60, 0xa8, 0xf5, 0x09, 0x0b, 0x46, 0x34, 0xda, 0xa4, 0x78, 0x72, 0xf0, 0x63, 0x1d, 0xf9, 0xfc, 0x84, 0xf9, 0xaa, 0xd2, 0x03, 0xa0, 0xa2, 0x4a, 0xd5, 0x33, 0xad, 0x71, 0xb6, 0x7b, 0x91, 0xb2, 0x98, 0x82, 0x38, 0xd8, 0xc1, 0xd2, 0x2a, 0x70, 0xc7, 0xb3, 0xb9, 0x8f, 0xd9, 0x90, 0x9c, 0x87, 0x86, 0x22, 0xcf, 0x7f, 0x63, 0x0a, 0x23, 0xf9, 0xbb, 0x72, 0x75, 0x84, 0xad, 0xc6, 0xf2, 0x1a, 0x90, 0x37, 0xb2, 0xb4, 0xc0, 0xa9, 0x0b, 0xff, 0xce, 0x6a, 0xf3, 0x48, 0xcb, 0x34, 0x0a, 0x9f, 0x6e, 0x71, 0xf1, 0xee, 0x57, 0x9e, 0x46, 0xef, 0xab, 0xd6, 0x39, 0xff, 0xc6, 0xc6, 0x22, 0xf1, 0x5a, 0x24, 0x51, 0xe7, 0xa7, 0xba, 0x51, 0xe3, 0xa7, 0x4c, 0x6a, 0xa4, 0x52, 0x0c, 0x2c, 0x19, 0x14, 0x6e, 0x22, 0x89, 0xb4, 0x24, 0xae, 0x2e, 0x5c, 0x38, 0x11, 0x6d, 0x78, 0x44, 0xf1, 0xa3, 0xd2, 0x9f, 0xad, 0x62, 0x88, 0x32, 0x68, 0xe2, 0x68, 0xc8, 0x98, 0xce, 0x28, 0x8a, 0x64, 0xa0, 0x0f, 0xac, 0x65, 0x17, 0x2c, 0x3a, 0x14, 0x7f, 0x9a, 0x89, 0x37, 0x13, 0x8a, 0x4e, 0x46, 0xdb, 0xe0, 0x67, 0x88, 0x21, 0xde, 0x41, 0x97, 0x11, 0x67, 0xc0, 0xee, 0xa2, 0x13, 0xfc, 0x10, 0x15, 0xcf, 0xa0, 0xe4, 0x66, 0x65, 0x18, 0xfa, 0x91, 0xa9, 0x1e, 0x1c, 0x06, 0x8d, 0x69, 0x9c, 0xf5, 0x4a, 0x78, 0xc4, 0x9b, 0xc0, 0x0a, 0x97, 0xfe, 0x89, 0x64, 0x7a, 0xab, 0xf9, 0xcd, 0xaa, 0xeb, 0x24, 0xd7, 0x28, 0x76, 0x09, 0xd0, 0x44, 0xbe, 0x3e, 0x67, 0x2a, 0x7a, 0xac, 0xc7, 0x8f, 0xff, 0x4e, 0x42, 0x62, 0x05, 0x5a, 0x64, 0x82, 0x6c, 0x25, 0xa9, 0xaf, 0xe5, 0x78, 0xa3, 0x9c, 0x13, 0x4d, 0xe3, 0x88, 0x91, 0x05, 0x55, 0x9b, 0xa8, 0x38, 0xfa, 0x68, 0x82, 0x83, 0x58, 0xb2, 0xdd, 0x80, 0xbe, 0xc2, 0xa5, 0x79, 0x73, 0x40, 0xd8, 0x0d, 0xf7, 0x48, 0x49, 0x52, 0x1f, 0x6e, 0xc0, 0xd4, 0x61, 0x9f, 0x09, 0x9a, 0xb3, 0x99, 0x60, 0x68, 0x55, 0x01, 0xd7, 0x02, 0xc2, 0x6d, 0x7c, 0x47, 0xae, 0xc3, 0x6b, 0x6a, 0x7d, 0xce, 0xdd, 0xe7, 0x1c, 0x57, 0x0f, 0xc2, 0x88, 0x04, 0xe1, 0x97, 0x25, 0x0d, 0x8c, 0xe3, 0x89, 0x15, 0x19, 0x67, 0x11, 0x04, 0x61, 0xbf, 0x5b, 0xe7, 0x7c, 0x21, 0x5c, 0xb9, 0x26, 0xc2, 0x94, 0xc4, 0x5a, 0xcc, 0xc6, 0x83, 0xc1, 0x21, 0x04, 0x5c, 0x77, 0x88, 0xd8, 0xcb, 0x6a, 0x87, 0xbb, 0xc6, 0x10, 0x6b, 0x85, 0xbd, 0xcb, 0xc0, 0x97, 0xde, 0x99, 0x89, 0xde, 0xeb, 0x7f, 0xd3, 0xb2, 0x8c, 0x87, 0xb3, 0x0f, 0xca, 0xf5, 0xf6, 0x46, 0xb1, 0x8d, 0x03, 0xfc, 0xfb, 0x03, 0xd6, 0x0e, 0xf1, 0xe4, 0x5c, 0x3e, 0x3b, 0x99, 0x26, 0xb4, 0xd6, 0xde, 0xb2, 0xc4, 0x64, 0xa6, 0xed, 0x99, 0x9e, 0x14, 0x0a, 0x75, 0xbe, 0xfc, 0x36, 0xd0, 0x75, 0xf9, 0x00, 0xbd, 0x2e, 0x79, 0xd0, 0x4a, 0x90, 0xbe, 0xc6, 0x47, 0xe8, 0x33, 0xd3, 0x5a, 0x6e, 0x83, 0xc5, 0xd1, 0xd7, 0xe2, 0xe0, 0x49, 0x5f, 0xd7, 0x3b, 0x08, 0x65, 0x6c, 0x5f, 0x0b, 0x92, 0xb8, 0x14, 0x32, 0x3f, 0xaf, 0xce, 0x37, 0x07, 0x53, 0x6c, 0x10, 0x5b, 0x1f, 0x7b, 0x1b, 0x53, 0x87, 0xda, 0xe0, 0xd8, 0x4d, 0x0f, 0xea, 0xeb, 0x7a, 0x48, 0xc2, 0xee, 0x40, 0x99, 0x22, 0x2b, 0x08, 0x10, 0xda, 0x2c, 0x67, 0xe9, 0x24, 0x14, 0x82, 0xfc, 0x5c, 0xfd, 0x76, 0xe5, 0x5c, 0xb4, 0x2b, 0xd0, 0x40, 0x4d, 0xc9, 0x48, 0x7a, 0xbb, 0xc3, 0xef, 0xb2, 0x45, 0x54, 0xae, 0xc2, 0x23, 0x1f, 0x9c, 0x5d, 0x53, 0x59, 0xc8, 0xd9, 0x36, 0x81, 0x55, 0xd0, 0xf8, 0x32, 0x7e, 0x14, 0xce, 0xd9, 0x6b, 0x2b, 0x31, 0x2e, 0xf5, 0x47, 0x7f, 0x6d, 0xd1, 0x2e, 0x09, 0xff, 0xad, 0x5d, 0x14, 0x32, 0x94, 0x97, 0x39, 0xc3, 0xcb, 0xc4, 0x2f, 0x79, 0x44, 0xfe, 0xc1, 0x1f, 0x8c, 0x23, 0xe1, 0xd6, 0xca, 0xae, 0xb0, 0x40, 0x33, 0xec, 0x7b, 0x2f, 0xf6, 0xdc, 0xf1, 0xfd, 0xf5, 0xe1, 0x81, 0xd0, 0x79, 0xac, 0xea, 0xce, 0x77, 0xb4, 0x8e, 0x3e, 0x64, 0xad, 0x5f, 0x60, 0x57, 0xbc, 0x6e, 0xcc, 0xc3, 0x65, 0x80, 0x94, 0x7c, 0xc5, 0x4b, 0x1b, 0x58, 0x9e, 0x7f, 0xc6, 0x70, 0xa2, 0xa3, 0xf6, 0xda, 0xd5, 0xe6, 0xab, 0xb1, 0x24, 0x97, 0x72, 0x4c, 0xce, 0xfa, 0x9a, 0xa7, 0x48, 0x1d, 0xb2, 0x5a, 0xef, 0x86, 0xbe, 0xd1, 0xef, 0xb5, 0x02, 0x1e, 0x89, 0xe9, 0x0b, 0x91, 0x51, 0xe6, 0xd7, 0x27, 0x7e, 0x12, 0xa8, 0x35, 0x1a, 0xd6, 0xd8, 0x01, 0x0e, 0x0f, 0xc2, 0x68, 0x66, 0x7b, 0x9c, 0x5f, 0xaa, 0xa4, 0x2d, 0xbe, 0x6a, 0x3c, 0xc3, 0x80, 0x43, 0x1f, 0x95, 0x84, 0xeb, 0x48, 0xa1, 0xfc, 0x36, 0x16, 0x75, 0xec, 0xa6, 0x56, 0x6f, 0x4d, 0xdc, 0xbe, 0x54, 0x08, 0x7c, 0x67, 0xdd, 0xbd, 0x8d, 0xfc, 0x59, 0x08, 0x0d, 0x97, 0x7a, 0x12, 0x0d, 0x75, 0x23, 0x3f, 0xd1, 0x72, 0xe6, 0xc3, 0xfc, 0x77, 0xdc, 0x6f, 0x99, 0x9e, 0x53, 0x61, 0x1f, 0x0b, 0xc2, 0xf3, 0xba, 0x8a, 0x84, 0x67, 0x00, 0x8f, 0xf7, 0xf2, 0x55, 0x2b, 0x98, 0x73, 0x95, 0x72, 0x32, 0x9e, 0x8c, 0xce, 0x00, 0x51, 0xc4, 0x9e, 0x8f, 0x6b, 0xc7, 0x92, 0x69, 0x13, 0x2f, 0x2e, 0x3c, 0x6a, 0x4c, 0x70, 0x41, 0x9f, 0x29, 0xe8, 0x06, 0x5f, 0x60, 0x0e, 0x3f, 0x48, 0x65, 0x74, 0xba, 0xb8, 0x15, 0xa5, 0x2c, 0x91, 0x2a, 0x35, 0x7a, 0x3a, 0x6b, 0xa8, 0xee, 0x93, 0x44, 0x80, 0x67, 0xba, 0xb9, 0xa6, 0xa9, 0x43, 0x74, 0xe1, 0xc3, 0x2d, 0x82, 0x91, 0xb0, 0x86, 0xe5, 0x1e, 0x66, 0x2f, 0xaa, 0x6f, 0xb8, 0x77, 0x28, 0x82, 0x0e, 0x78, 0x03, 0x4a, 0x46, 0xe0, 0xa0, 0xf8, 0xa1, 0xb7, 0x62, 0xb1, 0x4a, 0x0a, 0x12, 0xbb, 0xb9, 0x2e, 0xf1, 0x58, 0x12, 0x77, 0x83, 0x59, 0xdd, 0xce, 0x3e, 0xf7, 0x57, 0xb3, 0x61, 0x57, 0xb6, 0x6e, 0xaa, 0xef, 0xc0, 0xdd, 0xf6, 0xef, 0xd8, 0xd0, 0xf1, 0x88, 0xe5, 0x09, 0x59, 0xe7, 0xe1, 0x5d, 0x82, 0x3e, 0xe5, 0xa2, 0x23, 0x88, 0x59, 0xd9, 0x8b, 0xf7, 0xe5, 0x06, 0x93, 0xfa, 0x21, 0xbb, 0x21, 0x40, 0xf0, 0x0a, 0xb7, 0xb5, 0x7e, 0x29, 0x2d, 0x20, 0x52, 0xa8, 0x91, 0x3b, 0x76, 0x64, 0x20, 0x23, 0xfd, 0x60, 0x46, 0x1f, 0x1c, 0xbf, 0xcd, 0xeb, 0x4c, 0xcc, 0xeb, 0x0f, 0xb1, 0xb5, 0x5c, 0x55, 0xbe, 0x46, 0x79, 0xf0, 0xe3, 0x2e, 0xc4, 0xc4, 0x2c, 0x26, 0xa5, 0x16, 0x17, 0xb3, 0xcd, 0xea, 0x86, 0x6a, 0x94, 0x0f, 0x65, 0x84, 0xfa, 0xe3, 0x7a, 0x77, 0xee, 0x16, 0x06, 0x2f, 0xdd, 0xb3, 0xfe, 0x87, 0xb5, 0x96, 0xe2, 0x22, 0xcc, 0x47, 0xd6, 0x27, 0x73, 0xd3, 0xff, 0xb1, 0xfe, 0xb6, 0xc2, 0xa4, 0xa8, 0x43, 0x4e, 0xee, 0xd4, 0x0f, 0x6d, 0x2d, 0x2e, 0x1b, 0xca, 0x7d, 0x52, 0x4d, 0xc3, 0x6f, 0xcf, 0xc2, 0xc6, 0xe8, 0x52, 0xbe, 0xb3, 0x80, 0xde, 0xe7, 0x04, 0x27, 0x67, 0xcc, 0xb5, 0x58, 0x11, 0xf4, 0x49, 0x53, 0xe0, 0x52, 0xe9, 0x1d, 0xe3, 0x49, 0xb4, 0x5c, 0x83, 0x00, 0x25, 0x7c, 0x25, 0x0d, 0x40, 0xa3, 0x4e, 0x43, 0x90, 0xa8, 0xaf, 0x27, 0xb2, 0x24, 0xe5, 0xee, 0xc1, 0x81, 0x65, 0xcd, 0xea, 0x4d, 0x15, 0xf4, 0x3e, 0x48, 0xe7, 0xdd, 0xd1, 0x46, 0x34, 0x99, 0xca, 0x5a, 0x92, 0xbe, 0x5b, 0xaa, 0xec, 0xd9, 0x1f, 0x05, 0xd1, 0x23, 0xa5, 0xe3, 0xe2, 0x9f, 0x5a, 0x14, 0xac, 0x49, 0x8f, 0x88, 0x2b, 0xfc, 0xaf, 0xb2, 0x25, 0xd7, 0xc3, 0x4e, 0xe3, 0xf7, 0xfa, 0x42, 0x27, 0x46, 0x03, 0xd6, 0x5e, 0xd2, 0xab, 0x6b, 0x58, 0x37, 0xdc, 0xdb, 0x9f, 0x59, 0x3b, 0x01, 0xf3, 0x51, 0x1b, 0x8c, 0x87, 0xca, 0xdd, 0x18, 0x85, 0xc6, 0xb8, 0xb1, 0x5b, 0x6a, 0x14, 0x91, 0x60, 0x56, 0xea, 0xbe, 0xf0, 0x0a, 0xbb, 0x35, 0xe8, 0xcb, 0x3a, 0xad, 0x13, 0xa8, 0xc8, 0xd8, 0xb3, 0xf6, 0xff, 0xf6, 0xd6, 0xad, 0xcb, 0xe1, 0x4c, 0x07, 0xc3, 0x2e, 0x6b, 0xd3, 0x5b, 0x33, 0xd1, 0x29, 0x6f, 0x0b, 0x06, 0x40, 0xeb, 0x27, 0x57, 0x56, 0x45, 0x5b, 0xc7, 0x0c, 0x5d, 0x23, 0xd7, 0x27, 0x39, 0x64, 0x97, 0x7f, 0xd4, 0x21, 0x86, 0xb1, 0xb2, 0x06, 0xbb, 0xbf, 0xce, 0x64, 0x54, 0x33, 0xe8, 0x7d, 0x6c, 0x88, 0xc3, 0x5f, 0xf2, 0x65, 0xc1, 0x4b, 0xe1, 0xbd, 0x0a, 0x6b, 0x8d, 0x17, 0x0d, 0x7c, 0x8c, 0xdd, 0xda, 0x95, 0x97, 0xf1, 0xc9, 0x80, 0x1e, 0xdc, 0x3c, 0x0b, 0xe7, 0x05, 0xeb, 0xa7, 0x48, 0x5b, 0xe3, 0x00, 0xb8, 0x33, 0xa6, 0x2f, 0xff, 0xa7, 0xdc, 0x7d, 0xec, 0x8a, 0x30, 0xd1, 0x4b, 0x09, 0x2c, 0x46, 0x2c, 0x1b, 0x87, 0x59, 0x39, 0x66, 0x02, 0xd6, 0x1e, 0x08, 0x82, 0x02, 0x46, 0x43, 0x50, 0xba, 0xc3, 0x34, 0x65, 0xcc, 0x15, 0x15, 0x85, 0x38, 0x64, 0xcc, 0x02, 0x82, 0x28, 0xc7, 0xd4, 0xd4, 0x29, 0x6b, 0x06, 0x76, 0x41, 0x8c, 0x34, 0xa3, 0xfc, 0xf7, 0x38, 0x4c, 0x54, 0x52, 0x48, 0xd3, 0x25, 0xaa, 0xee, 0xc8, 0xe0, 0xf5, 0x02, 0x4c, 0xcc, 0xc0, 0x84, 0xd2, 0x43, 0x0b, 0xd9, 0xb4, 0x7c, 0xc4, 0x9b, 0xb5, 0x52, 0x55, 0x5d, 0x34, 0x79, 0xc9, 0xbc, 0xf7, 0x57, 0xce, 0xa6, 0x44, 0x09, 0x85, 0xbe, 0xbe, 0xaf, 0x14, 0xaa, 0x95, 0x7c, 0x5d, 0x03, 0x71, 0xc4, 0x53, 0xda, 0x65, 0x75, 0x4d, 0x33, 0x3d, 0x23, 0x31, 0x89, 0xdf, 0xe1, 0x78, 0x35, 0x64, 0x48, 0x21, 0xe5, 0x77, 0x1a, 0xc8, 0xa3, 0x31, 0x6d, 0xb3, 0x4a, 0xdb, 0x0b, 0xf3, 0x3e, 0x56, 0xdc, 0xd8, 0x93, 0x53, 0x40, 0x91, 0x3d, 0xcc, 0xcf, 0xdf, 0x79, 0x7c, 0x1a, 0x80, 0x98, 0x2c, 0xf6, 0xa5, 0x70, 0x45, 0x42, 0x33, 0xe5, 0xea, 0xe2, 0x5e, 0x2e, 0x71, 0x0f, 0x4f, 0xfc, 0x62, 0x31, 0x9b, 0x48, 0xf6, 0x8f, 0x51, 0xf6, 0x23, 0xca, 0xb4, 0x95, 0x97, 0xc2, 0xfe, 0x0d, 0x09, 0x7d, 0x8e, 0xde, 0x3f, 0x1d, 0xfc, 0x49, 0x5a, 0xfb, 0xb2, 0x6a, 0x10, 0x0c, 0xe5, 0xf1, 0x8a, 0x6a, 0x14, 0x75, 0x14, 0xe4, 0x60, 0x3c, 0xac, 0xc3, 0x4e, 0xfb, 0xef, 0x69, 0xe9, 0x90, 0x09, 0x9a, 0xcb, 0xa1, 0x60, 0xcd, 0x3f, 0x8e, 0xba, 0x0b, 0x80, 0x5e, 0xf4, 0x97, 0x6a, 0x0b, 0xe0, 0xc7, 0x0b, 0xbe, 0x18, 0xc3, 0x5a, 0x6e, 0x99, 0x40, 0x9a, 0xc7, 0x9a, 0x8d, 0x42, 0x03, 0x80, 0x8b, 0x97, 0x35, 0xdd, 0xe6, 0x00, 0xf5, 0x3b, 0x44, 0xd1, 0x86, 0x87, 0x7f, 0xe3, 0x13, 0x8b, 0xd4, 0x80, 0xca, 0x0f, 0xc8, 0xf8, 0x52, 0x7b, 0xbc, 0x4b, 0xe3, 0x13, 0xbb, 0x85, 0xf3, 0xe4, 0x6f, 0x50, 0x2a, 0x8b, 0x2c, 0x67, 0xf3, 0x84, 0xc9, 0xa3, 0x2b, 0x3f, 0xc2, 0x62, 0xe3, 0xe7, 0xb8, 0xeb, 0x2b, 0x9c, 0xfc, 0x3e, 0x3f, 0x4a, 0x53, 0xa8, 0xed, 0xf0, 0x7e, 0xc0, 0x65, 0xfd, 0x5f, 0xb0, 0x48, 0x43, 0x05, 0x50, 0xc2, 0x70, 0x31, 0x13, 0x28, 0x22, 0x7a, 0x3f, 0xac, 0xf9, 0x0e, 0x33, 0x06, 0xc6, 0xbf, 0x29, 0xd2, 0xbc, 0x9b, 0xd7, 0xdd, 0x70, 0x98, 0xe0, 0x14, 0x20, 0x6f, 0xfc, 0xfb, 0xbf, 0x46, 0x4a, 0x91, 0x0e, 0x14, 0xf4, 0x2a, 0x6f, 0xd6, 0xcd, 0x8c, 0x45, 0xef, 0x13, 0x20, 0x8a, 0xee, 0x9e, 0xfd, 0xf3, 0xe4, 0x76, 0x0d, 0x7b, 0x02, 0x24, 0xa4, 0x59, 0x4f, 0x51, 0x8f, 0x2d, 0x93, 0xeb, 0xc0, 0xea, 0x37, 0x75, 0xbc, 0x50, 0x4e, 0xed, 0xfc, 0x6d, 0xac, 0x27, 0x7b, 0x5e, 0xa6, 0xf7, 0x04, 0x54, 0xbd, 0x54, 0x84, 0xaf, 0x59, 0x45, 0xcf, 0x83, 0x8e, 0xbe, 0x72, 0x99, 0xb4, 0xfd, 0x21, 0x45, 0x51, 0x27, 0xae, 0x01, 0x80, 0x95, 0x58, 0x28, 0x89, 0xde, 0xfe, 0x9d, 0x9d, 0x1b, 0x17, 0x95, 0xb9, 0x65, 0xe4, 0xfa, 0xcb, 0x4e, 0xea, 0x94, 0x6e, 0x03, 0xa2, 0x58, 0xf6, 0x7a, 0xc7, 0x9b, 0x75, 0x96, 0xdd, 0x95, 0x27, 0xd7, 0x5a, 0xa4, 0x7e, 0xf4, 0x7b, 0x62, 0x79, 0x7e, 0x50, 0xf6, 0xa2, 0x64, 0x60, 0x87, 0x71, 0x98, 0xbd, 0x9a, 0x0a, 0xdb, 0x34, 0x72, 0xe3, 0x8d, 0xac, 0x2f, 0xee, 0x5c, 0x65, 0xda, 0xc7, 0xbc, 0x6f, 0x2c, 0x00, 0x0a, 0xf0, 0xfe, 0x80, 0x92, 0x63, 0xf7, 0x86, 0xa3, 0x67, 0x65, 0xb8, 0xe6, 0x94, 0xb0, 0x63, 0x4c, 0x1d, 0xa6, 0xa8, 0xe2, 0x2a, 0xff, 0xcd, 0x31, 0xa0, 0xc2, 0x54, 0x53, 0xeb, 0x6b, 0x47, 0xde, 0x6d, 0xe9, 0xc7, 0x24, 0x5e, 0x80, 0x77, 0x20, 0x36, 0x12, 0x34, 0xa8, 0x2f, 0x79, 0xaa, 0xf8, 0x55, 0x31, 0xf6, 0x41, 0x66, 0x0f, 0xb8, 0x87, 0x67, 0xde, 0xd1, 0xd6, 0x35, 0x63, 0x4f, 0xb2, 0x77, 0x96, 0x29, 0xd0, 0xa7, 0x17, 0x32, 0x38, 0x87, 0x07, 0xe0, 0xe2, 0x22, 0x90, 0x32, 0x7b, 0x2e, 0xb9, 0xba, 0x45, 0xdc, 0x7e, 0x28, 0xbd, 0x87, 0x44, 0x3e, 0x74, 0x87, 0xfd, 0x75, 0x8e, 0x29, 0x4d, 0x8c, 0xa5, 0xda, 0xb6, 0x0d, 0x82, 0xd3, 0xfb, 0xed, 0xae, 0x68, 0x4c, 0x3a, 0x8a, 0xa7, 0x33, 0x5f, 0xfb, 0xec, 0x60, 0x29, 0x88, 0x04, 0xbc, 0x24, 0x59, 0x88, 0xe0, 0xbf, 0x8f, 0xac, 0x15, 0xba, 0xa0, 0x88, 0x94, 0x16, 0x9f, 0x93, 0x9f, 0x34, 0x9e, 0xf2, 0xb9, 0x1a, 0x44, 0x2e, 0x10, 0x3d, 0x5c, 0x46, 0x19, 0x00, 0xc8, 0xf2, 0x49, 0xf5, 0x63, 0x04, 0x7e, 0x67, 0x6a, 0x07, 0x84, 0x73, 0x68, 0x7d, 0x67, 0x06, 0xa4, 0x3a, 0xbc, 0x13, 0x75, 0x49, 0x39, 0xb5, 0x2e, 0xfb, 0xab, 0x75, 0x65, 0xc9, 0x80, 0x6a, 0x40, 0xfd, 0x40, 0xae, 0xa3, 0x30, 0x13, 0x73, 0x36, 0x7e, 0x22, 0x3f, 0xd1, 0xeb, 0x93, 0x6c, 0x97, 0xa0, 0x1b, 0x66, 0x14, 0x8b, 0xda, 0x9c, 0xe0, 0x17, 0x6f, 0x08, 0xc7, 0xf0, 0x18, 0x9b, 0x0e, 0x24, 0x18, 0xb8, 0x64, 0x27, 0x75, 0x46, 0x26, 0x4e, 0xbc, 0xf1, 0x92, 0x1f, 0x5c, 0x17, 0xab, 0x7d, 0xfd, 0x86, 0x16, 0xf0, 0xb0, 0x34, 0x21, 0xf2, 0xec, 0xf5, 0x3b, 0x24, 0x3a, 0xf7, 0x42, 0xb6, 0x2b, 0xb6, 0xa3, 0x00, 0xe6, 0x27, 0x81, 0xd8, 0x05, 0x22, 0xb8, 0xa7, 0x6c, 0xc3, 0x90, 0xf0, 0xc6, 0xfb, 0x3b, 0x80, 0x4c, 0xfe, 0x80, 0x21, 0xbc, 0x57, 0xe0, 0xac, 0x35, 0x7b, 0x72, 0x90, 0xfe, 0x2c, 0xfb, 0x63, 0x61, 0xd3, 0x76, 0xee, 0x47, 0x26, 0x09, 0x8a, 0x90, 0xea, 0x47, 0x87, 0xdc, 0x04, 0xff, 0x4d, 0x8b, 0x61, 0xfb, 0x8c, 0xce, 0x48, 0x78, 0x54, 0x29, 0x63, 0x00, 0x33, 0x8c, 0xf3, 0xb7, 0x6f, 0xd4, 0x84, 0x52, 0x9b, 0x7b, 0xa8, 0xbd, 0x9d, 0xb0, 0xc5, 0x05, 0xdb, 0x41, 0xfd, 0x1f, 0xbc, 0xd2, 0x76, 0x99, 0x5f, 0xf5, 0xd5, 0x66, 0x28, 0xb1, 0x7d, 0x2e, 0x1f, 0x53, 0x67, 0x86, 0xab, 0x8a, 0x04, 0x73, 0x8b, 0x0a, 0x11, 0xdd, 0x02, 0xf6, 0x96, 0xa9, 0xcb, 0x2d, 0x83, 0x49, 0x2d, 0xb9, 0xa4, 0x5d, 0xc6, 0xd4, 0x0d, 0xba, 0xa8, 0x5a, 0xc4, 0x47, 0x72, 0xa3, 0xd8, 0xa2, 0x6a, 0xd8, 0xc8, 0xbc, 0x0e, 0xe7, 0x8e, 0xa6, 0xf0, 0x95, 0x2d, 0x51, 0xdc, 0x71, 0x3d, 0x56, 0x95, 0x72, 0xd0, 0x1b, 0xf4, 0xf7, 0x35, 0x0c, 0xe6, 0xd9, 0x5b, 0xb1, 0xbd, 0x98, 0x79, 0x35, 0x09, 0xf4, 0xe8, 0xd1, 0xf7, 0x9c, 0x7a, 0xe1, 0x3b, 0x90, 0xf4, 0x82, 0x0b, 0xe0, 0xad, 0xed, 0xeb, 0x20, 0xda, 0x79, 0xab, 0xc0, 0xc9, 0x4f, 0xa2, 0x74, 0x54, 0x2d, 0x92, 0x29, 0xb2, 0x2e, 0x61, 0x55, 0x60, 0x4a, 0xde, 0x96, 0x51, 0xca, 0xd0, 0x04, 0xaa, 0xdb, 0xd3, 0x74, 0x09, 0xf4, 0xa2, 0xd3, 0x7d, 0x51, 0xab, 0xed, 0xb6, 0x9e, 0x22, 0x10, 0x3a, 0x21, 0x7b, 0x52, 0x0d, 0x31, 0xf4, 0x01, 0xbd, 0x1a, 0xe9, 0xfc, 0x9a, 0x72, 0x25, 0x90, 0xab, 0x90, 0x96, 0xcc, 0x8d, 0x00, 0x4c, 0x0b, 0xdf, 0x84, 0x26, 0x0b, 0x22, 0x22, 0xb2, 0xb5, 0x16, 0xc3, 0x50, 0x61, 0x39, 0xbb, 0xdb, 0x7c, 0x5b, 0x36, 0x37, 0xad, 0x52, 0xa7, 0x56, 0xb3, 0xb4, 0xf7, 0xc0, 0x8d, 0x42, 0x56, 0x9e, 0x1a, 0xf8, 0xee, 0xcd, 0x55, 0x5d, 0xa7, 0x56, 0x6d, 0x7a, 0x77, 0xe7, 0xb5, 0xbf, 0xb4, 0x5d, 0xe0, 0x9e, 0x10, 0x0c, 0x31, 0x8d, 0xa6, 0x67, 0x1f, 0x12, 0x3b, 0x9a, 0x3d, 0xec, 0x2d, 0x4d, 0x50, 0x97, 0x4e, 0x62, 0x02, 0x34, 0xf6, 0x21, 0x3c, 0x6a, 0xf5, 0x14, 0x6d, 0xe1, 0x21, 0xe9, 0xa2, 0xd4, 0xbb, 0x9c, 0x4f, 0xbb, 0x97, 0x18, 0x73, 0xdd, 0x18, 0x1b, 0x02, 0x32, 0x9e, 0xe8, 0x32, 0xac, 0x04, 0x09, 0x41, 0x82, 0x24, 0x97, 0xeb, 0x9f, 0x08, 0x5e, 0x8d, 0x18, 0xaf, 0xa7, 0xee, 0xcf, 0x4c, 0xa6, 0x4d, 0xa4, 0x83, 0x69, 0xb7, 0xc8, 0xf0, 0xc5, 0x47, 0x2d, 0x3e, 0x95, 0x9f, 0x07, 0x4a, 0x98, 0x81, 0xcd, 0x53, 0x09, 0x15, 0xf8, 0xdb, 0x67, 0x9a, 0x5d, 0x21, 0x23, 0xf0, 0x78, 0x86, 0x63, 0x95, 0xc3, 0x11, 0x48, 0x01, 0xb6, 0x60, 0xa4, 0x62, 0x69, 0x36, 0x56, 0xe8, 0xe4, 0x2c, 0x34, 0x18, 0xe1, 0x0e, 0x84, 0xb8, 0x05, 0xba, 0x5a, 0xfc, 0xb7, 0x5a, 0xb7, 0x87, 0xc9, 0x74, 0x15, 0x18, 0xc9, 0xa9, 0x0f, 0xf0, 0x89, 0xc4, 0xeb, 0xa7, 0x24, 0xc6, 0xcf, 0x26, 0x8e, 0x40, 0x61, 0xf8, 0x9c, 0x32, 0x2e, 0x0b, 0x37, 0x2b, 0x6d, 0x6b, 0x6c, 0x23, 0x34, 0x83, 0x36, 0x16, 0x01, 0xfc, 0x1d, 0x49, 0x58, 0x7b, 0x22, 0xce, 0x9f, 0x61, 0x74, 0xf4, 0xf6, 0x7b, 0x94, 0x40, 0x13, 0xe5, 0xb5, 0x27, 0xe9, 0xaf, 0x3f, 0x39, 0x7e, 0x86, 0x8f, 0xfb, 0x60, 0xac, 0x1a, 0x41, 0x25, 0x94, 0xbb, 0x73, 0x3e, 0x5e, 0x76, 0x10, 0x13, 0x65, 0x42, 0x84, 0xda, 0x29, 0x1e, 0x81, 0xb0, 0xa1, 0xb9, 0x51, 0x9b, 0xcd, 0xc2, 0x7c, 0x83, 0xf3, 0x0c, 0xf0, 0x0b, 0x04, 0x01, 0x29, 0x52, 0xf4, 0xf3, 0xf0, 0x7f, 0x08, 0x6d, 0x0b, 0xc5, 0xa5, 0xd4, 0x45, 0x55, 0x3c, 0x1c, 0x8c, 0x08, 0x30, 0xe1, 0xf1, 0x3c, 0xc1, 0x2d, 0xe2, 0x19, 0x10, 0x14, 0xba, 0x51, 0x0c, 0x78, 0x89, 0x3b, 0xc9, 0xdd, 0x45, 0xa4, 0x0a, 0xd2, 0x40, 0x14, 0x78, 0x8e, 0x15, 0x87, 0xba, 0xbb, 0x0b, 0x88, 0xcc, 0xac, 0xcb, 0xba, 0x4b, 0xf5, 0x80, 0xdc, 0xd5, 0x83, 0xce, 0x8e, 0x6f, 0xd3, 0x4e, 0x81, 0xb9, 0x4a, 0x1b, 0x59, 0x0e, 0xb3, 0xcb, 0x23, 0xab, 0x15, 0xae, 0xb7, 0x8f, 0x73, 0x19, 0x37, 0x0d, 0x66, 0x59, 0x2e, 0xad, 0x78, 0xf4, 0x3e, 0x8a, 0xf4, 0x8b, 0x62, 0xf3, 0xf9, 0x9e, 0xc3, 0x41, 0x68, 0x1f, 0xbc, 0xf3, 0xe3, 0xf1, 0xcb, 0xb9, 0x09, 0x8b, 0x50, 0x58, 0xcd, 0x74, 0xc1, 0x1b, 0xf7, 0x49, 0xce, 0x75, 0xb4, 0x15, 0xbb, 0xa4, 0xbf, 0x95, 0x1d, 0xf6, 0x26, 0x3c, 0xc7, 0x35, 0xe2, 0xad, 0xc1, 0xb8, 0xef, 0x65, 0x32, 0xd7, 0x83, 0x08, 0x85, 0xbd, 0xa5, 0x82, 0xb1, 0xe5, 0x2c, 0x62, 0xdb, 0x09, 0xc9, 0xaf, 0xc3, 0xdb, 0x45, 0x38, 0x83, 0x14, 0x12, 0xda, 0x8a, 0x30, 0xb1, 0x3a, 0x75, 0xef, 0xfb, 0x95, 0xee, 0xe7, 0x77, 0x2d, 0xcb, 0x22, 0x8d, 0x65, 0x12, 0xb5, 0x28, 0x81, 0xf6, 0x19, 0x1b, 0x0b, 0xee, 0x11, 0x07, 0x84, 0xf5, 0x79, 0x82, 0xe8, 0x32, 0xdf, 0x0b, 0xfa, 0x8e, 0xba, 0x81, 0x14, 0x6a, 0x8e, 0x57, 0x68, 0x86, 0x1e, 0x90, 0xdb, 0x99, 0x44, 0x60, 0x3b, 0xda, 0xad, 0x84, 0x9f, 0x9d, 0x2e, 0xff, 0x87, 0x5d, 0x1b, 0x81, 0x65, 0x02, 0x65, 0xce, 0x96, 0x23, 0x87, 0x7f, 0x73, 0x02, 0xf2, 0xc5, 0x94, 0xa6, 0x77, 0x98, 0x2e, 0x0c, 0x2a, 0xd6, 0x07, 0x68, 0x22, 0x4f, 0xe7, 0x2a, 0x10, 0xd6, 0x8f, 0x5f, 0xfa, 0xc2, 0x6e, 0xba, 0x6f, 0x40, 0xef, 0x59, 0x56, 0xd9, 0x5f, 0x2b, 0x3a, 0x80, 0x86, 0x55, 0x6a, 0xd0, 0xff, 0x84, 0xa9, 0x29, 0x7c, 0xcb, 0x96, 0x1c, 0x78, 0x3c, 0x81, 0x58, 0xae, 0xd7, 0x22, 0xf4, 0xe0, 0x22, 0x31, 0x65, 0xfa, 0x45, 0x1d, 0xe5, 0x59, 0xac, 0x63, 0x44, 0xaf, 0x77, 0x2d, 0x52, 0x29, 0x5c, 0x09, 0x5c, 0xbe, 0x78, 0x78, 0xe7, 0x59, 0x8a, 0x67, 0x73, 0x71, 0x13, 0xe6, 0x83, 0x5c, 0xa3, 0xd0, 0x42, 0x80, 0x68, 0x3f, 0xbf, 0xc4, 0x78, 0x34, 0x96, 0x33, 0x97, 0xc0, 0xa4, 0x33, 0x44, 0x8a, 0x3c, 0x72, 0x95, 0xb2, 0x58, 0x3a, 0x6f, 0x82, 0x95, 0x8d, 0xae, 0x98, 0x6f, 0xe2, 0x99, 0x8a, 0xe0, 0xda, 0x15, 0x8e, 0x99, 0x19, 0x82, 0xb2, 0x79, 0x64, 0xf4, 0xb4, 0xf7, 0x99, 0x3f, 0x14, 0x0f, 0x1d, 0xc8, 0x8e, 0xbd, 0xf6, 0x3e, 0x8e, 0x48, 0xf0, 0xed, 0x77, 0xdc, 0xc7, 0xad, 0xa6, 0xe3, 0xd6, 0xab, 0xd8, 0x6b, 0x38, 0x59, 0x5e, 0x60, 0x57, 0x32, 0x66, 0xbd, 0xb7, 0x39, 0xc8, 0x53, 0x74, 0x87, 0xc5, 0xf3, 0x22, 0xea, 0x65, 0xba, 0x48, 0xed, 0x11, 0x39, 0x8f, 0x09, 0x61, 0x68, 0xab, 0x92, 0xde, 0x64, 0x07, 0x6f, 0xd0, 0xdb, 0x37, 0xa4, 0x4f, 0x87, 0xaf, 0xd3, 0x3b, 0xe1, 0x0e, 0xd8, 0x21, 0xbf, 0x41, 0x1f, 0x41, 0x89, 0xbb, 0x21, 0xbb, 0xcb, 0x9d, 0x77, 0x18, 0x9d, 0x5e, 0x5d, 0x0a, 0xe6, 0xa4, 0xc7, 0x70, 0x60, 0x7e, 0x77, 0x0f, 0x38, 0x34, 0xbf, 0xcf, 0x6e, 0x4d, 0x25, 0xe4, 0xb0, 0x3e, 0x01, 0x04, 0x6e, 0x9b, 0x2f, 0xbb, 0x71, 0xa2, 0x42, 0xad, 0xd4, 0xbb, 0x12, 0x6d, 0x22, 0x58, 0x04, 0x2c, 0x43, 0x7d, 0x59, 0x02, 0x61, 0x93, 0xbc, 0x13, 0x95, 0xea, 0x1c, 0x4a, 0x69, 0xb0, 0x25, 0xbc, 0xb0, 0xbb, 0xb5, 0x2d, 0x5c, 0xe7, 0x59, 0x8c, 0x23, 0x18, 0xbd, 0x22, 0x30, 0xec, 0x05, 0x2c, 0xd6, 0xc2, 0x9b, 0x41, 0x91, 0x81, 0xfb, 0xf0, 0xdd, 0x17, 0x31, 0x5c, 0x63, 0xb3, 0x76, 0x39, 0x63, 0xa5, 0xfd, 0x3e, 0x21, 0x72, 0x58, 0xbc, 0xd5, 0x38, 0xf4, 0x47, 0x27, 0xa4, 0xb9, 0xfb, 0xe4, 0xb2, 0xed, 0x10, 0xbe, 0x25, 0x48, 0x0b, 0x23, 0x68, 0xce, 0x34, 0x88, 0x30, 0xc7, 0xa4, 0xbc, 0x41, 0x49, 0x77, 0xcc, 0x32, 0x1c, 0xe7, 0x91, 0xf2, 0x38, 0x41, 0xb0, 0xb4, 0xa0, 0xb3, 0x1d, 0x20, 0x4c, 0x87, 0x97, 0x38, 0x32, 0xdc, 0xd4, 0xd7, 0xf8, 0xc7, 0x08, 0x40, 0xb6, 0x3a, 0x60, 0x69, 0xf9, 0x0d, 0xfb, 0x38, 0x0c, 0xb6, 0x30, 0xdc, 0x40, 0x05, 0x7a, 0xa5, 0x88, 0x68, 0x25, 0x64, 0x20, 0x82, 0xd0, 0xa2, 0x5e, 0x78, 0xb0, 0x58, 0x8f, 0xe2, 0x6d, 0x4e, 0xaa, 0xf8, 0x8f, 0xf5, 0xbb, 0x28, 0x2e, 0x47, 0x53, 0x55, 0x94, 0x90, 0x98, 0x87, 0x8d, 0xfa, 0x9c, 0x62, 0x17, 0xb8, 0x43, 0x3f, 0xe3, 0x6d, 0xe0, 0xf8, 0xc2, 0xcb, 0x5c, 0xe3, 0xd1, 0x93, 0xfa, 0xf7, 0x90, 0x90, 0x11, 0x64, 0x4f, 0xdc, 0xa9, 0x56, 0xc8, 0x04, 0x92, 0xf2, 0x24, 0xa8, 0xec, 0xee, 0xbb, 0x17, 0xa7, 0x2e, 0x9f, 0xd5, 0xfd, 0x0a, 0x0e, 0xca, 0x90, 0xeb, 0x62, 0x89, 0xfc, 0xd4, 0x27, 0x2f, 0x6c, 0x2c, 0x29, 0x34, 0xc0, 0xcd, 0x97, 0x27, 0x77, 0x2a, 0x14, 0x4a, 0xa7, 0xaf, 0x97, 0x40, 0xcd, 0xd2, 0x81, 0xa3, 0x27, 0x55, 0xc4, 0x98, 0x12, 0xcb, 0x2a, 0x92, 0x20, 0x74, 0x50, 0xe7, 0x4a, 0x1f, 0xf5, 0x94, 0xb3, 0x1f, 0xaa, 0x22, 0x8c, 0x5f, 0x9c, 0xb3, 0x7a, 0xc5, 0x87, 0xf6, 0x61, 0x4d, 0x10, 0x25, 0x62, 0x8c, 0x05, 0xd2, 0xac, 0xf6, 0x8b, 0xaa, 0xaf, 0x45, 0x31, 0x12, 0xbe, 0x8d, 0x09, 0x6a, 0x0b, 0xc6, 0x91, 0x57, 0xee, 0x09, 0x7a, 0x57, 0xdd, 0xa7, 0x53, 0xf5, 0x00, 0x31, 0x7c, 0xe8, 0x49, 0xbf, 0xc5, 0x85, 0x4d, 0xd6, 0xd4, 0xb9, 0xc9, 0x0c, 0x96, 0x53, 0x4a, 0x33, 0x72, 0xf8, 0x22, 0xdf, 0x3b, 0x3e, 0x11, 0x1a, 0x3f, 0x83, 0xda, 0x6c, 0x7a, 0xb6, 0xf6, 0x4e, 0x12, 0xdb, 0xad, 0x25, 0xf5, 0x46, 0xf4, 0x22, 0x3b, 0x74, 0xd7, 0x9b, 0x24, 0x45, 0x95, 0x6f, 0xc4, 0x3c, 0x9a, 0x31, 0x43, 0xcc, 0x43, 0x99, 0xae, 0xf3, 0x1c, 0xbe, 0x2d, 0x86, 0x2a, 0xda, 0xf7, 0x20, 0xec, 0xd4, 0x02, 0x9e, 0x91, 0xf1, 0x21, 0xca, 0x3d, 0x15, 0x0b, 0xea, 0x7a, 0xb0, 0x6e, 0x55, 0xcf, 0xf1, 0xe0, 0x73, 0x39, 0x62, 0xbf, 0xf0, 0xc8, 0x9f, 0x33, 0x66, 0xc5, 0xd8, 0xb8, 0x9f, 0xb6, 0x5e, 0xc5, 0x60, 0xe9, 0xad, 0xd2, 0xa5, 0xd8, 0xec, 0x94, 0x4b, 0x9a, 0x46, 0xf0, 0x6b, 0x5a, 0xf9, 0x43, 0xce, 0x05, 0xd8, 0xae, 0x99, 0xaa, 0x7e, 0xcf, 0xdd, 0x53, 0xd6, 0x8f, 0xe9, 0xb0, 0xa4, 0xeb, 0xcb, 0xac, 0xb6, 0x9f, 0x24, 0x14, 0x4a, 0xd1, 0x2c, 0xc9, 0xf6, 0x19, 0x26, 0xa0, 0xad, 0x84, 0x71, 0x11, 0x2f, 0x69, 0x32, 0xe0, 0xc9, 0x29, 0xa8, 0xca, 0x06, 0x4d, 0x4e, 0xcf, 0x0b, 0xff, 0x99, 0x22, 0x4f, 0x4e, 0x16, 0x08, 0x64, 0x1e, 0x50, 0xe5, 0x53, 0x75, 0x5f, 0x19, 0x54, 0xfe, 0x8c, 0xd2, 0x3e, 0x4b, 0x4e, 0x67, 0x4a, 0x7d, 0x12, 0x96, 0xa2, 0x2e, 0x3b, 0x79, 0x96, 0xcc, 0xb3, 0x72, 0xc6, 0xce, 0xda, 0xc5, 0x75, 0xf1, 0xd4, 0xea, 0xaa, 0xc7, 0x3c, 0x2d, 0xd6, 0x35, 0x2b, 0x69, 0x06, 0xd4, 0xdc, 0x9a, 0x37, 0xde, 0x60, 0xb0, 0x4a, 0xd9, 0x8a, 0xe0, 0xf9, 0xeb, 0xcf, 0x81, 0xa6, 0xa4, 0x4f, 0x20, 0x1b, 0x89, 0x35, 0xbc, 0xda, 0x87, 0x8a, 0x56, 0x5c, 0x7e, 0x34, 0xd5, 0x3d, 0x56, 0xec, 0x29, 0xe5, 0x99, 0xde, 0x27, 0xd6, 0x1d, 0xeb, 0xa9, 0x5d, 0x23, 0xc4, 0x66, 0x91, 0xd1, 0xd0, 0x16, 0xd5, 0xc5, 0x33, 0x32, 0xc7, 0x3b, 0x78, 0xa6, 0x5d, 0x8d, 0x67, 0x9e, 0xe2, 0x03, 0x11, 0xe9, 0x82, 0x49, 0x7e, 0x9e, 0x00, 0x29, 0xbf, 0x90, 0x51, 0x33, 0xd5, 0x8b, 0xb0, 0x7e, 0xf0, 0xfe, 0x01, 0x79, 0xa0, 0xa3, 0xbe, 0x33, 0x9f, 0x1a, 0x1e, 0xc2, 0x3d, 0xc8, 0x73, 0x23, 0xfe, 0x17, 0xcb, 0xeb, 0xae, 0x39, 0xe8, 0xd7, 0x40, 0x10, 0x67, 0x1a, 0x5f, 0x23, 0x6e, 0x5f, 0xb0, 0x31, 0x2f, 0x5b, 0xb2, 0xb7, 0xf1, 0xc1, 0x33, 0xdf, 0xfd, 0x88, 0xec, 0xe3, 0x51, 0x29, 0x9f, 0xf4, 0xd2, 0xd0, 0x63, 0x36, 0xd1, 0x55, 0x66, 0xa3, 0xd8, 0xe5, 0x6c, 0xd9, 0x85, 0x92, 0x8e, 0xa8, 0xfc, 0x59, 0x1b, 0x4f, 0x6a, 0xb5, 0x62, 0x59, 0xa9, 0x33, 0x07, 0x8a, 0x3e, 0xc9, 0xa7, 0x00, 0x9e, 0x70, 0xe0, 0xe7, 0x12, 0x58, 0x6b, 0x0e, 0xdd, 0x8c, 0x1e, 0x3c, 0x53, 0x7c, 0xd7, 0x26, 0x37, 0x37, 0x69, 0xa2, 0x47, 0xaf, 0xad, 0x12, 0x69, 0xe4, 0xbd, 0xee, 0x25, 0xc1, 0xc0, 0x84, 0x8c, 0x21, 0x13, 0x11, 0xa6, 0x02, 0x3b, 0x45, 0x77, 0x26, 0xad, 0x17, 0xef, 0xbb, 0xe8, 0xb6, 0xba, 0x1d, 0xb3, 0x41, 0x48, 0xc4, 0xc0, 0x77, 0x08, 0x27, 0xe9, 0xbb, 0x8a, 0xe0, 0x82, 0xae, 0xad, 0xc3, 0x15, 0x03, 0x99, 0x53, 0x48, 0xac, 0x8f, 0x99, 0x4d, 0x8f, 0xc0, 0xb2, 0xa4, 0xe6, 0x26, 0xe4, 0x7c, 0x6b, 0x89, 0x8a, 0x47, 0x19, 0x5c, 0x8e, 0x4f, 0xe3, 0x08, 0x1a, 0x66, 0xaa, 0x49, 0x79, 0x12, 0x19, 0x42, 0xf1, 0xdb, 0xb1, 0xa7, 0xc2, 0x83, 0xd2, 0x1d, 0x6f, 0x8d, 0x00, 0x7b, 0x1f, 0x9c, 0xb4, 0x0b, 0x92, 0xfa, 0x6d, 0xb5, 0x84, 0x65, 0x17, 0xef, 0x24, 0x96, 0x39, 0x9f, 0x8e, 0x4b, 0xf4, 0x2b, 0x70, 0xe8, 0x73, 0xa6, 0x76, 0x69, 0x1a, 0xed, 0xc8, 0xb9, 0x16, 0x21, 0xb6, 0x27, 0x55, 0x4a, 0xa7, 0x48, 0xe1, 0xf4, 0xe3, 0x5d, 0x90, 0x44, 0x7a, 0x51, 0x67, 0xa1, 0x3b, 0x08, 0x5c, 0xaa, 0x76, 0xe3, 0x74, 0x50, 0xc9, 0xd0, 0x8b, 0x22, 0x9d, 0x9f, 0xf6, 0x33, 0x4c, 0x99, 0x75, 0xc2, 0x2c, 0x58, 0x09, 0x93, 0xec, 0xa3, 0xce, 0x02, 0x93, 0x35, 0x31, 0x13, 0x4f, 0x2b, 0x39, 0x55, 0x91, 0x7a, 0xfd, 0x58, 0x2f, 0x09, 0x63, 0xe0, 0x96, 0x29, 0xc5, 0x1d, 0x80, 0x25, 0xec, 0xc6, 0x78, 0x87, 0x70, 0x76, 0x95, 0x95, 0x8d, 0x35, 0x44, 0xb5, 0x90, 0xa2, 0x5a, 0xfd, 0x89, 0x4e, 0xaf, 0x8d, 0x03, 0x21, 0xd0, 0x5f, 0x35, 0x68, 0x02, 0x05, 0x9a, 0x93, 0xf7, 0x94, 0x2e, 0xdd, 0x8d, 0xde, 0x47, 0x6b, 0x59, 0xe6, 0x1a, 0xb8, 0xdf, 0x3b, 0x35, 0x08, 0x4f, 0x95, 0xf3, 0xa4, 0xad, 0xf2, 0x7d, 0xe2, 0x79, 0xda, 0xce, 0x73, 0x33, 0x60, 0x5c, 0x8b, 0xd3, 0xcd, 0xef, 0xef, 0xa4, 0xf4, 0x97, 0xff, 0xa3, 0x2b, 0x47, 0x2a, 0x55, 0xbf, 0x71, 0x2e, 0x53, 0x18, 0x02, 0x0d, 0x40, 0x6a, 0xff, 0x75, 0x10, 0x07, 0x4c, 0x8b, 0x5b, 0xd5, 0x3a, 0xf6, 0x2f, 0x6a, 0xee, 0x36, 0x5c, 0xab, 0x0e, 0x33, 0x14, 0xc4, 0xda, 0xd4, 0xcf, 0x62, 0x45, 0x60, 0x93, 0xb4, 0xdf, 0xf2, 0x8a, 0x82, 0xfe, 0xa2, 0x86, 0xaa, 0x14, 0xcc, 0x2b, 0xc2, 0x38, 0x3e, 0xea, 0x66, 0x54, 0xef, 0xb9, 0xd0, 0xc8, 0xa9, 0xe8, 0x6e, 0x7b, 0x71, 0x62, 0x56, 0x34, 0x29, 0x20, 0x27, 0xf3, 0xd7, 0x43, 0x9c, 0x1e, 0x47, 0x6c, 0x4f, 0x4d, 0x73, 0x61, 0x11, 0xa5, 0x4d, 0x12, 0x3b, 0xeb, 0x9c, 0x23, 0x6b, 0x6d, 0x55, 0x1a, 0x57, 0x68, 0xea, 0x04, 0xdd, 0x0f, 0x20, 0xc2, 0xa4, 0x9d, 0x2c, 0x44, 0x27, 0x40, 0x82, 0xf3, 0x0f, 0x5a, 0x33, 0x5d, 0xdc, 0xe5, 0x8e, 0xa2, 0x7f, 0x2d, 0xff, 0xd1, 0x44, 0xfe, 0x09, 0x76, 0x17, 0x9d, 0xb8, 0xb9, 0xcb, 0x1d, 0x23, 0x8f, 0xd1, 0x0b, 0x95, 0x8c, 0xaa, 0x99, 0x35, 0x03, 0xfd, 0xfe, 0xc7, 0x2d, 0xb8, 0x91, 0x38, 0x33, 0x77, 0x6b, 0xb3, 0x70, 0x78, 0x57, 0xdc, 0x1b, 0x48, 0x9a, 0x8f, 0xdd, 0x72, 0x9d, 0x31, 0x7b, 0x4c, 0x7c, 0xf5, 0x84, 0x56, 0x92, 0x4e, 0x88, 0x81, 0xa5, 0xee, 0x6c, 0x94, 0x09, 0x18, 0x50, 0x1c, 0xfa, 0xa4, 0x21, 0x15, 0x7b, 0xbd, 0x83, 0x97, 0x73, 0xe9, 0xba, 0x89, 0xf7, 0xf6, 0xf3, 0x14, 0x17, 0xc3, 0x48, 0xdb, 0x35, 0x14, 0xa1, 0xbd, 0xc9, 0x35, 0x99, 0x30, 0x68, 0x67, 0x12, 0x4f, 0xca, 0xe6, 0x0f, 0x9e, 0xb8, 0x03, 0xce, 0x6b, 0x2d, 0x7f, 0x79, 0x9f, 0x16, 0xb0, 0x11, 0x36, 0xaf, 0xb5, 0x5f, 0x01, 0xe6, 0xc0, 0xd8, 0xc9, 0x72, 0xcf, 0xbe, 0x5c, 0x52, 0xf5, 0x6f, 0x3b, 0x80, 0x2e, 0xac, 0xca, 0xbf, 0x99, 0x62, 0xa3, 0xa5, 0x30, 0xaf, 0x84, 0x5b, 0xa6, 0x9f, 0x1f, 0x26, 0x65, 0x51, 0x55, 0x4e, 0xee, 0x3b, 0xe3, 0xcd, 0x82, 0x51, 0x1b, 0x6d, 0xda, 0x9d, 0xce, 0x54, 0xa9, 0xf8, 0x38, 0x23, 0xef, 0x7b, 0xf8, 0x45, 0x3d, 0xcd, 0xf5, 0xb7, 0x4b, 0x49, 0x2b, 0x88, 0x9d, 0xc7, 0x2b, 0x1a, 0xe7, 0xa8, 0xab, 0x40, 0xda, 0x1e, 0x8b, 0xbf, 0x11, 0x7c, 0xff, 0x19, 0x86, 0x58, 0x46, 0x3a, 0x5f, 0x5d, 0x71, 0x2d, 0x83, 0x51, 0x6e, 0xc2, 0x17, 0xb4, 0xe3, 0xcd, 0x77, 0x37, 0x0d, 0x1b, 0x12, 0x75, 0xd9, 0x49, 0x66, 0xfa, 0xd3, 0x8f, 0x1a, 0xee, 0xd7, 0x03, 0x3d, 0x60, 0x36, 0x8c, 0xbe, 0x9d, 0x30, 0x99, 0xf5, 0x4d, 0x4c, 0x4f, 0xaf, 0xd8, 0x6f, 0xff, 0xbe, 0x48, 0xc7, 0xba, 0xcc, 0x9d, 0x62, 0x10, 0x6e, 0x40, 0xdb, 0xe4, 0xf2, 0xed, 0xc0, 0x67, 0x30, 0x2e, 0x4e, 0xb1, 0xf5, 0x3e, 0x9f, 0x7b, 0x3e, 0x8f, 0x82, 0x41, 0x2f, 0xb2, 0xca, 0x61, 0x33, 0xdf, 0xd5, 0xe8, 0xce, 0x84, 0x49, 0x3b, 0x04, 0x64, 0x2e, 0x35, 0x0a, 0x5c, 0x34, 0x43, 0x74, 0x19, 0x75, 0x02, 0x8e, 0x5c, 0x70, 0xa2, 0xc9, 0x74, 0x8b, 0xda, 0x90, 0x09, 0xd8, 0x45, 0x92, 0x52, 0x88, 0x48, 0xf3, 0x1a, 0x8f, 0xe0, 0x36, 0x44, 0x18, 0x20, 0x25, 0x9e, 0x6a, 0xfb, 0xde, 0x4b, 0x43, 0x99, 0x30, 0x59, 0x2b, 0xac, 0xcf, 0x24, 0x21, 0xc6, 0x30, 0x9e, 0x63, 0xc9, 0xf6, 0x20, 0x41, 0xdb, 0x5d, 0xc1, 0xb8, 0x43, 0x81, 0x9d, 0x14, 0xe3, 0xae, 0x6b, 0xfa, 0xc0, 0xaa, 0xcc, 0x56, 0x98, 0x1d, 0x79, 0xd9, 0xd8, 0x8e, 0xc2, 0x00, 0xc2, 0x1a, 0xb7, 0x0d, 0x40, 0x10, 0xef, 0x78, 0x03, 0x99, 0xa1, 0xb2, 0xc3, 0xef, 0xeb, 0x29, 0xab, 0x9f, 0x07, 0x07, 0x84, 0x05, 0x60, 0xc9, 0x2b, 0x06, 0xa4, 0x96, 0xd1, 0xb1, 0xb4, 0x7e, 0x81, 0x15, 0xa0, 0x85, 0x4c, 0xf8, 0xce, 0xf0, 0x91, 0xb8, 0x7f, 0x43, 0xd2, 0x1f, 0xed, 0xb1, 0xda, 0x17, 0xba, 0x64, 0xa7, 0x63, 0x04, 0xa0, 0xdd, 0x9c, 0x6d, 0x17, 0x1a, 0x27, 0xd3, 0x07, 0x96, 0x27, 0x28, 0xe9, 0xdc, 0xab, 0x79, 0x7e, 0x15, 0x8a, 0x88, 0xe9, 0x1c, 0x77, 0x99, 0x30, 0x71, 0x3a, 0xab, 0x15, 0xdf, 0x71, 0xbf, 0x7a, 0xf7, 0xee, 0xc6, 0xe9, 0xde, 0x39, 0xa3, 0xc8, 0x45, 0x17, 0x9b, 0xcf, 0x15, 0x50, 0x7b, 0x3c, 0x5a, 0xa8, 0xf9, 0xb1, 0xc1, 0xf9, 0xcf, 0x77, 0x71, 0x56, 0xb8, 0x7f, 0x53, 0xa3, 0x84, 0x82, 0xea, 0xd0, 0x3f, 0xd8, 0x8b, 0x84, 0x6a, 0xbb, 0xad, 0xb9, 0x88, 0x41, 0x72, 0x4c, 0x27, 0x39, 0x7a, 0xa8, 0xcc, 0x0a, 0x8f, 0x34, 0xda, 0x62, 0xea, 0x5a, 0xcd, 0x99, 0xaa, 0x7d, 0x5a, 0x51, 0xa8, 0xbd, 0x1c, 0xba, 0x0f, 0x98, 0x6a, 0xb8, 0xdd, 0x8f, 0x6f, 0x38, 0x52, 0x81, 0xc5, 0x0c, 0x0c, 0xe1, 0x50, 0xfe, 0xdb, 0x17, 0xfc, 0x18, 0x95, 0xec, 0x5b, 0x79, 0x49, 0xf7, 0x86, 0xbd, 0x29, 0x0c, 0x78, 0x9f, 0x9c, 0x46, 0x6d, 0xcc, 0xab, 0x2f, 0xbe, 0xd4, 0x9e, 0x30, 0xe1, 0xf0, 0xa0, 0x0b, 0x2b, 0x67, 0x26, 0xdf, 0x46, 0x91, 0x7f, 0x8c, 0x9c, 0x7c, 0xd4, 0x2f, 0x8b, 0x82, 0x13, 0xb8, 0x8d, 0x17, 0x12, 0x49, 0x33, 0x58, 0x7b, 0x12, 0x1e, 0xe8, 0x55, 0x1a, 0xf8, 0xdb, 0x1f, 0x26, 0x8a, 0x9b, 0x01, 0x06, 0x79, 0xe6, 0x0f, 0xbd, 0xdf, 0x11, 0x40, 0x39, 0x40, 0xde, 0xe4, 0x1d, 0xbc, 0xce, 0xf8, 0x87, 0xda, 0xdc, 0x58, 0xab, 0xdc, 0xe2, 0xff, 0x9c, 0xc7, 0x26, 0xed, 0xf4, 0x3e, 0x18, 0xe5, 0x8a, 0xaa, 0x2e, 0x20, 0x6c, 0x28, 0xca, 0x68, 0xdc, 0x78, 0x2f, 0xbe, 0x80, 0xac, 0xa4, 0xa5, 0xc9, 0x75, 0xff, 0x1a, 0x3d, 0xe3, 0xd7, 0x4e, 0x30, 0xde, 0x9b, 0x47, 0x59, 0x63, 0x1a, 0xfc, 0xc0, 0x68, 0x7a, 0xec, 0x64, 0x0b, 0xe9, 0x3c, 0x72, 0xfa, 0x8e, 0xf2, 0x6a, 0x41, 0xdc, 0x61, 0x0d, 0x71, 0x57, 0x01, 0x60, 0x27, 0xe0, 0x30, 0x94, 0xf6, 0x8e, 0x34, 0x8f, 0x66, 0x6b, 0x43, 0x66, 0xd4, 0xe2, 0x09, 0x08, 0x39, 0x27, 0xc0, 0xbe, 0x9a, 0x5b, 0x1c, 0xab, 0x03, 0xbf, 0x95, 0xfd, 0xcd, 0xa4, 0x1c, 0xee, 0x7d, 0x5e, 0xa3, 0x56, 0xb3, 0x37, 0x7e, 0x7f, 0x96, 0x9c, 0x70, 0xa2, 0x1e, 0x71, 0xc9, 0xdd, 0xba, 0x63, 0xeb, 0xcd, 0x1f, 0x67, 0x99, 0x4a, 0xa8, 0x22, 0x12, 0x04, 0x19, 0x48, 0x9f, 0x1f, 0x6f, 0x2e, 0x46, 0x4a, 0x43, 0x65, 0x67, 0x9b, 0xa4, 0x68, 0x0f, 0x4e, 0x4e, 0x8e, 0xd6, 0xae, 0xe5, 0x56, 0x89, 0x1e, 0x82, 0xfa, 0x93, 0x82, 0x15, 0x93, 0x0f, 0x6f, 0xdf, 0x77, 0xbd, 0x9b, 0x83, 0x73, 0x4e, 0x08, 0xa2, 0x54, 0x13, 0xf8, 0xee, 0xa6, 0x36, 0x5a, 0xbd, 0xef, 0xca, 0x05, 0xd9, 0x89, 0x9f, 0x4d, 0xaf, 0x41, 0xc3, 0xba, 0x0c, 0xe4, 0x4f, 0x63, 0xf7, 0x25, 0x43, 0x64, 0xd2, 0xbe, 0xae, 0xc1, 0x73, 0x28, 0x4b, 0xf7, 0xec, 0x92, 0xae, 0xc7, 0x58, 0xac, 0x97, 0xd6, 0xce, 0xf3, 0xfc, 0xd7, 0xd6, 0xc1, 0xdd, 0x2b, 0x34, 0x2e, 0x6f, 0x3e, 0xb6, 0x47, 0x42, 0x3b, 0x04, 0x05, 0x57, 0x90, 0x01, 0x9d, 0xe7, 0xcb, 0x2f, 0xd3, 0x97, 0x03, 0xbd, 0x63, 0xaa, 0x9e, 0xab, 0xf8, 0xad, 0x63, 0xe5, 0x2b, 0xb9, 0x25, 0xbe, 0x26, 0x12, 0x99, 0x45, 0x86, 0xf5, 0x3d, 0xde, 0x52, 0xe7, 0x6e, 0x48, 0x56, 0xda, 0x8a, 0x62, 0xcc, 0xe4, 0x9d, 0x2e, 0x14, 0xab, 0xbf, 0xe0, 0x40, 0x4f, 0x6e, 0x00, 0xc6, 0xdf, 0x98, 0xf1, 0x56, 0x54, 0x16, 0x47, 0x27, 0x0e, 0xdc, 0x6c, 0x37, 0x68, 0xf2, 0x2d, 0x08, 0x3a, 0xc2, 0xdb, 0xc7, 0x8d, 0xcc, 0x4b, 0xb5, 0xad, 0x21, 0xbb, 0xa1, 0x8d, 0x83, 0xcc, 0xd4, 0x6d, 0x08, 0xf2, 0x8b, 0x7f, 0xe8, 0xf0, 0x39, 0xee, 0xc2, 0xf4, 0x67, 0x4a, 0x7a, 0x61, 0x71, 0xae, 0xc2, 0x93, 0x66, 0xb4, 0x10, 0x4f, 0x0c, 0xb9, 0xa2, 0x62, 0x1c, 0x4f, 0xa7, 0x6c, 0x7c, 0xb0, 0xa6, 0x37, 0x45, 0xe3, 0xaa, 0x25, 0xaf, 0xa7, 0xd6, 0x60, 0x9a, 0x64, 0xde, 0x54, 0x0a, 0x4a, 0x73, 0x76, 0x92, 0xc0, 0x01, 0x12, 0x57, 0xe2, 0x22, 0x55, 0x7e, 0xb3, 0x84, 0x6b, 0x7e, 0x0c, 0x73, 0xd3, 0x7b, 0x4a, 0x27, 0xf1, 0xd3, 0xb6, 0x7b, 0x96, 0xe1, 0xa8, 0xf9, 0x86, 0xee, 0xf1, 0xca, 0xcf, 0x3a, 0x3c, 0x44, 0x4f, 0xa1, 0x6d, 0xda, 0x2f, 0x68, 0x5d, 0xd6, 0x92, 0xcf, 0x6a, 0xfe, 0x72, 0x2c, 0x59, 0x69, 0xd2, 0x9c, 0x51, 0xc4, 0x9b, 0x1f, 0x2b, 0x83, 0xa6, 0xf5, 0x4b, 0xa8, 0x73, 0x11, 0x60, 0x54, 0xb6, 0xc9, 0x77, 0xe0, 0x19, 0x62, 0x70, 0x7c, 0x03, 0x56, 0xe1, 0xa8, 0x80, 0xb9, 0x2d, 0x3d, 0x5a, 0x1d, 0x8e, 0x0d, 0x56, 0x33, 0x94, 0x27, 0xcf, 0x68, 0xd6, 0xf3, 0x69, 0xb8, 0x19, 0x09, 0xb5, 0x2b, 0x20, 0xfe, 0x27, 0xc0, 0x6c, 0x7b, 0xc1, 0xb6, 0xd5, 0xe9, 0x3a, 0xdd, 0x78, 0x0c, 0xdd, 0xfb, 0x13, 0x9a, 0x16, 0xbb, 0x97, 0x47, 0x8c, 0x44, 0x1b, 0x1a, 0xcf, 0x87, 0x2e, 0x45, 0x7a, 0x7d, 0x61, 0x22, 0x7c, 0xf8, 0x1f, 0x13, 0x84, 0xf0, 0x24, 0x34, 0xb4, 0x8d, 0x37, 0x4c, 0xae, 0x4a, 0x57, 0x6f, 0x69, 0xb0, 0xa4, 0x0c, 0xf7, 0x28, 0x21, 0xaa, 0x6d, 0x80, 0x76, 0x09, 0xbc, 0x63, 0x62, 0xef, 0x39, 0x17, 0x19, 0x48, 0x44, 0xb0, 0xe6, 0xab, 0xd9, 0x89, 0xb0, 0xa0, 0xe0, 0x5a, 0xac, 0x66, 0x0a, 0x12, 0xf0, 0x04, 0x3b, 0xbb, 0x9a, 0x95, 0xd3, 0x0a, 0xa0, 0x4a, 0x36, 0x3c, 0xed, 0xba, 0xd2, 0xeb, 0xdc, 0x72, 0xcb, 0xfa, 0x8e, 0xc8, 0xa9, 0x7f, 0x0d, 0x7f, 0x4f, 0x8f, 0x55, 0xdd, 0xd7, 0x13, 0x4f, 0xc4, 0xdd, 0x0c, 0x87, 0xac, 0xa5, 0x75, 0x95, 0x43, 0xf1, 0xbf, 0x30, 0x2d, 0xe0, 0xad, 0x38, 0x61, 0x8a, 0xe3, 0x6a, 0x20, 0x3f, 0x6d, 0x52, 0xa3, 0xfb, 0x55, 0x71, 0x7f, 0xb0, 0x54, 0x72, 0xc0, 0xb7, 0x21, 0xef, 0x25, 0x46, 0x75, 0xa2, 0x1c, 0xea, 0x08, 0xed, 0xc3, 0xa7, 0x8d, 0x16, 0xf4, 0x33, 0xe2, 0x2c, 0x95, 0xb4, 0xe4, 0x9f, 0xfe, 0x7f, 0xda, 0x9e, 0xcb, 0x0e, 0x37, 0x67, 0x90, 0x62, 0x4b, 0x11, 0x58, 0x0a, 0x06, 0xa0, 0xbd, 0xf6, 0xe0, 0xd0, 0x74, 0x0f, 0x18, 0xc5, 0xef, 0xbf, 0xba, 0x3c, 0x18, 0x19, 0x96, 0x7e, 0x0b, 0x95, 0x5e, 0xbb, 0x91, 0xac, 0x67, 0x5b, 0x4e, 0x81, 0x91, 0x4b, 0x8a, 0x16, 0xc6, 0xd2, 0x0f, 0xcd, 0x54, 0xb5, 0xbb, 0x0a, 0x39, 0x48, 0xb5, 0xea, 0xbb, 0x52, 0xb1, 0x76, 0xad, 0x0d, 0xe4, 0x9d, 0xa6, 0x93, 0xd3, 0x47, 0x5b, 0xd7, 0x0f, 0x0a, 0x23, 0xe3, 0x9f, 0x64, 0x06, 0x96, 0x4a, 0xb4, 0x51, 0x20, 0xc9, 0xec, 0x1b, 0x73, 0x78, 0xd5, 0xc3, 0xe6, 0x0c, 0xde, 0x5d, 0x7d, 0x33, 0x00, 0x6e, 0x21, 0x86, 0x6d, 0x87, 0x74, 0x8a, 0xd4, 0x0a, 0x06, 0xa2, 0x99, 0x2f, 0x1d, 0x25, 0xfe, 0x9e, 0x8f, 0x46, 0x47, 0xa5, 0x56, 0xda, 0xe0, 0x86, 0xdd, 0x84, 0x86, 0xdc, 0x46, 0xc7, 0x38, 0xe4, 0x1c, 0x4f, 0xb1, 0xed, 0x3d, 0x4c, 0x78, 0xe3, 0x5c, 0x90, 0xe0, 0x87, 0x95, 0x50, 0x64, 0x24, 0x9f, 0x5d, 0x3a, 0x18, 0x4c, 0xcb, 0xad, 0x7c, 0x59, 0xb9, 0x14, 0xbe, 0x6c, 0xbd, 0xca, 0xfe, 0xef, 0xe8, 0xcb, 0x70, 0x55, 0xb3, 0x73, 0x40, 0xb1, 0xd1, 0x42, 0x71, 0xf1, 0x3f, 0x21, 0xb0, 0x1c, 0x60, 0x4a, 0x9e, 0xa5, 0x36, 0xa1, 0xee, 0xc6, 0xb2, 0xaf, 0x46, 0x8c, 0x66, 0x37, 0xbe, 0x59, 0xe7, 0x83, 0x37, 0xb8, 0x88, 0xd7, 0xee, 0x07, 0xb1, 0x8f, 0x9a, 0x03, 0xa7, 0x14, 0xfa, 0xa3, 0xb6, 0xeb, 0x83, 0x3a, 0x2a, 0xef, 0xfd, 0x83, 0x9d, 0x11, 0xbe, 0x4f, 0x51, 0x36, 0x94, 0x76, 0xe6, 0x68, 0xff, 0xb0, 0x3d, 0x48, 0xef, 0xc5, 0x84, 0x23, 0x47, 0x9f, 0xc8, 0xbe, 0x01, 0xdb, 0xdb, 0x53, 0x19, 0x68, 0xe3, 0x34, 0x2e, 0xf4, 0x3c, 0xd9, 0x6a, 0xc6, 0xe0, 0xff, 0xf1, 0xb5, 0xe6, 0xea, 0x97, 0x61, 0xce, 0x97, 0x3d, 0xa0, 0x68, 0xd4, 0x99, 0x91, 0x93, 0x5b, 0xae, 0x6d, 0x69, 0xf0, 0x7b, 0x4d, 0x2d, 0x02, 0xfe, 0x24, 0x11, 0x58, 0xec, 0x09, 0x72, 0xbc, 0xba, 0x16, 0x5b, 0x23, 0x61, 0x89, 0xb6, 0x7d, 0x33, 0xd6, 0xc4, 0xbd, 0x4c, 0x5f, 0x1f, 0x54, 0x7b, 0x7a, 0x27, 0xdd, 0x21, 0xb2, 0x91, 0x95, 0x7e, 0xcc, 0x93, 0xc3, 0x36, 0xd8, 0x53, 0x4a, 0x61, 0x20, 0x03, 0x5a, 0xb1, 0xd1, 0xf9, 0x1d, 0x6d, 0x86, 0x28, 0xb6, 0xa2, 0x76, 0x29, 0x21, 0x3b, 0x6e, 0x72, 0x25, 0x3c, 0x43, 0xa8, 0x87, 0xa4, 0xac, 0x92, 0xa7, 0xad, 0xd8, 0x1b, 0x16, 0x94, 0x69, 0xf2, 0xdb, 0x1e, 0x54, 0xcc, 0xa5, 0x50, 0xcf, 0x36, 0xd0, 0xe0, 0x13, 0x20, 0xd1, 0xc1, 0x69, 0xca, 0x7d, 0x14, 0xaa, 0xb1, 0x71, 0xff, 0xaf, 0xe6, 0x58, 0x84, 0x3a, 0x45, 0xb0, 0x52, 0xec, 0x32, 0x44, 0xf3, 0xe7, 0x49, 0x71, 0xc2, 0x3b, 0x98, 0xb6, 0xc2, 0x10, 0x8f, 0xd8, 0xeb, 0x5b, 0x64, 0x93, 0x7c, 0x46, 0xa3, 0x70, 0x88, 0xff, 0x5c, 0xe4, 0xe3, 0x77, 0xa5, 0xbb, 0x95, 0xb8, 0x57, 0x28, 0x45, 0x54, 0xd8, 0x0c, 0xe7, 0xb0, 0x8e, 0x5b, 0x26, 0xd5, 0x85, 0x7f, 0x16, 0x56, 0x2c, 0x39, 0xbe, 0xde, 0x90, 0x88, 0x6f, 0x07, 0xa7, 0xb8, 0x83, 0x5f, 0x6a, 0xa3, 0x39, 0x32, 0x10, 0xdc, 0x5e, 0xac, 0xc7, 0x73, 0x76, 0xbd, 0xbb, 0xca, 0xe9, 0xe8, 0xd1, 0x15, 0xfb, 0x11, 0x4b, 0x92, 0xb9, 0xab, 0x32, 0xf1, 0xb6, 0xb6, 0x60, 0xdb, 0x6b, 0x46, 0x40, 0xf3, 0x8d, 0x08, 0xcb, 0x86, 0x9a, 0x94, 0x9d, 0x52, 0x57, 0x64, 0x48, 0xdf, 0x6f, 0x34, 0xc8, 0xda, 0x21, 0x1c, 0x06, 0x27, 0x99, 0xf1, 0x58, 0xab, 0x11, 0x96, 0xfd, 0xac, 0x55, 0xf2, 0xfd, 0x53, 0xdf, 0xef, 0xd8, 0x78, 0xbd, 0x08, 0xc8, 0xb2, 0xad, 0xfd, 0x79, 0x40, 0x9e, 0x0d, 0xb9, 0xb3, 0x27, 0x35, 0xff, 0xf2, 0xbb, 0x9d, 0x92, 0xe7, 0x18, 0x5c, 0xb6, 0x6b, 0x97, 0x63, 0x0e, 0x2d, 0x8e, 0xa0, 0xd8, 0x83, 0x25, 0x89, 0xc0, 0xe4, 0xb0, 0xf0, 0x91, 0xfe, 0x7c, 0x53, 0x4d, 0x01, 0x60, 0xb4, 0x64, 0x00, 0xed, 0x51, 0x4a, 0x69, 0x27, 0xab, 0x11, 0x3a, 0x1d, 0xf4, 0x99, 0xa3, 0x7e, 0xef, 0x97, 0x3e, 0x70, 0x90, 0x05, 0x06, 0x16, 0xde, 0xdd, 0x20, 0xf4, 0x01, 0x9c, 0x1f, 0x6c, 0xc0, 0x63, 0xe5, 0xa4, 0x13, 0xa2, 0xb6, 0x1e, 0x69, 0x6e, 0x91, 0x69, 0x12, 0x5a, 0x51, 0xbb, 0xb6, 0x16, 0x25, 0xd8, 0xa8, 0xef, 0xa2, 0x01, 0x39, 0x63, 0xa7, 0x52, 0xf1, 0x7b, 0x70, 0x31, 0xf4, 0x23, 0xfa, 0xa5, 0x99, 0x74, 0xad, 0x1a, 0xfe, 0xbc, 0x8e, 0xf8, 0xb1, 0x0e, 0x19, 0x83, 0x0a, 0x67, 0x79, 0x4b, 0xdf, 0x43, 0x74, 0xa8, 0x7f, 0xbe, 0x4b, 0xf3, 0xf2, 0x75, 0x43, 0xc8, 0x1d, 0x1b, 0x93, 0xf3, 0xd7, 0x64, 0x4f, 0x39, 0xe9, 0x49, 0x75, 0x78, 0x1c, 0x7c, 0x15, 0x9b, 0xeb, 0xd5, 0xde, 0xbc, 0xef, 0x0f, 0x1d, 0x90, 0x48, 0x52, 0x55, 0xee, 0x1f, 0x70, 0xb1, 0xb0, 0x87, 0xcb, 0x38, 0xf9, 0xd5, 0x48, 0x83, 0x4a, 0x9a, 0x41, 0x9b, 0x33, 0x59, 0x07, 0xa2, 0x06, 0x23, 0xaa, 0xb4, 0x00, 0x13, 0x64, 0x81, 0x83, 0x3a, 0xfd, 0x56, 0xff, 0x8d, 0xd5, 0xaf, 0x0b, 0xe3, 0x19, 0xa2, 0xef, 0xc8, 0x83, 0x3a, 0xba, 0xb0, 0x85, 0x2e, 0xd9, 0x3d, 0x58, 0xb0, 0x4c, 0x43, 0x78, 0xe1, 0xb2, 0x1a, 0x02, 0x2c, 0xd9, 0xc7, 0xc9, 0xca, 0x5d, 0x43, 0x91, 0xd9, 0x35, 0x0c, 0xbe, 0xa4, 0xa7, 0x54, 0x95, 0x68, 0x2f, 0x56, 0x79, 0xb1, 0x06, 0x77, 0x1e, 0x07, 0x39, 0x67, 0xd8, 0x1d, 0x9a, 0x46, 0x1c, 0xd7, 0xdd, 0x10, 0x8e, 0x51, 0x5f, 0xf3, 0x59, 0x60, 0xca, 0x8c, 0x83, 0xd4, 0xb8, 0xb5, 0x0b, 0xd8, 0xd6, 0x75, 0xf3, 0x91, 0xf1, 0x23, 0x33, 0x79, 0x87, 0x91, 0xfe, 0x55, 0xd1, 0xea, 0x63, 0x46, 0xb0, 0x42, 0xf7, 0x1b, 0x2e, 0x0e, 0x59, 0x9f, 0xef, 0x77, 0x3c, 0xc5, 0x3e, 0x6d, 0xe1, 0x6f, 0xc0, 0xff, 0xf0, 0x56, 0x1c, 0x1d, 0xd5, 0xca, 0x88, 0x34, 0x31, 0x78, 0x16, 0x2c, 0xed, 0x68, 0x60, 0xff, 0x6c, 0x36, 0x11, 0x2d, 0xee, 0xb3, 0x97, 0x30, 0x6d, 0x33, 0x0a, 0x5a, 0x74, 0x2d, 0xc5, 0xd6, 0x42, 0x6a, 0x34, 0x1c, 0x7d, 0xda, 0xd4, 0xf4, 0x82, 0xee, 0x0f, 0x7f, 0x62, 0xf0, 0x39, 0xb2, 0xf3, 0xba, 0x80, 0xd9, 0xa5, 0x4b, 0x92, 0x0a, 0x87, 0x07, 0x78, 0xf6, 0x52, 0xa5, 0x51, 0x13, 0x63, 0x60, 0xc0, 0x4b, 0xcb, 0x71, 0xa3, 0x63, 0x56, 0xa7, 0xf2, 0x08, 0x42, 0x7b, 0x64, 0xc0, 0x43, 0x84, 0x3e, 0x6e, 0xc1, 0x25, 0xe1, 0xf8, 0x68, 0x64, 0x54, 0x54, 0xda, 0xff, 0xcd, 0x4d, 0x22, 0xb1, 0x90, 0xd4, 0x58, 0xd7, 0x92, 0x0e, 0x91, 0xfc, 0xd6, 0xe0, 0x7d, 0xfa, 0xea, 0x9c, 0x2f, 0xf4, 0x40, 0x23, 0xc0, 0x28, 0xdb, 0xcb, 0x48, 0xa4, 0xda, 0x23, 0x63, 0x5d, 0x1d, 0xb5, 0xd1, 0x7b, 0x14, 0xdf, 0xfe, 0xa2, 0xde, 0x6c, 0x46, 0xa1, 0x3e, 0x1b, 0x57, 0x1a, 0x83, 0x9b, 0xff, 0xf0, 0xd7, 0xde, 0xf6, 0x75, 0x67, 0xb3, 0x15, 0x27, 0x73, 0xfb, 0xa3, 0x2b, 0xd9, 0xed, 0x3b, 0xb5, 0x2c, 0x9e, 0x58, 0xe1, 0x3b, 0x90, 0x90, 0x29, 0x7e, 0x23, 0x22, 0xa0, 0x93, 0xf4, 0x04, 0x16, 0xff, 0xe8, 0xfe, 0xc2, 0x96, 0xec, 0x08, 0x00, 0xb7, 0xf1, 0x86, 0x28, 0x2d, 0x50, 0x67, 0x1d, 0xf4, 0x4d, 0x5c, 0xfb, 0x8c, 0x04, 0x7d, 0x58, 0xa7, 0x31, 0x20, 0x64, 0x37, 0x9d, 0x43, 0xb5, 0x2b, 0xe3, 0xd0, 0xbc, 0x56, 0x4a, 0xb7, 0x39, 0xba, 0xd0, 0xd5, 0xae, 0x3c, 0xdd, 0xf3, 0x4c, 0xb6, 0x61, 0xaa, 0xc2, 0xe6, 0x1b, 0xcb, 0xe9, 0x66, 0xd2, 0x12, 0x17, 0x46, 0xc2, 0xee, 0x80, 0x34, 0x32, 0x62, 0x3b, 0x35, 0x31, 0xe4, 0x17, 0x95, 0x83, 0x44, 0x57, 0x21, 0x54, 0xb3, 0xbd, 0x01, 0x07, 0xe5, 0xc3, 0xb4, 0x43, 0xf2, 0xbd, 0x60, 0x5c, 0x20, 0xb9, 0xe9, 0x28, 0x90, 0x2a, 0x4d, 0x0e, 0x31, 0xb8, 0xbc, 0xc2, 0x00, 0x60, 0xbc, 0x7e, 0x09, 0xe4, 0x0a, 0xf4, 0x99, 0x9d, 0xf6, 0xdc, 0x9a, 0x1d, 0x37, 0x45, 0xe4, 0x88, 0x22, 0xa3, 0xc0, 0xb1, 0x36, 0x3e, 0x2c, 0x34, 0x53, 0x31, 0xe9, 0x1d, 0x9c, 0x23, 0x7c, 0x7a, 0x70, 0x5e, 0x3e, 0x4e, 0x8d, 0x62, 0x7b, 0xa3, 0x19, 0xd0, 0x1a, 0x16, 0xe7, 0xf5, 0x3b, 0x54, 0xff, 0x22, 0x9d, 0xc3, 0x02, 0xcd, 0xee, 0x4c, 0xc7, 0x5e, 0x56, 0xe5, 0x0c, 0x44, 0xc5, 0xec, 0x90, 0x30, 0x96, 0x7c, 0xd8, 0x22, 0x38, 0x2d, 0xc6, 0xf1, 0x2e, 0xc6, 0x49, 0xdd, 0x94, 0x99, 0xc7, 0xb6, 0xca, 0x08, 0x33, 0x82, 0x6a, 0xee, 0xc2, 0x27, 0xa1, 0xee, 0xa3, 0x12, 0xf9, 0xd7, 0x0a, 0x55, 0x23, 0xca, 0x8c, 0x1e, 0xf3, 0x7f, 0x5d, 0x47, 0x1c, 0x26, 0x32, 0x7c, 0x62, 0x11, 0x4b, 0x95, 0x23, 0x7e, 0x90, 0xab, 0xc4, 0xb1, 0xb9, 0x65, 0xb0, 0x7f, 0xe3, 0x1b, 0xd8, 0x15, 0xc5, 0xce, 0xd0, 0x3a, 0x4f, 0xce, 0xdd, 0x69, 0x9f, 0xd8, 0x81, 0xf3, 0x72, 0xb8, 0x22, 0x17, 0xe7, 0x3e, 0xba, 0x90, 0xa3, 0xd0, 0x3b, 0x4a, 0x1f, 0x5a, 0x26, 0x99, 0xca, 0x7d, 0x6c, 0x7e, 0x20, 0x11, 0x2d, 0xcc, 0x0d, 0x1b, 0x1d, 0x38, 0x73, 0xda, 0xe1, 0x1e, 0x24, 0xa6, 0xda, 0xcc, 0x29, 0x00, 0x9f, 0x95, 0x08, 0xa7, 0x58, 0xda, 0x50, 0xf0, 0x8b, 0x2c, 0xb3, 0xb7, 0xaf, 0xa6, 0x82, 0x83, 0x1d, 0x72, 0x3a, 0x9a, 0xb0, 0x02, 0x48, 0xc0, 0xc2, 0x0e, 0x3a, 0x45, 0xf3, 0x13, 0xd6, 0xa9, 0x44, 0xec, 0x1a, 0xa0, 0x48, 0xbd, 0x47, 0xa8, 0x65, 0x51, 0x71, }; }; } tlfloat-1.15.0/src/include/tlfloat/tlfloat.h000066400000000000000000004567521477036600700207750ustar00rootroot00000000000000#ifndef __TLFLOAT_H_INCLUDED__ #define __TLFLOAT_H_INCLUDED__ #include #include #include #include #ifndef TLFLOAT_FP_NAN #define TLFLOAT_FP_NAN 0 #define TLFLOAT_FP_INFINITE 1 #define TLFLOAT_FP_ZERO 2 #define TLFLOAT_FP_SUBNORMAL 3 #define TLFLOAT_FP_NORMAL 4 #define TLFLOAT_FP_ILOGB0 ((int)0x80000000) #define TLFLOAT_FP_ILOGBNAN ((int)2147483647) #define TLFLOAT_FLT128_MANT_DIG 113 #define TLFLOAT_FLT128_MIN_EXP (-16381) #define TLFLOAT_FLT128_MAX_EXP 16384 #define TLFLOAT_FLT128_DIG 33 #define TLFLOAT_FLT128_MIN_10_EXP (-4931) #define TLFLOAT_FLT128_MAX_10_EXP 4932 #define TLFLOAT_FLT256_MANT_DIG 237 #endif #if defined(TLFLOAT_DOXYGEN) /** Calls to libquadmath functions are replaced to the corresponding calls to tlfloat functions if this macro is defined */ #define TLFLOAT_LIBQUADMATH_EMULATION #endif #ifdef __cplusplus #include #ifndef TLFLOAT_NO_LIBSTDCXX #include #include #include #endif extern "C" { #endif #if defined(TLFLOAT_COMPILER_SUPPORTS_INT128) typedef __int128_t tlfloat_int128_t_; typedef __uint128_t tlfloat_uint128_t_; #else /** tlfloat_int128_t_ and tlfloat_uint128_t_ are types for handling * 128-bit integer numbers in C. The data size and data structure of * these types are the same as ordinary integer types. These are POD * types that can be safely passed with C ABI. If the compiler * supports __int128_t and __uint128_t, these type are aliases for * those types. */ typedef struct { uint64_t e[1 << 1]; } tlfloat_int128_t_; typedef struct { uint64_t e[1 << 1]; } tlfloat_uint128_t_; #endif #if defined(TLFLOAT_COMPILER_SUPPORTS_FLOAT128) typedef __float128 tlfloat_quad_; #elif defined(TLFLOAT_LONGDOUBLE_IS_FLOAT128) typedef long double tlfloat_quad_; #elif defined(TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128) typedef _Float128 tlfloat_quad_; #else /** This type is for handling quadruple-precision IEEE floating-point * numbers in C. The data size and data structure of this type are the * same as a quad-precision floating-point number. This is a POD type * that can be safely passed with C ABI. If the compiler supports * __float128, this type is an alias for __float128. When compling * with a compiler on which long double is IEEE float 128, this type * is an alias for long double. */ typedef struct { uint64_t e[2]; } tlfloat_quad_; #endif /** This type is for handling octuple-precision IEEE floating-point * numbers in C. The data size and data structure of this type are the * same as an octuple-precision floating-point number. This is a POD * type that can be safely passed with C ABI. */ typedef struct { uint64_t e[4]; } tlfloat_octuple_; // /** This function returns TLFLOAT_VERSION_MAJOR * 1000000ULL + TLFLOAT_VERSION_MINOR * 1000ULL + TLFLOAT_VERSION_PATCH */ uint64_t tlfloat_version(); /** The tlfloat_printf family of functions has the functionality to produce output of numbers of the types defined in TLFloat library, * in addition to the functionality of the standard printf family of functions. * To output a number of type defined in TLFloat library, * use _m as the length modifier where m is a decimal integer represents the data size of the corresponding argument in bits. * For example, use '\%_256g' to output an octuple-precision FP number, and '\%_128d' to output a 128-bit signed integer. * Q and O modifier have to be used to output an FP number in tlfloat_quad and tlfloat_octuple types, respectively. */ int tlfloat_printf(const char *fmt, ...); /** See explanation for tlfloat_printf() */ int tlfloat_fprintf(FILE *fp, const char *fmt, ...); /** See explanation for tlfloat_printf() */ int tlfloat_snprintf(char *str, size_t size, const char *fmt, ...); /** See explanation for tlfloat_printf() */ int tlfloat_vprintf(const char *fmt, va_list ap); /** See explanation for tlfloat_printf() */ int tlfloat_vfprintf(FILE *fp, const char *fmt, va_list ap); /** See explanation for tlfloat_printf() */ int tlfloat_vsnprintf(char *str, size_t size, const char *fmt, va_list ap); #if defined(TLFLOAT_DOXYGEN) || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 14) /** This functionality is experimental. Please use tlfloat_printf functions instead. On systems with GLIBC, printf hooks can be registered by calling this function. */ int tlfloat_registerPrintfHook(); /** Unregister printf hooks */ void tlfloat_unregisterPrintfHook(); #endif /** The tlfloat_strtod family of functions provides functionality equivalent to the standard strtod family of functions, * but corresponds to the types defined in the TLFloat library. */ double tlfloat_strtod(const char *, const char **); float tlfloat_strtof(const char *, const char **); #if !defined(TLFLOAT_DOXYGEN) tlfloat_quad_ tlfloat_strtoq_(const char *, const char **); tlfloat_octuple_ tlfloat_strtoo_(const char *, const char **); tlfloat_int128_t_ tlfloat_strtoi128(const char *, const char **, const int); tlfloat_uint128_t_ tlfloat_strtou128(const char *, const char **, const int); // double tlfloat_cast_d_q(const tlfloat_quad_ x); double tlfloat_cast_d_o(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_cast_q_d_(const double x); tlfloat_quad_ tlfloat_cast_q_o (const tlfloat_octuple_ x); tlfloat_octuple_ tlfloat_cast_o_d_(const double x); tlfloat_octuple_ tlfloat_cast_o_q(const tlfloat_quad_ x); int64_t tlfloat_cast_i64_q(const tlfloat_quad_ x); tlfloat_quad_ tlfloat_cast_q_i64_(const int64_t x); int64_t tlfloat_cast_i64_o(const tlfloat_octuple_ x); tlfloat_octuple_ tlfloat_cast_o_i64_(const int64_t x); uint64_t tlfloat_cast_u64_q(const tlfloat_quad_ x); tlfloat_quad_ tlfloat_cast_q_u64_(const uint64_t x); uint64_t tlfloat_cast_u64_o(const tlfloat_octuple_ x); tlfloat_octuple_ tlfloat_cast_o_u64_(const uint64_t x); // tlfloat_int128_t_ tlfloat_cast_i128_i64_(const int64_t x); int64_t tlfloat_cast_i64_i128(const tlfloat_int128_t_ x); tlfloat_uint128_t_ tlfloat_cast_u128_u64_(const uint64_t x); uint64_t tlfloat_cast_u64_u128(const tlfloat_uint128_t_ x); tlfloat_int128_t_ tlfloat_cast_i128_d_(const double x); double tlfloat_cast_d_i128(const tlfloat_int128_t_ x); tlfloat_uint128_t_ tlfloat_cast_u128_d_(const double x); double tlfloat_cast_d_u128(const tlfloat_uint128_t_ x); tlfloat_int128_t_ tlfloat_cast_i128_q(const tlfloat_quad_ x); tlfloat_quad_ tlfloat_cast_q_i128(const tlfloat_int128_t_ x); tlfloat_uint128_t_ tlfloat_cast_u128_q(const tlfloat_quad_ x); tlfloat_quad_ tlfloat_cast_q_u128(const tlfloat_uint128_t_ x); tlfloat_int128_t_ tlfloat_cast_i128_o(const tlfloat_octuple_ x); tlfloat_octuple_ tlfloat_cast_o_i128(const tlfloat_int128_t_ x); tlfloat_uint128_t_ tlfloat_cast_u128_o(const tlfloat_octuple_ x); tlfloat_octuple_ tlfloat_cast_o_u128(const tlfloat_uint128_t_ x); int tlfloat_eq_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); int tlfloat_ne_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); int tlfloat_lt_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); int tlfloat_le_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); int tlfloat_gt_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); int tlfloat_ge_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); tlfloat_int128_t_ tlfloat_add_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); tlfloat_int128_t_ tlfloat_sub_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); tlfloat_int128_t_ tlfloat_mul_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); tlfloat_int128_t_ tlfloat_div_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); tlfloat_int128_t_ tlfloat_mod_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); tlfloat_int128_t_ tlfloat_and_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); tlfloat_int128_t_ tlfloat_or_i128_i128 (const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); tlfloat_int128_t_ tlfloat_xor_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y); tlfloat_int128_t_ tlfloat_not_i128(const tlfloat_int128_t_ x); tlfloat_int128_t_ tlfloat_shl_i128_i(const tlfloat_int128_t_ x, const int y); tlfloat_int128_t_ tlfloat_shr_i128_i(const tlfloat_int128_t_ x, const int y); tlfloat_int128_t_ tlfloat_neg_i128(const tlfloat_int128_t_ x); int tlfloat_eq_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); int tlfloat_ne_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); int tlfloat_lt_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); int tlfloat_le_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); int tlfloat_gt_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); int tlfloat_ge_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); tlfloat_uint128_t_ tlfloat_add_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); tlfloat_uint128_t_ tlfloat_sub_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); tlfloat_uint128_t_ tlfloat_mul_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); tlfloat_uint128_t_ tlfloat_div_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); tlfloat_uint128_t_ tlfloat_mod_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); tlfloat_uint128_t_ tlfloat_and_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); tlfloat_uint128_t_ tlfloat_or_u128_u128 (const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); tlfloat_uint128_t_ tlfloat_xor_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y); tlfloat_uint128_t_ tlfloat_not_u128(const tlfloat_uint128_t_ x); tlfloat_uint128_t_ tlfloat_shl_u128_i(const tlfloat_uint128_t_ x, const int y); tlfloat_uint128_t_ tlfloat_shr_u128_i(const tlfloat_uint128_t_ x, const int y); // int tlfloat_eq_q_q(const tlfloat_quad_ x, const tlfloat_quad_ y); int tlfloat_ne_q_q(const tlfloat_quad_ x, const tlfloat_quad_ y); int tlfloat_lt_q_q(const tlfloat_quad_ x, const tlfloat_quad_ y); int tlfloat_le_q_q(const tlfloat_quad_ x, const tlfloat_quad_ y); int tlfloat_gt_q_q(const tlfloat_quad_ x, const tlfloat_quad_ y); int tlfloat_ge_q_q(const tlfloat_quad_ x, const tlfloat_quad_ y); int tlfloat_eq_o_o(const tlfloat_octuple_ x, const tlfloat_octuple_ y); int tlfloat_ne_o_o(const tlfloat_octuple_ x, const tlfloat_octuple_ y); int tlfloat_lt_o_o(const tlfloat_octuple_ x, const tlfloat_octuple_ y); int tlfloat_le_o_o(const tlfloat_octuple_ x, const tlfloat_octuple_ y); int tlfloat_gt_o_o(const tlfloat_octuple_ x, const tlfloat_octuple_ y); int tlfloat_ge_o_o(const tlfloat_octuple_ x, const tlfloat_octuple_ y); #endif // #if !defined(TLFLOAT_DOXYGEN) // float tlfloat_addf(const float x, const float y); double tlfloat_add(const double x, const double y); float tlfloat_subf(const float x, const float y); double tlfloat_sub(const double x, const double y); float tlfloat_mulf(const float x, const float y); double tlfloat_mul(const double x, const double y); float tlfloat_divf(const float x, const float y); double tlfloat_div(const double x, const double y); float tlfloat_negf(const float x); double tlfloat_neg(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_fmaf(const float x, const float y, const float z); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_fma(const double x, const double y, const double z); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_sqrtf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_sqrt(const double x); // /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_fabsf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_fabs(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_copysignf(const float x, const float y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_copysign(const double x, const double y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_fmaxf(const float x, const float y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_fmax(const double x, const double y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_fminf(const float x, const float y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_fmin(const double x, const double y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_fdimf(const float x, const float y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_fdim(const double x, const double y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_ldexpf(const float x, const int y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_ldexp(const double x, const int y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_frexpf(const float x, int *y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_frexp(const double x, int *y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_modff(const float x, float *y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_modf(const double x, double *y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_nextafterf(const float x, const float y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_nextafter(const double x, const double y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ int tlfloat_ilogbf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ int tlfloat_ilogb(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ int tlfloat_isnanf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ int tlfloat_isnan(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ int tlfloat_isinff(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ int tlfloat_isinf(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ int tlfloat_finitef(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ int tlfloat_finite(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ int tlfloat_fpclassifyf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ int tlfloat_fpclassify(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ int tlfloat_signbitf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ int tlfloat_signbit(const double x); // /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_hypotf(const float x, const float y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_hypot(const double x, const double y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_truncf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_trunc(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_floorf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_floor(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_ceilf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_ceil(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_roundf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_round(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_rintf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_rint(const double x); // /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_sinf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_sin(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_cosf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_cos(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_tanf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_tan(const double x); float tlfloat_sinpif(const float x); double tlfloat_sinpi(const double x); float tlfloat_cospif(const float x); double tlfloat_cospi(const double x); float tlfloat_tanpif(const float x); double tlfloat_tanpi(const double x); void tlfloat_sincosf(const float x, float *s, float *c); void tlfloat_sincos(const double x, double *s, double *c); void tlfloat_sincospif(const float x, float *s, float *c); void tlfloat_sincospi(const double x, double *s, double *c); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_asinf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_asin(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_acosf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_acos(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_atanf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_atan(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_atan2f(const float y, const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_atan2(const double y, const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_expf(const float a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_exp(const double a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_expm1f(const float a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_expm1(const double a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_exp2f(const float a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_exp2(const double a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_exp10f(const float a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_exp10(const double a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_logf(const float a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_log(const double a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_log1pf(const float a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_log1p(const double a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_log2f(const float a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_log2(const double a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_log10f(const float a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_log10(const double a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_powf(const float x, const float y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_pow(const double x, const double y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_cbrtf(const float a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_cbrt(const double a); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_sinhf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_sinh(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_coshf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_cosh(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_tanhf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_tanh(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_asinhf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_asinh(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_acoshf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_acosh(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_atanhf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_atanh(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_fmodf(const float x, const float y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_fmod(const double x, const double y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_remainderf(const float x, const float y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_remainder(const double x, const double y); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_remquof(const float x, const float y, int *quo); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_remquo(const double x, const double y, int *quo); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_erff(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_erf(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_erfcf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_erfc(const double x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ float tlfloat_tgammaf(const float x); /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ double tlfloat_tgamma(const double x); /** This is experimental implementation of log gamma function. Link with -ltlfloat. */ float tlfloat_lgammaf(const float x); /** This is experimental implementation of log gamma function. Link with -ltlfloat. */ double tlfloat_lgamma(const double x); #if !defined(TLFLOAT_DOXYGEN) tlfloat_quad_ tlfloat_addq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_addo(const tlfloat_octuple_ x, const tlfloat_octuple_ y); tlfloat_quad_ tlfloat_subq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_subo(const tlfloat_octuple_ x, const tlfloat_octuple_ y); tlfloat_quad_ tlfloat_mulq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_mulo(const tlfloat_octuple_ x, const tlfloat_octuple_ y); tlfloat_quad_ tlfloat_divq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_divo(const tlfloat_octuple_ x, const tlfloat_octuple_ y); tlfloat_quad_ tlfloat_negq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_nego(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_fmaq(const tlfloat_quad_ x, const tlfloat_quad_ y, const tlfloat_quad_ z); tlfloat_octuple_ tlfloat_fmao(const tlfloat_octuple_ x, const tlfloat_octuple_ y, const tlfloat_octuple_ z); tlfloat_quad_ tlfloat_sqrtq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_sqrto(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_fabsq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_fabso(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_copysignq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_copysigno(const tlfloat_octuple_ x, const tlfloat_octuple_ y); tlfloat_quad_ tlfloat_fmaxq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_fmaxo(const tlfloat_octuple_ x, const tlfloat_octuple_ y); tlfloat_quad_ tlfloat_fminq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_fmino(const tlfloat_octuple_ x, const tlfloat_octuple_ y); tlfloat_quad_ tlfloat_fdimq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_fdimo(const tlfloat_octuple_ x, const tlfloat_octuple_ y); tlfloat_quad_ tlfloat_ldexpq(const tlfloat_quad_ x, const int y); tlfloat_octuple_ tlfloat_ldexpo(const tlfloat_octuple_ x, const int y); tlfloat_quad_ tlfloat_frexpq(const tlfloat_quad_ x, int *y); tlfloat_octuple_ tlfloat_frexpo(const tlfloat_octuple_ x, int *y); tlfloat_quad_ tlfloat_modfq(const tlfloat_quad_ x, tlfloat_quad_ *y); tlfloat_octuple_ tlfloat_modfo(const tlfloat_octuple_ x, tlfloat_octuple_ *y); tlfloat_quad_ tlfloat_nextafterq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_nextaftero(const tlfloat_octuple_ x, const tlfloat_octuple_ y); int tlfloat_ilogbq(const tlfloat_quad_ x); int tlfloat_ilogbo(const tlfloat_octuple_ x); int tlfloat_isnanq(const tlfloat_quad_ x); int tlfloat_isnano(const tlfloat_octuple_ x); int tlfloat_isinfq(const tlfloat_quad_ x); int tlfloat_isinfo(const tlfloat_octuple_ x); int tlfloat_finiteq(const tlfloat_quad_ x); int tlfloat_finiteo(const tlfloat_octuple_ x); int tlfloat_fpclassifyq(const tlfloat_quad_ x); int tlfloat_fpclassifyo(const tlfloat_octuple_ x); int tlfloat_signbitq(const tlfloat_quad_ x); int tlfloat_signbito(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_hypotq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_hypoto(const tlfloat_octuple_ x, const tlfloat_octuple_ y); tlfloat_quad_ tlfloat_truncq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_trunco(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_floorq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_flooro(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_ceilq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_ceilo(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_roundq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_roundo(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_rintq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_rinto(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_sinq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_sino(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_cosq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_coso(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_tanq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_tano(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_sinpiq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_sinpio(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_cospiq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_cospio(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_tanpiq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_tanpio(const tlfloat_octuple_ x); void tlfloat_sincosq(const tlfloat_quad_ x, tlfloat_quad_ *s, tlfloat_quad_ *c); void tlfloat_sincoso(const tlfloat_octuple_ x, tlfloat_octuple_ *s, tlfloat_octuple_ *c); void tlfloat_sincospiq(const tlfloat_quad_ x, tlfloat_quad_ *s, tlfloat_quad_ *c); void tlfloat_sincospio(const tlfloat_octuple_ x, tlfloat_octuple_ *s, tlfloat_octuple_ *c); tlfloat_quad_ tlfloat_asinq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_asino(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_acosq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_acoso(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_atanq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_atano(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_atan2q(const tlfloat_quad_ y, const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_atan2o(const tlfloat_octuple_ y, const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_expq(const tlfloat_quad_ a); tlfloat_octuple_ tlfloat_expo(const tlfloat_octuple_ a); tlfloat_quad_ tlfloat_expm1q(const tlfloat_quad_ a); tlfloat_octuple_ tlfloat_expm1o(const tlfloat_octuple_ a); tlfloat_quad_ tlfloat_exp2q(const tlfloat_quad_ a); tlfloat_octuple_ tlfloat_exp2o(const tlfloat_octuple_ a); tlfloat_quad_ tlfloat_exp10q(const tlfloat_quad_ a); tlfloat_octuple_ tlfloat_exp10o(const tlfloat_octuple_ a); tlfloat_quad_ tlfloat_logq(const tlfloat_quad_ a); tlfloat_octuple_ tlfloat_logo(const tlfloat_octuple_ a); tlfloat_quad_ tlfloat_log1pq(const tlfloat_quad_ a); tlfloat_octuple_ tlfloat_log1po(const tlfloat_octuple_ a); tlfloat_quad_ tlfloat_log2q(const tlfloat_quad_ a); tlfloat_octuple_ tlfloat_log2o(const tlfloat_octuple_ a); tlfloat_quad_ tlfloat_log10q(const tlfloat_quad_ a); tlfloat_octuple_ tlfloat_log10o(const tlfloat_octuple_ a); tlfloat_quad_ tlfloat_powq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_powo(const tlfloat_octuple_ x, const tlfloat_octuple_ y); tlfloat_quad_ tlfloat_cbrtq(const tlfloat_quad_ a); tlfloat_octuple_ tlfloat_cbrto(const tlfloat_octuple_ a); tlfloat_quad_ tlfloat_sinhq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_sinho(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_coshq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_cosho(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_tanhq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_tanho(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_asinhq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_asinho(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_acoshq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_acosho(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_atanhq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_atanho(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_erfq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_erfo(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_erfcq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_erfco(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_tgammaq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_tgammao(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_lgammaq(const tlfloat_quad_ x); tlfloat_octuple_ tlfloat_lgammao(const tlfloat_octuple_ x); tlfloat_quad_ tlfloat_fmodq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_fmodo(const tlfloat_octuple_ x, const tlfloat_octuple_ y); tlfloat_quad_ tlfloat_remainderq(const tlfloat_quad_ x, const tlfloat_quad_ y); tlfloat_octuple_ tlfloat_remaindero(const tlfloat_octuple_ x, const tlfloat_octuple_ y); tlfloat_quad_ tlfloat_remquoq(const tlfloat_quad_ x, const tlfloat_quad_ y, int *quo); tlfloat_octuple_ tlfloat_remquoo(const tlfloat_octuple_ x, const tlfloat_octuple_ y, int *quo); #endif // #if !defined(TLFLOAT_DOXYGEN) #ifdef __cplusplus } // extern "C" { #endif #if (defined(__cplusplus) && !defined(TLFLOAT_COMPILER_SUPPORTS_FLOAT128) && !defined(TLFLOAT_LONGDOUBLE_IS_FLOAT128) && !defined(TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128)) || defined(TLFLOAT_DOXYGEN) /** tlfloat_quad is a trivially copyable type for handling * quadruple-precision IEEE floating-point numbers in C and C++11. The * data size and data structure of this type are the same as a * quad-precision floating-point number. When compling C code, this * type is an alias for tlfloat_quad_. When compling C++ code without * IEEE float 128 support, this is a struct encapsulating a * tlfloat_quad_ variable with operators overloaded. */ struct tlfloat_quad { tlfloat_quad_ value; tlfloat_quad() { value.e[0] = value.e[1] = 0; } // Conversion to/from the corresponding C type constexpr tlfloat_quad(const tlfloat_quad_& v) : value(v) {} constexpr operator tlfloat_quad_() const { return value; } // Upcast / downcast explicit tlfloat_quad(const struct tlfloat_octuple& v); // Conversion to/from double tlfloat_quad(const double& d) : value(tlfloat_cast_q_d_(d)) {} explicit operator double() const { return tlfloat_cast_d_q(value); } // Conversion to/from integral types template::value && (sizeof(T) < 8 || !std::is_unsigned::value)), int>::type = 0> tlfloat_quad(const T& i) : value(tlfloat_cast_q_i64_(i)) {} template::value && std::is_unsigned::value && sizeof(T) == 8), int>::type = 0> tlfloat_quad(const T& u) : value(tlfloat_cast_q_u64_(u)) {} template::value && (sizeof(T) < 8 || !std::is_unsigned::value)), int>::type = 0> explicit operator T() const { return tlfloat_cast_i64_q(value); } template::value && std::is_unsigned::value && sizeof(T) == 8), int>::type = 0> explicit operator T() const { return tlfloat_cast_u64_q(value); } explicit tlfloat_quad(const tlfloat_int128_t_& i); explicit tlfloat_quad(const tlfloat_uint128_t_& u); explicit operator tlfloat_int128_t_() const; explicit operator tlfloat_uint128_t_() const; #if !defined(TLFLOAT_COMPILER_SUPPORTS_INT128) explicit tlfloat_quad(const struct tlfloat_int128_t& i); explicit tlfloat_quad(const struct tlfloat_uint128_t& u); #endif /** Any non-integer object is memcpy-ed */ template::value && !std::is_same::value && !std::is_same::value && #if !defined(TLFLOAT_COMPILER_SUPPORTS_INT128) !std::is_same::value && !std::is_same::value && #endif !std::is_floating_point::value && !std::is_pointer::value && !std::is_integral::value), int>::type = 0> tlfloat_quad(const fptype& s) { memcpy(&value, &s, sizeof(tlfloat_quad_)); } template::value && !std::is_same::value && !std::is_same::value && #if !defined(TLFLOAT_COMPILER_SUPPORTS_INT128) !std::is_same::value && !std::is_same::value && #endif !std::is_floating_point::value && !std::is_pointer::value && !std::is_integral::value), int>::type = 0> explicit operator fptype() const { fptype ret; memcpy(&ret, &value, sizeof(tlfloat_quad_)); return ret; } // tlfloat_quad operator+(const tlfloat_quad& rhs) const { return tlfloat_addq(value, rhs.value); } tlfloat_quad operator-(const tlfloat_quad& rhs) const { return tlfloat_subq(value, rhs.value); } tlfloat_quad operator*(const tlfloat_quad& rhs) const { return tlfloat_mulq(value, rhs.value); } tlfloat_quad operator/(const tlfloat_quad& rhs) const { return tlfloat_divq(value, rhs.value); } tlfloat_quad operator-() const { return tlfloat_negq(value); } tlfloat_quad operator+() const { return *this; } bool operator==(const tlfloat_quad& rhs) const { return tlfloat_eq_q_q(value, rhs.value); } bool operator!=(const tlfloat_quad& rhs) const { return tlfloat_ne_q_q(value, rhs.value); } bool operator< (const tlfloat_quad& rhs) const { return tlfloat_lt_q_q(value, rhs.value); } bool operator<=(const tlfloat_quad& rhs) const { return tlfloat_le_q_q(value, rhs.value); } bool operator> (const tlfloat_quad& rhs) const { return tlfloat_gt_q_q(value, rhs.value); } bool operator>=(const tlfloat_quad& rhs) const { return tlfloat_ge_q_q(value, rhs.value); } tlfloat_quad& operator++() { *this = tlfloat_addq(value, tlfloat_cast_q_i64_(1)); return *this; } tlfloat_quad& operator--() { *this = tlfloat_subq(value, tlfloat_cast_q_i64_(1)); return *this; } tlfloat_quad operator++(int) { tlfloat_quad t = *this; *this = tlfloat_addq(value, tlfloat_cast_q_i64_(1)); return t; } tlfloat_quad operator--(int) { tlfloat_quad t = *this; *this = tlfloat_subq(value, tlfloat_cast_q_i64_(1)); return t; } }; /** This macro is defined iff tlfloat_quad is not an alias of __float128, but a struct defined in tlfloat.h. */ #define TLFLOAT_QUAD_IS_STRUCT #else // #if (defined(__cplusplus) && !defined(TLFLOAT_COMPILER_SUPPORTS_FLOAT128) && !defined(TLFLOAT_LONGDOUBLE_IS_FLOAT128)) && !defined(TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128)) || defined(TLFLOAT_DOXYGEN) typedef tlfloat_quad_ tlfloat_quad; #endif #if defined(__cplusplus) || defined(TLFLOAT_DOXYGEN) /** tlfloat_octuple is a trivially copyable type for handling * octuple-precision IEEE floating-point numbers in C and older * C++11. The data size and data structure of this type are the same * as an octuple-precision floating-point number. When compling C * code, this type is an alias for tlfloat_octuple_. When compling C++ * code, this is a struct encapsulating a tlfloat_octuple_ variable * with operators overloaded. */ struct tlfloat_octuple { tlfloat_octuple_ value; tlfloat_octuple() { value.e[0] = value.e[1] = value.e[2] = value.e[3] = 0; } // Conversion to/from the corresponding C type constexpr tlfloat_octuple(const tlfloat_octuple_& v) : value(v) {} constexpr operator tlfloat_octuple_() const { return value; } // Upcast / downcast tlfloat_octuple(const tlfloat_quad& v) : value(tlfloat_cast_o_q(v)) {} explicit operator tlfloat_quad() const { return tlfloat_cast_q_o(value); } // Conversion to/from double tlfloat_octuple(const double& d) : value(tlfloat_cast_o_d_(d)) {} explicit operator double() const { return tlfloat_cast_d_o(value); } // Conversion to/from integral types template::value && (sizeof(T) < 8 || !std::is_unsigned::value)), int>::type = 0> tlfloat_octuple(const T& i) : value(tlfloat_cast_o_i64_(i)) {} template::value && std::is_unsigned::value && sizeof(T) == 8), int>::type = 0> tlfloat_octuple(const T& u) : value(tlfloat_cast_o_u64_(u)) {} template::value && (sizeof(T) < 8 || !std::is_unsigned::value)), int>::type = 0> explicit operator T() const { return tlfloat_cast_i64_o(value); } template::value && std::is_unsigned::value && sizeof(T) == 8), int>::type = 0> explicit operator T() const { return tlfloat_cast_u64_o(value); } tlfloat_octuple(const tlfloat_int128_t_& i); tlfloat_octuple(const tlfloat_uint128_t_& u); explicit operator tlfloat_int128_t_() const; explicit operator tlfloat_uint128_t_() const; #if !defined(TLFLOAT_COMPILER_SUPPORTS_INT128) tlfloat_octuple(const struct tlfloat_int128_t& i); tlfloat_octuple(const struct tlfloat_uint128_t& u); #endif /** Any non-integer object is memcpy-ed */ template::value && !std::is_floating_point::value && !std::is_pointer::value && !std::is_integral::value), int>::type = 0> tlfloat_octuple(const fptype& s) { memcpy(&value, &s, sizeof(tlfloat_octuple_)); } template::value && !std::is_floating_point::value && !std::is_pointer::value && !std::is_integral::value), int>::type = 0> explicit operator fptype() const { fptype ret; memcpy(&ret, &value, sizeof(tlfloat_octuple_)); return ret; } // tlfloat_octuple operator+(const tlfloat_octuple& rhs) const { return tlfloat_addo(value, rhs.value); } tlfloat_octuple operator-(const tlfloat_octuple& rhs) const { return tlfloat_subo(value, rhs.value); } tlfloat_octuple operator*(const tlfloat_octuple& rhs) const { return tlfloat_mulo(value, rhs.value); } tlfloat_octuple operator/(const tlfloat_octuple& rhs) const { return tlfloat_divo(value, rhs.value); } tlfloat_octuple operator-() const { return tlfloat_nego(value); } tlfloat_octuple operator+() const { return *this; } bool operator==(const tlfloat_octuple& rhs) const { return tlfloat_eq_o_o(value, rhs.value); } bool operator!=(const tlfloat_octuple& rhs) const { return tlfloat_ne_o_o(value, rhs.value); } bool operator< (const tlfloat_octuple& rhs) const { return tlfloat_lt_o_o(value, rhs.value); } bool operator<=(const tlfloat_octuple& rhs) const { return tlfloat_le_o_o(value, rhs.value); } bool operator> (const tlfloat_octuple& rhs) const { return tlfloat_gt_o_o(value, rhs.value); } bool operator>=(const tlfloat_octuple& rhs) const { return tlfloat_ge_o_o(value, rhs.value); } tlfloat_octuple& operator++() { *this = tlfloat_addo(value, tlfloat_cast_o_i64_(1)); return *this; } tlfloat_octuple& operator--() { *this = tlfloat_subo(value, tlfloat_cast_o_i64_(1)); return *this; } tlfloat_octuple operator++(int) { tlfloat_octuple t = *this; *this = tlfloat_addo(value, tlfloat_cast_o_i64_(1)); return t; } tlfloat_octuple operator--(int) { tlfloat_octuple t = *this; *this = tlfloat_subo(value, tlfloat_cast_o_i64_(1)); return t; } }; #define TLFLOAT_OCTUPLE_IS_STRUCT #else // #if defined(__cplusplus) || defined(TLFLOAT_DOXYGEN) typedef tlfloat_octuple_ tlfloat_octuple; #endif #if (defined(__cplusplus) && !defined(TLFLOAT_COMPILER_SUPPORTS_INT128)) || defined(TLFLOAT_DOXYGEN) /** tlfloat_int128_t is a trivially copyable type for handling 128-bit * signed integer in C and C++11. The data size and data structure of * this type are the same as ordinary integer types. When compling C * code, this type is an alias for tlfloat_int128_t_. When compling * C++ code without __int128_t support, this is a struct encapsulating * a tlfloat_int128_t variable with operators overloaded. */ struct tlfloat_int128_t { tlfloat_int128_t_ value; tlfloat_int128_t() { value.e[0] = value.e[1] = 0; } // Conversion to/from the corresponding C type tlfloat_int128_t(const tlfloat_int128_t_& v) : value(v) {} operator tlfloat_int128_t_() const { return value; } // Conversion to/from double explicit tlfloat_int128_t(const double& d) : value(tlfloat_cast_i128_d_(d)) {} explicit operator double() const { return tlfloat_cast_d_i128(value); } // Conversion to/from tlfloat_uint128_ explicit tlfloat_int128_t(const tlfloat_uint128_t_& d); explicit operator tlfloat_uint128_t_() const; // Conversion to/from integral types template::value && !std::is_unsigned::value && sizeof(T) <= 8), int>::type = 0> tlfloat_int128_t(const T& i) : value(tlfloat_cast_i128_i64_(i)) {} template::value && std::is_unsigned::value && sizeof(T) < 8), int>::type = 0> explicit tlfloat_int128_t(const T& u) : value(tlfloat_cast_i128_i64_((int64_t)u)) {} template::value && std::is_unsigned::value && sizeof(T) == 8), int>::type = 0> explicit tlfloat_int128_t(const T& u) : value((tlfloat_int128_t)tlfloat_cast_u128_u64_(u)) {} template::value && !std::is_unsigned::value && sizeof(T) <= 8), int>::type = 0> explicit operator T() const { return tlfloat_cast_i64_i128(value); } template::value && std::is_unsigned::value && sizeof(T) <= 8), int>::type = 0> explicit operator T() const { tlfloat_uint128_t_ v; memcpy(&v, &value, sizeof(v)); return tlfloat_cast_u64_u128(v); } #ifdef __BIGINT_HPP_INCLUDED__ tlfloat_int128_t(const tlfloat::BigInt<7>& d) { memcpy((void *)this, (void *)&d, sizeof(*this)); } operator tlfloat::BigInt<7>() const { tlfloat::BigInt<7> v; memcpy((void *)&v, (void *)this, sizeof(v)); return v; } #endif explicit tlfloat_int128_t(const tlfloat_quad_& f) : value(tlfloat_cast_i128_q(f)) {} explicit operator tlfloat_quad_() const { return tlfloat_cast_q_i128(value); } explicit tlfloat_int128_t(const tlfloat_octuple_& f) : value(tlfloat_cast_i128_o(f)) {} explicit operator tlfloat_octuple_() const { return tlfloat_cast_o_i128(value); } // tlfloat_int128_t operator+(const tlfloat_int128_t& rhs) const { return tlfloat_add_i128_i128(value, rhs.value); } tlfloat_int128_t operator-(const tlfloat_int128_t& rhs) const { return tlfloat_sub_i128_i128(value, rhs.value); } tlfloat_int128_t operator*(const tlfloat_int128_t& rhs) const { return tlfloat_mul_i128_i128(value, rhs.value); } tlfloat_int128_t operator/(const tlfloat_int128_t& rhs) const { return tlfloat_div_i128_i128(value, rhs.value); } tlfloat_int128_t operator%(const tlfloat_int128_t& rhs) const { return tlfloat_mod_i128_i128(value, rhs.value); } tlfloat_int128_t operator-() const { return tlfloat_neg_i128(value); } tlfloat_int128_t operator+() const { return *this; } tlfloat_int128_t operator&(const tlfloat_int128_t& rhs) const { return tlfloat_and_i128_i128(value, rhs.value); } tlfloat_int128_t operator|(const tlfloat_int128_t& rhs) const { return tlfloat_or_i128_i128 (value, rhs.value); } tlfloat_int128_t operator^(const tlfloat_int128_t& rhs) const { return tlfloat_xor_i128_i128(value, rhs.value); } tlfloat_int128_t operator~() const { return tlfloat_not_i128(value); } tlfloat_int128_t operator<<(const int& rhs) const { return tlfloat_shl_i128_i(value, rhs); } tlfloat_int128_t operator>>(const int& rhs) const { return tlfloat_shr_i128_i(value, rhs); } tlfloat_int128_t& operator<<=(int n) { *this = *this << n; return *this; } tlfloat_int128_t& operator>>=(int n) { *this = *this >> n; return *this; } bool operator==(const tlfloat_int128_t& rhs) const { return tlfloat_eq_i128_i128(value, rhs.value); } bool operator!=(const tlfloat_int128_t& rhs) const { return tlfloat_ne_i128_i128(value, rhs.value); } bool operator< (const tlfloat_int128_t& rhs) const { return tlfloat_lt_i128_i128(value, rhs.value); } bool operator<=(const tlfloat_int128_t& rhs) const { return tlfloat_le_i128_i128(value, rhs.value); } bool operator> (const tlfloat_int128_t& rhs) const { return tlfloat_gt_i128_i128(value, rhs.value); } bool operator>=(const tlfloat_int128_t& rhs) const { return tlfloat_ge_i128_i128(value, rhs.value); } tlfloat_int128_t& operator++() { *this = tlfloat_add_i128_i128(value, tlfloat_cast_i128_i64_(1)); return *this; } tlfloat_int128_t& operator--() { *this = tlfloat_sub_i128_i128(value, tlfloat_cast_i128_i64_(1)); return *this; } tlfloat_int128_t operator++(int) { tlfloat_int128_t t = *this; *this = tlfloat_add_i128_i128(value, tlfloat_cast_i128_i64_(1)); return t; } tlfloat_int128_t operator--(int) { tlfloat_int128_t t = *this; *this = tlfloat_sub_i128_i128(value, tlfloat_cast_i128_i64_(1)); return t; } }; /** tlfloat_uint128_t is a trivially copyable type for handling * 128-bit unsigned integer in C and C++11. The data size and data * structure of this type are the same as ordinary integer types. When * compling C code, this type is an alias for tlfloat_uint128_t_. When * compling C++ code without __uint128_t support, this is a struct * encapsulating a tlfloat_int128_t variable with operators * overloaded. */ struct tlfloat_uint128_t { tlfloat_uint128_t_ value; tlfloat_uint128_t() { value.e[0] = value.e[1] = 0; } // Conversion to/from the corresponding C type tlfloat_uint128_t(const tlfloat_uint128_t_& v) : value(v) {} operator tlfloat_uint128_t_() const { return value; } // Conversion to/from double explicit tlfloat_uint128_t(const double& d) : value(tlfloat_cast_u128_d_(d)) {} explicit operator double() const { return tlfloat_cast_d_u128(value); } // Conversion to/from tlfloat_int128_t explicit tlfloat_uint128_t(const tlfloat_int128_t& d) { memcpy((void *)this, (void *)&d, sizeof(*this)); } explicit operator tlfloat_int128_t() const { tlfloat_int128_t v; memcpy((void *)&v, (void *)this, sizeof(v)); return v; } // Conversion to/from integral types template::value && !std::is_unsigned::value && sizeof(T) <= 8), int>::type = 0> explicit tlfloat_uint128_t(const T& i) : value(tlfloat_cast_u128_u64_(i)) {} template::value && std::is_unsigned::value && sizeof(T) <= 8), int>::type = 0> tlfloat_uint128_t(const T& u) : value(tlfloat_cast_u128_u64_(u)) {} template::value && !std::is_unsigned::value && sizeof(T) <= 8), int>::type = 0> explicit operator T() const { tlfloat_int128_t_ v; memcpy(&v, &value, sizeof(v)); return (T)tlfloat_cast_i64_i128(v); } template::value && std::is_unsigned::value && sizeof(T) <= 8), int>::type = 0> explicit operator T() const { return (T)tlfloat_cast_u64_u128(value); } #ifdef __BIGINT_HPP_INCLUDED__ tlfloat_uint128_t(const tlfloat::BigUInt<7>& d) { memcpy((void *)this, (void *)&d, sizeof(*this)); } operator tlfloat::BigUInt<7>() const { tlfloat::BigUInt<7> v; memcpy((void *)&v, (void *)this, sizeof(v)); return v; } #endif explicit tlfloat_uint128_t(const tlfloat_quad_& f) : value(tlfloat_cast_u128_q(f)) {} explicit operator tlfloat_quad_() const { return tlfloat_cast_q_u128(value); } explicit tlfloat_uint128_t(const tlfloat_octuple_& f) : value(tlfloat_cast_u128_o(f)) {} explicit operator tlfloat_octuple_() const { return tlfloat_cast_o_u128(value); } // tlfloat_uint128_t operator+(const tlfloat_uint128_t& rhs) const { return tlfloat_add_u128_u128(value, rhs.value); } tlfloat_uint128_t operator-(const tlfloat_uint128_t& rhs) const { return tlfloat_sub_u128_u128(value, rhs.value); } tlfloat_uint128_t operator*(const tlfloat_uint128_t& rhs) const { return tlfloat_mul_u128_u128(value, rhs.value); } tlfloat_uint128_t operator/(const tlfloat_uint128_t& rhs) const { return tlfloat_div_u128_u128(value, rhs.value); } tlfloat_uint128_t operator%(const tlfloat_uint128_t& rhs) const { return tlfloat_mod_u128_u128(value, rhs.value); } tlfloat_uint128_t operator-() const { return (tlfloat_uint128_t)tlfloat_neg_i128((tlfloat_int128_t)value); } tlfloat_uint128_t operator+() const { return *this; } tlfloat_uint128_t operator&(const tlfloat_uint128_t& rhs) const { return tlfloat_and_u128_u128(value, rhs.value); } tlfloat_uint128_t operator|(const tlfloat_uint128_t& rhs) const { return tlfloat_or_u128_u128 (value, rhs.value); } tlfloat_uint128_t operator^(const tlfloat_uint128_t& rhs) const { return tlfloat_xor_u128_u128(value, rhs.value); } tlfloat_uint128_t operator~() const { return tlfloat_not_u128(value); } tlfloat_uint128_t operator<<(const int& rhs) const { return tlfloat_shl_u128_i(value, rhs); } tlfloat_uint128_t operator>>(const int& rhs) const { return tlfloat_shr_u128_i(value, rhs); } tlfloat_uint128_t& operator<<=(int n) { *this = *this << n; return *this; } tlfloat_uint128_t& operator>>=(int n) { *this = *this >> n; return *this; } bool operator==(const tlfloat_uint128_t& rhs) const { return tlfloat_eq_u128_u128(value, rhs.value); } bool operator!=(const tlfloat_uint128_t& rhs) const { return tlfloat_ne_u128_u128(value, rhs.value); } bool operator< (const tlfloat_uint128_t& rhs) const { return tlfloat_lt_u128_u128(value, rhs.value); } bool operator<=(const tlfloat_uint128_t& rhs) const { return tlfloat_le_u128_u128(value, rhs.value); } bool operator> (const tlfloat_uint128_t& rhs) const { return tlfloat_gt_u128_u128(value, rhs.value); } bool operator>=(const tlfloat_uint128_t& rhs) const { return tlfloat_ge_u128_u128(value, rhs.value); } tlfloat_uint128_t& operator++() { *this = tlfloat_add_u128_u128(value, tlfloat_cast_u128_u64_(1)); return *this; } tlfloat_uint128_t& operator--() { *this = tlfloat_sub_u128_u128(value, tlfloat_cast_u128_u64_(1)); return *this; } tlfloat_uint128_t operator++(int) { tlfloat_uint128_t t = *this; *this = tlfloat_add_u128_u128(value, tlfloat_cast_u128_u64_(1)); return t; } tlfloat_uint128_t operator--(int) { tlfloat_uint128_t t = *this; *this = tlfloat_sub_u128_u128(value, tlfloat_cast_u128_u64_(1)); return t; } }; inline tlfloat_int128_t::tlfloat_int128_t(const tlfloat_uint128_t_& d) { memcpy((void *)this, (void *)&d, sizeof(*this)); } inline tlfloat_int128_t::operator tlfloat_uint128_t_() const { tlfloat_uint128_t v; memcpy((void *)&v, (void *)this, sizeof(v)); return v; } /** This macro is defined iff tlfloat_int128_t and tlfloat_uint128_t are not aliases of __int128_t and __uint128_t, but structs defined in tlfloat.h. */ #define TLFLOAT_INT128_IS_STRUCT #else typedef tlfloat_int128_t_ tlfloat_int128_t; typedef tlfloat_uint128_t_ tlfloat_uint128_t; #endif // #if (defined(__cplusplus) && !defined(TLFLOAT_COMPILER_SUPPORTS_INT128)) || defined(TLFLOAT_DOXYGEN) #if defined(__cplusplus) || defined(TLFLOAT_DOXYGEN) inline tlfloat_octuple::tlfloat_octuple(const tlfloat_int128_t_& i) : value(tlfloat_cast_o_i128(i)) {} inline tlfloat_octuple::tlfloat_octuple(const tlfloat_uint128_t_& u) : value(tlfloat_cast_o_u128(u)) {} inline tlfloat_octuple::operator tlfloat_int128_t_() const { return tlfloat_cast_i128_o(value); } inline tlfloat_octuple::operator tlfloat_uint128_t_() const { return tlfloat_cast_u128_o(value); } #if !defined(TLFLOAT_COMPILER_SUPPORTS_INT128) inline tlfloat_octuple::tlfloat_octuple(const struct tlfloat_int128_t& i) : value(tlfloat_cast_o_i128(i)) {} inline tlfloat_octuple::tlfloat_octuple(const struct tlfloat_uint128_t& u) : value(tlfloat_cast_o_u128(u)) {} #endif #endif #if defined(TLFLOAT_COMPILER_SUPPORTS_FLOAT128) || defined(TLFLOAT_DOXYGEN) #define TLFLOAT_M_Eq 0x1.5bf0a8b1457695355fb8ac404e7ap+1Q #define TLFLOAT_M_LOG2Eq 0x1.71547652b82fe1777d0ffda0d23ap+0Q #define TLFLOAT_M_LOG10Eq 0x1.bcb7b1526e50e32a6ab7555f5a68p-2Q #define TLFLOAT_M_LN2q 0x1.62e42fefa39ef35793c7673007e6p-1Q #define TLFLOAT_M_LN10q 0x1.26bb1bbb5551582dd4adac5705a6p+1Q #define TLFLOAT_M_PIq 0x1.921fb54442d18469898cc51701b8p+1Q #define TLFLOAT_M_PI_2q 0x1.921fb54442d18469898cc51701b8p+0Q #define TLFLOAT_M_PI_4q 0x1.921fb54442d18469898cc51701b8p-1Q #define TLFLOAT_M_1_PIq 0x1.45f306dc9c882a53f84eafa3ea6ap-2Q #define TLFLOAT_M_2_PIq 0x1.45f306dc9c882a53f84eafa3ea6ap-1Q #define TLFLOAT_M_2_SQRTPIq 0x1.20dd750429b6d11ae3a914fed7fep+0Q #define TLFLOAT_M_SQRT2q 0x1.6a09e667f3bcc908b2fb1366ea95p+0Q #define TLFLOAT_M_SQRT1_2q 0x1.6a09e667f3bcc908b2fb1366ea95p-1Q #define TLFLOAT_FLT128_MAX 0x1.ffffffffffffffffffffffffffffp+16383Q #define TLFLOAT_FLT128_MIN 0x1p-16382Q #define TLFLOAT_FLT128_DENORM_MIN 0x0.0000000000000000000000000001p-16382Q #define TLFLOAT_FLT128_TRUE_MIN 0x0.0000000000000000000000000001p-16382Q #define TLFLOAT_FLT128_EPSILON 0x1p-112Q #elif defined(TLFLOAT_LONGDOUBLE_IS_FLOAT128) #define TLFLOAT_M_Eq 0x1.5bf0a8b1457695355fb8ac404e7ap+1L #define TLFLOAT_M_LOG2Eq 0x1.71547652b82fe1777d0ffda0d23ap+0L #define TLFLOAT_M_LOG10Eq 0x1.bcb7b1526e50e32a6ab7555f5a68p-2L #define TLFLOAT_M_LN2q 0x1.62e42fefa39ef35793c7673007e6p-1L #define TLFLOAT_M_LN10q 0x1.26bb1bbb5551582dd4adac5705a6p+1L #define TLFLOAT_M_PIq 0x1.921fb54442d18469898cc51701b8p+1L #define TLFLOAT_M_PI_2q 0x1.921fb54442d18469898cc51701b8p+0L #define TLFLOAT_M_PI_4q 0x1.921fb54442d18469898cc51701b8p-1L #define TLFLOAT_M_1_PIq 0x1.45f306dc9c882a53f84eafa3ea6ap-2L #define TLFLOAT_M_2_PIq 0x1.45f306dc9c882a53f84eafa3ea6ap-1L #define TLFLOAT_M_2_SQRTPIq 0x1.20dd750429b6d11ae3a914fed7fep+0L #define TLFLOAT_M_SQRT2q 0x1.6a09e667f3bcc908b2fb1366ea95p+0L #define TLFLOAT_M_SQRT1_2q 0x1.6a09e667f3bcc908b2fb1366ea95p-1L #define TLFLOAT_FLT128_MAX 0x1.ffffffffffffffffffffffffffffp+16383L #define TLFLOAT_FLT128_MIN 0x1p-16382L #define TLFLOAT_FLT128_DENORM_MIN 0x0.0000000000000000000000000001p-16382L #define TLFLOAT_FLT128_TRUE_MIN 0x0.0000000000000000000000000001p-16382L #define TLFLOAT_FLT128_EPSILON 0x1p-112L #elif defined(TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128) #define TLFLOAT_M_Eq 0x1.5bf0a8b1457695355fb8ac404e7ap+1F128 #define TLFLOAT_M_LOG2Eq 0x1.71547652b82fe1777d0ffda0d23ap+0F128 #define TLFLOAT_M_LOG10Eq 0x1.bcb7b1526e50e32a6ab7555f5a68p-2F128 #define TLFLOAT_M_LN2q 0x1.62e42fefa39ef35793c7673007e6p-1F128 #define TLFLOAT_M_LN10q 0x1.26bb1bbb5551582dd4adac5705a6p+1F128 #define TLFLOAT_M_PIq 0x1.921fb54442d18469898cc51701b8p+1F128 #define TLFLOAT_M_PI_2q 0x1.921fb54442d18469898cc51701b8p+0F128 #define TLFLOAT_M_PI_4q 0x1.921fb54442d18469898cc51701b8p-1F128 #define TLFLOAT_M_1_PIq 0x1.45f306dc9c882a53f84eafa3ea6ap-2F128 #define TLFLOAT_M_2_PIq 0x1.45f306dc9c882a53f84eafa3ea6ap-1F128 #define TLFLOAT_M_2_SQRTPIq 0x1.20dd750429b6d11ae3a914fed7fep+0F128 #define TLFLOAT_M_SQRT2q 0x1.6a09e667f3bcc908b2fb1366ea95p+0F128 #define TLFLOAT_M_SQRT1_2q 0x1.6a09e667f3bcc908b2fb1366ea95p-1F128 #define TLFLOAT_FLT128_MAX 0x1.ffffffffffffffffffffffffffffp+16383F128 #define TLFLOAT_FLT128_MIN 0x1p-16382F128 #define TLFLOAT_FLT128_DENORM_MIN 0x0.0000000000000000000000000001p-16382F128 #define TLFLOAT_FLT128_TRUE_MIN 0x0.0000000000000000000000000001p-16382F128 #define TLFLOAT_FLT128_EPSILON 0x1p-112F128 #elif defined(__cplusplus) #if !defined(__BYTE_ORDER__) || (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) static inline constexpr tlfloat_quad tlfloat_constq(uint64_t h, uint64_t l) { return tlfloat_quad_ { l, h }; } #else static inline constexpr tlfloat_quad tlfloat_constq(uint64_t h, uint64_t l) { return tlfloat_quad_ { h, l }; } #endif #define TLFLOAT_M_Eq tlfloat_constq( 0x40005bf0a8b14576, 0x95355fb8ac404e7a ) #define TLFLOAT_M_LOG2Eq tlfloat_constq( 0x3fff71547652b82f, 0xe1777d0ffda0d23a ) #define TLFLOAT_M_LOG10Eq tlfloat_constq( 0x3ffdbcb7b1526e50, 0xe32a6ab7555f5a68 ) #define TLFLOAT_M_LN2q tlfloat_constq( 0x3ffe62e42fefa39e, 0xf35793c7673007e6 ) #define TLFLOAT_M_LN10q tlfloat_constq( 0x400026bb1bbb5551, 0x582dd4adac5705a6 ) #define TLFLOAT_M_PIq tlfloat_constq( 0x4000921fb54442d1, 0x8469898cc51701b8 ) #define TLFLOAT_M_PI_2q tlfloat_constq( 0x3fff921fb54442d1, 0x8469898cc51701b8 ) #define TLFLOAT_M_PI_4q tlfloat_constq( 0x3ffe921fb54442d1, 0x8469898cc51701b8 ) #define TLFLOAT_M_1_PIq tlfloat_constq( 0x3ffd45f306dc9c88, 0x2a53f84eafa3ea6a ) #define TLFLOAT_M_2_PIq tlfloat_constq( 0x3ffe45f306dc9c88, 0x2a53f84eafa3ea6a ) #define TLFLOAT_M_2_SQRTPIq tlfloat_constq( 0x3fff20dd750429b6, 0xd11ae3a914fed7fe ) #define TLFLOAT_M_SQRT2q tlfloat_constq( 0x3fff6a09e667f3bc, 0xc908b2fb1366ea95 ) #define TLFLOAT_M_SQRT1_2q tlfloat_constq( 0x3ffe6a09e667f3bc, 0xc908b2fb1366ea95 ) #define TLFLOAT_FLT128_MAX tlfloat_constq( 0x7ffeffffffffffff, 0xffffffffffffffff ) #define TLFLOAT_FLT128_MIN tlfloat_constq( 0x0001000000000000, 0x0000000000000000 ) #define TLFLOAT_FLT128_DENORM_MIN tlfloat_constq( 0x0000000000000000, 0x0000000000000001 ) #define TLFLOAT_FLT128_TRUE_MIN tlfloat_constq( 0x0000000000000000, 0x0000000000000001 ) #define TLFLOAT_FLT128_EPSILON tlfloat_constq( 0x3f8f000000000000, 0x0000000000000000 ) #elif defined(__STDC_VERSION__) #if !defined(__BYTE_ORDER__) || (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) #define TLFLOAT_M_Eq ((tlfloat_quad_) { 0x95355fb8ac404e7a, 0x40005bf0a8b14576 }) #define TLFLOAT_M_LOG2Eq ((tlfloat_quad_) { 0xe1777d0ffda0d23a, 0x3fff71547652b82f }) #define TLFLOAT_M_LOG10Eq ((tlfloat_quad_) { 0xe32a6ab7555f5a68, 0x3ffdbcb7b1526e50 }) #define TLFLOAT_M_LN2q ((tlfloat_quad_) { 0xf35793c7673007e6, 0x3ffe62e42fefa39e }) #define TLFLOAT_M_LN10q ((tlfloat_quad_) { 0x582dd4adac5705a6, 0x400026bb1bbb5551 }) #define TLFLOAT_M_PIq ((const tlfloat_quad_) { 0x8469898cc51701b8, 0x4000921fb54442d1 }) #define TLFLOAT_M_PI_2q ((tlfloat_quad_) { 0x8469898cc51701b8, 0x3fff921fb54442d1 }) #define TLFLOAT_M_PI_4q ((tlfloat_quad_) { 0x8469898cc51701b8, 0x3ffe921fb54442d1 }) #define TLFLOAT_M_1_PIq ((tlfloat_quad_) { 0x2a53f84eafa3ea6a, 0x3ffd45f306dc9c88 }) #define TLFLOAT_M_2_PIq ((tlfloat_quad_) { 0x2a53f84eafa3ea6a, 0x3ffe45f306dc9c88 }) #define TLFLOAT_M_2_SQRTPIq ((tlfloat_quad_) { 0xd11ae3a914fed7fe, 0x3fff20dd750429b6 }) #define TLFLOAT_M_SQRT2q ((tlfloat_quad_) { 0xc908b2fb1366ea95, 0x3fff6a09e667f3bc }) #define TLFLOAT_M_SQRT1_2q ((tlfloat_quad_) { 0xc908b2fb1366ea95, 0x3ffe6a09e667f3bc }) #define TLFLOAT_FLT128_MAX ((tlfloat_quad_) { 0xffffffffffffffff, 0x7ffeffffffffffff }) #define TLFLOAT_FLT128_MIN ((tlfloat_quad_) { 0x0000000000000000, 0x0001000000000000 }) #define TLFLOAT_FLT128_DENORM_MIN ((tlfloat_quad_) { 0x0000000000000001, 0x0000000000000000 }) #define TLFLOAT_FLT128_TRUE_MIN ((tlfloat_quad_) { 0x0000000000000001, 0x0000000000000000 }) #define TLFLOAT_FLT128_EPSILON ((tlfloat_quad_) { 0x0000000000000000, 0x3f8f000000000000 }) #else #define TLFLOAT_M_Eq ((tlfloat_quad_) { 0x40005bf0a8b14576, 0x95355fb8ac404e7a }) #define TLFLOAT_M_LOG2Eq ((tlfloat_quad_) { 0x3fff71547652b82f, 0xe1777d0ffda0d23a }) #define TLFLOAT_M_LOG10Eq ((tlfloat_quad_) { 0x3ffdbcb7b1526e50, 0xe32a6ab7555f5a68 }) #define TLFLOAT_M_LN2q ((tlfloat_quad_) { 0x3ffe62e42fefa39e, 0xf35793c7673007e6 }) #define TLFLOAT_M_LN10q ((tlfloat_quad_) { 0x400026bb1bbb5551, 0x582dd4adac5705a6 }) #define TLFLOAT_M_PIq ((const tlfloat_quad_) { 0x4000921fb54442d1, 0x8469898cc51701b8 }) #define TLFLOAT_M_PI_2q ((tlfloat_quad_) { 0x3fff921fb54442d1, 0x8469898cc51701b8 }) #define TLFLOAT_M_PI_4q ((tlfloat_quad_) { 0x3ffe921fb54442d1, 0x8469898cc51701b8 }) #define TLFLOAT_M_1_PIq ((tlfloat_quad_) { 0x3ffd45f306dc9c88, 0x2a53f84eafa3ea6a }) #define TLFLOAT_M_2_PIq ((tlfloat_quad_) { 0x3ffe45f306dc9c88, 0x2a53f84eafa3ea6a }) #define TLFLOAT_M_2_SQRTPIq ((tlfloat_quad_) { 0x3fff20dd750429b6, 0xd11ae3a914fed7fe }) #define TLFLOAT_M_SQRT2q ((tlfloat_quad_) { 0x3fff6a09e667f3bc, 0xc908b2fb1366ea95 }) #define TLFLOAT_M_SQRT1_2q ((tlfloat_quad_) { 0x3ffe6a09e667f3bc, 0xc908b2fb1366ea95 }) #define TLFLOAT_FLT128_MAX ((tlfloat_quad_) { 0x7ffeffffffffffff, 0xffffffffffffffff }) #define TLFLOAT_FLT128_MIN ((tlfloat_quad_) { 0x0001000000000000, 0x0000000000000000 }) #define TLFLOAT_FLT128_DENORM_MIN ((tlfloat_quad_) { 0x0000000000000000, 0x0000000000000001 }) #define TLFLOAT_FLT128_TRUE_MIN ((tlfloat_quad_) { 0x0000000000000000, 0x0000000000000001 }) #define TLFLOAT_FLT128_EPSILON ((tlfloat_quad_) { 0x3f8f000000000000, 0x0000000000000000 }) #endif #endif #if defined(__cplusplus) #if !defined(__BYTE_ORDER__) || (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) static inline constexpr tlfloat_octuple tlfloat_consto(uint64_t w0, uint64_t w1, uint64_t w2, uint64_t w3) { return tlfloat_octuple_ { w3, w2, w1, w0 }; } #else static inline constexpr tlfloat_octuple tlfloat_consto(uint64_t w0, uint64_t w1, uint64_t w2, uint64_t w3) { return tlfloat_octuple_ { w0, w1, w2, w3 }; } #endif #define TLFLOAT_M_Eo tlfloat_consto(0x400005bf0a8b1457LL, 0x695355fb8ac404e7LL, 0xa79e3b1738b079c5LL, 0xa6d2b53c26c8228dLL) #define TLFLOAT_M_LOG2Eo tlfloat_consto(0x3ffff71547652b82LL, 0xfe1777d0ffda0d23LL, 0xa7d11d6aef551badLL, 0x2b4b1164a2cd9a34LL) #define TLFLOAT_M_LOG10Eo tlfloat_consto(0x3fffdbcb7b1526e5LL, 0x0e32a6ab7555f5a6LL, 0x7b8647dc68c048b9LL, 0x34404747e5a89ef2LL) #define TLFLOAT_M_LN2o tlfloat_consto(0x3fffe62e42fefa39LL, 0xef35793c7673007eLL, 0x5ed5e81e6864ce53LL, 0x16c5b141a2eb7175LL) #define TLFLOAT_M_LN10o tlfloat_consto(0x4000026bb1bbb555LL, 0x1582dd4adac5705aLL, 0x61451c51fd9f3b4bLL, 0xbf21d078c3d0403eLL) #define TLFLOAT_M_PIo tlfloat_consto(0x40000921fb54442dLL, 0x18469898cc51701bLL, 0x839a252049c1114cLL, 0xf98e804177d4c762LL) #define TLFLOAT_M_PI_2o tlfloat_consto(0x3ffff921fb54442dLL, 0x18469898cc51701bLL, 0x839a252049c1114cLL, 0xf98e804177d4c762LL) #define TLFLOAT_M_PI_4o tlfloat_consto(0x3fffe921fb54442dLL, 0x18469898cc51701bLL, 0x839a252049c1114cLL, 0xf98e804177d4c762LL) #define TLFLOAT_M_1_PIo tlfloat_consto(0x3fffd45f306dc9c8LL, 0x82a53f84eafa3ea6LL, 0x9bb81b6c52b32788LL, 0x72083fca2c757bd7LL) #define TLFLOAT_M_2_PIo tlfloat_consto(0x3fffe45f306dc9c8LL, 0x82a53f84eafa3ea6LL, 0x9bb81b6c52b32788LL, 0x72083fca2c757bd7LL) #define TLFLOAT_M_2_SQRTPIo tlfloat_consto(0x3ffff20dd750429bLL, 0x6d11ae3a914fed7fLL, 0xd8688281341d7587LL, 0xcea2e7342b06199dLL) #define TLFLOAT_M_SQRT2o tlfloat_consto(0x3ffff6a09e667f3bLL, 0xcc908b2fb1366ea9LL, 0x57d3e3adec175127LL, 0x75099da2f590b066LL) #define TLFLOAT_M_SQRT1_2o tlfloat_consto(0x3fffe6a09e667f3bLL, 0xcc908b2fb1366ea9LL, 0x57d3e3adec175127LL, 0x75099da2f590b066LL) #define TLFLOAT_FLT256_MAX tlfloat_consto(0x7fffefffffffffffLL, 0xffffffffffffffffLL, 0xffffffffffffffffLL, 0xffffffffffffffffLL) #define TLFLOAT_FLT256_MIN tlfloat_consto(0x0000100000000000LL, 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL) #define TLFLOAT_FLT256_DENORM_MIN tlfloat_consto(0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000001LL) #define TLFLOAT_FLT256_TRUE_MIN tlfloat_consto(0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000001LL) #define TLFLOAT_FLT256_EPSILON tlfloat_consto(0x3ff1300000000000LL, 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL) #elif defined(__STDC_VERSION__) #if !defined(__BYTE_ORDER__) || (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) #define TLFLOAT_M_Eo ((tlfloat_octuple_) { 0xa6d2b53c26c8228dLL, 0xa79e3b1738b079c5LL, 0x695355fb8ac404e7LL, 0x400005bf0a8b1457LL }) #define TLFLOAT_M_LOG2Eo ((tlfloat_octuple_) { 0x2b4b1164a2cd9a34LL, 0xa7d11d6aef551badLL, 0xfe1777d0ffda0d23LL, 0x3ffff71547652b82LL }) #define TLFLOAT_M_LOG10Eo ((tlfloat_octuple_) { 0x34404747e5a89ef2LL, 0x7b8647dc68c048b9LL, 0x0e32a6ab7555f5a6LL, 0x3fffdbcb7b1526e5LL }) #define TLFLOAT_M_LN2o ((tlfloat_octuple_) { 0x16c5b141a2eb7175LL, 0x5ed5e81e6864ce53LL, 0xef35793c7673007eLL, 0x3fffe62e42fefa39LL }) #define TLFLOAT_M_LN10o ((tlfloat_octuple_) { 0xbf21d078c3d0403eLL, 0x61451c51fd9f3b4bLL, 0x1582dd4adac5705aLL, 0x4000026bb1bbb555LL }) #define TLFLOAT_M_PIo ((tlfloat_octuple_) { 0xf98e804177d4c762LL, 0x839a252049c1114cLL, 0x18469898cc51701bLL, 0x40000921fb54442dLL }) #define TLFLOAT_M_PI_2o ((tlfloat_octuple_) { 0xf98e804177d4c762LL, 0x839a252049c1114cLL, 0x18469898cc51701bLL, 0x3ffff921fb54442dLL }) #define TLFLOAT_M_PI_4o ((tlfloat_octuple_) { 0xf98e804177d4c762LL, 0x839a252049c1114cLL, 0x18469898cc51701bLL, 0x3fffe921fb54442dLL }) #define TLFLOAT_M_1_PIo ((tlfloat_octuple_) { 0x72083fca2c757bd7LL, 0x9bb81b6c52b32788LL, 0x82a53f84eafa3ea6LL, 0x3fffd45f306dc9c8LL }) #define TLFLOAT_M_2_PIo ((tlfloat_octuple_) { 0x72083fca2c757bd7LL, 0x9bb81b6c52b32788LL, 0x82a53f84eafa3ea6LL, 0x3fffe45f306dc9c8LL }) #define TLFLOAT_M_2_SQRTPIo ((tlfloat_octuple_) { 0xcea2e7342b06199dLL, 0xd8688281341d7587LL, 0x6d11ae3a914fed7fLL, 0x3ffff20dd750429bLL }) #define TLFLOAT_M_SQRT2o ((tlfloat_octuple_) { 0x75099da2f590b066LL, 0x57d3e3adec175127LL, 0xcc908b2fb1366ea9LL, 0x3ffff6a09e667f3bLL }) #define TLFLOAT_M_SQRT1_2o ((tlfloat_octuple_) { 0x75099da2f590b066LL, 0x57d3e3adec175127LL, 0xcc908b2fb1366ea9LL, 0x3fffe6a09e667f3bLL }) #define TLFLOAT_FLT256_MAX ((tlfloat_octuple_) { 0xffffffffffffffffLL, 0xffffffffffffffffLL, 0xffffffffffffffffLL, 0x7fffefffffffffffLL }) #define TLFLOAT_FLT256_MIN ((tlfloat_octuple_) { 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL, 0x0000100000000000LL }) #define TLFLOAT_FLT256_DENORM_MIN ((tlfloat_octuple_) { 0x0000000000000001LL, 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL }) #define TLFLOAT_FLT256_TRUE_MIN ((tlfloat_octuple_) { 0x0000000000000001LL, 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL }) #define TLFLOAT_FLT256_EPSILON ((tlfloat_octuple_) { 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL, 0x3ff1300000000000LL }) #else #define TLFLOAT_M_Eo ((tlfloat_octuple_) { 0x400005bf0a8b1457LL, 0x695355fb8ac404e7LL, 0xa79e3b1738b079c5LL, 0xa6d2b53c26c8228dLL }) #define TLFLOAT_M_LOG2Eo ((tlfloat_octuple_) { 0x3ffff71547652b82LL, 0xfe1777d0ffda0d23LL, 0xa7d11d6aef551badLL, 0x2b4b1164a2cd9a34LL }) #define TLFLOAT_M_LOG10Eo ((tlfloat_octuple_) { 0x3fffdbcb7b1526e5LL, 0x0e32a6ab7555f5a6LL, 0x7b8647dc68c048b9LL, 0x34404747e5a89ef2LL }) #define TLFLOAT_M_LN2o ((tlfloat_octuple_) { 0x3fffe62e42fefa39LL, 0xef35793c7673007eLL, 0x5ed5e81e6864ce53LL, 0x16c5b141a2eb7175LL }) #define TLFLOAT_M_LN10o ((tlfloat_octuple_) { 0x4000026bb1bbb555LL, 0x1582dd4adac5705aLL, 0x61451c51fd9f3b4bLL, 0xbf21d078c3d0403eLL }) #define TLFLOAT_M_PIo ((tlfloat_octuple_) { 0x40000921fb54442dLL, 0x18469898cc51701bLL, 0x839a252049c1114cLL, 0xf98e804177d4c762LL }) #define TLFLOAT_M_PI_2o ((tlfloat_octuple_) { 0x3ffff921fb54442dLL, 0x18469898cc51701bLL, 0x839a252049c1114cLL, 0xf98e804177d4c762LL }) #define TLFLOAT_M_PI_4o ((tlfloat_octuple_) { 0x3fffe921fb54442dLL, 0x18469898cc51701bLL, 0x839a252049c1114cLL, 0xf98e804177d4c762LL }) #define TLFLOAT_M_1_PIo ((tlfloat_octuple_) { 0x3fffd45f306dc9c8LL, 0x82a53f84eafa3ea6LL, 0x9bb81b6c52b32788LL, 0x72083fca2c757bd7LL }) #define TLFLOAT_M_2_PIo ((tlfloat_octuple_) { 0x3fffe45f306dc9c8LL, 0x82a53f84eafa3ea6LL, 0x9bb81b6c52b32788LL, 0x72083fca2c757bd7LL }) #define TLFLOAT_M_2_SQRTPIo ((tlfloat_octuple_) { 0x3ffff20dd750429bLL, 0x6d11ae3a914fed7fLL, 0xd8688281341d7587LL, 0xcea2e7342b06199dLL }) #define TLFLOAT_M_SQRT2o ((tlfloat_octuple_) { 0x3ffff6a09e667f3bLL, 0xcc908b2fb1366ea9LL, 0x57d3e3adec175127LL, 0x75099da2f590b066LL }) #define TLFLOAT_M_SQRT1_2o ((tlfloat_octuple_) { 0x3fffe6a09e667f3bLL, 0xcc908b2fb1366ea9LL, 0x57d3e3adec175127LL, 0x75099da2f590b066LL }) #define TLFLOAT_FLT256_MAX ((tlfloat_octuple_) { 0x7fffefffffffffffLL, 0xffffffffffffffffLL, 0xffffffffffffffffLL, 0xffffffffffffffffLL }) #define TLFLOAT_FLT256_MIN ((tlfloat_octuple_) { 0x0000100000000000LL, 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL }) #define TLFLOAT_FLT256_DENORM_MIN ((tlfloat_octuple_) { 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000001LL }) #define TLFLOAT_FLT256_TRUE_MIN ((tlfloat_octuple_) { 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000001LL }) #define TLFLOAT_FLT256_EPSILON ((tlfloat_octuple_) { 0x3ff1300000000000LL, 0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL }) #endif #endif #if (defined(__cplusplus) && !defined(TLFLOAT_COMPILER_SUPPORTS_FLOAT128) && !defined(TLFLOAT_LONGDOUBLE_IS_FLOAT128) && !defined(TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128)) || defined(TLFLOAT_DOXYGEN) inline tlfloat_quad::tlfloat_quad(const struct tlfloat_octuple& v) : value(tlfloat_cast_q_o(v)) {} inline tlfloat_quad::tlfloat_quad(const tlfloat_int128_t_& i) : value(tlfloat_cast_q_i128(i)) {} inline tlfloat_quad::tlfloat_quad(const tlfloat_uint128_t_& u) : value(tlfloat_cast_q_u128(u)) {} inline tlfloat_quad::operator tlfloat_int128_t_() const { return tlfloat_cast_i128_q(value); } inline tlfloat_quad::operator tlfloat_uint128_t_() const { return tlfloat_cast_u128_q(value); } #if !defined(TLFLOAT_COMPILER_SUPPORTS_INT128) inline tlfloat_quad::tlfloat_quad(const struct tlfloat_int128_t& i) : value(tlfloat_cast_q_i128(i)) {} inline tlfloat_quad::tlfloat_quad(const struct tlfloat_uint128_t& u) : value(tlfloat_cast_q_u128(u)) {} #endif /** This function casts a octuple-precision FP number to a double-precision FP number. Link with -ltlfloat. */ static inline double tlfloat_cast_d_q(const tlfloat_quad x) { return tlfloat_cast_d_q(tlfloat_quad_(x)); } /** This function casts a quadruple-precision FP number to a octuple-precision FP number. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_cast_o_q(const tlfloat_quad x) { return tlfloat_cast_o_q(tlfloat_quad_(x)); } /** This function casts a quadruple-precision FP number to a 64-bit signed integer. Link with -ltlfloat. */ static inline int64_t tlfloat_cast_i64_q(const tlfloat_quad x) { return tlfloat_cast_i64_q(tlfloat_quad_(x)); } /** This function casts a quadruple-precision FP number to a 64-bit unsigned integer. Link with -ltlfloat. */ static inline uint64_t tlfloat_cast_u64_q(const tlfloat_quad x){ return tlfloat_cast_u64_q(tlfloat_quad_(x)); } /** This function performs addition of two quadruple-precision floating point numbers. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_addq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_addq(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function performs subtraction of two quadruple-precision floating point numbers. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_subq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_subq(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function performs multiplication of two quadruple-precision floating point numbers. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_mulq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_mulq(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function performs division of two quadruple-precision floating point numbers. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_divq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_divq(tlfloat_quad_(x), tlfloat_quad_(y)); } static inline tlfloat_quad tlfloat_negq(const tlfloat_quad x) { return tlfloat_negq(tlfloat_quad_(x)); } /** This function performs ordered comparison of two quad-precision floating point numbers. Link with -ltlfloat. */ static inline int tlfloat_eq_q_q(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_eq_q_q(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function performs ordered comparison of two quad-precision floating point numbers. Link with -ltlfloat. */ static inline int tlfloat_ne_q_q(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_ne_q_q(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function performs ordered comparison of two quad-precision floating point numbers. Link with -ltlfloat. */ static inline int tlfloat_lt_q_q(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_lt_q_q(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function performs ordered comparison of two quad-precision floating point numbers. Link with -ltlfloat. */ static inline int tlfloat_le_q_q(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_le_q_q(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function performs ordered comparison of two quad-precision floating point numbers. Link with -ltlfloat. */ static inline int tlfloat_gt_q_q(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_gt_q_q(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function performs ordered comparison of two quad-precision floating point numbers. Link with -ltlfloat. */ static inline int tlfloat_ge_q_q(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_ge_q_q(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_fmaq(const tlfloat_quad x, const tlfloat_quad y, const tlfloat_quad z) { return tlfloat_fmaq(tlfloat_quad_(x), tlfloat_quad_(y), tlfloat_quad_(z)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_sqrtq(const tlfloat_quad x) { return tlfloat_sqrtq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_fabsq(const tlfloat_quad x) { return tlfloat_fabsq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_copysignq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_copysignq(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_fmaxq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_fmaxq(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_fminq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_fminq(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_fdimq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_fdimq(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_ldexpq(const tlfloat_quad x, const int y) { return tlfloat_ldexpq(tlfloat_quad_(x), y); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_frexpq(const tlfloat_quad x, int *y) { return tlfloat_frexpq(tlfloat_quad_(x), y); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_modfq(const tlfloat_quad x, tlfloat_quad *y) { return tlfloat_modfq(tlfloat_quad_(x), (tlfloat_quad_ *)y); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_nextafterq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_nextafterq(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline int tlfloat_ilogbq(const tlfloat_quad x) { return tlfloat_ilogbq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline int tlfloat_isnanq(const tlfloat_quad x) { return tlfloat_isnanq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline int tlfloat_isinfq(const tlfloat_quad x) { return tlfloat_isinfq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline int tlfloat_finiteq(const tlfloat_quad x) { return tlfloat_finiteq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline int tlfloat_fpclassifyq(const tlfloat_quad x) { return tlfloat_fpclassifyq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline int tlfloat_signbitq(const tlfloat_quad x) { return tlfloat_signbitq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_hypotq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_hypotq(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_truncq(const tlfloat_quad x) { return tlfloat_truncq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_floorq(const tlfloat_quad x) { return tlfloat_floorq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_ceilq(const tlfloat_quad x) { return tlfloat_ceilq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_roundq(const tlfloat_quad x) { return tlfloat_roundq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_rintq(const tlfloat_quad x) { return tlfloat_rintq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_sinq(const tlfloat_quad x) { return tlfloat_sinq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_cosq(const tlfloat_quad x) { return tlfloat_cosq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_tanq(const tlfloat_quad x) { return tlfloat_tanq(tlfloat_quad_(x)); } static inline tlfloat_quad tlfloat_sinpiq(const tlfloat_quad x) { return tlfloat_sinpiq(tlfloat_quad_(x)); } static inline tlfloat_quad tlfloat_cospiq(const tlfloat_quad x) { return tlfloat_cospiq(tlfloat_quad_(x)); } static inline tlfloat_quad tlfloat_tanpiq(const tlfloat_quad x) { return tlfloat_tanpiq(tlfloat_quad_(x)); } static inline void tlfloat_sincosq(const tlfloat_quad x, tlfloat_quad *s, tlfloat_quad *c) { tlfloat_quad_ s_, c_; tlfloat_sincosq(tlfloat_quad_(x), &s_, &c_); *s = tlfloat_quad(s_); *c = tlfloat_quad(c_); } static inline void tlfloat_sincospiq(const tlfloat_quad x, tlfloat_quad *s, tlfloat_quad *c) { tlfloat_quad_ s_, c_; tlfloat_sincospiq(tlfloat_quad_(x), &s_, &c_); *s = tlfloat_quad(s_); *c = tlfloat_quad(c_); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_asinq(const tlfloat_quad x) { return tlfloat_asinq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_acosq(const tlfloat_quad x) { return tlfloat_acosq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_atanq(const tlfloat_quad x) { return tlfloat_atanq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_atan2q(const tlfloat_quad y, const tlfloat_quad x) { return tlfloat_atan2q(tlfloat_quad_(y), tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_expq(const tlfloat_quad x) { return tlfloat_expq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_expm1q(const tlfloat_quad x) { return tlfloat_expm1q(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_exp2q(const tlfloat_quad x) { return tlfloat_exp2q(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_exp10q(const tlfloat_quad x) { return tlfloat_exp10q(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_logq(const tlfloat_quad x) { return tlfloat_logq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_log1pq(const tlfloat_quad x) { return tlfloat_log1pq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_log2q(const tlfloat_quad x) { return tlfloat_log2q(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_log10q(const tlfloat_quad x) { return tlfloat_log10q(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_powq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_powq(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_cbrtq(const tlfloat_quad x) { return tlfloat_cbrtq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_sinhq(const tlfloat_quad x) { return tlfloat_sinhq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_coshq(const tlfloat_quad x) { return tlfloat_coshq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_tanhq(const tlfloat_quad x) { return tlfloat_tanhq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_asinhq(const tlfloat_quad x) { return tlfloat_asinhq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_acoshq(const tlfloat_quad x) { return tlfloat_acoshq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_atanhq(const tlfloat_quad x) { return tlfloat_atanhq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_erfq(const tlfloat_quad x) { return tlfloat_erfq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_erfcq(const tlfloat_quad x) { return tlfloat_erfcq(tlfloat_quad_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_tgammaq(const tlfloat_quad x) { return tlfloat_tgammaq(tlfloat_quad_(x)); } /** This is experimental implementation of log gamma function. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_lgammaq(const tlfloat_quad x) { return tlfloat_cast_q_o(tlfloat_lgammao(tlfloat_cast_o_q(tlfloat_quad_(x)))); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_fmodq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_fmodq(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_remainderq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_remainderq(tlfloat_quad_(x), tlfloat_quad_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_remquoq(const tlfloat_quad x, const tlfloat_quad y, int *quo) { return tlfloat_remquoq(tlfloat_quad_(x), tlfloat_quad_(y), quo); } #endif // #if (defined(__cplusplus) && !defined(TLFLOAT_COMPILER_SUPPORTS_FLOAT128) && !defined(TLFLOAT_LONGDOUBLE_IS_FLOAT128) && !defined(TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128)) || defined(TLFLOAT_DOXYGEN) /** This function casts a double-precision FP number to a quadruple-precision FP number. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_cast_q_d(const double x) { return tlfloat_cast_q_d_(x); } /** This function casts a 64-bit signed integer to a quadruple-precision FP number. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_cast_q_i64(const int64_t x) { return tlfloat_cast_q_i64_(x); } /** This function casts a 64-bit unsigned integer to a quadruple-precision FP number. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_cast_q_u64(const uint64_t x) { return tlfloat_cast_q_u64_(x); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_strtoq(const char *nptr, const char **endptr) { return tlfloat_strtoq_(nptr, endptr); } #ifdef TLFLOAT_LIBQUADMATH_EMULATION #if defined(TLFLOAT_COMPILER_SUPPORTS_FLOAT128) || defined(TLFLOAT_LONGDOUBLE_IS_FLOAT128) || defined(TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128) || defined(__STDC_VERSION__) || defined(__cplusplus) || defined(TLFLOAT_DOXYGEN) /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_Eq TLFLOAT_M_Eq /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_LOG2Eq TLFLOAT_M_LOG2Eq /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_LOG10Eq TLFLOAT_M_LOG10Eq /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_LN2q TLFLOAT_M_LN2q /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_LN10q TLFLOAT_M_LN10q /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_PIq TLFLOAT_M_PIq /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_PI_2q TLFLOAT_M_PI_2q /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_PI_4q TLFLOAT_M_PI_4q /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_1_PIq TLFLOAT_M_1_PIq /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_2_PIq TLFLOAT_M_2_PIq /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_2_SQRTPIq TLFLOAT_M_2_SQRTPIq /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_SQRT2q TLFLOAT_M_SQRT2q /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define M_SQRT1_2q TLFLOAT_M_SQRT1_2q /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define FLT128_MAX TLFLOAT_FLT128_MAX /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define FLT128_MIN TLFLOAT_FLT128_MIN /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define FLT128_DENORM_MIN TLFLOAT_FLT128_DENORM_MIN /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define FLT128_EPSILON TLFLOAT_FLT128_EPSILON #endif /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define FLT128_MANT_DIG TLFLOAT_FLT128_MANT_DIG /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define FLT128_MIN_EXP TLFLOAT_FLT128_MIN_EXP /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define FLT128_MAX_EXP TLFLOAT_FLT128_MAX_EXP /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define FLT128_DIG TLFLOAT_FLT128_DIG /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define FLT128_MIN_10_EXP TLFLOAT_FLT128_MIN_10_EXP /** This macro is defined only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. */ #define FLT128_MAX_10_EXP TLFLOAT_FLT128_MAX_10_EXP /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad strtoflt128(const char *s, const char **sp) { return tlfloat_strtoq_(s, sp); } /** This function is designed to be used as a replacement for the function of the same name in quadmath.h, * but it is actually an alias of tlfloat_snprintf. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline int quadmath_snprintf(char *str, size_t size, const char *fmt, ...) { va_list ap; va_start(ap, fmt); int ret = tlfloat_vsnprintf(str, size, fmt, ap); va_end(ap); return ret; } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad fmaq(const tlfloat_quad x, const tlfloat_quad y, const tlfloat_quad z) { return tlfloat_fmaq(x, y, z); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad sqrtq(const tlfloat_quad x) { return tlfloat_sqrtq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad fabsq(const tlfloat_quad x) { return tlfloat_fabsq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad copysignq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_copysignq(x, y); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad fmaxq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_fmaxq(x, y); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad fminq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_fminq(x, y); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad fdimq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_fdimq(x, y); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad ldexpq(const tlfloat_quad x, const int y) { return tlfloat_ldexpq(x, y); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad frexpq(const tlfloat_quad x, int *y) { return tlfloat_frexpq(x, y); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad modfq(const tlfloat_quad x, tlfloat_quad *y) { return tlfloat_modfq(x, y); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad nextafterq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_nextafterq(x, y); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline int ilogbq(const tlfloat_quad x) { return tlfloat_ilogbq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline int isnanq(const tlfloat_quad x) { return tlfloat_isnanq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline int isinfq(const tlfloat_quad x) { return tlfloat_isinfq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline int finiteq(const tlfloat_quad x) { return tlfloat_finiteq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline int fpclassifyq(const tlfloat_quad x) { return tlfloat_fpclassifyq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline int signbitq(const tlfloat_quad x) { return tlfloat_signbitq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad hypotq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_hypotq(x, y); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad truncq(const tlfloat_quad x) { return tlfloat_truncq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad floorq(const tlfloat_quad x) { return tlfloat_floorq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad ceilq(const tlfloat_quad x) { return tlfloat_ceilq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad roundq(const tlfloat_quad x) { return tlfloat_roundq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad rintq(const tlfloat_quad x) { return tlfloat_rintq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad sinq(const tlfloat_quad x) { return tlfloat_sinq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad cosq(const tlfloat_quad x) { return tlfloat_cosq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline void sincosq(const tlfloat_quad x, tlfloat_quad *s, tlfloat_quad *c) { tlfloat_sincosq(x, s, c); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad tanq(const tlfloat_quad x) { return tlfloat_tanq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad asinq(const tlfloat_quad x) { return tlfloat_asinq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad acosq(const tlfloat_quad x) { return tlfloat_acosq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad atanq(const tlfloat_quad x) { return tlfloat_atanq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad atan2q(const tlfloat_quad y, const tlfloat_quad x) { return tlfloat_atan2q(y, x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad expq(const tlfloat_quad x) { return tlfloat_expq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad expm1q(const tlfloat_quad x) { return tlfloat_expm1q(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad exp2q(const tlfloat_quad x) { return tlfloat_exp2q(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad exp10q(const tlfloat_quad x) { return tlfloat_exp10q(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad logq(const tlfloat_quad x) { return tlfloat_logq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad log1pq(const tlfloat_quad x) { return tlfloat_log1pq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad log2q(const tlfloat_quad x) { return tlfloat_log2q(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad log10q(const tlfloat_quad x) { return tlfloat_log10q(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad powq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_powq(x, y); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad cbrtq(const tlfloat_quad x) { return tlfloat_cbrtq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad sinhq(const tlfloat_quad x) { return tlfloat_sinhq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad coshq(const tlfloat_quad x) { return tlfloat_coshq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad tanhq(const tlfloat_quad x) { return tlfloat_tanhq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad asinhq(const tlfloat_quad x) { return tlfloat_asinhq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad acoshq(const tlfloat_quad x) { return tlfloat_acoshq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad atanhq(const tlfloat_quad x) { return tlfloat_atanhq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad erfq(const tlfloat_quad x) { return tlfloat_erfq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad erfcq(const tlfloat_quad x) { return tlfloat_erfcq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad tgammaq(const tlfloat_quad x) { return tlfloat_tgammaq(x); } /** This is experimental implementation of log gamma function. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad lgammaq(const tlfloat_quad x) { return tlfloat_lgammaq(x); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad fmodq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_fmodq(x, y); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad remainderq(const tlfloat_quad x, const tlfloat_quad y) { return tlfloat_remainderq(x, y); } /** This function has the same functionality as the corresponding function in quadmath.h. * This function is available only if TLFLOAT_LIBQUADMATH_EMULATION macro is defined. * Link with -ltlfloat. */ static inline tlfloat_quad remquoq(const tlfloat_quad x, const tlfloat_quad y, int *quo) { return tlfloat_remquoq(x, y, quo); } #endif // #ifdef TLFLOAT_LIBQUADMATH_EMULATION // #if defined(__cplusplus) || defined(TLFLOAT_DOXYGEN) #if !defined(TLFLOAT_DOXYGEN) #define TLFLOAT_OVERLOAD_OP2(OP, OPA) \ template::value && sizeof(T) <= 8) || (std::is_integral::value && sizeof(T) <= 8)), int>::type = 0> \ static inline tlfloat_octuple operator OP(const T& lhs, const tlfloat_octuple& rhs) { return tlfloat_octuple(lhs) OP rhs; } \ static inline tlfloat_octuple operator OP(const tlfloat_int128_t& lhs, const tlfloat_octuple& rhs) { return tlfloat_octuple(tlfloat_cast_o_i128(lhs)) OP rhs; } \ static inline tlfloat_octuple operator OP(const tlfloat_uint128_t& lhs, const tlfloat_octuple& rhs) { return tlfloat_octuple(tlfloat_cast_o_u128(lhs)) OP rhs; } \ template::value && sizeof(T) <= 8) || (std::is_integral::value && sizeof(T) <= 8)), int>::type = 0> \ static inline tlfloat_octuple operator OP(const tlfloat_octuple& lhs, const T& rhs) { return lhs OP tlfloat_octuple(rhs); } \ static inline tlfloat_octuple operator OP(const tlfloat_octuple& lhs, const tlfloat_int128_t& rhs) { return lhs OP tlfloat_cast_o_i128(rhs); } \ static inline tlfloat_octuple operator OP(const tlfloat_octuple& lhs, const tlfloat_uint128_t& rhs) { return lhs OP tlfloat_cast_o_u128(rhs); } \ static inline tlfloat_octuple operator OP(const tlfloat_quad& lhs, const tlfloat_octuple& rhs) { return tlfloat_octuple(lhs) OP rhs; } \ static inline tlfloat_octuple operator OP(const tlfloat_octuple& lhs, const tlfloat_quad& rhs) { return lhs OP tlfloat_octuple(rhs); } \ template \ static inline tlfloat_octuple& operator OPA(tlfloat_octuple& lhs, const rhstype& rhs) { return (lhs = lhs OP tlfloat_octuple(rhs)); } \ static_assert(true, "") #define TLFLOAT_OVERLOAD_OP2Q(OP, OPA) \ template::value && sizeof(T) <= 8) || (std::is_integral::value && sizeof(T) <= 8)), int>::type = 0> \ static inline tlfloat_quad operator OP(const T& lhs, const tlfloat_quad& rhs) { return tlfloat_quad(lhs) OP rhs; } \ static inline tlfloat_quad operator OP(const tlfloat_int128_t& lhs, const tlfloat_quad& rhs) { return tlfloat_quad(tlfloat_cast_q_i128(lhs)) OP rhs; } \ static inline tlfloat_quad operator OP(const tlfloat_uint128_t& lhs, const tlfloat_quad& rhs) { return tlfloat_quad(tlfloat_cast_q_u128(lhs)) OP rhs; } \ template::value && sizeof(T) <= 8) || (std::is_integral::value && sizeof(T) <= 8)), int>::type = 0> \ static inline tlfloat_quad operator OP(const tlfloat_quad& lhs, const T& rhs) { return lhs OP tlfloat_quad(rhs); } \ static inline tlfloat_quad operator OP(const tlfloat_quad& lhs, const tlfloat_int128_t& rhs) { return lhs OP tlfloat_cast_q_i128(rhs); } \ static inline tlfloat_quad operator OP(const tlfloat_quad& lhs, const tlfloat_uint128_t& rhs) { return lhs OP tlfloat_cast_q_u128(rhs); } \ template \ static inline tlfloat_quad& operator OPA(tlfloat_quad& lhs, const rhstype& rhs) { return (lhs = lhs OP tlfloat_quad(rhs)); } \ static_assert(true, "") #define TLFLOAT_OVERLOAD_OP2I(OP, OPA) \ template::value && sizeof(T) <= 8) || (std::is_integral::value && sizeof(T) <= 8)), int>::type = 0> \ static inline tlfloat_int128_t operator OP(const T& lhs, const tlfloat_int128_t& rhs) { return tlfloat_int128_t(lhs) OP rhs; } \ template::value && sizeof(T) <= 8) || (std::is_integral::value && sizeof(T) <= 8)), int>::type = 0> \ static inline tlfloat_uint128_t operator OP(const T& lhs, const tlfloat_uint128_t& rhs) { return tlfloat_uint128_t(lhs) OP rhs; } \ static inline tlfloat_int128_t operator OP(const tlfloat_int128_t& lhs, const tlfloat_int128_t_& rhs) { return lhs OP (tlfloat_int128_t)rhs; } \ static inline tlfloat_int128_t operator OP(const tlfloat_int128_t_& lhs, const tlfloat_int128_t& rhs) { return (tlfloat_int128_t)lhs OP rhs; } \ static inline tlfloat_uint128_t operator OP(const tlfloat_uint128_t& lhs, const tlfloat_uint128_t_& rhs) { return lhs OP (tlfloat_uint128_t)rhs; } \ static inline tlfloat_uint128_t operator OP(const tlfloat_uint128_t_& lhs, const tlfloat_uint128_t& rhs) { return (tlfloat_uint128_t)lhs OP rhs; } \ template \ static inline tlfloat_int128_t& operator OPA(tlfloat_int128_t& lhs, const rhstype& rhs) { return (lhs = lhs OP tlfloat_int128_t(rhs)); } \ template \ static inline tlfloat_uint128_t& operator OPA(tlfloat_uint128_t& lhs, const rhstype& rhs) { return (lhs = lhs OP tlfloat_uint128_t(rhs)); } \ static_assert(true, "") #define TLFLOAT_OVERLOAD_CMP(OP) \ template::value && sizeof(T) <= 8) || (std::is_integral::value && sizeof(T) <= 8)), int>::type = 0> \ static inline bool operator OP(const T& lhs, const tlfloat_octuple& rhs) { return tlfloat_octuple(lhs) OP rhs; } \ static inline bool operator OP(const tlfloat_int128_t& lhs, const tlfloat_octuple& rhs) { return tlfloat_octuple(tlfloat_cast_o_i128(lhs)) OP rhs; } \ static inline bool operator OP(const tlfloat_uint128_t& lhs, const tlfloat_octuple& rhs) { return tlfloat_octuple(tlfloat_cast_o_u128(lhs)) OP rhs; } \ template::value && sizeof(T) <= 8) || (std::is_integral::value && sizeof(T) <= 8)), int>::type = 0> \ static inline bool operator OP(const tlfloat_octuple& lhs, const T& rhs) { return lhs OP tlfloat_octuple(rhs); } \ static inline bool operator OP(const tlfloat_octuple& lhs, const tlfloat_int128_t& rhs) { return lhs OP tlfloat_octuple(tlfloat_cast_o_i128(rhs)); } \ static inline bool operator OP(const tlfloat_octuple& lhs, const tlfloat_uint128_t& rhs) { return lhs OP tlfloat_octuple(tlfloat_cast_o_u128(rhs)); } \ static inline bool operator OP(const tlfloat_octuple& lhs, const tlfloat_quad& rhs) { return lhs OP tlfloat_octuple(rhs); } \ static inline bool operator OP(const tlfloat_quad& lhs, const tlfloat_octuple& rhs) { return tlfloat_octuple(lhs) OP rhs; } \ static_assert(true, "") #define TLFLOAT_OVERLOAD_CMPQ(OP) \ template::value && sizeof(T) <= 8) || (std::is_integral::value && sizeof(T) <= 8)), int>::type = 0> \ static inline bool operator OP(const T& lhs, const tlfloat_quad& rhs) { return tlfloat_quad(lhs) OP rhs; } \ template::value && sizeof(T) <= 8) || (std::is_integral::value && sizeof(T) <= 8)), int>::type = 0> \ static inline bool operator OP(const tlfloat_quad& lhs, const T& rhs) { return lhs OP tlfloat_quad(rhs); } \ static_assert(true, "") #define TLFLOAT_OVERLOAD_CMPI(OP) \ template::value && sizeof(T) <= 8), int>::type = 0> \ static inline bool operator OP(const T& lhs, const tlfloat_int128_t& rhs) { return tlfloat_int128_t(lhs) OP rhs; } \ template::value && sizeof(T) <= 8), int>::type = 0> \ static inline bool operator OP(const tlfloat_int128_t& lhs, const T& rhs) { return lhs OP tlfloat_int128_t(rhs); } \ template::value && sizeof(T) <= 8), int>::type = 0> \ static inline bool operator OP(const T& lhs, const tlfloat_uint128_t& rhs) { return tlfloat_uint128_t(lhs) OP rhs; } \ template::value && sizeof(T) <= 8), int>::type = 0> \ static inline bool operator OP(const tlfloat_uint128_t& lhs, const T& rhs) { return lhs OP tlfloat_uint128_t(rhs); } \ static inline bool operator OP(const tlfloat_int128_t& lhs, const tlfloat_int128_t_& rhs) { return lhs OP (tlfloat_int128_t)rhs; } \ static inline bool operator OP(const tlfloat_int128_t_& lhs, const tlfloat_int128_t& rhs) { return (tlfloat_int128_t)lhs OP rhs; } \ static inline bool operator OP(const tlfloat_uint128_t& lhs, const tlfloat_uint128_t_& rhs) { return lhs OP (tlfloat_uint128_t)rhs; } \ static inline bool operator OP(const tlfloat_uint128_t_& lhs, const tlfloat_uint128_t& rhs) { return (tlfloat_uint128_t)lhs OP rhs; } \ static_assert(true, "") TLFLOAT_OVERLOAD_OP2(+, +=); TLFLOAT_OVERLOAD_OP2(-, -=); TLFLOAT_OVERLOAD_OP2(*, *=); TLFLOAT_OVERLOAD_OP2(/, /=); TLFLOAT_OVERLOAD_CMP(==); TLFLOAT_OVERLOAD_CMP(!=); TLFLOAT_OVERLOAD_CMP(<); TLFLOAT_OVERLOAD_CMP(<=); TLFLOAT_OVERLOAD_CMP(>); TLFLOAT_OVERLOAD_CMP(>=); #ifdef TLFLOAT_QUAD_IS_STRUCT TLFLOAT_OVERLOAD_OP2Q(+, +=); TLFLOAT_OVERLOAD_OP2Q(-, -=); TLFLOAT_OVERLOAD_OP2Q(*, *=); TLFLOAT_OVERLOAD_OP2Q(/, /=); TLFLOAT_OVERLOAD_CMPQ(==); TLFLOAT_OVERLOAD_CMPQ(!=); TLFLOAT_OVERLOAD_CMPQ(<); TLFLOAT_OVERLOAD_CMPQ(<=); TLFLOAT_OVERLOAD_CMPQ(>); TLFLOAT_OVERLOAD_CMPQ(>=); #endif #ifdef TLFLOAT_INT128_IS_STRUCT TLFLOAT_OVERLOAD_OP2I(+, +=); TLFLOAT_OVERLOAD_OP2I(-, -=); TLFLOAT_OVERLOAD_OP2I(*, *=); TLFLOAT_OVERLOAD_OP2I(/, /=); TLFLOAT_OVERLOAD_CMPI(==); TLFLOAT_OVERLOAD_CMPI(!=); TLFLOAT_OVERLOAD_CMPI(<); TLFLOAT_OVERLOAD_CMPI(<=); TLFLOAT_OVERLOAD_CMPI(>); TLFLOAT_OVERLOAD_CMPI(>=); #endif #undef TLFLOAT_OVERLOAD_OP2 #undef TLFLOAT_OVERLOAD_OP2Q #undef TLFLOAT_OVERLOAD_OP2I #undef TLFLOAT_OVERLOAD_CMP #undef TLFLOAT_OVERLOAD_CMPQ #undef TLFLOAT_OVERLOAD_CMPI #endif // #if !defined(TLFLOAT_DOXYGEN) /** This function casts a octuple-precision FP number to a double-precision FP number. Link with -ltlfloat. */ static inline double tlfloat_cast_d_o(const tlfloat_octuple x) { return tlfloat_cast_d_o(tlfloat_octuple_(x)); } /** This function casts a octuple-precision FP number to a quadruple-precision FP number. Link with -ltlfloat. */ static inline tlfloat_quad tlfloat_cast_q_o(const tlfloat_octuple x) { return tlfloat_cast_q_o(tlfloat_octuple_(x)); } /** This function casts a octuple-precision FP number to a 64-bit signed integer. Link with -ltlfloat. */ static inline int64_t tlfloat_cast_i64_o(const tlfloat_octuple x) { return tlfloat_cast_i64_o(tlfloat_octuple_(x)); } /** This function casts a octuple-precision FP number to a 64-bit unsigned integer. Link with -ltlfloat. */ static inline uint64_t tlfloat_cast_u64_o(const tlfloat_octuple x) { return tlfloat_cast_u64_o(tlfloat_octuple_(x)); } /** This function performs addition of two octuple-precision floating point numbers. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_addo(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_addo(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function performs subtraction of two octuple-precision floating point numbers. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_subo(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_subo(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function performs multiplication of two octuple-precision floating point numbers. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_mulo(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_mulo(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function performs division of two octuple-precision floating point numbers. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_divo(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_divo(tlfloat_octuple_(x), tlfloat_octuple_(y)); } static inline tlfloat_octuple tlfloat_nego(const tlfloat_octuple x) { return tlfloat_nego(tlfloat_octuple_(x)); } /** This function performs ordered comparison of two octuple-precision floating point numbers. Link with -ltlfloat. */ static inline int tlfloat_eq_o_o(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_eq_o_o(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function performs ordered comparison of two octuple-precision floating point numbers. Link with -ltlfloat. */ static inline int tlfloat_ne_o_o(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_ne_o_o(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function performs ordered comparison of two octuple-precision floating point numbers. Link with -ltlfloat. */ static inline int tlfloat_lt_o_o(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_lt_o_o(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function performs ordered comparison of two octuple-precision floating point numbers. Link with -ltlfloat. */ static inline int tlfloat_le_o_o(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_le_o_o(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function performs ordered comparison of two octuple-precision floating point numbers. Link with -ltlfloat. */ static inline int tlfloat_gt_o_o(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_gt_o_o(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function performs ordered comparison of two octuple-precision floating point numbers. Link with -ltlfloat. */ static inline int tlfloat_ge_o_o(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_ge_o_o(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_fmao(const tlfloat_octuple x, const tlfloat_octuple y, const tlfloat_octuple z) { return tlfloat_fmao(tlfloat_octuple_(x), tlfloat_octuple_(y), tlfloat_octuple_(z)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_sqrto(const tlfloat_octuple x) { return tlfloat_sqrto(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_fabso(const tlfloat_octuple x) { return tlfloat_fabso(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_copysigno(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_copysigno(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_fmaxo(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_fmaxo(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_fmino(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_fmino(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_fdimo(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_fdimo(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_ldexpo(const tlfloat_octuple x, const int y) { return tlfloat_ldexpo(tlfloat_octuple_(x), y); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_frexpo(const tlfloat_octuple x, int *y) { return tlfloat_frexpo(tlfloat_octuple_(x), y); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_modfo(const tlfloat_octuple x, tlfloat_octuple *y) { return tlfloat_modfo(tlfloat_octuple_(x), (tlfloat_octuple_ *)y); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_nextaftero(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_nextaftero(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline int tlfloat_ilogbo(const tlfloat_octuple x) { return tlfloat_ilogbo(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline int tlfloat_isnano(const tlfloat_octuple x) { return tlfloat_isnano(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline int tlfloat_isinfo(const tlfloat_octuple x) { return tlfloat_isinfo(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline int tlfloat_finiteo(const tlfloat_octuple x) { return tlfloat_finiteo(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline int tlfloat_signbito(const tlfloat_octuple x) { return tlfloat_signbito(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_hypoto(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_hypoto(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_trunco(const tlfloat_octuple x) { return tlfloat_trunco(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_flooro(const tlfloat_octuple x) { return tlfloat_flooro(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_ceilo(const tlfloat_octuple x) { return tlfloat_ceilo(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_roundo(const tlfloat_octuple x) { return tlfloat_roundo(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_rinto(const tlfloat_octuple x) { return tlfloat_rinto(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_sino(const tlfloat_octuple x) { return tlfloat_sino(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_coso(const tlfloat_octuple x) { return tlfloat_coso(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_tano(const tlfloat_octuple x) { return tlfloat_tano(tlfloat_octuple_(x)); } static inline tlfloat_octuple tlfloat_sinpio(const tlfloat_octuple x) { return tlfloat_sinpio(tlfloat_octuple_(x)); } static inline tlfloat_octuple tlfloat_cospio(const tlfloat_octuple x) { return tlfloat_cospio(tlfloat_octuple_(x)); } static inline tlfloat_octuple tlfloat_tanpio(const tlfloat_octuple x) { return tlfloat_tanpio(tlfloat_octuple_(x)); } static inline void tlfloat_sincoso(const tlfloat_octuple x, tlfloat_octuple *s, tlfloat_octuple *c) { tlfloat_octuple_ s_, c_; tlfloat_sincoso(tlfloat_octuple_(x), &s_, &c_); *s = tlfloat_octuple(s_); *c = tlfloat_octuple(c_); } static inline void tlfloat_sincospio(const tlfloat_octuple x, tlfloat_octuple *s, tlfloat_octuple *c) { tlfloat_octuple_ s_, c_; tlfloat_sincospio(tlfloat_octuple_(x), &s_, &c_); *s = tlfloat_octuple(s_); *c = tlfloat_octuple(c_); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_asino(const tlfloat_octuple x) { return tlfloat_asino(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_acoso(const tlfloat_octuple x) { return tlfloat_acoso(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_atano(const tlfloat_octuple x) { return tlfloat_atano(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_atan2o(const tlfloat_octuple y, const tlfloat_octuple x) { return tlfloat_atan2o(tlfloat_octuple_(y), tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_expo(const tlfloat_octuple x) { return tlfloat_expo(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_expm1o(const tlfloat_octuple x) { return tlfloat_expm1o(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_exp2o(const tlfloat_octuple x) { return tlfloat_exp2o(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_exp10o(const tlfloat_octuple x) { return tlfloat_exp10o(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_logo(const tlfloat_octuple x) { return tlfloat_logo(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_log1po(const tlfloat_octuple x) { return tlfloat_log1po(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_log2o(const tlfloat_octuple x) { return tlfloat_log2o(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_log10o(const tlfloat_octuple x) { return tlfloat_log10o(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_powo(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_powo(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_cbrto(const tlfloat_octuple x) { return tlfloat_cbrto(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_sinho(const tlfloat_octuple x) { return tlfloat_sinho(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_cosho(const tlfloat_octuple x) { return tlfloat_cosho(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_tanho(const tlfloat_octuple x) { return tlfloat_tanho(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_asinho(const tlfloat_octuple x) { return tlfloat_asinho(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_acosho(const tlfloat_octuple x) { return tlfloat_acosho(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_atanho(const tlfloat_octuple x) { return tlfloat_atanho(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_erfo(const tlfloat_octuple x) { return tlfloat_erfo(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_erfco(const tlfloat_octuple x) { return tlfloat_erfco(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_tgammao(const tlfloat_octuple x) { return tlfloat_tgammao(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_lgammao(const tlfloat_octuple x) { return tlfloat_lgammao(tlfloat_octuple_(x)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_fmodo(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_fmodo(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_remaindero(const tlfloat_octuple x, const tlfloat_octuple y) { return tlfloat_remaindero(tlfloat_octuple_(x), tlfloat_octuple_(y)); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_remquoo(const tlfloat_octuple x, const tlfloat_octuple y, int *quo) { return tlfloat_remquoo(tlfloat_octuple_(x), tlfloat_octuple_(y), quo); } namespace tlfloat { #ifndef TLFLOAT_NO_LIBSTDCXX static inline std::string to_string(const float a, int d=6) { std::vector buf(1000); tlfloat_snprintf(buf.data(), buf.size(), "%.*g", d, (double)a); return std::string(buf.data()); } static inline std::string to_string(const double a, int d=6) { std::vector buf(1000); tlfloat_snprintf(buf.data(), buf.size(), "%.*g", d, a); return std::string(buf.data()); } static inline std::string to_string(const tlfloat_quad& a, int d=6) { std::vector buf(1000); tlfloat_snprintf(buf.data(), buf.size(), "%.*Qg", d, a); return std::string(buf.data()); } static inline std::string to_string(const tlfloat_octuple& a, int d=6) { std::vector buf(1000); tlfloat_snprintf(buf.data(), buf.size(), "%.*Og", d, a); return std::string(buf.data()); } static inline std::string to_string(const tlfloat_int128_t& a) { std::vector buf(1000); tlfloat_snprintf(buf.data(), buf.size(), "%Qd", a); return std::string(buf.data()); } static inline std::string to_string(const tlfloat_uint128_t& a) { std::vector buf(1000); tlfloat_snprintf(buf.data(), buf.size(), "%Qu", a); return std::string(buf.data()); } #endif // #if !defined(TLFLOAT_DOXYGEN) #define TLFLOAT_POLYFUNC_f_f(OP) \ static inline float OP ## _(const float &x) { return tlfloat_ ## OP ## f(x); } \ static inline double OP ## _(const double &x) { return tlfloat_ ## OP(x); } \ static inline tlfloat_quad OP ## _(const tlfloat_quad &x) { return tlfloat_ ## OP ## q(x); } \ static inline tlfloat_octuple OP ## _(const tlfloat_octuple &x) { return tlfloat_ ## OP ## o(x); } \ static_assert(true, "") #define TLFLOAT_POLYFUNC_i_f(OP) \ static inline int OP ## _(const float &x) { return tlfloat_ ## OP ## f(x); } \ static inline int OP ## _(const double &x) { return tlfloat_ ## OP(x); } \ static inline int OP ## _(const tlfloat_quad &x) { return tlfloat_ ## OP ## q(x); } \ static inline int OP ## _(const tlfloat_octuple &x) { return tlfloat_ ## OP ## o(x); } \ static_assert(true, "") #define TLFLOAT_POLYFUNC_f_f_f(OP) \ static inline float OP ## _(const float &x, const float &y) { return tlfloat_ ## OP ## f(x, y); } \ static inline double OP ## _(const double &x, const double &y) { return tlfloat_ ## OP(x, y); } \ static inline tlfloat_quad OP ## _(const tlfloat_quad &x, const tlfloat_quad &y) { return tlfloat_ ## OP ## q(x, y); } \ static inline tlfloat_octuple OP ## _(const tlfloat_octuple &x, const tlfloat_octuple &y) { return tlfloat_ ## OP ## o(x, y); } \ static_assert(true, "") #define TLFLOAT_POLYFUNC_f_f_i(OP) \ static inline float OP ## _(const float &x, const int &y) { return tlfloat_ ## OP ## f(x, y); } \ static inline double OP ## _(const double &x, const int &y) { return tlfloat_ ## OP(x, y); } \ static inline tlfloat_quad OP ## _(const tlfloat_quad &x, const int &y) { return tlfloat_ ## OP ## q(x, y); } \ static inline tlfloat_octuple OP ## _(const tlfloat_octuple &x, const int &y) { return tlfloat_ ## OP ## o(x, y); } \ static_assert(true, "") #define TLFLOAT_POLYFUNC_f_f_pf(OP) \ static inline float OP ## _(const float &x, float *y) { return tlfloat_ ## OP ## f(x, y); } \ static inline double OP ## _(const double &x, double *y) { return tlfloat_ ## OP(x, y); } \ static inline tlfloat_quad OP ## _(const tlfloat_quad &x, tlfloat_quad *y) { return tlfloat_ ## OP ## q(x, y); } \ static inline tlfloat_octuple OP ## _(const tlfloat_octuple &x, tlfloat_octuple *y) { return tlfloat_ ## OP ## o(x, y); } \ static_assert(true, "") #define TLFLOAT_POLYFUNC_f_f_pi(OP) \ static inline float OP ## _(const float &x, int *y) { return tlfloat_ ## OP ## f(x, y); } \ static inline double OP ## _(const double &x, int *y) { return tlfloat_ ## OP(x, y); } \ static inline tlfloat_quad OP ## _(const tlfloat_quad &x, int *y) { return tlfloat_ ## OP ## q(x, y); } \ static inline tlfloat_octuple OP ## _(const tlfloat_octuple &x, int *y) { return tlfloat_ ## OP ## o(x, y); } \ static_assert(true, "") #define TLFLOAT_POLYFUNC_f_f_f_pi(OP) \ static inline float OP ## _(const float &x, const float &y, int *z) { return tlfloat_ ## OP ## f(x, y, z); } \ static inline double OP ## _(const double &x, const double &y, int *z) { return tlfloat_ ## OP(x, y, z); } \ static inline tlfloat_quad OP ## _(const tlfloat_quad &x, const tlfloat_quad &y, int *z) { return tlfloat_ ## OP ## q(x, y, z); } \ static inline tlfloat_octuple OP ## _(const tlfloat_octuple &x, const tlfloat_octuple &y, int *z) { return tlfloat_ ## OP ## o(x, y, z); } \ static_assert(true, "") #define TLFLOAT_POLYFUNC_f_f_f_f(OP) \ static inline float OP ## _(const float &x, const float &y, const float &z) { return tlfloat_ ## OP ## f(x, y, z); } \ static inline double OP ## _(const double &x, const double &y, const double &z) { return tlfloat_ ## OP(x, y, z); } \ static inline tlfloat_quad OP ## _(const tlfloat_quad &x, const tlfloat_quad &y, const tlfloat_quad &z) { return tlfloat_ ## OP ## q(x, y, z); } \ static inline tlfloat_octuple OP ## _(const tlfloat_octuple &x, const tlfloat_octuple &y, const tlfloat_octuple &z) { return tlfloat_ ## OP ## o(x, y, z); } \ static_assert(true, "") TLFLOAT_POLYFUNC_f_f_f(add); TLFLOAT_POLYFUNC_f_f_f(sub); TLFLOAT_POLYFUNC_f_f_f(mul); TLFLOAT_POLYFUNC_f_f_f(div); TLFLOAT_POLYFUNC_f_f(neg); TLFLOAT_POLYFUNC_f_f_f_f(fma); TLFLOAT_POLYFUNC_f_f(sqrt); TLFLOAT_POLYFUNC_f_f(cbrt); TLFLOAT_POLYFUNC_f_f(fabs); TLFLOAT_POLYFUNC_f_f_f(copysign); TLFLOAT_POLYFUNC_f_f_f(fmax); TLFLOAT_POLYFUNC_f_f_f(fmin); TLFLOAT_POLYFUNC_f_f_f(fdim); TLFLOAT_POLYFUNC_f_f_i(ldexp); TLFLOAT_POLYFUNC_f_f_pi(frexp); TLFLOAT_POLYFUNC_f_f_pf(modf); TLFLOAT_POLYFUNC_f_f_f(nextafter); TLFLOAT_POLYFUNC_i_f(ilogb); TLFLOAT_POLYFUNC_i_f(isnan); TLFLOAT_POLYFUNC_i_f(isinf); TLFLOAT_POLYFUNC_i_f(finite); TLFLOAT_POLYFUNC_i_f(fpclassify); TLFLOAT_POLYFUNC_i_f(signbit); TLFLOAT_POLYFUNC_f_f_f(hypot); TLFLOAT_POLYFUNC_f_f(trunc); TLFLOAT_POLYFUNC_f_f(floor); TLFLOAT_POLYFUNC_f_f(ceil); TLFLOAT_POLYFUNC_f_f(round); TLFLOAT_POLYFUNC_f_f(rint); TLFLOAT_POLYFUNC_f_f(sin); TLFLOAT_POLYFUNC_f_f(cos); TLFLOAT_POLYFUNC_f_f(tan); TLFLOAT_POLYFUNC_f_f(sinpi); TLFLOAT_POLYFUNC_f_f(cospi); TLFLOAT_POLYFUNC_f_f(tanpi); TLFLOAT_POLYFUNC_f_f(asin); TLFLOAT_POLYFUNC_f_f(acos); TLFLOAT_POLYFUNC_f_f(atan); TLFLOAT_POLYFUNC_f_f_f(atan2); TLFLOAT_POLYFUNC_f_f(exp); TLFLOAT_POLYFUNC_f_f(expm1); TLFLOAT_POLYFUNC_f_f(exp2); TLFLOAT_POLYFUNC_f_f(exp10); TLFLOAT_POLYFUNC_f_f(log); TLFLOAT_POLYFUNC_f_f(log1p); TLFLOAT_POLYFUNC_f_f(log2); TLFLOAT_POLYFUNC_f_f(log10); TLFLOAT_POLYFUNC_f_f_f(pow); TLFLOAT_POLYFUNC_f_f(sinh); TLFLOAT_POLYFUNC_f_f(cosh); TLFLOAT_POLYFUNC_f_f(tanh); TLFLOAT_POLYFUNC_f_f(asinh); TLFLOAT_POLYFUNC_f_f(acosh); TLFLOAT_POLYFUNC_f_f(atanh); TLFLOAT_POLYFUNC_f_f_f(fmod); TLFLOAT_POLYFUNC_f_f_f(remainder); TLFLOAT_POLYFUNC_f_f_f_pi(remquo); TLFLOAT_POLYFUNC_f_f(erf); TLFLOAT_POLYFUNC_f_f(erfc); TLFLOAT_POLYFUNC_f_f(tgamma); TLFLOAT_POLYFUNC_f_f(lgamma); #undef TLFLOAT_POLYFUNC_f_f_f_f #undef TLFLOAT_POLYFUNC_f_f_f_pi #undef TLFLOAT_POLYFUNC_f_f_pi #undef TLFLOAT_POLYFUNC_f_f_pf #undef TLFLOAT_POLYFUNC_f_f_f #undef TLFLOAT_POLYFUNC_i_f #undef TLFLOAT_POLYFUNC_f_f #endif // #if !defined(TLFLOAT_DOXYGEN) } // namespace tlfloat { static_assert(sizeof(tlfloat_quad) == 16, "sizeof(tlfloat_quad)"); static_assert(sizeof(tlfloat_octuple) == 32, "sizeof(tlfloat_octuple)"); #endif // #if defined(__cplusplus) || defined(TLFLOAT_DOXYGEN) /** This function casts a double-precision FP number to a octuple-precision FP number. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_cast_o_d(const double x) { return tlfloat_cast_o_d_(x); } /** This function casts a 64-bit signed integer to a octuple-precision FP number. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_cast_o_i64(const int64_t x) { return tlfloat_cast_o_i64_(x); } /** This function casts a 64-bit unsigned integer to a octuple-precision FP number. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_cast_o_u64(const uint64_t x) { return tlfloat_cast_o_u64_(x); } /** This function is for calling the corresponding function defined in tlfloat namespace from C language. Link with -ltlfloat. */ static inline tlfloat_octuple tlfloat_strtoo(const char *nptr, const char **endptr) { return tlfloat_strtoo_(nptr, endptr); } static inline tlfloat_int128_t tlfloat_cast_i128_i64(const int64_t x) { return tlfloat_cast_i128_i64_(x); } static inline tlfloat_uint128_t tlfloat_cast_u128_u64(const uint64_t x) { return tlfloat_cast_u128_u64_(x); } static inline tlfloat_int128_t tlfloat_cast_i128_d(const double x) { return tlfloat_cast_i128_d_(x); } static inline tlfloat_uint128_t tlfloat_cast_u128_d(const double x) { return tlfloat_cast_u128_d_(x); } // #endif // #ifndef __TLFLOAT_H_INCLUDED__ tlfloat-1.15.0/src/include/tlfloat/tlfloat.hpp000066400000000000000000002334251477036600700213230ustar00rootroot00000000000000#ifndef __TLFLOAT_HPP_INCLUDED__ #define __TLFLOAT_HPP_INCLUDED__ #include #include #ifndef TLFLOAT_FP_NAN #define TLFLOAT_FP_NAN 0 #define TLFLOAT_FP_INFINITE 1 #define TLFLOAT_FP_ZERO 2 #define TLFLOAT_FP_SUBNORMAL 3 #define TLFLOAT_FP_NORMAL 4 #define TLFLOAT_FP_ILOGB0 ((int)0x80000000) #define TLFLOAT_FP_ILOGBNAN ((int)2147483647) #endif namespace tlfloat { namespace detail { static const double LOG10_2_ = 0.30102999566398119521; // log(2)/log(10) static constexpr bool xisspace(int c) { return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'; } static constexpr bool xisdigit(int c) { return '0' <= c && c <= '9'; } static constexpr int xtolower(int c) { if ('A' <= c && c <= 'Z') return c - 'A' + 'a'; else return c; } static constexpr int xstrncasecmp(const char *p, const char *q, size_t n) { for(;n>0;n--) { if (*p == '\0' && *q == '\0') return 0; if (xtolower(*p) != xtolower(*q)) return *p > *q ? 1 : -1; p++; q++; } return 0; } static constexpr long long xstrtoll(const char *p, const char **endptr=nullptr) { bool negative = false; long long r = 0; while(xisspace(*p)) p++; if (*p == '-') { negative = true; p++; } else if (*p == '+') p++; while(xisdigit(*p)) { r = r * 10 + (*p - '0'); p++; } if (endptr) *endptr = p; return negative ? -r : r; } static constexpr TLFLOAT_INLINE double xsqrt(double d) { if (std::is_constant_evaluated()) { if (d == 0) return d; if (d < 0) return NAN; if (d == INFINITY) return INFINITY; double q = 1; if (d < 8.636168555094445E-78) { d *= 1.157920892373162E77; q = 2.9387358770557188E-39; } else if (d > 1.3407807929942597e+154) { d *= 7.4583407312002070e-155; q = 1.1579208923731620e+77; } double x = std::bit_cast(0x5fe6ec85e7de30da - (std::bit_cast(d) >> 1)); d *= 0.5; x *= 1.5 - d * x * x; x *= 1.5 - d * x * x; x *= 1.5 - d * x * x; return (x * d + 0.5 / x) * q; } return sqrt(d); } // static constexpr TLFLOAT_INLINE int icmp(uint16_t x, uint16_t y) { return x > y ? 1 : (x < y ? -1 : 0); } static constexpr TLFLOAT_INLINE int icmp(uint32_t x, uint32_t y) { return x > y ? 1 : (x < y ? -1 : 0); } static constexpr TLFLOAT_INLINE int icmp(uint64_t x, uint64_t y) { return x > y ? 1 : (x < y ? -1 : 0); } template static constexpr TLFLOAT_INLINE int icmp(const BigUInt& x, const BigUInt& y) { return x.compare(y); } // static constexpr TLFLOAT_INLINE uint32_t mul(uint16_t x, uint16_t y) { return uint32_t(x) * uint32_t(y); } static constexpr TLFLOAT_INLINE uint64_t mul(uint32_t x, uint32_t y) { return uint64_t(x) * uint64_t(y); } static constexpr TLFLOAT_INLINE BigUInt<7> mul(uint64_t x, uint64_t y) { return BigUInt<7>::mul(BigUInt<6>(x), BigUInt<6>(y)); } template static constexpr TLFLOAT_INLINE BigUInt mul(const BigUInt& x, const BigUInt& y) { return BigUInt::mul(x, y); } // static constexpr TLFLOAT_INLINE xpair divmod2(uint16_t x_, uint16_t y_) { uint32_t x = uint32_t(x_) << 15, y = y_ | (uint32_t(1) << 15); return xpair { uint16_t(x / y), uint16_t(x % y) }; } static constexpr TLFLOAT_INLINE xpair divmod2(uint32_t x_, uint32_t y_) { uint64_t x = uint64_t(x_) << 31, y = y_ | (uint64_t(1) << 31); return xpair { uint32_t(x / y), uint32_t(x % y) }; } static constexpr TLFLOAT_INLINE xpair divmod2(uint64_t x, uint64_t y) { #if defined(_MSC_VER) && !defined(__clang__) // This is required to avoid ICE auto a = BigUInt<6>(x).divmod2(y, BigUInt<6>(y).reciprocal2()); #else auto a = BigUInt<6>(x).divmod2(y); #endif return xpair { a.first.u64, a.second.u64 }; } template static constexpr TLFLOAT_INLINE xpair, BigUInt> divmod2(const BigUInt& x, const BigUInt& y) { #if defined(_MSC_VER) && !defined(__clang__) // This is required to avoid ICE return x.divmod2(y, y.reciprocal2()); #else return x.divmod2(y); #endif } // #ifndef TLFLOAT_ENABLE_INTSQRT static constexpr TLFLOAT_INLINE uint32_t isqrt(uint32_t s) { uint64_t u = xsqrt(double(s) * (double)0x100000000ULL); return u - (u >> 32); } static constexpr TLFLOAT_INLINE uint64_t isqrt(uint64_t s) { double d = xsqrt((double)uint64_t(s) * double(1ULL << 32) * double(1ULL << 32)); return d > 0x1.fffffffffffffp+63 ? UINT64_MAX : uint64_t(d); // nextafter((double)UINT64_MAX, 0) } static constexpr TLFLOAT_INLINE uint64_t isqrt(BigUInt<6> s) { double d = xsqrt((double)uint64_t(s) * double(1ULL << 32) * double(1ULL << 32)); return d > 0x1.fffffffffffffp+63 ? UINT64_MAX : uint64_t(d); } template static constexpr TLFLOAT_INLINE BigUInt isqrt(BigUInt s) { if (!std::is_constant_evaluated()) assert(s >= (BigUInt(1) << (sizeof(BigUInt) * 8 - 2))); BigUInt x = BigUInt(isqrt(s.high) | 1, 0); x = (x >> 1) + s.mulhiAprx(x.reciprocalAprx()); return x + ((~x >> (sizeof(x)*8 - 1)) & 1); } #else // #ifndef TLFLOAT_ENABLE_INTSQRT static constexpr uint8_t rsqrttab[256] = { 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xfa, 0xf8, 0xf7, 0xf5, 0xf3, 0xf1, 0xf0, 0xee, 0xec, 0xeb, 0xe9, 0xe8, 0xe6, 0xe5, 0xe4, 0xe2, 0xe1, 0xdf, 0xde, 0xdd, 0xdc, 0xda, 0xd9, 0xd8, 0xd7, 0xd6, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0, 0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8, 0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc2, 0xc1, 0xc0, 0xbf, 0xbe, 0xbd, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb9, 0xb8, 0xb7, 0xb6, 0xb6, 0xb5, 0xb4, 0xb4, 0xb3, 0xb2, 0xb2, 0xb1, 0xb0, 0xb0, 0xaf, 0xae, 0xae, 0xad, 0xac, 0xac, 0xab, 0xab, 0xaa, 0xa9, 0xa9, 0xa8, 0xa8, 0xa7, 0xa7, 0xa6, 0xa6, 0xa5, 0xa4, 0xa4, 0xa3, 0xa3, 0xa2, 0xa2, 0xa1, 0xa1, 0xa0, 0xa0, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9d, 0x9d, 0x9c, 0x9c, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x98, 0x98, 0x97, 0x97, 0x97, 0x96, 0x96, 0x95, 0x95, 0x95, 0x94, 0x94, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x91, 0x91, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x80, }; static constexpr TLFLOAT_INLINE uint8_t irsqrt(uint8_t s) { return rsqrttab[s]; } static constexpr TLFLOAT_INLINE uint16_t irsqrt(uint16_t s) { if (!std::is_constant_evaluated()) assert(s >= (1U << 14)); uint8_t t = (s + (1 << 7)) >> 8; t = irsqrt(uint8_t(t)); uint32_t u = (t * (0xc000ULL - ((uint16_t(t) * t * uint32_t(s) + (1U << 15)) >> 16)) + (1U << 6)) >> 7; return u > 0xffffU ? 0xffffU : u; } static constexpr TLFLOAT_INLINE uint32_t irsqrt(uint32_t s) { if (!std::is_constant_evaluated()) assert(s >= (1ULL << 30)); uint16_t t = (s + (1 << 15)) >> 16; t = irsqrt(uint16_t(t - (t == 0))); uint64_t u = (t * (0xc0000000ULL - ((uint32_t(t) * t * uint64_t(s) + (1U << 31)) >> 32)) + (1U << 14)) >> 15; return u > 0xffffffffU ? 0xffffffffU : u; } static constexpr TLFLOAT_INLINE uint64_t irsqrt(uint64_t s) { if (!std::is_constant_evaluated()) assert(s >= (1ULL << 62)); uint32_t t = (s + (1U << 31)) >> 32; t = irsqrt(uint32_t(t - (t == 0))); BigUInt<7> u = (t * (0xc000000000000000ULL - ((uint64_t(t) * t * BigUInt<7>(s) + (1ULL << 63)) >> 64)) + (1U << 30)) >> 31; return u > 0xffffffffffffffffULL ? 0xffffffffffffffffULL : u.low.u64; } template static constexpr TLFLOAT_INLINE BigUInt irsqrt(BigUInt s) { if (!std::is_constant_evaluated()) assert(s >= (BigUInt(1) << ((1 << N)-2))); BigUInt t = (s + (BigUInt(1) << ((1 << (N-1))-1))).high; t = irsqrt(BigUInt(t - (t == 0))); BigUInt u = (t * ((BigUInt(0xc) << ((1 << N)-4)) - ((BigUInt::mul(BigUInt::mul(t, t), s) + (BigUInt(1) << ((1 << N)-1))) >> (1 << N))) + (BigUInt(1) << ((1 << (N-1))-2))) >> ((1 << (N-1))-1); return u.high.isZero() ? u.low : ~BigUInt(0U); } template<> constexpr TLFLOAT_INLINE BigUInt<6> irsqrt(BigUInt<6> s) { return irsqrt(s.u64); } static constexpr TLFLOAT_INLINE uint32_t isqrt(uint32_t s) { if (s == 0) return 0; if (!std::is_constant_evaluated()) assert(s >= (1U << 30)); uint64_t u = (uint64_t(s) * irsqrt(s)) >> 31; return u > 0xffffffffU ? 0xffffffffU : u; } static constexpr TLFLOAT_INLINE uint64_t isqrt(uint64_t s) { if (s == 0) return 0; if (!std::is_constant_evaluated()) assert(s >= (1ULL << 62)); __uint128_t u = (__uint128_t(s) * irsqrt(s)) >> 63; return u > 0xffffffffffffffffULL ? 0xffffffffffffffffULL : u; } static constexpr TLFLOAT_INLINE uint64_t isqrt(BigUInt<6> s) { return isqrt(s.u64); } template static constexpr TLFLOAT_INLINE BigUInt isqrt(BigUInt s) { if (!std::is_constant_evaluated()) assert(s >= (BigUInt(1) << (sizeof(BigUInt) * 8 - 2))); BigUInt u = s.mulhiAprx(irsqrt(s)) << 1; return u.high.isZero() ? u.low : ~BigUInt(0U); } #endif // #ifndef TLFLOAT_ENABLE_INTSQRT template class UnpackedFloat { template friend class UnpackedFloat; static_assert(sizeof(longmant_t) == 2 * sizeof(mant_t)); static constexpr size_t sizeof_mant_t() { return sizeof(mant_t); } template static constexpr TLFLOAT_INLINE mant_t mantBits(const floattype& fl) { return toBits(fl) & ((mant_t(1) << nbmant) - 1); } template static constexpr TLFLOAT_INLINE mant_t expBits(const floattype& fl) { return (toBits(fl) >> nbmant) & ((mant_t(1) << nbexp) - 1); } template static constexpr TLFLOAT_INLINE mant_t toBits(const floattype& f) { static_assert(sizeof(floattype) == sizeof(mant_t)); return std::bit_cast(f); } template static constexpr TLFLOAT_INLINE floattype fromBits(const mant_t& u) { static_assert(sizeof(floattype) == sizeof(mant_t)); return std::bit_cast(u); } // public: int32_t exp; mant_t mant; bool sign, iszero, isinf, isnan; static constexpr TLFLOAT_INLINE int expoffset() { if constexpr (nbexp != 0) return (1 << (nbexp - 1)) - 1; return 0; } static constexpr TLFLOAT_INLINE int nbexp_() { return nbexp; } static constexpr TLFLOAT_INLINE int nbmant_() { return nbmant; } static constexpr TLFLOAT_INLINE longmant_t longmant_t_() { return 0; } static constexpr TLFLOAT_INLINE UnpackedFloat xUnpackedFloat() { return UnpackedFloat(0, 0, false, true, false, false); } constexpr TLFLOAT_INLINE int32_t ilogb() const { if (exp != 0) return exp - expoffset() + 1; return (sizeof(mant_t) * 8 - nbmant_()) - clz(mant) - expoffset(); } friend constexpr TLFLOAT_INLINE UnpackedFloat fabs(UnpackedFloat x) { x.sign = 0; return x; } friend constexpr TLFLOAT_INLINE UnpackedFloat ldexp_(UnpackedFloat x, const int e) { #if !(defined(__GNUC__) && !defined(__clang__)) static_assert(x.nbexp_() == 0); #endif if (!x.iszero) { int64_t y = x.exp + (int64_t)e; if (y < INT32_MIN) return zero(x.sign); if (y > INT32_MAX) return infinity(x.sign); x.exp = y; } return x; } friend constexpr TLFLOAT_INLINE UnpackedFloat ldexp(UnpackedFloat x, const int e) { return ldexp_(x.cast((decltype(UnpackedFloat::xUnpackedFloat())*) 0), e).cast((UnpackedFloat*) 0); } friend constexpr TLFLOAT_INLINE xpair frexp_(UnpackedFloat x) { static_assert(x.nbexp_() == 0); xpair ret = { x, x.exp - expoffset() + 2 }; ret.first.exp = expoffset() - 2; return ret; } friend constexpr TLFLOAT_INLINE int cmp(const UnpackedFloat &lhs, const UnpackedFloat &rhs) { if (lhs.iszero && rhs.iszero) return 0; if (rhs.iszero) return lhs.sign ? -1 : 1; if (lhs.iszero) return rhs.sign ? 1 : -1; if (!lhs.sign && rhs.sign) return +1; if ( lhs.sign && !rhs.sign) return -1; if (lhs.exp > rhs.exp) return lhs.sign ? -1 : 1; if (lhs.exp < rhs.exp) return rhs.sign ? 1 : -1; if (lhs.mant > rhs.mant) return lhs.sign ? -1 : 1; if (lhs.mant < rhs.mant) return lhs.sign ? 1 : -1; return 0; } static constexpr TLFLOAT_INLINE unsigned clz(uint64_t u) { return u == 0 ? 64 : clz64(u); } #ifdef TLFLOAT_ENABLE_GNUC_CLZ static constexpr TLFLOAT_INLINE unsigned clz(uint32_t u) { return u == 0 ? 32 : __builtin_clz(u); } #else static constexpr TLFLOAT_INLINE unsigned clz(uint32_t u) { return clz(uint64_t(u)) - 32; } #endif static constexpr TLFLOAT_INLINE unsigned clz(uint16_t u) { return clz(uint32_t(u)) - 16; } template static constexpr TLFLOAT_INLINE unsigned clz(const BigUInt& u) { return u.clz(); } // static constexpr TLFLOAT_INLINE bool bit(const uint64_t x, unsigned b) { return (x >> b) & 1; } template static constexpr TLFLOAT_INLINE bool bit(const BigUInt& x, unsigned b) { return x.bit(b); } // friend constexpr double to_double(const UnpackedFloat &uf) { typedef UnpackedFloat, 11, 52> udouble; return (double)uf.cast((udouble *)nullptr); } static constexpr TLFLOAT_INLINE UnpackedFloat nan() { return UnpackedFloat((mant_t(3) << (nbmant - 1)), (1 << nbexp) - 2, false, false, false, true); } static constexpr TLFLOAT_INLINE UnpackedFloat infinity(bool sign = false) { return UnpackedFloat(mant_t(1) << nbmant, (1 << nbexp) - 2, sign, false, true, false); } static constexpr TLFLOAT_INLINE UnpackedFloat flt_true_min(bool sign = false) { return UnpackedFloat(mant_t(1), 0, sign, false, false, false); } static constexpr TLFLOAT_INLINE UnpackedFloat flt_min(bool sign = false) { return UnpackedFloat(mant_t(1) << nbmant, 0, sign, false, false, false); } static constexpr TLFLOAT_INLINE UnpackedFloat flt_max(bool sign = false) { return UnpackedFloat((mant_t(2) << nbmant) - 1, (1 << nbexp) - 3, sign, false, false, false); } static constexpr TLFLOAT_INLINE UnpackedFloat zero(bool sign = false) { return UnpackedFloat(0, 0, sign, true, false, false); } static constexpr TLFLOAT_INLINE UnpackedFloat faddsub(const UnpackedFloat &lhs, const UnpackedFloat &rhs, bool negateRhs) { const bool rhssign = rhs.sign != negateRhs; const int ed = lhs.exp - rhs.exp; if (lhs.iszero | lhs.isinf | lhs.isnan | rhs.iszero | rhs.isinf | rhs.isnan | (ed > +nbmant+2) | (ed < -nbmant-2)) { if (lhs.iszero && rhs.iszero) return UnpackedFloat(0, 0, lhs.sign && rhssign, true, false, false); if (lhs.isnan || rhs.iszero) return lhs; if (rhs.isnan || lhs.iszero) return UnpackedFloat(rhs.mant, rhs.exp, rhssign, rhs.iszero, rhs.isinf, rhs.isnan); if (lhs.isinf || rhs.isinf) { if (lhs.isinf && rhs.isinf && lhs.sign == rhssign) return lhs; if (lhs.isinf && rhs.isinf && lhs.sign != rhssign) return nan(); if (lhs.isinf) return lhs; return UnpackedFloat(rhs.mant, rhs.exp, rhssign, rhs.iszero, rhs.isinf, rhs.isnan); } if (ed > +nbmant+2) return lhs; if (ed < -nbmant-2) return UnpackedFloat(rhs.mant, rhs.exp, rhssign, rhs.iszero, rhs.isinf, rhs.isnan); } const bool subtract = lhs.sign != rhssign; longmant_t lm, rm; if (ed > 0) { lm = longmant_t(lhs.mant) << (sizeof(mant_t) * 8 ); rm = longmant_t(rhs.mant) << (sizeof(mant_t) * 8 - ed); } else { lm = longmant_t(lhs.mant) << (sizeof(mant_t) * 8 + ed); rm = longmant_t(rhs.mant) << (sizeof(mant_t) * 8 ); } int64_t exp = ed > 0 ? lhs.exp : rhs.exp; longmant_t am = 0; bool resultsign = lhs.sign; if (!subtract) { am = lm + rm; if (bit(am, (sizeof(mant_t) * 8) + nbmant + 1)) { am >>= 1; exp++; } am += bit(am, sizeof(mant_t) * 8) + ((longmant_t(1) << (sizeof(mant_t) * 8 - 1)) - 1); if (bit(am, (sizeof(mant_t) * 8) + nbmant + 1)) { am >>= 1; exp++; } if constexpr (nbexp != 0) { if (exp >= (1 << nbexp) - 2) { exp = (1 << nbexp) - 2; am = longmant_t(1) << (nbmant + sizeof(mant_t) * 8); } } } else { am = lm < rm ? (rm - lm) : (lm - rm); resultsign = lm < rm ? rhssign : lhs.sign; if (am == 0) resultsign = false; const int x = clz(am) - (sizeof(mant_t) * 8 - nbmant - 1); am <<= x; exp -= x; int y = 0; if constexpr (nbexp != 0) { if (exp < 0) { if (exp <= -(int)sizeof(longmant_t) * 8) am = 0; y = -exp; exp = 0; } } am += bitmask(sizeof(mant_t) * 8 + y - 1) + bit(am, sizeof(mant_t) * 8 + y); am >>= y; if (bit(am, (sizeof(mant_t) * 8) + nbmant + 1)) { am >>= 1; exp++; } } am >>= sizeof(mant_t) * 8; if (am == 0) exp = 0; if constexpr (nbexp == 0) { if (exp < INT32_MIN) return zero(resultsign); if (exp > INT32_MAX) return infinity(resultsign); } return UnpackedFloat(mant_t(am), exp, resultsign, am == 0, nbexp != 0 && exp == (1 << nbexp) - 2, false); } static constexpr TLFLOAT_INLINE UnpackedFloat fmul(const UnpackedFloat &lhs, const UnpackedFloat &rhs) { if (int(lhs.isnan) | int(rhs.isnan) | (int(lhs.iszero) & int(rhs.isinf)) | (int(lhs.isinf) & int(rhs.iszero)) | int(lhs.isinf) | int(rhs.isinf)) { if (lhs.isnan) return lhs; if (rhs.isnan) return rhs; if ((lhs.iszero && rhs.isinf) || (lhs.isinf && rhs.iszero)) return nan(); if (lhs.isinf || rhs.isinf) return infinity(lhs.sign != rhs.sign); } longmant_t am = mul(lhs.mant, rhs.mant); const int x = (int)clz(am) - ((int)sizeof(mant_t)*8 - nbmant) * 2; am = am << (x + sizeof(mant_t)*8 - nbmant + 1); int64_t exp = (int64_t)lhs.exp + rhs.exp - expoffset() - x; int y = 0; if constexpr (nbexp != 0) { if (exp < 0) { if (exp <= -(int)sizeof(longmant_t) * 8) am = 0; y = -exp; exp = 0; } } am += bitmask(sizeof(mant_t) * 8 + y - 1) + bit(am, sizeof(mant_t) * 8 + y); am >>= y; if (bit(am, (sizeof(mant_t) * 8) + nbmant + 1)) { am >>= 1; exp++; } if constexpr (nbexp != 0) { if (exp >= (1 << nbexp) - 2) { exp = (1 << nbexp) - 2; am = longmant_t(1) << (nbmant + sizeof(mant_t) * 8); } } am >>= sizeof(mant_t) * 8; if (am == 0) exp = 0; if constexpr (nbexp == 0) { if (exp < INT32_MIN) return zero(lhs.sign != rhs.sign); if (exp > INT32_MAX) return infinity(lhs.sign != rhs.sign); } return UnpackedFloat(mant_t(am), exp, lhs.sign != rhs.sign, am == 0, nbexp != 0 && exp == (1 << nbexp) - 2, false); } static constexpr TLFLOAT_INLINE UnpackedFloat fdiv(const UnpackedFloat &lhs, const UnpackedFloat &rhs) { if (lhs.isnan | lhs.isinf | rhs.isnan | rhs.iszero | rhs.isinf) { if (lhs.isnan) return lhs; if (rhs.isnan) return rhs; if (rhs.iszero) { if (lhs.iszero) return nan(); return infinity(lhs.sign != rhs.sign); } if (rhs.isinf) { if (lhs.isinf) return nan(); return zero(lhs.sign != rhs.sign); } if (lhs.isinf) return infinity(lhs.sign != rhs.sign); } int64_t exp = (int64_t)lhs.exp - rhs.exp + expoffset() - 1; int sl = clz(lhs.mant); int sr = clz(rhs.mant); exp -= sl + 1 - sr; auto p = divmod2(mant_t(lhs.mant << sl), mant_t(rhs.mant << sr)); longmant_t am = longmant_t(p.first) << (nbmant + 2); int c = icmp(p.second, rhs.mant << (sr - 1)); c = c >= 0 ? c + 2 : p.second != 0 ? 1 : 0; am += longmant_t(c) << nbmant; const int x = clz(am) - nbexp; am = x >= 0 ? (am << (x & (sizeof(am)*8-1))) : (am >> -x); exp -= x; int y = 0; if constexpr (nbexp != 0) { if (exp < 0) { if (exp <= -(int)sizeof(longmant_t) * 8) am = 0; y = -exp; exp = 0; } } am += bitmask(sizeof(mant_t) * 8 + y - 1) + bit(am, sizeof(mant_t) * 8 + y); am >>= y; if (bit(am, (sizeof(mant_t) * 8) + nbmant + 1)) { am >>= 1; exp++; } if constexpr (nbexp != 0) { if (exp >= (1 << nbexp) - 2) { exp = (1 << nbexp) - 2; am = longmant_t(1) << (nbmant + sizeof(mant_t) * 8); } } am >>= sizeof(mant_t) * 8; if (am == 0) exp = 0; if constexpr (nbexp == 0) { if (exp < INT32_MIN) return zero(lhs.sign != rhs.sign); if (exp > INT32_MAX) return infinity(lhs.sign != rhs.sign); } return UnpackedFloat(mant_t(am), exp, lhs.sign != rhs.sign, am == 0, nbexp != 0 && exp == (1 << nbexp) - 2, false); } static constexpr UnpackedFloat fma(const UnpackedFloat &lhs, const UnpackedFloat &rhs, const UnpackedFloat &zhs) { if (lhs.isnan | lhs.isinf | rhs.isnan | rhs.isinf | zhs.isnan | zhs.isinf) { if (lhs.isnan) return lhs; if (rhs.isnan) return rhs; if (zhs.isnan) return zhs; if (lhs.isinf || rhs.isinf || zhs.isinf) { if ((lhs.iszero && rhs.isinf) || (lhs.isinf && rhs.iszero)) return nan(); if (!zhs.isinf) return infinity(lhs.sign != rhs.sign); if (!(lhs.isinf || rhs.isinf) || ((lhs.sign != rhs.sign) == zhs.sign)) return infinity(zhs.sign); return nan(); } } int64_t exp = (int64_t)lhs.exp + rhs.exp - expoffset(); longmant_t am = mul(lhs.mant, rhs.mant); const int x = (int)clz(am) - ((int)sizeof(mant_t)*8 - nbmant) * 2; am = am << (x + sizeof(mant_t)*8 - nbmant + 1); exp -= x; if (am == 0) exp = -expoffset(); int ed = exp - zhs.exp; if constexpr (nbexp == 0) { if (am == 0 && zhs.iszero) { ed = 0; } else if (am == 0) { ed = -(int)sizeof(longmant_t) * 8; } else if (zhs.iszero) { ed = +(int)sizeof(longmant_t) * 8; } } const bool subtract = (lhs.sign != rhs.sign) != zhs.sign; bool resultsign = lhs.sign != rhs.sign; const int NGB = 4; bool amsb = false, zmsb = false; longmant_t zm = longmant_t(zhs.mant) << (sizeof(mant_t) * 8); if (ed < 0) { if (ed <= -(int)sizeof(longmant_t) * 8 + NGB) { amsb = am != 0; am = 0; } else { amsb = (bitmask(NGB - ed) & am) != 0; am = (am >> -ed) & ~((longmant_t(1) << NGB) - 1); } } else { if (ed >= (int)sizeof(longmant_t) * 8 - NGB) { zmsb = zm != 0; zm = 0; } else { zmsb = (bitmask(NGB + ed) & zm) != 0; zm = (zm >> ed) & ~((longmant_t(1) << NGB) - 1); } } exp = ed > 0 ? exp : zhs.exp; if (!subtract) { am += zm; if (bit(am, (sizeof(mant_t) * 8) + nbmant + 1)) { am >>= 1; exp++; } am += ((longmant_t(1) << (sizeof(mant_t) * 8 - 1)) - 1) + (amsb || zmsb || bit(am, sizeof(mant_t) * 8)); } else { bool psb = am >= zm ? amsb : zmsb; bool nsb = am >= zm ? zmsb : amsb; resultsign = am >= zm ? resultsign : zhs.sign; am = am >= zm ? (am - zm) : (zm - am); if (am == 0 && !psb) resultsign = 0; const int x = clz(am) - (sizeof(mant_t) * 8 - nbmant - 1); am <<= x; exp -= x; const int y = (nbexp != 0 && exp < 0) ? -exp : 0; am += bitmask(sizeof(mant_t) * 8 + y - 1) + (!nsb && (psb || bit(am, sizeof(mant_t) * 8 + y))); am >>= y; } if (bit(am, (sizeof(mant_t) * 8) + nbmant + 1)) { am >>= 1; exp++; } if constexpr (nbexp != 0) { if (exp < 0) exp = 0; if (exp >= (1 << nbexp) - 2) { exp = (1 << nbexp) - 2; am = longmant_t(1) << (nbmant + sizeof(mant_t) * 8); } } am >>= sizeof(mant_t) * 8; if (am == 0) exp = 0; if constexpr (nbexp == 0) { if (exp < INT32_MIN) return zero(resultsign); if (exp > INT32_MAX) return infinity(resultsign); } return UnpackedFloat(mant_t(am), exp, resultsign, am == 0, nbexp != 0 && exp == (1 << nbexp) - 2, false); } // constexpr TLFLOAT_INLINE UnpackedFloat() = default; constexpr TLFLOAT_INLINE UnpackedFloat(const UnpackedFloat&) = default; constexpr TLFLOAT_INLINE UnpackedFloat& operator=(const UnpackedFloat&) = default; constexpr TLFLOAT_INLINE UnpackedFloat(const mant_t mant_, int32_t exp_, bool sign_, bool iszero_, bool isinf_, bool isnan_) : exp(exp_), mant(mant_), sign(sign_), iszero(iszero_), isinf(isinf_), isnan(isnan_) { } explicit constexpr TLFLOAT_INLINE UnpackedFloat(const int i) { *this = castFromInt(i); } static constexpr uint8_t hexchartab[256] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; constexpr UnpackedFloat(const char *ptr, const char **endptr=nullptr) { while(xisspace(*ptr)) ptr++; bool positive = true; if (*ptr == '-') { positive = false; ptr++; } else if (*ptr == '+') { ptr++; } if (xstrncasecmp(ptr, "nan", 3) == 0) { *this = nan(); if (endptr) { *endptr = ptr + 3; } return; } if (xstrncasecmp(ptr, "inf", 3) == 0) { *this = infinity(!positive); if (endptr) { *endptr = ptr + 3; } return; } if (*ptr == '0' && (*(ptr+1) == 'x' || *(ptr+1) == 'X')) { ptr += 2; longmant_t m = 0; exp = 0; bool bp = false; int dr = sizeof(mant_t)*2, wd = 0; uint64_t w = 0; while(*ptr != '\0' && dr >= 0) { int d = hexchartab[(uint8_t)*ptr]; if (d != 0xff) { ptr++; } else if (*ptr == '.') { if (bp) break; bp = true; ptr++; continue; } else break; w = (w << 4) + d; if (w != 0 || m != 0) dr--; wd++; if (w >= (1ULL << 60)) { if (m != 0) m <<= wd * 4; m |= w; w = 0; wd = 0; } if (bp) exp -= 4; } if (m != 0) m <<= wd * 4; m |= w; while(hexchartab[(uint8_t)*ptr] != 0xff) { ptr++; if (!bp) exp += 4; } if (*ptr == '.' && !bp) ptr++; while(hexchartab[(uint8_t)*ptr] != 0xff) ptr++; if (*ptr == 'p' || *ptr == 'P') { const char *q; long long z = xstrtoll(ptr+1, &q); if (!(ptr+1 == q || xisspace((int)*(ptr+1)))) { exp += z; ptr = q; } } const int x = (int)clz(m) - ((int)sizeof(m) * 8 - nbmant - 1); exp += nbmant - x - 1; if (x >= 0) { mant = x < (int)sizeof(mant_t)*8 ? mant_t(m << x) : 0; } else { mant = mant_t((m + (longmant_t(1) << (-x-1))) >> -x); if (bit(mant, nbmant + 1)) { mant >>= 1; exp++; } } sign = !positive; isinf = isnan = iszero = false; if (mant == 0) { iszero = true; exp = 0; } if (endptr) *endptr = ptr; return; } bool bp = false; UnpackedFloat n = castFromInt(0); int e = 0; for(unsigned i=0;;i++) { char c = ptr[i]; if (c == '\0') { ptr += i; break; } if (c == '.' && !bp) { bp = true; continue; } if ('0' <= c && c <= '9') { if (n.exp > expoffset() + nbmant) { if (!bp) e++; continue; } n = fma(n, castFromInt(10), castFromInt(c - '0')); if (bp) e--; continue; } if (c == 'e' || c == 'E') { e += xstrtoll(&ptr[i+1], &ptr); break; } } n *= UnpackedFloat::exp10i(e); if (!positive) n = -n; *this = n; if (endptr) *endptr = ptr; } template, int> = 0> constexpr TLFLOAT_INLINE UnpackedFloat(const floattype &fl) : exp(int32_t(expBits(fl) - (expBits(fl) != 0))), mant(mantBits(fl) | (mant_t(expBits(fl) != 0) << nbmant)), sign(toBits(fl) >> (sizeof(fl) * 8 - 1)), iszero((toBits(fl) & ((mant_t(1) << (sizeof(mant_t)*8-1))-1)) == 0), isinf((exp == ((1 << nbexp) - 2)) && mant == (mant_t(1) << nbmant)), isnan((exp == ((1 << nbexp) - 2)) && mant != (mant_t(1) << nbmant)) { static_assert(sizeof(floattype) == sizeof(mant_t)); } template explicit constexpr TLFLOAT_INLINE operator floattype() const { static_assert(sizeof(floattype) == sizeof(mant_t)); mant_t m = mant & ((mant_t(1) << nbmant) - 1); m |= mant_t(sign) << (sizeof(mant_t) * 8 - 1); m |= mant_t(exp + ((mant >> nbmant) != 0)) << nbmant; return fromBits(m); } template constexpr TLFLOAT_INLINE dsttype cast(const dsttype *ptr) const { typedef decltype(dsttype::mant) dmant_t; typedef decltype(dsttype::longmant_t_()) dlongmant_t; if (isnan) return dsttype::nan(); if constexpr (dsttype::nbmant_() > nbmant && (dsttype::sizeof_mant_t() > sizeof_mant_t() || nbexp == 0 || dsttype::nbexp_() == 0)) { int64_t e = (int64_t)exp - expoffset() + dsttype::expoffset(); const int x = clz(mant) - (sizeof(mant_t) * 8 - nbmant - 1); e -= x; int s = dsttype::nbmant_() - nbmant + x; if constexpr (dsttype::nbexp_() != 0) { if (e < 0) { s += e; e = 0; } } dmant_t m = s < int(sizeof(dmant_t)*8) ? dmant_t(mant) << s : 0; if (isinf || isnan) e = (1 << dsttype::nbexp_()) - 2; if (iszero) e = 0; return dsttype(m, (int)e, sign, iszero, isinf, isnan); } else if constexpr (dsttype::nbmant_() < nbmant && (dsttype::sizeof_mant_t() < sizeof_mant_t() || nbexp == 0 || dsttype::nbexp_() == 0)) { bool isinf_ = isinf, sb = false; int64_t e = (int64_t)exp - expoffset() + dsttype::expoffset(); mant_t m = mant; if constexpr (dsttype::nbexp_() != 0) { if (e >= (1 << dsttype::nbexp_()) - 2) isinf_ = true; if (e < 0) { sb = (m & bitmask(-e)) != 0; if (unsigned(-e) >= sizeof(mant_t)*8) { sb = m != 0; m = 0; } m >>= -e; e = 0; } } m += bit(m, nbmant - dsttype::nbmant_()) || sb; m += (mant_t(1) << ((nbmant - dsttype::nbmant_()) - 1)) - 1; if (bit(m, nbmant + 1)) { m >>= 1; e++; } m >>= nbmant - dsttype::nbmant_(); if (isinf_ || isnan) e = (1 << dsttype::nbexp_()) - 2; if (isinf_) m = mant_t(1) << dsttype::nbmant_(); if (isnan) m = mant_t(3) << (dsttype::nbmant_() - 1); bool iszero_ = iszero; if (dmant_t(m) == 0) iszero_ = true; if (iszero_) e = 0; return dsttype(dmant_t(m), (int)e, sign, iszero_, isinf_, isnan); } else if constexpr (dsttype::nbmant_() < nbmant && dsttype::sizeof_mant_t() == sizeof_mant_t()) { // BFloat16 <- Half int64_t e = (int64_t)exp - expoffset() + dsttype::expoffset(); const int x = clz(mant) - (sizeof(mant_t) * 8 - nbmant - 1); e -= x; dlongmant_t m = dlongmant_t(mant) << (dsttype::nbmant_() - nbmant + x + (sizeof(dlongmant_t)-sizeof(dmant_t))*8); if (isinf || isnan) e = (1 << dsttype::nbexp_()) - 2; if (iszero) e = 0; m += bitmask(sizeof(dmant_t) * 8 - 1) + bit(m, sizeof(dmant_t) * 8); if (bit(m, (sizeof(dmant_t) * 8) + dsttype::nbmant_() + 1)) { m >>= 1; e++; } m >>= sizeof(dmant_t) * 8; return dsttype(dmant_t(m), m == 0 ? 0 : e, sign, m == 0, isinf, isnan); } else if constexpr (dsttype::nbmant_() > nbmant && dsttype::sizeof_mant_t() == sizeof_mant_t()) { // Half <- BFloat16 bool isinf_ = isinf, sb = false; int64_t e = (int64_t)exp - expoffset() + dsttype::expoffset(); longmant_t m = longmant_t(mant) << (sizeof(mant_t) * 8); if constexpr (dsttype::nbexp_() != 0) { if (e >= (1 << dsttype::nbexp_()) - 2) isinf_ = true; if (e < 0) { sb = (m & bitmask(-e)) != 0; if (unsigned(-e) >= sizeof(longmant_t)*8) { sb = m != 0; m = 0; } m >>= -e; e = 0; } } m += bit(m, (nbmant + sizeof(mant_t)*8) - dsttype::nbmant_()) || sb; m += (longmant_t(1) << ((nbmant + sizeof(mant_t)*8 - dsttype::nbmant_()) - 1)) - 1; if (bit(m, nbmant + sizeof(mant_t)*8 + 1)) { m >>= 1; e++; } m >>= nbmant + sizeof(mant_t)*8 - dsttype::nbmant_(); if (isinf_ || isnan) e = (1 << dsttype::nbexp_()) - 2; if (isinf_) m = longmant_t(1) << dsttype::nbmant_(); if (isnan) m = longmant_t(3) << (dsttype::nbmant_() - 1); bool iszero_ = iszero; if (dmant_t(m) == 0) iszero_ = true; if (iszero_) e = 0; return dsttype(dmant_t(m), (int)e, sign, iszero_, isinf_, isnan); } else { static_assert(dsttype::nbmant_() == nbmant); static_assert(dsttype::sizeof_mant_t() == sizeof_mant_t()); return dsttype(mant, exp, sign, iszero, isinf, isnan); } } template && sizeof(dsttype) <= 8), int> = 0> constexpr TLFLOAT_INLINE dsttype castToInt(const dsttype *ptr) const { if (exp - expoffset() < -1) return 0; if constexpr (std::is_unsigned_v) { if (sign && !iszero) return ~dsttype(0); if (exp - expoffset() >= int(sizeof(dsttype)*8-1)) return ~dsttype(0); int s = nbmant - (exp - expoffset() + 1); return dsttype(s > 0 ? (mant >> s) : (dsttype(mant) << -s)); } else { if (exp - expoffset() >= int(sizeof(dsttype)*8-2)) return dsttype(dsttype(1) << (sizeof(dsttype)*8-1)); int s = nbmant - (exp - expoffset() + 1); dsttype r = s > 0 ? dsttype(mant >> s) : (dsttype(mant) << -s); return sign ? -r : r; } } template constexpr TLFLOAT_INLINE BigInt castToInt(const BigInt *ptr) const { if (exp - expoffset() < -1) return 0; if (exp - expoffset() >= int(sizeof(BigInt)*8-2)) return BigInt(BigInt(1) << (sizeof(BigInt)*8-1)); int s = nbmant - (exp - expoffset() + 1); BigInt r = BigInt(s > 0 ? BigUInt(mant >> s) : (BigUInt(mant) << -s)); return sign ? -r : r; } template constexpr TLFLOAT_INLINE BigUInt castToInt(const BigUInt *ptr) const { if (exp - expoffset() < -1) return 0; if (sign && !iszero) return ~BigUInt(0); if (exp - expoffset() >= int(sizeof(BigUInt)*8-1)) return ~BigUInt(0); int s = nbmant - (exp - expoffset() + 1); return s > 0 ? BigUInt(mant >> s) : (BigUInt(mant) << -s); } constexpr TLFLOAT_INLINE uint64_t castToInt2() const { int s = nbmant - (exp - expoffset() + 1); if (s <= -int(sizeof(uint64_t))*8 || s >= int(sizeof(mant_t))*8) return 0; return uint64_t(s > 0 ? (mant >> s) : (uint64_t(mant) << -s)); } template && sizeof(srctype) <= 8), int> = 0> static constexpr TLFLOAT_INLINE UnpackedFloat castFromInt(srctype src) { if (src == 0) return zero(); bool sign = false; uint64_t v = src; if constexpr (!std::is_unsigned_v) { sign = src < 0; v = src < 0 ? -int64_t(src) : src; } int x = sizeof(v) * 8 - clz(v); int s = nbmant - (x - 1) + int(sizeof(mant_t)) * 8; bool sb = false; longmant_t u = 0; if (s >= 0) { u = longmant_t(v) << s; } else { sb = (bitmask(-s) & v) != 0; u = v >> -s; } u += (((u >> (sizeof(mant_t) * 8)) & 1) || sb) + (longmant_t(1) << (sizeof(mant_t) * 8 - 1)) - 1; if (bit(u, nbmant + sizeof(mant_t) * 8 + 1)) { u >>= 1; x++; } u >>= sizeof(mant_t) * 8; return UnpackedFloat(mant_t(u), x + expoffset() - 2, sign, u == 0, false, false); } template static constexpr TLFLOAT_INLINE UnpackedFloat castFromInt(BigInt src) { if (src == 0) return zero(); bool sign = src < 0; BigUInt v = sign ? -src : src; int x = sizeof(v) * 8 - clz(v); int s = nbmant - (x - 1) + int(sizeof(mant_t)) * 8; bool sb = false; longmant_t u = 0; if (s >= 0) { u = longmant_t(v) << s; } else { sb = (bitmask(-s) & v) != 0; u = longmant_t(v >> -s); } u += (((u >> (sizeof(mant_t) * 8)) & 1) || sb) + (longmant_t(1) << (sizeof(mant_t) * 8 - 1)) - 1; if (bit(u, nbmant + sizeof(mant_t) * 8 + 1)) { u >>= 1; x++; } u >>= sizeof(mant_t) * 8; return UnpackedFloat(mant_t(u), x + expoffset() - 2, sign, u == 0, false, false); } template static constexpr TLFLOAT_INLINE UnpackedFloat castFromInt(BigUInt src) { if (src == 0) return zero(); BigUInt v = src; int x = sizeof(v) * 8 - clz(v); int s = nbmant - (x - 1) + int(sizeof(mant_t)) * 8; bool sb = false; longmant_t u = 0; if (s >= 0) { u = longmant_t(v) << s; } else { sb = (bitmask(-s) & v) != 0; u = longmant_t(v >> -s); } u += (((u >> (sizeof(mant_t) * 8)) & 1) || sb) + (longmant_t(1) << (sizeof(mant_t) * 8 - 1)) - 1; if (bit(u, nbmant + sizeof(mant_t) * 8 + 1)) { u >>= 1; x++; } u >>= sizeof(mant_t) * 8; return UnpackedFloat(mant_t(u), x + expoffset() - 2, false, u == 0, false, false); } #if defined(TLFLOAT_COMPILER_SUPPORTS_INT128) && !defined(__CUDA_ARCH__) constexpr TLFLOAT_INLINE __int128_t castToInt(const __int128_t *ptr) const { return __int128_t (castToInt((BigInt<7> *)0)); } constexpr TLFLOAT_INLINE __uint128_t castToInt(const __uint128_t *ptr) const { return __uint128_t(castToInt((BigUInt<7> *)0)); } static constexpr TLFLOAT_INLINE UnpackedFloat castFromInt(__int128_t src) { return castFromInt(BigInt <7>(src)); } static constexpr TLFLOAT_INLINE UnpackedFloat castFromInt(__uint128_t src) { return castFromInt(BigUInt<7>(src)); } #endif friend constexpr UnpackedFloat trunc(const UnpackedFloat &f) { if (f.iszero || f.isinf || f.isnan) return f; if (f.exp >= expoffset() + nbmant) return f; if (f.exp < expoffset() - 1) return zero(f.sign); int s = nbmant - (f.exp - expoffset() + 1); UnpackedFloat r = f; r.mant &= ~bitmask(s); return r; } friend constexpr UnpackedFloat floor(const UnpackedFloat &f) { if (f.iszero || f.isinf || f.isnan) return f; if (f.exp >= expoffset() + nbmant) return f; if (f.exp < expoffset() - 1) { if (f.iszero || !f.sign) return zero(f.sign); return castFromInt(-1); } int s = nbmant - (f.exp - expoffset() + 1); UnpackedFloat r = f; if (r.sign) r.mant += bitmask(s); r.mant &= ~bitmask(s); if (bit(r.mant, nbmant + 1)) { r.mant >>= 1; r.exp++; } return r; } friend constexpr UnpackedFloat ceil(const UnpackedFloat &f) { if (f.iszero || f.isinf || f.isnan) return f; if (f.exp >= expoffset() + nbmant) return f; if (f.exp < expoffset() - 1) { if (f.iszero || f.sign) return zero(f.sign); return castFromInt(1); } int s = nbmant - (f.exp - expoffset() + 1); UnpackedFloat r = f; if (!r.sign) r.mant += bitmask(s); r.mant &= ~bitmask(s); if (bit(r.mant, nbmant + 1)) { r.mant >>= 1; r.exp++; } return r; } friend constexpr UnpackedFloat round(const UnpackedFloat &f) { if (f.iszero || f.isinf || f.isnan) return f; if (f.exp >= expoffset() + nbmant - 1) return f; if (f.exp < expoffset() - 2) return zero(f.sign); int s = nbmant - (f.exp - expoffset() + 1); UnpackedFloat r = f; r.mant += mant_t(1) << (s - 1); r.mant &= ~((mant_t(1) << s) - 1); if (bit(r.mant, nbmant + 1)) { r.mant >>= 1; r.exp++; } if (r.mant == 0) return zero(f.sign); return r; } friend constexpr UnpackedFloat rint(const UnpackedFloat &f) { if (f.iszero || f.isinf || f.isnan) return f; if (f.exp >= expoffset() + nbmant - 1) return f; if (f.exp < expoffset() - 2) return zero(f.sign); int s = nbmant - (f.exp - expoffset() + 1); UnpackedFloat r = f; r.mant += bit(r.mant, s) + (mant_t(1) << (s - 1)) - 1; r.mant &= ~((mant_t(1) << s) - 1); if (bit(r.mant, nbmant + 1)) { r.mant >>= 1; r.exp++; } if (r.mant == 0) return zero(f.sign); return r; } friend constexpr UnpackedFloat sqrt_(const UnpackedFloat &f) { const int offset = 100000000; if (f.iszero) return f; int y = clz(f.mant) - (sizeof(mant_t) * 8 - nbmant - 1); int x = f.exp - y; int s0 = sizeof(longmant_t) * 8 - nbmant - 2 + (1 & ~(x + f.expoffset() + offset)) + y; longmant_t l = longmant_t(f.mant) << s0; l = isqrt(l); int s1 = sizeof(longmant_t) * 8 - nbmant - 1 - clz(l); l += bit(l, s1) + bitmask(s1 - 1); l -= ~l >> (sizeof(l) * 8 - 1); mant_t m = mant_t(l >> s1); if (bit(m, nbmant + 1)) { m >>= 1; x++; } return UnpackedFloat(mant_t(m), (x + f.expoffset() + offset * 2 + 1) / 2 - offset - 1, false, m == 0, false, false); } friend constexpr TLFLOAT_INLINE bool isint(const UnpackedFloat &f) { if (f.isinf || f.isnan) return false; return trunc(f) == f; } friend constexpr TLFLOAT_INLINE bool iseven(const UnpackedFloat &f) { return isint(ldexp(f, -1)); } friend constexpr TLFLOAT_INLINE UnpackedFloat toward0(UnpackedFloat f) { static_assert(f.nbexp_() == 0); if (f.iszero || f.isinf || f.isnan) return f; f.mant--; if (!((f.mant >> nbmant) & 1)) { f.exp--; f.mant <<= 1; } return f; } friend constexpr int32_t intlsb(const UnpackedFloat &f) { if (f.iszero || f.isinf || f.isnan) return 0; int s = nbmant - (f.exp - expoffset() + 1); if (s >= int(sizeof(f.mant)*8) || s <= -int(sizeof(uint16_t)*8)) return 0; int m = s >= 0 ? uint16_t(f.mant >> s) : (uint16_t(f.mant) << -s); return f.sign ? -m-1 : m; } // constexpr TLFLOAT_INLINE UnpackedFloat operator+() const { return UnpackedFloat(*this); } constexpr TLFLOAT_INLINE UnpackedFloat operator-() const { return UnpackedFloat(mant, exp, !sign, iszero, isinf, isnan); } constexpr UnpackedFloat operator+(const UnpackedFloat& rhs) const { return faddsub(*this, rhs, false); } constexpr UnpackedFloat operator-(const UnpackedFloat& rhs) const { return faddsub(*this, rhs, true); } constexpr UnpackedFloat operator*(const UnpackedFloat& rhs) const { return fmul(*this, rhs); } constexpr UnpackedFloat operator/(const UnpackedFloat& rhs) const { return fdiv(*this, rhs); } constexpr TLFLOAT_INLINE bool operator==(const UnpackedFloat& rhs) const { if (isnan || rhs.isnan) return false; return cmp(*this, rhs) == 0; } constexpr TLFLOAT_INLINE bool operator!=(const UnpackedFloat& rhs) const { return !((*this) == rhs); } constexpr TLFLOAT_INLINE bool operator>(const UnpackedFloat& rhs) const { if (isnan || rhs.isnan) return false; return cmp(*this, rhs) == 1; } constexpr TLFLOAT_INLINE bool operator<(const UnpackedFloat& rhs) const { if (isnan || rhs.isnan) return false; return cmp(*this, rhs) == -1; } constexpr TLFLOAT_INLINE bool operator<=(const UnpackedFloat& rhs) const { if (isnan || rhs.isnan) return false; return cmp(*this, rhs) != 1; } constexpr TLFLOAT_INLINE bool operator>=(const UnpackedFloat& rhs) const { if (isnan || rhs.isnan) return false; return cmp(*this, rhs) != -1; } // template constexpr TLFLOAT_INLINE UnpackedFloat operator+(const rhstype& rhs) const { return *this + UnpackedFloat(rhs); } template constexpr TLFLOAT_INLINE UnpackedFloat operator-(const rhstype& rhs) const { return *this - UnpackedFloat(rhs); } template constexpr TLFLOAT_INLINE UnpackedFloat operator*(const rhstype& rhs) const { return *this * UnpackedFloat(rhs); } template constexpr UnpackedFloat operator/(const rhstype& rhs) const { return *this / UnpackedFloat(rhs); } template constexpr TLFLOAT_INLINE bool operator==(const rhstype& rhs) const { return *this == UnpackedFloat(rhs); } template constexpr TLFLOAT_INLINE bool operator!=(const rhstype& rhs) const { return *this != UnpackedFloat(rhs); } template constexpr TLFLOAT_INLINE bool operator> (const rhstype& rhs) const { return *this > UnpackedFloat(rhs); } template constexpr TLFLOAT_INLINE bool operator< (const rhstype& rhs) const { return *this < UnpackedFloat(rhs); } template constexpr TLFLOAT_INLINE bool operator>=(const rhstype& rhs) const { return *this >= UnpackedFloat(rhs); } template constexpr TLFLOAT_INLINE bool operator<=(const rhstype& rhs) const { return *this <= UnpackedFloat(rhs); } template constexpr TLFLOAT_INLINE UnpackedFloat& operator=(const srctype& s) { UnpackedFloat n(s); *this = n; return *this; } template constexpr TLFLOAT_INLINE UnpackedFloat& operator+=(const rhstype& rhs) { *this = *this + UnpackedFloat(rhs); return *this; } template constexpr TLFLOAT_INLINE UnpackedFloat& operator-=(const rhstype& rhs) { *this = *this - UnpackedFloat(rhs); return *this; } template constexpr TLFLOAT_INLINE UnpackedFloat& operator*=(const rhstype& rhs) { *this = *this * UnpackedFloat(rhs); return *this; } template constexpr UnpackedFloat& operator/=(const rhstype& rhs) { *this = *this / UnpackedFloat(rhs); return *this; } // static constexpr TLFLOAT_INLINE UnpackedFloat exp10i(int a) { bool negative = a < 0; if (negative) a = -a; UnpackedFloat r = castFromInt(1), d = castFromInt(10); for(;a;a>>=1) { if (a & 1) r *= d; d *= d; } return negative ? castFromInt(1) / r : r; } friend constexpr TLFLOAT_INLINE int ilog10(const UnpackedFloat& a) { // returns floor(log10(a)) int ret = rint(a.ilogb() * LOG10_2_); UnpackedFloat e = UnpackedFloat::exp10i(ret); if (e > a) { ret--; } else if (e * castFromInt(10) < a) { ret++; } return ret; } TLFLOAT_NOINLINE friend int snprint(char *cbuf, const size_t bufsize, UnpackedFloat arg, char typespec, int width = 0, int precision = 6, bool flag_sign = false, bool flag_blank = false, bool flag_alt = false, bool flag_left = false, bool flag_zero = false, bool flag_upper = false) { if (bufsize == 0) return 0; if (bufsize == 1) { *cbuf = '\0'; return 0; } if (typespec != 'e' && typespec != 'f' && typespec != 'g' && typespec != 'a') return 0; detail::SafeArray buf(cbuf, bufsize); if (width > (long)bufsize) width = bufsize; int64_t idx = 0; char prefix = 0; int length = 0, flag_rtz = 0, mainpos = 0; if (arg.sign) { arg.sign = 0; prefix = '-'; } else if (flag_sign) { prefix = '+'; } else if (flag_blank) { prefix = ' '; } UnpackedFloat value = arg; if (value.isnan) { if (prefix) buf[idx++] = prefix; buf.strcpyFrom(idx, flag_upper ? "NAN" : "nan"); idx += 3; flag_zero = false; } else if (value.isinf) { if (prefix) buf[idx++] = prefix; buf.strcpyFrom(idx, flag_upper ? "INF" : "inf"); idx += 3; flag_zero = false; } else if (typespec != 'a') { if (precision < 0) precision = 6; if (precision > (long)bufsize/2 - 10) precision = bufsize/2 - 10; if (typespec == 'g' && precision > 0) precision--; UnpackedFloat rounder = value.iszero ? UnpackedFloat::zero() : ldexp(UnpackedFloat::exp10i(-precision), -1); if (typespec == 'f') { UnpackedFloat v = (value + rounder) * UnpackedFloat::exp10i(precision); if (iseven(v) || !isint(v)) value += rounder; } int exp = 0, e2 = 0; if (!arg.iszero) { exp = ilog10(value); value *= UnpackedFloat::exp10i(-exp); } bool flag_exp = typespec == 'e'; if (typespec != 'f') { UnpackedFloat v = value + rounder; if (iseven(v) || !isint(v)) value = v; } if (value >= castFromInt(10)) { value /= castFromInt(10); exp++; } else if (!value.iszero && value < castFromInt(1)) { value *= castFromInt(10); exp--; } if (typespec == 'g') { flag_rtz = !flag_alt; if (exp < -4 || exp > precision) { typespec = 'e'; } else { precision = precision - exp; typespec = 'f'; } } if (typespec != 'e') e2 = exp; bool flag_dp = precision > 0 || flag_alt; if (prefix) buf[idx++] = prefix; if (e2 < 0) { buf[idx++] = '0'; } else { for(;e2>=0;e2--) { int digit = value.castToInt((int *)nullptr); if (value < castFromInt(digit)) digit--; buf[idx++] = digit + '0'; value = (value - castFromInt(digit)) * castFromInt(10); } } if (flag_dp) buf[idx++] = '.'; for(e2++;e2 < 0 && precision > 0;precision--, e2++) buf[idx++] = '0'; while (precision-- > 0) { int digit = value.castToInt((int *)nullptr); if (value < castFromInt(digit)) digit--; buf[idx++] = digit + '0'; value = (value - castFromInt(digit)) * castFromInt(10); } if (flag_rtz && flag_dp) { while(buf[idx-1] == '0') buf[--idx] = '\0'; if (buf[idx-1] == '.') buf[--idx] = '\0'; } if (flag_exp || (typespec == 'e' && exp != 0)) { buf[idx++] = flag_upper ? 'E' : 'e'; if (arg.iszero) exp = 0; if (exp < 0){ buf[idx++] = '-'; exp = -exp; } else { buf[idx++] = '+'; } char str[32]; snprintf(str, sizeof(buf), "%02d", exp); buf.strcpyFrom(idx, str); idx += strlen(str); } } else { if (!value.iszero && precision >= 0 && precision < nbmant/4+1) { int s = nbmant - precision*4 - 1; if (s < nbmant && s >= 0) value.mant += ((mant_t)1) << s; if (bit(value.mant, nbmant + 1)) { value.mant >>= 1; value.exp++; } } if (prefix) buf[idx++] = prefix; buf.strcpyFrom(idx, flag_upper ? "0X" :"0x"); idx += 2; mainpos = idx; buf.strcpyFrom(idx, value.iszero ? "0" : "1"); idx += 1; mant_t m = value.mant << (sizeof(mant_t)*8 - nbmant); if ((!(m == 0 && precision < 0) && precision != 0) || flag_alt) buf.strcpyFrom(idx++, "."); const char *digits = flag_upper ? "0123456789ABCDEF" : "0123456789abcdef"; const int niter = precision >= 0 ? precision : -1; for(int i=0;(niter < 0 && m != 0) || i < niter;i++) { buf[idx++] = digits[(unsigned)((m >> (sizeof(mant_t)*8 - 4)) & 0xf)]; m <<= 4; } int exp = value.ilogb(); if (value.iszero) exp = 0; char str[32]; snprintf(str, sizeof(buf), "%c%+d", flag_upper ? 'P' : 'p', exp); buf.strcpyFrom(idx, str); idx += strlen(str); } buf[idx] = '\0'; length = idx; if (!flag_zero) mainpos = 0; if (!flag_left && length < width) { int nPad = width - length; for(int i=width; i-nPad >= mainpos; i--) buf[i] = buf[i-nPad]; int i = mainpos; if (prefix != 0 && flag_zero && typespec != 'a') i++; while (nPad-- > 0) buf[i++] = flag_zero ? '0' : ' '; length = width; } if (flag_left) { while (length < width) buf[length++] = ' '; buf[length] = '\0'; } return length; } }; // class UnpackedFloat template static consteval T const_M_PI_(int exp = 0) { return ldexp_( T("0x1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d4c76273644a29410f31c6809bbdf2a33679a748636605614dbe4be286e9fc26adadaa38488p+1"), exp); } template static consteval T const_M_E_(int exp = 0) { return ldexp_( T("0x2.b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfef324e7738926cfbe5f4bf8d8d8c31d763da06c80abb1185eb4f7c7b5757f59584p+0"), exp); } } // namespace detail /** * This is a trivially copyable generic template class that * represents an IEEE 754 floating-point number. By adjusting the * template parameters, it can represent an IEEE 754 floating-point * number of any precision. The data size and data structure of the * object are the same as the corresponding floating-point number * represented in the IEEE 754 format. */ template class TLFloat { template friend class TLFloat; typedef detail::UnpackedFloat uhalf; typedef detail::UnpackedFloat ubf16; typedef detail::UnpackedFloat ufloat; typedef detail::UnpackedFloat, 11, 52> udouble; typedef detail::UnpackedFloat, BigUInt<8>, 15, 112> uquad; typedef detail::UnpackedFloat, BigUInt<9>, 19, 236> uoctuple; typedef decltype(Unpacked_t::mant) mant_t; typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; public: mant_t m = 0; /** Returns NaN */ static constexpr TLFLOAT_INLINE TLFloat nan() { return Unpacked_t::nan(); } /** Returns infinity of the given sign */ static constexpr TLFLOAT_INLINE TLFloat infinity(bool sign=false) { return Unpacked_t::infinity(sign); } /** Returns the minimum representative number of the given sign */ static constexpr TLFLOAT_INLINE TLFloat flt_true_min(bool sign=false) { return Unpacked_t::flt_true_min(sign); } /** Returns the minimum normalized number of the given sign */ static constexpr TLFLOAT_INLINE TLFloat flt_min(bool sign=false) { return Unpacked_t::flt_min(sign); } /** Returns the maximum representative number of the given sign */ static constexpr TLFLOAT_INLINE TLFloat flt_max(bool sign=false) { return Unpacked_t::flt_max(sign); } /** Returns the absolute value difference between 1.0 and the next representable value */ static constexpr TLFLOAT_INLINE TLFloat flt_epsilon() { return nextafter(TLFloat(1), 2) - 1; } /** Returns zero of the given sign */ static constexpr TLFLOAT_INLINE TLFloat zero(bool sign=false) { return Unpacked_t::zero(sign); } constexpr TLFLOAT_INLINE TLFloat() = default; constexpr TLFLOAT_INLINE TLFloat(const TLFloat&) = default; constexpr TLFLOAT_INLINE TLFloat& operator=(const TLFloat&) = default; constexpr TLFLOAT_INLINE Unpacked_t getUnpacked() const { return Unpacked_t(m); } static constexpr TLFLOAT_INLINE Unpacked_t to_Unpacked_t(TLFloat f = zero()) { return f.getUnpacked(); } template constexpr TLFLOAT_INLINE TLFloat(const detail::UnpackedFloat &tf) : m(mant_t(tf.cast((Unpacked_t *)0))) {} /** Cast from an instance of any TLFloat class */ template constexpr TLFLOAT_INLINE TLFloat(const TLFloat& s) : TLFloat(s.getUnpacked().cast((const Unpacked_t *)nullptr)) {} /** Cast from any primitive integer type */ template), int> = 0> constexpr TLFLOAT_INLINE TLFloat(const inttype x) : TLFloat(Unpacked_t::castFromInt(x)) {} /** Cast to any primitive integer type */ template), int> = 0> constexpr TLFLOAT_INLINE operator inttype() const { return getUnpacked().castToInt((const inttype *)nullptr); } template constexpr TLFLOAT_INLINE TLFloat(const BigInt x) : TLFloat(Unpacked_t::castFromInt(x)) {} template constexpr TLFLOAT_INLINE TLFloat(const BigUInt x) : TLFloat(Unpacked_t::castFromInt(x)) {} template constexpr TLFLOAT_INLINE operator BigInt () const { return getUnpacked().castToInt((const BigInt *)nullptr); } template constexpr TLFLOAT_INLINE operator BigUInt() const { return getUnpacked().castToInt((const BigUInt *)nullptr); } constexpr TLFloat(const double d) { if constexpr (sizeof(mant_t) == sizeof(double)) { m = std::bit_cast(d); } else { udouble td(d); m = mant_t(td.cast((const Unpacked_t *)nullptr)); } } constexpr TLFloat(const float f) { if constexpr (sizeof(mant_t) == sizeof(float)) { m = std::bit_cast(f); } else { ufloat tf(f); m = mant_t(tf.cast((const Unpacked_t *)nullptr)); } } /** Any non-integer object is bitcast to a TLFloat type of the same size with this constructor */ template && (std::is_floating_point_v || (!std::is_pointer_v && !std::is_integral_v))), int> = 0> constexpr TLFLOAT_INLINE TLFloat(const fptype& s) { m = std::bit_cast(s); } template && (std::is_floating_point_v || (!std::is_pointer_v && !std::is_integral_v))), int> = 0> explicit constexpr TLFLOAT_INLINE operator fptype() const { return std::bit_cast(m); } /** This works like strtod */ constexpr TLFloat(const char *ptr, const char **endptr=nullptr) { *this = TLFloat(xUnpacked_t(ptr, endptr).cast((Unpacked_t *)nullptr)); } explicit constexpr TLFLOAT_INLINE operator Unpacked_t() const { return Unpacked_t(m); } explicit constexpr operator double() const { if constexpr (sizeof(mant_t) == sizeof(double)) { return std::bit_cast(m); } else { Unpacked_t tf(m); return double(tf.cast((const udouble *)nullptr)); } } explicit constexpr operator float() const { if constexpr (sizeof(mant_t) == sizeof(float)) { return std::bit_cast(m); } else { Unpacked_t tf(m); return float(tf.cast((const ufloat *)nullptr)); } } constexpr TLFLOAT_INLINE TLFloat operator-() const { TLFloat n(*this); n.m ^= mant_t(1) << (sizeof(mant_t)*8-1); return n; } constexpr TLFLOAT_INLINE TLFloat operator+() const { return TLFloat(*this); } /** This function performs addition of two floating point numbers. This function returns correctly rounded results. */ constexpr TLFloat operator+(const TLFloat& rhs) const { return getUnpacked() + rhs.getUnpacked(); } /** This function performs subtraction of floating point numbers. This function returns correctly rounded results. */ constexpr TLFloat operator-(const TLFloat& rhs) const { return getUnpacked() - rhs.getUnpacked(); } /** This function performs multiplication of two floating point numbers. This function returns correctly rounded results. */ constexpr TLFloat operator*(const TLFloat& rhs) const { return getUnpacked() * rhs.getUnpacked(); } /** This function performs division of floating point numbers. This function returns correctly rounded results. */ constexpr TLFloat operator/(const TLFloat& rhs) const { return getUnpacked() / rhs.getUnpacked(); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ friend constexpr TLFloat fabs(const TLFloat& u) { TLFloat n(u); n.m &= ~(mant_t(1) << (sizeof(mant_t)*8-1)); return n; } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ friend constexpr TLFloat copysign(const TLFloat& x, const TLFloat& y) { TLFloat n(x); n.m &= ~(mant_t(1) << (sizeof(mant_t)*8-1)); n.m |= y.m & (mant_t(1) << (sizeof(mant_t)*8-1)); return n; } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ friend constexpr TLFloat fmax(const TLFloat& x, const TLFloat& y) { return isnan(y) ? x : (x > y ? x : y); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ friend constexpr TLFloat fmin(const TLFloat& x, const TLFloat& y) { return isnan(y) ? x : (x < y ? x : y); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ friend constexpr TLFloat fdim(const TLFloat& x, const TLFloat& y) { TLFloat ret = x - y; if (ret < 0 || x == y) ret = 0; return ret; } /** This function has the same functionality as the corresponding function in math.h. */ friend constexpr bool isnan(const TLFloat& u) { return u.getUnpacked().isnan; } /** This function has the same functionality as the corresponding function in math.h. */ friend constexpr bool isinf(const TLFloat& u) { return u.getUnpacked().isinf; } /** This function has the same functionality as the corresponding function in math.h. */ friend constexpr bool finite(const TLFloat& u) { return !(isnan(u) || isinf(u)); } /** This function has the same functionality as the corresponding function in math.h. */ friend constexpr int fpclassify(const TLFloat& u) { if (isnan(u)) return TLFLOAT_FP_NAN; if (isinf(u)) return TLFLOAT_FP_INFINITE; if (u == 0) return TLFLOAT_FP_ZERO; if (fabs(u) < u.getUnpacked().flt_min()) return TLFLOAT_FP_SUBNORMAL; return TLFLOAT_FP_NORMAL; } /** This function has the same functionality as the corresponding function in math.h. */ friend constexpr TLFLOAT_INLINE bool signbit(const TLFloat& u) { TLFloat n(u); return Unpacked_t::bit(n.m, sizeof(mant_t) * 8 - 1); } friend constexpr TLFLOAT_INLINE bool iszero(const TLFloat& u) { return u.getUnpacked().iszero; } friend constexpr TLFLOAT_INLINE bool isint(const TLFloat& u) { return isint(u.getUnpacked()); } friend constexpr TLFLOAT_INLINE bool iseven(const TLFloat& u) { return iseven(u.getUnpacked()); } /** This function performs the fused multiply-add operation of floating point numbers. This function returns correctly rounded results. */ friend constexpr TLFloat fma(const TLFloat& x, const TLFloat& y, const TLFloat& z) { return Unpacked_t::fma(x.getUnpacked(), y.getUnpacked(), z.getUnpacked()); } /** This function performs ordered comparison of two floating point numbers. */ constexpr TLFLOAT_INLINE bool operator==(const TLFloat& rhs) const { return getUnpacked() == rhs.getUnpacked(); } /** This function performs ordered comparison of two floating point numbers. */ constexpr TLFLOAT_INLINE bool operator!=(const TLFloat& rhs) const { return getUnpacked() != rhs.getUnpacked(); } /** This function performs ordered comparison of two floating point numbers. */ constexpr TLFLOAT_INLINE bool operator> (const TLFloat& rhs) const { return getUnpacked() > rhs.getUnpacked(); } /** This function performs ordered comparison of two floating point numbers. */ constexpr TLFLOAT_INLINE bool operator< (const TLFloat& rhs) const { return getUnpacked() < rhs.getUnpacked(); } /** This function performs ordered comparison of two floating point numbers. */ constexpr TLFLOAT_INLINE bool operator>=(const TLFloat& rhs) const { return getUnpacked() >= rhs.getUnpacked(); } /** This function performs ordered comparison of two floating point numbers. */ constexpr TLFLOAT_INLINE bool operator<=(const TLFloat& rhs) const { return getUnpacked() <= rhs.getUnpacked(); } // template constexpr TLFLOAT_INLINE TLFloat& operator=(const srctype& s) { TLFloat n(s); *this = n; return *this; } template constexpr TLFLOAT_INLINE TLFloat& operator+=(const rhstype& rhs) { *this = *this + TLFloat(rhs); return *this; } template constexpr TLFLOAT_INLINE TLFloat& operator-=(const rhstype& rhs) { *this = *this - TLFloat(rhs); return *this; } template constexpr TLFLOAT_INLINE TLFloat& operator*=(const rhstype& rhs) { *this = *this * TLFloat(rhs); return *this; } template constexpr TLFloat& operator/=(const rhstype& rhs) { *this = *this / TLFloat(rhs); return *this; } constexpr TLFLOAT_INLINE TLFloat& operator++() { *this += 1; return *this; } constexpr TLFLOAT_INLINE TLFloat& operator--() { *this -= 1; return *this; } constexpr TLFLOAT_INLINE TLFloat operator++(int) { TLFloat t = *this; *this += 1; return t; } constexpr TLFLOAT_INLINE TLFloat operator--(int) { TLFloat t = *this; *this -= 1; return t; } // // Double + int, Double + float, Double + Float template || sizeof(rhstype) <= sizeof(mant_t)), int> = 0> constexpr TLFLOAT_INLINE TLFloat operator+(const rhstype& rhs) const { return *this + TLFloat(rhs); } template || sizeof(rhstype) <= sizeof(mant_t)), int> = 0> constexpr TLFLOAT_INLINE TLFloat operator-(const rhstype& rhs) const { return *this - TLFloat(rhs); } template || sizeof(rhstype) <= sizeof(mant_t)), int> = 0> constexpr TLFLOAT_INLINE TLFloat operator*(const rhstype& rhs) const { return *this * TLFloat(rhs); } template || sizeof(rhstype) <= sizeof(mant_t)), int> = 0> constexpr TLFloat operator/(const rhstype& rhs) const { return *this / TLFloat(rhs); } // int + Double, float + Double, Float + Double template || sizeof(lhstype) <= sizeof(mant_t)), int> = 0> friend constexpr TLFLOAT_INLINE TLFloat operator+(const lhstype& lhs, const TLFloat &rhs) { return TLFloat(lhs) + rhs; } template || sizeof(lhstype) <= sizeof(mant_t)), int> = 0> friend constexpr TLFLOAT_INLINE TLFloat operator-(const lhstype& lhs, const TLFloat &rhs) { return TLFloat(lhs) - rhs; } template || sizeof(lhstype) <= sizeof(mant_t)), int> = 0> friend constexpr TLFLOAT_INLINE TLFloat operator*(const lhstype& lhs, const TLFloat &rhs) { return TLFloat(lhs) * rhs; } template || sizeof(lhstype) <= sizeof(mant_t)), int> = 0> friend constexpr TLFloat operator/(const lhstype& lhs, const TLFloat &rhs) { return TLFloat(lhs) / rhs; } // Double == int, Double == float, Double == Float template || sizeof(rhstype) <= sizeof(mant_t)), int> = 0> constexpr TLFLOAT_INLINE bool operator==(const rhstype& rhs) const { return *this == TLFloat(rhs); } template || sizeof(rhstype) <= sizeof(mant_t)), int> = 0> constexpr TLFLOAT_INLINE bool operator!=(const rhstype& rhs) const { return *this != TLFloat(rhs); } template || sizeof(rhstype) <= sizeof(mant_t)), int> = 0> constexpr TLFLOAT_INLINE bool operator> (const rhstype& rhs) const { return *this > TLFloat(rhs); } template || sizeof(rhstype) <= sizeof(mant_t)), int> = 0> constexpr TLFLOAT_INLINE bool operator< (const rhstype& rhs) const { return *this < TLFloat(rhs); } template || sizeof(rhstype) <= sizeof(mant_t)), int> = 0> constexpr TLFLOAT_INLINE bool operator>=(const rhstype& rhs) const { return *this >= TLFloat(rhs); } template || sizeof(rhstype) <= sizeof(mant_t)), int> = 0> constexpr TLFLOAT_INLINE bool operator<=(const rhstype& rhs) const { return *this <= TLFloat(rhs); } // int == Double, float == Double, Float == Double template || sizeof(lhstype) <= sizeof(mant_t)), int> = 0> friend constexpr TLFLOAT_INLINE bool operator==(const lhstype& lhs, const TLFloat &rhs) { return TLFloat(lhs) == rhs; } template || sizeof(lhstype) <= sizeof(mant_t)), int> = 0> friend constexpr TLFLOAT_INLINE bool operator!=(const lhstype& lhs, const TLFloat &rhs) { return TLFloat(lhs) != rhs; } template || sizeof(lhstype) <= sizeof(mant_t)), int> = 0> friend constexpr TLFLOAT_INLINE bool operator> (const lhstype& lhs, const TLFloat &rhs) { return TLFloat(lhs) > rhs; } template || sizeof(lhstype) <= sizeof(mant_t)), int> = 0> friend constexpr TLFLOAT_INLINE bool operator< (const lhstype& lhs, const TLFloat &rhs) { return TLFloat(lhs) < rhs; } template || sizeof(lhstype) <= sizeof(mant_t)), int> = 0> friend constexpr TLFLOAT_INLINE bool operator>=(const lhstype& lhs, const TLFloat &rhs) { return TLFloat(lhs) >= rhs; } template || sizeof(lhstype) <= sizeof(mant_t)), int> = 0> friend constexpr TLFLOAT_INLINE bool operator<=(const lhstype& lhs, const TLFloat &rhs) { return TLFloat(lhs) <= rhs; } // /** This function has the same functionality as the corresponding function in math.h. */ friend constexpr int32_t ilogb(const TLFloat& f) { auto u = f.getUnpacked(); if (u.isinf) return 2147483647; if (u.isnan) return TLFLOAT_FP_ILOGBNAN; if (u.exp != 0) return u.exp - Unpacked_t::expoffset() + 1; if (u.mant == 0) return TLFLOAT_FP_ILOGB0; return (sizeof(mant_t) * 8 - Unpacked_t::nbmant_()) - Unpacked_t::clz(u.mant) - Unpacked_t::expoffset(); } friend constexpr xpair frexp(const TLFloat& f) { if (f == 0 || isnan(f) || isinf(f)) return xpair { f, 0 }; auto p = frexp_(f.getUnpacked().cast((xUnpacked_t *)0)); return xpair { (TLFloat)p.first.cast((Unpacked_t *)0), p.second }; } /** This function has the same functionality as the corresponding function in math.h. */ friend constexpr TLFloat frexp(const TLFloat& f, int *exp) { auto p = frexp(f); if (exp) *exp = p.second; return p.first; } /** This function has the same functionality as the corresponding function in math.h. */ friend constexpr TLFloat ldexp(const TLFloat& f, int exp) { return (TLFloat)ldexp_(f.getUnpacked().cast((xUnpacked_t *)0), exp).cast((Unpacked_t *)0); } /** Returns 10^a */ static constexpr TLFloat exp10i(int a) { return TLFloat(Unpacked_t::exp10i(a)); } /** This function finds the square root of a floating point number. This function returns correctly rounded results. */ friend constexpr TLFloat sqrt(const TLFloat& d) { if (d < 0) return nan(); if (isinf(d) || isnan(d)) return d; if (d.getUnpacked().iszero) return d; return TLFloat(sqrt_(d.getUnpacked())); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ friend constexpr TLFloat hypot(const TLFloat& x, const TLFloat& y) { auto xx = x.getUnpacked().cast((xUnpacked_t *)0); auto yy = y.getUnpacked().cast((xUnpacked_t *)0); if (xx.isinf || yy.isinf) return infinity(false); if (xx.isnan || yy.isnan) return nan(); return sqrt_(xx * xx + yy * yy).cast((Unpacked_t *)0); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ friend constexpr TLFloat trunc(const TLFloat& d) { return (TLFloat)trunc(d.getUnpacked()); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ friend constexpr TLFloat floor(const TLFloat& d) { return (TLFloat)floor(d.getUnpacked()); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ friend constexpr TLFloat ceil (const TLFloat& d) { return (TLFloat)ceil (d.getUnpacked()); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ friend constexpr TLFloat round(const TLFloat& d) { return (TLFloat)round(d.getUnpacked()); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ friend constexpr TLFloat rint (const TLFloat& d) { return (TLFloat)rint (d.getUnpacked()); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ friend constexpr TLFloat modf(const TLFloat& x, TLFloat* iptr) { if (isnan(x) || iszero(x)) { *iptr = x; return x; } if (isinf(x)) { *iptr = x; return zero(signbit(x)); } TLFloat i = trunc(x); if (iptr) *iptr = i; return x - i; } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ friend constexpr TLFloat nextafter(const TLFloat& x, const TLFloat& y) { if (isnan(x)) return x; if (isnan(y)) return y; int c = cmp(x.getUnpacked(), y.getUnpacked()), i = signbit(x) ? 1 : -1; TLFloat r = x; if (iszero(x)) { if (c > 0) { r.m = (mant_t(1) << (sizeof(mant_t)*8-1)) + 1; } else if (c < 0) { r.m = 1; } else { r = y; } } else { r.m += c * i; } return r; } }; // class TLFloat // #if defined(TLFLOAT_DOXYGEN) || !defined(TLFLOAT_NO_LIBSTDCXX) #ifndef TLFLOAT_DOXYGEN template static std::string to_string_d(const detail::UnpackedFloat &uf) { std::string s; char buf[32]; snprintf(buf, sizeof(buf), "%.18lg", to_double(uf)); s += std::string(buf) + " : "; s += "sign = " + std::to_string(uf.sign); s += ", iszero = " + std::to_string(uf.iszero); s += ", isinf = " + std::to_string(uf.isinf); s += ", isnan = " + std::to_string(uf.isnan); s += ", exp = " + std::to_string(uf.exp - uf.expoffset()) + "(" + std::to_string(uf.exp) + ")"; s += std::string(", mant = ") + toHexString(uf.mant); return s; } template static std::string to_string(Unpacked_t u, int d=6) { typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; std::vector buf(1000); snprint(buf.data(), buf.size(), u.cast((xUnpacked_t *)0), 'g', 0, d, false, false, false, false, false, false); return std::string(buf.data()); } #endif /** This works like sprintf(str, "%.6g", *this) where the precision can be specified with d */ template static std::string to_string(TLFloat a, int d=6) { typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; std::vector buf(1000); snprint(buf.data(), buf.size(), a.getUnpacked().cast((xUnpacked_t *)0), 'g', 0, d, false, false, false, false, false, false); return std::string(buf.data()); } template static std::ostream& operator<<(std::ostream &os, const TLFloat& a) { typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; std::vector buf(1000); std::ios_base::fmtflags f = os.flags(); char typespec = 'g'; if ((f & os.fixed) != 0) typespec = 'f'; if ((f & os.hex) != 0) typespec = 'a'; snprint(buf.data(), buf.size(), a.getUnpacked().cast((xUnpacked_t *)0), typespec, os.width(), os.precision(), false, false, false, (f & std::ios::left) != 0, false, (f & std::ios::uppercase) != 0); return os << buf.data(); } #endif // #if defined(TLFLOAT_DOXYGEN) || !defined(TLFLOAT_NO_LIBSTDCXX) // typedef TLFloat> BFloat16; ///< This class represents a BFloat16 floating-point number. The data size and data structure of the objects are the same as the corresponding floating-point number. typedef TLFloat> Half; ///< This class represents a half-precision IEEE 754 floating-point number. The data size and data structure of the objects are the same as the corresponding floating-point number. typedef TLFloat> Float; ///< This class represents a single-precision IEEE 754 floating-point number. The data size and data structure of the objects are the same as the corresponding floating-point number. typedef TLFloat, 11, 52>> Double; ///< This class represents a double-precision IEEE 754 floating-point number. The data size and data structure of the objects are the same as the corresponding floating-point number. typedef TLFloat, BigUInt<8>, 15, 112>> Quad; ///< This class represents a quadruple-precision IEEE 754 floating-point number. The data size and data structure of the objects are the same as the corresponding floating-point number. typedef TLFloat, BigUInt<9>, 19, 236>> Octuple; ///< This class represents a octuple-precision IEEE 754 floating-point number. The data size and data structure of the objects are the same as the corresponding floating-point number. static_assert(sizeof(BFloat16) == 2); static_assert(sizeof(Half) == 2); static_assert(sizeof(Float) == 4); static_assert(sizeof(Double) == 8); static_assert(sizeof(Quad) == 16); static_assert(sizeof(Octuple) == 32); static_assert(std::is_trivially_copyable_v); static_assert(std::is_trivially_copyable_v); static_assert(std::is_trivially_copyable_v); static_assert(std::is_trivially_copyable_v); static_assert(std::is_trivially_copyable_v); static_assert(std::is_trivially_copyable_v); } // namespace tlfloat #endif // #ifndef __TLFLOAT_HPP_INCLUDED__ tlfloat-1.15.0/src/include/tlfloat/tlfloatconfig.hpp.in000066400000000000000000000010121477036600700230770ustar00rootroot00000000000000#ifndef __TLFLOATVERSION_HPP_INCLUDED__ #define __TLFLOATVERSION_HPP_INCLUDED__ #define TLFLOAT_VERSION_MAJOR @TLFLOAT_VERSION_MAJOR@ #define TLFLOAT_VERSION_MINOR @TLFLOAT_VERSION_MINOR@ #define TLFLOAT_VERSION_PATCH @TLFLOAT_VERSION_PATCH@ #cmakedefine TLFLOAT_COMPILER_SUPPORTS_INT128 #cmakedefine TLFLOAT_COMPILER_SUPPORTS_ISOFLOAT128 #cmakedefine TLFLOAT_COMPILER_SUPPORTS_FLOAT128 #cmakedefine TLFLOAT_LONGDOUBLE_IS_FLOAT128 #cmakedefine TLFLOAT_COMPILER_SUPPORTS_FP16 #cmakedefine TLFLOAT_ENABLE_INTSQRT #endif tlfloat-1.15.0/src/include/tlfloat/tlmath.hpp000066400000000000000000002701551477036600700211500ustar00rootroot00000000000000#ifndef __TLMATH_HPP_INCLUDED__ #define __TLMATH_HPP_INCLUDED__ #include #include #include #if defined(__clang_major__) && !defined(_MSC_VER) #if __clang_major__ < 17 #warning Unsupported clang version #endif #endif namespace tlfloat { namespace detail { typedef UnpackedFloat xhalf; typedef UnpackedFloat xfloat; typedef UnpackedFloat, 0, 62> xdouble; typedef UnpackedFloat, BigUInt<8>, 0, 126> xquad; typedef UnpackedFloat, BigUInt<9>, 0, 254> xoctuple; typedef UnpackedFloat, BigUInt<10>, 0, 510> xsedecuple; // template static consteval Unpacked_t constSqrt2O2() { return ldexp_(sqrt_(Unpacked_t(2)), -1); } template static consteval Unpacked_t constOneOthree() { return Unpacked_t(1) / Unpacked_t(3); } template static consteval Unpacked_t constRSqrtPI() { return Unpacked_t(1) / sqrt_(const_M_PI_()); } template static consteval T constLNPI() { return T("0x1.250d048e7a1bd0bd5f956c6a843f49985e6ddbf3b3f2606e33802ecaefa9308e5aa6c4df523160e6d2402c256db0b866738aa8787561937377769e99dceda3bfp+0"); } template static consteval T constLN2PI() { return T("0x1.d67f1c864beb4a6929792002883240479f611f1a268b169bbd8d46267b542aba425f3affc01d0d7f27d57f20b8aad37760b956ae3699b4b79ecdd9c2ee575be5p+0"); } template static consteval T constLN2() { return T("0x1.62e42fefa39ef35793c7673007e5ed5e81e6864ce5316c5b141a2eb71755f457cf70ec40dbd75930ab2aa5f695f43621da5d5c6b827042884eae765222d37048p-1"); } template static consteval T upper(T v) { typedef decltype(T::mant) mant_t; v.mant &= ~((mant_t(1) << (sizeof(mant_t)*8/2)) - 1); return v; } template static consteval T constLN2U() { return upper(constLN2()); } template static consteval T constLN2L() { return (constLN2() - constLN2U().cast((const xsedecuple *)nullptr)).cast((const T *)nullptr); } template static consteval T constLN10() { return T("0x1.26bb1bbb5551582dd4adac5705a61451c51fd9f3b4bbf21d078c3d0403e05ae52c5e05af635020b998e1978058be1ad058c448308217c5b5f71ef10805ca2dacp+1"); } template static consteval T constRLN2() { return T("0x1.71547652b82fe1777d0ffda0d23a7d11d6aef551bad2b4b1164a2cd9a342648fbc3887eeaa2ed9ac49b25eeb82d7c167d52173cc1895213f897f5e06a7be7368p+0"); } template static consteval T constRLN10() { return T("0x1.bcb7b1526e50e32a6ab7555f5a67b8647dc68c048b934404747e5a89ef1d4a78ea849df42805e7e52446ab258c8c942a319c77b3fa71b978df4571a5919b4f6p-2"); } template static consteval T constCbrt2() { return T("0x1.428a2f98d728ae223ddab715be250d0c288f10291631fbc061800cc36fa2dd3a60b7d03da26f0840f25cc16b0f95075c30967a6b5ac6827ab31f06edf4a3486cp+0"); } template static consteval T constCbrt4() { return T("0x1.965fea53d6e3c82b05999ab43dc4def1980762158a0a815f2291ac0cf93041e5875f13657a43adc3896c0b95c0244e271d6f695f41523046622bc574b2caeaecp+0"); } template static consteval T constEuler() { return T("0x9.3c467e37db0c7a4d1be3f810152cb56a1cecc3af65cc0190c03df34709affbd8e4b59fa03a9f0eed0649ccb621057d11056ae9132135a08e43b4673d74bafea5p-4"); } // template static consteval xarray genSinCoef() { xarray a; for(unsigned k=0;k static consteval xarray genCosCoef() { xarray a; for(unsigned k=0;k static consteval xarray genTanCoef() { xarray a; for(unsigned k=0;k static consteval xarray genAtanCoef() { xarray a; for(unsigned k=0;k static consteval xarray genExpCoef() { xarray a; for(unsigned k=0;k static consteval xarray genLogCoef() { xarray a; for(unsigned k=0;k static consteval xarray genCbrtCoef() { xarray a; for(unsigned k=0;k static consteval xarray genGammaCoef() { xarray a; for(unsigned k=0;k static constexpr xpair ph(const Unpacked_t &ux, int p) { typedef decltype(ux.mant) mant_t; typedef decltype(Unpacked_t::longmant_t_()) longmant_t; if (ux.iszero || ux.exp < Unpacked_t::expoffset()-5) return xpair(ux, 0); const int mantexp = ux.exp - Unpacked_t::expoffset() - Unpacked_t::nbmant_() + 1; const int m = (mantexp - 1) < 0 ? 0 : (mantexp - 1); int rpiexp = p - (m & ~7) - sizeof(mant_t) * 8; longmant_t rpih = 0, rpil = 0; for(unsigned i=0;i> (sizeof(mant_t) * 8)); int q = 0; if (-(mantexp + rpiexp) < (int)sizeof(longmant_t)*8) { longmant_t qm = (rm + (longmant_t(1) << (-(mantexp + rpiexp) - 1))) & (~longmant_t(0) << -(mantexp + rpiexp)); rm -= qm; q = int(qm >> -(mantexp + rpiexp)); } int exp = mantexp + rpiexp - p; for(unsigned j=sizeof(mant_t) * 2;Unpacked_t::clz(rm) > sizeof(mant_t) * 8 || Unpacked_t::clz(~rm) > sizeof(mant_t) * 8;j += sizeof(mant_t)) { rm = (rm << (sizeof(mant_t) * 8)) + ((ux.mant * rpil) & ((longmant_t(1) << (sizeof(mant_t) * 8)) - 1)); rpil = 0; for(unsigned i=0;i> (sizeof(mant_t) * 8)); exp -= sizeof(mant_t) * 8; } bool sign = ux.sign; if (rm >> (sizeof(rm) * 8 - 1)) { rm = -rm; q = -q; sign = !sign; } int x = sizeof(rm) * 8 - Unpacked_t::clz(rm); int s = Unpacked_t::nbmant_() - (x - 1); mant_t u = mant_t(s >= 0 ? (rm << s) : ((rm + (mant_t(1) << (-s - 1))) >> -s)); if (Unpacked_t::bit(u, Unpacked_t::nbmant_() + 1)) { u >>= 1; x++; } Unpacked_t r = Unpacked_t(u, x + Unpacked_t::expoffset() - 2 + exp, false, false, false, false) * const_M_PI_(); return xpair(sign ? -r : r, sign ? -q & 0xff : q & 0xff); } // template static constexpr Unpacked_t sin_(const Unpacked_t& a) { const xpair p = ph(a, 1); Unpacked_t d = Unpacked_t(0); if (p.second & 1) { constexpr xarray cosCoef = genCosCoef(); d = cosCoef.e[N+1]; for(int i=N-0;i>=0;i--) d = Unpacked_t::fma(d, -p.first * p.first, cosCoef.e[i]); } else { constexpr xarray sinCoef = genSinCoef(); d = sinCoef.e[N]; for(int i=N-1;i>=0;i--) d = Unpacked_t::fma(d, -p.first * p.first, sinCoef.e[i]); d *= p.first; } return (p.second & 2) ? -d : d; } template static constexpr tlfloat_t sin(const tlfloat_t& a) { if (isnan(a)) return a; if (isinf(a)) return tlfloat_t::nan(); auto y = sin_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); return tlfloat_t(y.cast((const decltype(a.getUnpacked()) *)nullptr)); } template static constexpr Unpacked_t cos_(const Unpacked_t& a) { const xpair p = ph(a, 1); Unpacked_t d = Unpacked_t(0); if (p.second & 1) { constexpr xarray sinCoef = genSinCoef(); d = sinCoef.e[N]; for(int i=N-1;i>=0;i--) d = Unpacked_t::fma(d, -p.first * p.first, sinCoef.e[i]); d *= -p.first; } else { constexpr xarray cosCoef = genCosCoef(); d = cosCoef.e[N+1]; for(int i=N-0;i>=0;i--) d = Unpacked_t::fma(d, -p.first * p.first, cosCoef.e[i]); } return (p.second & 2) ? -d : d; } template static constexpr tlfloat_t cos(const tlfloat_t& a) { if (isnan(a)) return a; if (isinf(a)) return tlfloat_t::nan(); auto y = cos_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); return tlfloat_t(y.cast((const decltype(a.getUnpacked()) *)nullptr)); } // template static constexpr xpair tan_(const Unpacked_t& a) { const xpair p = ph(a, 1); Unpacked_t x = ldexp_(p.first, -1-int(M)), y; constexpr xarray tanCoef = genTanCoef(); Unpacked_t d = tanCoef.e[N-1]; for(int i=N-1;i>0;i--) d = Unpacked_t::fma(d, x * x, tanCoef.e[i-1]); d *= x; if constexpr (M > 0) { for(unsigned i=0;i { x, y }; } template static constexpr tlfloat_t tan(const tlfloat_t& a) { if (isnan(a)) return a; if (isinf(a)) return tlfloat_t::nan(); auto y = tan_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); return tlfloat_t((y.first / y.second).cast((const decltype(a.getUnpacked()) *)nullptr)); } // template static constexpr Unpacked_t sinpi_(const Unpacked_t& a) { constexpr xarray sinCoef = genSinCoef(); const Unpacked_t p = const_M_PI_() * a; Unpacked_t d = sinCoef.e[N]; for(int i=N-1;i>=0;i--) d = Unpacked_t::fma(d, -p * p, sinCoef.e[i]); return d * -p; } template static constexpr Unpacked_t cospi_(const Unpacked_t& a) { constexpr xarray cosCoef = genCosCoef(); const Unpacked_t p = const_M_PI_() * a; Unpacked_t d = cosCoef.e[N+1]; for(int i=N-0;i>=0;i--) d = Unpacked_t::fma(d, -p * p, cosCoef.e[i]); return d; } template static constexpr tlfloat_t sinpi(const tlfloat_t& a) { if (isnan(a) || iszero(a)) return a; if (isinf(a)) return tlfloat_t::nan(); auto x = ldexp_(a.getUnpacked().cast((const Unpacked_t *)nullptr), 1), y = ldexp_(x - round(x), -1); int lx = intlsb(ldexp_(x, 1)); if (((lx >= 0 && (lx & 3) == 0) || (lx < 0 && (lx & 3) == 3)) && isint(x)) return Unpacked_t::zero(x.sign); Unpacked_t z = ((lx+3)&2) ? sinpi_(y) : cospi_(y); if ((lx+7)&4) z.sign = !z.sign; return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t cospi(const tlfloat_t& a) { if (isnan(a)) return a; if (isinf(a)) return tlfloat_t::nan(); auto x = ldexp_(a.getUnpacked().cast((const Unpacked_t *)nullptr), 1), y = ldexp_(x - round(x), -1); int lx = intlsb(ldexp_(x, 1)); if (!((lx+3)&2) && y.iszero) return Unpacked_t::zero(false); Unpacked_t z = ((lx+3)&2) ? cospi_(y) : sinpi_(y); if ((lx+1)&4) z.sign = !z.sign; return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t tanpi(const tlfloat_t& a) { if (isnan(a) || iszero(a)) return a; if (isinf(a)) return tlfloat_t::nan(); auto x = ldexp_(a.getUnpacked().cast((const Unpacked_t *)nullptr), 1), y = ldexp_(x - round(x), -1); int lx = intlsb(ldexp_(x, 1)); if (((lx >= 0 && (lx & 3) == 0) || (lx < 0 && (lx & 3) == 3)) && isint(x)) return Unpacked_t::zero(lx & 4); auto p = tan_(const_M_PI_() * y); auto z = ((lx+1)&2) ? p.second / p.first : p.first / p.second; if (z.isinf) z.sign = !(lx & 4); if ((lx+1)&2) z.sign = !z.sign; return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } // template static constexpr Unpacked_t atan2_(Unpacked_t y, Unpacked_t x) { constexpr xarray atanCoef = genAtanCoef(); int q = 0; if (fabs(y) > fabs(x)) { Unpacked_t t = x; x = y; y = -t; q = x.sign ? -1 : 1; } else if (x.sign) { q = y.sign? -2 : 2; } Unpacked_t d = y / x, r = atanCoef.e[N]; for(unsigned i=0;i=0;i--) r = Unpacked_t::fma(r, d * d, atanCoef.e[i]); r *= d; Unpacked_t qu = Unpacked_t(q); if (q == 0) qu.sign = r.sign; if (x.iszero) { r = Unpacked_t(0); qu.sign = r.sign = y.sign; } return Unpacked_t::fma(qu, ldexp_(const_M_PI_(), -1), ldexp_(r, M)); } template static constexpr tlfloat_t atan2(tlfloat_t y, tlfloat_t x) { if (isnan(y)) return y; if (isnan(x)) return x; if (int(isinf(y)) | isinf(x)) { y = isinf(y) ? (signbit(y) ? -1 : 1) : (signbit(y) ? -0.0 : +0.0); x = isinf(x) ? (signbit(x) ? -1 : 1) : (signbit(x) ? -0.0 : +0.0); } Unpacked_t z = atan2_(y.getUnpacked().cast((const Unpacked_t *)nullptr), x.getUnpacked().cast((const Unpacked_t *)nullptr)); return tlfloat_t(z.cast((const decltype(x.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t atan(const tlfloat_t &a) { if (isnan(a)) return a; Unpacked_t y = isinf(a) ? Unpacked_t(signbit(a) ? -1 : 1) : a.getUnpacked().cast((const Unpacked_t *)nullptr); Unpacked_t x = Unpacked_t(isinf(a) ? 0 : 1); Unpacked_t z = atan2_(y, x); return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t asin(const tlfloat_t &a) { if (isnan(a)) return a; if (fabs(a) > 1) return tlfloat_t::nan(); Unpacked_t y = a.getUnpacked().cast((const Unpacked_t *)nullptr); Unpacked_t x = sqrt_((Unpacked_t(1) + y) * (Unpacked_t(1) - y)); Unpacked_t z = atan2_(y, x); return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t acos(const tlfloat_t &a) { if (isnan(a)) return a; if (fabs(a) > 1) return tlfloat_t::nan(); Unpacked_t x = a.getUnpacked().cast((const Unpacked_t *)nullptr); Unpacked_t y = sqrt_((Unpacked_t(1) + x) * (Unpacked_t(1) - x)); Unpacked_t z = atan2_(y, x); return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } // template static constexpr Unpacked_t exp_(Unpacked_t d) { constexpr xarray expCoef = genExpCoef(); if (d.exp > 28) return d.sign ? Unpacked_t(0) : Unpacked_t::infinity(); int64_t q = rint(d * constRLN2()).castToInt((int64_t *)nullptr); d = Unpacked_t::fma(Unpacked_t::castFromInt(-q), constLN2U(), d); d = Unpacked_t::fma(Unpacked_t::castFromInt(-q), constLN2L(), d); d = ldexp_(d, -M); Unpacked_t s = expCoef.e[N+1]; for(int i=N;i>=0;i--) s = Unpacked_t::fma(s, d, expCoef.e[i]); if constexpr (M > 0) for(unsigned i=0;i static constexpr Unpacked_t expm1_(Unpacked_t d) { constexpr xarray expCoef = genExpCoef(); if (d.iszero) return d; if (d.exp > 28) return d.sign ? Unpacked_t(-1) : Unpacked_t::infinity(); int64_t q = rint(d * constRLN2()).castToInt((int64_t *)nullptr); d = Unpacked_t::fma(Unpacked_t::castFromInt(-q), constLN2U(), d); d = Unpacked_t::fma(Unpacked_t::castFromInt(-q), constLN2L(), d); d = ldexp_(d, -M); Unpacked_t s = expCoef.e[N+1]; for(int i=N;i>=1;i--) s = Unpacked_t::fma(s, d, expCoef.e[i]); s *= d; if constexpr (M > 0) for(unsigned i=0;i static constexpr tlfloat_t exp(const tlfloat_t &a) { if (isnan(a)) return a; if (isinf(a) && signbit(a)) return 0; Unpacked_t z = exp_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t exp(const tlfloat_t &a, const Unpacked_t &SCALE) { if (isnan(a)) return a; if (isinf(a) && signbit(a)) return 0; Unpacked_t z = exp_(a.getUnpacked().cast((const Unpacked_t *)nullptr) * SCALE); return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t expm1(const tlfloat_t &a) { if (isnan(a)) return a; if (isinf(a) && signbit(a)) return -1; Unpacked_t z = expm1_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } // template static constexpr Unpacked_t log_(Unpacked_t d) { constexpr xarray logCoef = genLogCoef(); xpair p = frexp_(d); Unpacked_t fr = p.first; int e = p.second, m = 0; if (fr < constSqrt2O2()) { fr.exp++; e--; } if constexpr (M > 0) { if (fabs(fr - Unpacked_t(1)).ilogb() > T) { for(unsigned i=0;i=0;i--) y = Unpacked_t::fma(y, x*x, logCoef.e[i]); y *= x; y = Unpacked_t::fma(Unpacked_t(e), constLN2L(), ldexp_(y, m)); return Unpacked_t::fma(Unpacked_t(e), constLN2U(), y); } template static constexpr tlfloat_t log(const tlfloat_t &a) { if (isnan(a)) return a; if (a == 0) return tlfloat_t::infinity(true); if (signbit(a)) return tlfloat_t::nan(); if (isinf(a)) return tlfloat_t::infinity(); Unpacked_t z = log_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t log(const tlfloat_t &a, const Unpacked_t &SCALE) { if (isnan(a)) return a; if (a == 0) return tlfloat_t::infinity(true); if (signbit(a)) return tlfloat_t::nan(); if (isinf(a)) return tlfloat_t::infinity(); Unpacked_t z = log_(a.getUnpacked().cast((const Unpacked_t *)nullptr)) * SCALE; return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } template static constexpr Unpacked_t log1p_(Unpacked_t d) { constexpr xarray logCoef = genLogCoef(); xpair p = frexp_(d + Unpacked_t(1)); Unpacked_t fr = p.first; int e = p.second; if (fr < constSqrt2O2()) { fr.exp++; e--; } fr = e == 0 ? d : (fr - Unpacked_t(1)); if constexpr (M > 0) for(unsigned i=0;i=0;i--) y = Unpacked_t::fma(y, x*x, logCoef.e[i]); y *= x; y = Unpacked_t::fma(Unpacked_t(e), constLN2L(), ldexp_(y, M)); return Unpacked_t::fma(Unpacked_t(e), constLN2U(), y); } template static constexpr tlfloat_t log1p(const tlfloat_t &a) { if (isnan(a) || a == 0) return a; if (a == -1) return tlfloat_t::infinity(true); if (a < -1) return tlfloat_t::nan(); if (isinf(a)) return tlfloat_t::infinity(); Unpacked_t z = log1p_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } // template static constexpr tlfloat_t pow(const tlfloat_t &x, const tlfloat_t &y) { if (signbit(x) && finite(x) && !iszero(x) && finite(y) && !isint(y)) return tlfloat_t::nan(); if (x == 1 || iszero(y)) return 1; if (isnan(x)) return x; if (isnan(y)) return y; bool yisoddint = isint(y) && !iseven(y); if (!signbit(y) && !iszero(y) && iszero(x) && yisoddint) return tlfloat_t::zero(signbit(x)); if (iszero(x) && !signbit(y) && !iszero(y) && !yisoddint) return 0; if (isinf(y) && x == -1) return 1; bool absxlt1 = -1 < x && x < 1; if (isinf(y) && signbit(y) && absxlt1) return tlfloat_t::infinity(); bool absxgt1 = x < -1 || 1 < x; if (isinf(y) && signbit(y) && absxgt1) return 0; if (isinf(y) && !signbit(y) && absxlt1) return 0; if (isinf(y) && !signbit(y) && absxgt1) return tlfloat_t::infinity(); if (isinf(x) && signbit(x) && yisoddint && signbit(y)) return tlfloat_t::zero(true); if (isinf(x) && signbit(x) && signbit(y) && !iszero(y) && !yisoddint) return 0; if (isinf(x) && signbit(x) && !signbit(y) && yisoddint) return tlfloat_t::infinity(true); if (isinf(x) && signbit(x) && !signbit(y) && !iszero(y) && !yisoddint) return tlfloat_t::infinity(false); if (isinf(x) && !signbit(x) && signbit(y) && !iszero(y)) return 0; if (isinf(x) && !signbit(x) && !signbit(y) && !iszero(y)) return tlfloat_t::infinity(false); if (iszero(x) && yisoddint && signbit(y)) return tlfloat_t::infinity(signbit(x)); if (iszero(x) && signbit(y) && !iszero(y) && !yisoddint) return tlfloat_t::infinity(false); Unpacked_t z = log_(fabs(x).getUnpacked().cast((const Unpacked_t *)nullptr)); z = exp_(z * y.getUnpacked().cast((const Unpacked_t *)nullptr)); if (signbit(x) && yisoddint) z.sign = !z.sign; return tlfloat_t(z.cast((const decltype(x.getUnpacked()) *)nullptr)); } // template static constexpr Unpacked_t cbrt_(Unpacked_t d) { const int eoffset = 1 << 20; constexpr xarray cbrtCoef = genCbrtCoef(); int e = (d * constOneOthree()).ilogb() + 2; d.exp -= e; int r = (e + eoffset * 3) % 3; Unpacked_t q = Unpacked_t(1); if (r == 1) q = constCbrt2(); if (r == 2) q = constCbrt4(); q.exp += (e + eoffset * 3) / 3 - eoffset; if (d.sign) q.sign = !q.sign; d.sign = false; Unpacked_t x = cbrtCoef.e[N+1], y; for(int i=N;i>=0;i--) x = Unpacked_t::fma(x, d - Unpacked_t(1), cbrtCoef.e[i]); if constexpr (M > 0) { for(unsigned i=0;i(), x); } } y = x * x * d; return Unpacked_t::fma(Unpacked_t::fma(y, x, Unpacked_t(-1)), -ldexp_(constOneOthree(), 1) * y, y) * q; } template static constexpr tlfloat_t cbrt(const tlfloat_t &a) { if (iszero(a) || isinf(a) || isnan(a)) return a; Unpacked_t z = cbrt_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } // template static constexpr tlfloat_t sinh(const tlfloat_t &a) { Unpacked_t x = a.getUnpacked().cast((const Unpacked_t *)nullptr), y = fabs(x); if (x.isnan || x.isinf) return a; if (y > Unpacked_t::castFromInt(1ULL << O)) return tlfloat_t::infinity(x.sign); Unpacked_t d = expm1_(fabs(x)); d = ldexp_(d * (d + Unpacked_t(2)) / (d + Unpacked_t(1)), -1); if (x.sign) d.sign = !d.sign; return tlfloat_t(d.cast((decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t cosh(const tlfloat_t &a) { Unpacked_t x = a.getUnpacked().cast((const Unpacked_t *)nullptr), y = fabs(x); if (x.isnan) return a; if (x.iszero) return 1; if (y > Unpacked_t::castFromInt(1ULL << O)) return tlfloat_t::infinity(); Unpacked_t d = exp_(fabs(x)); d = ldexp_(d + Unpacked_t(1) / d, -1); return tlfloat_t(d.cast((decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t tanh(const tlfloat_t &a) { Unpacked_t x = a.getUnpacked().cast((const Unpacked_t *)nullptr), y = fabs(x); if (x.isnan) return a; if (y.isinf || y > Unpacked_t::castFromInt(1ULL << O)) return x.sign ? -1 : 1; Unpacked_t d = expm1_(ldexp_(y, 1)); d = d / (d + Unpacked_t(2)); if (x.sign) d.sign = !d.sign; return tlfloat_t(d.cast((decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t asinh(const tlfloat_t &a) { Unpacked_t x = a.getUnpacked().cast((const Unpacked_t *)nullptr), y = fabs(x); if (x.isnan || y.isinf) return a; bool ygt1 = y > Unpacked_t(1); Unpacked_t d = ygt1 ? Unpacked_t(1) / y : y; d = sqrt_(Unpacked_t::fma(d, d, Unpacked_t(1))); if (ygt1) { d = log_(Unpacked_t::fma(d, y, y)); } else { d = log1p_(d - Unpacked_t(1) + y); } if (x.sign) d.sign = !d.sign; return tlfloat_t(d.cast((decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t acosh(const tlfloat_t &a) { Unpacked_t x = a.getUnpacked().cast((const Unpacked_t *)nullptr); if (x.isnan) return a; if (x < Unpacked_t(1)) return tlfloat_t::nan(); if (x.isinf) return tlfloat_t::infinity(); Unpacked_t d = log_(sqrt_((x + Unpacked_t(1))*(x - Unpacked_t(1))) + x); return tlfloat_t(d.cast((decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t atanh(const tlfloat_t &a) { Unpacked_t x = a.getUnpacked().cast((const Unpacked_t *)nullptr), y = fabs(x); if (x.isnan) return a; if (x.isinf) return tlfloat_t::nan(); if (y > Unpacked_t(1)) return tlfloat_t::nan(); if (y == Unpacked_t(1)) return tlfloat_t::infinity(x.sign); Unpacked_t d = ldexp_(log1p_(ldexp_(y, 1) / (Unpacked_t(1) - y)), -1); if (x.sign) d.sign = !d.sign; return tlfloat_t(d.cast((decltype(a.getUnpacked()) *)nullptr)); } // template static constexpr Unpacked_t fmod_(const Unpacked_t &n, const Unpacked_t &d, const Unpacked_t &rd) { Unpacked_t r = n, d3 = d * Unpacked_t(3), d2 = ldexp_(d, 1); for(int i=0;i<(1 << 20);i++) { Unpacked_t q = trunc(toward0(r * rd)); if (d3 > r && r > d) q = Unpacked_t(2); if (d2 > r && r >= d) q = Unpacked_t(1); r = Unpacked_t::fma(q, -d, r); if (r < d) break; } return r; } template static constexpr tlfloat_t fmod(const tlfloat_t &n, const tlfloat_t &d) { Unpacked_t un = n.getUnpacked().cast((Unpacked_t *)0); Unpacked_t ud = d.getUnpacked().cast((Unpacked_t *)0); if (un.isinf || ud.iszero) return tlfloat_t::nan(); if (un.isnan || ud.isinf) return n; if (ud.isnan) return d; Unpacked_t ur = fmod_(fabs(un), fabs(ud), toward0(Unpacked_t(1) / fabs(ud))); if (un.sign) ur.sign = !ur.sign; return tlfloat_t(ur.cast((decltype(n.getUnpacked()) *)nullptr)); } template static constexpr Unpacked_t remainder_(const Unpacked_t &n, const Unpacked_t &d, const Unpacked_t &rd) { Unpacked_t r = n, d15 = d * ldexp_(Unpacked_t(3), -1), d05 = ldexp_(d, -1); bool qisodd = false; for(int i=0;i<(1 << 20);i++) { Unpacked_t q = rint(r * rd); if (fabs(r) < d15) q = Unpacked_t(r.sign ? -1 : 1); if (fabs(r) < d05 || (!qisodd && fabs(r) == d05)) q = Unpacked_t(0); if (q.iszero) break; qisodd = qisodd != (isint(q) && !iseven(q)); r = Unpacked_t::fma(q, -d, r); } return r; } template static constexpr tlfloat_t remainder(const tlfloat_t &n, const tlfloat_t &d) { Unpacked_t un = n.getUnpacked().cast((Unpacked_t *)0); Unpacked_t ud = d.getUnpacked().cast((Unpacked_t *)0); if (un.isinf || ud.iszero) return tlfloat_t::nan(); if (un.isnan || ud.isinf) return n; if (ud.isnan) return d; Unpacked_t ur = remainder_(fabs(un), fabs(ud), toward0(Unpacked_t(1) / fabs(ud))); if (un.sign) ur.sign = !ur.sign; return tlfloat_t(ur.cast((decltype(n.getUnpacked()) *)nullptr)); } template static constexpr xpair remquo_(const Unpacked_t &n, const Unpacked_t &d, const Unpacked_t &rd) { Unpacked_t r = n, d15 = d * ldexp_(Unpacked_t(3), -1), d05 = ldexp_(d, -1); int64_t quo = 0; bool qisodd = false; for(int i=0;i<(1 << 20);i++) { Unpacked_t q = rint(r * rd); if (fabs(r) < d15) q = Unpacked_t(r.sign ? -1 : 1); if (fabs(r) < d05 || (!qisodd && fabs(r) == d05)) q = Unpacked_t(0); if (q.iszero) break; qisodd = qisodd != (isint(q) && !iseven(q)); quo += q.sign ? -int64_t(q.castToInt2() & ((1ULL << 63)-1)) : int64_t(q.castToInt2() & ((1ULL << 63)-1)); r = Unpacked_t::fma(q, -d, r); } quo &= (1ULL << 63)-1; return xpair(r, n.sign != d.sign ? -quo : quo); } template static constexpr xpair remquo(const tlfloat_t &n, const tlfloat_t &d) { Unpacked_t un = n.getUnpacked().cast((Unpacked_t *)0); Unpacked_t ud = d.getUnpacked().cast((Unpacked_t *)0); if (un.isinf || ud.iszero) return xpair(tlfloat_t::nan(), 0); if (un.isnan || ud.isinf) return xpair(n, 0); if (ud.isnan) return xpair(d, 0); auto p = remquo_(fabs(un), fabs(ud), toward0(Unpacked_t(1) / fabs(ud))); if (un.sign) p.first.sign = !p.first.sign; if (un.sign != ud.sign) p.second = -p.second; return xpair(tlfloat_t(p.first.cast((decltype(n.getUnpacked()) *)nullptr)), p.second); } // template static constexpr Unpacked_t erf_(const Unpacked_t& z) { Unpacked_t n = Unpacked_t::castFromInt(N*2+1), d = Unpacked_t(1), t; for(int i=N;i>0;i-=2) { t = n; n = n*Unpacked_t(i*2-1) + z*z*Unpacked_t(i*2-0)*d; d = t; t = n; n = n*Unpacked_t(i*2-3) - z*z*Unpacked_t(i*2-2)*d; d = t; } d = ldexp_(d, 1); return z * constRSqrtPI() * exp_(-(z*z)) * (d / n); } template static constexpr Unpacked_t erfc_(const Unpacked_t& z) { Unpacked_t n = Unpacked_t(1), d = n, t; for(int i=N;i>0;i-=2) { t = n; n = n + ldexp_(Unpacked_t(i), -1) * d; d = t; t = n; n = z * z * n + ldexp_(Unpacked_t(i - 1), -1) * d; d = t; } return z * constRSqrtPI() * exp_(-(z*z)) * (d / n); } template static constexpr tlfloat_t erf(const tlfloat_t &a) { if (isnan(a)) return a; if (isinf(a)) return signbit(a) ? -1 : 1; Unpacked_t z; if (a < (tlfloat_t)(-T * 0.1)) { z = Unpacked_t(-1) - erfc_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); } else if (a < (tlfloat_t)(T * 0.1)) { z = erf_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); } else { z = Unpacked_t(1) - erfc_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); } return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t erfc(const tlfloat_t &a) { if (isnan(a)) return a; if (isinf(a)) return signbit(a) ? 2 : 0; Unpacked_t z; if (a < (tlfloat_t)(-T * 0.1)) { z = Unpacked_t(2) + erfc_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); } else if (a < (tlfloat_t)(T * 0.1)) { z = Unpacked_t(1) - erf_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); } else { z = erfc_(a.getUnpacked().cast((const Unpacked_t *)nullptr)); } return tlfloat_t(z.cast((const decltype(a.getUnpacked()) *)nullptr)); } // template static constexpr xpair lgamma_(const Unpacked_t& z) { constexpr xarray gammaCoef = genGammaCoef(); const Unpacked_t one = Unpacked_t(1), p5 = Unpacked_t("0x1p-1"); const bool reflect = z < Unpacked_t(-1); Unpacked_t a = reflect ? one - z : z; const Unpacked_t in = rint(a), fr = a - in; Unpacked_t w = Unpacked_t(1); if (in < Unpacked_t(R)) { for(int i = in.castToInt((int *)0);i=0;i--) y = Unpacked_t::fma(y, one / (a*a), gammaCoef.e[i]); y = y/a + (a - p5)*log_(a) - a + p5*constLN2PI(); y -= log_(fabs(w)); bool sign = w.sign; if (reflect) { Unpacked_t s = sin_(const_M_PI_() * fr); y = constLNPI() - log_(fabs(s)) - y; sign = sign != s.sign; sign = sign == iseven(in); } return xpair(sign, y); } template static constexpr tlfloat_t tgamma(const tlfloat_t &z) { Unpacked_t zu = z.getUnpacked().cast((const Unpacked_t *)nullptr); if (zu.isnan || (!zu.sign && zu.isinf)) return z; if (zu.iszero) return tlfloat_t::infinity(zu.sign); if (zu.sign && isint(zu)) return tlfloat_t::nan(); auto p = lgamma_(zu); Unpacked_t r = exp_(p.second); r.sign = r.sign != p.first; return tlfloat_t(r.cast((const decltype(z.getUnpacked()) *)nullptr)); } template static constexpr tlfloat_t lgamma(const tlfloat_t &z, bool *signptr = nullptr) { Unpacked_t zu = z.getUnpacked().cast((const Unpacked_t *)nullptr); if (signptr) *signptr = false; if (zu.isnan) return z; if (zu.iszero|| zu.isinf) { if (signptr) *signptr = zu.sign; return tlfloat_t::infinity(); } if (zu.sign && isint(zu)) return tlfloat_t::infinity(); auto p = lgamma_(zu); if (signptr) *signptr = p.first; return tlfloat_t(p.second.cast((const decltype(z.getUnpacked()) *)nullptr)); } } // /** Returns 2^exp * PI */ template static inline consteval tlfloat_t const_M_PI(int exp = 0) { typedef decltype(tlfloat_t::to_Unpacked_t()) Unpacked_t; typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; return detail::const_M_PI_(exp).cast((Unpacked_t *)0); } /** Returns 2^exp * log_2 (e) */ template static inline consteval tlfloat_t const_M_LOG2E(int exp = 0) { typedef decltype(tlfloat_t::to_Unpacked_t()) Unpacked_t; typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; return ldexp_(detail::constRLN2(), exp).cast((Unpacked_t*)0); } /** Returns 2^exp * log_10 (e) */ template static inline consteval tlfloat_t const_M_LOG10E(int exp = 0) { typedef decltype(tlfloat_t::to_Unpacked_t()) Unpacked_t; typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; return ldexp_(detail::constRLN10(), exp).cast((Unpacked_t*)0); } /** Returns 2^exp * log 2 */ template static inline consteval tlfloat_t const_M_LN2(int exp = 0) { typedef decltype(tlfloat_t::to_Unpacked_t()) Unpacked_t; typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; return ldexp_(detail::constLN2(), exp).cast((Unpacked_t*)0); } /** Returns 2^exp * log 10 */ template static inline consteval tlfloat_t const_M_LN10(int exp = 0) { typedef decltype(tlfloat_t::to_Unpacked_t()) Unpacked_t; typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; return ldexp_(detail::constLN10(), exp).cast((Unpacked_t*)0); } /** Returns 2^exp / PI */ template static inline consteval tlfloat_t const_M_1_PI(int exp = 0) { typedef decltype(tlfloat_t::to_Unpacked_t()) Unpacked_t; typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; return (xUnpacked_t(1) / detail::const_M_PI_(-exp)).cast((Unpacked_t *)0); } /** Returns 2^exp / sqrt(PI) */ template static inline consteval tlfloat_t const_M_1_SQRTPI(int exp = 0) { typedef decltype(tlfloat_t::to_Unpacked_t()) Unpacked_t; typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; return (ldexp_(xUnpacked_t(1), exp) / sqrt_(detail::const_M_PI_(0))).cast((Unpacked_t*)0); } /** Returns 2^exp * E */ template static inline consteval tlfloat_t const_M_E(int exp = 0) { typedef decltype(tlfloat_t::to_Unpacked_t()) Unpacked_t; typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; return detail::const_M_E_(exp).cast((Unpacked_t *)0); } /** Returns the Euler–Mascheroni constant */ template static inline consteval tlfloat_t const_Euler() { typedef decltype(tlfloat_t::to_Unpacked_t()) Unpacked_t; typedef decltype(Unpacked_t::xUnpackedFloat()) xUnpacked_t; return detail::constEuler().cast((Unpacked_t*)0); } // /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 sin(const BFloat16& a) { return detail::sin(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half sin(const Half& a) { return detail::sin(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float sin(const Float& a) { return detail::sin(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double sin(const Double& a) { return detail::sin(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad sin(const Quad& a) { return detail::sin(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple sin(const Octuple& a) { return detail::sin(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 cos(const BFloat16& a) { return detail::cos(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half cos(const Half& a) { return detail::cos(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float cos(const Float& a) { return detail::cos(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double cos(const Double& a) { return detail::cos(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad cos(const Quad& a) { return detail::cos(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple cos(const Octuple& a) { return detail::cos(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 tan(const BFloat16& a) { return detail::tan(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half tan(const Half& a) { return detail::tan(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float tan(const Float& a) { return detail::tan(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double tan(const Double& a) { return detail::tan(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad tan(const Quad& a) { return detail::tan(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple tan(const Octuple& a) { return detail::tan(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 atan2(const BFloat16& y, const BFloat16& x) { return detail::atan2(y, x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half atan2(const Half& y, const Half& x) { return detail::atan2(y, x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float atan2(const Float& y, const Float& x) { return detail::atan2(y, x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double atan2(const Double& y, const Double& x) { return detail::atan2(y, x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad atan2(const Quad& y, const Quad& x) { return detail::atan2(y, x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple atan2(const Octuple& y, const Octuple& x) { return detail::atan2(y, x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 asin(const BFloat16& a) { return detail::asin(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half asin(const Half& a) { return detail::asin(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float asin(const Float& a) { return detail::asin(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double asin(const Double& a) { return detail::asin(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad asin(const Quad& a) { return detail::asin(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple asin(const Octuple& a) { return detail::asin(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 acos(const BFloat16& a) { return detail::acos(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half acos(const Half& a) { return detail::acos(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float acos(const Float& a) { return detail::acos(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double acos(const Double& a) { return detail::acos(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad acos(const Quad& a) { return detail::acos(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple acos(const Octuple& a) { return detail::acos(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 atan(const BFloat16& a) { return detail::atan(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half atan(const Half& a) { return detail::atan(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float atan(const Float& a) { return detail::atan(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double atan(const Double& a) { return detail::atan(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad atan(const Quad& a) { return detail::atan(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple atan(const Octuple& a) { return detail::atan(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 exp(const BFloat16& a) { return detail::exp(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half exp(const Half& a) { return detail::exp(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float exp(const Float& a) { return detail::exp(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double exp(const Double& a) { return detail::exp(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad exp(const Quad& a) { return detail::exp(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple exp(const Octuple& a) { return detail::exp(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 expm1(const BFloat16& a) { return detail::expm1(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half expm1(const Half& a) { return detail::expm1(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float expm1(const Float& a) { return detail::expm1(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double expm1(const Double& a) { return detail::expm1(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad expm1(const Quad& a) { return detail::expm1(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple expm1(const Octuple& a) { return detail::expm1(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 exp2(const BFloat16& a) { return detail::exp(a, detail::constLN2()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half exp2(const Half& a) { return detail::exp(a, detail::constLN2()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float exp2(const Float& a) { return detail::exp(a, detail::constLN2()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double exp2(const Double& a) { return detail::exp(a, detail::constLN2()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad exp2(const Quad& a) { return detail::exp(a, detail::constLN2()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple exp2(const Octuple& a) { return detail::exp(a, detail::constLN2()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 exp10(const BFloat16& a) { return detail::exp(a, detail::constLN10()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half exp10(const Half& a) { return detail::exp(a, detail::constLN10()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float exp10(const Float& a) { return detail::exp(a, detail::constLN10()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double exp10(const Double& a) { return detail::exp(a, detail::constLN10()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad exp10(const Quad& a) { return detail::exp(a, detail::constLN10()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple exp10(const Octuple& a) { return detail::exp(a, detail::constLN10()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 log(const BFloat16& a) { return detail::log(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half log(const Half& a) { return detail::log(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float log(const Float& a) { return detail::log(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double log(const Double& a) { return detail::log(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad log(const Quad& a) { return detail::log(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple log(const Octuple& a) { return detail::log(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 log1p(const BFloat16& a) { return detail::log1p(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half log1p(const Half& a) { return detail::log1p(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float log1p(const Float& a) { return detail::log1p(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double log1p(const Double& a) { return detail::log1p(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad log1p(const Quad& a) { return detail::log1p(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple log1p(const Octuple& a) { return detail::log1p(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 log2(const BFloat16& a) { return detail::log(a, detail::constRLN2()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half log2(const Half& a) { return detail::log(a, detail::constRLN2()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float log2(const Float& a) { return detail::log(a, detail::constRLN2()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double log2(const Double& a) { return detail::log(a, detail::constRLN2()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad log2(const Quad& a) { return detail::log(a, detail::constRLN2()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple log2(const Octuple& a) { return detail::log(a, detail::constRLN2()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 log10(const BFloat16& a) { return detail::log(a, detail::constRLN10()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half log10(const Half& a) { return detail::log(a, detail::constRLN10()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float log10(const Float& a) { return detail::log(a, detail::constRLN10()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double log10(const Double& a) { return detail::log(a, detail::constRLN10()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad log10(const Quad& a) { return detail::log(a, detail::constRLN10()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple log10(const Octuple& a) { return detail::log(a, detail::constRLN10()); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 pow(const BFloat16& x, const BFloat16& y) { return detail::pow(x, y); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half pow(const Half& x, const Half& y) { return detail::pow(x, y); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float pow(const Float& x, const Float& y) { return detail::pow(x, y); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double pow(const Double& x, const Double& y) { return detail::pow(x, y); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad pow(const Quad& x, const Quad& y) { return detail::pow(x, y); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple pow(const Octuple& x, const Octuple& y) { return detail::pow(x, y); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 cbrt(const BFloat16& a) { return detail::cbrt(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half cbrt(const Half& a) { return detail::cbrt(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float cbrt(const Float& a) { return detail::cbrt(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double cbrt(const Double& a) { return detail::cbrt(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad cbrt(const Quad& a) { return detail::cbrt(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple cbrt(const Octuple& a) { return detail::cbrt(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 sinh(const BFloat16& a) { return detail::sinh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half sinh(const Half& a) { return detail::sinh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float sinh(const Float& a) { return detail::sinh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double sinh(const Double& a) { return detail::sinh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad sinh(const Quad& a) { return detail::sinh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple sinh(const Octuple& a) { return detail::sinh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 cosh(const BFloat16& a) { return detail::cosh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half cosh(const Half& a) { return detail::cosh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float cosh(const Float& a) { return detail::cosh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double cosh(const Double& a) { return detail::cosh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad cosh(const Quad& a) { return detail::cosh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple cosh(const Octuple& a) { return detail::cosh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 tanh(const BFloat16& a) { return detail::tanh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half tanh(const Half& a) { return detail::tanh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float tanh(const Float& a) { return detail::tanh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double tanh(const Double& a) { return detail::tanh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad tanh(const Quad& a) { return detail::tanh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple tanh(const Octuple& a) { return detail::tanh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 asinh(const BFloat16& a) { return detail::asinh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half asinh(const Half& a) { return detail::asinh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float asinh(const Float& a) { return detail::asinh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double asinh(const Double& a) { return detail::asinh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad asinh(const Quad& a) { return detail::asinh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple asinh(const Octuple& a) { return detail::asinh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 acosh(const BFloat16& a) { return detail::acosh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half acosh(const Half& a) { return detail::acosh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float acosh(const Float& a) { return detail::acosh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double acosh(const Double& a) { return detail::acosh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad acosh(const Quad& a) { return detail::acosh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple acosh(const Octuple& a) { return detail::acosh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 atanh(const BFloat16& a) { return detail::atanh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half atanh(const Half& a) { return detail::atanh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float atanh(const Float& a) { return detail::atanh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double atanh(const Double& a) { return detail::atanh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad atanh(const Quad& a) { return detail::atanh(a); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple atanh(const Octuple& a) { return detail::atanh(a); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr BFloat16 fmod(const BFloat16& y, const BFloat16& x) { return detail::fmod(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr Half fmod(const Half& y, const Half& x) { return detail::fmod(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr Float fmod(const Float& y, const Float& x) { return detail::fmod(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr Double fmod(const Double& y, const Double& x) { return detail::fmod(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr Quad fmod(const Quad& y, const Quad& x) { return detail::fmod(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr Octuple fmod(const Octuple& y, const Octuple& x) { return detail::fmod(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr BFloat16 remainder(const BFloat16& y, const BFloat16& x) { return detail::remainder(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr Half remainder(const Half& y, const Half& x) { return detail::remainder(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr Float remainder(const Float& y, const Float& x) { return detail::remainder(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr Double remainder(const Double& y, const Double& x) { return detail::remainder(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr Quad remainder(const Quad& y, const Quad& x) { return detail::remainder(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr Octuple remainder(const Octuple& y, const Octuple& x) { return detail::remainder(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr xpair remquo(const BFloat16& y, const BFloat16& x) { return detail::remquo(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr xpair remquo(const Half& y, const Half& x) { return detail::remquo(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr xpair remquo(const Float& y, const Float& x) { return detail::remquo(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr xpair remquo(const Double& y, const Double& x) { return detail::remquo(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr xpair remquo(const Quad& y, const Quad& x) { return detail::remquo(y, x); } /** This function has the same functionality as the corresponding function in math.h. This function returns correctly rounded results. */ static inline constexpr xpair remquo(const Octuple& y, const Octuple& x) { return detail::remquo(y, x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 erf(const BFloat16& x) { return detail::erf(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half erf(const Half& x) { return detail::erf(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float erf(const Float& x) { return detail::erf(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double erf(const Double& x) { return detail::erf(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad erf(const Quad& x) { return detail::erf(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple erf(const Octuple& x) { return detail::erf(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 erfc(const BFloat16& x) { return detail::erfc(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half erfc(const Half& x) { return detail::erfc(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float erfc(const Float& x) { return detail::erfc(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double erfc(const Double& x) { return detail::erfc(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad erfc(const Quad& x) { return detail::erfc(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple erfc(const Octuple& x) { return detail::erfc(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 tgamma(const BFloat16& x) { return detail::tgamma(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Half tgamma(const Half& x) { return detail::tgamma(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Float tgamma(const Float& x) { return detail::tgamma(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Double tgamma(const Double& x) { return detail::tgamma(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Quad tgamma(const Quad& x) { return detail::tgamma(x); } /** This function has the same functionality as the corresponding function in math.h. The accuracy of the return value is 1ULP. */ static inline constexpr Octuple tgamma(const Octuple& x) { return detail::tgamma(x); } /** This function has the same functionality as the corresponding function in math.h. This implementation is experimental and has no error bound. */ static inline constexpr BFloat16 lgamma(const BFloat16& x, bool *sign = 0) { return detail::lgamma(x, sign); } /** This function has the same functionality as the corresponding function in math.h. This implementation is experimental and has no error bound. */ static inline constexpr Half lgamma(const Half& x, bool *sign = 0) { return detail::lgamma(x, sign); } /** This function has the same functionality as the corresponding function in math.h. This implementation is experimental and has no error bound. */ static inline constexpr Float lgamma(const Float& x, bool *sign = 0) { return detail::lgamma(x, sign); } /** This function has the same functionality as the corresponding function in math.h. This implementation is experimental and has no error bound. */ static inline constexpr Double lgamma(const Double& x, bool *sign = 0) { return detail::lgamma(x, sign); } /** This function has the same functionality as the corresponding function in math.h. This implementation is experimental and has no error bound. */ static inline constexpr Quad lgamma(const Quad& x, bool *sign = 0) { return detail::lgamma(x, sign); } /** This function has the same functionality as the corresponding function in math.h. This implementation is experimental and has no error bound. */ static inline constexpr Octuple lgamma(const Octuple& x, bool *sign = 0) { return detail::lgamma(x, sign); } /** This function returns sin(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 sinpi(const BFloat16& a) { return detail::sinpi(a); } /** This function returns sin(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Half sinpi(const Half& a) { return detail::sinpi(a); } /** This function returns sin(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Float sinpi(const Float& a) { return detail::sinpi(a); } /** This function returns sin(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Double sinpi(const Double& a) { return detail::sinpi(a); } /** This function returns sin(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Quad sinpi(const Quad& a) { return detail::sinpi(a); } /** This function returns sin(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Octuple sinpi(const Octuple& a) { return detail::sinpi(a); } /** This function returns cos(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 cospi(const BFloat16& a) { return detail::cospi(a); } /** This function returns cos(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Half cospi(const Half& a) { return detail::cospi(a); } /** This function returns cos(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Float cospi(const Float& a) { return detail::cospi(a); } /** This function returns cos(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Double cospi(const Double& a) { return detail::cospi(a); } /** This function returns cos(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Quad cospi(const Quad& a) { return detail::cospi(a); } /** This function returns cos(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Octuple cospi(const Octuple& a) { return detail::cospi(a); } /** This function returns tan(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr BFloat16 tanpi(const BFloat16& a) { return detail::tanpi(a); } /** This function returns tan(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Half tanpi(const Half& a) { return detail::tanpi(a); } /** This function returns tan(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Float tanpi(const Float& a) { return detail::tanpi(a); } /** This function returns tan(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Double tanpi(const Double& a) { return detail::tanpi(a); } /** This function returns tan(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Quad tanpi(const Quad& a) { return detail::tanpi(a); } /** This function returns tan(PI * x). The accuracy of the return value is 1ULP. */ static inline constexpr Octuple tanpi(const Octuple& a) { return detail::tanpi(a); } static inline constexpr xpair sincos(const BFloat16& a) { return { detail::sin(a), detail::cos(a) }; } static inline constexpr xpair sincos(const Half& a) { return { detail::sin(a), detail::cos(a) }; } static inline constexpr xpair sincos(const Float& a) { return { detail::sin(a), detail::cos(a) }; } static inline constexpr xpair sincos(const Double& a) { return { detail::sin(a), detail::cos(a) }; } static inline constexpr xpair sincos(const Quad& a) { return { detail::sin(a), detail::cos(a) }; } static inline constexpr xpair sincos(const Octuple& a) { return { detail::sin(a), detail::cos(a) }; } static inline constexpr xpair sincospi(const BFloat16& a) { return { detail::sinpi(a), detail::cospi(a) }; } static inline constexpr xpair sincospi(const Half& a) { return { detail::sinpi(a), detail::cospi(a) }; } static inline constexpr xpair sincospi(const Float& a) { return { detail::sinpi(a), detail::cospi(a) }; } static inline constexpr xpair sincospi(const Double& a) { return { detail::sinpi(a), detail::cospi(a) }; } static inline constexpr xpair sincospi(const Quad& a) { return { detail::sinpi(a), detail::cospi(a) }; } static inline constexpr xpair sincospi(const Octuple& a) { return { detail::sinpi(a), detail::cospi(a) }; } } #endif // #ifndef __TLMATH_HPP_INCLUDED__ tlfloat-1.15.0/src/include/tlfloat/tlmathcoef.hpp000066400000000000000000000513161477036600700220010ustar00rootroot00000000000000namespace tlfloat { namespace detail { static constexpr const char *sinCoefStr[] = { "0x1p+0", // 1 "0x1.55555555555555555555555555555555555555555555555555555555555555555p-3", // 0.166667 "0x1.11111111111111111111111111111111111111111111111111111111111111111p-7", // 0.00833333 "0x1.a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01ap-13", // 0.000198413 "0x1.71de3a556c7338faac1c88e500171de3a556c7338faac1c88e500171de3a556c7p-19", // 2.75573e-06 "0x1.ae64567f544e38fe747e4b837dc71e202b72f11b6aaac590f0129fef8e3a91f28p-26", // 2.50521e-08 "0x1.6124613a86d097ca38331d23af684d3b3757bf4471c732840d301a3425ee6a9fap-33", // 1.6059e-10 "0x1.ae7f3e733b81f11d8656b0ee8cafe91ebd5ec707db2878187199b98b26ed00c29p-41", // 7.64716e-13 "0x1.952c77030ad4a6b2605197771affea7748d1ac43a117079e890927198e0c3cf36p-49", // 2.81146e-15 "0x1.2f49b4681415724ca1ec3b7b9674b57eb741a062878d7ef76b1154a8d61e1ea73p-57", // 8.22064e-18 "0x1.71b8ef6dcf5718bef146fcee6e45218487a0757f6d2b4571e19b38e15309e5fa2p-66", // 1.95729e-20 "0x1.761b413163819d97b8704dd7f627984d6ff0465264584e5cf884c736f7f1bb2bap-75", // 3.86817e-23 "0x1.3f3ccdd165fa8d4e44a419776f10b893fff294c13014bdbff99dad68eee2c1da2p-84", // 6.44695e-26 "0x1.d1ab1c2dccea320a9a18f15d427734a0749e62d53e1ccbda09a68ca1d127c285p-94", // 9.18369e-29 "0x1.259f98b4358ad7abe30e7766f1291d666f5d9049ed27987f64aa97ba866741e76p-103", // 1.131e-31 "0x1.434d2e783f5bc42e1ee46fa6bfc3913b62f2db6e93b6e244b31ba1023acd155d7p-113", // 1.21613e-34 "0x1.3981254dd0d51b5382cdffa974227d50dc124925687348048ea66d958e5a43436p-123", // 1.15163e-37 "0x1.0dc59c716d91f2833c7f5a7e0623b3afda3303ff7d9742b4532af69b5e875343ep-133", // 9.67759e-41 "0x1.9ec8d1c94e85af4c78b15c3d89d2f3fcb2a927344305c831b36193c49a9107539p-144", // 7.26546e-44 "0x1.1e99449a4bacde0104476aeb4c3ab2f3022f1749c497dc344e5775a5e6d373f61p-154", // 4.90247e-47 "0x1.65e61c39d0240c7e25cfd1b1b2dca885a152887a1738054011e8d8d92a3dc1833p-165", // 2.98931e-50 "0x1.95db45257e5122dcbae56def3720370619e16b6b8c9493b419fab93c928f2c86p-176", // 1.65521e-53 "0x1.a3cb8722206478e02c5e91c64cabec5f43a03d75f74a8d65fce02aa71f1773defp-187", // 8.35965e-57 "0x1.8da8e0a127eb9b78b454d8b628e52abe2d969b50b8fe645081a8890682562822fp-198", // 3.86663e-60 "0x1.5a42f0dfeb085d94a3fd410e1231c72d6f18e8c3ad46004619d32fe9cdca266e9p-209", // 1.64397e-63 "0x1.161872bf7b8233772d91c5d112d44064bd9e588eb2eaeb2337e0d3f566d55a7fcp-220", // 6.44696e-67 "0x1.9d4f1058674df40f206da45356515f54b343c3e4ccf98ffed6939f55aec0fd65dp-232", // 2.33925e-70 }; static constexpr const char *cosCoefStr[] = { "0x1p+0", // 1 "0x1p-1", // 0.5 "0x1.55555555555555555555555555555555555555555555555555555555555555555p-5", // 0.0416667 "0x1.6c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16cp-10", // 0.00138889 "0x1.a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01ap-16", // 2.48016e-05 "0x1.27e4fb7789f5c72ef016d3ea6678e4b61ddf05c2d95567d3a50ccdf4b1c84456cp-22", // 2.75573e-07 "0x1.1eed8eff8d897b544da987acfe84bec01cf74b679c71d90b4ab7154a5ed1b6a1bp-29", // 2.08768e-09 "0x1.93974a8c07c9d20badf145dfa3e4ea8cd188da975d75f096ea801df2747e30b67p-37", // 1.14707e-11 "0x1.ae7f3e733b81f11d8656b0ee8cafe91ebd5ec707db2878187199b98b26ed00c29p-45", // 4.77948e-14 "0x1.6827863b97d977bb004886a2c2aa9786799dee7500f806c5cf2494887e43c4669p-53", // 1.56192e-16 "0x1.e542ba402022507a9cad2bf8f0babbfdf2029a373f48cb25781bbaa7bcfcfdd85p-62", // 4.11032e-19 "0x1.0ce396db7f8529450c90b7f338ec7577a874b28b381f7852d29f6f2f8235be876p-70", // 8.89679e-22 "0x1.f2cf01972f577cca4b4067ca9d8a20673feb086ddb20687bf6065ef3f5424ee4ep-80", // 1.61174e-24 "0x1.88e85fc6a4e59a38f2050ba6b01494676265a363ec684bfff82486a888798c203p-89", // 2.4796e-27 "0x1.0a18a2635085d373c5c51c354a8d42a4d4eccac2feebe233733a998109cd93b9bp-98", // 3.27989e-30 "0x1.3932c5047d60e60caded4c2989c574b187db44931f192b328d82c3fa28f6acb29p-108", // 3.76999e-33 "0x1.434d2e783f5bc42e1ee46fa6bfc3913b62f2db6e93b6e244b31ba1023acd155d7p-118", // 3.80039e-36 "0x1.2710231c0fd7a13f8a2b4af9d6b70c8856a7cc5f715d70f53af6fdb9ef6403124p-128", // 3.38716e-39 "0x1.df983290c2ca92b06b8d12a7275bea1c2e9395546d7eaf797768d2db52b7b078ap-139", // 2.68822e-42 "0x1.5d4acb9c0c3aae913d370a4ec4e78a182aa96461e799145fbf7a97623151b553ep-149", // 1.91196e-45 "0x1.ca8ed42a12ae3001a07244abad2ab7eb36b1bedc6dbfc6ba16f255d63e1f1ff01p-160", // 1.22562e-48 "0x1.10af527530de836c4d9225dcb909a4f81963742c4273d33d01747474b27831eap-170", // 7.11741e-52 "0x1.272b1b03fec6a4fd9f327e7f6de8e232fb8cab36f1e06b6bb5cd9dfd81dc7d78cp-181", // 3.76184e-55 "0x1.240804f65951062ca46e4f25c6084b63a97a9a0f47dad1ab1f37c4a0c7b74579bp-192", // 1.81732e-58 "0x1.091b406b6ff267a5cd8de5cec5ee1c7ec90f1235d0a99835abc5b0af018ec56cap-203", // 8.05548e-62 "0x1.bb36f6e12cd78205f0a05345360246a08e345d236d2666c0210e51cf1be4083bap-215", // 3.28795e-65 "0x1.56457989358c8e1c86dacc15037b62f224741e3979beab3f09b23ff2f4b7d1d85p-226", // 1.2398e-68 "0x1.e9d8f6ed83ea9c83b4a7df335cd23818889c2a8a6e31425d70174194f50aa7952p-238", // 4.33194e-72 }; static constexpr const char *tanCoefStr[] = { "0x1p+0", // 1 "0x1.55555555555555555555555555555555555555555555555555555555555555555p-2", // 0.333333 "0x1.11111111111111111111111111111111111111111111111111111111111111111p-3", // 0.133333 "0x1.ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1bap-5", // 0.0539683 "0x1.664f4882c10f9f32d6bba49dd81664f4882c10f9f32d6bba49dd81664f4882c1p-6", // 0.0218695 "0x1.226e355e6c23c8f5b51c3974fb201d943551d033403abcd18e00916ce73a05fc6p-7", // 0.00886324 "0x1.d6d3d0e157ddfb5fcc0da5c9a3ccbf7803392d31f0f1e489aed531efa6d26e87fp-9", // 0.00359213 "0x1.7da36452b75e2b6a1d935e8b44c332e280ce9b23015763f9a2e6a037d980b9255p-10", // 0.00145583 "0x1.355824803674452236558fc7c8c4fa131ee47a6efb5bcc8488abdd1852d67f1e8p-11", // 0.000590027 "0x1.f57d7734d166421aab5227996a014ee33533957a54b46573823e26625e6342897p-13", // 0.000239129 "0x1.967e18afcafac8a27ad6f4aec67c988153224339d65502fc723bdbedebd085423p-14", // 9.69154e-05 "0x1.497d8eea2525933e5a05c9a50c6421139aedab67102ccb01abed979489a855ccep-15", // 3.92783e-05 "0x1.0b132d39a60504ec9d30b0658500bf1949290cf2324e41fcc351d9c6574b60b28p-16", // 1.59189e-05 "0x1.b0f72d3ee24e922d11bbab2ac11e2eba4af0306249bcb930bb58b0113e21d2579p-18", // 6.45169e-06 "0x1.5ef2da474e5b6c7b3c5028bb861fa405ca59dc51e637c80297bd77c8e44004b8dp-19", // 2.61477e-06 "0x1.1c77df95c1c0d02dc9139620f15ba7a8ac4fc1a4e8925de5e9f6908d90d78776bp-20", // 1.05973e-06 "0x1.cd299de4ae6bb384dfb0d8b8d524ebda3c47ff027d158d4dc1f56acbc56357845p-22", // 4.29491e-07 "0x1.75cde6563fed8e86fb51ef870af5f42e294d35c9d7a3de838d564c79c8041626bp-23", // 1.74066e-07 "0x1.2efe8db3aff1f23114006472b898a2a16d216a7897780f92c0b4105f63325742dp-24", // 7.05464e-08 "0x1.eb3229047434bca678aab17c61a99ba2a33aa5291c045f64c3f8904afbd676ba5p-26", // 2.85914e-08 "0x1.8e25ff9327e2b98b1141fe7f008ea28771332489c0d52ecb35be9ef1393114c87p-27", // 1.15876e-08 "0x1.42ba1a349b4901148f65da823d34eb19beab79bd676ba12dcb664f7b016326d3dp-28", // 4.6963e-09 "0x1.0597b61cb3092292027ce60a84edabdb6c9c6a4b7302e0adb75164831e95ea83p-29", // 1.90334e-09 "0x1.a813f6eaa7058527550642834433baebc467a339f0d50e5b96d9f8ca557c1fbc7p-31", // 7.71393e-10 "0x1.57bea2950f11e4282ba8d79e4a096024115aae4da54d3b6dc85d3a71371cd7707p-32", // 3.12634e-10 "0x1.16a101c5fde961fd1dd595ffe284dd729619804411fe8fe27d0cf7cc4ba294314p-33", // 1.26706e-10 }; static constexpr const char *atanCoefStr[] = { "0x1p+0", // 1 "-0x1.55555555555555555555555555555555555555555555555555555555555555555p-2", // -0.333333 "0x1.99999999999999999999999999999999999999999999999999999999999999999p-3", // 0.2 "-0x1.24924924924924924924924924924924924924924924924924924924924924924p-3", // -0.142857 "0x1.c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c7p-4", // 0.111111 "-0x1.745d1745d1745d1745d1745d1745d1745d1745d1745d1745d1745d1745d1745d1p-4", // -0.0909091 "0x1.3b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13bp-4", // 0.0769231 "-0x1.11111111111111111111111111111111111111111111111111111111111111111p-4", // -0.0666667 "0x1.e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1ep-5", // 0.0588235 "-0x1.af286bca1af286bca1af286bca1af286bca1af286bca1af286bca1af286bca1afp-5", // -0.0526316 "0x1.86186186186186186186186186186186186186186186186186186186186186186p-5", // 0.047619 "-0x1.642c8590b21642c8590b21642c8590b21642c8590b21642c8590b21642c8590b2p-5", // -0.0434783 "0x1.47ae147ae147ae147ae147ae147ae147ae147ae147ae147ae147ae147ae147ae1p-5", // 0.04 "-0x1.2f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12fp-5", // -0.037037 "0x1.1a7b9611a7b9611a7b9611a7b9611a7b9611a7b9611a7b9611a7b9611a7b9611ap-5", // 0.0344828 "-0x1.08421084210842108421084210842108421084210842108421084210842108421p-5", // -0.0322581 "0x1.f07c1f07c1f07c1f07c1f07c1f07c1f07c1f07c1f07c1f07c1f07c1f07c1f07c1p-6", // 0.030303 "-0x1.d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d4p-6", // -0.0285714 "0x1.bacf914c1bacf914c1bacf914c1bacf914c1bacf914c1bacf914c1bacf914c1bap-6", // 0.027027 "-0x1.a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a4p-6", // -0.025641 "0x1.8f9c18f9c18f9c18f9c18f9c18f9c18f9c18f9c18f9c18f9c18f9c18f9c18f9c1p-6", // 0.0243902 "-0x1.7d05f417d05f417d05f417d05f417d05f417d05f417d05f417d05f417d05f417dp-6", // -0.0232558 "0x1.6c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16cp-6", // 0.0222222 }; static constexpr const char *expCoefStr[] = { "0x1p+0", // 1 "0x1p+0", // 1 "0x1p-1", // 0.5 "0x1.55555555555555555555555555555555555555555555555555555555555555555p-3", // 0.166667 "0x1.55555555555555555555555555555555555555555555555555555555555555555p-5", // 0.0416667 "0x1.11111111111111111111111111111111111111111111111111111111111111111p-7", // 0.00833333 "0x1.6c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16cp-10", // 0.00138889 "0x1.a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01ap-13", // 0.000198413 "0x1.a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01ap-16", // 2.48016e-05 "0x1.71de3a556c7338faac1c88e500171de3a556c7338faac1c88e500171de3a556c7p-19", // 2.75573e-06 "0x1.27e4fb7789f5c72ef016d3ea6678e4b61ddf05c2d95567d3a50ccdf4b1c84456cp-22", // 2.75573e-07 "0x1.ae64567f544e38fe747e4b837dc71e202b72f11b6aaac590f0129fef8e3a91f28p-26", // 2.50521e-08 "0x1.1eed8eff8d897b544da987acfe84bec01cf74b679c71d90b4ab7154a5ed1b6a1bp-29", // 2.08768e-09 "0x1.6124613a86d097ca38331d23af684d3b3757bf4471c732840d301a3425ee6a9fap-33", // 1.6059e-10 "0x1.93974a8c07c9d20badf145dfa3e4ea8cd188da975d75f096ea801df2747e30b67p-37", // 1.14707e-11 "0x1.ae7f3e733b81f11d8656b0ee8cafe91ebd5ec707db2878187199b98b26ed00c29p-41", // 7.64716e-13 "0x1.ae7f3e733b81f11d8656b0ee8cafe91ebd5ec707db2878187199b98b26ed00c29p-45", // 4.77948e-14 "0x1.952c77030ad4a6b2605197771affea7748d1ac43a117079e890927198e0c3cf36p-49", // 2.81146e-15 "0x1.6827863b97d977bb004886a2c2aa9786799dee7500f806c5cf2494887e43c4669p-53", // 1.56192e-16 "0x1.2f49b4681415724ca1ec3b7b9674b57eb741a062878d7ef76b1154a8d61e1ea73p-57", // 8.22064e-18 "0x1.e542ba402022507a9cad2bf8f0babbfdf2029a373f48cb25781bbaa7bcfcfdd85p-62", // 4.11032e-19 "0x1.71b8ef6dcf5718bef146fcee6e45218487a0757f6d2b4571e19b38e15309e5fa2p-66", // 1.95729e-20 "0x1.0ce396db7f8529450c90b7f338ec7577a874b28b381f7852d29f6f2f8235be876p-70", // 8.89679e-22 "0x1.761b413163819d97b8704dd7f627984d6ff0465264584e5cf884c736f7f1bb2bap-75", // 3.86817e-23 "0x1.f2cf01972f577cca4b4067ca9d8a20673feb086ddb20687bf6065ef3f5424ee4ep-80", // 1.61174e-24 "0x1.3f3ccdd165fa8d4e44a419776f10b893fff294c13014bdbff99dad68eee2c1da2p-84", // 6.44695e-26 "0x1.88e85fc6a4e59a38f2050ba6b01494676265a363ec684bfff82486a888798c203p-89", // 2.4796e-27 "0x1.d1ab1c2dccea320a9a18f15d427734a0749e62d53e1ccbda09a68ca1d127c285p-94", // 9.18369e-29 "0x1.0a18a2635085d373c5c51c354a8d42a4d4eccac2feebe233733a998109cd93b9bp-98", // 3.27989e-30 "0x1.259f98b4358ad7abe30e7766f1291d666f5d9049ed27987f64aa97ba866741e76p-103", // 1.131e-31 "0x1.3932c5047d60e60caded4c2989c574b187db44931f192b328d82c3fa28f6acb29p-108", // 3.76999e-33 "0x1.434d2e783f5bc42e1ee46fa6bfc3913b62f2db6e93b6e244b31ba1023acd155d7p-113", // 1.21613e-34 "0x1.434d2e783f5bc42e1ee46fa6bfc3913b62f2db6e93b6e244b31ba1023acd155d7p-118", // 3.80039e-36 "0x1.3981254dd0d51b5382cdffa974227d50dc124925687348048ea66d958e5a43436p-123", // 1.15163e-37 "0x1.2710231c0fd7a13f8a2b4af9d6b70c8856a7cc5f715d70f53af6fdb9ef6403124p-128", // 3.38716e-39 "0x1.0dc59c716d91f2833c7f5a7e0623b3afda3303ff7d9742b4532af69b5e875343ep-133", // 9.67759e-41 "0x1.df983290c2ca92b06b8d12a7275bea1c2e9395546d7eaf797768d2db52b7b078ap-139", // 2.68822e-42 "0x1.9ec8d1c94e85af4c78b15c3d89d2f3fcb2a927344305c831b36193c49a9107539p-144", // 7.26546e-44 }; static constexpr const char *logCoefStr[] = { "0x1p+1", // 2 "0x1.55555555555555555555555555555555555555555555555555555555555555555p-1", // 0.666667 "0x1.99999999999999999999999999999999999999999999999999999999999999999p-2", // 0.4 "0x1.24924924924924924924924924924924924924924924924924924924924924924p-2", // 0.285714 "0x1.c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c7p-3", // 0.222222 "0x1.745d1745d1745d1745d1745d1745d1745d1745d1745d1745d1745d1745d1745d1p-3", // 0.181818 "0x1.3b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13b13bp-3", // 0.153846 "0x1.11111111111111111111111111111111111111111111111111111111111111111p-3", // 0.133333 "0x1.e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1ep-4", // 0.117647 "0x1.af286bca1af286bca1af286bca1af286bca1af286bca1af286bca1af286bca1afp-4", // 0.105263 "0x1.86186186186186186186186186186186186186186186186186186186186186186p-4", // 0.0952381 "0x1.642c8590b21642c8590b21642c8590b21642c8590b21642c8590b21642c8590b2p-4", // 0.0869565 "0x1.47ae147ae147ae147ae147ae147ae147ae147ae147ae147ae147ae147ae147ae1p-4", // 0.08 "0x1.2f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12fp-4", // 0.0740741 "0x1.1a7b9611a7b9611a7b9611a7b9611a7b9611a7b9611a7b9611a7b9611a7b9611ap-4", // 0.0689655 "0x1.08421084210842108421084210842108421084210842108421084210842108421p-4", // 0.0645161 "0x1.f07c1f07c1f07c1f07c1f07c1f07c1f07c1f07c1f07c1f07c1f07c1f07c1f07c1p-5", // 0.0606061 "0x1.d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d41d4p-5", // 0.0571429 "0x1.bacf914c1bacf914c1bacf914c1bacf914c1bacf914c1bacf914c1bacf914c1bap-5", // 0.0540541 "0x1.a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a4p-5", // 0.0512821 "0x1.8f9c18f9c18f9c18f9c18f9c18f9c18f9c18f9c18f9c18f9c18f9c18f9c18f9c1p-5", // 0.0487805 "0x1.7d05f417d05f417d05f417d05f417d05f417d05f417d05f417d05f417d05f417dp-5", // 0.0465116 "0x1.6c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16cp-5", // 0.0444444 "0x1.5c9882b9310572620ae4c415c9882b9310572620ae4c415c9882b9310572620aep-5", // 0.0425532 "0x1.4e5e0a72f05397829cbc14e5e0a72f05397829cbc14e5e0a72f05397829cbc14ep-5", // 0.0408163 "0x1.41414141414141414141414141414141414141414141414141414141414141414p-5", // 0.0392157 "0x1.3521cfb2b78c13521cfb2b78c13521cfb2b78c13521cfb2b78c13521cfb2b78c1p-5", // 0.0377358 "0x1.29e4129e4129e4129e4129e4129e4129e4129e4129e4129e4129e4129e4129e41p-5", // 0.0363636 "0x1.1f7047dc11f7047dc11f7047dc11f7047dc11f7047dc11f7047dc11f7047dc11fp-5", // 0.0350877 "0x1.15b1e5f75270d0456c797dd49c34115b1e5f75270d0456c797dd49c34115b1e5fp-5", // 0.0338983 "0x1.0c9714fbcda3ac10c9714fbcda3ac10c9714fbcda3ac10c9714fbcda3ac10c971p-5", // 0.0327869 "0x1.04104104104104104104104104104104104104104104104104104104104104104p-5", // 0.031746 "0x1.f81f81f81f81f81f81f81f81f81f81f81f81f81f81f81f81f81f81f81f81f81f8p-6", // 0.0307692 "0x1.e9131abf0b7672a07a44c6afc2dd9ca81e9131abf0b7672a07a44c6afc2dd9ca8p-6", // 0.0298507 "0x1.dae6076b981dae6076b981dae6076b981dae6076b981dae6076b981dae6076b98p-6", // 0.0289855 }; static constexpr const char *cbrtCoefStr[] = { "0x1p+0", // 1 "-0x1.55555555555555555555555555555555555555555555555555555555555555555p-2", // -0.333333 "0x1.c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c71c7p-3", // 0.222222 "-0x1.61f9add3c0ca4587e6b74f0329161f9add3c0ca4587e6b74f0329161f9add3c0cp-3", // -0.17284 "0x1.26fabb85cb5339f140436c82a23d1a5663075fde49beaee172d4ce7c5010db20ap-3", // 0.144033 "-0x1.ff4c33f8fa07b9c44d41ab0490ae2da6cdc88409d528625393d743c668a5c0167p-4", // -0.124829 }; static constexpr const char *gammaCoefStr[] = { "0x1.55555555555555555555555555555555555555555555555555555555555555555p-4", // 0.0833333 "-0x1.6c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16c16cp-9", // -0.00277778 "0x1.a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01a01ap-11", // 0.000793651 "-0x1.38138138138138138138138138138138138138138138138138138138138138138p-11", // -0.000595238 "0x1.b951e2b18ff23570ea73806e5478ac63fc8d5c3a9ce01b951e2b18ff23570ea73p-11", // 0.000841751 "-0x1.f6ab0d9993c7c81f6ab0d9993c7c81f6ab0d9993c7c81f6ab0d9993c7c81f6abp-10", // -0.00191753 "0x1.a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a41a4p-8", // 0.00641026 "-0x1.e4286cb0f5397dc2064a8ed3175b9fe4286cb0f5397dc2064a8ed3175b9fe4286p-6", // -0.0295507 "0x1.6fe96381e067ffa1876fe96381e067ffa1876fe96381e067ffa1876fe96381e06p-3", // 0.179644 "-0x1.6476701181f39edbdb9ce625987d4c0e9162983e954e04476701181f39edbdb9cp+0", // -1.39243 "0x1.ace44322ce005a74f53910c8b380169d3d4e44322ce005a74f53910c8b380169dp+3", // 13.4029 "-0x1.39b2525cccc1aab67ee25d73c0f9473b68952525cccc1aab67ee25d73c0f9473bp+7", // -156.848 "0x1.12234e81b4e81b4e81b4e81b4e81b4e81b4e81b4e81b4e81b4e81b4e81b4e81b4p+11", // 2193.1 "-0x1.1a198ae1c4ab7eb3feddd849691fe36729b25c5fa4a108591aa839b7978d16bbdp+15", // -36108.8 "0x1.51a2089a6e11a38433dc9fb888d3995db9600d30469ab0572c127abdcac58108dp+19", // 691472 "-0x1.d1089b142d3577880c2d3577880c2d3577880c2d3577880c2d3577880c2d35778p+23", // -1.52382e+07 "0x1.6d29a0f6433b79890cede62433b79890cede62433b79890cede62433b79890cedp+28", // 3.82901e+08 "-0x1.445119d9e466ed5d4c049ab892ec2c69b51180f27e0f43f1e60cd6fd4a438b9bbp+33", // -1.08823e+10 "0x1.43779bc9d4024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171p+38", // 3.4732e+11 "-0x1.6800b7bc07a8c854486b02e295ec854486b02e295ec854486b02e295ec854486bp+43", // -1.23696e+13 "0x1.bc8cd6f8f1f755c78753cdb5d5c8db31ddd9593d0ae7da3d55812a5a765b9ebafp+48", // 4.88788e+14 "-0x1.2efaec50eee5379680a13e9fb108c896e406f8bc2a2cc36997aad26cf51c74b9p+54", // -2.13203e+16 "0x1.c5c266feb5e17db216d6146a5a9e66b907b4cb2fa644d4de8d74a474098596889p+59", // 1.02178e+18 "-0x1.73c1280b15b1202d69f25ff30d9bdd4413b1b1035a8ae2ac3ea14fa61e9675192p+65", // -5.35755e+19 "0x1.4befddf3ce358f90064d5699917e7ef88f1e8e2b610c81d2167b2bdaa31141b3bp+71", // 3.06158e+21 "-0x1.41df01caf2a81099b4c924b8d90c9234d29bdde119739d7a0e2e61e78a27f1333p+77", // -1.89999e+23 "0x1.51d7fc91b42fbb332f20ec1619c04add8eb0f2f7e904d200cd74ee21a90463d06p+83", // 1.27634e+25 "-0x1.7eb054866aadf62e4992b56ad97d85de77436bde251628f048136e6f8f2d97d85p+89", // -9.25285e+26 "0x1.d28166e47cd8fa1ceee1cce20862db968b81d6f1d0dad3abdbf7fb54c66d0ee5p+95", // 7.21882e+28 "-0x1.31342a0d12ce4cc7f198769e8a306bc22e9631937ac14fa96b8e7d039ab9dc374p+102", // -6.04518e+30 "0x1.ab9d9181cb599fdab1f7db2b872005987b1a9448be405987b1a9448be405987b1p+108", // 5.42067e+32 "-0x1.400a6d954abb28dc25cb7384e71e1b1a99958544402feeeada99958544402feeep+115", // -5.19296e+34 "0x1.feb94900e31a08f00a73200abc4e59d9826bcbb3431848c6801ceb0c52be31b39p+121", // 5.30366e+36 "-0x1.b1959bd1fa84a486a39cca5b435920df12e1b004135bf4cac31ed2676b3d63991p+128", // -5.76333e+38 "0x1.86eb77e97a0097e8da4c14c29ffba6dafac985398a2a50786c12225f1a19d211ap+135", // 6.65116e+40 "-0x1.75a66c437f64a59273b1d1e2d66f326cb2c4a8eee9a081265e60576553decf60bp+142", // -8.13738e+42 }; } } tlfloat-1.15.0/src/tester/000077500000000000000000000000001477036600700153525ustar00rootroot00000000000000tlfloat-1.15.0/src/tester/CMakeLists.txt000066400000000000000000000204021477036600700201100ustar00rootroot00000000000000if (TLFLOAT_COMPILER_SUPPORTS_INT128) add_executable(test_bigint3 test_bigint3.cpp) add_test(NAME test_bigint3 COMMAND test_bigint3) endif() if (BUILD_LIBS) add_executable(test_bigint4 test_bigint4.cpp) target_link_libraries(test_bigint4 tlfloat) add_test(NAME test_bigint4 COMMAND test_bigint4) endif() if (BUILDING_WITH_GLIBC AND BUILD_LIBS) add_executable(test_printf test_printf.cpp) target_link_libraries(test_printf tlfloat) add_test(NAME test_printf COMMAND test_printf) set_tests_properties(test_printf PROPERTIES COST "2") endif() add_executable(test_bigint2 test_bigint2.cpp) add_test(NAME test_bigint2 COMMAND test_bigint2) if(ENABLE_CUDA_TEST) add_executable(test_cuda test_cuda.cu) target_compile_options(test_cuda PRIVATE "--maxrregcount;128;--expt-relaxed-constexpr;--std;c++20") add_test(NAME test_cuda COMMAND test_cuda) set_tests_properties(test_cuda PROPERTIES COST "3") endif() add_executable(test_arith test_arith.cpp) add_executable(test_arith_noopt test_arith.cpp) target_compile_definitions(test_arith_noopt PRIVATE TLFLOAT_DISABLE_ARCH_OPTIMIZATION=1) if (TLFLOAT_ENABLE_LIBQUADMATH) target_link_libraries(test_arith quadmath) target_link_libraries(test_arith_noopt quadmath) endif() add_test(NAME test_arith COMMAND test_arith) set_tests_properties(test_arith PROPERTIES COST "1") add_test(NAME test_arith_noopt COMMAND test_arith_noopt) set_tests_properties(test_arith_noopt PROPERTIES COST "1") if (INSTALL_CONTINUOUS_TESTERS) install( TARGETS test_arith test_arith_noopt DESTINATION "${INSTALL_BINDIR}" COMPONENT tester ) endif() add_executable(test_hash test_hash.cpp) add_test(NAME test_hash COMMAND test_hash 73aabab9b968750a42459cef0ec1e1170160b1762713b9eceffa7f0d6555e11f) set_tests_properties(test_hash PROPERTIES COST "2") add_executable(test_hash_noopt test_hash.cpp) target_compile_definitions(test_hash_noopt PRIVATE TLFLOAT_DISABLE_ARCH_OPTIMIZATION=1) add_test(NAME test_hash_noopt COMMAND test_hash_noopt 73aabab9b968750a42459cef0ec1e1170160b1762713b9eceffa7f0d6555e11f) set_tests_properties(test_hash_noopt PROPERTIES COST "2") if (BUILD_LIBS) add_executable(test_printf_hash test_printf_hash.cpp) target_link_libraries(test_printf_hash tlfloat) add_test(NAME test_printf_hash COMMAND test_printf_hash 2398daffe3037ec51f353ed9da2221f53d4d86fc554e0f93873381f74e1d352c) set_tests_properties(test_printf_hash PROPERTIES COST "2") endif() if (LIB_MPFR) add_executable(test_mpfr test_mpfr.cpp) target_link_libraries(test_mpfr ${LIB_MPFR}) if (TLFLOAT_ENABLE_LIBQUADMATH) target_link_libraries(test_mpfr quadmath) endif() add_test(NAME test_mpfr COMMAND test_mpfr) set_tests_properties(test_mpfr PROPERTIES COST "2") add_executable(test_mpfr_noopt test_mpfr.cpp) target_compile_definitions(test_mpfr_noopt PRIVATE TLFLOAT_DISABLE_ARCH_OPTIMIZATION=1) target_link_libraries(test_mpfr_noopt ${LIB_MPFR}) if (TLFLOAT_ENABLE_LIBQUADMATH) target_link_libraries(test_mpfr_noopt quadmath) endif() add_test(NAME test_mpfr_noopt COMMAND test_mpfr_noopt) set_tests_properties(test_mpfr_noopt PROPERTIES COST "2") if (INSTALL_CONTINUOUS_TESTERS) install( TARGETS test_mpfr test_mpfr_noopt DESTINATION "${INSTALL_BINDIR}" COMPONENT tester ) endif() add_executable(tester1 tester1.cpp) target_link_libraries(tester1 ${LIB_MPFR}) if (TLFLOAT_ENABLE_LIBQUADMATH) target_link_libraries(tester1 quadmath) endif() add_test(NAME tester1 COMMAND tester1) set_tests_properties(tester1 PROPERTIES COST "2") add_executable(tester1_noopt tester1.cpp) target_compile_definitions(tester1_noopt PRIVATE TLFLOAT_DISABLE_ARCH_OPTIMIZATION=1) target_link_libraries(tester1_noopt ${LIB_MPFR}) if (TLFLOAT_ENABLE_LIBQUADMATH) target_link_libraries(tester1_noopt quadmath) endif() add_test(NAME tester1_noopt COMMAND tester1_noopt) set_tests_properties(tester1_noopt PROPERTIES COST "2") endif() # if (LIB_MPFR AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_SYSTEM_PROCESSOR MATCHES "(arm64|aarch64)") AND BUILD_EXHAUSTIVE_TESTING) add_executable(test_exhaustive32 test_exhaustive32.cpp) target_link_libraries(test_exhaustive32 ${LIB_MPFR}) if (TLFLOAT_ENABLE_LIBQUADMATH) target_link_libraries(test_exhaustive32 quadmath) endif() add_executable(test_exhaustive_bf16_mpfr test_exhaustive_bf16_mpfr.cpp) target_link_libraries(test_exhaustive_bf16_mpfr ${LIB_MPFR}) if (OpenMP_CXX_FOUND) target_compile_options(test_exhaustive32 PRIVATE ${OpenMP_CXX_FLAGS}) target_link_options(test_exhaustive32 PRIVATE ${OpenMP_CXX_FLAGS}) target_include_directories(test_exhaustive32 PRIVATE ${OpenMP_CXX_INCLUDE_DIRS}) target_compile_options(test_exhaustive_bf16_mpfr PRIVATE ${OpenMP_CXX_FLAGS}) target_link_options(test_exhaustive_bf16_mpfr PRIVATE ${OpenMP_CXX_FLAGS}) target_include_directories(test_exhaustive_bf16_mpfr PRIVATE ${OpenMP_CXX_INCLUDE_DIRS}) endif() if (ENABLE_EXHAUSTIVE_TESTING) add_test(NAME test_exhaustive32 COMMAND test_exhaustive32) add_test(NAME test_exhaustive_bf16_mpfr COMMAND test_exhaustive_bf16_mpfr) endif() if (INSTALL_CONTINUOUS_TESTERS) install( TARGETS test_exhaustive32 test_exhaustive_bf16_mpfr DESTINATION "${INSTALL_BINDIR}" COMPONENT tester ) endif() endif() # if (TLFLOAT_COMPILER_SUPPORTS_ARM_FP16 AND LIB_MPFR AND BUILD_EXHAUSTIVE_TESTING) add_executable(test_exhaustive16 test_exhaustive16.cpp) target_link_libraries(test_exhaustive16 ${LIB_MPFR}) target_compile_options(test_exhaustive16 PRIVATE "-march=armv8.2-a+fp16") if (OpenMP_CXX_FOUND) target_compile_options(test_exhaustive16 PRIVATE ${OpenMP_CXX_FLAGS}) target_link_options(test_exhaustive16 PRIVATE ${OpenMP_CXX_FLAGS}) target_include_directories(test_exhaustive16 PRIVATE ${OpenMP_CXX_INCLUDE_DIRS}) endif() if (ENABLE_EXHAUSTIVE_TESTING) add_test(NAME test_exhaustive16 COMMAND test_exhaustive16) endif() if (INSTALL_CONTINUOUS_TESTERS) install( TARGETS test_exhaustive16 DESTINATION "${INSTALL_BINDIR}" COMPONENT tester ) endif() endif() if (TLFLOAT_COMPILER_SUPPORTS_BF16 AND BUILD_EXHAUSTIVE_TESTING) add_executable(test_exhaustive_bf16 test_exhaustive_bf16.cpp) if (OpenMP_CXX_FOUND) target_compile_options(test_exhaustive_bf16 PRIVATE ${OpenMP_CXX_FLAGS}) target_link_options(test_exhaustive_bf16 PRIVATE ${OpenMP_CXX_FLAGS}) target_include_directories(test_exhaustive_bf16 PRIVATE ${OpenMP_CXX_INCLUDE_DIRS}) endif() if (ENABLE_EXHAUSTIVE_TESTING) add_test(NAME test_exhaustive_bf16 COMMAND test_exhaustive_bf16) endif() if (INSTALL_CONTINUOUS_TESTERS) install( TARGETS test_exhaustive_bf16 DESTINATION "${INSTALL_BINDIR}" COMPONENT tester ) endif() endif() # if (BUILD_LIBS) add_library(test_octuple_obj OBJECT test_octuple.cpp) target_compile_definitions(test_octuple_obj PRIVATE TLFLOAT_NO_LIBSTDCXX=1) target_compile_options(test_octuple_obj PRIVATE ${NOEXCEPT_CXX_FLAGS}) set_target_properties(test_octuple_obj PROPERTIES LINKER_LANGUAGE C) add_executable(test_octuple test_octuple_dummy.c) target_link_libraries(test_octuple test_octuple_obj tlfloat ${LIBM}) set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") set_target_properties(test_octuple PROPERTIES LINKER_LANGUAGE C) add_test(NAME test_octuple COMMAND test_octuple) add_executable(test_capi test_capi.c) target_link_libraries(test_capi tlfloat ${LIBM}) if (TLFLOAT_ENABLE_LIBQUADMATH) target_link_libraries(test_capi quadmath) endif() set_target_properties(test_capi PROPERTIES LINKER_LANGUAGE C) add_test(NAME test_capi COMMAND test_capi) if(NOT (("${CMAKE_SYSTEM_NAME}" STREQUAL "Emscripten") OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "14.0.0"))) add_executable(test_cpp11api test_cpp11api.cpp) target_link_libraries(test_cpp11api tlfloat) set_target_properties(test_cpp11api PROPERTIES CXX_STANDARD 11) add_test(NAME test_cpp11api COMMAND test_cpp11api) set_tests_properties(test_cpp11api PROPERTIES COST "1") add_executable(test_cpp11api20 test_cpp11api.cpp) target_link_libraries(test_cpp11api20 tlfloat) add_test(NAME test_cpp11api20 COMMAND test_cpp11api20) set_tests_properties(test_cpp11api20 PROPERTIES COST "1") endif() endif() tlfloat-1.15.0/src/tester/test_arith.cpp000066400000000000000000001462531477036600700202370ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(TLFLOAT_ENABLE_LIBQUADMATH) #include #endif using namespace std; using namespace tlfloat; using namespace tlfloat::detail; static_assert(Float::flt_min() == FLT_MIN); static_assert(Float::flt_true_min() == FLT_TRUE_MIN); static_assert(Float::flt_max() == FLT_MAX); static_assert(Float::flt_epsilon() == FLT_EPSILON); static_assert(Double::flt_min() == DBL_MIN); static_assert(Double::flt_true_min() == DBL_TRUE_MIN); static_assert(Double::flt_max() == DBL_MAX); static_assert(Double::flt_epsilon() == DBL_EPSILON); static void check(const char* msg, double x, double y) { if (isnan(x) && isnan(y)) return; uint64_t u, v; memcpy((void *)&u, (void *)&x, sizeof(u)); memcpy((void *)&v, (void *)&y, sizeof(v)); if (u == v) return; cout << "NG " << msg << endl; printf("x : %.18g %016llx\n", x, (unsigned long long)u); printf("y : %.18g %016llx\n", y, (unsigned long long)v); exit(-1); } static void check(const char* msg, Octuple x, Octuple y) { check(msg, (double)x, (double)y); } int main(int argc, char **argv) { uint64_t niter = 100000; if (argc >= 2) niter = strtoull(argv[1], nullptr, 10); if (niter == 0) { #if defined(__GNUC__) cout << "Build " << __DATE__ << " " << __TIME__ << endl; #endif cout << "Testing continuously" << endl; } typedef UnpackedFloat ufloat; typedef UnpackedFloat, 11, 52> udouble; typedef UnpackedFloat xfloat; typedef UnpackedFloat, 0, 62> xdouble; shared_ptr rng = createPreferredRNG(); for(uint64_t i=0;niter == 0 || inextLT(65536) - 32768, i2 = (int)rng->nextLT(65536) - 32768; int it, ic; float f1 = rndf(rng), f2 = rndf(rng), f3 = rndf(rng); ufloat tlf1(f1), tlf2(f2), tlf3(f3); double d1 = rndd(rng), d2 = rndd(rng), d3 = rndd(rng); udouble tld1(d1), tld2(d2), tld3(d3); #ifdef ENABLE_QUAD quad q1 = rndq(rng), q2 = rndq(rng), q3 = rndq(rng); uquad tlq1(q1), tlq2(q2), tlq3(q3); #endif // float f4t = float(ufloat::faddsub(tlf1, tlf2, false)); float f4c = f1 + f2; if (!cmpf(f4t, f4c)) { cout << "f1: " << f1 << " : " << to_string_d(ufloat(f1 )) << endl; cout << "f2: " << f2 << " : " << to_string_d(ufloat(f2 )) << endl; cout << "+t: " << f4t << " : " << to_string_d(ufloat(f4t)) << endl; cout << "+c: " << f4c << " : " << to_string_d(ufloat(f4c)) << endl; cout << "NG" << endl; exit(-1); } float f5t = float(ufloat::faddsub(tlf1, tlf2, true)); float f5c = f1 - f2; if (!cmpf(f5t, f5c)) { cout << "f1: " << f1 << " : " << to_string_d(ufloat(f1 )) << endl; cout << "f2: " << f2 << " : " << to_string_d(ufloat(f2 )) << endl; cout << "-t: " << f5t << " : " << to_string_d(ufloat(f5t)) << endl; cout << "-c: " << f5c << " : " << to_string_d(ufloat(f5c)) << endl; cout << "NG" << endl; exit(-1); } float f6t = float(ufloat::fmul(tlf1, tlf2)); float f6c = f1 * f2; if (!cmpf(f6t, f6c)) { cout << "f1: " << f1 << " : " << to_string_d(ufloat(f1 )) << endl; cout << "f2: " << f2 << " : " << to_string_d(ufloat(f2 )) << endl; cout << "*t: " << f6t << " : " << to_string_d(ufloat(f6t)) << endl; cout << "*c: " << f6c << " : " << to_string_d(ufloat(f6c)) << endl; cout << "NG" << endl; exit(-1); } float f7t = float(ufloat::fdiv(tlf1, tlf2)); float f7c = f1 / f2; if (!cmpf(f7t, f7c)) { cout << "f1: " << f1 << " : " << to_string_d(ufloat(f1 )) << endl; cout << "f2: " << f2 << " : " << to_string_d(ufloat(f2 )) << endl; cout << "/t: " << f7t << " : " << to_string_d(ufloat(f7t)) << endl; cout << "/c: " << f7c << " : " << to_string_d(ufloat(f7c)) << endl; cout << "NG" << endl; exit(-1); } if ((tlf1 == tlf2) != (f1 == f2)) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1 )) << endl; cout << "f2 : " << f2 << " : " << to_string_d(ufloat(f2 )) << endl; cout << "==t: " << (tlf1 == tlf2) << endl; cout << "==c: " << (f1 == f2) << endl; cout << "NG" << endl; exit(-1); } if ((tlf1 != tlf2) != (f1 != f2)) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1 )) << endl; cout << "f2 : " << f2 << " : " << to_string_d(ufloat(f2 )) << endl; cout << "!=t: " << (tlf1 != tlf2) << endl; cout << "!=c: " << (f1 != f2) << endl; cout << "NG" << endl; exit(-1); } if ((tlf1 < tlf2) != (f1 < f2)) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1 )) << endl; cout << "f2 : " << f2 << " : " << to_string_d(ufloat(f2 )) << endl; cout << "< t: " << (tlf1 < tlf2) << endl; cout << "< c: " << (f1 < f2) << endl; cout << "NG" << endl; exit(-1); } if ((tlf1 > tlf2) != (f1 > f2)) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1 )) << endl; cout << "f2 : " << f2 << " : " << to_string_d(ufloat(f2 )) << endl; cout << "> t: " << (tlf1 > tlf2) << endl; cout << "> c: " << (f1 > f2) << endl; cout << "NG" << endl; exit(-1); } if ((tlf1 <= tlf2) != (f1 <= f2)) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1 )) << endl; cout << "f2 : " << f2 << " : " << to_string_d(ufloat(f2 )) << endl; cout << "<=t: " << (tlf1 <= tlf2) << endl; cout << "<=c: " << (f1 <= f2) << endl; cout << "NG" << endl; exit(-1); } if ((tlf1 >= tlf2) != (f1 >= f2)) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1 )) << endl; cout << "f2 : " << f2 << " : " << to_string_d(ufloat(f2 )) << endl; cout << ">=t: " << (tlf1 >= tlf2) << endl; cout << ">=c: " << (f1 >= f2) << endl; cout << "NG" << endl; exit(-1); } #if defined(__GLIBC__) || defined(FP_FAST_FMA) float f8t = float(ufloat::fma(tlf1, tlf2, tlf3)); float f8c = fmaf(f1, f2, f3); if (!cmpf(f8t, f8c)) { cout << "f1: " << f1 << " : " << to_string_d(ufloat(f1 )) << endl; cout << "f2: " << f2 << " : " << to_string_d(ufloat(f2 )) << endl; cout << "f3: " << f3 << " : " << to_string_d(ufloat(f3 )) << endl; cout << "ft: " << f8t << " : " << to_string_d(ufloat(f8t)) << endl; cout << "fc: " << f8c << " : " << to_string_d(ufloat(f8c)) << endl; cout << "NG" << endl; exit(-1); } #endif float f9t = float(tld1.cast((const ufloat *)nullptr)); float f9c = d1; if (!cmpf(f9t, f9c)) { cout << "d1: " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "ct: " << f9t << " : " << to_string_d(ufloat(f9t)) << endl; cout << "cc: " << f9c << " : " << to_string_d(ufloat(f9c)) << endl; cout << "NG" << endl; exit(-1); } #ifdef ENABLE_QUAD float fat = float(tlq1.cast((const ufloat *)nullptr)); float fac = q1; if (!cmpf(fat, fac)) { cout << "q1: " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "ct: " << fat << " : " << to_string_d(ufloat(fat)) << endl; cout << "cc: " << fac << " : " << to_string_d(ufloat(fac)) << endl; cout << "NG" << endl; exit(-1); } #endif if ((i & 31) == 0 && fabs(f1) > 1e-30 && fabs(f1) < 1e+30) { float fbt = (float)Float(to_string(Float(tlf1), 9).c_str()); float fbc = (float)tlf1; if (!cmpf(fbt, fbc, 7)) { cout << "f1: " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "s : " << to_string(Float(tlf1), 9) << endl; cout << "ct: " << fbt << " : " << to_string_d(ufloat(fbt)) << endl; cout << "cc: " << fbc << " : " << to_string_d(ufloat(fbc)) << endl; cout << "NG" << endl; exit(-1); } } float fc, ft, fn = f1; fc = truncf(fn); ft = (float)trunc(Float(fn).getUnpacked()); if (!cmpf(fc, ft)) { printf("\ntruncf\nfn = %.10g, fc = %.10g, ft = %.10g\n", fn, fc, ft); exit(-1); } fc = floorf(fn); ft = (float)floor(Float(fn).getUnpacked()); if (!cmpf(fc, ft)) { printf("\nfloorf\nfn = %.10g, fc = %.10g, ft = %.10g\n", fn, fc, ft); exit(-1); } fc = ceilf(fn); ft = (float)ceil(Float(fn).getUnpacked()); if (!cmpf(fc, ft)) { printf("\nceilf\nfn = %.10g, fc = %.10g, ft = %.10g\n", fn, fc, ft); exit(-1); } fc = roundf(fn); ft = (float)round(Float(fn).getUnpacked()); if (!cmpf(fc, ft)) { printf("\nroundf\nfn = %.10g, fc = %.10g, ft = %.10g\n", fn, fc, ft); exit(-1); } fc = rintf(fn); ft = (float)rint(Float(fn).getUnpacked()); if (!cmpf(fc, ft)) { printf("\nrintf\nfn = %.10g, fc = %.10g, ft = %.10g\n", fn, fc, ft); exit(-1); } // if ((bool)isnan(f1) != (bool)isnan(Float(f1))) { printf("\nisnan f1 = %.10g\n", f1); exit(-1); } if ((bool)isinf(f1) != (bool)isinf(Float(f1))) { printf("\nisinf f1 = %.10g, c = %d, t = %d\n", f1, isinf(f1), isinf(Float(f1))); exit(-1); } if ((bool)finite__(f1) != (bool)finite(Float(f1))) { printf("\nfinite f1 = %.10g\n", f1); exit(-1); } #ifndef __APPLE__ if (!cmpf(ldexpf(f1, i1), (float)ldexp(Float(f1), i1))) { printf("\nldexpf f1 = %.10g, i1 = %d\n", f1, i1); printf("c = %.10g, t = %.10g\n", ldexpf(f1, i1), (float)ldexp(Float(f1), i1)); exit(-1); } #endif if (!cmpf(frexpf(f1, &ic), (float)frexp(Float(f1), &it)) || (!isnan(f1) && !isinf(f1) && ic != it)) { printf("\nfrexpf f1 = %.10g, it = %d, ic = %d\n", f1, it, ic); printf("c = %.10g, t = %.10g\n", frexpf(f1, &ic), (float)frexp(Float(f1), &it)); exit(-1); } // double d1t = double(tlf1.cast((const udouble *)nullptr)); double d1c = f1; if (!cmpd(d1t, d1c)) { cout << "cast float to double" << endl; cout << "f1: " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "ct: " << d1t << " : " << to_string_d(udouble(d1t)) << endl; cout << "cc: " << d1c << " : " << to_string_d(udouble(d1c)) << endl; cout << "NG" << endl; exit(-1); } if (f1 >= 0 && f1 < ldexp(1, 16) && tlf1.castToInt((const uint16_t *)nullptr) != uint16_t(float(tlf1))) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "ust: " << d1t << " : " << tlf1.castToInt((const uint16_t *)nullptr) << endl; cout << "usc: " << d1c << " : " << uint16_t(float(tlf1)) << endl; cout << "NG" << endl; exit(-1); } if (f1 >= -ldexp(1, 15) && f1 < ldexp(1, 15) && tlf1.castToInt((const int16_t *)nullptr) != int16_t(float(tlf1))) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "sst: " << d1t << " : " << tlf1.castToInt((const int16_t *)nullptr) << endl; cout << "ssc: " << d1c << " : " << int16_t(float(tlf1)) << endl; cout << "NG" << endl; exit(-1); } if (f1 >= 0 && f1 < ldexp(1, 32) && tlf1.castToInt((const uint32_t *)nullptr) != uint32_t(float(tlf1))) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "uit: " << tlf1.castToInt((const uint32_t *)nullptr) << endl; cout << "uic: " << uint32_t(float(tlf1)) << endl; cout << "NG" << endl; exit(-1); } if (f1 >= -ldexp(1, 31) && f1 < ldexp(1, 31) && tlf1.castToInt((const int32_t *)nullptr) != int32_t(float(tlf1))) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "sit: " << tlf1.castToInt((const int32_t *)nullptr) << endl; cout << "sic: " << int32_t(float(tlf1)) << endl; cout << "NG" << endl; exit(-1); } if (f1 >= 0 && f1 < ldexp(1, 64) && tlf1.castToInt((const uint64_t *)nullptr) != uint64_t(float(tlf1))) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "ult: " << tlf1.castToInt((const uint64_t *)nullptr) << endl; cout << "ulc: " << uint64_t(float(tlf1)) << endl; cout << "NG" << endl; exit(-1); } if (f1 >= -ldexp(1, 63) && f1 < ldexp(1, 63) && tlf1.castToInt((const int64_t *)nullptr) != int64_t(float(tlf1))) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "slt: " << tlf1.castToInt((const int64_t *)nullptr) << endl; cout << "slc: " << int64_t(float(tlf1)) << endl; cout << "NG" << endl; exit(-1); } #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 if (f1 >= 0 && f1 < ldexp(1, 128) && tlf1.castToInt((const BigUInt<7> *)nullptr) != UINT128(float(tlf1))) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "u128t: " << tlf1.castToInt((const BigUInt<7> *)nullptr) << endl; cout << "u128c: " << UINT128(float(tlf1)) << endl; cout << "NG" << endl; exit(-1); } if (f1 >= -ldexp(1, 127) && f1 < ldexp(1, 127) && tlf1.castToInt((const BigInt<7> *)nullptr) != INT128(float(tlf1))) { cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "s128t: " << tlf1.castToInt((const BigInt<7> *)nullptr) << endl; cout << "s128c: " << INT128(float(tlf1)) << endl; cout << "NG" << endl; exit(-1); } #endif // double d4t = double(udouble::faddsub(tld1, tld2, false)); double d4c = d1 + d2; if (!cmpd(d4t, d4c)) { cout << "d1: " << d1 << " : " << to_string_d(udouble(d1 )) << endl; cout << "d2: " << d2 << " : " << to_string_d(udouble(d2 )) << endl; cout << "+t: " << d4t << " : " << to_string_d(udouble(d4t)) << endl; cout << "+c: " << d4c << " : " << to_string_d(udouble(d4c)) << endl; cout << "NG" << endl; exit(-1); } double d5t = double(udouble::faddsub(tld1, tld2, true)); double d5c = d1 - d2; if (!cmpd(d5t, d5c)) { cout << "d1: " << d1 << " : " << to_string_d(udouble(d1 )) << endl; cout << "d2: " << d2 << " : " << to_string_d(udouble(d2 )) << endl; cout << "-t: " << d5t << " : " << to_string_d(udouble(d5t)) << endl; cout << "-c: " << d5c << " : " << to_string_d(udouble(d5c)) << endl; cout << "NG" << endl; exit(-1); } double d6t = double(udouble::fmul(tld1, tld2)); double d6c = d1 * d2; if (!cmpd(d6t, d6c)) { cout << "d1: " << d1 << " : " << to_string_d(udouble(d1 )) << endl; cout << "d2: " << d2 << " : " << to_string_d(udouble(d2 )) << endl; cout << "*t: " << d6t << " : " << to_string_d(udouble(d6t)) << endl; cout << "*c: " << d6c << " : " << to_string_d(udouble(d6c)) << endl; cout << "NG" << endl; exit(-1); } double d7t = double(udouble::fdiv(tld1, tld2)); double d7c = d1 / d2; if (!cmpd(d7t, d7c)) { cout << "d1: " << d1 << " : " << to_string_d(udouble(d1 )) << endl; cout << "d2: " << d2 << " : " << to_string_d(udouble(d2 )) << endl; cout << "/t: " << d7t << " : " << to_string_d(udouble(d7t)) << endl; cout << "/c: " << d7c << " : " << to_string_d(udouble(d7c)) << endl; cout << "NG" << endl; exit(-1); } #if defined(__GLIBC__) || defined(FP_FAST_FMA) double d8t = double(udouble::fma(tld1, tld2, tld3)); double d8c = fma(d1, d2, d3); if (!cmpd(d8t, d8c)) { cout << "d1: " << d1 << " : " << to_string_d(udouble(d1 )) << endl; cout << "d2: " << d2 << " : " << to_string_d(udouble(d2 )) << endl; cout << "d3: " << d3 << " : " << to_string_d(udouble(d3 )) << endl; cout << "ft: " << d8t << " : " << to_string_d(udouble(d8t)) << endl; cout << "fc: " << d8c << " : " << to_string_d(udouble(d8c)) << endl; cout << "NG" << endl; exit(-1); } #endif #ifdef ENABLE_QUAD double d9t = double(tlq1.cast((const udouble *)nullptr)); double d9c = q1; if (!cmpf(d9t, d9c)) { cout << "cast double to quad" << endl; cout << "q1: " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "ct: " << d9t << " : " << to_string_d(udouble(d9t)) << endl; cout << "cc: " << d9c << " : " << to_string_d(udouble(d9c)) << endl; cout << "NG" << endl; exit(-1); } #endif if (d1 >= 0 && d1 < ldexp(1, 16) && tld1.castToInt((const uint16_t *)nullptr) != uint16_t(double(tld1))) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "ust: " << tld1.castToInt((const uint16_t *)nullptr) << endl; cout << "usc: " << uint16_t(double(tld1)) << endl; cout << "NG" << endl; exit(-1); } if (d1 >= -ldexp(1, 15) && d1 < ldexp(1, 15) && tld1.castToInt((const int16_t *)nullptr) != int16_t(double(tld1))) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "sst: " << tld1.castToInt((const int16_t *)nullptr) << endl; cout << "ssc: " << int16_t(double(tld1)) << endl; cout << "NG" << endl; exit(-1); } if (d1 >= 0 && d1 < ldexp(1, 32) && tld1.castToInt((const uint32_t *)nullptr) != uint32_t(double(tld1))) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "uit: " << tld1.castToInt((const uint32_t *)nullptr) << endl; cout << "uic: " << uint32_t(double(tld1)) << endl; cout << "NG" << endl; exit(-1); } if (d1 >= -ldexp(1, 31) && d1 < ldexp(1, 31) && tld1.castToInt((const int32_t *)nullptr) != int32_t(double(tld1))) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "sit: " << tld1.castToInt((const int32_t *)nullptr) << endl; cout << "sic: " << int32_t(double(tld1)) << endl; cout << "NG" << endl; exit(-1); } if (d1 >= 0 && d1 < ldexp(1, 64) && tld1.castToInt((const uint64_t *)nullptr) != uint64_t(double(tld1))) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "ult: " << tld1.castToInt((const uint64_t *)nullptr) << endl; cout << "ulc: " << uint64_t(double(tld1)) << endl; cout << "NG" << endl; exit(-1); } if (d1 >= -ldexp(1, 63) && d1 < ldexp(1, 63) && tld1.castToInt((const int64_t *)nullptr) != int64_t(double(tld1))) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "slt: " << tld1.castToInt((const int64_t *)nullptr) << endl; cout << "slc: " << int64_t(double(tld1)) << endl; cout << "NG" << endl; exit(-1); } #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 if (d1 >= 0 && d1 < ldexp(1, 128) && tld1.castToInt((const BigUInt<7> *)nullptr) != UINT128(double(tld1))) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "u128t: " << tld1.castToInt((const BigUInt<7> *)nullptr) << endl; cout << "u128c: " << UINT128(double(tld1)) << endl; cout << "NG" << endl; exit(-1); } if (d1 >= -ldexp(1, 127) && d1 < ldexp(1, 127) && tld1.castToInt((const BigInt<7> *)nullptr) != INT128(double(tld1))) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "s128t: " << tld1.castToInt((const BigInt<7> *)nullptr) << endl; cout << "s128c: " << INT128(double(tld1)) << endl; cout << "NG" << endl; exit(-1); } #endif if ((tld1 == tld2) != (d1 == d2)) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1 )) << endl; cout << "d2 : " << d2 << " : " << to_string_d(udouble(d2 )) << endl; cout << "==t: " << (tld1 == tld2) << endl; cout << "==c: " << (d1 == d2) << endl; cout << "NG" << endl; exit(-1); } if ((tld1 != tld2) != (d1 != d2)) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1 )) << endl; cout << "d2 : " << d2 << " : " << to_string_d(udouble(d2 )) << endl; cout << "!=t: " << (tld1 != tld2) << endl; cout << "!=c: " << (d1 != d2) << endl; cout << "NG" << endl; exit(-1); } if ((tld1 < tld2) != (d1 < d2)) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1 )) << endl; cout << "d2 : " << d2 << " : " << to_string_d(udouble(d2 )) << endl; cout << "< t: " << (tld1 < tld2) << endl; cout << "< c: " << (d1 < d2) << endl; cout << "NG" << endl; exit(-1); } if ((tld1 > tld2) != (d1 > d2)) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1 )) << endl; cout << "d2 : " << d2 << " : " << to_string_d(udouble(d2 )) << endl; cout << "> t: " << (tld1 > tld2) << endl; cout << "> c: " << (d1 > d2) << endl; cout << "NG" << endl; exit(-1); } if ((tld1 <= tld2) != (d1 <= d2)) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1 )) << endl; cout << "d2 : " << d2 << " : " << to_string_d(udouble(d2 )) << endl; cout << "<=t: " << (tld1 <= tld2) << endl; cout << "<=c: " << (d1 <= d2) << endl; cout << "NG" << endl; exit(-1); } if ((tld1 >= tld2) != (d1 >= d2)) { cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1 )) << endl; cout << "d2 : " << d2 << " : " << to_string_d(udouble(d2 )) << endl; cout << ">=t: " << (tld1 >= tld2) << endl; cout << ">=c: " << (d1 >= d2) << endl; cout << "NG" << endl; exit(-1); } if ((i & 31) == 0 && fabs(d1) > 1e-250 && fabs(d1) < 1e+250) { double dbt = (double)Double(to_string(Double(tld1), 18).c_str()); double dbc = (double)tld1; if (!cmpd(dbt, dbc, 7)) { cout << "d1: " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "s : " << to_string(Double(tld1), 18) << endl; cout << "ct: " << dbt << " : " << to_string_d(udouble(dbt)) << endl; cout << "cc: " << dbc << " : " << to_string_d(udouble(dbc)) << endl; cout << "NG" << endl; exit(-1); } } double dc, dt, dn = d1; dc = trunc(dn); dt = (double)trunc(Double(dn).getUnpacked()); if (!cmpd(dc, dt)) { printf("\ntrunc\ndn = %.18lg, dc = %.18lg, dt = %.18lg\n", dn, dc, dt); exit(-1); } dc = floor(dn); dt = (double)floor(Double(dn).getUnpacked()); if (!cmpd(dc, dt)) { printf("\nfloor\ndn = %.18lg, dc = %.18lg, dt = %.18lg\n", dn, dc, dt); exit(-1); } dc = ceil(dn); dt = (double)ceil(Double(dn).getUnpacked()); if (!cmpd(dc, dt)) { printf("\nceil\ndn = %.18lg, dc = %.18lg, dt = %.18lg\n", dn, dc, dt); exit(-1); } dc = round(dn); dt = (double)round(Double(dn).getUnpacked()); if (!cmpd(dc, dt)) { printf("\nround\ndn = %.18lg, dc = %.18lg, dt = %.18lg\n", dn, dc, dt); exit(-1); } dc = rint(dn); dt = (double)rint(Double(dn).getUnpacked()); if (!cmpd(dc, dt)) { printf("\nrint\ndn = %.18lg, dc = %.18lg, dt = %.18lg\n", dn, dc, dt); exit(-1); } // if ((bool)isnan(d1) != (bool)isnan(Double(d1))) { printf("\nisnan d1 = %.10g\n", d1); exit(-1); } if ((bool)isinf(d1) != (bool)isinf(Double(d1))) { printf("\nisinf d1 = %.10g\n", d1); exit(-1); } if ((bool)finite__(d1) != (bool)finite(Double(d1))) { printf("\nfinite d1 = %.10g\n", d1); exit(-1); } if (!cmpfpclass(fpclassify(d1), fpclassify(Double(d1)))) { printf("\nfpclassify d1 = %.10g, c = %d, t = %d\n", d1, fpclassify(d1), fpclassify(Double(d1))); cout << to_string_d(Double(d1).getUnpacked()) << endl; exit(-1); } #ifndef __APPLE__ if (!cmpd(ldexp(d1, i1), (double)ldexp(Double(d1), i1))) { printf("\nldexp d1 = %.18lg, i1 = %d\n", d1, i1); exit(-1); } #endif if (!cmpd(frexp(d1, &ic), (double)frexp(Double(d1), &it)) || (!isnan(d1) && !isinf(d1) && ic != it)) { printf("\nfrexp d1 = %.10g, it = %d, ic = %d\n", d1, it, ic); printf("c = %.10g, t = %.10g\n", frexp(d1, &ic), (double)frexp(Double(d1), &it)); exit(-1); } // #ifdef ENABLE_QUAD quad q1t = quad(tlf1.cast((const uquad *)nullptr)); quad q1c = f1; if (!cmpq(q1t, q1c)) { cout << "cast from float to quad" << endl; cout << "f1: " << q1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "ct: " << q1t << " : " << to_string_d(uquad(q1t)) << endl; cout << "cc: " << q1c << " : " << to_string_d(uquad(q1c)) << endl; cout << "NG" << endl; exit(-1); } q1t = quad(tld1.cast((const uquad *)nullptr)); q1c = d1; if (!cmpq(q1t, q1c)) { cout << "cast from double to quad" << endl; cout << "d1: " << q1 << " : " << to_string_d(udouble(d1)) << endl; cout << "ct: " << q1t << " : " << to_string_d(uquad(q1t)) << endl; cout << "cc: " << q1c << " : " << to_string_d(uquad(q1c)) << endl; cout << "NG" << endl; exit(-1); } if (q1 >= 0 && q1 < ldexp(1, 16) && tlq1.castToInt((const uint16_t *)nullptr) != uint16_t(quad(tlq1))) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "ust: " << q1t << " : " << tlq1.castToInt((const uint16_t *)nullptr) << endl; cout << "usc: " << q1c << " : " << uint16_t(quad(tlq1)) << endl; cout << "NG" << endl; exit(-1); } if (q1 >= -ldexp(1, 15) && q1 < ldexp(1, 15) && tlq1.castToInt((const int16_t *)nullptr) != int16_t(quad(tlq1))) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "sst: " << q1t << " : " << tlq1.castToInt((const int16_t *)nullptr) << endl; cout << "ssc: " << q1c << " : " << int16_t(quad(tlq1)) << endl; cout << "NG" << endl; exit(-1); } if (q1 >= 0 && q1 < ldexp(1, 32) && tlq1.castToInt((const uint32_t *)nullptr) != uint32_t(quad(tlq1))) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "uit: " << tlq1.castToInt((const uint32_t *)nullptr) << endl; cout << "uic: " << uint32_t(quad(tlq1)) << endl; cout << "NG" << endl; exit(-1); } if (q1 >= -ldexp(1, 31) && q1 < ldexp(1, 31) && tlq1.castToInt((const int32_t *)nullptr) != int32_t(quad(tlq1))) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "sit: " << tlq1.castToInt((const int32_t *)nullptr) << endl; cout << "sic: " << int32_t(quad(tlq1)) << endl; cout << "NG" << endl; exit(-1); } if (q1 >= 0 && q1 < ldexp(1, 64) && tlq1.castToInt((const uint64_t *)nullptr) != uint64_t(quad(tlq1))) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "ult: " << tlq1.castToInt((const uint64_t *)nullptr) << endl; cout << "ulc: " << uint64_t(quad(tlq1)) << endl; cout << "NG" << endl; exit(-1); } if (q1 >= -ldexp(1, 63) && q1 < ldexp(1, 63) && tlq1.castToInt((const int64_t *)nullptr) != int64_t(quad(tlq1))) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "slt: " << tlq1.castToInt((const int64_t *)nullptr) << endl; cout << "slc: " << int64_t(quad(tlq1)) << endl; cout << "NG" << endl; exit(-1); } #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 if (q1 >= 0 && q1 < ldexp(1, 128) && tlq1.castToInt((const BigUInt<7> *)nullptr) != UINT128(quad(tlq1))) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "u128t: " << tlq1.castToInt((const BigUInt<7> *)nullptr) << endl; cout << "u128c: " << UINT128(quad(tlq1)) << endl; cout << "NG" << endl; exit(-1); } if (q1 >= -ldexp(1, 127) && q1 < ldexp(1, 127) && tlq1.castToInt((const BigInt<7> *)nullptr) != INT128(quad(tlq1))) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "s128t: " << tlq1.castToInt((const BigInt<7> *)nullptr) << endl; cout << "s128c: " << INT128(quad(tlq1)) << endl; cout << "NG" << endl; exit(-1); } #endif // quad q4t = quad(uquad::faddsub(tlq1, tlq2, false)); quad q4c = q1 + q2; if (!cmpq(d4t, d4c)) { cout << "q1: " << q1 << " : " << to_string_d(uquad(q1 )) << endl; cout << "q2: " << q2 << " : " << to_string_d(uquad(q2 )) << endl; cout << "+t: " << d4t << " : " << to_string_d(uquad(q4t)) << endl; cout << "+c: " << d4c << " : " << to_string_d(uquad(q4c)) << endl; cout << "NG" << endl; exit(-1); } quad q5t = quad(uquad::faddsub(tlq1, tlq2, true)); quad q5c = q1 - q2; if (!cmpq(d5t, d5c)) { cout << "q1: " << q1 << " : " << to_string_d(uquad(q1 )) << endl; cout << "q2: " << q2 << " : " << to_string_d(uquad(q2 )) << endl; cout << "-t: " << d5t << " : " << to_string_d(uquad(q5t)) << endl; cout << "-c: " << d5c << " : " << to_string_d(uquad(q5c)) << endl; cout << "NG" << endl; exit(-1); } quad q6t = quad(uquad::fmul(tlq1, tlq2)); quad q6c = q1 * q2; if (!cmpq(d6t, d6c)) { cout << "q1: " << q1 << " : " << to_string_d(uquad(q1 )) << endl; cout << "q2: " << q2 << " : " << to_string_d(uquad(q2 )) << endl; cout << "*t: " << d6t << " : " << to_string_d(uquad(q6t)) << endl; cout << "*c: " << d6c << " : " << to_string_d(uquad(q6c)) << endl; cout << "NG" << endl; exit(-1); } quad q7t = quad(uquad::fdiv(tlq1, tlq2)); quad q7c = q1 / q2; if (!cmpq(d7t, d7c)) { cout << "q1: " << q1 << " : " << to_string_d(uquad(q1 )) << endl; cout << "q2: " << q2 << " : " << to_string_d(uquad(q2 )) << endl; cout << "/t: " << d7t << " : " << to_string_d(uquad(q7t)) << endl; cout << "/c: " << d7c << " : " << to_string_d(uquad(q7c)) << endl; cout << "NG" << endl; exit(-1); } quad q8t = quad(uquad::fma(tlq1, tlq2, tlq3)); quad q8c = fmaq(q1, q2, q3); if (!cmpq(d8t, d8c)) { cout << "q1: " << q1 << " : " << to_string_d(uquad(q1 )) << endl; cout << "q2: " << q2 << " : " << to_string_d(uquad(q2 )) << endl; cout << "q3: " << q3 << " : " << to_string_d(uquad(q3 )) << endl; cout << "ft: " << d8t << " : " << to_string_d(uquad(q8t)) << endl; cout << "fc: " << d8c << " : " << to_string_d(uquad(q8c)) << endl; cout << "NG" << endl; exit(-1); } if ((tlq1 == tlq2) != (q1 == q2)) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1 )) << endl; cout << "q2 : " << q2 << " : " << to_string_d(uquad(q2 )) << endl; cout << "==t: " << (tlq1 == tlq2) << endl; cout << "==c: " << (q1 == q2) << endl; cout << "NG" << endl; exit(-1); } if ((tlq1 != tlq2) != (q1 != q2)) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1 )) << endl; cout << "q2 : " << q2 << " : " << to_string_d(uquad(q2 )) << endl; cout << "!=t: " << (tlq1 != tlq2) << endl; cout << "!=c: " << (q1 != q2) << endl; cout << "NG" << endl; exit(-1); } if ((tlq1 < tlq2) != (q1 < q2)) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1 )) << endl; cout << "q2 : " << q2 << " : " << to_string_d(uquad(q2 )) << endl; cout << "< t: " << (tlq1 < tlq2) << endl; cout << "< c: " << (q1 < q2) << endl; cout << "NG" << endl; exit(-1); } if ((tlq1 > tlq2) != (q1 > q2)) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1 )) << endl; cout << "q2 : " << q2 << " : " << to_string_d(uquad(q2 )) << endl; cout << "> t: " << (tlq1 > tlq2) << endl; cout << "> c: " << (q1 > q2) << endl; cout << "NG" << endl; exit(-1); } if ((tlq1 <= tlq2) != (q1 <= q2)) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1 )) << endl; cout << "q2 : " << q2 << " : " << to_string_d(uquad(q2 )) << endl; cout << "<=t: " << (tlq1 <= tlq2) << endl; cout << "<=c: " << (q1 <= q2) << endl; cout << "NG" << endl; exit(-1); } if ((tlq1 >= tlq2) != (q1 >= q2)) { cout << "q1 : " << q1 << " : " << to_string_d(uquad(q1 )) << endl; cout << "q2 : " << q2 << " : " << to_string_d(uquad(q2 )) << endl; cout << ">=t: " << (tlq1 >= tlq2) << endl; cout << ">=c: " << (q1 >= q2) << endl; cout << "NG" << endl; exit(-1); } static const quad qp1k = (quad)(0x1p+512) * (quad)(0x1p+512), qn1k = (quad)(0x1p-1024); if ((i & 3) == 0) { { int c = ilogbq(q1), t = ilogb(Quad(q1)); if (!(t == c) && !(t == TLFLOAT_FP_ILOGB0 && c == FP_ILOGB0) && !(t == TLFLOAT_FP_ILOGBNAN && c == FP_ILOGBNAN)) { cout << "ilogb" << endl; cout << "q1: " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "c : " << c << endl; cout << "t : " << t << endl; cout << "NG" << endl; exit(-1); } } if (qn1k * 1e-300 < q1 && q1 < qp1k * 1e+300 && !cmpq((quad)sqrt(Quad(q1)), sqrtq(q1), 1)) { cout << "sqrtq" << endl; cout << "q1: " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "c : " << sqrtq(q1) << " : " << to_string_d(uquad(sqrtq(q1))) << endl; cout << "t : " << sqrt(Quad(q1)) << " : " << to_string_d(uquad((quad)sqrt(Quad(q1)))) << endl; cout << "NG" << endl; exit(-1); } Octuple o1 = Quad(q1); Octuple o2 = sqrt(o1); if (!cmpq((quad)(Quad)sqrt(o1), (quad)(Quad)o2)) { cout << "sqrtq vs sqrto" << endl; cout << "q1: " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "c : " << (quad)(Quad)o2 << " : " << to_string_d(Quad(o2).getUnpacked()) << endl; cout << "t : " << sqrt(Quad(tlq1)) << " : " << to_string_d(sqrt(Quad(tlq1)).getUnpacked()) << endl; cout << "NG" << endl; exit(-1); } } if ((i & 31) == 0 && fabsq(q1) > qn1k * qn1k * qn1k * qn1k && fabsq(q1) < qp1k * qp1k * qp1k * qp1k) { quad qbt = (quad)Quad(to_string(Quad(tlq1), 36).c_str()); quad qbc = (quad)tlq1; if (!cmpq(qbt, qbc, 7)) { cout << "q1: " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "s : " << to_string(Quad(tlq1), 36) << endl; cout << "ct: " << qbt << " : " << to_string_d(uquad(qbt)) << endl; cout << "cc: " << qbc << " : " << to_string_d(uquad(qbc)) << endl; cout << "NG" << endl; exit(-1); } } quad qc, qt, qn = q1; qc = truncq(qn); qt = (quad)trunc(Quad(qn).getUnpacked()); if (!cmpq(qc, qt)) { printf("\ntruncq\n"); cout << "q1: " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "s : " << to_string(Quad(tlq1), 36) << endl; cout << "ct: " << qt << " : " << to_string_d(uquad(qt)) << endl; cout << "cc: " << qc << " : " << to_string_d(uquad(qc)) << endl; cout << "NG" << endl; exit(-1); } qc = floorq(qn); qt = (quad)floor(Quad(qn).getUnpacked()); if (!cmpq(qc, qt)) { printf("\nfloorq\n"); cout << "q1: " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "s : " << to_string(Quad(tlq1), 36) << endl; cout << "ct: " << qt << " : " << to_string_d(uquad(qt)) << endl; cout << "cc: " << qc << " : " << to_string_d(uquad(qc)) << endl; cout << "NG" << endl; exit(-1); } qc = ceilq(qn); qt = (quad)ceil(Quad(qn).getUnpacked()); if (!cmpq(qc, qt)) { printf("\nceilq\n"); cout << "q1: " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "s : " << to_string(Quad(tlq1), 36) << endl; cout << "ct: " << qt << " : " << to_string_d(uquad(qt)) << endl; cout << "cc: " << qc << " : " << to_string_d(uquad(qc)) << endl; cout << "NG" << endl; exit(-1); } qc = roundq(qn); qt = (quad)round(Quad(qn).getUnpacked()); if (!cmpq(qc, qt)) { printf("\nroundq\n"); cout << "q1: " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "s : " << to_string(Quad(tlq1), 36) << endl; cout << "ct: " << qt << " : " << to_string_d(uquad(qt)) << endl; cout << "cc: " << qc << " : " << to_string_d(uquad(qc)) << endl; cout << "NG" << endl; exit(-1); } qc = rintq(qn); qt = (quad)rint(Quad(qn).getUnpacked()); if (!cmpq(qc, qt)) { printf("\nrintq\n"); cout << "q1: " << q1 << " : " << to_string_d(uquad(q1)) << endl; cout << "s : " << to_string(Quad(tlq1), 36) << endl; cout << "ct: " << qt << " : " << to_string_d(uquad(qt)) << endl; cout << "cc: " << qc << " : " << to_string_d(uquad(qc)) << endl; cout << "NG" << endl; exit(-1); } // if ((bool)isnanq(q1) != (bool)isnan(Quad(q1))) { printf("\nisnan q1 = %.10g\n", (double)q1); exit(-1); } if ((bool)isinfq(q1) != (bool)isinf(Quad(q1))) { printf("\nisinf q1 = %.10g\n", (double)q1); exit(-1); } if ((bool)finiteq(q1) != (bool)finite(Quad(q1))) { printf("\nfinite q1 = %.10g\n", (double)q1); exit(-1); } #ifdef QUADMATH_H if (!cmpfpclass(fpclassifyq(q1), fpclassify(Quad(q1)))) { printf("\nfpclassify q1 = %.10g\n", (double)q1); exit(-1); } if (!cmpq(ldexpq(q1, i1), (quad)ldexp(Quad(q1), i1))) { printf("\nldexpq q1 = %.18lg, i1 = %d\n", (double)q1, i1); exit(-1); } #endif #endif // #ifdef ENABLE_QUAD // xfloat xf1 = tlf1.cast((const xfloat*)0); xfloat xf2 = tlf2.cast((const xfloat*)0); xfloat xf3 = tlf3.cast((const xfloat*)0); if (!cmpf((float)xf1.cast((const ufloat*)0), f1)) { cout << "cast between xfloat and ufloat" << endl; cout << "f1: " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "t1: " << to_string_d(xf1) << endl; cout << "t2: " << (float)xf1.cast((const ufloat*)0) << " : " << to_string_d(xf1.cast((const ufloat*)0)) << endl; cout << "NG" << endl; exit(-1); } xfloat xf4 = xfloat::faddsub(xf1, xf2, false); if (!cmpf((float)xf4.cast((const ufloat*)0), f1 + f2, 1)) { cout << "xfloat add" << endl; cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "f2 : " << f2 << " : " << to_string_d(ufloat(f2)) << endl; cout << "xf1: " << to_string_d(xf1) << endl; cout << "xf2: " << to_string_d(xf2) << endl; cout << "t : " << (float)xf4.cast((const ufloat*)0) << " : " << to_string_d(xf4.cast((const ufloat*)0)) << endl; cout << "c : " << (f1 + f2) << " : " << to_string_d(ufloat((f1 + f2))) << endl; cout << "NG" << endl; exit(-1); } xfloat xf5 = xfloat::faddsub(xf1, xf2, true); if (!cmpf((float)xf5.cast((const ufloat*)0), f1 - f2, 1)) { cout << "xfloat sub" << endl; cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "f2 : " << f2 << " : " << to_string_d(ufloat(f2)) << endl; cout << "xf1: " << to_string_d(xf1) << endl; cout << "xf2: " << to_string_d(xf2) << endl; cout << "t : " << (float)xf5.cast((const ufloat*)0) << " : " << to_string_d(xf5.cast((const ufloat*)0)) << endl; cout << "c : " << (f1 - f2) << " : " << to_string_d(ufloat((f1 - f2))) << endl; cout << "NG" << endl; exit(-1); } xfloat xf6 = xfloat::fmul(xf1, xf2); if (!cmpf((float)xf6.cast((const ufloat*)0), f1 * f2, 1)) { cout << "xfloat mul" << endl; cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "f2 : " << f2 << " : " << to_string_d(ufloat(f2)) << endl; cout << "xf1: " << to_string_d(xf1) << endl; cout << "xf2: " << to_string_d(xf2) << endl; cout << "t : " << (float)xf6.cast((const ufloat*)0) << " : " << to_string_d(xf6.cast((const ufloat*)0)) << endl; cout << "c : " << (f1 * f2) << " : " << to_string_d(ufloat((f1 * f2))) << endl; cout << "NG" << endl; exit(-1); } xfloat xf7 = xfloat::fdiv(xf1, xf2); if (!cmpf((float)xf7.cast((const ufloat*)0), f1 / f2, 1)) { cout << "xfloat div" << endl; cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "f2 : " << f2 << " : " << to_string_d(ufloat(f2)) << endl; cout << "xf1: " << to_string_d(xf1) << endl; cout << "xf2: " << to_string_d(xf2) << endl; cout << "t : " << (float)xf7.cast((const ufloat*)0) << " : " << to_string_d(xf7.cast((const ufloat*)0)) << endl; cout << "c : " << (f1 / f2) << " : " << to_string_d(ufloat((f1 / f2))) << endl; cout << "NG" << endl; exit(-1); } xfloat xf8 = xfloat::fma(xf1, xf2, xf3); if (!cmpf((float)xf8.cast((const ufloat*)0), fmaf(f1, f2, f3), 1)) { cout << "xfloat fma" << endl; cout << "f1 : " << f1 << " : " << to_string_d(ufloat(f1)) << endl; cout << "f2 : " << f2 << " : " << to_string_d(ufloat(f2)) << endl; cout << "f3 : " << f3 << " : " << to_string_d(ufloat(f3)) << endl; cout << "xf1: " << to_string_d(xf1) << endl; cout << "xf2: " << to_string_d(xf2) << endl; cout << "xf3: " << to_string_d(xf3) << endl; cout << "t : " << (float)xf8.cast((const ufloat*)0) << " : " << to_string_d(xf8.cast((const ufloat*)0)) << endl; cout << "c : " << fmaf(f1, f2, f3) << " : " << to_string_d(ufloat(fma(f1, f2, f3))) << endl; cout << "NG" << endl; exit(-1); } xdouble xd1 = tld1.cast((const xdouble*)0); xdouble xd2 = tld2.cast((const xdouble*)0); xdouble xd3 = tld3.cast((const xdouble*)0); if (!cmpd((double)xd1.cast((const udouble*)0), d1)) { cout << "cast between xdouble and udouble" << endl; cout << "d1: " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "t1: " << to_string_d(xd1) << endl; cout << "t2: " << (double)xd1.cast((const udouble*)0) << " : " << to_string_d(xd1.cast((const udouble*)0)) << endl; cout << "NG" << endl; exit(-1); } xdouble xd4 = xdouble::faddsub(xd1, xd2, false); if (!cmpd((double)xd4.cast((const udouble*)0), d1 + d2, 1)) { cout << "xdouble add" << endl; cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "d2 : " << d2 << " : " << to_string_d(udouble(d2)) << endl; cout << "xd1: " << to_string_d(xd1) << endl; cout << "xd2: " << to_string_d(xd2) << endl; cout << "t : " << (double)xd4.cast((const udouble*)0) << " : " << to_string_d(xd4.cast((const udouble*)0)) << endl; cout << "c : " << (d1 + d2) << " : " << to_string_d(udouble((d1 + d2))) << endl; cout << "NG" << endl; exit(-1); } xdouble xd5 = xdouble::faddsub(xd1, xd2, true); if (!cmpd((double)xd5.cast((const udouble*)0), d1 - d2, 1)) { cout << "xdouble sub" << endl; cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "d2 : " << d2 << " : " << to_string_d(udouble(d2)) << endl; cout << "xd1: " << to_string_d(xd1) << endl; cout << "xd2: " << to_string_d(xd2) << endl; cout << "t : " << (double)xd5.cast((const udouble*)0) << " : " << to_string_d(xd5.cast((const udouble*)0)) << endl; cout << "c : " << (d1 - d2) << " : " << to_string_d(udouble((d1 - d2))) << endl; cout << "NG" << endl; exit(-1); } xdouble xd6 = xdouble::fmul(xd1, xd2); if (!cmpd((double)xd6.cast((const udouble*)0), d1 * d2, 1)) { cout << "xdouble mul" << endl; cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "d2 : " << d2 << " : " << to_string_d(udouble(d2)) << endl; cout << "xd1: " << to_string_d(xd1) << endl; cout << "xd2: " << to_string_d(xd2) << endl; cout << "t : " << (double)xd6.cast((const udouble*)0) << " : " << to_string_d(xd6.cast((const udouble*)0)) << endl; cout << "c : " << (d1 * d2) << " : " << to_string_d(udouble((d1 * d2))) << endl; cout << "NG" << endl; exit(-1); } xdouble xd7 = xdouble::fdiv(xd1, xd2); if (!cmpd((double)xd7.cast((const udouble*)0), d1 / d2, 1)) { cout << "xdouble div" << endl; cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "d2 : " << d2 << " : " << to_string_d(udouble(d2)) << endl; cout << "xd1: " << to_string_d(xd1) << endl; cout << "xd2: " << to_string_d(xd2) << endl; cout << "t : " << (double)xd7.cast((const udouble*)0) << " : " << to_string_d(xd7.cast((const udouble*)0)) << endl; cout << "c : " << (d1 / d2) << " : " << to_string_d(udouble((d1 / d2))) << endl; cout << "NG" << endl; exit(-1); } xdouble xd8 = xdouble::fma(xd1, xd2, xd3); if (!cmpd((double)xd8.cast((const udouble*)0), fma(d1, d2, d3), 1)) { cout << "xdouble fma" << endl; cout << "d1 : " << d1 << " : " << to_string_d(udouble(d1)) << endl; cout << "d2 : " << d2 << " : " << to_string_d(udouble(d2)) << endl; cout << "d3 : " << d3 << " : " << to_string_d(udouble(d3)) << endl; cout << "xd1: " << to_string_d(xd1) << endl; cout << "xd2: " << to_string_d(xd2) << endl; cout << "xd3: " << to_string_d(xd3) << endl; cout << "t : " << (double)xd8.cast((const udouble*)0) << " : " << to_string_d(xd8.cast((const udouble*)0)) << endl; cout << "c : " << fma(d1, d2, d3) << " : " << to_string_d(udouble(fma(d1, d2, d3))) << endl; cout << "NG" << endl; exit(-1); } // { int16_t i16; rng->nextBytes((unsigned char *)&i16, sizeof(i16)); ufloat uf = ufloat::castFromInt(i16); if (!cmpf(float(uf), float(i16))) { cout << "float i16 " << i16 << endl; } udouble ud = udouble::castFromInt(i16); if (!cmpd(double(ud), double(i16))) { cout << "double i16 " << i16 << endl; } #ifdef ENABLE_QUAD uquad uq = uquad::castFromInt(i16); if (!cmpd(quad(uq), quad(i16))) { cout << "quad i16 " << i16 << endl; } #endif } { uint16_t u16; rng->nextBytes((unsigned char *)&u16, sizeof(u16)); ufloat uf = ufloat::castFromInt(u16); if (!cmpf(float(uf), float(u16))) { cout << "float u16 " << u16 << endl; } udouble ud = udouble::castFromInt(u16); if (!cmpd(double(ud), double(u16))) { cout << "double u16 " << u16 << endl; } #ifdef ENABLE_QUAD uquad uq = uquad::castFromInt(u16); if (!cmpd(quad(uq), quad(u16))) { cout << "quad u16 " << u16 << endl; } #endif } { int32_t i32; rng->nextBytes((unsigned char *)&i32, sizeof(i32)); ufloat uf = ufloat::castFromInt(i32); if (!cmpf(float(uf), float(i32))) { cout << "float i32 " << i32 << endl; } udouble ud = udouble::castFromInt(i32); if (!cmpd(double(ud), double(i32))) { cout << "double i32 " << i32 << endl; } #ifdef ENABLE_QUAD uquad uq = uquad::castFromInt(i32); if (!cmpd(quad(uq), quad(i32))) { cout << "quad i32 " << i32 << endl; } #endif } { uint32_t u32; rng->nextBytes((unsigned char *)&u32, sizeof(u32)); ufloat uf = ufloat::castFromInt(u32); if (!cmpf(float(uf), float(u32))) { cout << "float u32 " << u32 << endl; } udouble ud = udouble::castFromInt(u32); if (!cmpd(double(ud), double(u32))) { cout << "double u32 " << u32 << endl; } #ifdef ENABLE_QUAD uquad uq = uquad::castFromInt(u32); if (!cmpd(quad(uq), quad(u32))) { cout << "quad u32 " << u32 << endl; } #endif } { int64_t i64; rng->nextBytes((unsigned char *)&i64, sizeof(i64)); ufloat uf = ufloat::castFromInt(i64); if (!cmpf(float(uf), float(i64))) { cout << "float i64 " << i64 << endl; } udouble ud = udouble::castFromInt(i64); if (!cmpd(double(ud), double(i64))) { cout << "double i64 " << i64 << endl; } #ifdef ENABLE_QUAD uquad uq = uquad::castFromInt(i64); if (!cmpd(quad(uq), quad(i64))) { cout << "quad i64 " << i64 << endl; } #endif } { uint64_t u64; rng->nextBytes((unsigned char *)&u64, sizeof(u64)); ufloat uf = ufloat::castFromInt(u64); if (!cmpf(float(uf), float(u64))) { cout << "float u64 " << u64 << endl; } udouble ud = udouble::castFromInt(u64); if (!cmpd(double(ud), double(u64))) { cout << "double u64 " << u64 << endl; } #ifdef ENABLE_QUAD uquad uq = uquad::castFromInt(u64); if (!cmpd(quad(uq), quad(u64))) { cout << "quad u64 " << u64 << endl; } #endif } #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 { INT128 i128; rng->nextBytes((unsigned char *)&i128, sizeof(i128)); ufloat uf = ufloat::castFromInt(i128); if (!cmpf(float(uf), float(i128))) { cout << "float i128 " << i128 << endl; } udouble ud = udouble::castFromInt(i128); if (!cmpd(double(ud), double(i128))) { cout << "double i128 " << i128 << endl; } #ifdef ENABLE_QUAD uquad uq = uquad::castFromInt(i128); if (!cmpd(quad(uq), quad(i128))) { cout << "quad i128 " << i128 << endl; } #endif } { UINT128 u128; rng->nextBytes((unsigned char *)&u128, sizeof(u128)); ufloat uf = ufloat::castFromInt(u128); if (!cmpf(float(uf), float(u128))) { cout << "float u128 " << u128 << endl; } udouble ud = udouble::castFromInt(u128); if (!cmpd(double(ud), double(u128))) { cout << "double u128 " << u128 << endl; } #ifdef ENABLE_QUAD uquad uq = uquad::castFromInt(u128); if (!cmpd(quad(uq), quad(u128))) { cout << "quad u128 " << u128 << endl; } #endif } #endif // #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 } for(uint64_t i=0;niter == 0 || inextLT(65536) - 32768, i2 = (int)rng->nextLT(65536) - 32768; // check("(double)Double(Octuple(d1))", (double)Double(Octuple(d1)), d1); check("(double)(Double)Octuple(i1)", (double)(Double)Octuple(i1), (double)i1); check("o1 + o2", o1 + o2, d1 + d2); check("d1 + o2", d1 + o2, d1 + d2); check("f1 + o2", f1 + o2, d1 + d2); check("o1 + f2", o1 + f2, d1 + d2); check("i1 + o2", i1 + o2, i1 + d2); check("o1 + i2", o1 + i2, d1 + i2); o0 = o1; o0 += o2; check("o0 = o1; o0 += o2;", o0, d1 + d2); o0 = o1; o0 += q2; check("o0 = o1; o0 += q2;", o0, d1 + d2); o0 = o1; o0 += d2; check("o0 = o1; o0 += d2;", o0, d1 + d2); o0 = o1; o0 += i2; check("o0 = o1; o0 += i2;", o0, d1 + i2); o0 = o1; d0 = d1; check("o0 = o1; o0 ++;", o0++, d0++); check("o0 = o1; o0 ++; (2)", o0, d0); o0 = o1; d0 = d1; check("o0 = o1; ++ o0;", ++o0, ++d0); check("o0 = o1; ++ o0; (2)", o0, d0); check("o1 - o2", o1 - o2, d1 - d2); check("d1 - o2", d1 - o2, d1 - d2); check("f1 - o2", f1 - o2, d1 - d2); check("o1 - f2", o1 - f2, d1 - d2); check("i1 - o2", i1 - o2, i1 - d2); check("o1 - i2", o1 - i2, d1 - i2); o0 = o1; o0 -= o2; check("o0 = o1; o0 -= o2;", o0, d1 - d2); o0 = o1; o0 -= q2; check("o0 = o1; o0 -= q2;", o0, d1 - d2); o0 = o1; o0 -= d2; check("o0 = o1; o0 -= d2;", o0, d1 - d2); o0 = o1; o0 -= i2; check("o0 = o1; o0 -= i2;", o0, d1 - i2); o0 = o1; d0 = d1; check("o0 = o1; o0 --;", o0--, d0--); check("o0 = o1; o0 --; (2)", o0, d0); o0 = o1; d0 = d1; check("o0 = o1; -- o0;", --o0, --d0); check("o0 = o1; -- o0; (2)", o0, d0); check("o1 * o2", o1 * o2, d1 * d2); check("d1 * o2", d1 * o2, d1 * d2); check("f1 * o2", f1 * o2, d1 * d2); check("o1 * f2", o1 * f2, d1 * d2); check("i1 * o2", i1 * o2, i1 * d2); check("o1 * i2", o1 * i2, d1 * i2); o0 = o1; o0 *= o2; check("o0 = o1; o0 *= o2;", o0, d1 * d2); o0 = o1; o0 *= q2; check("o0 = o1; o0 *= q2;", o0, d1 * d2); o0 = o1; o0 *= d2; check("o0 = o1; o0 *= d2;", o0, d1 * d2); o0 = o1; o0 *= i2; check("o0 = o1; o0 *= i2;", o0, d1 * i2); check("o1 / o2", o1 / o2, d1 / d2); check("d1 / o2", d1 / o2, d1 / d2); check("f1 / o2", f1 / o2, d1 / d2); check("o1 / f2", o1 / f2, d1 / d2); check("i1 / o2", i1 / o2, i1 / d2); check("o1 / i2", o1 / i2, d1 / i2); o0 = o1; o0 /= o2; check("o0 = o1; o0 /= o2;", o0, d1 / d2); o0 = o1; o0 /= q2; check("o0 = o1; o0 /= q2;", o0, d1 / d2); o0 = o1; o0 /= d2; check("o0 = o1; o0 /= d2;", o0, d1 / d2); o0 = o1; o0 /= i2; check("o0 = o1; o0 /= i2;", o0, d1 / i2); } cout << "OK" << endl; exit(0); } tlfloat-1.15.0/src/tester/test_bigint2.cpp000066400000000000000000000142121477036600700204530ustar00rootroot00000000000000#include #include #include #include #include #include "suppress.hpp" #include "tlfloat/bigint.hpp" #include "testerutil.hpp" #define M 9 using namespace std; using namespace tlfloat; template xpair, BigUInt> xdivmod2(BigUInt n, BigUInt d) { BigUInt xn = BigUInt(n) << ((1 << N) - 1); BigUInt xd = d | (BigUInt(1) << ((1 << N)-1)); return xpair, BigUInt>(BigUInt(xn / xd), BigUInt(xn % xd)); } template BigUInt xreciprocal2(BigUInt d_) { BigUInt d = d_ | (BigUInt(1) << ((1 << N)-1)); BigUInt u = (~BigUInt(0)) / d; return (BigUInt)u; } template void doTestRec2(BigUInt d) { auto tr = d.reciprocal2(); auto cr = xreciprocal2(d); if (tr != (cr-1) && tr != cr && tr != (cr+1) && tr != (cr+2)) { cout << "N = " << N << endl; cout << "d = " << toHexString(d) << endl; cout << "c r2 = " << toHexString(cr) << endl; cout << "t r2 = " << toHexString(tr) << endl; exit(-1); } } template void doTestDivmod2(BigUInt n, BigUInt d) { auto c = xdivmod2(n, d); auto t = n.divmod2(d, d.reciprocal2()); if (c.first != t.first || c.second != t.second) { cout << "N = " << N << endl; cout << "n = " << toHexString(n) << " " << n << endl; cout << "d = " << toHexString(d) << " " << d << endl; cout << "d.r2 = " << toHexString(d.reciprocal2()) << endl; cout << "t.q = " << toHexString(t.first ) << endl; cout << "c.q = " << toHexString(c.first ) << endl; cout << "t.r = " << toHexString(t.second) << endl; cout << "c.r = " << toHexString(c.second) << endl; exit(-1); } t = n.divmod2(d); if (c.first != t.first || c.second != t.second) { cout << "N = " << N << endl; cout << "n = " << toHexString(n) << " " << n << endl; cout << "d = " << toHexString(d) << " " << d << endl; cout << "t.q = " << toHexString(t.first ) << endl; cout << "c.q = " << toHexString(c.first ) << endl; cout << "t.r = " << toHexString(t.second) << endl; cout << "c.r = " << toHexString(c.second) << endl; exit(-1); } if (d != 0) { t = n.divmod(d); if (t.second >= d || t.first * d + t.second != n) { cout << "N = " << N << endl; cout << "n = " << toHexString(n) << " " << n << endl; cout << "d = " << toHexString(d) << " " << d << endl; cout << "t.q = " << toHexString(t.first ) << endl; cout << "t.r = " << toHexString(t.second) << endl; exit(-1); } t = n.divmod(d, d.reciprocal()); if (t.second >= d || t.first * d + t.second != n) { cout << "N = " << N << endl; cout << "n = " << toHexString(n) << " " << n << endl; cout << "d = " << toHexString(d) << " " << d << endl; cout << "d.r = " << toHexString(d.reciprocal()) << endl; cout << "t.q = " << toHexString(t.first ) << endl; cout << "t.r = " << toHexString(t.second) << endl; exit(-1); } } } template void testLoop() { cout << "<" << N << ">"; fflush(stdout); for(int i=0;i<(1 << N);i++) { BigUInt d = BigUInt(1) << i; doTestRec2(d-1); doTestRec2(d ); doTestRec2(d+1); for(int j=0;j<(1 << N);j++) { BigUInt n = BigUInt(1) << j; doTestDivmod2(n-1, d-1); doTestDivmod2(n-1, d); doTestDivmod2(n-1, d+1); doTestDivmod2(n, d-1); doTestDivmod2(n, d); doTestDivmod2(n, d+1); doTestDivmod2(n+1, d-1); doTestDivmod2(n+1, d); doTestDivmod2(n+1, d+1); } } } bool checkRNG(shared_ptr rng, int n, int nloop, int thres) { vector bin(n); cout << "[" << n << "]"; fflush(stdout); for(int i=0;inextLT(n)]++; for(int i=0;i(uint64_t(n), rng))]++; for(int i=0;i n49 = BigUInt(unsigned(n)).pow(49); BigUInt n50 = n49 * n, recn49 = n49.reciprocal(); for(int i=0;i(n50, rng).divmod(n49, recn49, NULL))]++; } for(int i=0;i(); testLoop<8>(); testLoop<9>(); shared_ptr rng = createPreferredRNG(); if (ntest != 1) { if (argc == 1) { for(int i=3;i<=23;i+=2) { if (!checkRNG(rng, i, 10000, (10000/i) * 80 / 100) && !checkRNG(rng, i, 10000, (10000/i) * 80 / 100)) { cout << "NG" << endl; exit(-1); } } ntest = 10; } else { for(int i=3;i<=23;i+=2) checkRNG(rng, i, 1000000, (1000000/i) * 98 / 100); } } for(int i=0;i m = CryptUtil::genPrime(BigUInt(1) << n, rng); BigUInt a = CryptUtil::genRand(BigUInt(1) << n, rng); BigUInt ainv = (BigUInt)BigUInt(a).pow(m-2, m); BigUInt::Montgomery mg(m); if (mg.reduce(mg.pow(mg.transform(a), m-2)) != ainv) { cout << "Montgomery" << endl; cout << "m = " << m << endl; cout << "a = " << a << endl; cout << "c ainv = " << ainv << endl; cout << "t ainv = " << mg.reduce(mg.pow(mg.transform(a), m-2)) << endl; cout << "NG" << endl; exit(-1); } if (ntest == 1) { cout << "m = " << m << endl; cout << "a = " << a << endl; cout << "ainv = " << ainv << endl; cout << "(a * ainv) mod m = " << (a * ainv) % m << endl; } if (a.gcd(m) != 1 || (a * ainv) % m != 1) { cout << "NG" << endl; exit(-1); } } if (ntest != 1) cout << endl << "OK" << endl; return 0; } tlfloat-1.15.0/src/tester/test_bigint3.cpp000066400000000000000000000267501477036600700204660ustar00rootroot00000000000000#include #include #include #include "suppress.hpp" #include "tlfloat/bigint.hpp" #include "testerutil.hpp" using namespace std; using namespace tlfloat; bool success = true; void e(const char *mes) { cerr << mes << endl; success = false; } void checks(uint64_t high0, uint64_t low0, uint64_t high1, uint64_t low1, double d) { #if 0 printf("checks 0x%016llx%016llx 0x%016llx%016llx %.16g\n", (unsigned long long)high0, (unsigned long long)low0, (unsigned long long)high1, (unsigned long long)low1, d); #endif converter128 cnv0(high0, low0); BigInt<7> i0 = cnv0.bi; __int128_t b0 = cnv0.i128; converter128 cnv1(high1, low1); BigInt<7> i1 = cnv1.bi; __int128_t b1 = cnv1.i128; if (double(i0) != double(b0)) { cerr << i0 << endl; e("checks : operator double"); } if (double(i1) != double(b1)) { cerr << i1 << endl; e("checks : operator double"); } if ((high0 != 0 || low0 != 0) && fabs((double((BigUInt<7>)i0) - (ldexp(double(high0), 64) + double(low0))) / (ldexp(double(high0), 64) + double(low0))) > 1e-14) { cerr << "i0 = " << i0 << ", hl = " << (ldexp(double(high0), 64) + double(low0)) << endl; e("checku : operator double 2s"); } if (!equal(__int128_t(d), BigInt<7>(d))) { fprintf(stderr, "%.20g\n", d); e("checks : cast from double"); } if (BigInt<7>(to_string(i0).c_str()) != i0) e("to/from string"); if ((i0 == i1) != (b0 == b1)) e("=="); if ((i1 == i0) != (b1 == b0)) e("=="); if ((i0 == i0) != (b0 == b0)) e("=="); if ((i1 == i1) != (b1 == b1)) e("=="); if (!equal(i0++, b0++) || !equal(i1++, b1++)) e("++ suffix"); if (!equal(++i0, ++b0) || !equal(++i1, ++b1)) e("++ prefix"); if (!equal(i0--, b0--) || !equal(i1--, b1--)) e("-- suffix"); if (!equal(--i0, --b0) || !equal(--i1, --b1)) e("-- prefix"); if (!equal(-i0, -b0) || !equal(-i1, -b1)) e("- unary"); if (!equal(+i0, +b0) || !equal(+i1, +b1)) e("+ unary"); if ((long long)(i0) != (long long)(b0)) e("(long long)"); if (long(i0) != long(b0)) e("(long)"); if (int(i0) != int(b0)) e("(int)"); if (short(i0) != short(b0)) e("(short)"); if (char(i0) != char(b0)) e("(short)"); if ((unsigned long long)(i0) != (unsigned long long)(b0)) e("(unsigned long long)"); if ((unsigned long)(i0) != (unsigned long)(b0)) e("(unsigned long)"); if ((unsigned int)(i0) != (unsigned int)(b0)) e("(unsigned int)"); if ((unsigned short)(i0) != (unsigned short)(b0)) e("(unsigned short)"); if ((unsigned char)(i0) != (unsigned char)(b0)) e("(unsigned char)"); if ((bool)(i0) != (bool)(b0)) e("(bool)"); if (!equal(BigInt<7>((long long)(i0)), __int128_t((long long)(b0)))) e("(long long)2"); if (!equal(BigInt<7>((long)(i0)), __int128_t((long)(b0)))) e("(long)2"); if (!equal(BigInt<7>((int)(i0)), __int128_t((int)(b0)))) e("(int)2"); if (!equal(BigInt<7>((short)(i0)), __int128_t((short)(b0)))) e("(short)2"); if (!equal(BigInt<7>((char)(i0)), __int128_t((char)(b0)))) e("(char)2"); if (!equal(BigInt<7>((unsigned long long)(i0)), __int128_t((unsigned long long)(b0)))) e("(unsigned long long)2"); if (!equal(BigInt<7>((unsigned long)(i0)), __int128_t((unsigned long)(b0)))) e("(unsigned long)2"); if (!equal(BigInt<7>((unsigned)(i0)), __int128_t((unsigned)(b0)))) e("(unsigned)2"); if (!equal(BigInt<7>((unsigned short)(i0)), __int128_t((unsigned short)(b0)))) e("(unsigned short)2"); if (!equal(BigInt<7>((unsigned char)(i0)), __int128_t((unsigned char)(b0)))) e("(unsigned char)2"); if (!equal(BigInt<7>((bool)(i0)), __int128_t((bool)(b0)))) e("(bool)2"); if ((i0 < i1) != (b0 < b1)) e("<"); if ((i1 < i0) != (b1 < b0)) e("<"); if ((i0 < i0) != (b0 < b0)) e("<"); if ((i1 < i1) != (b1 < b1)) e("<"); if (!equal(i0 + i1, b0 + b1)) e("+"); if (!equal(i1 + i0, b1 + b0)) e("+"); if (!equal(i0 - i1, b0 - b1)) e("-"); if (!equal(i1 - i0, b1 - b0)) e("-"); if (!equal(i0 * i1, b0 * b1)) e("*"); if (!equal(i1 * i0, b1 * b0)) e("*"); if (!equal(i0 / i1, b0 / b1)) e("/"); if (!equal(i1 / i0, b1 / b0)) e("/"); if (!equal(i0 % i1, b0 % b1)) e("%"); if (!equal(i1 % i0, b1 % b0)) e("%"); if (!equal(i0 << 3, b0 << 3)) e("<<"); if (!equal((i0 <<= 3), (b0 <<= 3))) e("<<="); if (!equal(i0 >> 3, b0 >> 3)) e(">>"); if (!equal((i0 >>= 3), (b0 >>= 3))) e(">>="); if (!equal(i0 += 3, b0 += 3)) e("+="); if (!equal(i0 -= 3, b0 -= 3)) e("-="); if (!equal(i0 *= 3, b0 *= 3)) e("*="); if (!equal(i0 /= 3, b0 /= 3)) e("/="); if (!equal(i1 += i0, b1 += b0)) e("+="); if (!equal(i1 -= i0, b1 -= b0)) e("-="); if (!equal(i1 *= i0, b1 *= b0)) e("*="); //if (!equal(i1 /= i0, b1 /= b0)) e("/="); { stringstream ssc, sst; ssc << (int64_t)low0 << endl; sst << BigInt<7>((int64_t)low0) << endl; if (ssc.str() != sst.str()) { cout << "NG 0s c = <" << ssc.str() << ">, t = <" << sst.str() << ">" << endl; exit(-1); } } { stringstream ssc, sst; ssc << setw(20) << (int64_t)low0 << endl; sst << setw(20) << BigInt<7>((int64_t)low0) << endl; if (ssc.str() != sst.str()) { cout << "NG 1s c = <" << ssc.str() << ">, t = <" << sst.str() << ">" << endl; exit(-1); } } { stringstream ssc, sst; ssc << setw(20) << right << (int64_t)low0 << endl; sst << setw(20) << right << BigInt<7>((int64_t)low0) << endl; if (ssc.str() != sst.str()) { cout << "NG 2s c = <" << ssc.str() << ">, t = <" << sst.str() << ">" << endl; exit(-1); } } } void checku(uint64_t high0, uint64_t low0, uint64_t high1, uint64_t low1, double d) { #if 0 printf("checku 0x%016llx%016llx 0x%016llx%016llx %.16g\n", (unsigned long long)high0, (unsigned long long)low0, (unsigned long long)high1, (unsigned long long)low1, d); #endif converter128 cnv0(high0, low0); BigUInt<7> i0 = cnv0.bi; __uint128_t b0 = cnv0.u128; converter128 cnv1(high1, low1); BigUInt<7> i1 = cnv1.bi; __uint128_t b1 = cnv1.u128; if (double(i0) != double(b0)) { cerr << i0 << endl; e("checku : operator double 1u"); } if (double(i1) != double(b1)) { cerr << i1 << endl; e("checku : operator double 1u"); } if ((high0 != 0 || low0 != 0) && fabs((double(i0) - (ldexp(double(high0), 64) + double(low0))) / (ldexp(double(high0), 64) + double(low0))) > 1e-14) { cerr << "i0 = " << i0 << ", hl = " << (ldexp(double(high0), 64) + double(low0)) << endl; e("checku : operator double 2u"); } if (!equal(__uint128_t(d), BigUInt<7>(d))) { fprintf(stderr, "%.20g\n", d); e("checku : cast from double"); } // if (BigUInt<7>(to_string(i0).c_str()) != i0) e("to/from string unsigned"); if ((i0 == i1) != (b0 == b1)) e("=="); if ((i1 == i0) != (b1 == b0)) e("=="); if ((i0 == i0) != (b0 == b0)) e("=="); if ((i1 == i1) != (b1 == b1)) e("=="); if (!equal(i0++, b0++) || !equal(i1++, b1++)) e("++ suffix"); if (!equal(++i0, ++b0) || !equal(++i1, ++b1)) e("++ prefix"); if (!equal(i0--, b0--) || !equal(i1--, b1--)) e("-- suffix"); if (!equal(--i0, --b0) || !equal(--i1, --b1)) e("-- prefix"); if (!equal(-i0, -b0) || !equal(-i1, -b1)) e("- unary"); if (!equal(+i0, +b0) || !equal(+i1, +b1)) e("+ unary"); if ((long long)(i0) != (long long)(b0)) e("(long long)"); if (long(i0) != long(b0)) e("(long)"); if (int(i0) != int(b0)) e("(int)"); if (short(i0) != short(b0)) e("(short)"); if (char(i0) != char(b0)) e("(short)"); if ((unsigned long long)(i0) != (unsigned long long)(b0)) e("(unsigned long long)"); if ((unsigned long)(i0) != (unsigned long)(b0)) e("(unsigned long)"); if ((unsigned int)(i0) != (unsigned int)(b0)) e("(unsigned int)"); if ((unsigned short)(i0) != (unsigned short)(b0)) e("(unsigned short)"); if ((unsigned char)(i0) != (unsigned char)(b0)) e("(unsigned char)"); if ((bool)(i0) != (bool)(b0)) e("(bool)"); if (!equal(BigUInt<7>((long long)(i0)), __int128_t((long long)(b0)))) e("(long long)3"); if (!equal(BigUInt<7>((long)(i0)), __int128_t((long)(b0)))) e("(long)3"); if (!equal(BigUInt<7>((int)(i0)), __int128_t((int)(b0)))) e("(int)3"); if (!equal(BigUInt<7>((short)(i0)), __int128_t((short)(b0)))) e("(short)3"); if (!equal(BigUInt<7>((char)(i0)), __int128_t((char)(b0)))) e("(char)3"); if (!equal(BigUInt<7>((unsigned long long)(i0)), __int128_t((unsigned long long)(b0)))) e("(unsigned long long)4"); if (!equal(BigUInt<7>((unsigned long)(i0)), __int128_t((unsigned long)(b0)))) e("(unsigned long)4"); if (!equal(BigUInt<7>((unsigned)(i0)), __int128_t((unsigned)(b0)))) e("(unsigned)4"); if (!equal(BigUInt<7>((unsigned short)(i0)), __int128_t((unsigned short)(b0)))) e("(unsigned short)4"); if (!equal(BigUInt<7>((unsigned char)(i0)), __int128_t((unsigned char)(b0)))) e("(unsigned char)4"); if (!equal(BigUInt<7>((bool)(i0)), __int128_t((bool)(b0)))) e("(bool)4"); if ((i0 < i1) != (b0 < b1)) e("<"); if ((i1 < i0) != (b1 < b0)) e("<"); if ((i0 < i0) != (b0 < b0)) e("<"); if ((i1 < i1) != (b1 < b1)) e("<"); if (!equal(i0 + i1, b0 + b1)) e("+"); if (!equal(i1 + i0, b1 + b0)) e("+"); if (!equal(i0 - i1, b0 - b1)) e("-"); if (!equal(i1 - i0, b1 - b0)) e("-"); if (!equal(i0 * i1, b0 * b1)) e("*"); if (!equal(i1 * i0, b1 * b0)) e("*"); if (!equal(i0 / i1, b0 / b1)) e("/"); if (!equal(i1 / i0, b1 / b0)) e("/"); if (!equal(i0 % i1, b0 % b1)) e("%"); if (!equal(i1 % i0, b1 % b0)) e("%"); if (!equal(i0 << 3, b0 << 3)) e("<<"); if (!equal((i0 <<= 3), (b0 <<= 3))) e("<<="); if (!equal(i0 >> 3, b0 >> 3)) e(">>"); if (!equal((i0 >>= 3), (b0 >>= 3))) e(">>="); if (!equal(i0 += 3, b0 += 3)) e("+="); if (!equal(i0 -= 3, b0 -= 3)) e("-="); if (!equal(i0 *= 3, b0 *= 3)) e("*="); if (!equal(i0 /= 3, b0 /= 3)) e("/="); if (!equal(i1 += i0, b1 += b0)) e("+="); if (!equal(i1 -= i0, b1 -= b0)) e("-="); if (!equal(i1 *= i0, b1 *= b0)) e("*="); if (!equal(i1 /= i0, b1 /= b0)) e("/="); // { stringstream ssc, sst; ssc << (uint64_t)low0 << endl; sst << BigUInt<7>((uint64_t)low0) << endl; if (ssc.str() != sst.str()) { cout << "NG 0u c = <" << ssc.str() << ">, t = <" << sst.str() << ">" << endl; exit(-1); } } { stringstream ssc, sst; ssc << setw(20) << (uint64_t)low0 << endl; sst << setw(20) << BigUInt<7>((uint64_t)low0) << endl; if (ssc.str() != sst.str()) { cout << "NG 1u c = <" << ssc.str() << ">, t = <" << sst.str() << ">" << endl; exit(-1); } } { stringstream ssc, sst; ssc << setw(20) << hex << (uint64_t)low0 << endl; sst << setw(20) << hex << BigUInt<7>((uint64_t)low0) << endl; if (ssc.str() != sst.str()) { cout << "NG 2u c = <" << ssc.str() << ">, t = <" << sst.str() << ">" << endl; exit(-1); } } { stringstream ssc, sst; ssc << setw(20) << oct << (uint64_t)low0 << endl; sst << setw(20) << oct << BigUInt<7>((uint64_t)low0) << endl; if (ssc.str() != sst.str()) { cout << "NG 3u c = <" << ssc.str() << ">, t = <" << sst.str() << ">" << endl; exit(-1); } } { stringstream ssc, sst; ssc << setw(20) << right << (uint64_t)low0 << endl; sst << setw(20) << right << BigUInt<7>((uint64_t)low0) << endl; if (ssc.str() != sst.str()) { cout << "NG 4u c = <" << ssc.str() << ">, t = <" << sst.str() << ">" << endl; exit(-1); } } } int main(int argc, char **argv) { int n = 10000; if (argc != 1) n = atoi(argv[1]); shared_ptr rng = createPreferredRNG(); for(int i=0;inextDouble(), rng->nextLT(256)-128); checku(rng->next64(), rng->next64(), rng->next64(), rng->next64(), d0); d0 = rng->nextBool() ? -d0 : d0; checks(rng->next64(), rng->next64(), rng->next64(), rng->next64(), d0); } if (!success) { cout << "NG" << endl; return -1; } cout << "OK" << endl; return 0; } tlfloat-1.15.0/src/tester/test_bigint4.cpp000066400000000000000000000265331477036600700204660ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include "suppress.hpp" #include "tlfloat/bigint.hpp" #include "tlfloat/tlfloat.h" #include "testerutil.hpp" using namespace std; using namespace tlfloat; bool equal(BigInt<7> i0, tlfloat_uint128_t b0) { return equal((tlfloat_int128_t)b0, i0); } bool equal(BigUInt<7> u0, tlfloat_int128_t b0) { return equal((tlfloat_uint128_t)b0, u0); } bool success = true; void e(const char *mes) { cerr << mes << endl << endl; success = false; } void checks(uint64_t high0, uint64_t low0, uint64_t high1, uint64_t low1, double d) { #if 0 printf("checks 0x%016llx%016llx 0x%016llx%016llx %.16g\n", (unsigned long long)high0, (unsigned long long)low0, (unsigned long long)high1, (unsigned long long)low1, d); #endif converter128 cnv0(high0, low0); BigInt<7> i0 = cnv0.bi; tlfloat_int128_t b0 = cnv0.ti128; converter128 cnv1(high1, low1); BigInt<7> i1 = cnv1.bi; tlfloat_int128_t b1 = cnv1.ti128; if (!equal(i0, b0)) e("checks : cast with union"); if (!equal((BigInt<7>)b0, b0)) e("checks : cast BigInt<7> <- tlfloat_int128_t"); if (!equal(i0, (tlfloat_int128_t)i0)) e("checks : cast tlfloat_int128_t <- BigInt<7>"); if (double(i0) != double(b0)) { cerr << i0 << endl; e("checks : operator double"); } if (double(i1) != double(b1)) { cerr << i1 << endl; e("checks : operator double"); } if (!equal(tlfloat_int128_t(d), BigInt<7>(d))) { fprintf(stderr, "%.20g\n", d); e("checks : cast from double"); } if ((tlfloat_int128_t)tlfloat_quad((tlfloat_int128_t)low0) != low0) { cerr << i0 << endl; e("checks : cast tlfloat_quad"); } if ((tlfloat_int128_t)tlfloat_octuple(b0) != b0) { cerr << i0 << endl; e("checks : cast tlfloat_octuple"); } // { char str[256]; tlfloat_snprintf(str, sizeof(str), "%Qd", b0); if (b0 != tlfloat_strtoi128(str, NULL, 10)) e("Qd to/from string signed base 10"); if (b0 != tlfloat_strtoi128(str, NULL, 0)) e("Qd to/from string signed base 0"); } if ((i0 == i1) != (b0 == b1)) e("=="); if ((i1 == i0) != (b1 == b0)) e("=="); if ((i0 == i0) != (b0 == b0)) e("=="); if ((i1 == i1) != (b1 == b1)) e("=="); if (!equal(i0++, b0++) || !equal(i1++, b1++)) e("++ suffix"); if (!equal(++i0, ++b0) || !equal(++i1, ++b1)) e("++ prefix"); if (!equal(i0--, b0--) || !equal(i1--, b1--)) e("-- suffix"); if (!equal(--i0, --b0) || !equal(--i1, --b1)) e("-- prefix"); if (!equal(-i0, -b0) || !equal(-i1, -b1)) e("- unary"); if (!equal(+i0, +b0) || !equal(+i1, +b1)) e("+ unary"); if ((long long)(i0) != (long long)(b0)) e("(long long)"); if (long(i0) != long(b0)) e("(long)"); if (int(i0) != int(b0)) e("(int)"); if (short(i0) != short(b0)) e("(short)"); if (char(i0) != char(b0)) e("(short)"); if ((unsigned long long)(i0) != (unsigned long long)(b0)) e("(unsigned long long) 1s"); if ((unsigned long)(i0) != (unsigned long)(b0)) e("(unsigned long) 1s"); if ((unsigned int)(i0) != (unsigned int)(b0)) e("(unsigned int) 1s"); if ((unsigned short)(i0) != (unsigned short)(b0)) e("(unsigned short) 1s"); if ((unsigned char)(i0) != (unsigned char)(b0)) e("(unsigned char) 1s"); if ((bool)(i0) != (bool)(b0)) e("(bool)"); if (!equal(BigInt<7>((long long)(i0)), tlfloat_int128_t((long long)(b0)))) e("(long long) 2s"); if (!equal(BigInt<7>((long)(i0)), tlfloat_int128_t((long)(b0)))) e("(long) 2s"); if (!equal(BigInt<7>((int)(i0)), tlfloat_int128_t((int)(b0)))) e("(int) 2s"); if (!equal(BigInt<7>((short)(i0)), tlfloat_int128_t((short)(b0)))) e("(short) 2s"); if (!equal(BigInt<7>((char)(i0)), tlfloat_int128_t((char)(b0)))) e("(char) 2s"); if (!equal(BigInt<7>((unsigned long long)(i0)), tlfloat_int128_t((unsigned long long)(b0)))) e("(unsigned long long) 2s"); if (!equal(BigInt<7>((unsigned long)(i0)), tlfloat_int128_t((unsigned long)(b0)))) e("(unsigned long) 2s"); if (!equal(BigInt<7>((unsigned)(i0)), tlfloat_int128_t((unsigned)(b0)))) e("(unsigned) 2s"); if (!equal(BigInt<7>((unsigned short)(i0)), tlfloat_int128_t((unsigned short)(b0)))) e("(unsigned short) 2s"); if (!equal(BigInt<7>((unsigned char)(i0)), tlfloat_int128_t((unsigned char)(b0)))) e("(unsigned char) 2s"); if (!equal(BigInt<7>((bool)(i0)), tlfloat_int128_t((bool)(b0)))) e("(bool) 2s"); if ((i0 < i1) != (b0 < b1)) e("<"); if ((i1 < i0) != (b1 < b0)) e("<"); if ((i0 < i0) != (b0 < b0)) e("<"); if ((i1 < i1) != (b1 < b1)) e("<"); if (!equal(i0 + i1, b0 + b1)) e("+"); if (!equal(i1 + i0, b1 + b0)) e("+"); if (!equal(i0 - i1, b0 - b1)) e("-"); if (!equal(i1 - i0, b1 - b0)) e("-"); if (!equal(i0 * i1, b0 * b1)) e("*"); if (!equal(i1 * i0, b1 * b0)) e("*"); if (!equal(i0 / i1, b0 / b1)) e("/"); if (!equal(i1 / i0, b1 / b0)) e("/"); if (!equal(i0 % i1, b0 % b1)) e("%"); if (!equal(i1 % i0, b1 % b0)) e("%"); if (!equal(i0 << 3, b0 << 3)) e("<<"); if (!equal((i0 <<= 3), (b0 <<= 3))) e("<<="); if (!equal(i0 >> 3, b0 >> 3)) e(">>"); if (!equal((i0 >>= 3), (b0 >>= 3))) e(">>="); if (!equal(i0 += 3, b0 += 3)) e("+="); if (!equal(i0 -= 3ULL, b0 -= 3ULL)) e("-="); if (!equal(i0 *= 3, b0 *= 3)) e("*="); if (!equal(i0 /= 3, b0 /= 3)) e("/="); if (!equal(i1 += i0, b1 += b0)) e("+="); if (!equal(i1 -= i0, b1 -= tlfloat_int128_t_(b0))) e("-="); if (!equal(i1 *= i0, b1 *= tlfloat_uint128_t(b0))) e("*="); if (!equal(i1 /= i0, b1 /= b0)) e("/="); } void checku(uint64_t high0, uint64_t low0, uint64_t high1, uint64_t low1, double d) { #if 0 printf("checku 0x%016llx%016llx 0x%016llx%016llx %.16g\n", (unsigned long long)high0, (unsigned long long)low0, (unsigned long long)high1, (unsigned long long)low1, d); #endif converter128 cnv0(high0, low0); BigUInt<7> i0 = cnv0.bi; tlfloat_uint128_t b0 = cnv0.tu128; converter128 cnv1(high1, low1); BigUInt<7> i1 = cnv1.bi; tlfloat_uint128_t b1 = cnv1.tu128; if (!equal(i0, b0)) e("checku : cast with union"); if (!equal((BigUInt<7>)b0, b0)) e("checku : cast BigUInt<7> <- tlfloat_uint128_t"); if (!equal(i0, (tlfloat_uint128_t)i0)) e("checku : cast tlfloat_uint128_t <- BigUInt<7>"); if (double(i0) != double(b0)) { cerr << i0 << endl; e("checku : operator double"); } if (double(i1) != double(b1)) { cerr << i1 << endl; e("checku : operator double"); } if (!equal(tlfloat_uint128_t(d), BigUInt<7>(d))) { fprintf(stderr, "%.20g\n", d); e("checku : cast from double"); } if ((tlfloat_uint128_t)tlfloat_quad((tlfloat_uint128_t)low0) != low0) { cerr << i0 << endl; e("checku : cast tlfloat_quad"); } if ((tlfloat_uint128_t)tlfloat_octuple(b0) != b0) { cerr << i0 << endl; e("checku : cast tlfloat_octuple"); } // { char str[256]; tlfloat_snprintf(str, sizeof(str), "%Qu", b0); if (b0 != tlfloat_strtou128(str, NULL, 10)) e("Qu to/from string unsigned base 10"); if (b0 != tlfloat_strtou128(str, NULL, 0)) e("Qu to/from string unsigned base 10"); tlfloat_snprintf(str, sizeof(str), "%Qo", b0); if (b0 != tlfloat_strtou128(str, NULL, 8)) e("Qo to/from string unsigned base 8"); tlfloat_snprintf(str, sizeof(str), "0%Qo", b0); if (b0 != tlfloat_strtou128(str, NULL, 0)) e("Qo to/from string unsigned base 0"); tlfloat_snprintf(str, sizeof(str), "%Qx", b0); if (b0 != tlfloat_strtou128(str, NULL, 16)) e("Qx to/from string unsigned base 16"); tlfloat_snprintf(str, sizeof(str), "0x%Qx", b0); if (b0 != tlfloat_strtou128(str, NULL, 0)) e("Qx to/from string unsigned base 0"); } if ((i0 == i1) != (b0 == b1)) e("=="); if ((i1 == i0) != (b1 == b0)) e("=="); if ((i0 == i0) != (b0 == b0)) e("=="); if ((i1 == i1) != (b1 == b1)) e("=="); if (!equal(i0++, b0++) || !equal(i1++, b1++)) e("++ suffix"); if (!equal(++i0, ++b0) || !equal(++i1, ++b1)) e("++ prefix"); if (!equal(i0--, b0--) || !equal(i1--, b1--)) e("-- suffix"); if (!equal(--i0, --b0) || !equal(--i1, --b1)) e("-- prefix"); if (!equal(-i0, -b0) || !equal(-i1, -b1)) e("- unary"); if (!equal(+i0, +b0) || !equal(+i1, +b1)) e("+ unary"); if ((long long)(i0) != (long long)(b0)) e("(long long)"); if (long(i0) != long(b0)) e("(long)"); if (int(i0) != int(b0)) e("(int)"); if (short(i0) != short(b0)) e("(short)"); if (char(i0) != char(b0)) e("(short)"); if ((unsigned long long)(i0) != (unsigned long long)(b0)) e("(unsigned long long) 1u"); if ((unsigned long)(i0) != (unsigned long)(b0)) e("(unsigned long) 1u"); if ((unsigned int)(i0) != (unsigned int)(b0)) e("(unsigned int) 1u"); if ((unsigned short)(i0) != (unsigned short)(b0)) e("(unsigned short) 1u"); if ((unsigned char)(i0) != (unsigned char)(b0)) e("(unsigned char) 1u"); if ((bool)(i0) != (bool)(b0)) e("(bool)"); if (!equal(BigUInt<7>((long long)(i0)), tlfloat_int128_t((long long)(b0)))) e("(long long)3u"); if (!equal(BigUInt<7>((long)(i0)), tlfloat_int128_t((long)(b0)))) e("(long)3u"); if (!equal(BigUInt<7>((int)(i0)), tlfloat_int128_t((int)(b0)))) e("(int)3u"); if (!equal(BigUInt<7>((short)(i0)), tlfloat_int128_t((short)(b0)))) e("(short)3u"); if (!equal(BigUInt<7>((char)(i0)), tlfloat_int128_t((char)(b0)))) e("(char)3u"); if (!equal(BigUInt<7>((unsigned long long)(i0)), tlfloat_uint128_t((unsigned long long)(b0)))) e("(unsigned long long)4u"); if (!equal(BigUInt<7>((unsigned long)(i0)), tlfloat_uint128_t((unsigned long)(b0)))) e("(unsigned long)4u"); if (!equal(BigUInt<7>((unsigned)(i0)), tlfloat_uint128_t((unsigned)(b0)))) e("(unsigned)4u"); if (!equal(BigUInt<7>((unsigned short)(i0)), tlfloat_uint128_t((unsigned short)(b0)))) e("(unsigned short)4u"); if (!equal(BigUInt<7>((unsigned char)(i0)), tlfloat_uint128_t((unsigned char)(b0)))) e("(unsigned char)4u"); if (!equal(BigUInt<7>((bool)(i0)), tlfloat_int128_t((bool)(b0)))) e("(bool)4u"); if ((i0 < i1) != (b0 < b1)) e("<"); if ((i1 < i0) != (b1 < b0)) e("<"); if ((i0 < i0) != (b0 < b0)) e("<"); if ((i1 < i1) != (b1 < b1)) e("<"); if (!equal(i0 + i1, b0 + b1)) e("+"); if (!equal(i1 + i0, b1 + b0)) e("+"); if (!equal(i0 - i1, b0 - b1)) e("-"); if (!equal(i1 - i0, b1 - b0)) e("-"); if (!equal(i0 * i1, b0 * b1)) e("*"); if (!equal(i1 * i0, b1 * b0)) e("*"); if (!equal(i0 / i1, b0 / b1)) e("/"); if (!equal(i1 / i0, b1 / b0)) e("/"); if (!equal(i0 % i1, b0 % b1)) e("%"); if (!equal(i1 % i0, b1 % b0)) e("%"); if (!equal(i0 << 3, b0 << 3)) e("<<"); if (!equal((i0 <<= 3), (b0 <<= 3))) e("<<="); if (!equal(i0 >> 3, b0 >> 3)) e(">>"); if (!equal((i0 >>= 3), (b0 >>= 3))) e(">>="); if (!equal(i0 += 3, b0 += 3)) e("+="); if (!equal(i0 -= 3LL, b0 -= 3LL)) e("-="); if (!equal(i0 *= 3, b0 *= 3)) e("*="); if (!equal(i0 /= 3, b0 /= 3)) e("/="); if (!equal(i1 += i0, b1 += b0)) e("+="); if (!equal(i1 -= i0, b1 -= tlfloat_uint128_t_(b0))) e("-="); if (!equal(i1 *= i0, b1 *= tlfloat_int128_t(b0))) e("*="); if (!equal(i1 /= i0, b1 /= b0)) e("/="); } int main(int argc, char **argv) { int n = 10000; if (argc != 1) n = atoi(argv[1]); shared_ptr rng = createPreferredRNG(); for(int i=0;inextDouble(), rng->nextLT(256)-128); checku(rng->next64(), rng->next64(), rng->next64(), rng->next64(), d0); d0 = rng->nextBool() ? -d0 : d0; checks(rng->next64(), rng->next64(), rng->next64(), rng->next64(), d0); } if (!success) { cout << "NG" << endl; return -1; } cout << "OK" << endl; return 0; } tlfloat-1.15.0/src/tester/test_capi.c000066400000000000000000000710631477036600700175000ustar00rootroot00000000000000#include #include #include #include #include #include #if defined(TLFLOAT_ENABLE_LIBQUADMATH) #include #define TRUE_LIBQUADMATH #else #define TLFLOAT_LIBQUADMATH_EMULATION #endif #include "tlfloat/tlfloat.h" #ifdef __STDC_VERSION__ const tlfloat_quad testvar = M_PIq; #endif void checkStr(const char *p, const char *q, const char *mes) { if (strcmp(p, q) != 0) { printf("NG : %s\n", mes); printf("p : %s\n", p); printf("q : %s\n", q); exit(-1); } } void checkInt(const int u, const int v, const char *mes) { if (u != v) { printf("NG : %s\n", mes); printf("u : %d\n", u); printf("v : %d\n", v); exit(-1); } } void checkQuo(const int u, const int v, const char *mes) { int u2 = u & 0x7, v2 = v & 0x7; if (u < 0) u2 = -u2; if (v < 0) v2 = -v2; if (u2 != v2) { printf("NG : %s\n", mes); printf("u : %d %d\n", u, u2); printf("v : %d %d\n", v, v2); exit(-1); } } void checkDouble(const double u, const double v, const char *mes) { if (isinf(u) && isinf(v)) return; if (u != v) { printf("NG : %s\n", mes); printf("u : %.20g\n", u); printf("v : %.20g\n", v); exit(-1); } } #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 __int128_t rndi128() { __int128_t r = 0; for(int i=0;i<8;i++) r = (r << 16) ^ rand(); r &= ~((~(__uint128_t)0) << (rand() & 127)); return r; } __uint128_t rndu128() { __uint128_t r = 0; for(int i=0;i<8;i++) r = (r << 16) ^ rand(); r &= ~((~(__uint128_t)0) << (rand() & 127)); return r; } void checkInt128(const tlfloat_int128_t u_, const __int128_t v, const char *mes) { __int128_t u; memcpy(&u, &u_, sizeof(u)); if (u != v) { printf("NG : %s\n", mes); printf("u : 0x%016llx%016llx\n", (unsigned long long)(u >> 64), (unsigned long long)u); printf("v : 0x%016llx%016llx\n", (unsigned long long)(v >> 64), (unsigned long long)v); exit(-1); } } void checkUInt128(const tlfloat_uint128_t u_, const __uint128_t v, const char *mes) { __uint128_t u; memcpy(&u, &u_, sizeof(u)); if (u != v) { printf("NG : %s\n", mes); printf("u : 0x%016llx%016llx\n", (unsigned long long)(u >> 64), (unsigned long long)u); printf("v : 0x%016llx%016llx\n", (unsigned long long)(v >> 64), (unsigned long long)v); exit(-1); } } void doTestInt128(const __int128_t x, const __int128_t y) { tlfloat_int128_t x_, y_; memcpy(&x_, &x, sizeof(x_)); memcpy(&y_, &y, sizeof(y_)); //printf("x : 0x%016llx%016llx\n", (unsigned long long)(x >> 64), (unsigned long long)x); //printf("y : 0x%016llx%016llx\n", (unsigned long long)(y >> 64), (unsigned long long)y); checkInt128(tlfloat_add_i128_i128(x_, y_), x + y, "int128 +"); checkInt128(tlfloat_sub_i128_i128(x_, y_), x - y, "int128 -"); checkInt128(tlfloat_mul_i128_i128(x_, y_), x * y, "int128 *"); if (y != 0) { checkInt128(tlfloat_div_i128_i128(x_, y_), x / y, "int128 /"); checkInt128(tlfloat_mod_i128_i128(x_, y_), x % y, "int128 %"); } checkInt128(tlfloat_neg_i128 (x_ ), -x , "int128 -"); checkInt128(tlfloat_and_i128_i128(x_, y_), x & y, "int128 &"); checkInt128(tlfloat_or_i128_i128 (x_, y_), x | y, "int128 |"); checkInt128(tlfloat_xor_i128_i128(x_, y_), x ^ y, "int128 ^"); checkInt128(tlfloat_not_i128 (x_ ), ~x , "int128 ~"); checkInt128(tlfloat_shl_i128_i (x_, (int)(y & 127)), x << (int)(y & 127), "int128 <<"); checkInt128(tlfloat_shr_i128_i (x_, (int)(y & 127)), x >> (int)(y & 127), "int128 >>"); checkInt(tlfloat_eq_i128_i128(x_, y_), x == y, "int128 =="); checkInt(tlfloat_ne_i128_i128(x_, y_), x != y, "int128 !="); checkInt(tlfloat_gt_i128_i128(x_, y_), x > y, "int128 >"); checkInt(tlfloat_ge_i128_i128(x_, y_), x >= y, "int128 >="); checkInt(tlfloat_lt_i128_i128(x_, y_), x < y, "int128 <"); checkInt(tlfloat_le_i128_i128(x_, y_), x <= y, "int128 <="); checkDouble(tlfloat_cast_d_i128(x_), (double)x, "cast double <= int128"); checkDouble(tlfloat_cast_d_q(tlfloat_cast_q_i128(x_)), (double)x, "cast double <= quad <= int128"); checkDouble(tlfloat_cast_d_o(tlfloat_cast_o_i128(x_)), (double)x, "cast double <= octuple <= int128"); checkInt128(tlfloat_cast_i128_d((double)x), (__int128)(double)x, "cast int128 <= double"); checkInt128(tlfloat_cast_i128_q(tlfloat_cast_q_d((double)x)), (__int128)(double)x, "cast int128 <= quad <= double"); checkInt128(tlfloat_cast_i128_o(tlfloat_cast_o_d((double)x)), (__int128)(double)x, "cast int128 <= octuple <= double"); } void doTestUInt128(const __uint128_t x, const __uint128_t y) { tlfloat_uint128_t x_, y_; memcpy(&x_, &x, sizeof(x_)); memcpy(&y_, &y, sizeof(y_)); //printf("x : 0x%016llx%016llx\n", (unsigned long long)(x >> 64), (unsigned long long)x); //printf("y : 0x%016llx%016llx\n", (unsigned long long)(y >> 64), (unsigned long long)y); checkUInt128(tlfloat_add_u128_u128(x_, y_), x + y, "uint128 +"); checkUInt128(tlfloat_sub_u128_u128(x_, y_), x - y, "uint128 -"); checkUInt128(tlfloat_mul_u128_u128(x_, y_), x * y, "uint128 *"); if (y != 0) { checkUInt128(tlfloat_div_u128_u128(x_, y_), x / y, "uint128 /"); checkUInt128(tlfloat_mod_u128_u128(x_, y_), x % y, "uint128 %"); } checkUInt128(tlfloat_and_u128_u128(x_, y_), x & y, "uint128 &"); checkUInt128(tlfloat_or_u128_u128 (x_, y_), x | y, "uint128 |"); checkUInt128(tlfloat_xor_u128_u128(x_, y_), x ^ y, "uint128 ^"); checkUInt128(tlfloat_not_u128 (x_ ), ~x , "uint128 ~"); checkUInt128(tlfloat_shl_u128_i (x_, (int)(y & 127)), x << (int)(y & 127), "uint128 <<"); checkUInt128(tlfloat_shr_u128_i (x_, (int)(y & 127)), x >> (int)(y & 127), "uint128 >>"); checkInt(tlfloat_eq_u128_u128(x_, y_), x == y, "uint128 =="); checkInt(tlfloat_ne_u128_u128(x_, y_), x != y, "uint128 !="); checkInt(tlfloat_gt_u128_u128(x_, y_), x > y, "uint128 >"); checkInt(tlfloat_ge_u128_u128(x_, y_), x >= y, "uint128 >="); checkInt(tlfloat_lt_u128_u128(x_, y_), x < y, "uint128 <"); checkInt(tlfloat_le_u128_u128(x_, y_), x <= y, "uint128 <="); checkDouble(tlfloat_cast_d_u128(x_), (double)x, "cast double <= uint128"); checkDouble(tlfloat_cast_d_q(tlfloat_cast_q_u128(x_)), (double)x, "cast double <= quad <= uint128"); checkDouble(tlfloat_cast_d_o(tlfloat_cast_o_u128(x_)), (double)x, "cast double <= octuple <= uint128"); checkUInt128(tlfloat_cast_u128_d((double)x), (__uint128_t)(double)x, "cast uint128 <= double"); checkUInt128(tlfloat_cast_u128_q(tlfloat_cast_q_d((double)x)), (__uint128_t)(double)x, "cast unt128 <= quad <= double"); checkUInt128(tlfloat_cast_u128_o(tlfloat_cast_o_d((double)x)), (__uint128_t)(double)x, "cast unt128 <= octuple <= double"); } #endif char buf0[1000], buf1[1000]; int main(int argc, char **argv) { if (tlfloat_version() != TLFLOAT_VERSION_MAJOR * 1000000ULL + TLFLOAT_VERSION_MINOR * 1000ULL + TLFLOAT_VERSION_PATCH) { printf("NG : tlfloat_version()\n"); exit(-1); } const char *endptr = NULL, *oneTenth = "0.1"; checkInt(tlfloat_snprintf(buf0, sizeof(buf0), "%.8g", tlfloat_strtod(oneTenth, &endptr)), 3, "Return value of tlfloat_snprintf 1"); checkStr(buf0, "0.1", "strtod"); checkInt(endptr - oneTenth, 3, "tlfloat_strtod endptr"); checkInt(tlfloat_snprintf(buf0, sizeof(buf0), "%.8g", tlfloat_sin(tlfloat_strtod("0.1", NULL))), 11, "Return value of tlfloat_snprintf 2"); checkStr(buf0, "0.099833417", "sin"); tlfloat_snprintf(buf0, sizeof(buf0), "%.8Qg", tlfloat_strtoq("0.1", NULL)); checkStr(buf0, "0.1", "strtoq"); tlfloat_snprintf(buf0, sizeof(buf0), "%.8Qg", tlfloat_sinq(tlfloat_strtoq("0.1", NULL))); checkStr(buf0, "0.099833417", "sinq"); tlfloat_snprintf(buf0, sizeof(buf0), "%.8Qg", strtoflt128("0.1", NULL)); checkStr(buf0, "0.1", "quadmath strtoflt128"); tlfloat_snprintf(buf0, sizeof(buf0), "%.8Qg", sinq(strtoflt128("0.1", NULL))); checkStr(buf0, "0.099833417", "quadmath sinq val"); quadmath_snprintf(buf0, sizeof(buf0), "%.8Qg", strtoflt128("0.1", NULL)); checkStr(buf0, "0.1", "quadmath_snprintf"); { tlfloat_quad q = tlfloat_strtoq("0.1", NULL); tlfloat_snprintf(buf0, sizeof(buf0), "%.8Pg", &q); checkStr(buf0, "0.1", "strtoq ptr"); q = tlfloat_sinq(tlfloat_strtoq("0.1", NULL)); tlfloat_snprintf(buf0, sizeof(buf0), "%.8Pg", &q); checkStr(buf0, "0.099833417", "sinq ptr"); q = strtoflt128("0.1", NULL); tlfloat_snprintf(buf0, sizeof(buf0), "%.8Pg", &q); checkStr(buf0, "0.1", "quadmath strtoflt128 ptr"); q = sinq(strtoflt128("0.1", NULL)); tlfloat_snprintf(buf0, sizeof(buf0), "%.8Pg", &q); checkStr(buf0, "0.099833417", "quadmath sinq val ptr"); } #ifdef TLFLOAT_COMPILER_SUPPORTS_FLOAT128 tlfloat_snprintf(buf0, sizeof(buf0), "%.8Qg", (__float128)1.0 / (__float128)10.0); checkStr(buf0, "0.1", "tlfloat_snprintf"); #elif defined(TLFLOAT_LONGDOUBLE_IS_FLOAT128) tlfloat_snprintf(buf0, sizeof(buf0), "%.8Lg", strtold("0.1", NULL)); checkStr(buf0, "0.1", "strtold"); #endif tlfloat_snprintf(buf0, sizeof(buf0), "%.8Og", tlfloat_strtoo("0.1", NULL)); checkStr(buf0, "0.1", "strtoo"); tlfloat_snprintf(buf0, sizeof(buf0), "%.8Og", tlfloat_sino(tlfloat_strtoo("0.1", NULL))); checkStr(buf0, "0.099833417", "sino"); // tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_cast_q_o(tlfloat_strtoo("0.123", NULL))); checkStr("0.123", buf1, "tlfloat_cast_q_o"); tlfloat_snprintf(buf1, sizeof(buf1), "%.12Qg", tlfloat_cast_q_d(tlfloat_strtod("0.123", NULL))); checkStr("0.123", buf1, "tlfloat_cast_q_d"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_cast_o_q(tlfloat_strtoq("0.123", NULL))); checkStr("0.123", buf1, "tlfloat_cast_o_q"); tlfloat_snprintf(buf1, sizeof(buf1), "%.12Og", tlfloat_cast_o_d(tlfloat_strtod("0.123", NULL))); checkStr("0.123", buf1, "tlfloat_cast_o_d"); tlfloat_quad q0 = strtoflt128("0.123", NULL), q1 = strtoflt128("1.234", NULL), q2 = strtoflt128("-0.345", NULL); tlfloat_octuple o0 = tlfloat_strtoo("0.123", NULL), o1 = tlfloat_strtoo("1.234", NULL), o2 = tlfloat_strtoo("-0.345", NULL); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", fmaq(q0, q1, q2)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_fmaq(q0, q1, q2)); checkStr(buf0, buf1, "quadmath fmaq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_fmao(o0, o1, o2)); checkStr(buf0, buf1, "quadmath fmao"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", sqrtq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_sqrtq(q0)); checkStr(buf0, buf1, "quadmath sqrtq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_sqrto(o0)); checkStr(buf0, buf1, "quadmath sqrto"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", sinq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_sinq(q0)); checkStr(buf0, buf1, "quadmath sinq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_sino(o0)); checkStr(buf0, buf1, "quadmath sino"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", cosq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_cosq(q0)); checkStr(buf0, buf1, "quadmath cosq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_coso(o0)); checkStr(buf0, buf1, "quadmath coso"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", tanq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_tanq(q0)); checkStr(buf0, buf1, "quadmath tanq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_tano(o0)); checkStr(buf0, buf1, "quadmath tano"); tlfloat_snprintf(buf1, sizeof(buf1), "%.6Qg", tlfloat_sinpiq(q0)); checkStr("0.376871", buf1, "quadmath sinpiq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.6Og", tlfloat_sinpio(o0)); checkStr("0.376871", buf1, "quadmath sinpio"); tlfloat_snprintf(buf1, sizeof(buf1), "%.6Qg", tlfloat_cospiq(q0)); checkStr("0.926266", buf1, "quadmath cospiq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.6Og", tlfloat_cospio(o0)); checkStr("0.926266", buf1, "quadmath cospio"); tlfloat_snprintf(buf1, sizeof(buf1), "%.6Qg", tlfloat_tanpiq(q0)); checkStr("0.406871", buf1, "quadmath tanpiq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.6Og", tlfloat_tanpio(o0)); checkStr("0.406871", buf1, "quadmath tanpio"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", asinq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_asinq(q0)); checkStr(buf0, buf1, "quadmath asinq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_asino(o0)); checkStr(buf0, buf1, "quadmath asino"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", acosq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_acosq(q0)); checkStr(buf0, buf1, "quadmath acosq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_acoso(o0)); checkStr(buf0, buf1, "quadmath acoso"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", atanq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_atanq(q0)); checkStr(buf0, buf1, "quadmath atanq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_atano(o0)); checkStr(buf0, buf1, "quadmath atano"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", atan2q(q0, q1)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_atan2q(q0, q1)); checkStr(buf0, buf1, "quadmath atan2q"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_atan2o(o0, o1)); checkStr(buf0, buf1, "quadmath atan2o"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", sinhq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_sinhq(q0)); checkStr(buf0, buf1, "quadmath sinhq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_sinho(o0)); checkStr(buf0, buf1, "quadmath sinho"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", coshq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_coshq(q0)); checkStr(buf0, buf1, "quadmath coshq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_cosho(o0)); checkStr(buf0, buf1, "quadmath cosho"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", tanhq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_tanhq(q0)); checkStr(buf0, buf1, "quadmath tanhq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_tanho(o0)); checkStr(buf0, buf1, "quadmath tanho"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", asinhq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_asinhq(q0)); checkStr(buf0, buf1, "quadmath asinhq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_asinho(o0)); checkStr(buf0, buf1, "quadmath asinho"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", acoshq(q1)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_acoshq(q1)); checkStr(buf0, buf1, "quadmath acoshq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_acosho(o1)); checkStr(buf0, buf1, "quadmath acosho"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", atanhq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_atanhq(q0)); checkStr(buf0, buf1, "quadmath atanhq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_atanho(o0)); checkStr(buf0, buf1, "quadmath atanho"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", expq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_expq(q0)); checkStr(buf0, buf1, "quadmath expq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_expo(o0)); checkStr(buf0, buf1, "quadmath expo"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", exp2q(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_exp2q(q0)); checkStr(buf0, buf1, "quadmath exp2q"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_exp2o(o0)); checkStr(buf0, buf1, "quadmath exp2o"); #ifndef TRUE_LIBQUADMATH quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", exp10q(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_exp10q(q0)); checkStr(buf0, buf1, "quadmath exp10q"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_exp10o(o0)); checkStr(buf0, buf1, "quadmath exp10o"); #endif quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", expm1q(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_expm1q(q0)); checkStr(buf0, buf1, "quadmath expm1q"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_expm1o(o0)); checkStr(buf0, buf1, "quadmath expm1o"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", logq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_logq(q0)); checkStr(buf0, buf1, "quadmath logq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_logo(o0)); checkStr(buf0, buf1, "quadmath logo"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", log2q(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_log2q(q0)); checkStr(buf0, buf1, "quadmath log2q"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_log2o(o0)); checkStr(buf0, buf1, "quadmath log2o"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", log10q(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_log10q(q0)); checkStr(buf0, buf1, "quadmath log10q"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_log10o(o0)); checkStr(buf0, buf1, "quadmath log10o"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", log1pq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_log1pq(q0)); checkStr(buf0, buf1, "quadmath log1pq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_log1po(o0)); checkStr(buf0, buf1, "quadmath log1po"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", powq(q0, q1)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_powq(q0, q1)); checkStr(buf0, buf1, "quadmath powq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_powo(o0, o1)); checkStr(buf0, buf1, "quadmath powo"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", cbrtq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_cbrtq(q0)); checkStr(buf0, buf1, "quadmath cbrtq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_cbrto(o0)); checkStr(buf0, buf1, "quadmath cbrto"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", erfq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_erfq(q0)); checkStr(buf0, buf1, "quadmath erfq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_erfo(o0)); checkStr(buf0, buf1, "quadmath erfo"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", erfcq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_erfcq(q0)); checkStr(buf0, buf1, "quadmath erfcq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_erfco(o0)); checkStr(buf0, buf1, "quadmath erfco"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", tgammaq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_tgammaq(q0)); checkStr(buf0, buf1, "quadmath tgammaq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_tgammao(o0)); checkStr(buf0, buf1, "quadmath tgammao"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", lgammaq(q0)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_lgammaq(q0)); checkStr(buf0, buf1, "quadmath lgammaq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_lgammao(o0)); checkStr(buf0, buf1, "quadmath lgammao"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", hypotq(q0, q1)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_hypotq(q0, q1)); checkStr(buf0, buf1, "quadmath hypotq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_hypoto(o0, o1)); checkStr(buf0, buf1, "quadmath hypoto"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", fmodq(q0, q1)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_fmodq(q0, q1)); checkStr(buf0, buf1, "quadmath fmodq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_fmodo(o0, o1)); checkStr(buf0, buf1, "quadmath fmodo"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", remainderq(q0, q1)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_remainderq(q0, q1)); checkStr(buf0, buf1, "quadmath remainderq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_remaindero(o0, o1)); checkStr(buf0, buf1, "quadmath remaindero"); int cquo = 0, tquo = 0; quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", remquoq(q0, q1, &cquo)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_remquoq(q0, q1, &tquo)); checkStr(buf0, buf1, "quadmath remquoq remainder"); checkQuo(cquo, tquo, "quadmath remquoq quo"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_remquoo(o0, o1, &tquo)); checkStr(buf0, buf1, "quadmath remquoo remainder"); checkQuo(cquo, tquo, "quadmath remquoo quo"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", fabsq(q2)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_fabsq(q2)); checkStr(buf0, buf1, "quadmath fabsq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_fabso(o2)); checkStr(buf0, buf1, "quadmath fabso"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", copysignq(q0, q2)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_copysignq(q0, q2)); checkStr(buf0, buf1, "quadmath copysignq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_copysigno(o0, o2)); checkStr(buf0, buf1, "quadmath copysigno"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", fmaxq(q0, q2)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_fmaxq(q0, q2)); checkStr(buf0, buf1, "quadmath fmaxq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_fmaxo(o0, o2)); checkStr(buf0, buf1, "quadmath fmaxo"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", fminq(q0, q2)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_fminq(q0, q2)); checkStr(buf0, buf1, "quadmath fminq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_fmino(o0, o2)); checkStr(buf0, buf1, "quadmath fmino"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", fdimq(q0, q2)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_fdimq(q0, q2)); checkStr(buf0, buf1, "quadmath fdimq"); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Og", tlfloat_fdimo(o0, o2)); checkStr(buf0, buf1, "quadmath fdimo"); quadmath_snprintf(buf0, sizeof(buf0), "%.24Qg", nextafterq(q0, q2)); tlfloat_snprintf(buf1, sizeof(buf1), "%.24Qg", tlfloat_nextafterq(q0, q2)); checkStr(buf0, buf1, "quadmath nextafterq"); #ifdef __STDC_VERSION__ tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_Eq); checkStr("0x1.5bf0a8b1457695355fb8ac404e7ap+1", buf1, "M_Eq"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_LOG2Eq); checkStr("0x1.71547652b82fe1777d0ffda0d23ap+0", buf1, "M_LOG2Eq"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_LOG10Eq); checkStr("0x1.bcb7b1526e50e32a6ab7555f5a68p-2", buf1, "M_LOG10Eq"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_LN2q); checkStr("0x1.62e42fefa39ef35793c7673007e6p-1", buf1, "M_LN2q"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_LN10q); checkStr("0x1.26bb1bbb5551582dd4adac5705a6p+1", buf1, "M_LN10q"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_PIq); checkStr("0x1.921fb54442d18469898cc51701b8p+1", buf1, "M_PIq"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_PI_2q); checkStr("0x1.921fb54442d18469898cc51701b8p+0", buf1, "M_PI_2q"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_PI_4q); checkStr("0x1.921fb54442d18469898cc51701b8p-1", buf1, "M_PI_4q"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_1_PIq); checkStr("0x1.45f306dc9c882a53f84eafa3ea6ap-2", buf1, "M_1_PIq"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_2_PIq); checkStr("0x1.45f306dc9c882a53f84eafa3ea6ap-1", buf1, "M_2_PIq"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_2_SQRTPIq); checkStr("0x1.20dd750429b6d11ae3a914fed7fep+0", buf1, "M_2_SQRTPIq"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_SQRT2q); checkStr("0x1.6a09e667f3bcc908b2fb1366ea95p+0", buf1, "M_SQRT2q"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", M_SQRT1_2q); checkStr("0x1.6a09e667f3bcc908b2fb1366ea95p-1", buf1, "M_SQRT1_2q"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", FLT128_MAX); checkStr("0x1.ffffffffffffffffffffffffffffp+16383", buf1, "FLT128_MAX"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", FLT128_MIN); checkStr("0x1p-16382", buf1, "FLT128_MIN"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", FLT128_DENORM_MIN); checkStr("0x1p-16494", buf1, "FLT128_DENORM_MIN"); tlfloat_snprintf(buf1, sizeof(buf1), "%Qa", FLT128_EPSILON); checkStr("0x1p-112", buf1, "FLT128_EPSILON"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_Eo); checkStr("0x1.5bf0a8b1457695355fb8ac404e7a79e3b1738b079c5a6d2b53c26c8228dp+1", buf1, "TLFLOAT_M_Eo"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_LOG2Eo); checkStr("0x1.71547652b82fe1777d0ffda0d23a7d11d6aef551bad2b4b1164a2cd9a34p+0", buf1, "TLFLOAT_M_LOG2Eo"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_LOG10Eo); checkStr("0x1.bcb7b1526e50e32a6ab7555f5a67b8647dc68c048b934404747e5a89ef2p-2", buf1, "TLFLOAT_M_LOG10Eo"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_LN2o); checkStr("0x1.62e42fefa39ef35793c7673007e5ed5e81e6864ce5316c5b141a2eb7175p-1", buf1, "TLFLOAT_M_LN2o"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_LN10o); checkStr("0x1.26bb1bbb5551582dd4adac5705a61451c51fd9f3b4bbf21d078c3d0403ep+1", buf1, "TLFLOAT_M_LN10o"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_PIo); checkStr("0x1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d4c762p+1", buf1, "TLFLOAT_M_PIo"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_PI_2o); checkStr("0x1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d4c762p+0", buf1, "TLFLOAT_M_PI_2o"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_PI_4o); checkStr("0x1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d4c762p-1", buf1, "TLFLOAT_M_PI_4o"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_1_PIo); checkStr("0x1.45f306dc9c882a53f84eafa3ea69bb81b6c52b3278872083fca2c757bd7p-2", buf1, "TLFLOAT_M_1_PIo"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_2_PIo); checkStr("0x1.45f306dc9c882a53f84eafa3ea69bb81b6c52b3278872083fca2c757bd7p-1", buf1, "TLFLOAT_M_2_PIo"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_2_SQRTPIo); checkStr("0x1.20dd750429b6d11ae3a914fed7fd8688281341d7587cea2e7342b06199dp+0", buf1, "TLFLOAT_M_2_SQRTPIo"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_SQRT2o); checkStr("0x1.6a09e667f3bcc908b2fb1366ea957d3e3adec17512775099da2f590b066p+0", buf1, "TLFLOAT_M_SQRT2o"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_M_SQRT1_2o); checkStr("0x1.6a09e667f3bcc908b2fb1366ea957d3e3adec17512775099da2f590b066p-1", buf1, "TLFLOAT_M_SQRT1_2o"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_FLT256_MAX); checkStr("0x1.fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp+262143", buf1, "TLFLOAT_FLT256_MAX"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_FLT256_MIN); checkStr("0x1p-262142", buf1, "TLFLOAT_FLT256_MIN"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_FLT256_DENORM_MIN); checkStr("0x1p-262378", buf1, "TLFLOAT_FLT256_DENORM_MIN"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_FLT256_TRUE_MIN); checkStr("0x1p-262378", buf1, "TLFLOAT_FLT256_TRUE_MIN"); tlfloat_snprintf(buf1, sizeof(buf1), "%Oa", TLFLOAT_FLT256_EPSILON); checkStr("0x1p-236", buf1, "TLFLOAT_FLT256_EPSILON"); #endif { float a = tlfloat_strtof("0.1", NULL), s, c; tlfloat_sincosf(a, &s, &c); checkInt(s == tlfloat_sinf(a), 1, "sin in tlfloat_sincosf"); checkInt(c == tlfloat_cosf(a), 1, "cos in tlfloat_sincosf"); tlfloat_sincospif(a, &s, &c); checkInt(s == tlfloat_sinpif(a), 1, "sin in tlfloat_sincosf"); checkInt(c == tlfloat_cospif(a), 1, "cos in tlfloat_sincosf"); } { double a = tlfloat_strtod("0.1", NULL), s, c; tlfloat_sincos(a, &s, &c); checkInt(s == tlfloat_sin(a), 1, "sin in tlfloat_sincos"); checkInt(c == tlfloat_cos(a), 1, "cos in tlfloat_sincos"); tlfloat_sincospi(a, &s, &c); checkInt(s == tlfloat_sinpi(a), 1, "sin in tlfloat_sincos"); checkInt(c == tlfloat_cospi(a), 1, "cos in tlfloat_sincos"); } { tlfloat_quad a = tlfloat_strtoq("0.1", NULL), s, c; tlfloat_sincosq(a, &s, &c); checkInt(tlfloat_eq_q_q(s, tlfloat_sinq(a)), 1, "sin in tlfloat_sincosq"); checkInt(tlfloat_eq_q_q(c, tlfloat_cosq(a)), 1, "cos in tlfloat_sincosq"); tlfloat_sincospiq(a, &s, &c); checkInt(tlfloat_eq_q_q(s, tlfloat_sinpiq(a)), 1, "sin in tlfloat_sincosq"); checkInt(tlfloat_eq_q_q(c, tlfloat_cospiq(a)), 1, "cos in tlfloat_sincosq"); } { tlfloat_octuple a = tlfloat_strtoo("0.1", NULL), s, c; tlfloat_sincoso(a, &s, &c); checkInt(tlfloat_eq_o_o(s, tlfloat_sino(a)), 1, "sin in tlfloat_sincoso"); checkInt(tlfloat_eq_o_o(c, tlfloat_coso(a)), 1, "cos in tlfloat_sincoso"); tlfloat_sincospio(a, &s, &c); checkInt(tlfloat_eq_o_o(s, tlfloat_sinpio(a)), 1, "sin in tlfloat_sincoso"); checkInt(tlfloat_eq_o_o(c, tlfloat_cospio(a)), 1, "cos in tlfloat_sincoso"); } // #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 srand(time(NULL)); for(int i=0;i<100000;i++) { doTestInt128(rndi128(), rndi128()); doTestUInt128(rndu128(), rndu128()); } printf("int128 OK\n"); #endif // printf("OK\n"); exit(0); } tlfloat-1.15.0/src/tester/test_cpp11api.cpp000066400000000000000000001214721477036600700205420ustar00rootroot00000000000000#include #include #include #include #include #include #include #if __cplusplus >= 202002L #include #endif #define TLFLOAT_LIBQUADMATH_EMULATION #include #include using namespace std; using namespace tlfloat; static_assert(is_trivially_copyable::value, "tlfloat_quad not trivially copyable"); static_assert(is_trivially_copyable::value, "tlfloat_octuple not trivially copyable"); static_assert(is_trivially_copyable::value, "tlfloat_int128_t not trivially copyable"); static_assert(is_trivially_copyable::value, "tlfloat_uint128_t not trivially copyable"); extern const tlfloat_quad testvar = M_PIq; static void check(const string& msg, double x, double y, int t=0) { uint64_t u, v; memcpy((void *)&u, (void *)&x, sizeof(u)); memcpy((void *)&v, (void *)&y, sizeof(v)); #if 0 printf("%s : ", msg.c_str()); printf("x : %.18g %016llx, ", x, (unsigned long long)u); printf("y : %.18g %016llx\n", y, (unsigned long long)v); #endif if (isnan(x) && isnan(y)) return; if (t == 0 && u == v) return; int d = int(int64_t(u) - int64_t(v)); if (-t <= d && d <= t) return; cout << "NG " << msg << endl; printf("x : %.18g %016llx\n", x, (unsigned long long)u); printf("y : %.18g %016llx\n", y, (unsigned long long)v); exit(-1); } static void check(const string& msg, tlfloat_octuple x, double y, int t=0) { check(msg, double(x), y, t); } static void check(const string& msg, tlfloat_quad x, double y, int t=0) { check(msg, double(x), y, t); } static void check(const string& msg, int x, int y) { if (x == y) return; cout << "NG " << msg << endl; printf("x : %d\n", x); printf("y : %d\n", y); exit(-1); } static void check_ilogb(const string& msg, int t, int c) { if (t == TLFLOAT_FP_ILOGB0 && c == FP_ILOGB0) return; if (t == TLFLOAT_FP_ILOGBNAN && c == FP_ILOGBNAN) return; if (t == c) return; cout << "NG " << msg << endl; printf("t : %d\n", t); printf("c : %d\n", c); exit(-1); } static void check(const string& msg, bool x, bool y) { check(msg, (int)x, (int)y); } static void checkQuo(const string& msg, int x, int y) { int x2 = x & 0x7, y2 = y & 0x7; if (x < 0) x2 = -x2; if (y < 0) y2 = -y2; if (x2 == y2) return; cout << "NG " << msg << endl; printf("x : %x %d\n", x, x2); printf("y : %x %d\n", y, y2); exit(-1); } static void check(const string& msg, const char* x, const char* y) { if (strncmp(x, y, strlen(y)) == 0) return; cout << "NG " << msg << endl; printf("x : %s\n", x); printf("y : %s\n", y); exit(-1); } static void checkStr(const char *p, const char *q, const char *mes) { if (strcmp(p, q) != 0) { printf("NG : %s\n", mes); printf("p : %s\n", p); printf("q : %s\n", q); exit(-1); } } static double o2d(tlfloat_octuple o) { return (double)o; } static double q2d(tlfloat_quad q) { return (double)q; } void doTest(const string &s1, const string &s2) { tlfloat_octuple o0; tlfloat_octuple o1 = tlfloat_strtoo(s1.c_str(), NULL); tlfloat_octuple o2 = tlfloat_strtoo(s2.c_str(), NULL); tlfloat_octuple q0; tlfloat_quad q1 = tlfloat_strtoq(s1.c_str(), NULL); tlfloat_quad q2 = strtoflt128(s2.c_str(), NULL); double d0; double d1 = (double)(tlfloat_quad)atof(s1.c_str()); double d2 = atof(s2.c_str()); float f1 = d1, f2 = d2; int i1 = atoi(s1.c_str()); int i2 = atoi(s2.c_str()); tlfloat_int128_t j1 = tlfloat_strtoi128(s1.c_str(), NULL, 10); tlfloat_int128_t j2 = tlfloat_strtoi128(s2.c_str(), NULL, 10); long long k1 = strtoll(s1.c_str(), NULL, 10); long long k2 = strtoll(s2.c_str(), NULL, 10); check("tlfloat_stroo", o1, d1); check("tlfloat_stroq", q1, d1); char strx[256], stry[256]; snprintf(stry, sizeof(stry), "%.12g %.12g %d\n", d1, d2, 12345678); tlfloat_snprintf(strx, sizeof(strx), "%.12_256g %.12_256g %d\n", o1, o2, 12345678); check("tlfloat_snprintf tlfloat_octuple", strx, stry); tlfloat_snprintf(strx, sizeof(strx), "%.12Qg %.12Qg %d\n", q1, q2, 12345678); check("tlfloat_snprintf tlfloat_quad", strx, stry); quadmath_snprintf(strx, sizeof(strx), "%.12Qg %.12Qg %d\n", q1, q2, 12345678); check("quadmath_snprintf tlfloat_quad", strx, stry); check("double(tlfloat_octuple(d1))", double(tlfloat_octuple(d1)), d1); check("double(tlfloat_quad(d1))", double(tlfloat_quad(d1)), d1); check("tlfloat_octuple(q1)", (double)tlfloat_octuple(q1), d1); check("tlfloat_octuple(d1)", (double)tlfloat_octuple(d1), d1); check("tlfloat_octuple(f1)", (double)tlfloat_octuple(f1), d1); check("tlfloat_octuple(i1)", (double)tlfloat_octuple(i1), (double)i1); check("tlfloat_octuple(j1)", (double)tlfloat_octuple(j1), (double)j1); check("tlfloat_octuple(k1)", (double)tlfloat_octuple(k1), (double)k1); check("tlfloat_quad(o1)", (double)tlfloat_quad(o1), d1); check("tlfloat_quad(d1)", (double)tlfloat_quad(d1), d1); check("tlfloat_quad(f1)", (double)tlfloat_quad(f1), d1); check("tlfloat_quad(i1)", (double)tlfloat_quad(i1), (double)i1); check("tlfloat_quad(j1)", (double)tlfloat_quad(j1), (double)j1); check("tlfloat_quad(k1)", (double)tlfloat_quad(k1), (double)k1); check("tlfloat_int128_t(o1)", (double)tlfloat_int128_t(o1), (double)o1); check("o2d(i1)", o2d(i1), (double)i1); check("o2d(j1)", o2d(j1), (double)j1); check("o2d(k1)", o2d(k1), (double)k1); check("tlfloat_int128_t(q1)", (double)tlfloat_int128_t(q1), (double)q1); check("o2d(q1)", o2d(q1), (double)q1); check("q2d(d1)", q2d(d1), d1); check("q2d(i1)", q2d(i1), (double)i1); check("o1 + o2", o1 + o2, d1 + d2); check("d1 + o2", d1 + o2, d1 + d2); check("f1 + o2", f1 + o2, d1 + d2); check("o1 + f2", o1 + f2, d1 + d2); check("i1 + o2", i1 + o2, i1 + d2); check("j1 + o2", j1 + o2, (double)j1 + d2); check("k1 + o2", k1 + o2, (double)k1 + d2); check("o1 + i2", o1 + i2, d1 + i2); check("o1 + j2", o1 + j2, d1 + (double)j2); check("o1 + k2", o1 + k2, d1 + (double)k2); o0 = o1; o0 += o2; check("o0 = o1; o0 += o2;", o0, d1 + d2); o0 = o1; o0 += q2; check("o0 = o1; o0 += q2;", o0, d1 + d2); o0 = o1; o0 += d2; check("o0 = o1; o0 += d2;", o0, d1 + d2); o0 = o1; o0 += i2; check("o0 = o1; o0 += i2;", o0, d1 + i2); o0 = o1; o0 += j2; check("o0 = o1; o0 += j2;", o0, d1 + (double)j2); o0 = o1; o0 += k2; check("o0 = o1; o0 += k2;", o0, d1 + (double)k2); o0 = o1; d0 = d1; check("o0 = o1; o0 ++;", o0++, d0++); check("o0 = o1; o0 ++; (2)", o0, d0); o0 = o1; d0 = d1; check("o0 = o1; ++ o0;", ++o0, ++d0); check("o0 = o1; ++ o0; (2)", o0, d0); check("o1 - o2", o1 - o2, d1 - d2); check("d1 - o2", d1 - o2, d1 - d2); check("f1 - o2", f1 - o2, d1 - d2); check("o1 - f2", o1 - f2, d1 - d2); check("i1 - o2", i1 - o2, i1 - d2); check("j1 - o2", j1 - o2, (double)j1 - d2); check("k1 - o2", k1 - o2, (double)k1 - d2); check("o1 - i2", o1 - i2, d1 - i2); check("o1 - j2", o1 - j2, d1 - (double)j2); check("o1 - k2", o1 - k2, d1 - (double)k2); o0 = o1; o0 -= o2; check("o0 = o1; o0 -= o2;", o0, d1 - d2); o0 = o1; o0 -= q2; check("o0 = o1; o0 -= q2;", o0, d1 - d2); o0 = o1; o0 -= d2; check("o0 = o1; o0 -= d2;", o0, d1 - d2); o0 = o1; o0 -= i2; check("o0 = o1; o0 -= i2;", o0, d1 - i2); o0 = o1; o0 -= j2; check("o0 = o1; o0 -= j2;", o0, d1 - (double)j2); o0 = o1; o0 -= k2; check("o0 = o1; o0 -= k2;", o0, d1 - (double)k2); o0 = o1; d0 = d1; check("o0 = o1; o0 --;", o0--, d0--); check("o0 = o1; o0 --; (2)", o0, d0); o0 = o1; d0 = d1; check("o0 = o1; -- o0;", --o0, --d0); check("o0 = o1; -- o0; (2)", o0, d0); check("o1 * o2", o1 * o2, d1 * d2); check("d1 * o2", d1 * o2, d1 * d2); check("f1 * o2", f1 * o2, d1 * d2); check("o1 * f2", o1 * f2, d1 * d2); check("i1 * o2", i1 * o2, i1 * d2); check("j1 * o2", j1 * o2, (double)j1 * d2); check("k1 * o2", k1 * o2, (double)k1 * d2); check("o1 * i2", o1 * i2, d1 * i2); check("o1 * j2", o1 * j2, d1 * (double)j2); check("o1 * k2", o1 * k2, d1 * (double)k2); o0 = o1; o0 *= o2; check("o0 = o1; o0 *= o2;", o0, d1 * d2); o0 = o1; o0 *= q2; check("o0 = o1; o0 *= q2;", o0, d1 * d2); o0 = o1; o0 *= d2; check("o0 = o1; o0 *= d2;", o0, d1 * d2); o0 = o1; o0 *= i2; check("o0 = o1; o0 *= i2;", o0, d1 * i2); o0 = o1; o0 *= j2; check("o0 = o1; o0 *= j2;", o0, d1 * (double)j2); o0 = o1; o0 *= k2; check("o0 = o1; o0 *= k2;", o0, d1 * (double)k2); check("o1 / o2", o1 / o2, d1 / d2); check("d1 / o2", d1 / o2, d1 / d2); check("f1 / o2", f1 / o2, d1 / d2); check("o1 / f2", o1 / f2, d1 / d2); check("i1 / o2", i1 / o2, i1 / d2); check("j1 / o2", j1 / o2, (double)j1 / d2); check("k1 / o2", k1 / o2, (double)k1 / d2); check("o1 / i2", o1 / i2, d1 / i2); check("o1 / j2", o1 / j2, d1 / (double)j2); check("o1 / k2", o1 / k2, d1 / (double)k2); o0 = o1; o0 /= o2; check("o0 = o1; o0 /= o2;", o0, d1 / d2); o0 = o1; o0 /= q2; check("o0 = o1; o0 /= q2;", o0, d1 / d2); o0 = o1; o0 /= d2; check("o0 = o1; o0 /= d2;", o0, d1 / d2); o0 = o1; o0 /= i2; check("o0 = o1; o0 /= i2;", o0, d1 / i2); o0 = o1; o0 /= j2; check("o0 = o1; o0 /= j2;", o0, d1 / (double)j2); o0 = o1; o0 /= k2; check("o0 = o1; o0 /= k2;", o0, d1 / (double)k2); check("q1 + q2", q1 + q2, d1 + d2); check("d1 + q2", d1 + q2, d1 + d2); check("f1 + q2", f1 + q2, d1 + d2); check("q1 + f2", q1 + f2, d1 + d2); check("i1 + q2", i1 + q2, i1 + d2); check("j1 + q2", (tlfloat_quad)j1 + q2, (double)j1 + d2); check("k1 + q2", (tlfloat_quad)k1 + q2, (double)k1 + d2); check("q1 + i2", q1 + i2, d1 + i2); check("q1 + j2", q1 + (tlfloat_quad)j2, d1 + (double)j2); check("q1 + k2", q1 + (tlfloat_quad)k2, d1 + (double)k2); q0 = q1; q0 += o2; check("q0 = q1; q0 += o2;", q0, d1 + d2); q0 = q1; q0 += q2; check("q0 = q1; q0 += q2;", q0, d1 + d2); q0 = q1; q0 += d2; check("q0 = q1; q0 += d2;", q0, d1 + d2); q0 = q1; q0 += i2; check("q0 = q1; q0 += i2;", q0, d1 + i2); q0 = q1; q0 += j2; check("q0 = q1; q0 += j2;", q0, d1 + (double)j2); q0 = q1; q0 += k2; check("q0 = q1; q0 += k2;", q0, d1 + (double)k2); check("q1 - q2", q1 - q2, d1 - d2); check("d1 - q2", d1 - q2, d1 - d2); check("f1 - q2", f1 - q2, d1 - d2); check("q1 - f2", q1 - f2, d1 - d2); check("i1 - q2", i1 - q2, i1 - d2); check("j1 - q2", (tlfloat_quad)j1 - q2, (double)j1 - d2); check("k1 - q2", (tlfloat_quad)k1 - q2, (double)k1 - d2); check("q1 - i2", q1 - i2, d1 - i2); check("q1 - j2", q1 - (tlfloat_quad)j2, d1 - (double)j2); check("q1 - k2", q1 - (tlfloat_quad)k2, d1 - (double)k2); q0 = q1; q0 -= o2; check("q0 = q1; q0 -= o2;", q0, d1 - d2); q0 = q1; q0 -= q2; check("q0 = q1; q0 -= q2;", q0, d1 - d2); q0 = q1; q0 -= d2; check("q0 = q1; q0 -= d2;", q0, d1 - d2); q0 = q1; q0 -= i2; check("q0 = q1; q0 -= i2;", q0, d1 - i2); q0 = q1; q0 -= j2; check("q0 = q1; q0 -= j2;", q0, d1 - (double)j2); q0 = q1; q0 -= k2; check("q0 = q1; q0 -= k2;", q0, d1 - (double)k2); check("q1 * q2", q1 * q2, d1 * d2); check("d1 * q2", d1 * q2, d1 * d2); check("f1 * q2", f1 * q2, d1 * d2); check("q1 * f2", q1 * f2, d1 * d2); check("i1 * q2", i1 * q2, i1 * d2); check("j1 * q2", (tlfloat_quad)j1 * q2, (double)j1 * d2); check("k1 * q2", (tlfloat_quad)k1 * q2, (double)k1 * d2); check("q1 * i2", q1 * i2, d1 * i2); check("q1 * j2", q1 * (tlfloat_quad)j2, d1 * (double)j2); check("q1 * k2", q1 * (tlfloat_quad)k2, d1 * (double)k2); q0 = q1; q0 *= o2; check("q0 = q1; q0 *= o2;", q0, d1 * d2); q0 = q1; q0 *= q2; check("q0 = q1; q0 *= q2;", q0, d1 * d2); q0 = q1; q0 *= d2; check("q0 = q1; q0 *= d2;", q0, d1 * d2); q0 = q1; q0 *= i2; check("q0 = q1; q0 *= i2;", q0, d1 * i2); q0 = q1; q0 *= j2; check("q0 = q1; q0 *= j2;", q0, d1 * (double)j2); q0 = q1; q0 *= k2; check("q0 = q1; q0 *= k2;", q0, d1 * (double)k2); check("q1 / q2", q1 / q2, d1 / d2); check("d1 / q2", d1 / q2, d1 / d2); check("f1 / q2", f1 / q2, d1 / d2); check("q1 / f2", q1 / f2, d1 / d2); check("i1 / q2", i1 / q2, i1 / d2); check("j1 / q2", (tlfloat_quad)j1 / q2, (double)j1 / d2); check("k1 / q2", (tlfloat_quad)k1 / q2, (double)k1 / d2); check("q1 / i2", q1 / i2, d1 / i2); check("q1 / j2", q1 / (tlfloat_quad)j2, d1 / (double)j2); check("q1 / k2", q1 / (tlfloat_quad)k2, d1 / (double)k2); q0 = q1; q0 /= o2; check("q0 = q1; q0 /= o2;", q0, d1 / d2); q0 = q1; q0 /= q2; check("q0 = q1; q0 /= q2;", q0, d1 / d2); q0 = q1; q0 /= d2; check("q0 = q1; q0 /= d2;", q0, d1 / d2); q0 = q1; q0 /= i2; check("q0 = q1; q0 /= i2;", q0, d1 / i2); q0 = q1; q0 /= j2; check("q0 = q1; q0 /= j2;", q0, d1 / (double)j2); q0 = q1; q0 /= k2; check("q0 = q1; q0 /= k2;", q0, d1 / (double)k2); const int T = 4; check("tlfloat_sqrto(o1)", tlfloat_sqrto(o1), sqrt(d1), T); check("sqrt_(o1)", sqrt_(o1), sqrt(d1), T); check("tlfloat_fabso(o1)", tlfloat_fabso(o1), fabs(d1), T); check("fabs_(o1)", fabs_(o1), fabs(d1), T); check("tlfloat_trunco(o1)", tlfloat_trunco(o1), trunc(d1), T); check("trunc_(o1)", trunc_(o1), trunc(d1), T); check("tlfloat_flooro(o1)", tlfloat_flooro(o1), floor(d1), T); check("floor_(o1)", floor_(o1), floor(d1), T); check("tlfloat_ceilo(o1)", tlfloat_ceilo(o1), ceil(d1), T); check("ceil_(o1)", ceil_(o1), ceil(d1), T); check("tlfloat_roundo(o1)", tlfloat_roundo(o1), round(d1), T); check("round_(o1)", round_(o1), round(d1), T); check("tlfloat_rinto(o1)", tlfloat_rinto(o1), rint(d1), T); check("rint_(o1)", rint_(o1), rint(d1), T); check("tlfloat_sino(o1)", tlfloat_sino(o1), sin(d1), T); check("sin_(o1)", sin_(o1), sin(d1), T); check("tlfloat_coso(o1)", tlfloat_coso(o1), cos(d1), T); check("cos_(o1)", cos_(o1), cos(d1), T); check("tlfloat_tano(o1)", tlfloat_tano(o1), tan(d1), T); check("tan_(o1)", tan_(o1), tan(d1), T); if (trunc(d1*2) != d1*2) { check("tlfloat_sinpio(o1)", tlfloat_sinpio(o1), sin(M_PI*d1), T); check("sinpi_(o1)", sinpi_(o1), sin(M_PI*d1), T); check("tlfloat_cospio(o1)", tlfloat_cospio(o1), cos(M_PI*d1), T); check("cospi_(o1)", cospi_(o1), cos(M_PI*d1), T); check("tlfloat_tanpio(o1)", tlfloat_tanpio(o1), tan(M_PI*d1), T); check("tanpi_(o1)", tanpi_(o1), tan(M_PI*d1), T); } check("tlfloat_asino(o1)", tlfloat_asino(o1), asin(d1), T); check("asin_(o1)", asin_(o1), asin(d1), T); check("tlfloat_acoso(o1)", tlfloat_acoso(o1), acos(d1), T); check("acos_(o1)", acos_(o1), acos(d1), T); check("tlfloat_atano(o1)", tlfloat_atano(o1), atan(d1), T); check("atan_(o1)", atan_(o1), atan(d1), T); check("tlfloat_sinho(o1)", tlfloat_sinho(o1), sinh(d1), T); check("sinh_(o1)", sinh_(o1), sinh(d1), T); check("tlfloat_cosho(o1)", tlfloat_cosho(o1), cosh(d1), T); check("cosh_(o1)", cosh_(o1), cosh(d1), T); check("tlfloat_tanho(o1)", tlfloat_tanho(o1), tanh(d1), T); check("tanh_(o1)", tanh_(o1), tanh(d1), T); check("tlfloat_asinho(o1)", tlfloat_asinho(o1), asinh(d1), T); check("asinh_(o1)", asinh_(o1), asinh(d1), T); check("tlfloat_acosho(o1)", tlfloat_acosho(o1), acosh(d1), T); check("acosh_(o1)", acosh_(o1), acosh(d1), T); check("tlfloat_atanho(o1)", tlfloat_atanho(o1), atanh(d1), T); check("atanh_(o1)", atanh_(o1), atanh(d1), T); check("tlfloat_erfo(o1)", tlfloat_erfo(o1), erf(d1), T); check("erf_(o1)", erf_(o1), erf(d1), T); check("tlfloat_erfco(o1)", tlfloat_erfco(o1), erfc(d1), T); check("erfc_(o1)", erfc_(o1), erfc(d1), T); check("tlfloat_tgammao(o1)", tlfloat_tgammao(o1), tgamma(d1), T); check("tgamma_(o1)", tgamma_(o1), tgamma(d1), T); check("tlfloat_expo(o1)", tlfloat_expo(o1), exp(d1), T); check("exp_(o1)", exp_(o1), exp(d1), T); check("tlfloat_exp2o(o1)", tlfloat_exp2o(o1), exp2(d1), T); check("exp2_(o1)", exp2_(o1), exp2(d1), T); #ifdef _GNU_SOURCE check("tlfloat_exp10o(o1)", tlfloat_exp10o(o1), exp10(d1), T); check("exp10_(o1)", exp10_(o1), exp10(d1), T); #endif check("tlfloat_expm1o(o1)", tlfloat_expm1o(o1), expm1(d1), T); check("expm1_(o1)", expm1_(o1), expm1(d1), T); check("tlfloat_logo(o1)", tlfloat_logo(o1), log(d1), T); check("log_(o1)", log_(o1), log(d1), T); check("tlfloat_log2o(o1)", tlfloat_log2o(o1), log2(d1), T); check("log2_(o1)", log2_(o1), log2(d1), T); check("tlfloat_log10o(o1)", tlfloat_log10o(o1), log10(d1), T); check("log10_(o1)", log10_(o1), log10(d1), T); check("tlfloat_logp1o(o1)", tlfloat_log1po(o1), log1p(d1), T); check("logp1_(o1)", log1p_(o1), log1p(d1), T); check("tlfloat_cbrto(o1)", tlfloat_cbrto(o1), cbrt(d1), T); check("cbrt_(o1)", cbrt_(o1), cbrt(d1), T); check("tlfloat_copysigno(o1, o2)", tlfloat_copysigno(o1, o2), copysign(d1, d2), T); check("copysign_(o1, o2)", copysign_(o1, o2), copysign(d1, d2), T); check("tlfloat_fmaxo(o1, o2)", tlfloat_fmaxo(o1, o2), fmax(d1, d2), T); check("fmax_(o1, o2)", fmax_(o1, o2), fmax(d1, d2), T); check("tlfloat_fmino(o1, o2)", tlfloat_fmino(o1, o2), fmin(d1, d2), T); check("fmin_(o1, o2)", fmin_(o1, o2), fmin(d1, d2), T); check("tlfloat_fdimo(o1, o2)", tlfloat_fdimo(o1, o2), fdim(d1, d2), T); check("fdim_(o1, o2)", fdim_(o1, o2), fdim(d1, d2), T); check("tlfloat_nextaftero(o1, o2)", tlfloat_nextaftero(o1, o2), nextafter(d1, d2), T); check("nextafter_(o1, o2)", nextafter_(o1, o2), nextafter(d1, d2), T); check("tlfloat_hypoto(o1, o2)", tlfloat_hypoto(o1, o2), hypot(d1, d2), T); check("hypot_(o1, o2)", hypot_(o1, o2), hypot(d1, d2), T); check("tlfloat_fmodo(o1, o2)", tlfloat_fmodo(o1, o2), fmod(d1, d2), T); check("fmod_(o1, o2)", fmod_(o1, o2), fmod(d1, d2), T); check("tlfloat_remaindero(o1, o2)", tlfloat_remaindero(o1, o2), remainder(d1, d2), T); check("remainder_(o1, o2)", remainder_(o1, o2), remainder(d1, d2), T); int qt = 0, qc = 0; #ifndef __i386__ check("tlfloat_remquoo(o1, o2, &quo) remainder", tlfloat_remquoo(o1, o2, &qt), remquo(d1, d2, &qc), T); check("remquo_(o1, o2, &quo) remainder", remquo_(o1, o2, &qt), remquo(d1, d2, &qc), T); checkQuo("tlfloat_remquoo(o1, o2, &quo) quo", qt, qc); #endif check_ilogb("tlfloat_ilogbo(o1)", tlfloat_ilogbo(o1), ilogb(d1)); check_ilogb("ilogb_(o1)", ilogb_(o1), ilogb(d1)); check("tlfloat_isnano(o1)", (bool)tlfloat_isnano(o1), (bool)isnan(d1)); check("isnan_(o1)", (bool)isnan_(o1), (bool)isnan(d1)); check("tlfloat_isinfo(o1)", (bool)tlfloat_isinfo(o1), (bool)isinf(d1)); check("isinf_(o1)", (bool)isinf_(o1), (bool)isinf(d1)); check("tlfloat_finiteo(o1)", (bool)tlfloat_finiteo(o1), (bool)finite__(d1)); check("finite_(o1)", (bool)finite_(o1), (bool)finite__(d1)); check("tlfloat_signbito(o1)", (bool)tlfloat_signbito(o1), (bool)signbit(d1)); check("signbit_(o1)", (bool)signbit_(o1), (bool)signbit(d1)); check("tlfloat_ldexpo(o1, i2)", tlfloat_ldexpo(o1, i2), ldexp(d1, i2), T); check("ldexp_(o1, i2)", ldexp_(o1, i2), ldexp(d1, i2), T); check("tlfloat_frexpo(o1, &qt)", tlfloat_frexpo(o1, &qt), frexp(d1, &qc), T); check("frexp_(o1, &qt)", frexp_(o1, &qt), frexp(d1, &qc), T); if (!isnan(d1) && !isinf(d1)) check("exp in tlfloat_frexpo(o1, &qt)", qt, qc); check("tlfloat_powo(o1, o2)", tlfloat_powo(o1, o2), pow(d1, d2), T); check("pow_(o1, o2)", pow_(o1, o2), pow(d1, d2), T); check("tlfloat_atan2o(o1, o2)", tlfloat_atan2o(o1, o2), atan2(d1, d2), T); check("atan2_(o1, o2)", atan2_(o1, o2), atan2(d1, d2), T); check("tlfloat_fmao(o1, o2, o2)", tlfloat_fmao(o1, o2, o2), fma(d1, d2, d2), T); check("fma_(o1, o2, o2)", fma_(o1, o2, o2), fma(d1, d2, d2), T); check("tlfloat_sqrtq(q1)", tlfloat_sqrtq(q1), sqrt(d1), T); check("sqrt_(q1)", sqrt_(q1), sqrt(d1), T); check("tlfloat_fabsq(q1)", tlfloat_fabsq(q1), fabs(d1), T); check("fabs_(q1)", fabs_(q1), fabs(d1), T); check("tlfloat_truncq(q1)", tlfloat_truncq(q1), trunc(d1), T); check("trunc_(q1)", trunc_(q1), trunc(d1), T); check("tlfloat_floorq(q1)", tlfloat_floorq(q1), floor(d1), T); check("floor_(q1)", floor_(q1), floor(d1), T); check("tlfloat_ceilq(q1)", tlfloat_ceilq(q1), ceil(d1), T); check("ceil_(q1)", ceil_(q1), ceil(d1), T); check("tlfloat_roundq(q1)", tlfloat_roundq(q1), round(d1), T); check("round_(q1)", round_(q1), round(d1), T); check("tlfloat_rintq(q1)", tlfloat_rintq(q1), rint(d1), T); check("rint_(q1)", rint_(q1), rint(d1), T); check("tlfloat_sinq(q1)", tlfloat_sinq(q1), sin(d1), T); check("sin_(q1)", sin_(q1), sin(d1), T); check("tlfloat_cosq(q1)", tlfloat_cosq(q1), cos(d1), T); check("cos_(q1)", cos_(q1), cos(d1), T); check("tlfloat_tanq(q1)", tlfloat_tanq(q1), tan(d1), T); check("tan_(q1)", tan_(q1), tan(d1), T); if (trunc(d1*2) != d1*2) { check("tlfloat_sinpiq(q1)", tlfloat_sinpiq(q1), sin(M_PI*d1), T); check("sinpi_(q1)", sinpi_(q1), sin(M_PI*d1), T); check("tlfloat_cospiq(q1)", tlfloat_cospiq(q1), cos(M_PI*d1), T); check("cospi_(q1)", cospi_(q1), cos(M_PI*d1), T); check("tlfloat_tanpiq(q1)", tlfloat_tanpiq(q1), tan(M_PI*d1), T); check("tanpi_(q1)", tanpi_(q1), tan(M_PI*d1), T); } check("tlfloat_asinq(q1)", tlfloat_asinq(q1), asin(d1), T); check("asin_(q1)", asin_(q1), asin(d1), T); check("tlfloat_acosq(q1)", tlfloat_acosq(q1), acos(d1), T); check("acos_(q1)", acos_(q1), acos(d1), T); check("tlfloat_atanq(q1)", tlfloat_atanq(q1), atan(d1), T); check("atan_(q1)", atan_(q1), atan(d1), T); check("tlfloat_sinhq(q1)", tlfloat_sinhq(q1), sinh(d1), T); check("sinh_(q1)", sinh_(q1), sinh(d1), T); check("tlfloat_coshq(q1)", tlfloat_coshq(q1), cosh(d1), T); check("cosh_(q1)", cosh_(q1), cosh(d1), T); check("tlfloat_tanhq(q1)", tlfloat_tanhq(q1), tanh(d1), T); check("tanh_(q1)", tanh_(q1), tanh(d1), T); check("tlfloat_asinhq(q1)", tlfloat_asinhq(q1), asinh(d1), T); check("asinh_(q1)", asinh_(q1), asinh(d1), T); check("tlfloat_acoshq(q1)", tlfloat_acoshq(q1), acosh(d1), T); check("acosh_(q1)", acosh_(q1), acosh(d1), T); check("tlfloat_atanhq(q1)", tlfloat_atanhq(q1), atanh(d1), T); check("atanh_(q1)", atanh_(q1), atanh(d1), T); check("tlfloat_erfq(q1)", tlfloat_erfq(q1), erf(d1), T); check("erf_(q1)", erf_(q1), erf(d1), T); check("tlfloat_erfcq(q1)", tlfloat_erfcq(q1), erfc(d1), T); check("erfc_(q1)", erfc_(q1), erfc(d1), T); check("tlfloat_tgammaq(q1)", tlfloat_tgammaq(q1), tgamma(d1), T); check("tgamma_(q1)", tgamma_(q1), tgamma(d1), T); check("tlfloat_expq(q1)", tlfloat_expq(q1), exp(d1), T); check("exp_(q1)", exp_(q1), exp(d1), T); check("tlfloat_exp2q(q1)", tlfloat_exp2q(q1), exp2(d1), T); check("exp2_(q1)", exp2_(q1), exp2(d1), T); #ifdef _GNU_SOURCE check("tlfloat_exp10q(q1)", tlfloat_exp10q(q1), exp10(d1), T); check("exp10_(q1)", exp10_(q1), exp10(d1), T); #endif check("tlfloat_expm1q(q1)", tlfloat_expm1q(q1), expm1(d1), T); check("expm1_(q1)", expm1_(q1), expm1(d1), T); check("tlfloat_logq(q1)", tlfloat_logq(q1), log(d1), T); check("log_(q1)", log_(q1), log(d1), T); check("tlfloat_log2q(q1)", tlfloat_log2q(q1), log2(d1), T); check("log2_(q1)", log2_(q1), log2(d1), T); check("tlfloat_log10q(q1)", tlfloat_log10q(q1), log10(d1), T); check("log10_(q1)", log10_(q1), log10(d1), T); check("tlfloat_logp1q(q1)", tlfloat_log1pq(q1), log1p(d1), T); check("logp1_(q1)", log1p_(q1), log1p(d1), T); check("tlfloat_cbrtq(q1)", tlfloat_cbrtq(q1), cbrt(d1), T); check("cbrt_(q1)", cbrt_(q1), cbrt(d1), T); check("tlfloat_copysignq(q1, q2)", tlfloat_copysignq(q1, q2), copysign(d1, d2), T); check("copysign_(q1, q2)", copysign_(q1, q2), copysign(d1, d2), T); check("tlfloat_fmaxq(q1, q2)", tlfloat_fmaxq(q1, q2), fmax(d1, d2), T); check("fmax_(q1, q2)", fmax_(q1, q2), fmax(d1, d2), T); check("tlfloat_fminq(q1, q2)", tlfloat_fminq(q1, q2), fmin(d1, d2), T); check("fmin_(q1, q2)", fmin_(q1, q2), fmin(d1, d2), T); check("tlfloat_fdimq(q1, q2)", tlfloat_fdimq(q1, q2), fdim(d1, d2), T); check("fdim_(q1, q2)", fdim_(q1, q2), fdim(d1, d2), T); check("tlfloat_nextafterq(q1, q2)", tlfloat_nextafterq(q1, q2), nextafter(d1, d2), T); check("nextafter_(q1, q2)", nextafter_(q1, q2), nextafter(d1, d2), T); check("tlfloat_hypotq(q1, q2)", tlfloat_hypotq(q1, q2), hypot(d1, d2), T); check("hypot_(q1, q2)", hypot_(q1, q2), hypot(d1, d2), T); check("tlfloat_fmodq(q1, q2)", tlfloat_fmodq(q1, q2), fmod(d1, d2), T); check("fmod_(q1, q2)", fmod_(q1, q2), fmod(d1, d2), T); check("tlfloat_remainderq(q1, q2)", tlfloat_remainderq(q1, q2), remainder(d1, d2), T); check("remainder_(q1, q2)", remainder_(q1, q2), remainder(d1, d2), T); qt = qc = 0; #ifndef __i386__ check("tlfloat_remquoq(q1, q2, &quo) remainder", tlfloat_remquoq(q1, q2, &qt), remquo(d1, d2, &qc), T); check("remquo_(q1, q2, &quo) remainder", remquo_(q1, q2, &qt), remquo(d1, d2, &qc), T); checkQuo("tlfloat_remquoq(q1, q2, &quo) quo", qt, qc); #endif check_ilogb("tlfloat_ilogbq(q1)", tlfloat_ilogbq(q1), ilogb(d1)); check_ilogb("ilogb_(q1)", ilogb_(q1), ilogb(d1)); check("tlfloat_isnanq(q1)", (bool)tlfloat_isnanq(q1), (bool)isnan(d1)); check("isnan_(q1)", (bool)isnan_(q1), (bool)isnan(d1)); check("tlfloat_isinfq(q1)", (bool)tlfloat_isinfq(q1), (bool)isinf(d1)); check("isinf_(q1)", (bool)isinf_(q1), (bool)isinf(d1)); check("tlfloat_finiteq(q1)", (bool)tlfloat_finiteq(q1), (bool)finite__(d1)); check("finite_(q1)", (bool)finite_(q1), (bool)finite__(d1)); check("tlfloat_signbitq(q1)", (bool)tlfloat_signbitq(q1), (bool)signbit(d1)); check("signbit_(q1)", (bool)signbit_(q1), (bool)signbit(d1)); check("tlfloat_ldexpq(q1, i2)", tlfloat_ldexpq(q1, i2), ldexp(d1, i2), T); check("ldexp_(q1, i2)", ldexp_(q1, i2), ldexp(d1, i2), T); check("tlfloat_frexpq(q1, &qt)", tlfloat_frexpq(q1, &qt), frexp(d1, &qc), T); check("frexp_(q1, &qt)", frexp_(q1, &qt), frexp(d1, &qc), T); if (!isnan(d1) && !isinf(d1)) check("exp in tlfloat_frexpq(q1, &qt)", qt, qc); check("tlfloat_powq(q1, q2)", tlfloat_powq(q1, q2), pow(d1, d2), T); check("pow_(q1, q2)", pow_(q1, q2), pow(d1, d2), T); check("tlfloat_atan2q(q1, q2)", tlfloat_atan2q(q1, q2), atan2(d1, d2), T); check("atan2_(q1, q2)", atan2_(q1, q2), atan2(d1, d2), T); check("tlfloat_fmaq(q1, q2, q2)", tlfloat_fmaq(q1, q2, q2), fma(d1, d2, d2), T); check("fma_(q1, q2, q2)", fma_(q1, q2, q2), fma(d1, d2, d2), T); check("sqrtq(q1)", sqrtq(q1), sqrt(d1), T); check("fabsq(q1)", fabsq(q1), fabs(d1), T); check("truncq(q1)", truncq(q1), trunc(d1), T); check("floorq(q1)", floorq(q1), floor(d1), T); check("ceilq(q1)", ceilq(q1), ceil(d1), T); check("roundq(q1)", roundq(q1), round(d1), T); check("rintq(q1)", rintq(q1), rint(d1), T); check("sinq(q1)", sinq(q1), sin(d1), T); check("cosq(q1)", cosq(q1), cos(d1), T); { tlfloat_quad s, c; sincosq(q1, &s, &c); check("sin in sincosq(q1)", s, sin(d1), T); check("cos in sincosq(q1)", c, cos(d1), T); } check("tanq(q1)", tanq(q1), tan(d1), T); check("asinq(q1)", asinq(q1), asin(d1), T); check("acosq(q1)", acosq(q1), acos(d1), T); check("atanq(q1)", atanq(q1), atan(d1), T); check("sinhq(q1)", sinhq(q1), sinh(d1), T); check("coshq(q1)", coshq(q1), cosh(d1), T); check("tanhq(q1)", tanhq(q1), tanh(d1), T); check("asinhq(q1)", asinhq(q1), asinh(d1), T); check("acoshq(q1)", acoshq(q1), acosh(d1), T); check("atanhq(q1)", atanhq(q1), atanh(d1), T); check("erfq(q1)", erfq(q1), erf(d1), T); check("erfcq(q1)", erfcq(q1), erfc(d1), T); check("tgammaq(q1)", tgammaq(q1), tgamma(d1), T); //check("lgammaq(q1)", lgammaq(q1), lgamma(d1), T); check("expq(q1)", expq(q1), exp(d1), T); check("exp2q(q1)", exp2q(q1), exp2(d1), T); #ifdef _GNU_SOURCE check("exp10q(q1)", exp10q(q1), exp10(d1), T); #endif check("expm1q(q1)", expm1q(q1), expm1(d1), T); check("logq(q1)", logq(q1), log(d1), T); check("log2q(q1)", log2q(q1), log2(d1), T); check("log10q(q1)", log10q(q1), log10(d1), T); check("logp1q(q1)", log1pq(q1), log1p(d1), T); check("cbrtq(q1)", cbrtq(q1), cbrt(d1), T); check("copysignq(q1, q2)", copysignq(q1, q2), copysign(d1, d2), T); check("fmaxq(q1, q2)", fmaxq(q1, q2), fmax(d1, d2), T); check("fminq(q1, q2)", fminq(q1, q2), fmin(d1, d2), T); check("fdimq(q1, q2)", fdimq(q1, q2), fdim(d1, d2), T); check("nextafterq(q1, q2)", nextafterq(q1, q2), nextafter(d1, d2), T); check("hypotq(q1, q2)", hypotq(q1, q2), hypot(d1, d2), T); check("fmodq(q1, q2)", fmodq(q1, q2), fmod(d1, d2), T); check("remainderq(q1, q2)", remainderq(q1, q2), remainder(d1, d2), T); qt = qc = 0; #ifndef __i386__ check("remquoq(q1, q2, &quo) remainder", remquoq(q1, q2, &qt), remquo(d1, d2, &qc), T); checkQuo("remquoq(q1, q2, &quo) quo", qt, qc); #endif check_ilogb("ilogbq(q1)", ilogbq(q1), ilogb(d1)); check("isnanq(q1)", (bool)isnanq(q1), (bool)isnan(d1)); check("isinfq(q1)", (bool)isinfq(q1), (bool)isinf(d1)); check("finiteq(q1)", (bool)finiteq(q1), (bool)finite_(d1)); check("signbitq(q1)", (bool)signbitq(q1), (bool)signbit(d1)); check("ldexpq(q1, i2)", ldexpq(q1, i2), ldexp(d1, i2), T); check("powq(q1, q2)", powq(q1, q2), pow(d1, d2), T); check("atan2q(q1, q2)", atan2q(q1, q2), atan2(d1, d2), T); check("fmaq(q1, q2, q2)", fmaq(q1, q2, q2), fma(d1, d2, d2), T); check("+o1 == +o2", +o1 == +o2, +d1 == +d2); check("-o1 == -o2", -o1 == -o2, -d1 == -d2); check("o1 == o2", o1 == o2, d1 == d2); check("o1 != o2", o1 != o2, d1 != d2); check("o1 > o2", o1 > o2, d1 > d2); check("o1 >= o2", o1 >= o2, d1 >= d2); check("o1 < o2", o1 < o2, d1 < d2); check("o1 <= o2", o1 <= o2, d1 <= d2); check("o1 == q2", o1 == q2, d1 == d2); check("o1 != q2", o1 != q2, d1 != d2); check("o1 > q2", o1 > q2, d1 > d2); check("o1 >= q2", o1 >= q2, d1 >= d2); check("o1 < q2", o1 < q2, d1 < d2); check("o1 <= q2", o1 <= q2, d1 <= d2); check("o1 == d2", o1 == d2, d1 == d2); check("o1 != d2", o1 != d2, d1 != d2); check("o1 > d2", o1 > d2, d1 > d2); check("o1 >= d2", o1 >= d2, d1 >= d2); check("o1 < d2", o1 < d2, d1 < d2); check("o1 <= d2", o1 <= d2, d1 <= d2); check("o1 == i2", o1 == i2, d1 == i2); check("o1 != i2", o1 != i2, d1 != i2); check("o1 > i2", o1 > i2, d1 > i2); check("o1 >= i2", o1 >= i2, d1 >= i2); check("o1 < i2", o1 < i2, d1 < i2); check("o1 <= i2", o1 <= i2, d1 <= i2); check("o1 == j2", o1 == j2, d1 == (double)j2); check("o1 != j2", o1 != j2, d1 != (double)j2); check("o1 > j2", o1 > j2, d1 > (double)j2); check("o1 >= j2", o1 >= j2, d1 >= (double)j2); check("o1 < j2", o1 < j2, d1 < (double)j2); check("o1 <= j2", o1 <= j2, d1 <= (double)j2); check("o1 == k2", o1 == k2, d1 == (double)k2); check("o1 != k2", o1 != k2, d1 != (double)k2); check("o1 > k2", o1 > k2, d1 > (double)k2); check("o1 >= k2", o1 >= k2, d1 >= (double)k2); check("o1 < k2", o1 < k2, d1 < (double)k2); check("o1 <= k2", o1 <= k2, d1 <= (double)k2); check("+q1 == +q2", +q1 == +q2, +d1 == +d2); check("-q1 == -q2", -q1 == -q2, -d1 == -d2); check("q1 == o2", q1 == o2, d1 == d2); check("q1 != o2", q1 != o2, d1 != d2); check("q1 > o2", q1 > o2, d1 > d2); check("q1 >= o2", q1 >= o2, d1 >= d2); check("q1 < o2", q1 < o2, d1 < d2); check("q1 <= o2", q1 <= o2, d1 <= d2); check("q1 == q2", q1 == q2, d1 == d2); check("q1 != q2", q1 != q2, d1 != d2); check("q1 > q2", q1 > q2, d1 > d2); check("q1 >= q2", q1 >= q2, d1 >= d2); check("q1 < q2", q1 < q2, d1 < d2); check("q1 <= q2", q1 <= q2, d1 <= d2); check("q1 == d2", q1 == d2, d1 == d2); check("q1 != d2", q1 != d2, d1 != d2); check("q1 > d2", q1 > d2, d1 > d2); check("q1 >= d2", q1 >= d2, d1 >= d2); check("q1 < d2", q1 < d2, d1 < d2); check("q1 <= d2", q1 <= d2, d1 <= d2); check("q1 == i2", q1 == i2, d1 == i2); check("q1 != i2", q1 != i2, d1 != i2); check("q1 > i2", q1 > i2, d1 > i2); check("q1 >= i2", q1 >= i2, d1 >= i2); check("q1 < i2", q1 < i2, d1 < i2); check("q1 <= i2", q1 <= i2, d1 <= i2); check("q1 == j2", q1 == (tlfloat_quad)j2, d1 == (double)j2); check("q1 != j2", q1 != (tlfloat_quad)j2, d1 != (double)j2); check("q1 > j2", q1 > (tlfloat_quad)j2, d1 > (double)j2); check("q1 >= j2", q1 >= (tlfloat_quad)j2, d1 >= (double)j2); check("q1 < j2", q1 < (tlfloat_quad)j2, d1 < (double)j2); check("q1 <= j2", q1 <= (tlfloat_quad)j2, d1 <= (double)j2); check("q1 == k2", q1 == (tlfloat_quad)k2, d1 == (double)k2); check("q1 != k2", q1 != (tlfloat_quad)k2, d1 != (double)k2); check("q1 > k2", q1 > (tlfloat_quad)k2, d1 > (double)k2); check("q1 >= k2", q1 >= (tlfloat_quad)k2, d1 >= (double)k2); check("q1 < k2", q1 < (tlfloat_quad)k2, d1 < (double)k2); check("q1 <= k2", q1 <= (tlfloat_quad)k2, d1 <= (double)k2); #if __cplusplus >= 202002L o1 = (tlfloat_octuple)tlfloat::Octuple(s1.c_str()); check("cast Octuple -> tlfloat_octuple", o1, d1); check("cast tlfloat_octuple -> Octuple", isnan(tlfloat::Octuple(o1)) || tlfloat::Octuple(o1) == tlfloat::Octuple(s1.c_str()), true); q1 = (tlfloat_quad)tlfloat::Quad(s1.c_str()); check("cast Quad -> tlfloat_quad", q1, d1); check("cast tlfloat_quad -> Quad", isnan(tlfloat::Quad(q1)) || tlfloat::Quad(q1) == tlfloat::Quad(s1.c_str()), true); #endif } tlfloat_octuple AGMo(int N) { tlfloat_octuple y = tlfloat_sqrto(2.0) - 1; tlfloat_octuple a = tlfloat_ldexpo(y * y, 1); for(int k=0;k #include #include #include #include "tlfloat/tlmath.hpp" #include "testerutil.hpp" using namespace std; using namespace tlfloat; int cudaMultiProcessorCount = -1; int N = 0, blockSize = 0; int nLoop = 1 << 4, nThread = 1 << 8, nBlock = 0; #define cudaErrorCheck(ans) { gpuAssert((ans), __FILE__, __LINE__); } inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true) { if (code != cudaSuccess) { fprintf(stderr,"%s(%d) : GPUassert: %s\n", file, line, cudaGetErrorString(code)); if (abort) exit(code); } } int64_t getTime() { return chrono::duration_cast (chrono::high_resolution_clock::now() - chrono::system_clock::from_time_t(0)).count(); } template T rnd(shared_ptr rng) { for(;;) { T f; rng->nextBytes((unsigned char *)&f, sizeof(f)); f = frexp(f, nullptr); if (finite(f)) return f; } } void *cudaMallocManaged_(size_t size) { void *ptr; cudaErrorCheck( cudaMallocManaged(&ptr, size) ); return ptr; } // template using Func1 = T (*)(const T&); template func> __global__ void kern(int n, T *r, T *x) { int index = threadIdx.x, stride = blockDim.x; for (int i = index; i < n; i += stride) r[i] = func(x[i]); } template func> void doTest(const char *mes, T *r, T *x) { auto t0 = getTime(); kern<<>>(N, r, x); cudaErrorCheck( cudaPeekAtLastError() ); cudaErrorCheck( cudaDeviceSynchronize() ); auto t1 = getTime(); for (int i = 0; i < N; i++) { if (r[i].m == func(x[i]).m) continue; cout << mes << " : NG" << endl; cout << "arg1 : " << to_string(x[i], 75) << endl; cout << "device : " << to_string(r[i], 75) << endl; cout << "host : " << to_string(func(x[i]), 75) << endl; exit(-1); } auto t2 = getTime(); cout << mes << " : OK (D:" << (t1 - t0)/1000.0 << "ms, H:" << (t2 - t1)/1000.0 << "ms)" << endl; } // template using Func2 = T (*)(const T&, const T&); template func> __global__ void kern(int n, T *r, T *x, T *y) { int index = threadIdx.x, stride = blockDim.x; for (int i = index; i < n; i += stride) r[i] = func(x[i], y[i]); } template func> void doTest(const char *mes, T *r, T *x, T *y) { auto t0 = getTime(); kern<<>>(N, r, x, y); cudaErrorCheck( cudaPeekAtLastError() ); cudaErrorCheck( cudaDeviceSynchronize() ); auto t1 = getTime(); for (int i = 0; i < N; i++) { if (r[i].m == func(x[i], y[i]).m) continue; cout << mes << " : NG" << endl; cout << "arg1 : " << to_string(x[i], 75) << endl; cout << "arg2 : " << to_string(y[i], 75) << endl; cout << "device : " << to_string(r[i], 75) << endl; cout << "host : " << to_string(func(x[i], y[i]), 75) << endl; exit(-1); } auto t2 = getTime(); cout << mes << " : OK (D:" << (t1 - t0)/1000.0 << "ms, H:" << (t2 - t1)/1000.0 << "ms)" << endl; } // template using Func2i = xpair (*)(const T&, const T&); template func> __global__ void kern(int n, T *r, int64_t *ri, T *x, T *y) { int index = threadIdx.x, stride = blockDim.x; for (int i = index; i < n; i += stride) { xpair p = func(x[i], y[i]); r[i] = p.first; ri[i] = p.second; } } template func> void doTest(const char *mes, T *r, int64_t *ri, T *x, T *y) { auto t0 = getTime(); kern<<>>(N, r, ri, x, y); cudaErrorCheck( cudaPeekAtLastError() ); cudaErrorCheck( cudaDeviceSynchronize() ); auto t1 = getTime(); for (int i = 0; i < N; i++) { auto p = func(x[i], y[i]); if (r[i].m == p.first.m && ri[i] == p.second) continue; cout << mes << " : NG" << endl; cout << "arg1 : " << to_string(x[i], 75) << endl; cout << "device : " << to_string(r[i], 75) << ", " << ri[i] << endl; cout << "host : " << to_string(p.first, 75) << p.second << endl; exit(-1); } auto t2 = getTime(); cout << mes << " : OK (D:" << (t1 - t0)/1000.0 << "ms, H:" << (t2 - t1)/1000.0 << "ms)" << endl; } // template using Func3 = T (*)(const T&, const T&, const T&); template func> __global__ void kern(int n, T *r, T *x, T *y, T *z) { int index = threadIdx.x, stride = blockDim.x; for (int i = index; i < n; i += stride) r[i] = func(x[i], y[i], z[i]); } template func> void doTest(const char *mes, T *r, T *x, T *y, T *z) { auto t0 = getTime(); kern<<>>(N, r, x, y, z); cudaErrorCheck( cudaPeekAtLastError() ); cudaErrorCheck( cudaDeviceSynchronize() ); auto t1 = getTime(); for (int i = 0; i < N; i++) { if (r[i].m == func(x[i], y[i], z[i]).m) continue; cout << mes << " : NG" << endl; cout << "arg1 : " << to_string(x[i], 75) << endl; cout << "arg2 : " << to_string(y[i], 75) << endl; cout << "arg3 : " << to_string(z[i], 75) << endl; cout << "device : " << to_string(r[i], 75) << endl; cout << "host : " << to_string(func(x[i], y[i], z[i]), 75) << endl; exit(-1); } auto t2 = getTime(); cout << mes << " : OK (D:" << (t1 - t0)/1000.0 << "ms, H:" << (t2 - t1)/1000.0 << "ms)" << endl; } // template static constexpr T fabs_(const T &a1) { return fabs(a1); } template static constexpr T copysign_(const T &a1, const T &a2) { return copysign(a1, a2); } template static constexpr T fmax_(const T &a1, const T &a2) { return fmax(a1, a2); } template static constexpr T fmin_(const T &a1, const T &a2) { return fmin(a1, a2); } template static constexpr T fdim_(const T &a1, const T &a2) { return fdim(a1, a2); } template static constexpr T add_(const T &a1, const T &a2) { return a1 + a2; } template static constexpr T mul_(const T &a1, const T &a2) { return a1 * a2; } template static constexpr T div_(const T &a1, const T &a2) { return a1 / a2; } template static constexpr T fma_(const T &a1, const T &a2, const T &a3) { return fma(a1, a2, a3); } template static constexpr T sqrt_(const T &a) { return sqrt(a); } template static constexpr T hypot_(const T &a1, const T &a2) { return hypot(a1, a2); } template static constexpr T trunc_(const T &a) { return trunc(a); } template static constexpr T floor_(const T &a) { return floor(a); } template static constexpr T ceil_(const T &a) { return ceil(a); } template static constexpr T round_(const T &a) { return round(a); } template static constexpr T rint_(const T &a) { return rint(a); } template static constexpr T nextafter_(const T &a1, const T &a2) { return nextafter(a1, a2); } template static constexpr T lgamma_(const T &a1) { return lgamma(a1, nullptr); } int main(int argc, char **argv) { { int device; cudaErrorCheck(cudaGetDevice(&device)); cudaDeviceProp devProp; cudaErrorCheck(cudaGetDeviceProperties(&devProp, device)); cudaMultiProcessorCount = devProp.multiProcessorCount; nBlock = devProp.multiProcessorCount; } if (argc >= 2) nThread = atoi(argv[1]); if (argc >= 3) nLoop = atoi(argv[2]); N = nLoop * nThread * nBlock; cout << "N = " << N << ", nLoop = " << nLoop << ", nBlock = " << nBlock << ", nThread = " << nThread << endl; auto rng = createPreferredRNG(); Octuple *xo = (Octuple *)cudaMallocManaged_(N*sizeof(Octuple)); Octuple *yo = (Octuple *)cudaMallocManaged_(N*sizeof(Octuple)); Octuple *zo = (Octuple *)cudaMallocManaged_(N*sizeof(Octuple)); Octuple *ro = (Octuple *)cudaMallocManaged_(N*sizeof(Octuple)); Quad *xq = (Quad *)cudaMallocManaged_(N*sizeof(Quad)); Quad *yq = (Quad *)cudaMallocManaged_(N*sizeof(Quad)); Quad *zq = (Quad *)cudaMallocManaged_(N*sizeof(Quad)); Quad *rq = (Quad *)cudaMallocManaged_(N*sizeof(Quad)); Double *xd = (Double *)cudaMallocManaged_(N*sizeof(Double)); Double *yd = (Double *)cudaMallocManaged_(N*sizeof(Double)); Double *zd = (Double *)cudaMallocManaged_(N*sizeof(Double)); Double *rd = (Double *)cudaMallocManaged_(N*sizeof(Double)); Float *xf = (Float *)cudaMallocManaged_(N*sizeof(Float)); Float *yf = (Float *)cudaMallocManaged_(N*sizeof(Float)); Float *zf = (Float *)cudaMallocManaged_(N*sizeof(Float)); Float *rf = (Float *)cudaMallocManaged_(N*sizeof(Float)); Half *xh = (Half *)cudaMallocManaged_(N*sizeof(Half)); Half *yh = (Half *)cudaMallocManaged_(N*sizeof(Half)); Half *zh = (Half *)cudaMallocManaged_(N*sizeof(Half)); Half *rh = (Half *)cudaMallocManaged_(N*sizeof(Half)); int64_t *ri = (int64_t *)cudaMallocManaged_(N*sizeof(int64_t)); { vector v; v = genTestValues(N, rng); for(int i=0;i(N, rng); for(int i=0;i(N, rng); for(int i=0;i v; v = genTestValues(N, rng); for(int i=0;i(N, rng); for(int i=0;i(N, rng); for(int i=0;i v; v = genTestValues(N, rng); for(int i=0;i(N, rng); for(int i=0;i(N, rng); for(int i=0;i v; v = genTestValues(N, rng); for(int i=0;i(N, rng); for(int i=0;i(N, rng); for(int i=0;i v; v = genTestValues(N, rng); for(int i=0;i(N, rng); for(int i=0;i(N, rng); for(int i=0;i("Octuple fabs", ro, xo); doTest("Quad fabs", rq, xq); doTest("Double fabs", rd, xd); doTest("Float fabs", rf, xf); doTest("Half fabs", rh, xh); doTest("Octuple copysign", ro, xo, yo); doTest("Quad copysign", rq, xq, yq); doTest("Double copysign", rd, xd, yd); doTest("Float copysign", rf, xf, yf); doTest("Half copysign", rh, xh, yh); doTest("Octuple fmax", ro, xo, yo); doTest("Quad fmax", rq, xq, yq); doTest("Double fmax", rd, xd, yd); doTest("Float fmax", rf, xf, yf); doTest("Half fmax", rh, xh, yh); doTest("Octuple fmin", ro, xo, yo); doTest("Quad fmin", rq, xq, yq); doTest("Double fmin", rd, xd, yd); doTest("Float fmin", rf, xf, yf); doTest("Half fmin", rh, xh, yh); doTest("Octuple fdim", ro, xo, yo); doTest("Quad fdim", rq, xq, yq); doTest("Double fdim", rd, xd, yd); doTest("Float fdim", rf, xf, yf); doTest("Half fdim", rh, xh, yh); doTest("Octuple add_", ro, xo, yo); doTest("Quad add_", rq, xq, yq); doTest("Double add_", rd, xd, yd); doTest("Float add_", rf, xf, yf); doTest("Half add_", rh, xh, yh); doTest("Octuple mul_", ro, xo, yo); doTest("Quad mul_", rq, xq, yq); doTest("Double mul_", rd, xd, yd); doTest("Float mul_", rf, xf, yf); doTest("Half mul_", rh, xh, yh); doTest("Octuple div_", ro, xo, yo); doTest("Quad div_", rq, xq, yq); doTest("Double div_", rd, xd, yd); doTest("Float div_", rf, xf, yf); doTest("Half div_", rh, xh, yh); doTest("Octuple fma", ro, xo, yo, zo); doTest("Quad fma", rq, xq, yq, zq); doTest("Double fma", rd, xd, yd, zd); doTest("Float fma", rf, xf, yf, zf); doTest("Half fma", rh, xh, yh, zh); doTest("Octuple sqrt", ro, xo); doTest("Quad sqrt", rq, xq); doTest("Double sqrt", rd, xd); doTest("Float sqrt", rf, xf); doTest("Half sqrt", rh, xh); doTest("Octuple hypot", ro, xo, yo); doTest("Quad hypot", rq, xq, yq); doTest("Double hypot", rd, xd, yd); doTest("Float hypot", rf, xf, yf); doTest("Half hypot", rh, xh, yh); doTest("Octuple trunc", ro, xo); doTest("Quad trunc", rq, xq); doTest("Double trunc", rd, xd); doTest("Float trunc", rf, xf); doTest("Half trunc", rh, xh); doTest("Octuple floor", ro, xo); doTest("Quad floor", rq, xq); doTest("Double floor", rd, xd); doTest("Float floor", rf, xf); doTest("Half floor", rh, xh); doTest("Octuple ceil", ro, xo); doTest("Quad ceil", rq, xq); doTest("Double ceil", rd, xd); doTest("Float ceil", rf, xf); doTest("Half ceil", rh, xh); doTest("Octuple round", ro, xo); doTest("Quad round", rq, xq); doTest("Double round", rd, xd); doTest("Float round", rf, xf); doTest("Half round", rh, xh); doTest("Octuple rint", ro, xo); doTest("Quad rint", rq, xq); doTest("Double rint", rd, xd); doTest("Float rint", rf, xf); doTest("Half rint", rh, xh); doTest("Octuple nextafter", ro, xo, yo); doTest("Quad nextafter", rq, xq, yq); doTest("Double nextafter", rd, xd, yd); doTest("Float nextafter", rf, xf, yf); doTest("Half nextafter", rh, xh, yh); doTest("Octuple sin", ro, xo); doTest("Quad sin", rq, xq); doTest("Double sin", rd, xd); doTest("Float sin", rf, xf); doTest("Half sin", rh, xh); doTest("Octuple cos", ro, xo); doTest("Quad cos", rq, xq); doTest("Double cos", rd, xd); doTest("Float cos", rf, xf); doTest("Half cos", rh, xh); doTest("Octuple tan", ro, xo); doTest("Quad tan", rq, xq); doTest("Double tan", rd, xd); doTest("Float tan", rf, xf); doTest("Half tan", rh, xh); doTest("Octuple sinpi", ro, xo); doTest("Quad sinpi", rq, xq); doTest("Double sinpi", rd, xd); doTest("Float sinpi", rf, xf); doTest("Half sinpi", rh, xh); doTest("Octuple cospi", ro, xo); doTest("Quad cospi", rq, xq); doTest("Double cospi", rd, xd); doTest("Float cospi", rf, xf); doTest("Half cospi", rh, xh); doTest("Octuple tanpi", ro, xo); doTest("Quad tanpi", rq, xq); doTest("Double tanpi", rd, xd); doTest("Float tanpi", rf, xf); doTest("Half tanpi", rh, xh); doTest("Octuple atan2", ro, xo, yo); doTest("Quad atan2", rq, xq, yq); doTest("Double atan2", rd, xd, yd); doTest("Float atan2", rf, xf, yf); doTest("Half atan2", rh, xh, yh); doTest("Octuple asin", ro, xo); doTest("Quad asin", rq, xq); doTest("Double asin", rd, xd); doTest("Float asin", rf, xf); doTest("Half asin", rh, xh); doTest("Octuple acos", ro, xo); doTest("Quad acos", rq, xq); doTest("Double acos", rd, xd); doTest("Float acos", rf, xf); doTest("Half acos", rh, xh); doTest("Octuple atan", ro, xo); doTest("Quad atan", rq, xq); doTest("Double atan", rd, xd); doTest("Float atan", rf, xf); doTest("Half atan", rh, xh); doTest("Octuple log", ro, xo); doTest("Quad log", rq, xq); doTest("Double log", rd, xd); doTest("Float log", rf, xf); doTest("Half log", rh, xh); doTest("Octuple log2", ro, xo); doTest("Quad log2", rq, xq); doTest("Double log2", rd, xd); doTest("Float log2", rf, xf); doTest("Half log2", rh, xh); doTest("Octuple log10", ro, xo); doTest("Quad log10", rq, xq); doTest("Double log10", rd, xd); doTest("Float log10", rf, xf); doTest("Half log10", rh, xh); doTest("Octuple log1p", ro, xo); doTest("Quad log1p", rq, xq); doTest("Double log1p", rd, xd); doTest("Float log1p", rf, xf); doTest("Half log1p", rh, xh); doTest("Octuple exp", ro, xo); doTest("Quad exp", rq, xq); doTest("Double exp", rd, xd); doTest("Float exp", rf, xf); doTest("Half exp", rh, xh); doTest("Octuple exp2", ro, xo); doTest("Quad exp2", rq, xq); doTest("Double exp2", rd, xd); doTest("Float exp2", rf, xf); doTest("Half exp2", rh, xh); doTest("Octuple exp10", ro, xo); doTest("Quad exp10", rq, xq); doTest("Double exp10", rd, xd); doTest("Float exp10", rf, xf); doTest("Half exp10", rh, xh); doTest("Octuple expm1", ro, xo); doTest("Quad expm1", rq, xq); doTest("Double expm1", rd, xd); doTest("Float expm1", rf, xf); doTest("Half expm1", rh, xh); doTest("Octuple pow", ro, xo, yo); doTest("Quad pow", rq, xq, yq); doTest("Double pow", rd, xd, yd); doTest("Float pow", rf, xf, yf); doTest("Half pow", rh, xh, yh); doTest("Octuple cbrt", ro, xo); doTest("Quad cbrt", rq, xq); doTest("Double cbrt", rd, xd); doTest("Float cbrt", rf, xf); doTest("Half cbrt", rh, xh); doTest("Octuple sinh", ro, xo); doTest("Quad sinh", rq, xq); doTest("Double sinh", rd, xd); doTest("Float sinh", rf, xf); doTest("Half sinh", rh, xh); doTest("Octuple cosh", ro, xo); doTest("Quad cosh", rq, xq); doTest("Double cosh", rd, xd); doTest("Float cosh", rf, xf); doTest("Half cosh", rh, xh); doTest("Octuple tanh", ro, xo); doTest("Quad tanh", rq, xq); doTest("Double tanh", rd, xd); doTest("Float tanh", rf, xf); doTest("Half tanh", rh, xh); doTest("Octuple asinh", ro, xo); doTest("Quad asinh", rq, xq); doTest("Double asinh", rd, xd); doTest("Float asinh", rf, xf); doTest("Half asinh", rh, xh); doTest("Octuple acosh", ro, xo); doTest("Quad acosh", rq, xq); doTest("Double acosh", rd, xd); doTest("Float acosh", rf, xf); doTest("Half acosh", rh, xh); doTest("Octuple atanh", ro, xo); doTest("Quad atanh", rq, xq); doTest("Double atanh", rd, xd); doTest("Float atanh", rf, xf); doTest("Half atanh", rh, xh); doTest("Octuple erf", ro, xo); doTest("Quad erf", rq, xq); doTest("Double erf", rd, xd); doTest("Float erf", rf, xf); doTest("Half erf", rh, xh); doTest("Octuple erfc", ro, xo); doTest("Quad erfc", rq, xq); doTest("Double erfc", rd, xd); doTest("Float erfc", rf, xf); doTest("Half erfc", rh, xh); doTest("Octuple tgamma", ro, xo); doTest("Quad tgamma", rq, xq); doTest("Double tgamma", rd, xd); doTest("Float tgamma", rf, xf); doTest("Half tgamma", rh, xh); doTest("Octuple lgamma", ro, xo); doTest("Quad lgamma", rq, xq); doTest("Double lgamma", rd, xd); doTest("Float lgamma", rf, xf); doTest("Half lgamma", rh, xh); doTest("Octuple fmod", ro, xo, yo); doTest("Quad fmod", rq, xq, yq); doTest("Double fmod", rd, xd, yd); doTest("Float fmod", rf, xf, yf); doTest("Half fmod", rh, xh, yh); doTest("Octuple remainder", ro, xo, yo); doTest("Quad remainder", rq, xq, yq); doTest("Double remainder", rd, xd, yd); doTest("Float remainder", rf, xf, yf); doTest("Half remainder", rh, xh, yh); doTest("Octuple remquo", ro, ri, xo, yo); doTest("Quad remquo", rq, ri, xq, yq); doTest("Double remquo", rd, ri, xd, yd); doTest("Float remquo", rf, ri, xf, yf); doTest("Half remquo", rh, ri, xh, yh); cudaFree(ri); cudaFree(rh); cudaFree(zh); cudaFree(yh); cudaFree(xh); cudaFree(rf); cudaFree(zf); cudaFree(yf); cudaFree(xf); cudaFree(rd); cudaFree(zd); cudaFree(yd); cudaFree(xd); cudaFree(rq); cudaFree(zq); cudaFree(yq); cudaFree(xq); cudaFree(ro); cudaFree(zo); cudaFree(yo); cudaFree(xo); return 0; } tlfloat-1.15.0/src/tester/test_exhaustive16.cpp000066400000000000000000000725671477036600700214720ustar00rootroot00000000000000#include #include #include #include #include #if defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) #define MPFR_WANT_FLOAT128 #endif #include #include "suppress.hpp" #include "tlfloat/tlmath.hpp" #include "testerutil.hpp" using namespace std; using namespace tlfloat; using namespace tlfloat::detail; #define TEST_SQRT #define TEST_TRIG #define TEST_ROUND #define TEST_ARITH #define TEST_COMPARE #define TEST_INVTRIG #define TEST_EXP #define TEST_LOG #define TEST_FMA #define TEST_POW #define TEST_CBRT #define TEST_HYP #define TEST_ERF #define TEST_GAMMA #define TEST_MODREM static void sighandler(int signum) { cerr << "Caught SIGILL" << endl; exit(0); } int main(int argc, char **argv) { signal(SIGILL, sighandler); typedef UnpackedFloat uhalf; typedef TLFloat Half; atomic_int progress; #pragma omp parallel for for(uint32_t u32=0;u32 < 0x10000;u32++) { if ((u32 & 0xff) == 0xff) { progress++; int k = progress; printf(" %d / 256\r", k); fflush(stdout); } uint16_t u = ((u32 << 8) | (u32 >> 8)) & 0xffff; __fp16 fu; memcpy((void *)&fu, (void *)&u, sizeof(fu)); #ifdef TEST_SQRT { __fp16 fw = vsqrth_f16(fu); __fp16 fx = __fp16(sqrt(Half(fu))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("sqrt u = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "c: " << fw << " : " << to_string_d(uhalf(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(uhalf(fx)) << endl; exit(-1); } } #endif { mpfr_set_default_prec(32); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); Half x = Half(fu); #ifdef TEST_TRIG { Half r = sin(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_sin(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf sin\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = cos(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_cos(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf cos\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = tan(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_tan(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf tan\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #ifdef TLFLOAT_ENABLE_MPFR_SINPI { Half r = sinpi(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_sinpi(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf sinpi\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = cospi(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_cospi(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf cospi\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = tanpi(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_tanpi(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf tanpi\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #endif #ifdef TEST_INVTRIG { Half r = asin(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_asin(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf asin\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = acos(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_acos(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf acos\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = atan(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_atan(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf atan\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_EXP { Half r = exp(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_exp(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf exp\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = expm1(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_expm1(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf expm1\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = exp2(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_exp2(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf exp2\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = exp10(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_exp10(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf exp10\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_LOG { Half r = log(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_log(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf log\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = log1p(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_log1p(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf log1p\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = log2(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_log2(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf log2\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = log10(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_log10(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf log10\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_CBRT { Half r = cbrt(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_cbrt(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf cbrt\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_HYP { Half r = sinh(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_sinh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf sinh\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = cosh(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_cosh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf cosh\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = tanh(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_tanh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf tanh\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = asinh(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_asinh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf asinh\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = acosh(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_acosh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf acosh\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = atanh(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_atanh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf atanh\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_ERF { Half r = erf(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_erf(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf erf\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = erfc(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_erfc(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf erfc\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_GAMMA { Half r = tgamma(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_gamma(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf tgamma\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Half r = lgamma(x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); int msign = 0; mpfr_lgamma(mx, &msign, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf lgamma\n"); cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif mpfr_clears(mx, my, mz, NULL); } #ifdef TEST_ROUND { __fp16 fw = vrndh_f16(fu); __fp16 fx = __fp16(trunc(uhalf(fu))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("trunc u = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "c: " << fw << " : " << to_string_d(uhalf(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(uhalf(fx)) << endl; exit(-1); } } { __fp16 fw = vrndmh_f16(fu); __fp16 fx = __fp16(floor(uhalf(fu))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("floor u = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "c: " << fw << " : " << to_string_d(uhalf(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(uhalf(fx)) << endl; exit(-1); } } { __fp16 fw = vrndph_f16(fu); __fp16 fx = __fp16(ceil(uhalf(fu))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("ceil u = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "c: " << fw << " : " << to_string_d(uhalf(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(uhalf(fx)) << endl; exit(-1); } } { __fp16 fw = vrndah_f16(fu); __fp16 fx = __fp16(round(uhalf(fu))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("round u = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "c: " << fw << " : " << to_string_d(uhalf(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(uhalf(fx)) << endl; exit(-1); } } { __fp16 fw = vrndnh_f16(fu); __fp16 fx = __fp16(rint(uhalf(fu))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("rint u = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "c: " << fw << " : " << to_string_d(uhalf(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(uhalf(fx)) << endl; exit(-1); } } #endif for(uint32_t v32=0;v32 < 0x10000;v32++) { uint16_t v = ((v32 << 8) | (v32 >> 8)) & 0xffff; __fp16 fv; memcpy((void *)&fv, (void *)&v, sizeof(fv)); #ifdef TEST_ARITH { __fp16 fw = vaddh_f16(fu, fv); __fp16 fx = __fp16(uhalf::faddsub(uhalf(fu), uhalf(fv), false)); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("u = %04x, v = %04x, w = %04x, x = %04x\n", (unsigned)u, (unsigned)v, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "v: " << fv << " : " << to_string_d(uhalf(fv)) << endl; cout << "c: " << fw << " : " << to_string_d(uhalf(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(uhalf(fx)) << endl; exit(-1); } } { __fp16 fw = vsubh_f16(fu, fv); __fp16 fx = __fp16(uhalf::faddsub(uhalf(fu), uhalf(fv), true)); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("u = %04x, v = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)v, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "v: " << fv << " : " << to_string_d(uhalf(fv)) << endl; cout << "c: " << fw << " : " << to_string_d(uhalf(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(uhalf(fx)) << endl; exit(-1); } } { __fp16 fw = vmulh_f16(fu, fv); __fp16 fx = __fp16(uhalf::fmul(uhalf(fu), uhalf(fv))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("u = %04x, v = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)v, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "v: " << fv << " : " << to_string_d(uhalf(fv)) << endl; cout << "c: " << fw << " : " << to_string_d(uhalf(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(uhalf(fx)) << endl; exit(-1); } } { __fp16 fw = vdivh_f16(fu, fv); __fp16 fx = __fp16(uhalf::fdiv(uhalf(fu), uhalf(fv))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("u = %04x, v = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)v, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "v: " << fv << " : " << to_string_d(uhalf(fv)) << endl; cout << "c: " << fw << " : " << to_string_d(uhalf(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(uhalf(fx)) << endl; exit(-1); } } #endif #ifdef TEST_COMPARE { bool bc = vceqh_f16(fu, fv); bool bt = uhalf(fu) == uhalf(fv); if (bc != bt) { printf("== : u = %04x, v = %04x, bc = %d, bt = %d\n", (unsigned)u, (unsigned)v, (int)bc, (int)bt); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "v: " << fv << " : " << to_string_d(uhalf(fv)) << endl; exit(-1); } } { bool bc = vcleh_f16(fu, fv); bool bt = uhalf(fu) <= uhalf(fv); if (bc != bt) { printf("<= : u = %04x, v = %04x, bc = %d, bt = %d\n", (unsigned)u, (unsigned)v, (int)bc, (int)bt); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "v: " << fv << " : " << to_string_d(uhalf(fv)) << endl; exit(-1); } } { bool bc = vcgeh_f16(fu, fv); bool bt = uhalf(fu) >= uhalf(fv); if (bc != bt) { printf(">= : u = %04x, v = %04x, bc = %d, bt = %d\n", (unsigned)u, (unsigned)v, (int)bc, (int)bt); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "v: " << fv << " : " << to_string_d(uhalf(fv)) << endl; exit(-1); } } { bool bc = vclth_f16(fu, fv); bool bt = uhalf(fu) < uhalf(fv); if (bc != bt) { printf("< : u = %04x, v = %04x, bc = %d, bt = %d\n", (unsigned)u, (unsigned)v, (int)bc, (int)bt); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "v: " << fv << " : " << to_string_d(uhalf(fv)) << endl; exit(-1); } } { bool bc = vcgth_f16(fu, fv); bool bt = uhalf(fu) > uhalf(fv); if (bc != bt) { printf("> : u = %04x, v = %04x, bc = %d, bt = %d\n", (unsigned)u, (unsigned)v, (int)bc, (int)bt); cout << "u: " << fu << " : " << to_string_d(uhalf(fu)) << endl; cout << "v: " << fv << " : " << to_string_d(uhalf(fv)) << endl; exit(-1); } } #endif #ifdef TEST_INVTRIG { mpfr_set_default_prec(32); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); Half x = Half(fu); Half y = Half(fv); { Half r = atan2(y, x); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_atan2(mx, my, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf atan2\n"); cout << "y = " << (__fp16)y << endl; cout << "x = " << (__fp16)x << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } mpfr_clears(mx, my, mz, NULL); } #endif #ifdef TEST_POW { mpfr_set_default_prec(32); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); Half x = Half(fu); Half y = Half(fv); { Half r = pow(x, y); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_pow(mx, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.7) { printf("\nhalf pow\n"); cout << "x = " << (__fp16)x << endl; cout << "y = " << (__fp16)y << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } mpfr_clears(mx, my, mz, NULL); } #endif #ifdef TEST_MODREM { mpfr_set_default_prec(32); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); Half x = Half(fu); Half y = Half(fv); { Half r = fmod(x, y); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_fmod(mx, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.5) { printf("\nhalf fmod\n"); cout << "x = " << (__fp16)x << endl; cout << "y = " << (__fp16)y << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } mpfr_clears(mx, my, mz, NULL); } { mpfr_set_default_prec(32); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); Half x = Half(fu); Half y = Half(fv); { Half r = remainder(x, y); uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_remainder(mx, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.5) { printf("\nhalf remainder\n"); cout << "x = " << (__fp16)x << endl; cout << "y = " << (__fp16)y << endl; cout << "c = " << c << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } mpfr_clears(mx, my, mz, NULL); } { mpfr_set_default_prec(32); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); Half x = Half(fu); Half y = Half(fv); { auto p = remquo(x, y); Half r = p.first; uhalf xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); long int mq = 0; mpfr_remquo(mx, &mq, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, uhalf::flt_true_min(), uhalf::flt_max()); if (ulp > 0.5 || mq != p.second) { printf("\nhalf remquo\n"); cout << "x = " << (__fp16)x << endl; cout << "y = " << (__fp16)y << endl; cout << "c = " << c << ", " << mq << endl; cout << "r = " << (__fp16)r << " : " << to_string_d(Half(r).getUnpacked()) << ", " << p.second << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } mpfr_clears(mx, my, mz, NULL); } #endif #ifdef TEST_FMA __fp16 fz[] = { 6e-8, -12e-8, 18e-8, -24e-8, 30e-8, -36e-8, 1e-5, -1e-4, 1e-3, -1e-2, 65504, -32768, +0.0, -0.0, (__fp16)+INFINITY, (__fp16)-INFINITY }; for(unsigned i=0;i #include #include #include #if defined(TLFLOAT_ENABLE_LIBQUADMATH) #include #endif #if defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) #define MPFR_WANT_FLOAT128 #endif #include #include "suppress.hpp" #include "tlfloat/tlmath.hpp" #include "testerutil.hpp" using namespace std; using namespace tlfloat; using namespace tlfloat::detail; typedef UnpackedFloat ufloat; typedef UnpackedFloat uhalf; typedef UnpackedFloat ubf16; #define TEST_CAST #define TEST_SQRT #define TEST_TRIG #define TEST_INVTRIG #define TEST_EXP #define TEST_LOG #define TEST_CBRT #define TEST_HYP #define TEST_ERF #define TEST_GAMMA int main(int argc, char **argv) { double maxulp_sqrt_ = 0, maxulp_sqrt = 0.5; double maxulp_sin = 0.5, maxulp_cos = 0.5, maxulp_tan = 0.5; double maxulp_sinpi = 0.5, maxulp_cospi = 0.5, maxulp_tanpi = 0.5; double maxulp_asin = 0.5, maxulp_acos = 0.5, maxulp_atan = 0.5; double maxulp_exp = 0.5, maxulp_expm1 = 0.5; double maxulp_exp2 = 0.5, maxulp_exp10 = 0.5; double maxulp_log = 0.5, maxulp_log1p = 0.5; double maxulp_log2 = 0.5, maxulp_log10 = 0.5; double maxulp_cbrt = 0.5; double maxulp_sinh = 0.5, maxulp_cosh = 0.5, maxulp_tanh = 0.5; double maxulp_asinh = 0.5, maxulp_acosh = 0.5, maxulp_atanh = 0.5; double maxulp_erf = 0.5, maxulp_erfc = 0.5; double maxulp_tgamma = 0.5, maxulp_lgamma = 0.5; atomic_int progress; #pragma omp parallel for for(uint64_t u64=0;u64 < 0x100000000ULL;u64++) { if ((u64 & 0xfffff) == 0xfffff) { progress++; int k = progress; printf("%5d / 4096\r", k); fflush(stdout); } uint32_t u = ((u64 << 16) | (u64 >> 16)) & 0xffffffff; float x; memcpy((void *)&x, (void *)&u, sizeof(x)); #ifdef TEST_CAST { double cd = (double)x; double td = (double)(Double)Float(x); if (!(isnan((double)cd) && isnan((double)td)) && cd != td) { printf("cast to double : u = %08x\n", (unsigned)u); cout << "x: " << (double)x << " : " << to_string_d(ufloat(x)) << endl; cout << "c: " << (double)cd << " : " << to_string_d(udouble(cd)) << endl; cout << "t: " << (double)td << " : " << to_string_d(udouble(td)) << endl; exit(-1); } #if defined(TLFLOAT_COMPILER_SUPPORTS_FP16) __fp16 cf16 = (__fp16)x; __fp16 tf16 = (__fp16)(Half)Float(x); if (!(isnan((double)cf16) && isnan((double)tf16)) && cf16 != tf16) { printf("cast to fp16 : u = %08x\n", (unsigned)u); cout << "x: " << (double)x << " : " << to_string_d(ufloat(x)) << endl; cout << "c: " << (double)cf16 << " : " << to_string_d(uhalf(cf16)) << endl; cout << "t: " << (double)tf16 << " : " << to_string_d(uhalf(tf16)) << endl; exit(-1); } #endif #if defined(TLFLOAT_COMPILER_SUPPORTS_BF16) __bf16 cb16 = (__bf16)x; __bf16 tb16 = (__bf16)(BFloat16)Float(x); if (!(isnan((double)cb16) && isnan((double)tb16)) && cb16 != tb16) { printf("cast to bfloat16 : u = %08x\n", (unsigned)u); cout << "x: " << (double)x << " : " << to_string_d(ufloat(x)) << endl; cout << "c: " << (double)cb16 << " : " << to_string_d(ubf16(cb16)) << endl; cout << "t: " << (double)tb16 << " : " << to_string_d(ubf16(tb16)) << endl; exit(-1); } #endif } #endif #ifdef TEST_SQRT if (x >= 0 && finite__(x)) { mpfr_set_default_prec(32); mpfr_t mx; mpfr_inits(mx, NULL); auto xfr = sqrt_(Float(x).getUnpacked().cast((const xfloat *)nullptr)); float r = (float)Float(xfr.cast((const ufloat *)nullptr)); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sqrt(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::zero(), ufloat::infinity()); if (ulp > maxulp_sqrt_) { maxulp_sqrt_ = ulp; printf("\nsqrt_\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } mpfr_clears(mx, NULL); if (ulp > 0.5) { printf("NG\n"); exit(-1); } } { mpfr_set_default_prec(32); mpfr_t mx; mpfr_inits(mx, NULL); auto xfr = sqrt(Float(x)).getUnpacked().cast((const ufloat *)nullptr); float r = (float)Float(xfr.cast((const ufloat *)nullptr)); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sqrt(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_sqrt) { maxulp_sqrt = ulp; printf("\nsqrt\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } mpfr_clears(mx, NULL); if (ulp > 0.5) { printf("NG\n"); exit(-1); } } #endif { mpfr_set_default_prec(32); mpfr_t mx; mpfr_inits(mx, NULL); #ifdef TEST_TRIG { float r = (float)sin(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sin(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_sin) { maxulp_sin = ulp; printf("\nsin\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)cos(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_cos(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_cos) { maxulp_cos = ulp; printf("\ncos\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)tan(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_tan(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_tan) { maxulp_tan = ulp; printf("\ntan\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } #ifdef TLFLOAT_ENABLE_MPFR_SINPI { float r = (float)sinpi(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sinpi(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_sinpi) { maxulp_sinpi = ulp; printf("\nsinpi\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)cospi(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_cospi(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_cospi) { maxulp_cospi = ulp; printf("\ncospi\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)tanpi(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_tanpi(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_tanpi) { maxulp_tanpi = ulp; printf("\ntanpi\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } #endif #endif #ifdef TEST_INVTRIG { float r = (float)atan(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_atan(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_atan) { maxulp_atan = ulp; printf("\natan\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)asin(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_asin(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_asin) { maxulp_asin = ulp; printf("\nasin\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)acos(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_acos(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_acos) { maxulp_acos = ulp; printf("\nacos\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } #endif #ifdef TEST_EXP { float r = (float)exp(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_exp(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_exp) { maxulp_exp = ulp; printf("\nexp\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)expm1(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_expm1(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_expm1) { maxulp_expm1 = ulp; printf("\nexpm1\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)exp2(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_exp2(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_exp2) { maxulp_exp2 = ulp; printf("\nexp2\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)exp10(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_exp10(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_exp10) { maxulp_exp10 = ulp; printf("\nexp10\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } #endif #ifdef TEST_LOG { float r = (float)log(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_log(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_log) { maxulp_log = ulp; printf("\nlog\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)log1p(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_log1p(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_log1p) { maxulp_log1p = ulp; printf("\nlog1p\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)log2(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_log2(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_log2) { maxulp_log2 = ulp; printf("\nlog2\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)log10(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_log10(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_log10) { maxulp_log10 = ulp; printf("\nlog10\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } #endif #ifdef TEST_CBRT { float r = (float)cbrt(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_cbrt(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_cbrt) { maxulp_cbrt = ulp; printf("\ncbrt\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } #endif #ifdef TEST_HYP { float r = (float)sinh(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sinh(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_sinh) { maxulp_sinh = ulp; printf("\nsinh\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)cosh(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_cosh(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_cosh) { maxulp_cosh = ulp; printf("\ncosh\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)tanh(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_tanh(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_tanh) { maxulp_tanh = ulp; printf("\ntanh\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)asinh(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_asinh(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_asinh) { maxulp_asinh = ulp; printf("\nasinh\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)acosh(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_acosh(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_acosh) { maxulp_acosh = ulp; printf("\nacosh\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)atanh(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_atanh(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_atanh) { maxulp_atanh = ulp; printf("\natanh\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } #endif #ifdef TEST_ERF { float r = (float)erf(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_erf(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_erf) { maxulp_erf = ulp; printf("\nerf\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } { float r = (float)erfc(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_erfc(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_erfc) { maxulp_erfc = ulp; printf("\nerfc\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } #endif #ifdef TEST_GAMMA { float r = (float)tgamma(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_gamma(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_tgamma) { maxulp_tgamma = ulp; printf("\ntgamma\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } #if 0 { float r = (float)lgamma(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); int msign = 0; mpfr_lgamma(mx, &msign, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > maxulp_lgamma) { maxulp_lgamma = ulp; printf("\nlgamma\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); fflush(stdout); } if (ulp >= 1.0) { printf("NG\n"); exit(-1); } } #endif #endif mpfr_clears(mx, NULL); } } } tlfloat-1.15.0/src/tester/test_exhaustive_bf16.cpp000066400000000000000000000167261477036600700221340ustar00rootroot00000000000000#include #include #include #include #include "suppress.hpp" #include "tlfloat/tlmath.hpp" #include "testerutil.hpp" using namespace std; using namespace tlfloat; using namespace tlfloat::detail; #define TEST_ARITH #define TEST_COMPARE #define TEST_CASTFP16 typedef UnpackedFloat ubf16; typedef TLFloat BFloat16; typedef UnpackedFloat uhalf; typedef TLFloat Half; int main(int argc, char **argv) { atomic_int progress; #pragma omp parallel for for(uint32_t u32=0;u32 < 0x10000;u32++) { if ((u32 & 0xff) == 0xff) { progress++; int k = progress; printf(" %d / 256\r", k); fflush(stdout); } uint16_t u = ((u32 << 8) | (u32 >> 8)) & 0xffff; __bf16 fu; #if defined(TEST_CASTFP16) && defined(TLFLOAT_COMPILER_SUPPORTS_FP16) { __fp16 gu; gu = bit_cast<__fp16>(u); __bf16 fw = (__bf16)(float)gu; __bf16 fx = (__bf16)(BFloat16)Half(gu); if (!(isnan((double)fw) && isnan((double)fx)) && fw != fx) { printf("cast from fp16 to bf16 : u = %04x\n", (unsigned)u); cout << "u: " << (double)gu << " : " << to_string_d(uhalf(gu)) << endl; cout << "c: " << (double)fw << " : " << to_string_d(ubf16(fw)) << endl; cout << "t: " << (double)fx << " : " << to_string_d(ubf16(fx)) << endl; exit(-1); } fu = bit_cast<__bf16>(u); __fp16 gw = (__fp16)(float)fu; __fp16 gx = (__fp16)(Half)BFloat16(fu); if (!(isnan((double)gw) && isnan((double)gx)) && gw != gx) { printf("cast from bf16 to fp16 : u = %04x\n", (unsigned)u); cout << "u: " << (double)fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "c: " << (double)gw << " : " << to_string_d(uhalf(gw)) << endl; cout << "t: " << (double)gx << " : " << to_string_d(uhalf(gx)) << endl; exit(-1); } float hw = (float)fu; float hx = (float)(Float)BFloat16(fu); if (!(isnan((double)hw) && isnan((double)hx)) && hw != hx) { printf("cast from bf16 to float : u = %04x\n", (unsigned)u); cout << "u: " << (double)fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "c: " << (double)hw << " : " << to_string_d(ufloat(hw)) << endl; cout << "t: " << (double)hx << " : " << to_string_d(ufloat(hx)) << endl; exit(-1); } hw = (float)gu; hx = (float)(Float)Half(gu); if (!(isnan((double)hw) && isnan((double)hx)) && hw != hx) { printf("cast from half to float : u = %04x\n", (unsigned)u); cout << "u: " << (double)gu << " : " << to_string_d(uhalf(gu)) << endl; cout << "c: " << (double)hw << " : " << to_string_d(ufloat(hw)) << endl; cout << "t: " << (double)hx << " : " << to_string_d(ufloat(hx)) << endl; exit(-1); } } #endif memcpy((void *)&fu, (void *)&u, sizeof(fu)); for(uint32_t v32=0;v32 < 0x10000;v32++) { uint16_t v = ((v32 << 8) | (v32 >> 8)) & 0xffff; __bf16 fv; memcpy((void *)&fv, (void *)&v, sizeof(fv)); #ifdef TEST_ARITH { __bf16 fw = fu + fv; __bf16 fx = __bf16(ubf16::faddsub(ubf16(fu), ubf16(fv), false)); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan((double)fw) && isnan((double)fx)) && w != x) { printf("u = %04x, v = %04x, w = %04x, x = %04x\n", (unsigned)u, (unsigned)v, (unsigned)w, (unsigned)x); cout << "u: " << (double)fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "v: " << (double)fv << " : " << to_string_d(ubf16(fv)) << endl; cout << "c: " << (double)fw << " : " << to_string_d(ubf16(fw)) << endl; cout << "t: " << (double)fx << " : " << to_string_d(ubf16(fx)) << endl; exit(-1); } } { __bf16 fw = fu - fv; __bf16 fx = __bf16(ubf16::faddsub(ubf16(fu), ubf16(fv), true)); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan((double)fw) && isnan((double)fx)) && w != x) { printf("u = %04x, v = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)v, (unsigned)w, (unsigned)x); cout << "u: " << (double)fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "v: " << (double)fv << " : " << to_string_d(ubf16(fv)) << endl; cout << "c: " << (double)fw << " : " << to_string_d(ubf16(fw)) << endl; cout << "t: " << (double)fx << " : " << to_string_d(ubf16(fx)) << endl; exit(-1); } } { __bf16 fw = fu * fv; __bf16 fx = __bf16(ubf16::fmul(ubf16(fu), ubf16(fv))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan((double)fw) && isnan((double)fx)) && w != x) { printf("u = %04x, v = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)v, (unsigned)w, (unsigned)x); cout << "u: " << (double)fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "v: " << (double)fv << " : " << to_string_d(ubf16(fv)) << endl; cout << "c: " << (double)fw << " : " << to_string_d(ubf16(fw)) << endl; cout << "t: " << (double)fx << " : " << to_string_d(ubf16(fx)) << endl; exit(-1); } } { __bf16 fw = fu / fv; __bf16 fx = __bf16(ubf16::fdiv(ubf16(fu), ubf16(fv))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan((double)fw) && isnan((double)fx)) && w != x) { printf("u = %04x, v = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)v, (unsigned)w, (unsigned)x); cout << "u: " << (double)fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "v: " << (double)fv << " : " << to_string_d(ubf16(fv)) << endl; cout << "c: " << (double)fw << " : " << to_string_d(ubf16(fw)) << endl; cout << "t: " << (double)fx << " : " << to_string_d(ubf16(fx)) << endl; exit(-1); } } #endif #ifdef TEST_COMPARE { bool bc = (fu == fv); bool bt = ubf16(fu) == ubf16(fv); if (bc != bt) { printf("== : u = %04x, v = %04x, bc = %d, bt = %d\n", (unsigned)u, (unsigned)v, (int)bc, (int)bt); cout << "u: " << (double)fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "v: " << (double)fv << " : " << to_string_d(ubf16(fv)) << endl; exit(-1); } } { bool bc = (fu <= fv); bool bt = ubf16(fu) <= ubf16(fv); if (bc != bt) { printf("<= : u = %04x, v = %04x, bc = %d, bt = %d\n", (unsigned)u, (unsigned)v, (int)bc, (int)bt); cout << "u: " << (double)fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "v: " << (double)fv << " : " << to_string_d(ubf16(fv)) << endl; exit(-1); } } { bool bc = (fu >= fv); bool bt = ubf16(fu) >= ubf16(fv); if (bc != bt) { printf(">= : u = %04x, v = %04x, bc = %d, bt = %d\n", (unsigned)u, (unsigned)v, (int)bc, (int)bt); cout << "u: " << (double)fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "v: " << (double)fv << " : " << to_string_d(ubf16(fv)) << endl; exit(-1); } } { bool bc = (fu < fv); bool bt = ubf16(fu) < ubf16(fv); if (bc != bt) { printf("< : u = %04x, v = %04x, bc = %d, bt = %d\n", (unsigned)u, (unsigned)v, (int)bc, (int)bt); cout << "u: " << (double)fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "v: " << (double)fv << " : " << to_string_d(ubf16(fv)) << endl; exit(-1); } } { bool bc = (fu > fv); bool bt = ubf16(fu) > ubf16(fv); if (bc != bt) { printf("> : u = %04x, v = %04x, bc = %d, bt = %d\n", (unsigned)u, (unsigned)v, (int)bc, (int)bt); cout << "u: " << (double)fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "v: " << (double)fv << " : " << to_string_d(ubf16(fv)) << endl; exit(-1); } } #endif } } cout << endl << "OK" << endl; return 0; } tlfloat-1.15.0/src/tester/test_exhaustive_bf16_mpfr.cpp000066400000000000000000000632531477036600700231550ustar00rootroot00000000000000#include #include #include #include #if defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) #define MPFR_WANT_FLOAT128 #endif #include #include "suppress.hpp" #include "tlfloat/tlmath.hpp" #include "testerutil.hpp" using namespace std; using namespace tlfloat; using namespace tlfloat::detail; #define TEST_SQRT #define TEST_TRIG #define TEST_ROUND #define TEST_INVTRIG #define TEST_EXP #define TEST_LOG #define TEST_FMA #define TEST_POW #define TEST_CBRT #define TEST_HYP #define TEST_ERF #define TEST_GAMMA #define TEST_MODREM int main(int argc, char **argv) { typedef UnpackedFloat ubf16; typedef TLFloat BFloat16; atomic_int progress; #pragma omp parallel for for(uint32_t u32=0;u32 < 0x10000;u32++) { if ((u32 & 0xff) == 0xff) { progress++; int k = progress; printf(" %d / 256\r", k); fflush(stdout); } uint16_t u = ((u32 << 8) | (u32 >> 8)) & 0xffff; BFloat16 fu; memcpy((void *)&fu, (void *)&u, sizeof(fu)); { mpfr_set_default_prec(32); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); BFloat16 x = BFloat16(fu); #ifdef TEST_SQRT { BFloat16 r = sqrt(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_sqrt(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.5) { printf("\nbf16 sqrt\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_TRIG { BFloat16 r = sin(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_sin(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 sin\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = cos(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_cos(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 cos\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = tan(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_tan(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 tan\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #ifdef TLFLOAT_ENABLE_MPFR_SINPI { BFloat16 r = sinpi(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_sinpi(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 sinpi\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = cospi(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_cospi(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 cospi\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = tanpi(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_tanpi(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 tanpi\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #endif #ifdef TEST_INVTRIG { BFloat16 r = asin(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_asin(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 asin\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = acos(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_acos(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 acos\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = atan(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_atan(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 atan\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_EXP { BFloat16 r = exp(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_exp(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 exp\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = expm1(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_expm1(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 expm1\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = exp2(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_exp2(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 exp2\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = exp10(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_exp10(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 exp10\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_LOG { BFloat16 r = log(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_log(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 log\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = log1p(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_log1p(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 log1p\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = log2(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_log2(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 log2\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = log10(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_log10(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 log10\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_CBRT { BFloat16 r = cbrt(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_cbrt(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 cbrt\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_HYP { BFloat16 r = sinh(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_sinh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 sinh\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = cosh(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_cosh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 cosh\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = tanh(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_tanh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 tanh\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = asinh(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_asinh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 asinh\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = acosh(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_acosh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 acosh\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = atanh(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_atanh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 atanh\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_ERF { BFloat16 r = erf(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_erf(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 erf\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = erfc(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_erfc(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 erfc\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #ifdef TEST_GAMMA { BFloat16 r = tgamma(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_gamma(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 tgamma\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { BFloat16 r = lgamma(x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); int msign = 0; mpfr_lgamma(mx, &msign, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 lgamma\n"); cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif mpfr_clears(mx, my, mz, NULL); } #ifdef TEST_ROUND { BFloat16 fw = trunc((double)fu); BFloat16 fx = BFloat16(trunc(ubf16(fu))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("trunc u = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "c: " << fw << " : " << to_string_d(ubf16(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(ubf16(fx)) << endl; exit(-1); } } { BFloat16 fw = floor((double)fu); BFloat16 fx = BFloat16(floor(ubf16(fu))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("floor u = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "c: " << fw << " : " << to_string_d(ubf16(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(ubf16(fx)) << endl; exit(-1); } } { BFloat16 fw = ceil((double)fu); BFloat16 fx = BFloat16(ceil(ubf16(fu))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("ceil u = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "c: " << fw << " : " << to_string_d(ubf16(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(ubf16(fx)) << endl; exit(-1); } } { BFloat16 fw = round((double)fu); BFloat16 fx = BFloat16(round(ubf16(fu))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("round u = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "c: " << fw << " : " << to_string_d(ubf16(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(ubf16(fx)) << endl; exit(-1); } } { BFloat16 fw = rint((double)fu); BFloat16 fx = BFloat16(rint(ubf16(fu))); uint16_t w, x; memcpy((void *)&w, (void *)&fw, sizeof(w)); memcpy((void *)&x, (void *)&fx, sizeof(x)); if (!(isnan(fw) && isnan(fx)) && w != x) { printf("rint u = %04x, y = %04x, z = %04x\n", (unsigned)u, (unsigned)w, (unsigned)x); cout << "u: " << fu << " : " << to_string_d(ubf16(fu)) << endl; cout << "c: " << fw << " : " << to_string_d(ubf16(fw)) << endl; cout << "t: " << fx << " : " << to_string_d(ubf16(fx)) << endl; exit(-1); } } #endif for(uint32_t v32=0;v32 < 0x10000;v32++) { uint16_t v = ((v32 << 8) | (v32 >> 8)) & 0xffff; BFloat16 fv; memcpy((void *)&fv, (void *)&v, sizeof(fv)); #ifdef TEST_INVTRIG { mpfr_set_default_prec(32); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); BFloat16 x = BFloat16(fu); BFloat16 y = BFloat16(fv); { BFloat16 r = atan2(y, x); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_atan2(mx, my, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 atan2\n"); cout << "y = " << (BFloat16)y << endl; cout << "x = " << (BFloat16)x << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } mpfr_clears(mx, my, mz, NULL); } #endif #ifdef TEST_POW { mpfr_set_default_prec(32); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); BFloat16 x = BFloat16(fu); BFloat16 y = BFloat16(fv); { BFloat16 r = pow(x, y); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_pow(mx, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.7) { printf("\nbf16 pow\n"); cout << "x = " << (BFloat16)x << endl; cout << "y = " << (BFloat16)y << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } mpfr_clears(mx, my, mz, NULL); } #endif #ifdef TEST_MODREM { mpfr_set_default_prec(32); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); BFloat16 x = BFloat16(fu); BFloat16 y = BFloat16(fv); { BFloat16 r = fmod(x, y); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_fmod(mx, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.5) { printf("\nbf16 fmod\n"); cout << "x = " << (BFloat16)x << endl; cout << "y = " << (BFloat16)y << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } mpfr_clears(mx, my, mz, NULL); } { mpfr_set_default_prec(32); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); BFloat16 x = BFloat16(fu); BFloat16 y = BFloat16(fv); { BFloat16 r = remainder(x, y); ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_remainder(mx, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.5) { printf("\nbf16 remainder\n"); cout << "x = " << (BFloat16)x << endl; cout << "y = " << (BFloat16)y << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } mpfr_clears(mx, my, mz, NULL); } { mpfr_set_default_prec(32); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); BFloat16 x = BFloat16(fu); BFloat16 y = BFloat16(fv); { auto p = remquo(x, y); BFloat16 r = p.first; ubf16 xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); long int mq = 0; mpfr_remquo(mx, &mq, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, mx, ubf16::flt_true_min(), ubf16::flt_max()); if (ulp > 0.5 || mq != p.second) { printf("\nbf16 remquo\n"); cout << "x = " << (BFloat16)x << endl; cout << "y = " << (BFloat16)y << endl; cout << "c = " << c << ", " << mq << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << ", " << p.second << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } mpfr_clears(mx, my, mz, NULL); } #endif #ifdef TEST_FMA { mpfr_set_default_prec(32); mpfr_t mw, mx, my, mz; mpfr_inits(mw, mx, my, mz, NULL); BFloat16 x = BFloat16(fu); BFloat16 y = BFloat16(fv); BFloat16 fz[] = { 6e-8, -12e-8, 18e-8, -24e-8, 30e-8, -36e-8, 1e-5, -1e-4, 1e-3, -1e-2, 65504, -32768, +0.0, -0.0, (BFloat16)+INFINITY, (BFloat16)-INFINITY }; for(unsigned i=0;i 0.5) { printf("\nbf16 fma\n"); cout << "x = " << (BFloat16)x << endl; cout << "y = " << (BFloat16)y << endl; cout << "z = " << (BFloat16)z << endl; cout << "c = " << c << endl; cout << "r = " << (BFloat16)r << " : " << to_string_d(BFloat16(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } mpfr_clears(mw, mx, my, mz, NULL); } #endif } } cout << endl << "OK" << endl; return 0; } tlfloat-1.15.0/src/tester/test_hash.cpp000066400000000000000000000604471477036600700200530ustar00rootroot00000000000000#include #include #include #include #include #include "tlfloat/tlmath.hpp" #include "testerutil.hpp" using namespace std; using namespace tlfloat; int N = 10000; auto sha256 = PSHA2_256_Internal(); template T rnd(shared_ptr rng) { for(;;) { T f; rng->nextBytesW((unsigned char *)&f, sizeof(f)); if (finite(f)) return f; } } // template using Func1 = T (*)(const T&); template func> void computeHash(const char *mes, T *r, T *x, FILE *fp=nullptr, int mode=0) { for (int i = 0; i < N; i++) { T f = func(x[i]); if (mode == 0) { sha256.appendWord((void *)&f.m, sizeof(f.m)); } else if (mode == 1) { fwrite_((void *)&x[i].m, sizeof(x[i].m), 1, fp); fwrite_((void *)&f.m, sizeof(f.m), 1, fp); } else if (mode == 2) { T t = 0; if (fread((void *)&t, sizeof(t), 1, fp) != 1 || t.m != x[i].m) { cout << mes << " : arg does not match" << endl; cout << "arg file : " << toHexString(t.m) << " : " << to_string(t, 75) << endl; cout << "arg host : " << toHexString(x[i].m) << " : " << to_string(x[i], 75) << endl; } if (fread((void *)&t, sizeof(t), 1, fp) != 1 || t.m != f.m) { cout << mes << endl; cout << "arg1 : " << to_string(x[i], 75) << endl; cout << "file : " << toHexString(t.m) << " : " << to_string(t, 75) << endl; cout << "host : " << toHexString(f.m) << " : " << to_string(f, 75) << endl; } } } } template using Func2 = T (*)(const T&, const T&); template func> void computeHash(const char *mes, T *r, T *x, T *y, FILE *fp=nullptr, int mode=0) { for (int i = 0; i < N; i++) { T f = func(x[i], y[i]); if (mode == 0) { sha256.appendWord((void *)&f.m, sizeof(f.m)); } else if (mode == 1) { fwrite_((void *)&f.m, sizeof(f.m), 1, fp); } else if (mode == 2) { T t = 0; if (fread((void *)&t, sizeof(t), 1, fp) != 1 || t.m != f.m) { cout << mes << endl; cout << "arg1 : " << to_string(x[i], 75) << endl; cout << "arg2 : " << to_string(y[i], 75) << endl; cout << "file : " << toHexString(t.m) << " : " << to_string(t, 75) << endl; cout << "host : " << toHexString(f.m) << " : " << to_string(f, 75) << endl; } } } } template using Func2i = xpair (*)(const T&, const T&); template func> void computeHash(const char *mes, T *r, T *x, T *y, FILE *fp=nullptr, int mode=0) { for (int i = 0; i < N; i++) { xpair p = func(x[i], y[i]); if (mode == 0) { sha256.appendWord((void *)&p.first.m, sizeof(p.first.m)); sha256.appendWord((void *)&p.second, sizeof(p.second)); } else if (mode == 1) { fwrite_((void *)&p.first.m, sizeof(p.first.m), 1, fp); fwrite_((void *)&p.second, sizeof(p.second), 1, fp); } else if (mode == 2) { T t = 0; size_t s0 = fread((void *)&t, sizeof(t), 1, fp); int64_t q = 0; size_t s1 = fread((void *)&q, sizeof(q), 1, fp); if (s0 != 1 || s1 != 1 || t.m != p.first.m || q != p.second) { cout << mes << endl; cout << "arg1 : " << to_string(x[i], 75) << endl; cout << "arg2 : " << to_string(y[i], 75) << endl; cout << "file : " << toHexString(t.m) << " : " << to_string(t, 75) << ", " << q << endl; cout << "host : " << toHexString(p.first.m) << " : " << to_string(p.first, 75) << ", " << p.second << endl; } } } } template using Func3 = T (*)(const T&, const T&, const T&); template func> void computeHash(const char *mes, T *r, T *x, T *y, T *z, FILE *fp=nullptr, int mode=0) { for (int i = 0; i < N; i++) { T f = func(x[i], y[i], z[i]); if (mode == 0) { sha256.appendWord((void *)&f.m, sizeof(f.m)); } else if (mode == 1) { fwrite_((void *)&f.m, sizeof(f.m), 1, fp); } else if (mode == 2) { T t = 0; if (fread((void *)&t, sizeof(t), 1, fp) != 1 || t.m != f.m) { cout << mes << endl; cout << "arg1 : " << to_string(x[i], 75) << endl; cout << "arg2 : " << to_string(y[i], 75) << endl; cout << "arg3 : " << to_string(z[i], 75) << endl; cout << "file : " << toHexString(t.m) << " : " << to_string(t, 75) << endl; cout << "host : " << toHexString(f.m) << " : " << to_string(f, 75) << endl; } } } } // template static constexpr T fabs_(const T &a1) { return fabs(a1); } template static constexpr T copysign_(const T &a1, const T &a2) { return copysign(a1, a2); } template static constexpr T fmax_(const T &a1, const T &a2) { return fmax(a1, a2); } template static constexpr T fmin_(const T &a1, const T &a2) { return fmin(a1, a2); } template static constexpr T fdim_(const T &a1, const T &a2) { return fdim(a1, a2); } template static constexpr T add_(const T &a1, const T &a2) { return a1 + a2; } template static constexpr T mul_(const T &a1, const T &a2) { return a1 * a2; } template static constexpr T div_(const T &a1, const T &a2) { return a1 / a2; } template static constexpr T fma_(const T &a1, const T &a2, const T &a3) { return fma(a1, a2, a3); } template static constexpr T sqrt_(const T &a) { return sqrt(a); } template static constexpr T hypot_(const T &a1, const T &a2) { return hypot(a1, a2); } template static constexpr T trunc_(const T &a) { return trunc(a); } template static constexpr T floor_(const T &a) { return floor(a); } template static constexpr T ceil_(const T &a) { return ceil(a); } template static constexpr T round_(const T &a) { return round(a); } template static constexpr T rint_(const T &a) { return rint(a); } template static constexpr T nextafter_(const T &a1, const T &a2) { return nextafter(a1, a2); } template static constexpr T lgamma_(const T &a1) { return lgamma(a1, nullptr); } // int main(int argc, char **argv) { FILE *fp = nullptr; int mode = 0; if (argc == 3 && strcmp(argv[1], "r") == 0) { fp = fopen(argv[2], "rb"); if (!fp) { cerr << "Could not open " << argv[2] << endl; exit(-1); } mode = 2; } else if (argc == 3 && strcmp(argv[1], "w") == 0) { fp = fopen(argv[2], "wb"); if (!fp) { cerr << "Could not open " << argv[2] << endl; exit(-1); } mode = 1; } auto rng = shared_ptr(new LCG64(0)); Octuple *xo = (Octuple *)malloc(N*sizeof(Octuple)); Octuple *yo = (Octuple *)malloc(N*sizeof(Octuple)); Octuple *zo = (Octuple *)malloc(N*sizeof(Octuple)); Octuple *ro = (Octuple *)malloc(N*sizeof(Octuple)); Quad *xq = (Quad *)malloc(N*sizeof(Quad)); Quad *yq = (Quad *)malloc(N*sizeof(Quad)); Quad *zq = (Quad *)malloc(N*sizeof(Quad)); Quad *rq = (Quad *)malloc(N*sizeof(Quad)); Double *xd = (Double *)malloc(N*sizeof(Double)); Double *yd = (Double *)malloc(N*sizeof(Double)); Double *zd = (Double *)malloc(N*sizeof(Double)); Double *rd = (Double *)malloc(N*sizeof(Double)); Float *xf = (Float *)malloc(N*sizeof(Float)); Float *yf = (Float *)malloc(N*sizeof(Float)); Float *zf = (Float *)malloc(N*sizeof(Float)); Float *rf = (Float *)malloc(N*sizeof(Float)); Half *xh = (Half *)malloc(N*sizeof(Half)); Half *yh = (Half *)malloc(N*sizeof(Half)); Half *zh = (Half *)malloc(N*sizeof(Half)); Half *rh = (Half *)malloc(N*sizeof(Half)); for (int i = 0; i < N; i++) { xo[i] = rnd(rng); yo[i] = rnd(rng); zo[i] = rnd(rng); xq[i] = rnd(rng); yq[i] = rnd(rng); zq[i] = rnd(rng); xd[i] = rnd(rng); yd[i] = rnd(rng); zd[i] = rnd(rng); xf[i] = rnd(rng); yf[i] = rnd(rng); zf[i] = rnd(rng); xh[i] = rnd(rng); yh[i] = rnd(rng); zh[i] = rnd(rng); } computeHash("Octuple fabs", ro, xo, fp, mode); computeHash("Quad fabs", rq, xq, fp, mode); computeHash("Double fabs", rd, xd, fp, mode); computeHash("Float fabs", rf, xf, fp, mode); computeHash("Half fabs", rh, xh, fp, mode); computeHash("Octuple copysign", ro, xo, yo, fp, mode); computeHash("Quad copysign", rq, xq, yq, fp, mode); computeHash("Double copysign", rd, xd, yd, fp, mode); computeHash("Float copysign", rf, xf, yf, fp, mode); computeHash("Half copysign", rh, xh, yh, fp, mode); computeHash("Octuple fmax", ro, xo, yo, fp, mode); computeHash("Quad fmax", rq, xq, yq, fp, mode); computeHash("Double fmax", rd, xd, yd, fp, mode); computeHash("Float fmax", rf, xf, yf, fp, mode); computeHash("Half fmax", rh, xh, yh, fp, mode); computeHash("Octuple fmin", ro, xo, yo, fp, mode); computeHash("Quad fmin", rq, xq, yq, fp, mode); computeHash("Double fmin", rd, xd, yd, fp, mode); computeHash("Float fmin", rf, xf, yf, fp, mode); computeHash("Half fmin", rh, xh, yh, fp, mode); computeHash("Octuple fdim", ro, xo, yo, fp, mode); computeHash("Quad fdim", rq, xq, yq, fp, mode); computeHash("Double fdim", rd, xd, yd, fp, mode); computeHash("Float fdim", rf, xf, yf, fp, mode); computeHash("Half fdim", rh, xh, yh, fp, mode); computeHash("Octuple add_", ro, xo, yo, fp, mode); computeHash("Quad add_", rq, xq, yq, fp, mode); computeHash("Double add_", rd, xd, yd, fp, mode); computeHash("Float add_", rf, xf, yf, fp, mode); computeHash("Half add_", rh, xh, yh, fp, mode); computeHash("Octuple mul_", ro, xo, yo, fp, mode); computeHash("Quad mul_", rq, xq, yq, fp, mode); computeHash("Double mul_", rd, xd, yd, fp, mode); computeHash("Float mul_", rf, xf, yf, fp, mode); computeHash("Half mul_", rh, xh, yh, fp, mode); computeHash("Octuple div_", ro, xo, yo, fp, mode); computeHash("Quad div_", rq, xq, yq, fp, mode); computeHash("Double div_", rd, xd, yd, fp, mode); computeHash("Float div_", rf, xf, yf, fp, mode); computeHash("Half div_", rh, xh, yh, fp, mode); computeHash("Octuple fma", ro, xo, yo, zo, fp, mode); computeHash("Quad fma", rq, xq, yq, zq, fp, mode); computeHash("Double fma", rd, xd, yd, zd, fp, mode); computeHash("Float fma", rf, xf, yf, zf, fp, mode); computeHash("Half fma", rh, xh, yh, zh, fp, mode); computeHash("Octuple sqrt", ro, xo, fp, mode); computeHash("Quad sqrt", rq, xq, fp, mode); computeHash("Double sqrt", rd, xd, fp, mode); computeHash("Float sqrt", rf, xf, fp, mode); computeHash("Half sqrt", rh, xh, fp, mode); computeHash("Octuple hypot", ro, xo, yo, fp, mode); computeHash("Quad hypot", rq, xq, yq, fp, mode); computeHash("Double hypot", rd, xd, yd, fp, mode); computeHash("Float hypot", rf, xf, yf, fp, mode); computeHash("Half hypot", rh, xh, yh, fp, mode); computeHash("Octuple trunc", ro, xo, fp, mode); computeHash("Quad trunc", rq, xq, fp, mode); computeHash("Double trunc", rd, xd, fp, mode); computeHash("Float trunc", rf, xf, fp, mode); computeHash("Half trunc", rh, xh, fp, mode); computeHash("Octuple floor", ro, xo, fp, mode); computeHash("Quad floor", rq, xq, fp, mode); computeHash("Double floor", rd, xd, fp, mode); computeHash("Float floor", rf, xf, fp, mode); computeHash("Half floor", rh, xh, fp, mode); computeHash("Octuple ceil", ro, xo, fp, mode); computeHash("Quad ceil", rq, xq, fp, mode); computeHash("Double ceil", rd, xd, fp, mode); computeHash("Float ceil", rf, xf, fp, mode); computeHash("Half ceil", rh, xh, fp, mode); computeHash("Octuple round", ro, xo, fp, mode); computeHash("Quad round", rq, xq, fp, mode); computeHash("Double round", rd, xd, fp, mode); computeHash("Float round", rf, xf, fp, mode); computeHash("Half round", rh, xh, fp, mode); computeHash("Octuple rint", ro, xo, fp, mode); computeHash("Quad rint", rq, xq, fp, mode); computeHash("Double rint", rd, xd, fp, mode); computeHash("Float rint", rf, xf, fp, mode); computeHash("Half rint", rh, xh, fp, mode); computeHash("Octuple nextafter", ro, xo, yo, fp, mode); computeHash("Quad nextafter", rq, xq, yq, fp, mode); computeHash("Double nextafter", rd, xd, yd, fp, mode); computeHash("Float nextafter", rf, xf, yf, fp, mode); computeHash("Half nextafter", rh, xh, yh, fp, mode); computeHash("Octuple sin", ro, xo, fp, mode); computeHash("Quad sin", rq, xq, fp, mode); computeHash("Double sin", rd, xd, fp, mode); computeHash("Float sin", rf, xf, fp, mode); computeHash("Half sin", rh, xh, fp, mode); computeHash("Octuple cos", ro, xo, fp, mode); computeHash("Quad cos", rq, xq, fp, mode); computeHash("Double cos", rd, xd, fp, mode); computeHash("Float cos", rf, xf, fp, mode); computeHash("Half cos", rh, xh, fp, mode); computeHash("Octuple tan", ro, xo, fp, mode); computeHash("Quad tan", rq, xq, fp, mode); computeHash("Double tan", rd, xd, fp, mode); computeHash("Float tan", rf, xf, fp, mode); computeHash("Half tan", rh, xh, fp, mode); computeHash("Octuple sinpi", ro, xo, fp, mode); computeHash("Quad sinpi", rq, xq, fp, mode); computeHash("Double sinpi", rd, xd, fp, mode); computeHash("Float sinpi", rf, xf, fp, mode); computeHash("Half sinpi", rh, xh, fp, mode); computeHash("Octuple cospi", ro, xo, fp, mode); computeHash("Quad cospi", rq, xq, fp, mode); computeHash("Double cospi", rd, xd, fp, mode); computeHash("Float cospi", rf, xf, fp, mode); computeHash("Half cospi", rh, xh, fp, mode); computeHash("Octuple tanpi", ro, xo, fp, mode); computeHash("Quad tanpi", rq, xq, fp, mode); computeHash("Double tanpi", rd, xd, fp, mode); computeHash("Float tanpi", rf, xf, fp, mode); computeHash("Half tanpi", rh, xh, fp, mode); computeHash("Octuple atan2", ro, xo, yo, fp, mode); computeHash("Quad atan2", rq, xq, yq, fp, mode); computeHash("Double atan2", rd, xd, yd, fp, mode); computeHash("Float atan2", rf, xf, yf, fp, mode); computeHash("Half atan2", rh, xh, yh, fp, mode); computeHash("Octuple asin", ro, xo, fp, mode); computeHash("Quad asin", rq, xq, fp, mode); computeHash("Double asin", rd, xd, fp, mode); computeHash("Float asin", rf, xf, fp, mode); computeHash("Half asin", rh, xh, fp, mode); computeHash("Octuple acos", ro, xo, fp, mode); computeHash("Quad acos", rq, xq, fp, mode); computeHash("Double acos", rd, xd, fp, mode); computeHash("Float acos", rf, xf, fp, mode); computeHash("Half acos", rh, xh, fp, mode); computeHash("Octuple atan", ro, xo, fp, mode); computeHash("Quad atan", rq, xq, fp, mode); computeHash("Double atan", rd, xd, fp, mode); computeHash("Float atan", rf, xf, fp, mode); computeHash("Half atan", rh, xh, fp, mode); computeHash("Octuple log", ro, xo, fp, mode); computeHash("Quad log", rq, xq, fp, mode); computeHash("Double log", rd, xd, fp, mode); computeHash("Float log", rf, xf, fp, mode); computeHash("Half log", rh, xh, fp, mode); computeHash("Octuple log2", ro, xo, fp, mode); computeHash("Quad log2", rq, xq, fp, mode); computeHash("Double log2", rd, xd, fp, mode); computeHash("Float log2", rf, xf, fp, mode); computeHash("Half log2", rh, xh, fp, mode); computeHash("Octuple log10", ro, xo, fp, mode); computeHash("Quad log10", rq, xq, fp, mode); computeHash("Double log10", rd, xd, fp, mode); computeHash("Float log10", rf, xf, fp, mode); computeHash("Half log10", rh, xh, fp, mode); computeHash("Octuple log1p", ro, xo, fp, mode); computeHash("Quad log1p", rq, xq, fp, mode); computeHash("Double log1p", rd, xd, fp, mode); computeHash("Float log1p", rf, xf, fp, mode); computeHash("Half log1p", rh, xh, fp, mode); computeHash("Octuple exp", ro, xo, fp, mode); computeHash("Quad exp", rq, xq, fp, mode); computeHash("Double exp", rd, xd, fp, mode); computeHash("Float exp", rf, xf, fp, mode); computeHash("Half exp", rh, xh, fp, mode); computeHash("Octuple exp2", ro, xo, fp, mode); computeHash("Quad exp2", rq, xq, fp, mode); computeHash("Double exp2", rd, xd, fp, mode); computeHash("Float exp2", rf, xf, fp, mode); computeHash("Half exp2", rh, xh, fp, mode); computeHash("Octuple exp10", ro, xo, fp, mode); computeHash("Quad exp10", rq, xq, fp, mode); computeHash("Double exp10", rd, xd, fp, mode); computeHash("Float exp10", rf, xf, fp, mode); computeHash("Half exp10", rh, xh, fp, mode); computeHash("Octuple expm1", ro, xo, fp, mode); computeHash("Quad expm1", rq, xq, fp, mode); computeHash("Double expm1", rd, xd, fp, mode); computeHash("Float expm1", rf, xf, fp, mode); computeHash("Half expm1", rh, xh, fp, mode); computeHash("Octuple pow", ro, xo, yo, fp, mode); computeHash("Quad pow", rq, xq, yq, fp, mode); computeHash("Double pow", rd, xd, yd, fp, mode); computeHash("Float pow", rf, xf, yf, fp, mode); computeHash("Half pow", rh, xh, yh, fp, mode); computeHash("Octuple cbrt", ro, xo, fp, mode); computeHash("Quad cbrt", rq, xq, fp, mode); computeHash("Double cbrt", rd, xd, fp, mode); computeHash("Float cbrt", rf, xf, fp, mode); computeHash("Half cbrt", rh, xh, fp, mode); computeHash("Octuple sinh", ro, xo, fp, mode); computeHash("Quad sinh", rq, xq, fp, mode); computeHash("Double sinh", rd, xd, fp, mode); computeHash("Float sinh", rf, xf, fp, mode); computeHash("Half sinh", rh, xh, fp, mode); computeHash("Octuple cosh", ro, xo, fp, mode); computeHash("Quad cosh", rq, xq, fp, mode); computeHash("Double cosh", rd, xd, fp, mode); computeHash("Float cosh", rf, xf, fp, mode); computeHash("Half cosh", rh, xh, fp, mode); computeHash("Octuple tanh", ro, xo, fp, mode); computeHash("Quad tanh", rq, xq, fp, mode); computeHash("Double tanh", rd, xd, fp, mode); computeHash("Float tanh", rf, xf, fp, mode); computeHash("Half tanh", rh, xh, fp, mode); computeHash("Octuple asinh", ro, xo, fp, mode); computeHash("Quad asinh", rq, xq, fp, mode); computeHash("Double asinh", rd, xd, fp, mode); computeHash("Float asinh", rf, xf, fp, mode); computeHash("Half asinh", rh, xh, fp, mode); computeHash("Octuple acosh", ro, xo, fp, mode); computeHash("Quad acosh", rq, xq, fp, mode); computeHash("Double acosh", rd, xd, fp, mode); computeHash("Float acosh", rf, xf, fp, mode); computeHash("Half acosh", rh, xh, fp, mode); computeHash("Octuple atanh", ro, xo, fp, mode); computeHash("Quad atanh", rq, xq, fp, mode); computeHash("Double atanh", rd, xd, fp, mode); computeHash("Float atanh", rf, xf, fp, mode); computeHash("Half atanh", rh, xh, fp, mode); computeHash("Octuple erf", ro, xo, fp, mode); computeHash("Quad erf", rq, xq, fp, mode); computeHash("Double erf", rd, xd, fp, mode); computeHash("Float erf", rf, xf, fp, mode); computeHash("Half erf", rh, xh, fp, mode); computeHash("Octuple erfc", ro, xo, fp, mode); computeHash("Quad erfc", rq, xq, fp, mode); computeHash("Double erfc", rd, xd, fp, mode); computeHash("Float erfc", rf, xf, fp, mode); computeHash("Half erfc", rh, xh, fp, mode); computeHash("Octuple tgamma", ro, xo, fp, mode); computeHash("Quad tgamma", rq, xq, fp, mode); computeHash("Double tgamma", rd, xd, fp, mode); computeHash("Float tgamma", rf, xf, fp, mode); computeHash("Half tgamma", rh, xh, fp, mode); computeHash("Octuple lgamma", ro, xo, fp, mode); computeHash("Quad lgamma", rq, xq, fp, mode); computeHash("Double lgamma", rd, xd, fp, mode); computeHash("Float lgamma", rf, xf, fp, mode); computeHash("Half lgamma", rh, xh, fp, mode); computeHash("Octuple fmod", ro, xo, yo, fp, mode); computeHash("Quad fmod", rq, xq, yq, fp, mode); computeHash("Double fmod", rd, xd, yd, fp, mode); computeHash("Float fmod", rf, xf, yf, fp, mode); computeHash("Half fmod", rh, xh, yh, fp, mode); computeHash("Octuple remainder", ro, xo, yo, fp, mode); computeHash("Quad remainder", rq, xq, yq, fp, mode); computeHash("Double remainder", rd, xd, yd, fp, mode); computeHash("Float remainder", rf, xf, yf, fp, mode); computeHash("Half remainder", rh, xh, yh, fp, mode); computeHash("Octuple remquo", ro, xo, yo, fp, mode); computeHash("Quad remquo", rq, xq, yq, fp, mode); computeHash("Double remquo", rd, xd, yd, fp, mode); computeHash("Float remquo", rf, xf, yf, fp, mode); computeHash("Half remquo", rh, xh, yh, fp, mode); free(rh); free(zh); free(yh); free(xh); free(rf); free(zf); free(yf); free(xf); free(rd); free(zd); free(yd); free(xd); free(rq); free(zq); free(yq); free(xq); free(ro); free(zo); free(yo); free(xo); if (mode == 0) { uint8_t h[32]; sha256.finalize_bytes(&h); if (argc == 1) { for(int i=0;i<32;i++) printf("%02x", h[i]); printf("\n"); } else { unsigned int a[32]; if (sscanf(argv[1], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", &a[ 0], &a[ 1], &a[ 2], &a[ 3], &a[ 4], &a[ 5], &a[ 6], &a[ 7], &a[ 8], &a[ 9], &a[10], &a[11], &a[12], &a[13], &a[14], &a[15], &a[16], &a[17], &a[18], &a[19], &a[20], &a[21], &a[22], &a[23], &a[24], &a[25], &a[26], &a[27], &a[28], &a[29], &a[30], &a[31]) != 32) { printf("NG (arg format)\n"); exit(-1); } for(int i=0;i<32;i++) { if (h[i] != a[i]) { printf("NG\n"); exit(-1); } } printf("OK\n"); } } if (fp) fclose(fp); return 0; } tlfloat-1.15.0/src/tester/test_mpfr.cpp000066400000000000000000003456411477036600700200760ustar00rootroot00000000000000#include #include #include #include #if defined(TLFLOAT_ENABLE_LIBQUADMATH) #include #endif #if defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) #define MPFR_WANT_FLOAT128 #endif #include #include "suppress.hpp" #include "tlfloat/tlmath.hpp" #include "testerutil.hpp" using namespace std; using namespace tlfloat; using namespace tlfloat::detail; #define TEST_FLOAT #define TEST_DOUBLE #define TEST_QUAD #define TEST_OCTUPLE #define TEST_SQRT #define TEST_TRIG #define TEST_ROUND #define TEST_ARITH #define TEST_INVTRIG #define TEST_EXP #define TEST_LOG #define TEST_POW #define TEST_CBRT #define TEST_HYP #define TEST_MODREM #define TEST_ERF #define TEST_GAMMA #define TEST_MISC int main(int argc, char **argv) { uint64_t niter = argc > 1 ? strtoull(argv[1], nullptr, 10) : 100000; if (niter == 0) { #if defined(__GNUC__) cout << "Build " << __DATE__ << " " << __TIME__ << endl; #endif cout << "Testing continuously" << endl; } #ifdef TEST_FLOAT cout << " "; #endif #ifdef TEST_DOUBLE cout << " "; #endif #ifdef TEST_QUAD cout << " "; #endif #ifdef TEST_OCTUPLE cout << " "; #endif #ifdef TEST_SQRT cout << "[SQRT] "; #endif #ifdef TEST_TRIG cout << "[TRIG] "; #endif #ifdef TEST_ROUND cout << "[ROUND] "; #endif #ifdef TEST_ARITH cout << "[ARITH] "; #endif #ifdef TEST_INVTRIG cout << "[INVTRIG] "; #endif #ifdef TEST_EXP cout << "[EXP] "; #endif #ifdef TEST_LOG cout << "[LOG] "; #endif #ifdef TEST_POW cout << "[POW] "; #endif #ifdef TEST_CBRT cout << "[CBRT] "; #endif #ifdef TEST_HYP cout << "[HYP] "; #endif #ifdef TEST_MODREM cout << "[MODREM] "; #endif #ifdef TEST_ERF cout << "[ERF] "; #endif #ifdef TEST_GAMMA cout << "[GAMMA] "; #endif #ifdef TEST_MISC cout << "[MISC] "; #endif cout << endl; auto rng = createPreferredRNG(); for(uint64_t i=0;niter == 0 || inextLT(7); { float x = rndf(rng), y = rndf(rng); { mpfr_set_default_prec(32); mpfr_t mx, my; mpfr_inits(mx, my, NULL); #if defined(TEST_FLOAT) && defined(TEST_SQRT) { ufloat xfr = sqrt(Float(x)).getUnpacked().cast((const ufloat *)nullptr); float r = (float)Float(xfr.cast((const ufloat *)nullptr)); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sqrt(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.5) { printf("\nfloat sqrt\n"); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n", c); printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { ufloat xfr = hypot(Float(x), Float(y)).getUnpacked().cast((const ufloat *)nullptr); float r = (float)Float(xfr.cast((const ufloat *)nullptr)); mpfr_set_d(mx, x, GMP_RNDN); mpfr_set_d(my, y, GMP_RNDN); mpfr_hypot(mx, mx, my, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat hypot\n"); printf("x = %.8g\n", x); printf("y = %.8g\n", y); printf("t = %.8g\n", r); printf("c = %.8g\n", c); printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_FLOAT) && defined(TEST_TRIG) { float r = (float)sin(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sin(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat sin\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)cos(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_cos(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat cos\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)tan(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_tan(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.56) { printf("\nfloat tan\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } #ifdef TLFLOAT_ENABLE_MPFR_SINPI { float r = (float)sinpi(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sinpi(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat sinpi\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)cospi(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_cospi(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat cospi\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)tanpi(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_tanpi(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.56) { printf("\nfloat tanpi\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #endif #if defined(TEST_FLOAT) && defined(TEST_INVTRIG) { float r = (float)atan2(Float(y), Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(my, y, GMP_RNDN); mpfr_set_d(mx, x, GMP_RNDN); mpfr_atan2(mx, my, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat atan2\n"); printf("ulp = %g\n", ulp); printf("y = %.8g\n", y); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)asin(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_asin(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat asin\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)acos(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_acos(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat acos\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)atan(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_atan(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat atan\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_FLOAT) && defined(TEST_EXP) { float r = (float)exp(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_exp(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat exp\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)expm1(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_expm1(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat expm1\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)exp2(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_exp2(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat exp2\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)exp10(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_exp10(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat exp10\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_FLOAT) && defined(TEST_LOG) { float r = (float)log(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_log(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat log\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)log1p(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_log1p(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat log1p\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)log2(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_log2(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat log2\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)log10(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_log10(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat log10\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_FLOAT) && defined(TEST_POW) { float r = (float)pow(Float(y), Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(my, y, GMP_RNDN); mpfr_set_d(mx, x, GMP_RNDN); mpfr_pow(mx, my, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat pow\n"); printf("ulp = %g\n", ulp); printf("y = %.8g\n", y); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_FLOAT) && defined(TEST_MODREM) { float r = (float)fmod(Float(y), Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(my, y, GMP_RNDN); mpfr_set_d(mx, x, GMP_RNDN); mpfr_fmod(mx, my, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.5) { printf("\nfloat fmod\n"); printf("ulp = %g\n", ulp); printf("y = %.8g\n", y); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)remainder(Float(y), Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(my, y, GMP_RNDN); mpfr_set_d(mx, x, GMP_RNDN); mpfr_remainder(mx, my, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.5) { printf("\nfloat remainder\n"); printf("ulp = %g\n", ulp); printf("y = %.8g\n", y); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { auto a = remquo(Float(y), Float(x)); ufloat xfr = Float(a.first).getUnpacked(); mpfr_set_d(my, y, GMP_RNDN); mpfr_set_d(mx, x, GMP_RNDN); long int q = 0; mpfr_remquo(mx, &q, my, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.5 || !eqquo(a.second, q)) { printf("\nfloat remquo\n"); printf("ulp = %g\n", ulp); printf("y = %.8g\n", y); printf("x = %.8g\n", x); printf("t = %.8g, %ld\n", (float)a.first, (long int)a.second); printf("c = %.8g, %ld\n\n", c, q); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_FLOAT) && defined(TEST_CBRT) { float r = (float)cbrt(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_cbrt(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat cbrt\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_FLOAT) && defined(TEST_HYP) { float r = (float)sinh(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sinh(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat sinh\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)cosh(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_cosh(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat cosh\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)tanh(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_tanh(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat tanh\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)asinh(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_asinh(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat asinh\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)acosh(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_acosh(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat acosh\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)atanh(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_atanh(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat atanh\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_FLOAT) && defined(TEST_ERF) { float r = (float)erf(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_erf(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat erf\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)erfc(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_erfc(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat erfc\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_FLOAT) && defined(TEST_GAMMA) { float r = (float)tgamma(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_gamma(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55) { printf("\nfloat tgamma\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } #if 0 { bool rsign = false; float r = (float)lgamma(Float(x), &rsign); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); int msign = 0; mpfr_lgamma(mx, &msign, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.55 || (msign == -1) != rsign) { printf("\nfloat lgamma\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g, sign = %d\n" , r, (int)rsign); printf("c = %.8g, sign = %d\n\n", c, (int)(msign == -1)); cout << "NG" << endl; //exit(-1); } } #endif #endif #if defined(TEST_FLOAT) && defined(TEST_MISC) { float r = (float)fabs(Float(x)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_abs(mx, mx, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.5) { printf("\nfloat fabs\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)copysign(Float(x), Float(y)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_set_d(my, y, GMP_RNDN); mpfr_copysign(mx, mx, my, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.5 && !isnan(y)) { printf("\nfloat copysign\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("y = %.8g\n", y); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)fmax(Float(x), Float(y)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_set_d(my, y, GMP_RNDN); mpfr_max(mx, mx, my, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.5) { printf("\nfloat fmax\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)fmin(Float(x), Float(y)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_set_d(my, y, GMP_RNDN); mpfr_min(mx, mx, my, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.5) { printf("\nfloat fmin\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { float r = (float)fdim(Float(x), Float(y)); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_set_d(my, y, GMP_RNDN); mpfr_dim(mx, mx, my, GMP_RNDN); float c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.5) { printf("\nfloat fdim\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n\n", c); cout << "NG" << endl; exit(-1); } } { Float w; float r = (float)modf(Float(x), &w); ufloat xfr = Float(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_modf(mx, my, mx, GMP_RNDN); double ci = mpfr_get_d(mx, GMP_RNDN); float c = mpfr_get_d(my, GMP_RNDN); double ulp = countULP(xfr, my, ufloat::flt_true_min(), ufloat::flt_max()); if (ulp > 0.5 || (!(isnan(w) && isnan(ci)) && double(w) != ci)) { printf("\nfloat modf\n"); printf("ulp = %g\n", ulp); printf("x = %.8g\n", x); printf("t = %.8g\n", r); printf("c = %.8g\n", c); printf("ci = %.8g\n\n", ci); cout << "NG" << endl; exit(-1); } } #endif mpfr_clears(mx, my, NULL); } } // { double x = rndd(rng), y = rndd(rng); { mpfr_set_default_prec(64); mpfr_t mx, my; mpfr_inits(mx, my, NULL); #if defined(TEST_DOUBLE) && defined(TEST_SQRT) { auto xfr = sqrt(Double(x)).getUnpacked().cast((const udouble *)nullptr); double r = (double)Double(xfr.cast((const udouble *)nullptr)); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sqrt(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.5) { printf("\ndouble sqrt\n"); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n", c); printf("ulp = %g\n", ulp); exit(-1); } } { auto xfr = hypot(Double(x), Double(y)).getUnpacked().cast((const udouble *)nullptr); double r = (double)Double(xfr.cast((const udouble *)nullptr)); mpfr_set_d(mx, x, GMP_RNDN); mpfr_set_d(my, y, GMP_RNDN); mpfr_hypot(mx, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble hypot\n"); printf("x = %.20lg\n", x); printf("y = %.20lg\n", y); printf("t = %.20lg\n", r); printf("c = %.20lg\n", c); printf("ulp = %g\n", ulp); exit(-1); } } #endif #if defined(TEST_DOUBLE) && defined(TEST_TRIG) { double r = (double)sin(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sin(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.506) { printf("\ndouble sin\n"); printf("ulp = %g\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)cos(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_cos(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.506) { printf("\ndouble cos\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)tan(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_tan(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.51) { printf("\ndouble tan\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } #ifdef TLFLOAT_ENABLE_MPFR_SINPI { double r = (double)sinpi(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sinpi(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.506) { printf("\ndouble sinpi\n"); printf("ulp = %g\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)cospi(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_cospi(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.506) { printf("\ndouble cospi\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)tanpi(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_tanpi(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.51) { printf("\ndouble tanpi\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #endif #if defined(TEST_DOUBLE) && defined(TEST_INVTRIG) { double r = (double)atan2(Double(y), Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(my, y, GMP_RNDN); mpfr_set_d(mx, x, GMP_RNDN); mpfr_atan2(mx, my, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.51) { printf("\ndouble atan2\n"); printf("ulp = %lg\n", ulp); printf("y = %.20lg\n", y); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)asin(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_asin(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.51) { printf("\ndouble asin\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)acos(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_acos(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.51) { printf("\ndouble acos\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)atan(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_atan(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.51) { printf("\ndouble atan\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_DOUBLE) && defined(TEST_EXP) { double r = (double)exp(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_exp(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble exp\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)expm1(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_expm1(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble expm1\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)exp2(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_exp2(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble exp2\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)exp10(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_exp10(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble exp10\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_DOUBLE) && defined(TEST_LOG) { double r = (double)log(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_log(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble log\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)log1p(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_log1p(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble log1p\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)log2(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_log2(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.506) { printf("\ndouble log2\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)log10(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_log10(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.506) { printf("\ndouble log10\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_DOUBLE) && defined(TEST_POW) { double r = (double)pow(Double(y), Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(my, y, GMP_RNDN); mpfr_set_d(mx, x, GMP_RNDN); mpfr_pow(mx, my, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.51) { printf("\ndouble pow\n"); printf("ulp = %lg\n", ulp); printf("y = %.20lg\n", y); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_DOUBLE) && defined(TEST_MODREM) { double r = (double)fmod(Double(y), Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(my, y, GMP_RNDN); mpfr_set_d(mx, x, GMP_RNDN); mpfr_fmod(mx, my, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.5) { printf("\ndouble fmod\n"); printf("ulp = %lg\n", ulp); printf("y = %.20lg\n", y); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)remainder(Double(y), Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(my, y, GMP_RNDN); mpfr_set_d(mx, x, GMP_RNDN); mpfr_remainder(mx, my, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.5) { printf("\ndouble remainder\n"); printf("ulp = %lg\n", ulp); printf("y = %.20lg\n", y); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { auto a = remquo(Double(y), Double(x)); udouble xfr = Double(a.first).getUnpacked(); mpfr_set_d(my, y, GMP_RNDN); mpfr_set_d(mx, x, GMP_RNDN); long int q = 0; mpfr_remquo(mx, &q, my, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.5 || !eqquo(a.second, q)) { printf("\ndouble remquo\n"); printf("ulp = %lg\n", ulp); printf("y = %.20lg\n", y); printf("x = %.20lg\n", x); printf("t = %.20lg, %ld\n", (double)a.first, (long int)a.second); printf("c = %.20lg, %ld\n\n", c, (long int)q); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_DOUBLE) && defined(TEST_CBRT) { double r = (double)cbrt(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_cbrt(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble cbrt\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_DOUBLE) && defined(TEST_HYP) { double r = (double)sinh(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_sinh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble sinh\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)cosh(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_cosh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble cosh\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)tanh(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_tanh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble tanh\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)asinh(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_asinh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble asinh\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)acosh(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_acosh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble acosh\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)atanh(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_atanh(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble atanh\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_DOUBLE) && defined(TEST_ERF) { double r = (double)erf(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_erf(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble erf\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)erfc(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_erfc(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble erfc\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_DOUBLE) && defined(TEST_GAMMA) { double r = (double)tgamma(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_gamma(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble tgamma\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } #if 0 { bool rsign = false; double r = (double)lgamma(Double(x), &rsign); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); int msign = 0; mpfr_lgamma(mx, &msign, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.505) { printf("\ndouble lgamma\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg, sign = %d\n" , r, (int)rsign); printf("c = %.20lg, sign = %d\n\n", c, (int)(msign == -1)); cout << "NG" << endl; //exit(-1); } } #endif #endif #if defined(TEST_DOUBLE) && defined(TEST_MISC) { double r = (double)fabs(Double(x)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_abs(mx, mx, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.5) { printf("\ndouble fabs\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)copysign(Double(x), Double(y)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_set_d(my, y, GMP_RNDN); mpfr_copysign(mx, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.5 && !isnan(y)) { printf("\ndouble copysign\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)fmax(Double(x), Double(y)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_set_d(my, y, GMP_RNDN); mpfr_max(mx, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.5) { printf("\ndouble fmax\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)fmin(Double(x), Double(y)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_set_d(my, y, GMP_RNDN); mpfr_min(mx, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.5) { printf("\ndouble fmin\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { double r = (double)fdim(Double(x), Double(y)); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_set_d(my, y, GMP_RNDN); mpfr_dim(mx, mx, my, GMP_RNDN); double c = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xfr, mx, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.5) { printf("\ndouble fdim\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } { Double w; double r = (double)modf(Double(x), &w); udouble xfr = Double(r).getUnpacked(); mpfr_set_d(mx, x, GMP_RNDN); mpfr_modf(mx, my, mx, GMP_RNDN); double ci = mpfr_get_d(mx, GMP_RNDN); double c = mpfr_get_d(my, GMP_RNDN); double ulp = countULP(xfr, my, udouble::flt_true_min(), udouble::flt_max()); if (ulp > 0.5 || (!(isnan(w) && isnan(ci)) && double(w) != ci)) { printf("\ndouble modf\n"); printf("ulp = %lg\n", ulp); printf("x = %.20lg\n", x); printf("t = %.20lg\n", r); printf("c = %.20lg\n\n", c); cout << "NG" << endl; exit(-1); } } #endif mpfr_clears(mx, my, NULL); } } if ((i & 31) == 0) { quad_ x = rndq(rng), y = rndq(rng), z = rndq(rng); { mpfr_set_default_prec(128); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); #if defined(TEST_QUAD) && defined(TEST_ARITH) { auto xfr = (Quad(x) + Quad(y)).getUnpacked(); quad_ r = (quad_)Quad(xfr); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); mpfr_set_float128(my, y, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif mpfr_add(mx, mx, my, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5) { printf("\nquad add\n"); cout << "x = " << x << endl; cout << "y = " << y << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << ", " << to_string(mx, 72) << " : " << to_string_d(Quad(c).getUnpacked()) << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << ", " << " : " << to_string_d(Quad(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); exit(-1); } } { auto xfr = (Quad(x) * Quad(y)).getUnpacked(); quad_ r = (quad_)Quad(xfr); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); mpfr_set_float128(my, y, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif mpfr_mul(mx, mx, my, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5) { printf("\nquad mul\n"); cout << "x = " << x << endl; cout << "y = " << y << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << ", " << to_string(mx, 72) << " : " << to_string_d(Quad(c).getUnpacked()) << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << " : " << to_string_d(Quad(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); exit(-1); } } { auto xfr = (Quad(x) / Quad(y)).getUnpacked(); quad_ r = (quad_)Quad(xfr); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); mpfr_set_float128(my, y, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif mpfr_div(mx, mx, my, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5) { printf("\nquad div\n"); cout << "x = " << x << endl; cout << "y = " << y << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << ", " << to_string(mx, 72) << " : " << to_string_d(Quad(c).getUnpacked()) << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << " : " << to_string_d(Quad(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); exit(-1); } } { auto xfr = fma(Quad(x), Quad(y), Quad(z)).getUnpacked(); quad_ r = (quad_)Quad(xfr); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); mpfr_set_float128(my, y, GMP_RNDN); mpfr_set_float128(mz, z, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(mz, Quad(z).getUnpacked(), GMP_RNDN); #endif mpfr_fma(mx, mx, my, mz, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5) { printf("\nquad fma\n"); cout << "x = " << x << endl; cout << "y = " << y << endl; cout << "z = " << z << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << ", " << to_string(mx, 72) << " : " << to_string_d(Quad(c).getUnpacked()) << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << ", " << " : " << to_string_d(Quad(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); exit(-1); } } #endif #if defined(TEST_QUAD) && defined(TEST_SQRT) { auto xfr = sqrt(Quad(x)).getUnpacked(); quad_ r = (quad_)Quad(xfr); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_sqrt(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5) { printf("\nquad sqrt\n"); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; printf("ulp = %g\n", ulp); exit(-1); } } { auto xfr = hypot(Quad(x), Quad(y)).getUnpacked(); quad_ r = (quad_)Quad(xfr); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); mpfr_set_float128(my, y, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif mpfr_hypot(mx, mx, my, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad hypot\n"); cout << "x = " << x << endl; cout << "y = " << y << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; printf("ulp = %g\n", ulp); exit(-1); } } #endif #if defined(TEST_QUAD) && defined(TEST_TRIG) { quad_ r = (quad_)sin(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_sin(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad sin\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)cos(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_cos(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad cos\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)tan(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_tan(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad tan\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } #ifdef TLFLOAT_ENABLE_MPFR_SINPI { quad_ r = (quad_)sinpi(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_sinpi(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad sinpi\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)cospi(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_cospi(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad cospi\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)tanpi(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_tanpi(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad tanpi\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } #endif #endif #if defined(TEST_QUAD) && defined(TEST_INVTRIG) { quad_ r = (quad_)atan2(Quad(y), Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(my, y, GMP_RNDN); mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif mpfr_atan2(mx, my, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad atan2\n"); printf("ulp = %g\n", ulp); cout << "y = " << y << endl; cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)asin(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_asin(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad asin\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)acos(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_acos(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad acos\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)atan(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_atan(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad atan\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_QUAD) && defined(TEST_EXP) { quad_ r = (quad_)exp(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_exp(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad exp\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)expm1(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_expm1(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad expm1\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)exp2(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_exp2(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad exp2\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)exp10(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_exp10(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad exp10\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_QUAD) && defined(TEST_LOG) { quad_ r = (quad_)log(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_log(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad log\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)log1p(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_log1p(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad log1p\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)log2(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_log2(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad log2\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)log10(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_log10(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad log10\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_QUAD) && defined(TEST_POW) { quad_ r = (quad_)pow(Quad(y), Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(my, y, GMP_RNDN); mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif mpfr_pow(mx, my, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad pow\n"); printf("ulp = %g\n", ulp); cout << "y = " << y << endl; cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_QUAD) && defined(TEST_MODREM) { quad_ r = (quad_)fmod(Quad(y), Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(my, y, GMP_RNDN); mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif mpfr_fmod(mx, my, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5) { printf("\nquad fmod\n"); printf("ulp = %g\n", ulp); cout << "y = " << y << endl; cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)remainder(Quad(y), Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(my, y, GMP_RNDN); mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif mpfr_remainder(mx, my, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5) { printf("\nquad remainder\n"); printf("ulp = %g\n", ulp); cout << "y = " << y << endl; cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { auto a = remquo(Quad(y), Quad(x)); uquad xfr = Quad(a.first).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(my, y, GMP_RNDN); mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif long int q = 0; mpfr_remquo(mx, &q, my, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5 || !eqquo(a.second, q)) { printf("\nquad remquo\n"); printf("ulp = %g\n", ulp); cout << "y = " << y << endl; cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << ", " << q << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << a.first << ", " << a.second << endl; cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_QUAD) && defined(TEST_CBRT) { quad_ r = (quad_)cbrt(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_cbrt(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad cbrt\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_QUAD) && defined(TEST_HYP) { quad_ r = (quad_)sinh(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_sinh(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad sinh\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)cosh(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_cosh(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad cosh\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)tanh(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_tanh(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad tanh\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)asinh(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_asinh(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad asinh\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)acosh(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_acosh(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad acosh\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)atanh(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_atanh(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad atanh\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_QUAD) && defined(TEST_ERF) { quad_ r = (quad_)erf(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_erf(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad erf\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)erfc(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_erfc(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad erfc\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_QUAD) && defined(TEST_GAMMA) { quad_ r = (quad_)tgamma(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_gamma(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501) { printf("\nquad tgamma\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } #if 0 { bool rsign = false; quad_ r = (quad_)lgamma(Quad(x), &rsign); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif int msign = 0; mpfr_lgamma(mx, &msign, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.501 || (msign == -1) != rsign) { printf("\nquad lgamma\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << ", sign = " << (msign == -1) << endl; #else cout << "c = " << to_string(mx, 72) << ", sign = " << (msign == -1) << endl; #endif cout << "r = " << r << ", sign = " << rsign << endl; cout << "NG" << endl; //exit(-1); } } #endif #endif #if defined(TEST_QUAD) && defined(TEST_MISC) { quad_ r = (quad_)fabs(Quad(x)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_abs(mx, mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5) { printf("\nquad fabs\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)copysign(Quad(x), Quad(y)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); mpfr_set_float128(my, y, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif mpfr_copysign(mx, mx, my, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5 && y == y) { printf("\nquad copysign\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)fmax(Quad(x), Quad(y)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); mpfr_set_float128(my, y, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif mpfr_max(mx, mx, my, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5) { printf("\nquad fmax\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)fmin(Quad(x), Quad(y)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); mpfr_set_float128(my, y, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif mpfr_min(mx, mx, my, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5) { printf("\nquad fmin\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { quad_ r = (quad_)fdim(Quad(x), Quad(y)); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); mpfr_set_float128(my, y, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, Quad(y).getUnpacked(), GMP_RNDN); #endif mpfr_dim(mx, mx, my, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(mx, GMP_RNDN); #endif double ulp = countULP(xfr, mx, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5) { printf("\nquad fdim\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; cout << "NG" << endl; exit(-1); } } { Quad w; quad_ r = (quad_)modf(Quad(x), &w); uquad xfr = Quad(r).getUnpacked(); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) mpfr_set_float128(mx, x, GMP_RNDN); #else mpfr_set_unpacked(mx, Quad(x).getUnpacked(), GMP_RNDN); #endif mpfr_modf(mx, my, mx, GMP_RNDN); double ci = mpfr_get_d(mx, GMP_RNDN); #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) quad_ c = mpfr_get_float128(my, GMP_RNDN); #endif double ulp = countULP(xfr, my, uquad::flt_true_min(), uquad::flt_max()); if (ulp > 0.5 || (!(isnan(w) && isnan(ci)) && double(w) != ci)) { printf("\nquad modf\n"); printf("ulp = %g\n", ulp); cout << "x = " << x << endl; #if defined(ENABLE_QUAD) && defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) cout << "c = " << c << endl; #else cout << "c = " << to_string(mx, 72) << endl; #endif cout << "r = " << r << endl; printf("ci = %.8g\n", ci); cout << "NG" << endl; exit(-1); } } #endif mpfr_clears(mx, my, mz, NULL); } } if ((i & 2047) == 0) { Octuple x = rndo(rng); Octuple y = rndo(rng); Octuple z = rndo(rng); { mpfr_set_default_prec(256); mpfr_set_emin(-100000000); mpfr_set_emax( 100000000); mpfr_t mx, my, mz; mpfr_inits(mx, my, mz, NULL); #if defined(TEST_OCTUPLE) && defined(TEST_ARITH) { uoctuple xfr = (Octuple(x) + Octuple(y)).getUnpacked(); Octuple r = Octuple(xfr); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_add(mx, mx, my, GMP_RNDN); double ulp = countULP(xfr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5) { printf("\noctuple add\n"); cout << "x = " << x << endl; cout << "y = " << y << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); exit(-1); } } { uoctuple xfr = (Octuple(x) * Octuple(y)).getUnpacked(); Octuple r = Octuple(xfr); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_mul(mx, mx, my, GMP_RNDN); double ulp = countULP(xfr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5) { printf("\noctuple mul\n"); cout << "x = " << x << endl; cout << "y = " << y << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); exit(-1); } } { uoctuple xfr = (Octuple(x) / Octuple(y)).getUnpacked(); Octuple r = Octuple(xfr); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_div(mx, mx, my, GMP_RNDN); double ulp = countULP(xfr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5) { printf("\noctuple div\n"); cout << "x = " << x << endl; cout << "y = " << y << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); exit(-1); } } { uoctuple xfr = fma(Octuple(x), Octuple(y), Octuple(z)).getUnpacked(); Octuple r = Octuple(xfr); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(mz, z.getUnpacked(), GMP_RNDN); mpfr_fma(mx, mx, my, mz, GMP_RNDN); double ulp = countULP(xfr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5) { printf("\noctuple fma\n"); cout << "x = " << x << endl; cout << "y = " << y << endl; cout << "z = " << z << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); exit(-1); } } #endif #if defined(TEST_OCTUPLE) && defined(TEST_SQRT) { uoctuple xcr = sqrt(Octuple(x)).getUnpacked().cast((const uoctuple *)nullptr); Octuple r = Octuple(xcr); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_sqrt(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5) { printf("\noctuple sqrt\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { uoctuple xcr = hypot(Octuple(x), Octuple(y)).getUnpacked().cast((const uoctuple *)nullptr); Octuple r = Octuple(xcr); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_hypot(mx, mx, my, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple hypot\n"); cout << "x = " << x << endl; cout << "y = " << y << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_OCTUPLE) && defined(TEST_TRIG) { Octuple r = sin(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_sin(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple sin\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = cos(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_cos(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple cos\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = tan(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_tan(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple tan\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #ifdef TLFLOAT_ENABLE_MPFR_SINPI { Octuple r = sinpi(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_sinpi(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple sinpi\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = cospi(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_cospi(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple cospi\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = tanpi(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_tanpi(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple tanpi\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #endif #if defined(TEST_OCTUPLE) && defined(TEST_INVTRIG) { Octuple r = atan2(Octuple(y), Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_atan2(mx, my, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple atan2\n"); cout << "y = " << to_string(y, 72) << endl; cout << "x = " << to_string(x, 72) << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = asin(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_asin(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple asin\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = acos(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_acos(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple acos\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = atan(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_atan(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple atan\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_OCTUPLE) && defined(TEST_EXP) { Octuple r = exp(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_exp(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple exp\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = expm1(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_expm1(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple expm1\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = exp2(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_exp2(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple exp2\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = exp10(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_exp10(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple exp10\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_OCTUPLE) && defined(TEST_LOG) { Octuple r = log(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_log(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple log\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = log1p(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_log1p(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple log1p\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = log2(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_log2(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple log2\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = log10(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_log10(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple log10\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_OCTUPLE) && defined(TEST_POW) { Octuple r = pow(Octuple(y), Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_pow(mx, my, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple pow\n"); cout << "y = " << to_string(y, 72) << endl; cout << "x = " << to_string(x, 72) << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_OCTUPLE) && defined(TEST_MODREM) { Octuple r = fmod(Octuple(y), Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_fmod(mx, my, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5) { printf("\noctuple fmod\n"); cout << "y = " << to_string(y, 72) << endl; cout << "x = " << to_string(x, 72) << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = remainder(Octuple(y), Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_remainder(mx, my, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5) { printf("\noctuple remainder\n"); cout << "y = " << to_string(y, 72) << endl; cout << "x = " << to_string(x, 72) << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { auto a = remquo(Octuple(y), Octuple(x)); uoctuple xcr = a.first.getUnpacked(); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); long int q = 0; mpfr_remquo(mx, &q, my, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5 || !eqquo(a.second, q)) { printf("\noctuple remquo\n"); cout << "y = " << to_string(y, 72) << endl; cout << "x = " << to_string(x, 72) << endl; cout << "c = " << to_string(mx, 72) << ", " << q << endl; cout << "r = " << to_string(a.first, 72) << " : " << to_string_d(Octuple(a.first).getUnpacked()) << ", " << a.second << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_OCTUPLE) && defined(TEST_CBRT) { Octuple r = cbrt(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_cbrt(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple cbrt\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_OCTUPLE) && defined(TEST_HYP) { Octuple r = sinh(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_sinh(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple sinh\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = cosh(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_cosh(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple cosh\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = tanh(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_tanh(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple tanh\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = asinh(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_asinh(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple asinh\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = acosh(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_acosh(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple acosh\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = atanh(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_atanh(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple atanh\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_OCTUPLE) && defined(TEST_ERF) { Octuple r = erf(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_erf(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple erf\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = erfc(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_erfc(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple erfc\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif #if defined(TEST_OCTUPLE) && defined(TEST_GAMMA) { Octuple r = tgamma(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_gamma(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002) { printf("\noctuple tgamma\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #if 0 { bool rsign = false; Octuple r = lgamma(Octuple(x), &rsign); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); int msign = 0; mpfr_lgamma(mx, &msign, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5002 || (msign == -1) != rsign) { printf("\noctuple lgamma\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << ", sign = " << (msign == -1) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << ", sign = " << rsign << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; //exit(-1); } } #endif #endif #if defined(TEST_OCTUPLE) && defined(TEST_MISC) { Octuple r = fabs(Octuple(x)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_abs(mx, mx, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5) { printf("\noctuple fabs\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = copysign(Octuple(x), Octuple(y)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_copysign(mx, mx, my, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5 && !isnan(y)) { printf("\noctuple copysign\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = fmax(Octuple(x), Octuple(y)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_max(mx, mx, my, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5) { printf("\noctuple fmax\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = fmin(Octuple(x), Octuple(y)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_min(mx, mx, my, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5) { printf("\noctuple fmin\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple r = fdim(Octuple(x), Octuple(y)); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(my, y.getUnpacked(), GMP_RNDN); mpfr_dim(mx, mx, my, GMP_RNDN); double ulp = countULP(xcr, mx, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5) { printf("\noctuple fdim\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } { Octuple w; Octuple r = modf(Octuple(x), &w); uoctuple xcr = r.getUnpacked(); mpfr_set_unpacked(mx, x.getUnpacked(), GMP_RNDN); mpfr_modf(mx, my, mx, GMP_RNDN); double ci = mpfr_get_d(mx, GMP_RNDN); double ulp = countULP(xcr, my, uoctuple::flt_true_min(), uoctuple::flt_max()); if (ulp > 0.5 || (!(isnan(w) && isnan(ci)) && double(w) != ci)) { printf("\noctuple modf\n"); cout << "x = " << x << endl; cout << "c = " << to_string(mx, 72) << endl; cout << "r = " << to_string(r , 72) << " : " << to_string_d(Octuple(r).getUnpacked()) << endl; printf("ci = %.8g\n", ci); printf("ulp = %g\n", ulp); cout << "NG" << endl; exit(-1); } } #endif mpfr_clears(mx, my, mz, NULL); } } } cout << "OK" << endl; exit(0); } tlfloat-1.15.0/src/tester/test_octuple.cpp000066400000000000000000000176351477036600700206040ustar00rootroot00000000000000#include #include #include "tlfloat/tlmath.hpp" #include "tlfloat/tlfloat.h" using namespace std; using namespace tlfloat; #if defined(__GLIBC__) static_assert(Double(const_M_E()) == M_E); static_assert(Double(const_M_E()) == M_E); static_assert(Double(const_M_LOG2E()) == M_LOG2E); static_assert(Double(const_M_LOG2E()) == M_LOG2E); static_assert(Double(const_M_LOG10E()) == M_LOG10E); static_assert(Double(const_M_LOG10E()) == M_LOG10E); static_assert(Double(const_M_LN2()) == M_LN2); static_assert(Double(const_M_LN2()) == M_LN2); static_assert(Double(const_M_PI()) == M_PI); static_assert(Double(const_M_PI()) == M_PI); static_assert(Double(const_M_PI(-1)) == M_PI_2); static_assert(Double(const_M_PI(-1)) == M_PI_2); static_assert(Double(const_M_PI(-2)) == M_PI_4); static_assert(Double(const_M_PI(-2)) == M_PI_4); static_assert(Double(const_M_1_PI()) == M_1_PI); static_assert(Double(const_M_1_PI()) == M_1_PI); static_assert(Double(const_M_1_PI(1)) == M_2_PI); static_assert(Double(const_M_1_PI(1)) == M_2_PI); static_assert(Double(const_M_1_SQRTPI(1)) == M_2_SQRTPI); static_assert(Double(const_M_1_SQRTPI(1)) == M_2_SQRTPI); #endif static_assert(Double(const_Euler()) == 0.5772156649015328606); static_assert(Double(const_Euler()) == 0.5772156649015328606); template T AGM(int N) { T y = sqrt(T(2.0)) - 1; T a = ldexp(y * y, 1); for(int k=0;k consteval T Machin() { return 4*(T("0x0.000000000000000000000000000000004p+132")*atan(T("0.2"))-atan(1/T("0x1de00000000000000000000000000000000p-129"))); } int main(int argc, char **argv) { char buf[1024]; // snprint(buf, sizeof(buf), AGM(1), 'g', 0, 5); printf("Half (AGM) : %s\n", buf); if (strncmp(buf, "3.1", 3) != 0) { printf("NG\n"); return -1; } // snprint(buf, sizeof(buf), Machin(), 'g', 0, 5); printf("Half (Machin) : %s\n", buf); if (strncmp(buf, "3.14", 4) != 0) { printf("NG\n"); return -1; } // tlfloat_snprintf(buf, sizeof(buf), "%.5_16g", const_M_PI()); printf("Half (const_M_PI()) : %s\n", buf); if (strncmp(buf, "3.14", 4) != 0) { printf("NG\n"); return -1; } // tlfloat_snprintf(buf, sizeof(buf), "%.5_16g", const_M_E()); printf("Half (const_M_E()) : %s\n", buf); if (strncmp(buf, "2.718", 5) != 0) { printf("NG\n"); return -1; } // snprint(buf, sizeof(buf), AGM(1), 'g', 0, 8); printf("Float (AGM) : %s\n", buf); if (strncmp(buf, "3.141592", 8) != 0) { printf("NG\n"); return -1; } // snprint(buf, sizeof(buf), Machin(), 'g', 0, 9); printf("Float (Machin) : %s\n", buf); if (strncmp(buf, "3.141592", 8) != 0) { printf("NG\n"); return -1; } // tlfloat_snprintf(buf, sizeof(buf), "%.16_64g", AGM(2)); printf("Double (AGM) : %s\n", buf); if (strncmp(buf, "3.141592653589", 14) != 0) { printf("NG\n"); return -1; } // snprint(buf, sizeof(buf), Machin(), 'g', 0, 16); printf("Double (Machin) : %s\n", buf); if (strncmp(buf, "3.141592653589", 14) != 0) { printf("NG\n"); return -1; } // tlfloat_snprintf(buf, sizeof(buf), "%.35_128g", AGM(2)); printf("Quad (AGM) : %s\n", buf); if (strncmp(buf, "3.14159265358979323846264338327950", 34) != 0) { printf("NG\n"); return -1; } // snprint(buf, sizeof(buf), Machin(), 'g', 0, 35); printf("Quad (Machin) : %s\n", buf); if (strncmp(buf, "3.14159265358979323846264338327950", 34) != 0) { printf("NG\n"); return -1; } // tlfloat_snprintf(buf, sizeof(buf), "%.37_128g", const_M_PI()); printf("Quad (const_M_PI()) : %s\n", buf); if (strncmp(buf, "3.141592653589793238462643383279502", 35) != 0) { printf("NG\n"); return -1; } // tlfloat_snprintf(buf, sizeof(buf), "%.37_128g", const_M_E()); printf("Quad (const_M_E()) : %s\n", buf); if (strncmp(buf, "2.718281828459045235360287471352662", 35) != 0) { printf("NG\n"); return -1; } // tlfloat_snprintf(buf, sizeof(buf), "%.72_256g", AGM(3)); printf("Octuple (AGM) : %s\n", buf); if (strncmp(buf, "3.14159265358979323846264338327950288419716939937510582097494459230781", 70) != 0) { printf("NG\n"); return -1; } // snprint(buf, sizeof(buf), Machin(), 'g', 0, 72); printf("Octuple (Machin) : %s\n", buf); if (strncmp(buf, "3.14159265358979323846264338327950288419716939937510582097494459230781", 70) != 0) { printf("NG\n"); return -1; } // tlfloat_snprintf(buf, sizeof(buf), "%.72_256g", const_M_PI()); printf("Octuple (const_M_PI()) : %s\n", buf); if (strncmp(buf, "3.14159265358979323846264338327950288419716939937510582097494459230781", 70) != 0) { printf("NG\n"); return -1; } // tlfloat_snprintf(buf, sizeof(buf), "%.72_256g", const_M_E()); printf("Octuple (const_M_E()) : %s\n", buf); if (strncmp(buf, "2.71828182845904523536028747135266249775724709369995957496696762772407", 70) != 0) { printf("NG\n"); return -1; } // if (fabs((double)Double(const_M_LN10()) - log(10)) > 1e-8 || fabs((double)Double(const_M_LN10()) - log(10)) > 1e-8) { printf("NG : const_M_LN10\n"); return -1; } if (sin(BFloat16("0.1")) != sincos(BFloat16("0.1")).first || cos(BFloat16("0.1")) != sincos(BFloat16("0.1")).second) { printf("NG : sincos(BFloat16)\n"); return -1; } if (sin(Half("0.1")) != sincos(Half("0.1")).first || cos(Half("0.1")) != sincos(Half("0.1")).second) { printf("NG : sincos(Half)\n"); return -1; } if (sin(Float("0.1")) != sincos(Float("0.1")).first || cos(Float("0.1")) != sincos(Float("0.1")).second) { printf("NG : sincos(Float)\n"); return -1; } if (sin(Double("0.1")) != sincos(Double("0.1")).first || cos(Double("0.1")) != sincos(Double("0.1")).second) { printf("NG : sincos(Double)\n"); return -1; } if (sin(Quad("0.1")) != sincos(Quad("0.1")).first || cos(Quad("0.1")) != sincos(Quad("0.1")).second) { printf("NG : sincos(Quad)\n"); return -1; } if (sin(Octuple("0.1")) != sincos(Octuple("0.1")).first || cos(Octuple("0.1")) != sincos(Octuple("0.1")).second) { printf("NG : sincos(Octuple)\n"); return -1; } if (sinpi(BFloat16("0.1")) != sincospi(BFloat16("0.1")).first || cospi(BFloat16("0.1")) != sincospi(BFloat16("0.1")).second) { printf("NG : sincospi(BFloat16)\n"); return -1; } if (sinpi(Half("0.1")) != sincospi(Half("0.1")).first || cospi(Half("0.1")) != sincospi(Half("0.1")).second) { printf("NG : sincospi(Half)\n"); return -1; } if (sinpi(Float("0.1")) != sincospi(Float("0.1")).first || cospi(Float("0.1")) != sincospi(Float("0.1")).second) { printf("NG : sincospi(Float)\n"); return -1; } if (sinpi(Double("0.1")) != sincospi(Double("0.1")).first || cospi(Double("0.1")) != sincospi(Double("0.1")).second) { printf("NG : sincospi(Double)\n"); return -1; } if (sinpi(Quad("0.1")) != sincospi(Quad("0.1")).first || cospi(Quad("0.1")) != sincospi(Quad("0.1")).second) { printf("NG : sincospi(Quad)\n"); return -1; } if (sinpi(Octuple("0.1")) != sincospi(Octuple("0.1")).first || cospi(Octuple("0.1")) != sincospi(Octuple("0.1")).second) { printf("NG : sincospi(Octuple)\n"); return -1; } // printf("OK\n"); return 0; } tlfloat-1.15.0/src/tester/test_octuple_dummy.c000066400000000000000000000000241477036600700214370ustar00rootroot00000000000000void donothing() {} tlfloat-1.15.0/src/tester/test_printf.cpp000066400000000000000000001023621477036600700204230ustar00rootroot00000000000000#include #include #include #include #include #include #include "tlfloat/tlfloat.hpp" #include "tlfloat/tlfloat.h" #include "testerutil.hpp" using namespace tlfloat; static const int test_widths[] = { -1, 0, 1, 2, 3, 4, 6, 8, 12, 16, 20, 32 }; static const int test_precs[] = { 0, 1, 2, 3, 4, 8, 12, 14 }; bool xisdigit(int c) { return '0' <= c && c <= '9'; } bool xisxdigit(int c) { return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); } int xtolower(int c) { if ('A' <= c && c <= 'Z') return c - 'A' + 'a'; else return c; } int xstrcmp(const char *p, const char *q, int prec) { for(;;) { if (*p == '\0' && *q == '\0') return 0; if (xtolower(*p) == 'e' || xtolower(*p) == 'p') prec = 10000; if (xisxdigit(*p) && xisxdigit(*q)) { if (prec > 0 && *p != *q) return *p > *q ? 1 : -1; prec--; } else if (*p != *q) { return *p > *q ? 1 : -1; } p++; q++; } } void doTest(const char *fmt, ...) { static char strt[1024], strc[1024]; va_list ap; va_start(ap, fmt); int rett = tlfloat_vsnprintf(strt, sizeof(strt), fmt, ap); va_end(ap); va_start(ap, fmt); int retc = vsnprintf(strc, sizeof(strc), fmt, ap); va_end(ap); if (rett != retc || strcmp(strt, strc) != 0) { printf("%s : c=[%s] t=[%s] retc=%d rett=%d\n", fmt, strc, strt, retc, rett); exit(-1); } } template void testem(double val, int cmpprec=10) { const char *types[] = { "e", "f", "g", "a" }; int nbits = sizeof(T) * 8; for(int i=0;i<4;i++) { for(int alt=0;alt<2;alt++) { for(int zero=0;zero<2;zero++) { for(int left=0;left<2;left++) { for(int blank=0;blank<2;blank++) { for(int sign=0;sign<2;sign++) { char fmt[120], corr0[120], corr1[120], test[120]; int lc0, lc1, lt; snprintf(fmt, 100, "%%%s%s%s%s%s%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); lc0 = snprintf(corr0, 100, fmt, val); lc1 = snprintf(corr1, 100, fmt, strtod(corr0, nullptr)); snprintf(fmt, 100, "%%%s%s%s%s%s_%d%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", nbits, types[i]); lt = tlfloat_snprintf(test, 8, fmt, T(val)); lt = tlfloat_snprintf(test, 100, fmt, T(val)); if( (lt != lc0 && lt != lc1) || (xstrcmp(test, corr0, cmpprec) != 0 && xstrcmp(test, corr1, cmpprec) != 0) || (strtod(corr0, NULL) != tlfloat_strtod(corr0, NULL) && strstr(corr0, "nan") == NULL) ) { printf("%s : c0=[%s] c1=[%s] t=[%s] lc0=%d lc1=%d lt=%d %g %g <%016llx>\n", fmt, corr0, corr1, test, lc0, lc1, lt, strtod(corr0, NULL), (double)tlfloat_strtod(corr0, NULL), std::bit_cast(val)); exit(-1); } for(unsigned w=0;w\n", fmt, corr0, corr1, test, lc0, lc1, lt, strtod(corr0, NULL), (double)tlfloat_strtod(corr0, NULL), std::bit_cast(val)); exit(-1); } // snprintf(fmt, 100, "%%%s%s%s%s%s*.%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); lc0 = snprintf(corr0, 100, fmt, width, val); lc1 = snprintf(corr1, 100, fmt, width, strtod(corr0, nullptr)); snprintf(fmt, 100, "%%%s%s%s%s%s*._%d%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", nbits, types[i]); lt = tlfloat_snprintf(test, 8, fmt, width, T(val)); lt = tlfloat_snprintf(test, 100, fmt, width, T(val)); if( (lt != lc0 && lt != lc1) || (xstrcmp(test, corr0, cmpprec) != 0 && xstrcmp(test, corr1, cmpprec) != 0) || (strtod(corr0, NULL) != tlfloat_strtod(corr0, NULL) && strstr(corr0, "nan") == NULL) ) { printf("%s : c0=[%s] c1=[%s] t=[%s] lc0=%d lc1=%d lt=%d %g %g <%016llx>\n", fmt, corr0, corr1, test, lc0, lc1, lt, strtod(corr0, NULL), (double)tlfloat_strtod(corr0, NULL), std::bit_cast(val)); exit(-1); } } for(unsigned p=0;p\n", fmt, corr0, corr1, test, lc0, lc1, lt, strtod(corr0, NULL), (double)tlfloat_strtod(corr0, NULL), std::bit_cast(val)); exit(-1); } // snprintf(fmt, 100, "%%%s%s%s%s%s*.*%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); lc0 = snprintf(corr0, 100, fmt, width, prec, val); lc1 = snprintf(corr1, 100, fmt, width, prec, strtod(corr0, nullptr)); snprintf(fmt, 100, "%%%s%s%s%s%s*.*_%d%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", nbits, types[i]); lt = tlfloat_snprintf(test, 8, fmt, width, prec, T(val)); lt = tlfloat_snprintf(test, 100, fmt, width, prec, T(val)); if( (lt != lc0 && lt != lc1) || (xstrcmp(test, corr0, cmpprec) != 0 && xstrcmp(test, corr1, cmpprec) != 0) || (strtod(corr0, NULL) != tlfloat_strtod(corr0, NULL) && strstr(corr0, "nan") == NULL) ) { printf("%s : c0=[%s] c1=[%s] t=[%s] lc0=%d lc1=%d lt=%d %g %g <%016llx>\n", fmt, corr0, corr1, test, lc0, lc1, lt, strtod(corr0, NULL), (double)tlfloat_strtod(corr0, NULL), std::bit_cast(val)); exit(-1); } } snprintf(fmt, 100, "%%%s%s%s%s%s.%d%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", prec, types[i]); lc0 = snprintf(corr0, 100, fmt, val); lc1 = snprintf(corr1, 100, fmt, strtod(corr0, nullptr)); snprintf(fmt, 100, "%%%s%s%s%s%s.%d_%d%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", prec, nbits, types[i]); lt = tlfloat_snprintf(test, 8, fmt, T(val)); lt = tlfloat_snprintf(test, 100, fmt, T(val)); if( (lt != lc0 && lt != lc1) || (xstrcmp(test, corr0, cmpprec) != 0 && xstrcmp(test, corr1, cmpprec) != 0) || (strtod(corr0, NULL) != tlfloat_strtod(corr0, NULL) && strstr(corr0, "nan") == NULL) ) { printf("%s : c0=[%s] c1=[%s] t=[%s] lc0=%d lc1=%d lt=%d %g %g <%016llx>\n", fmt, corr0, corr1, test, lc0, lc1, lt, strtod(corr0, NULL), (double)tlfloat_strtod(corr0, NULL), std::bit_cast(val)); exit(-1); } // snprintf(fmt, 100, "%%%s%s%s%s%s.*%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); lc0 = snprintf(corr0, 100, fmt, prec, val); lc1 = snprintf(corr1, 100, fmt, prec, strtod(corr0, nullptr)); snprintf(fmt, 100, "%%%s%s%s%s%s.*_%d%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", nbits, types[i]); lt = tlfloat_snprintf(test, 8, fmt, prec, T(val)); lt = tlfloat_snprintf(test, 100, fmt, prec, T(val)); if( (lt != lc0 && lt != lc1) || (xstrcmp(test, corr0, cmpprec) != 0 && xstrcmp(test, corr1, cmpprec) != 0) || (strtod(corr0, NULL) != tlfloat_strtod(corr0, NULL) && strstr(corr0, "nan") == NULL) ) { printf("%s : c0=[%s] c1=[%s] t=[%s] lc0=%d lc1=%d lt=%d %g %g <%016llx>\n", fmt, corr0, corr1, test, lc0, lc1, lt, strtod(corr0, NULL), (double)tlfloat_strtod(corr0, NULL), std::bit_cast(val)); exit(-1); } } } } } } } } } void testem32(int32_t val) { const char *types[] = { "d", "u", "x", "o" }; const int base[] = { 10, 10, 16, 8 }; for(int i=0;i<4;i++) { for(int alt=0;alt<2;alt++) { for(int zero=0;zero<2;zero++) { for(int left=0;left<2;left++) { for(int blank=0;blank<2;blank++) { for(int sign=0;sign<2;sign++) { char fmt[120], corr[120], test[120]; snprintf(fmt, 100, "%%%s%s%s%s%s%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); snprintf(corr, 100, fmt, val); snprintf(fmt, 100, "%%%s%s%s%s%s_32%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); tlfloat_snprintf(test, 8, fmt, val); tlfloat_snprintf(test, 100, fmt, val); if(strcmp(test,corr) != 0) { printf("%s : c=[%s] t=[%s]\n", fmt, corr, test); exit(-1); } { const char *tp = test; char *cp = test; if ((unsigned long long)BigUInt<7>(test, &tp, base[i]) != strtoull(test, &cp, base[i]) || tp != cp) { printf("%s : 0U t=%llu(%d) c=%llu(%d)\n", test, (unsigned long long)BigUInt<7>(test, nullptr, base[i]), int(tp-test), strtoull(test, nullptr, base[i]), int(cp-test)); exit(-1); } } { const char *tp = test; char *cp = test; if ((long long)BigInt<7>(test, &tp, base[i]) != strtoll(test, &cp, base[i]) || tp != cp) { printf("%s : 0S t=%lld(%d) c=%lld(%d)\n", test, (long long)BigInt<7>(test, nullptr, base[i]), int(tp-test), strtoll(test, nullptr, base[i]), int(cp-test)); exit(-1); } } // for(unsigned w=0;w(test, &tp, base[i]) != strtoull(test, &cp, base[i]) || tp != cp) { printf("%s : 0U t=%llu(%d) c=%llu(%d)\n", test, (unsigned long long)BigUInt<7>(test, nullptr, base[i]), int(tp-test), strtoull(test, nullptr, base[i]), int(cp-test)); exit(-1); } } { const char *tp = test; char *cp = test; if ((long long)BigInt<7>(test, &tp, base[i]) != strtoll(test, &cp, base[i]) || tp != cp) { printf("%s : 0S t=%lld(%d) c=%lld(%d)\n", test, (long long)BigInt<7>(test, nullptr, base[i]), int(tp-test), strtoll(test, nullptr, base[i]), int(cp-test)); exit(-1); } } // snprintf(fmt, 100, "%%%s%s%s%s%s*.%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); snprintf(corr, 100, fmt, width, val); snprintf(fmt, 100, "%%%s%s%s%s%s*._32%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); tlfloat_snprintf(test, 8, fmt, width, val); tlfloat_snprintf(test, 100, fmt, width, val); if(strcmp(test,corr) != 0) { printf("%s : c=[%s] t=[%s]\n", fmt, corr, test); exit(-1); } { const char *tp = test; char *cp = test; if ((unsigned long long)BigUInt<7>(test, &tp, base[i]) != strtoull(test, &cp, base[i]) || tp != cp) { printf("%s : 0U t=%llu(%d) c=%llu(%d)\n", test, (unsigned long long)BigUInt<7>(test, nullptr, base[i]), int(tp-test), strtoull(test, nullptr, base[i]), int(cp-test)); exit(-1); } } { const char *tp = test; char *cp = test; if ((long long)BigInt<7>(test, &tp, base[i]) != strtoll(test, &cp, base[i]) || tp != cp) { printf("%s : 0S t=%lld(%d) c=%lld(%d)\n", test, (long long)BigInt<7>(test, nullptr, base[i]), int(tp-test), strtoll(test, nullptr, base[i]), int(cp-test)); exit(-1); } } } for(int prec=4;prec<=12;prec += 1) { for(unsigned w=0;w(test, &tp, base[i]) != strtoull(test, &cp, base[i]) || tp != cp) { printf("%s : 0U t=%llu(%d) c=%llu(%d)\n", test, (unsigned long long)BigUInt<7>(test, nullptr, base[i]), int(tp-test), strtoull(test, nullptr, base[i]), int(cp-test)); exit(-1); } } { const char *tp = test; char *cp = test; if ((long long)BigInt<7>(test, &tp, base[i]) != strtoll(test, &cp, base[i]) || tp != cp) { printf("%s : 0S t=%lld(%d) c=%lld(%d)\n", test, (long long)BigInt<7>(test, nullptr, base[i]), int(tp-test), strtoll(test, nullptr, base[i]), int(cp-test)); exit(-1); } } // snprintf(fmt, 100, "%%%s%s%s%s%s*.*%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); snprintf(corr, 100, fmt, width, prec, val); snprintf(fmt, 100, "%%%s%s%s%s%s*.*_32%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); tlfloat_snprintf(test, 8, fmt, width, prec, val); tlfloat_snprintf(test, 100, fmt, width, prec, val); if(strcmp(test,corr) != 0) { printf("%s : c=[%s] t=[%s]\n", fmt, corr, test); exit(-1); } { const char *tp = test; char *cp = test; if ((unsigned long long)BigUInt<7>(test, &tp, base[i]) != strtoull(test, &cp, base[i]) || tp != cp) { printf("%s : 0U t=%llu(%d) c=%llu(%d)\n", test, (unsigned long long)BigUInt<7>(test, nullptr, base[i]), int(tp-test), strtoull(test, nullptr, base[i]), int(cp-test)); exit(-1); } } { const char *tp = test; char *cp = test; if ((long long)BigInt<7>(test, &tp, base[i]) != strtoll(test, &cp, base[i]) || tp != cp) { printf("%s : 0S t=%lld(%d) c=%lld(%d)\n", test, (long long)BigInt<7>(test, nullptr, base[i]), int(tp-test), strtoll(test, nullptr, base[i]), int(cp-test)); exit(-1); } } } snprintf(fmt, 100, "%%%s%s%s%s%s.%d%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", prec, types[i]); snprintf(corr, 100, fmt, val); snprintf(fmt, 100, "%%%s%s%s%s%s.%d_32%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", prec, types[i]); tlfloat_snprintf(test, 8, fmt, val); tlfloat_snprintf(test, 100, fmt, val); if(strcmp(test,corr) != 0) { printf("%s : c=[%s] t=[%s]\n", fmt, corr, test); exit(-1); } { const char *tp = test; char *cp = test; if ((unsigned long long)BigUInt<7>(test, &tp, base[i]) != strtoull(test, &cp, base[i]) || tp != cp) { printf("%s : 0U t=%llu(%d) c=%llu(%d)\n", test, (unsigned long long)BigUInt<7>(test, nullptr, base[i]), int(tp-test), strtoull(test, nullptr, base[i]), int(cp-test)); exit(-1); } } { const char *tp = test; char *cp = test; if ((long long)BigInt<7>(test, &tp, base[i]) != strtoll(test, &cp, base[i]) || tp != cp) { printf("%s : 0S t=%lld(%d) c=%lld(%d)\n", test, (long long)BigInt<7>(test, nullptr, base[i]), int(tp-test), strtoll(test, nullptr, base[i]), int(cp-test)); exit(-1); } } // snprintf(fmt, 100, "%%%s%s%s%s%s.*%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); snprintf(corr, 100, fmt, prec, val); snprintf(fmt, 100, "%%%s%s%s%s%s.*_32%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); tlfloat_snprintf(test, 8, fmt, prec, val); tlfloat_snprintf(test, 100, fmt, prec, val); if(strcmp(test,corr) != 0) { printf("%s : c=[%s] t=[%s]\n", fmt, corr, test); exit(-1); } { const char *tp = test; char *cp = test; if ((unsigned long long)BigUInt<7>(test, &tp, base[i]) != strtoull(test, &cp, base[i]) || tp != cp) { printf("%s : 0U t=%llu(%d) c=%llu(%d)\n", test, (unsigned long long)BigUInt<7>(test, nullptr, base[i]), int(tp-test), strtoull(test, nullptr, base[i]), int(cp-test)); exit(-1); } } { const char *tp = test; char *cp = test; if ((long long)BigInt<7>(test, &tp, base[i]) != strtoll(test, &cp, base[i]) || tp != cp) { printf("%s : 0S t=%lld(%d) c=%lld(%d)\n", test, (long long)BigInt<7>(test, nullptr, base[i]), int(tp-test), strtoll(test, nullptr, base[i]), int(cp-test)); exit(-1); } } } } } } } } } } void testem64(int64_t val) { const char *types[] = { "lld", "llu", "llx", "llo" }; const char *types2[] = { "d", "u", "x", "o" }; for(int i=0;i<4;i++) { for(int alt=0;alt<2;alt++) { for(int zero=0;zero<2;zero++) { for(int left=0;left<2;left++) { for(int blank=0;blank<2;blank++) { for(int sign=0;sign<2;sign++) { char fmt[120], corr[120], test[120]; snprintf(fmt, 90, "%%%s%s%s%s%s%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types[i]); snprintf(corr, 98, fmt, val); snprintf(fmt, 90, "%%%s%s%s%s%s_64%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types2[i]); tlfloat_snprintf(test, 8, fmt, val); tlfloat_snprintf(test, 98, fmt, val); if(strcmp(test,corr) != 0) { printf("%s : c=[%s] t=[%s]\n", fmt, corr, test); } for(unsigned w=0;w(val)); tlfloat_snprintf(test, 98, fmt, BigInt<7>(val)); if(strcmp(test,corr) != 0) { printf("%s : c=[%s] t=[%s]\n", fmt, corr, test); } #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 snprintf(fmt, 90, "%%%s%s%s%s%sQ%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", types2[i]); tlfloat_snprintf(test, 8, fmt, __int128_t(val)); tlfloat_snprintf(test, 98, fmt, __int128_t(val)); if(strcmp(test,corr) != 0) { printf("%s(__int128_t) : c=[%s] t=[%s]\n", fmt, corr, test); } #endif for(unsigned w=0;w(val)); tlfloat_snprintf(test, 98, fmt, BigInt<7>(val)); if(strcmp(test,corr) != 0) { printf("%s : c=[%s] t=[%s]\n", fmt, corr, test); exit(-1); } #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 snprintf(fmt, 90, "%%%s%s%s%s%s%d.Q%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", width, types2[i]); tlfloat_snprintf(test, 8, fmt, __int128_t(val)); tlfloat_snprintf(test, 98, fmt, __int128_t(val)); if(strcmp(test,corr) != 0) { printf("%s(__int128_t) : c=[%s] t=[%s]\n", fmt, corr, test); } #endif } for(int prec=0;prec<=12;prec += 2) { for(unsigned w=0;w(val)); tlfloat_snprintf(test, 98, fmt, BigInt<7>(val)); if(strcmp(test,corr) != 0) { printf("%s : c=[%s] t=[%s]\n", fmt, corr, test); exit(-1); } #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 snprintf(fmt, 90, "%%%s%s%s%s%s%d.%dQ%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", width, prec, types2[i]); tlfloat_snprintf(test, 8, fmt, __int128_t(val)); tlfloat_snprintf(test, 98, fmt, __int128_t(val)); if(strcmp(test,corr) != 0) { printf("%s(__int128_t) : c=[%s] t=[%s]\n", fmt, corr, test); } #endif } snprintf(fmt, 90, "%%%s%s%s%s%s.%d%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", prec, types[i]); snprintf(corr, 98, fmt, val); snprintf(fmt, 90, "%%%s%s%s%s%s.%d_128%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", prec, types2[i]); tlfloat_snprintf(test, 8, fmt, BigInt<7>(val)); tlfloat_snprintf(test, 98, fmt, BigInt<7>(val)); if(strcmp(test,corr) != 0) { printf("%s : c=[%s] t=[%s]\n", fmt, corr, test); exit(-1); } #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 snprintf(fmt, 90, "%%%s%s%s%s%s.%dQ%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", prec, types2[i]); tlfloat_snprintf(test, 8, fmt, __int128_t(val)); tlfloat_snprintf(test, 98, fmt, __int128_t(val)); if(strcmp(test,corr) != 0) { printf("%s(__int128_t) : c=[%s] t=[%s]\n", fmt, corr, test); } #endif } } } } } } } } using namespace std; int main(int argc, char **argv) { auto rng = createPreferredRNG(); int var; doTest("head %d [%*g] [%.*g] [%*.*g] %% %d tail", 123, 8, 100.1234567, 7, 101.1234567, 11, 9, 102.1234567, 321); doTest("head %d [%*d] [%.*d] [%*.*d] %%%d tail", 123, 8, 100, 7, 101, 11, 9, 102, 321); doTest("head %d [%*s] [%.*s] [%*.*s] %d%% tail", 123, 8, "abc", 7, "def", 11, 9, "ghi", 321); doTest("head %.8d %hhd %hd %d %ld %lld %jd %zd %td %.4d tail", 123, (signed char)1, (short int)2, (int)3, (long int)4, (long long int)5, (intmax_t)6, (size_t)7, (ptrdiff_t) 8, 321); doTest("head %.8d %hhd %hd %d %ld %lld %jd %zd %td %.4d tail", -123, (signed char)-1, (short int)-2, (int)-3, (long int)-4, (long long int)-5, (intmax_t)-6, (size_t)7, (ptrdiff_t)-8, -321); doTest("head %10.8d %hhi %hi %i %li %lli %ji %zi %ti %8.5d tail", 123, (signed char)1, (short int)2, (int)3, (long int)4, (long long int)5, (intmax_t)6, (size_t)7, (ptrdiff_t) 8, 321); doTest("head %10.8d %hhi %hi %i %li %lli %ji %zi %ti %8.5d tail", -123, (signed char)-1, (short int)-2, (int)-3, (long int)-4, (long long int)-5, (intmax_t)-6, (size_t)7, (ptrdiff_t)-8, -321); doTest("head %-10d %hhx %hx %x %lx %llx %jx %zx %tx %-10.9d tail", 123, (unsigned char)1, (short unsigned)2, (unsigned)3, (long unsigned)4, (long long unsigned)5, (uintmax_t)6, (size_t)7, (ptrdiff_t) 8, 321); doTest("head %+10d %hhX %hX %X %lX %llX %jX %zX %tX %+10.9d tail", 123, (unsigned char)1, (short unsigned)2, (unsigned)3, (long unsigned)4, (long long unsigned)5, (uintmax_t)6, (size_t)7, (ptrdiff_t) 8, 321); doTest("head %d %hhu %hu %u %lu %llu %ju %zu %tu %d tail", 123, (unsigned char)1, (short unsigned)2, (unsigned)3, (long unsigned)4, (long long unsigned)5, (uintmax_t)6, (size_t)7, (ptrdiff_t) 8, 321); doTest("head %d %hho %ho %o %lo %llo %jo %zo %to %d tail", 123, (unsigned char)1, (short unsigned)2, (unsigned)3, (long unsigned)4, (long long unsigned)5, (uintmax_t)6, (size_t)7, (ptrdiff_t) 8, 321); doTest("head %d %f %F %e %E %g %G %a %A %d tail", 123, 0.11, 0.21, 0.31, 0.41, 0.51, 0.61, 0.71, 0.81, 321); doTest("head %d %f %F %e %E %g %G %a %A %d tail", -123, -0.11, -0.21, -0.31, -0.41, -0.51, -0.61, -0.71, -0.81, -321); doTest("head %d %Lf %LF %Le %LE %Lg %LG %La %LA %d tail", 123, 0.11L, 0.21L, 0.31L, 0.41L, 0.51L, 0.61L, 0.71L, 0.81L, 321); doTest("head %d %Lf %LF %Le %LE %Lg %LG %La %LA %d tail", -123, -0.11L, -0.21L, -0.31L, -0.41L, -0.51L, -0.61L, -0.71L, -0.81L, -321); doTest("head %d %c %s %p %p %d tail", 123, 111, "string", NULL, &var, 321); doTest("head %d %c %s %p %p %d tail", -123, 111, "string", NULL, &var, -321); testem32(0); for(int i=0;i<31;i++) { testem32(+1 << i); testem32(-1 << i); } cout << "int32_t OK" << endl; testem64(0); for(int i=0;i<63;i++) { testem64(+1LL << i); testem64(-1LL << i); } cout << "int64_t OK" << endl; testem128(0); for(int i=0;i<63;i++) { testem128(+1LL << i); testem128(-1LL << i); } cout << "128bit int OK" << endl; testem(NAN, 5); testem(+0.0, 5); testem(-0.0, 5); testem(+INFINITY, 5); testem(-INFINITY, 5); testem(+1.0, 5); testem(-1.0, 5); cout << "Float OK" << endl; testem(NAN); testem(+0.0); testem(-0.0); testem(+INFINITY); testem(-INFINITY); testem(+1.0); testem(-1.0); testem(+0.1); testem(-0.1); testem(+1e+12); testem(-1e+12); testem(+1.234567890123456789e+12); testem(-1.234567890123456789e+12); testem(+1e-12); testem(-1e-12); testem(+1.234567890123456789e-12); testem(-1.234567890123456789e-12); testem(+1e+120); testem(-1e+120); testem(+1.234567890123456789e+120); testem(-1.234567890123456789e+120); testem(+1e-120); testem(-1e-120); testem(+1.234567890123456789e-120); testem(-1.234567890123456789e-120); cout << "Double OK" << endl; testem(NAN); testem(+0.0); testem(-0.0); testem(+INFINITY); testem(-INFINITY); testem(+1.0); testem(-1.0); testem(+0.1); testem(-0.1); testem(+1e+12); testem(-1e+12); testem(+1.234567890123456789e+12); testem(-1.234567890123456789e+12); testem(+1e-12); testem(-1e-12); testem(+1.234567890123456789e-12); testem(-1.234567890123456789e-12); testem(+1e+120); testem(-1e+120); testem(+1.234567890123456789e+120); testem(-1.234567890123456789e+120); testem(+1e-120); testem(-1e-120); testem(+1.234567890123456789e-120); testem(-1.234567890123456789e-120); for(int i=0;i<1000;i++) { static char str[1024]; Quad qc = rndQ(rng); tlfloat_snprintf(str, 8, "%.40_128g", qc); tlfloat_snprintf(str, sizeof(str), "%.40_128g", qc); Quad qt = tlfloat_strtoq(str, nullptr); if (!cmpq(qc, qt, 1)) { printf("Quad snprintf : %s\n", str); tlfloat_printf("qc = %.40_128g\n", qc); tlfloat_printf("qt = %.40_128g\n", qt); exit(-1); } } cout << "Quad OK" << endl; testem(NAN); testem(+0.0); testem(-0.0); testem(+INFINITY); testem(-INFINITY); testem(+1.0); testem(-1.0); testem(+0.1); testem(-0.1); testem(+1e+12); testem(-1e+12); testem(+1.234567890123456789e+12); testem(-1.234567890123456789e+12); testem(+1e-12); testem(-1e-12); testem(+1.234567890123456789e-12); testem(-1.234567890123456789e-12); testem(+1e+120); testem(-1e+120); testem(+1.234567890123456789e+120); testem(-1.234567890123456789e+120); testem(+1e-120); testem(-1e-120); testem(+1.234567890123456789e-120); testem(-1.234567890123456789e-120); for(int i=0;i<1000;i++) { static char str[1024]; Octuple oc = rndo(rng); tlfloat_snprintf(str, 8, "%.80_256g", oc); tlfloat_snprintf(str, sizeof(str), "%.80_256g", oc); Octuple ot = tlfloat_strtoo(str, nullptr); if (!cmpo(oc, ot, 1)) { printf("Octuple snprintf : %s\n", str); tlfloat_printf("oc = %.80_256g\n", oc); tlfloat_printf("ot = %.80_256g\n", ot); exit(-1); } } cout << "Octuple OK" << endl; cout << "OK" << endl; exit(0); } tlfloat-1.15.0/src/tester/test_printf_hash.cpp000066400000000000000000000404071477036600700214270ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "tlfloat/tlfloat.hpp" #include "tlfloat/tlfloat.h" #include "testerutil.hpp" using namespace tlfloat; FILE *fp = nullptr; auto sha256 = PSHA2_256_Internal(); static const int test_widths[] = { -1, 0, 1, 2, 3, 4, 6, 8, 12, 16, 20, 32 }; static const int test_precs[] = { 0, 1, 2, 3, 4, 8, 12, 14 }; void doTest(const char *fmt, ...) { static char strt[1024]; va_list ap; va_start(ap, fmt); int rett = tlfloat_vsnprintf(strt, sizeof(strt), fmt, ap); va_end(ap); sha256.appendWord((void *)&rett, sizeof(rett)); sha256.append((void *)strt, strlen(strt)+1); if (fp) { fwrite((void *)strt, strlen(strt), 1, fp); fputc((int)'\n', fp); } } template void testem(double val, int cmpprec=10) { const char *types[] = { "e", "f", "g", "a" }; int nbits = sizeof(T) * 8; for(int i=0;i<4;i++) { for(int alt=0;alt<2;alt++) { for(int zero=0;zero<2;zero++) { for(int left=0;left<2;left++) { for(int blank=0;blank<2;blank++) { for(int sign=0;sign<2;sign++) { char fmt[120], test[120]; int lt; snprintf(fmt, 100, "%%%s%s%s%s%s_%d%s", alt ? "#" : "", zero ? "0" : "", left ? "-" : "", blank ? " " : "", sign ? "+" : "", nbits, types[i]); lt = tlfloat_snprintf(test, 100, fmt, T(val)); sha256.appendWord((void *)<, sizeof(lt)); sha256.append((void *)test, strlen(test)+1); if (fp) { fwrite((void *)test, strlen(test), 1, fp); fputc((int)'\n', fp); } for(unsigned w=0;w(new LCG64(0)); int mode = 0; if (argc >= 3 && strcmp(argv[1], "w") == 0) { if (strcmp(argv[2], "-") == 0) { fp = stdout; } else { fp = fopen(argv[2], "wb"); if (!fp) { cerr << "Could not open " << argv[2] << endl; exit(-1); } } mode = 1; } for(int i=0;i<1000;i++) { doTest("%d %.20g %d", 123, rndd(rng), 321); doTest("%d %.40_128g %d", 123, rndQ(rng), 321); doTest("%d %.80_256g %d", 123, rndo(rng), 321); } doTest("head %d [%*g] [%.*g] [%*.*g] %d tail", 123, 8, 100.1234567, 7, 101.1234567, 11, 9, 102.1234567, 321); doTest("head %d [%*d] [%.*d] [%*.*d] %d tail", 123, 8, 100, 7, 101, 11, 9, 102, 321); doTest("head %d [%*s] [%.*s] [%*.*s] %d tail", 123, 8, "abc", 7, "def", 11, 9, "ghi", 321); doTest("head %.8d %hhd %hd %d %ld %lld %jd %zd %td %.4d tail", 123, (signed char)1, (short int)2, (int)3, (long int)4, (long long int)5, (intmax_t)6, (size_t)7, (ptrdiff_t) 8, 321); doTest("head %.8d %hhd %hd %d %ld %lld %jd %zd %td %.4d tail", -123, (signed char)-1, (short int)-2, (int)-3, (long int)-4, (long long int)-5, (intmax_t)-6, (size_t)7, (ptrdiff_t)-8, -321); doTest("head %10.8d %hhi %hi %i %li %lli %ji %zi %ti %8.5d tail", 123, (signed char)1, (short int)2, (int)3, (long int)4, (long long int)5, (intmax_t)6, (size_t)7, (ptrdiff_t) 8, 321); doTest("head %10.8d %hhi %hi %i %li %lli %ji %zi %ti %8.5d tail", -123, (signed char)-1, (short int)-2, (int)-3, (long int)-4, (long long int)-5, (intmax_t)-6, (size_t)7, (ptrdiff_t)-8, -321); doTest("head %-10d %hhx %hx %x %lx %llx %jx %zx %tx %-10.9d tail", 123, (unsigned char)1, (short unsigned)2, (unsigned)3, (long unsigned)4, (long long unsigned)5, (uintmax_t)6, (size_t)7, (ptrdiff_t) 8, 321); doTest("head %+10d %hhX %hX %X %lX %llX %jX %zX %tX %+10.9d tail", 123, (unsigned char)1, (short unsigned)2, (unsigned)3, (long unsigned)4, (long long unsigned)5, (uintmax_t)6, (size_t)7, (ptrdiff_t) 8, 321); doTest("head %d %hhu %hu %u %lu %llu %ju %zu %tu %d tail", 123, (unsigned char)1, (short unsigned)2, (unsigned)3, (long unsigned)4, (long long unsigned)5, (uintmax_t)6, (size_t)7, (ptrdiff_t) 8, 321); doTest("head %d %hho %ho %o %lo %llo %jo %zo %to %d tail", 123, (unsigned char)1, (short unsigned)2, (unsigned)3, (long unsigned)4, (long long unsigned)5, (uintmax_t)6, (size_t)7, (ptrdiff_t) 8, 321); doTest("head %d %f %F %e %E %g %G %a %A %d tail", 123, 0.11, 0.21, 0.31, 0.41, 0.51, 0.61, 0.71, 0.81, 321); doTest("head %d %f %F %e %E %g %G %a %A %d tail", -123, -0.11, -0.21, -0.31, -0.41, -0.51, -0.61, -0.71, -0.81, -321); testem32(0); for(int i=0;i<31;i++) { testem32(+1 << i); testem32(-1 << i); } testem64(0); for(int i=0;i<63;i++) { testem64(+1LL << i); testem64(-1LL << i); } double xnan = bit_cast(int64_t(-1)); testem(xnan, 5); testem(+0.0, 5); testem(-0.0, 5); testem(+INFINITY, 5); testem(-INFINITY, 5); testem(+1.0, 5); testem(-1.0, 5); testem(xnan); testem(+0.0); testem(-0.0); testem(+INFINITY); testem(-INFINITY); testem(+1.0); testem(-1.0); testem(+0.1); testem(-0.1); testem(+1e+12); testem(-1e+12); testem(+1.234567890123456789e+12); testem(-1.234567890123456789e+12); testem(+1e-12); testem(-1e-12); testem(+1.234567890123456789e-12); testem(-1.234567890123456789e-12); testem(+1e+120); testem(-1e+120); testem(+1.234567890123456789e+120); testem(-1.234567890123456789e+120); testem(+1e-120); testem(-1e-120); testem(+1.234567890123456789e-120); testem(-1.234567890123456789e-120); testem(xnan); testem(+0.0); testem(-0.0); testem(+INFINITY); testem(-INFINITY); testem(+1.0); testem(-1.0); testem(+0.1); testem(-0.1); testem(+1e+12); testem(-1e+12); testem(+1.234567890123456789e+12); testem(-1.234567890123456789e+12); testem(+1e-12); testem(-1e-12); testem(+1.234567890123456789e-12); testem(-1.234567890123456789e-12); testem(+1e+120); testem(-1e+120); testem(+1.234567890123456789e+120); testem(-1.234567890123456789e+120); testem(+1e-120); testem(-1e-120); testem(+1.234567890123456789e-120); testem(-1.234567890123456789e-120); testem(xnan); testem(+0.0); testem(-0.0); testem(+INFINITY); testem(-INFINITY); testem(+1.0); testem(-1.0); testem(+0.1); testem(-0.1); testem(+1e+12); testem(-1e+12); testem(+1.234567890123456789e+12); testem(-1.234567890123456789e+12); testem(+1e-12); testem(-1e-12); testem(+1.234567890123456789e-12); testem(-1.234567890123456789e-12); testem(+1e+120); testem(-1e+120); testem(+1.234567890123456789e+120); testem(-1.234567890123456789e+120); testem(+1e-120); testem(-1e-120); testem(+1.234567890123456789e-120); testem(-1.234567890123456789e-120); // if (mode == 0) { uint8_t h[32]; sha256.finalize_bytes(&h); if (argc == 1) { for(int i=0;i<32;i++) printf("%02x", h[i]); printf("\n"); } else { unsigned int a[32]; if (sscanf(argv[1], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", &a[ 0], &a[ 1], &a[ 2], &a[ 3], &a[ 4], &a[ 5], &a[ 6], &a[ 7], &a[ 8], &a[ 9], &a[10], &a[11], &a[12], &a[13], &a[14], &a[15], &a[16], &a[17], &a[18], &a[19], &a[20], &a[21], &a[22], &a[23], &a[24], &a[25], &a[26], &a[27], &a[28], &a[29], &a[30], &a[31]) != 32) { printf("NG (arg format)\n"); exit(-1); } for(int i=0;i<32;i++) { if (h[i] != a[i]) { printf("NG\n"); exit(-1); } } printf("OK\n"); } } exit(0); } tlfloat-1.15.0/src/tester/tester1.cpp000066400000000000000000000701551477036600700174550ustar00rootroot00000000000000#include #include #include #include #include #if defined(TLFLOAT_ENABLE_LIBQUADMATH) #include #endif #if defined(TLFLOAT_ENABLE_MPFR_WANT_FLOAT128) #define MPFR_WANT_FLOAT128 #endif #include #include "suppress.hpp" #include #include using namespace std; using namespace tlfloat; int mpfr_lgamma_(mpfr_t rop, const mpfr_t op, mpfr_rnd_t rnd) { int sign; return mpfr_lgamma(rop, &sign, op, rnd); } template using Func1 = T (*)(const T&); template using Func2 = T (*)(const T&, const T&); template using Func2i = xpair (*)(const T&, const T&); template using Func3 = T (*)(const T&, const T&, const T&); using MPFRFunc1 = int (*)(mpfr_t rop, const mpfr_t op, mpfr_rnd_t rnd); using MPFRFunc1NR = int (*)(mpfr_t rop, const mpfr_t op); using MPFRFunc2 = int (*)(mpfr_t rop, const mpfr_t op1, const mpfr_t op2, mpfr_rnd_t rnd); using MPFRFunc2i = int (*)(mpfr_t rop, long int *ip, const mpfr_t op1, const mpfr_t op2, mpfr_rnd_t rnd); using MPFRFunc3 = int (*)(mpfr_t rop, const mpfr_t op1, const mpfr_t op2, const mpfr_t op3, mpfr_rnd_t rnd); template static constexpr T fabs_(const T &a1) { return fabs(a1); } template static constexpr T copysign_(const T &a1, const T &a2) { return copysign(a1, a2); } template static constexpr T fmax_(const T &a1, const T &a2) { return fmax(a1, a2); } template static constexpr T fmin_(const T &a1, const T &a2) { return fmin(a1, a2); } template static constexpr T fdim_(const T &a1, const T &a2) { return fdim(a1, a2); } template static constexpr T add_(const T &a1, const T &a2) { return a1 + a2; } template static constexpr T sub_(const T &a1, const T &a2) { return a1 - a2; } template static constexpr T mul_(const T &a1, const T &a2) { return a1 * a2; } template static constexpr T div_(const T &a1, const T &a2) { return a1 / a2; } template static constexpr T fma_(const T &a1, const T &a2, const T &a3) { return fma(a1, a2, a3); } template static constexpr T sqrt_(const T &a) { return sqrt(a); } template static constexpr T hypot_(const T &a1, const T &a2) { return hypot(a1, a2); } template static constexpr T trunc_(const T &a) { return trunc(a); } template static constexpr T floor_(const T &a) { return floor(a); } template static constexpr T ceil_(const T &a) { return ceil(a); } template static constexpr T round_(const T &a) { return round(a); } template static constexpr T rint_(const T &a) { return rint(a); } template static constexpr T nextafter_(const T &a1, const T &a2) { return nextafter(a1, a2); } template static constexpr T lgamma_(const T &a1) { return lgamma(a1, nullptr); } template func, MPFRFunc1 mpfrFunc> void doTest(const char *mes, T a1, mpfr_t &mr, mpfr_t &ma1) { T r = func(a1); typedef decltype(r.getUnpacked()) Unpacked_t; mpfr_set_unpacked(ma1, a1.getUnpacked(), GMP_RNDN); mpfrFunc(mr, ma1, GMP_RNDN); double ulp = countULP(r.getUnpacked(), mr, Unpacked_t::flt_true_min(), Unpacked_t::flt_max(), fabs(double(a1)) < 2); if (ulp <= 1.0) return; cout << mes << endl; cout << "arg1 : " << to_string(a1, 72) << endl; cout << "tlfloat : " << to_string(r, 72) << endl; cout << "mpfr : " << to_string(mr, 72) << endl; exit(-1); } template func, MPFRFunc1NR mpfrFunc> void doTest(const char *mes, T a1, mpfr_t &mr, mpfr_t &ma1) { T r = func(a1); typedef decltype(r.getUnpacked()) Unpacked_t; mpfr_set_unpacked(ma1, a1.getUnpacked(), GMP_RNDN); mpfrFunc(mr, ma1); double ulp = countULP(r.getUnpacked(), mr, Unpacked_t::flt_true_min(), Unpacked_t::flt_max(), true); if (ulp <= 1.0) return; cout << mes << endl; cout << "arg1 : " << to_string(a1, 72) << endl; cout << "tlfloat : " << to_string(r, 72) << endl; cout << "mpfr : " << to_string(mr, 72) << endl; exit(-1); } template func, MPFRFunc2 mpfrFunc> void doTest(const char *mes, T a1, T a2, mpfr_t &mr, mpfr_t &ma1, mpfr_t &ma2, bool skipnan = false) { if (skipnan && isnan(a2)) return; T r = func(a1, a2); typedef decltype(r.getUnpacked()) Unpacked_t; mpfr_set_unpacked(ma1, a1.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(ma2, a2.getUnpacked(), GMP_RNDN); mpfrFunc(mr, ma1, ma2, GMP_RNDN); double ulp = countULP(r.getUnpacked(), mr, Unpacked_t::flt_true_min(), Unpacked_t::flt_max(), true); if (ulp <= 1.0) return; cout << mes << endl; cout << "arg1 : " << to_string(a1, 72) << endl; cout << "arg2 : " << to_string(a2, 72) << endl; cout << "tlfloat : " << to_string(r, 72) << endl; cout << "mpfr : " << to_string(mr, 72) << endl; exit(-1); } template func, MPFRFunc2i mpfrFunc> void doTest(const char *mes, T a1, T a2, mpfr_t &mr, mpfr_t &ma1, mpfr_t &ma2, bool skipnan = false) { if (skipnan && isnan(a2)) return; xpair r = func(a1, a2); typedef decltype(r.first.getUnpacked()) Unpacked_t; mpfr_set_unpacked(ma1, a1.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(ma2, a2.getUnpacked(), GMP_RNDN); long int mq = 0; mpfrFunc(mr, &mq, ma1, ma2, GMP_RNDN); double ulp = countULP(r.first.getUnpacked(), mr, Unpacked_t::flt_true_min(), Unpacked_t::flt_max(), true); if (ulp <= 0.5 && eqquo(r.second, mq)) return; cout << mes << endl; cout << "arg1 : " << to_string(a1, 72) << endl; cout << "arg2 : " << to_string(a2, 72) << endl; cout << "tlfloat : " << to_string(r.first, 72) << ", " << r.second << endl; printf("%016llx\n", (long long)r.second); cout << "mpfr : " << to_string(mr, 72) << ", " << mq << endl; printf("%016llx\n", (long long)mq); exit(-1); } template func, MPFRFunc3 mpfrFunc> void doTest(const char *mes, T a1, T a2, T a3, mpfr_t &mr, mpfr_t &ma1, mpfr_t &ma2, mpfr_t &ma3, bool skipnan = false) { if (skipnan && isnan(a2)) return; T r = func(a1, a2, a3); typedef decltype(r.getUnpacked()) Unpacked_t; mpfr_set_unpacked(ma1, a1.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(ma2, a2.getUnpacked(), GMP_RNDN); mpfr_set_unpacked(ma3, a3.getUnpacked(), GMP_RNDN); mpfrFunc(mr, ma1, ma2, ma3, GMP_RNDN); double ulp = countULP(r.getUnpacked(), mr, Unpacked_t::flt_true_min(), Unpacked_t::flt_max(), true); if (ulp <= 1.0) return; cout << mes << endl; cout << "arg1 : " << to_string(a1, 72) << endl; cout << "arg2 : " << to_string(a2, 72) << endl; cout << "tlfloat : " << to_string(r, 72) << endl; cout << "mpfr : " << to_string(mr, 72) << endl; exit(-1); } int main(int argc, char **argv) { int n = 100; if (argc >= 2) n = atoi(argv[1]); mpfr_set_default_prec(256); mpfr_t mr, ma1, ma2, ma3; mpfr_inits(mr, ma1, ma2, ma3, NULL); auto rng = createPreferredRNG(); vector hvalues = genTestValues(n, rng); vector fvalues = genTestValues(n, rng); vector dvalues = genTestValues(n, rng); vector qvalues = genTestValues(n, rng); vector ovalues = genTestValues(n, rng); int N = hvalues.size(); for(int index0 = 0;index0 < N;index0++) { doTest("Half fabs", hvalues[index0], mr, ma1); doTest("Float fabs", fvalues[index0], mr, ma1); doTest("Double fabs", dvalues[index0], mr, ma1); doTest("Quad fabs", qvalues[index0], mr, ma1); doTest("Octuple fabs", ovalues[index0], mr, ma1); doTest("Half sqrt", hvalues[index0], mr, ma1); doTest("Float sqrt", fvalues[index0], mr, ma1); doTest("Double sqrt", dvalues[index0], mr, ma1); doTest("Quad sqrt", qvalues[index0], mr, ma1); doTest("Octuple sqrt", ovalues[index0], mr, ma1); doTest("Half trunc", hvalues[index0], mr, ma1); doTest("Float trunc", fvalues[index0], mr, ma1); doTest("Double trunc", dvalues[index0], mr, ma1); doTest("Quad trunc", qvalues[index0], mr, ma1); doTest("Octuple trunc", ovalues[index0], mr, ma1); doTest("Half floor", hvalues[index0], mr, ma1); doTest("Float floor", fvalues[index0], mr, ma1); doTest("Double floor", dvalues[index0], mr, ma1); doTest("Quad floor", qvalues[index0], mr, ma1); doTest("Octuple floor", ovalues[index0], mr, ma1); doTest("Half ceil", hvalues[index0], mr, ma1); doTest("Float ceil", fvalues[index0], mr, ma1); doTest("Double ceil", dvalues[index0], mr, ma1); doTest("Quad ceil", qvalues[index0], mr, ma1); doTest("Octuple ceil", ovalues[index0], mr, ma1); doTest("Half round", hvalues[index0], mr, ma1); doTest("Float round", fvalues[index0], mr, ma1); doTest("Double round", dvalues[index0], mr, ma1); doTest("Quad round", qvalues[index0], mr, ma1); doTest("Octuple round", ovalues[index0], mr, ma1); doTest("Half rint", hvalues[index0], mr, ma1); doTest("Float rint", fvalues[index0], mr, ma1); doTest("Double rint", dvalues[index0], mr, ma1); doTest("Quad rint", qvalues[index0], mr, ma1); doTest("Octuple rint", ovalues[index0], mr, ma1); doTest("Half sin", hvalues[index0], mr, ma1); doTest("Float sin", fvalues[index0], mr, ma1); doTest("Double sin", dvalues[index0], mr, ma1); doTest("Quad sin", qvalues[index0], mr, ma1); doTest("Octuple sin", ovalues[index0], mr, ma1); doTest("Half cos", hvalues[index0], mr, ma1); doTest("Float cos", fvalues[index0], mr, ma1); doTest("Double cos", dvalues[index0], mr, ma1); doTest("Quad cos", qvalues[index0], mr, ma1); doTest("Octuple cos", ovalues[index0], mr, ma1); doTest("Half tan", hvalues[index0], mr, ma1); doTest("Float tan", fvalues[index0], mr, ma1); doTest("Double tan", dvalues[index0], mr, ma1); doTest("Quad tan", qvalues[index0], mr, ma1); doTest("Octuple tan", ovalues[index0], mr, ma1); #ifdef TLFLOAT_ENABLE_MPFR_SINPI doTest("Half sinpi", hvalues[index0], mr, ma1); doTest("Float sinpi", fvalues[index0], mr, ma1); doTest("Double sinpi", dvalues[index0], mr, ma1); doTest("Quad sinpi", qvalues[index0], mr, ma1); doTest("Octuple sinpi", ovalues[index0], mr, ma1); doTest("Half cospi", hvalues[index0], mr, ma1); doTest("Float cospi", fvalues[index0], mr, ma1); doTest("Double cospi", dvalues[index0], mr, ma1); doTest("Quad cospi", qvalues[index0], mr, ma1); doTest("Octuple cospi", ovalues[index0], mr, ma1); doTest("Half tanpi", hvalues[index0], mr, ma1); doTest("Float tanpi", fvalues[index0], mr, ma1); doTest("Double tanpi", dvalues[index0], mr, ma1); doTest("Quad tanpi", qvalues[index0], mr, ma1); doTest("Octuple tanpi", ovalues[index0], mr, ma1); #endif doTest("Half asin", hvalues[index0], mr, ma1); doTest("Float asin", fvalues[index0], mr, ma1); doTest("Double asin", dvalues[index0], mr, ma1); doTest("Quad asin", qvalues[index0], mr, ma1); doTest("Octuple asin", ovalues[index0], mr, ma1); doTest("Half acos", hvalues[index0], mr, ma1); doTest("Float acos", fvalues[index0], mr, ma1); doTest("Double acos", dvalues[index0], mr, ma1); doTest("Quad acos", qvalues[index0], mr, ma1); doTest("Octuple acos", ovalues[index0], mr, ma1); doTest("Half atan", hvalues[index0], mr, ma1); doTest("Float atan", fvalues[index0], mr, ma1); doTest("Double atan", dvalues[index0], mr, ma1); doTest("Quad atan", qvalues[index0], mr, ma1); doTest("Octuple atan", ovalues[index0], mr, ma1); doTest("Half log", hvalues[index0], mr, ma1); doTest("Float log", fvalues[index0], mr, ma1); doTest("Double log", dvalues[index0], mr, ma1); doTest("Quad log", qvalues[index0], mr, ma1); doTest("Octuple log", ovalues[index0], mr, ma1); doTest("Half log2", hvalues[index0], mr, ma1); doTest("Float log2", fvalues[index0], mr, ma1); doTest("Double log2", dvalues[index0], mr, ma1); doTest("Quad log2", qvalues[index0], mr, ma1); doTest("Octuple log2", ovalues[index0], mr, ma1); doTest("Half log10", hvalues[index0], mr, ma1); doTest("Float log10", fvalues[index0], mr, ma1); doTest("Double log10", dvalues[index0], mr, ma1); doTest("Quad log10", qvalues[index0], mr, ma1); doTest("Octuple log10", ovalues[index0], mr, ma1); doTest("Half log1p", hvalues[index0], mr, ma1); doTest("Float log1p", fvalues[index0], mr, ma1); doTest("Double log1p", dvalues[index0], mr, ma1); doTest("Quad log1p", qvalues[index0], mr, ma1); doTest("Octuple log1p", ovalues[index0], mr, ma1); doTest("Half exp", hvalues[index0], mr, ma1); doTest("Float exp", fvalues[index0], mr, ma1); doTest("Double exp", dvalues[index0], mr, ma1); doTest("Quad exp", qvalues[index0], mr, ma1); doTest("Octuple exp", ovalues[index0], mr, ma1); doTest("Half exp2", hvalues[index0], mr, ma1); doTest("Float exp2", fvalues[index0], mr, ma1); doTest("Double exp2", dvalues[index0], mr, ma1); doTest("Quad exp2", qvalues[index0], mr, ma1); doTest("Octuple exp2", ovalues[index0], mr, ma1); doTest("Half exp10", hvalues[index0], mr, ma1); doTest("Float exp10", fvalues[index0], mr, ma1); doTest("Double exp10", dvalues[index0], mr, ma1); doTest("Quad exp10", qvalues[index0], mr, ma1); doTest("Octuple exp10", ovalues[index0], mr, ma1); doTest("Half expm1", hvalues[index0], mr, ma1); doTest("Float expm1", fvalues[index0], mr, ma1); doTest("Double expm1", dvalues[index0], mr, ma1); doTest("Quad expm1", qvalues[index0], mr, ma1); doTest("Octuple expm1", ovalues[index0], mr, ma1); doTest("Half sinh", hvalues[index0], mr, ma1); doTest("Float sinh", fvalues[index0], mr, ma1); doTest("Double sinh", dvalues[index0], mr, ma1); doTest("Quad sinh", qvalues[index0], mr, ma1); doTest("Octuple sinh", ovalues[index0], mr, ma1); doTest("Half cosh", hvalues[index0], mr, ma1); doTest("Float cosh", fvalues[index0], mr, ma1); doTest("Double cosh", dvalues[index0], mr, ma1); doTest("Quad cosh", qvalues[index0], mr, ma1); doTest("Octuple cosh", ovalues[index0], mr, ma1); doTest("Half tanh", hvalues[index0], mr, ma1); doTest("Float tanh", fvalues[index0], mr, ma1); doTest("Double tanh", dvalues[index0], mr, ma1); doTest("Quad tanh", qvalues[index0], mr, ma1); doTest("Octuple tanh", ovalues[index0], mr, ma1); doTest("Half asinh", hvalues[index0], mr, ma1); doTest("Float asinh", fvalues[index0], mr, ma1); doTest("Double asinh", dvalues[index0], mr, ma1); doTest("Quad asinh", qvalues[index0], mr, ma1); doTest("Octuple asinh", ovalues[index0], mr, ma1); doTest("Half acosh", hvalues[index0], mr, ma1); doTest("Float acosh", fvalues[index0], mr, ma1); doTest("Double acosh", dvalues[index0], mr, ma1); doTest("Quad acosh", qvalues[index0], mr, ma1); doTest("Octuple acosh", ovalues[index0], mr, ma1); doTest("Half atanh", hvalues[index0], mr, ma1); doTest("Float atanh", fvalues[index0], mr, ma1); doTest("Double atanh", dvalues[index0], mr, ma1); doTest("Quad atanh", qvalues[index0], mr, ma1); doTest("Octuple atanh", ovalues[index0], mr, ma1); doTest("Half erf", hvalues[index0], mr, ma1); doTest("Float erf", fvalues[index0], mr, ma1); doTest("Double erf", dvalues[index0], mr, ma1); doTest("Quad erf", qvalues[index0], mr, ma1); doTest("Octuple erf", ovalues[index0], mr, ma1); doTest("Half erfc", hvalues[index0], mr, ma1); doTest("Float erfc", fvalues[index0], mr, ma1); doTest("Double erfc", dvalues[index0], mr, ma1); doTest("Quad erfc", qvalues[index0], mr, ma1); doTest("Octuple erfc", ovalues[index0], mr, ma1); doTest("Half tgamma", hvalues[index0], mr, ma1); doTest("Float tgamma", fvalues[index0], mr, ma1); doTest("Double tgamma", dvalues[index0], mr, ma1); doTest("Quad tgamma", qvalues[index0], mr, ma1); doTest("Octuple tgamma", ovalues[index0], mr, ma1); #if 0 doTest("Half lgamma", hvalues[index0], mr, ma1); doTest("Float lgamma", fvalues[index0], mr, ma1); doTest("Double lgamma", dvalues[index0], mr, ma1); doTest("Quad lgamma", qvalues[index0], mr, ma1); doTest("Octuple lgamma", ovalues[index0], mr, ma1); #endif for(int index1 = 0;index1 < N;index1++) { doTest("Half copysign", hvalues[index0], hvalues[index1], mr, ma1, ma2, true); doTest("Float copysign", fvalues[index0], fvalues[index1], mr, ma1, ma2, true); doTest("Double copysign", dvalues[index0], dvalues[index1], mr, ma1, ma2, true); doTest("Quad copysign", qvalues[index0], qvalues[index1], mr, ma1, ma2, true); doTest("Octuple copysign", ovalues[index0], ovalues[index1], mr, ma1, ma2, true); doTest("Half fdim", hvalues[index0], hvalues[index1], mr, ma1, ma2); doTest("Float fdim", fvalues[index0], fvalues[index1], mr, ma1, ma2); doTest("Double fdim", dvalues[index0], dvalues[index1], mr, ma1, ma2); doTest("Quad fdim", qvalues[index0], qvalues[index1], mr, ma1, ma2); doTest("Octuple fdim", ovalues[index0], ovalues[index1], mr, ma1, ma2); doTest("Half add", hvalues[index0], hvalues[index1], mr, ma1, ma2); doTest("Float add", fvalues[index0], fvalues[index1], mr, ma1, ma2); doTest("Double add", dvalues[index0], dvalues[index1], mr, ma1, ma2); doTest("Quad add", qvalues[index0], qvalues[index1], mr, ma1, ma2); doTest("Octuple add", ovalues[index0], ovalues[index1], mr, ma1, ma2); doTest("Half sub", hvalues[index0], hvalues[index1], mr, ma1, ma2); doTest("Float sub", fvalues[index0], fvalues[index1], mr, ma1, ma2); doTest("Double sub", dvalues[index0], dvalues[index1], mr, ma1, ma2); doTest("Quad sub", qvalues[index0], qvalues[index1], mr, ma1, ma2); doTest("Octuple sub", ovalues[index0], ovalues[index1], mr, ma1, ma2); doTest("Half mul", hvalues[index0], hvalues[index1], mr, ma1, ma2); doTest("Float mul", fvalues[index0], fvalues[index1], mr, ma1, ma2); doTest("Double mul", dvalues[index0], dvalues[index1], mr, ma1, ma2); doTest("Quad mul", qvalues[index0], qvalues[index1], mr, ma1, ma2); doTest("Octuple mul", ovalues[index0], ovalues[index1], mr, ma1, ma2); doTest("Half div", hvalues[index0], hvalues[index1], mr, ma1, ma2); doTest("Float div", fvalues[index0], fvalues[index1], mr, ma1, ma2); doTest("Double div", dvalues[index0], dvalues[index1], mr, ma1, ma2); doTest("Quad div", qvalues[index0], qvalues[index1], mr, ma1, ma2); doTest("Octuple div", ovalues[index0], ovalues[index1], mr, ma1, ma2); doTest("Half hypot", hvalues[index0], hvalues[index1], mr, ma1, ma2); doTest("Float hypot", fvalues[index0], fvalues[index1], mr, ma1, ma2); doTest("Double hypot", dvalues[index0], dvalues[index1], mr, ma1, ma2); doTest("Quad hypot", qvalues[index0], qvalues[index1], mr, ma1, ma2); doTest("Octuple hypot", ovalues[index0], ovalues[index1], mr, ma1, ma2); doTest("Half atan2", hvalues[index0], hvalues[index1], mr, ma1, ma2); doTest("Float atan2", fvalues[index0], fvalues[index1], mr, ma1, ma2); doTest("Double atan2", dvalues[index0], dvalues[index1], mr, ma1, ma2); doTest("Quad atan2", qvalues[index0], qvalues[index1], mr, ma1, ma2); doTest("Octuple atan2", ovalues[index0], ovalues[index1], mr, ma1, ma2); doTest("Half pow", hvalues[index0], hvalues[index1], mr, ma1, ma2); doTest("Float pow", fvalues[index0], fvalues[index1], mr, ma1, ma2); doTest("Double pow", dvalues[index0], dvalues[index1], mr, ma1, ma2); doTest("Quad pow", qvalues[index0], qvalues[index1], mr, ma1, ma2); doTest("Octuple pow", ovalues[index0], ovalues[index1], mr, ma1, ma2); doTest("Half fmod", hvalues[index0], hvalues[index1], mr, ma1, ma2); doTest("Float fmod", fvalues[index0], fvalues[index1], mr, ma1, ma2); doTest("Double fmod", dvalues[index0], dvalues[index1], mr, ma1, ma2); doTest("Quad fmod", qvalues[index0], qvalues[index1], mr, ma1, ma2); doTest("Octuple fmod", ovalues[index0], ovalues[index1], mr, ma1, ma2); doTest("Half remainder", hvalues[index0], hvalues[index1], mr, ma1, ma2); doTest("Float remainder", fvalues[index0], fvalues[index1], mr, ma1, ma2); doTest("Double remainder", dvalues[index0], dvalues[index1], mr, ma1, ma2); doTest("Quad remainder", qvalues[index0], qvalues[index1], mr, ma1, ma2); doTest("Octuple remainder", ovalues[index0], ovalues[index1], mr, ma1, ma2); #ifndef __i386__ doTest("Half remquo", hvalues[index0], hvalues[index1], mr, ma1, ma2); doTest("Float remquo", fvalues[index0], fvalues[index1], mr, ma1, ma2); doTest("Double remquo", dvalues[index0], dvalues[index1], mr, ma1, ma2); doTest("Quad remquo", qvalues[index0], qvalues[index1], mr, ma1, ma2); doTest("Octuple remquo", ovalues[index0], ovalues[index1], mr, ma1, ma2); #endif for(int index2 = 0;index2 < N;index2++) { doTest("Half fma", hvalues[index0], hvalues[index1], hvalues[index2], mr, ma1, ma2, ma3); doTest("Float fma", fvalues[index0], fvalues[index1], fvalues[index2], mr, ma1, ma2, ma3); doTest("Double fma", dvalues[index0], dvalues[index1], dvalues[index2], mr, ma1, ma2, ma3); doTest("Quad fma", qvalues[index0], qvalues[index1], qvalues[index2], mr, ma1, ma2, ma3); doTest("Octuple fma", ovalues[index0], ovalues[index1], ovalues[index2], mr, ma1, ma2, ma3); } } // { stringstream ssc, sst; ssc << (double)dvalues[index0] << endl; sst << dvalues[index0] << endl; if (ssc.str() != sst.str()) { cout << "NG 0 c = <" << ssc.str() << ">, t = <" << sst.str() << ">" << endl; exit(-1); } } { stringstream ssc, sst; ssc << setw(20) << (double)dvalues[index0] << endl; sst << setw(20) << dvalues[index0] << endl; if (ssc.str() != sst.str()) { cout << "NG 1 c = <" << ssc.str() << ">, t = <" << sst.str() << ">" << endl; exit(-1); } } { stringstream ssc, sst; ssc << setprecision(14) << (double)dvalues[index0] << endl; sst << setprecision(14) << dvalues[index0] << endl; if (ssc.str() != sst.str()) { cout << "NG 2 c = <" << ssc.str() << ">, t = <" << sst.str() << ">" << endl; exit(-1); } } { stringstream ssc, sst; ssc << setw(20) << right << (double)dvalues[index0] << endl; sst << setw(20) << right << dvalues[index0] << endl; if (ssc.str() != sst.str()) { cout << "NG 3 c = <" << ssc.str() << ">, t = <" << sst.str() << ">" << endl; exit(-1); } } } mpfr_clears(mr, ma1, ma2, ma3, NULL); cout << "OK" << endl; exit(0); } tlfloat-1.15.0/src/tlfloat/000077500000000000000000000000001477036600700155115ustar00rootroot00000000000000tlfloat-1.15.0/src/tlfloat/CMakeLists.txt000066400000000000000000000046771477036600700202670ustar00rootroot00000000000000if (BUILD_LIBS) add_library(tlfloat_inline OBJECT arith.cpp misc.cpp trig.cpp logexp.cpp invtrig.cpp hyp.cpp erfgamma.cpp) target_compile_options(tlfloat_inline PRIVATE ${NOEXCEPT_CXX_FLAGS}) if (ENABLE_INLINING AND "${LC_CMAKE_BUILD_TYPE}" STREQUAL "release") target_compile_options(tlfloat_inline PRIVATE ${INLINE_CXX_FLAGS}) target_compile_definitions(tlfloat_inline PRIVATE TLFLOAT_ENABLE_INLINING=1) endif() add_library(tlfloat printf.cpp) target_compile_options(tlfloat PRIVATE ${NOEXCEPT_CXX_FLAGS}) target_link_libraries(tlfloat PRIVATE tlfloat_inline) set(INCLUDEDIR "${PROJECT_SOURCE_DIR}/src/include") set(VERFILE "${PROJECT_BINARY_DIR}/include/tlfloat/tlfloatconfig.hpp") set_target_properties(tlfloat PROPERTIES VERSION ${TLFLOAT_VERSION} SOVERSION ${TLFLOAT_SOVERSION} PUBLIC_HEADER "${INCLUDEDIR}/tlfloat/bigint.hpp;${INCLUDEDIR}/tlfloat/rpitab.hpp;${INCLUDEDIR}/tlfloat/tlfloat.hpp;${INCLUDEDIR}/tlfloat/tlmath.hpp;${INCLUDEDIR}/tlfloat/tlmathcoef.hpp;${INCLUDEDIR}/tlfloat/tlfloat.h;${VERFILE}" ) install( TARGETS tlfloat tlfloat_inline EXPORT tlfloatTargets LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/tlfloat" COMPONENT tlfloat_Development ) else(BUILD_LIBS) set(INCLUDEDIR "${PROJECT_SOURCE_DIR}/src/include") set(VERFILE "${PROJECT_BINARY_DIR}/include/tlfloat/tlfloatconfig.hpp") install( FILES "${INCLUDEDIR}/tlfloat/bigint.hpp" "${INCLUDEDIR}/tlfloat/rpitab.hpp" "${INCLUDEDIR}/tlfloat/tlfloat.hpp" "${INCLUDEDIR}/tlfloat/tlmath.hpp" "${INCLUDEDIR}/tlfloat/tlmathcoef.hpp" "${INCLUDEDIR}/tlfloat/tlfloat.h" "${VERFILE}" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/tlfloat" ) endif(BUILD_LIBS) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tlfloat.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/tlfloat.pc" @ONLY) install( FILES "${CMAKE_CURRENT_BINARY_DIR}/tlfloat.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" COMPONENT tlfloat_Development ) if (FALSE) # Currently disabled because I still don't fully understand how this works configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/tlfloatConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/tlfloatConfig.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/tlfloat" ) install( FILES "${CMAKE_CURRENT_BINARY_DIR}/tlfloatConfig.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/tlfloat" COMPONENT tlfloat_Development ) endif() tlfloat-1.15.0/src/tlfloat/arith.cpp000066400000000000000000000263561477036600700173400ustar00rootroot00000000000000#include #include #include #include "suppress.hpp" #define TLFLOAT_NO_LIBSTDCXX #include "tlfloat/tlmath.hpp" #include "tlfloat/tlfloat.h" using namespace tlfloat; extern "C" { float tlfloat_addf(const float x, const float y) { return (float)(Float(x) + Float(y)); } double tlfloat_add(const double x, const double y) { return (double)(Double(x) + Double(y)); } tlfloat_quad_ tlfloat_addq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)(Quad(x) + Quad(y)); } tlfloat_octuple_ tlfloat_addo(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)(Octuple(x) + Octuple(y)); } float tlfloat_subf(const float x, const float y) { return (float)(Float(x) - Float(y)); } double tlfloat_sub(const double x, const double y) { return (double)(Double(x) - Double(y)); } tlfloat_quad_ tlfloat_subq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)(Quad(x) - Quad(y)); } tlfloat_octuple_ tlfloat_subo(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)(Octuple(x) - Octuple(y)); } float tlfloat_mulf(const float x, const float y) { return (float)(Float(x) * Float(y)); } double tlfloat_mul(const double x, const double y) { return (double)(Double(x) * Double(y)); } tlfloat_quad_ tlfloat_mulq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)(Quad(x) * Quad(y)); } tlfloat_octuple_ tlfloat_mulo(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)(Octuple(x) * Octuple(y)); } float tlfloat_divf(const float x, const float y) { return (float)(Float(x) / Float(y)); } double tlfloat_div(const double x, const double y) { return (double)(Double(x) / Double(y)); } tlfloat_quad_ tlfloat_divq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)(Quad(x) / Quad(y)); } tlfloat_octuple_ tlfloat_divo(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)(Octuple(x) / Octuple(y)); } float tlfloat_fmaf(const float x, const float y, const float z) { return (float)fma(Float(x), Float(y), Float(z)); } double tlfloat_fma(const double x, const double y, const double z) { return (double)fma(Double(x), Double(y), Double(z)); } tlfloat_quad_ tlfloat_fmaq(const tlfloat_quad_ x, const tlfloat_quad_ y, const tlfloat_quad_ z) { return (tlfloat_quad_)fma(Quad(x), Quad(y), Quad(z)); } tlfloat_octuple_ tlfloat_fmao(const tlfloat_octuple_ x, const tlfloat_octuple_ y, const tlfloat_octuple_ z) { return (tlfloat_octuple_)fma(Octuple(x), Octuple(y), Octuple(z)); } float tlfloat_sqrtf(const float x) { return (float)sqrt(Float(x)); } double tlfloat_sqrt(const double x) { return (double)sqrt(Double(x)); } tlfloat_quad_ tlfloat_sqrtq(const tlfloat_quad_ x) { return (tlfloat_quad_)sqrt(Quad(x)); } tlfloat_octuple_ tlfloat_sqrto(const tlfloat_octuple_ x) { return (tlfloat_octuple_)sqrt(Octuple(x)); } // float tlfloat_negf(const float x) { return (float)-Float(x); } double tlfloat_neg(const double x) { return (double)-Double(x); } tlfloat_quad_ tlfloat_negq(const tlfloat_quad_ x) { return (tlfloat_quad_)-Quad(x); } tlfloat_octuple_ tlfloat_nego(const tlfloat_octuple_ x) { return (tlfloat_octuple_)-Octuple(x); } float tlfloat_fabsf(const float x) { return (float)fabs(Float(x)); } double tlfloat_fabs(const double x) { return (double)fabs(Double(x)); } tlfloat_quad_ tlfloat_fabsq(const tlfloat_quad_ x) { return (tlfloat_quad_)fabs(Quad(x)); } tlfloat_octuple_ tlfloat_fabso(const tlfloat_octuple_ x) { return (tlfloat_octuple_)fabs(Octuple(x)); } float tlfloat_copysignf(const float x, const float y) { return (float)copysign(Float(x), Float(y)); } double tlfloat_copysign(const double x, const double y) { return (double)copysign(Double(x), Double(y)); } tlfloat_quad_ tlfloat_copysignq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)copysign(Quad(x), Quad(y)); } tlfloat_octuple_ tlfloat_copysigno(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)copysign(Octuple(x), Octuple(y)); } float tlfloat_fmaxf(const float x, const float y) { return (float)fmax(Float(x), Float(y)); } double tlfloat_fmax(const double x, const double y) { return (double)fmax(Double(x), Double(y)); } tlfloat_quad_ tlfloat_fmaxq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)fmax(Quad(x), Quad(y)); } tlfloat_octuple_ tlfloat_fmaxo(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)fmax(Octuple(x), Octuple(y)); } float tlfloat_fminf(const float x, const float y) { return (float)fmin(Float(x), Float(y)); } double tlfloat_fmin(const double x, const double y) { return (double)fmin(Double(x), Double(y)); } tlfloat_quad_ tlfloat_fminq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)fmin(Quad(x), Quad(y)); } tlfloat_octuple_ tlfloat_fmino(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)fmin(Octuple(x), Octuple(y)); } float tlfloat_fdimf(const float x, const float y) { return (float)fdim(Float(x), Float(y)); } double tlfloat_fdim(const double x, const double y) { return (double)fdim(Double(x), Double(y)); } tlfloat_quad_ tlfloat_fdimq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)fdim(Quad(x), Quad(y)); } tlfloat_octuple_ tlfloat_fdimo(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)fdim(Octuple(x), Octuple(y)); } float tlfloat_ldexpf(const float x, const int y) { return (float)ldexp(Float(x), y); } double tlfloat_ldexp(const double x, const int y) { return (double)ldexp(Double(x), y); } tlfloat_quad_ tlfloat_ldexpq(const tlfloat_quad_ x, const int y) { return (tlfloat_quad_)ldexp(Quad(x), y); } tlfloat_octuple_ tlfloat_ldexpo(const tlfloat_octuple_ x, const int y) { return (tlfloat_octuple_)ldexp(Octuple(x), y); } float tlfloat_frexpf(const float x, int *y) { return (float)frexp(Float(x), y); } double tlfloat_frexp(const double x, int *y) { return (double)frexp(Double(x), y); } tlfloat_quad_ tlfloat_frexpq(const tlfloat_quad_ x, int *y) { return (tlfloat_quad_)frexp(Quad(x), y); } tlfloat_octuple_ tlfloat_frexpo(const tlfloat_octuple_ x, int *y) { return (tlfloat_octuple_)frexp(Octuple(x), y); } float tlfloat_modff(const float x, float *y) { Float z; float r = (float)modf(Float(x), &z); *y = (float)z; return r; } double tlfloat_modf(const double x, double *y) { Double z; double r = (double)modf(Double(x), &z); *y = (double)z; return r; } tlfloat_quad_ tlfloat_modfq(const tlfloat_quad_ x, tlfloat_quad_ *y) { Quad z; tlfloat_quad_ r = (tlfloat_quad_)modf(Quad(x), &z); *y = (tlfloat_quad_)z; return r; } tlfloat_octuple_ tlfloat_modfo(const tlfloat_octuple_ x, tlfloat_octuple_ *y) { Octuple z; tlfloat_octuple_ r = (tlfloat_octuple_)modf(Octuple(x), &z); *y = (tlfloat_octuple_)z; return r; } float tlfloat_nextafterf(const float x, const float y) { return (float)nextafter(Float(x), Float(y)); } double tlfloat_nextafter(const double x, const double y) { return (double)nextafter(Double(x), Double(y)); } tlfloat_quad_ tlfloat_nextafterq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)nextafter(Quad(x), Quad(y)); } tlfloat_octuple_ tlfloat_nextaftero(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)nextafter(Octuple(x), Octuple(y)); } int tlfloat_ilogbf(const float x) { return ilogb(Float(x)); } int tlfloat_ilogb(const double x) { return ilogb(Double(x)); } int tlfloat_ilogbq(const tlfloat_quad_ x) { return ilogb(Quad(x)); } int tlfloat_ilogbo(const tlfloat_octuple_ x) { return ilogb(Octuple(x)); } int tlfloat_isnanf(const float x) { return isnan(Float(x)); } int tlfloat_isnan(const double x) { return isnan(Double(x)); } int tlfloat_isnanq(const tlfloat_quad_ x) { return isnan(Quad(x)); } int tlfloat_isnano(const tlfloat_octuple_ x) { return isnan(Octuple(x)); } int tlfloat_isinff(const float x) { return isinf(Float(x)); } int tlfloat_isinf(const double x) { return isinf(Double(x)); } int tlfloat_isinfq(const tlfloat_quad_ x) { return isinf(Quad(x)); } int tlfloat_isinfo(const tlfloat_octuple_ x) { return isinf(Octuple(x)); } int tlfloat_finitef(const float x) { return finite(Float(x)); } int tlfloat_finite(const double x) { return finite(Double(x)); } int tlfloat_finiteq(const tlfloat_quad_ x) { return finite(Quad(x)); } int tlfloat_finiteo(const tlfloat_octuple_ x) { return finite(Octuple(x)); } int tlfloat_fpclassifyf(const float x) { return fpclassify(Float(x)); } int tlfloat_fpclassify(const double x) { return fpclassify(Double(x)); } int tlfloat_fpclassifyq(const tlfloat_quad_ x) { return fpclassify(Quad(x)); } int tlfloat_fpclassifyo(const tlfloat_octuple_ x) { return fpclassify(Octuple(x)); } int tlfloat_signbitf(const float x) { return signbit(Float(x)); } int tlfloat_signbit(const double x) { return signbit(Double(x)); } int tlfloat_signbitq(const tlfloat_quad_ x) { return signbit(Quad(x)); } int tlfloat_signbito(const tlfloat_octuple_ x) { return signbit(Octuple(x)); } // float tlfloat_hypotf(const float x, const float y) { return (float)hypot(Float(x), Float(y)); } double tlfloat_hypot(const double x, const double y) { return (double)hypot(Double(x), Double(y)); } tlfloat_quad_ tlfloat_hypotq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)hypot(Quad(x), Quad(y)); } tlfloat_octuple_ tlfloat_hypoto(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)hypot(Octuple(x), Octuple(y)); } float tlfloat_truncf(const float x) { return (float)trunc(Float(x)); } double tlfloat_trunc(const double x) { return (double)trunc(Double(x)); } tlfloat_quad_ tlfloat_truncq(const tlfloat_quad_ x) { return (tlfloat_quad_)trunc(Quad(x)); } tlfloat_octuple_ tlfloat_trunco(const tlfloat_octuple_ x) { return (tlfloat_octuple_)trunc(Octuple(x)); } float tlfloat_floorf(const float x) { return (float)floor(Float(x)); } double tlfloat_floor(const double x) { return (double)floor(Double(x)); } tlfloat_quad_ tlfloat_floorq(const tlfloat_quad_ x) { return (tlfloat_quad_)floor(Quad(x)); } tlfloat_octuple_ tlfloat_flooro(const tlfloat_octuple_ x) { return (tlfloat_octuple_)floor(Octuple(x)); } float tlfloat_ceilf(const float x) { return (float)ceil(Float(x)); } double tlfloat_ceil(const double x) { return (double)ceil(Double(x)); } tlfloat_quad_ tlfloat_ceilq(const tlfloat_quad_ x) { return (tlfloat_quad_)ceil(Quad(x)); } tlfloat_octuple_ tlfloat_ceilo(const tlfloat_octuple_ x) { return (tlfloat_octuple_)ceil(Octuple(x)); } float tlfloat_roundf(const float x) { return (float)round(Float(x)); } double tlfloat_round(const double x) { return (double)round(Double(x)); } tlfloat_quad_ tlfloat_roundq(const tlfloat_quad_ x) { return (tlfloat_quad_)round(Quad(x)); } tlfloat_octuple_ tlfloat_roundo(const tlfloat_octuple_ x) { return (tlfloat_octuple_)round(Octuple(x)); } float tlfloat_rintf(const float x) { return (float)rint(Float(x)); } double tlfloat_rint(const double x) { return (double)rint(Double(x)); } tlfloat_quad_ tlfloat_rintq(const tlfloat_quad_ x) { return (tlfloat_quad_)rint(Quad(x)); } tlfloat_octuple_ tlfloat_rinto(const tlfloat_octuple_ x) { return (tlfloat_octuple_)rint(Octuple(x)); } } tlfloat-1.15.0/src/tlfloat/erfgamma.cpp000066400000000000000000000031241477036600700177740ustar00rootroot00000000000000#include #include #include #include "suppress.hpp" #define TLFLOAT_NO_LIBSTDCXX #include "tlfloat/tlmath.hpp" #include "tlfloat/tlfloat.h" using namespace tlfloat; extern "C" { float tlfloat_erff(const float a) { return (float)erf(Float(a)); } double tlfloat_erf(const double a) { return (double)erf(Double(a)); } tlfloat_quad_ tlfloat_erfq(const tlfloat_quad_ a) { return (tlfloat_quad_)erf(Quad(a)); } tlfloat_octuple_ tlfloat_erfo(const tlfloat_octuple_ a) { return (tlfloat_octuple_)erf(Octuple(a)); } float tlfloat_erfcf(const float a) { return (float)erfc(Float(a)); } double tlfloat_erfc(const double a) { return (double)erfc(Double(a)); } tlfloat_quad_ tlfloat_erfcq(const tlfloat_quad_ a) { return (tlfloat_quad_)erfc(Quad(a)); } tlfloat_octuple_ tlfloat_erfco(const tlfloat_octuple_ a) { return (tlfloat_octuple_)erfc(Octuple(a)); } float tlfloat_tgammaf(const float a) { return (float)tgamma(Float(a)); } double tlfloat_tgamma(const double a) { return (double)tgamma(Double(a)); } tlfloat_quad_ tlfloat_tgammaq(const tlfloat_quad_ a) { return (tlfloat_quad_)tgamma(Quad(a)); } tlfloat_octuple_ tlfloat_tgammao(const tlfloat_octuple_ a) { return (tlfloat_octuple_)tgamma(Octuple(a)); } float tlfloat_lgammaf(const float a) { return (float)lgamma(Float(a)); } double tlfloat_lgamma(const double a) { return (double)lgamma(Double(a)); } tlfloat_quad_ tlfloat_lgammaq(const tlfloat_quad_ a) { return (tlfloat_quad_)lgamma(Quad(a)); } tlfloat_octuple_ tlfloat_lgammao(const tlfloat_octuple_ a) { return (tlfloat_octuple_)lgamma(Octuple(a)); } } tlfloat-1.15.0/src/tlfloat/hyp.cpp000066400000000000000000000044101477036600700170140ustar00rootroot00000000000000#include #include #include #include "suppress.hpp" #define TLFLOAT_NO_LIBSTDCXX #include "tlfloat/tlmath.hpp" #include "tlfloat/tlfloat.h" using namespace tlfloat; extern "C" { float tlfloat_sinhf(const float x) { return (float)sinh(Float(x)); } double tlfloat_sinh(const double x) { return (double)sinh(Double(x)); } tlfloat_quad_ tlfloat_sinhq(const tlfloat_quad_ x) { return (tlfloat_quad_)sinh(Quad(x)); } tlfloat_octuple_ tlfloat_sinho(const tlfloat_octuple_ x) { return (tlfloat_octuple_)sinh(Octuple(x)); } float tlfloat_coshf(const float x) { return (float)cosh(Float(x)); } double tlfloat_cosh(const double x) { return (double)cosh(Double(x)); } tlfloat_quad_ tlfloat_coshq(const tlfloat_quad_ x) { return (tlfloat_quad_)cosh(Quad(x)); } tlfloat_octuple_ tlfloat_cosho(const tlfloat_octuple_ x) { return (tlfloat_octuple_)cosh(Octuple(x)); } float tlfloat_tanhf(const float x) { return (float)tanh(Float(x)); } double tlfloat_tanh(const double x) { return (double)tanh(Double(x)); } tlfloat_quad_ tlfloat_tanhq(const tlfloat_quad_ x) { return (tlfloat_quad_)tanh(Quad(x)); } tlfloat_octuple_ tlfloat_tanho(const tlfloat_octuple_ x) { return (tlfloat_octuple_)tanh(Octuple(x)); } float tlfloat_asinhf(const float x) { return (float)asinh(Float(x)); } double tlfloat_asinh(const double x) { return (double)asinh(Double(x)); } tlfloat_quad_ tlfloat_asinhq(const tlfloat_quad_ x) { return (tlfloat_quad_)asinh(Quad(x)); } tlfloat_octuple_ tlfloat_asinho(const tlfloat_octuple_ x) { return (tlfloat_octuple_)asinh(Octuple(x)); } float tlfloat_acoshf(const float x) { return (float)acosh(Float(x)); } double tlfloat_acosh(const double x) { return (double)acosh(Double(x)); } tlfloat_quad_ tlfloat_acoshq(const tlfloat_quad_ x) { return (tlfloat_quad_)acosh(Quad(x)); } tlfloat_octuple_ tlfloat_acosho(const tlfloat_octuple_ x) { return (tlfloat_octuple_)acosh(Octuple(x)); } float tlfloat_atanhf(const float x) { return (float)atanh(Float(x)); } double tlfloat_atanh(const double x) { return (double)atanh(Double(x)); } tlfloat_quad_ tlfloat_atanhq(const tlfloat_quad_ x) { return (tlfloat_quad_)atanh(Quad(x)); } tlfloat_octuple_ tlfloat_atanho(const tlfloat_octuple_ x) { return (tlfloat_octuple_)atanh(Octuple(x)); } } tlfloat-1.15.0/src/tlfloat/invtrig.cpp000066400000000000000000000032761477036600700177070ustar00rootroot00000000000000#include #include #include #include "suppress.hpp" #define TLFLOAT_NO_LIBSTDCXX #include "tlfloat/tlmath.hpp" #include "tlfloat/tlfloat.h" using namespace tlfloat; extern "C" { float tlfloat_asinf(const float x) { return (float)asin(Float(x)); } double tlfloat_asin(const double x) { return (double)asin(Double(x)); } tlfloat_quad_ tlfloat_asinq(const tlfloat_quad_ x) { return (tlfloat_quad_)asin(Quad(x)); } tlfloat_octuple_ tlfloat_asino(const tlfloat_octuple_ x) { return (tlfloat_octuple_)asin(Octuple(x)); } float tlfloat_acosf(const float x) { return (float)acos(Float(x)); } double tlfloat_acos(const double x) { return (double)acos(Double(x)); } tlfloat_quad_ tlfloat_acosq(const tlfloat_quad_ x) { return (tlfloat_quad_)acos(Quad(x)); } tlfloat_octuple_ tlfloat_acoso(const tlfloat_octuple_ x) { return (tlfloat_octuple_)acos(Octuple(x)); } float tlfloat_atanf(const float x) { return (float)atan(Float(x)); } double tlfloat_atan(const double x) { return (double)atan(Double(x)); } tlfloat_quad_ tlfloat_atanq(const tlfloat_quad_ x) { return (tlfloat_quad_)atan(Quad(x)); } tlfloat_octuple_ tlfloat_atano(const tlfloat_octuple_ x) { return (tlfloat_octuple_)atan(Octuple(x)); } float tlfloat_atan2f(const float y, const float x) { return (float)atan2(Float(y), Float(x)); } double tlfloat_atan2(const double y, const double x) { return (double)atan2(Double(y), Double(x)); } tlfloat_quad_ tlfloat_atan2q(const tlfloat_quad_ y, const tlfloat_quad_ x) { return (tlfloat_quad_)atan2(Quad(y), Quad(x)); } tlfloat_octuple_ tlfloat_atan2o(const tlfloat_octuple_ y, const tlfloat_octuple_ x) { return (tlfloat_octuple_)atan2(Octuple(y), Octuple(x)); } } tlfloat-1.15.0/src/tlfloat/logexp.cpp000066400000000000000000000066001477036600700175150ustar00rootroot00000000000000#include #include #include #include "suppress.hpp" #define TLFLOAT_NO_LIBSTDCXX #include "tlfloat/tlmath.hpp" #include "tlfloat/tlfloat.h" using namespace tlfloat; extern "C" { float tlfloat_expf(const float a) { return (float)exp(Float(a)); } double tlfloat_exp(const double a) { return (double)exp(Double(a)); } tlfloat_quad_ tlfloat_expq(const tlfloat_quad_ a) { return (tlfloat_quad_)exp(Quad(a)); } tlfloat_octuple_ tlfloat_expo(const tlfloat_octuple_ a) { return (tlfloat_octuple_)exp(Octuple(a)); } float tlfloat_expm1f(const float a) { return (float)expm1(Float(a)); } double tlfloat_expm1(const double a) { return (double)expm1(Double(a)); } tlfloat_quad_ tlfloat_expm1q(const tlfloat_quad_ a) { return (tlfloat_quad_)expm1(Quad(a)); } tlfloat_octuple_ tlfloat_expm1o(const tlfloat_octuple_ a) { return (tlfloat_octuple_)expm1(Octuple(a)); } float tlfloat_exp2f(const float a) { return (float)exp2(Float(a)); } double tlfloat_exp2(const double a) { return (double)exp2(Double(a)); } tlfloat_quad_ tlfloat_exp2q(const tlfloat_quad_ a) { return (tlfloat_quad_)exp2(Quad(a)); } tlfloat_octuple_ tlfloat_exp2o(const tlfloat_octuple_ a) { return (tlfloat_octuple_)exp2(Octuple(a)); } float tlfloat_exp10f(const float a) { return (float)exp10(Float(a)); } double tlfloat_exp10(const double a) { return (double)exp10(Double(a)); } tlfloat_quad_ tlfloat_exp10q(const tlfloat_quad_ a) { return (tlfloat_quad_)exp10(Quad(a)); } tlfloat_octuple_ tlfloat_exp10o(const tlfloat_octuple_ a) { return (tlfloat_octuple_)exp10(Octuple(a)); } float tlfloat_logf(const float a) { return (float)log(Float(a)); } double tlfloat_log(const double a) { return (double)log(Double(a)); } tlfloat_quad_ tlfloat_logq(const tlfloat_quad_ a) { return (tlfloat_quad_)log(Quad(a)); } tlfloat_octuple_ tlfloat_logo(const tlfloat_octuple_ a) { return (tlfloat_octuple_)log(Octuple(a)); } float tlfloat_log1pf(const float a) { return (float)log1p(Float(a)); } double tlfloat_log1p(const double a) { return (double)log1p(Double(a)); } tlfloat_quad_ tlfloat_log1pq(const tlfloat_quad_ a) { return (tlfloat_quad_)log1p(Quad(a)); } tlfloat_octuple_ tlfloat_log1po(const tlfloat_octuple_ a) { return (tlfloat_octuple_)log1p(Octuple(a)); } float tlfloat_log2f(const float a) { return (float)log2(Float(a)); } double tlfloat_log2(const double a) { return (double)log2(Double(a)); } tlfloat_quad_ tlfloat_log2q(const tlfloat_quad_ a) { return (tlfloat_quad_)log2(Quad(a)); } tlfloat_octuple_ tlfloat_log2o(const tlfloat_octuple_ a) { return (tlfloat_octuple_)log2(Octuple(a)); } float tlfloat_log10f(const float a) { return (float)log10(Float(a)); } double tlfloat_log10(const double a) { return (double)log10(Double(a)); } tlfloat_quad_ tlfloat_log10q(const tlfloat_quad_ a) { return (tlfloat_quad_)log10(Quad(a)); } tlfloat_octuple_ tlfloat_log10o(const tlfloat_octuple_ a) { return (tlfloat_octuple_)log10(Octuple(a)); } float tlfloat_powf(const float x, const float y) { return (float)pow(Float(x), Float(y)); } double tlfloat_pow(const double x, const double y) { return (double)pow(Double(x), Double(y)); } tlfloat_quad_ tlfloat_powq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)pow(Quad(x), Quad(y)); } tlfloat_octuple_ tlfloat_powo(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)pow(Octuple(x), Octuple(y)); } } tlfloat-1.15.0/src/tlfloat/misc.cpp000066400000000000000000000320361477036600700171540ustar00rootroot00000000000000#include #include #include #include "suppress.hpp" #define TLFLOAT_NO_LIBSTDCXX #include "tlfloat/tlmath.hpp" #include "tlfloat/tlfloat.h" using namespace tlfloat; extern "C" { uint64_t tlfloat_version() { return TLFLOAT_VERSION_MAJOR * 1000000ULL + TLFLOAT_VERSION_MINOR * 1000ULL + TLFLOAT_VERSION_PATCH; } // double tlfloat_cast_d_q(const tlfloat_quad_ x) { return (double)Double(Quad(x)); } double tlfloat_cast_d_o(const tlfloat_octuple_ x) { return (double)Double(Octuple(x)); } tlfloat_quad_ tlfloat_cast_q_d_(const double x) { return (tlfloat_quad_)Quad(Double(x)); } tlfloat_quad_ tlfloat_cast_q_o (const tlfloat_octuple_ x) { return (tlfloat_quad_)Quad(Octuple(x)); } tlfloat_octuple_ tlfloat_cast_o_d_(const double x) { return (tlfloat_octuple_)Octuple(Double(x)); } tlfloat_octuple_ tlfloat_cast_o_q (const tlfloat_quad_ x) { return (tlfloat_octuple_)Octuple(Quad(x)); } int64_t tlfloat_cast_i64_q(const tlfloat_quad_ x) { return (int64_t)Quad(x); } tlfloat_quad_ tlfloat_cast_q_i64_(const int64_t x) { return (tlfloat_quad_)Quad(x); } int64_t tlfloat_cast_i64_o(const tlfloat_octuple_ x) { return (int64_t)Octuple(x); } tlfloat_octuple_ tlfloat_cast_o_i64_(const int64_t x) { return (tlfloat_octuple_)Octuple(x); } uint64_t tlfloat_cast_u64_q(const tlfloat_quad_ x) { return (uint64_t)Quad(x); } tlfloat_quad_ tlfloat_cast_q_u64_(const uint64_t x) { return (tlfloat_quad_)Quad(x); } uint64_t tlfloat_cast_u64_o(const tlfloat_octuple_ x) { return (uint64_t)Octuple(x); } tlfloat_octuple_ tlfloat_cast_o_u64_(const uint64_t x) { return (tlfloat_octuple_)Octuple(x); } // int tlfloat_eq_q_q(const tlfloat_quad_ x, const tlfloat_quad_ y) { return Quad(x) == Quad(y); } int tlfloat_ne_q_q(const tlfloat_quad_ x, const tlfloat_quad_ y) { return Quad(x) != Quad(y); } int tlfloat_lt_q_q(const tlfloat_quad_ x, const tlfloat_quad_ y) { return Quad(x) < Quad(y); } int tlfloat_le_q_q(const tlfloat_quad_ x, const tlfloat_quad_ y) { return Quad(x) <= Quad(y); } int tlfloat_gt_q_q(const tlfloat_quad_ x, const tlfloat_quad_ y) { return Quad(x) > Quad(y); } int tlfloat_ge_q_q(const tlfloat_quad_ x, const tlfloat_quad_ y) { return Quad(x) >= Quad(y); } int tlfloat_eq_o_o(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return Octuple(x) == Octuple(y); } int tlfloat_ne_o_o(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return Octuple(x) != Octuple(y); } int tlfloat_lt_o_o(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return Octuple(x) < Octuple(y); } int tlfloat_le_o_o(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return Octuple(x) <= Octuple(y); } int tlfloat_gt_o_o(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return Octuple(x) > Octuple(y); } int tlfloat_ge_o_o(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return Octuple(x) >= Octuple(y); } // tlfloat_int128_t_ tlfloat_cast_i128_i64_(const int64_t x) { return std::bit_cast(BigInt<7>(x)); } int64_t tlfloat_cast_i64_i128(const tlfloat_int128_t_ x) { return (int64_t)std::bit_cast>(x); } tlfloat_uint128_t_ tlfloat_cast_u128_u64_(const uint64_t x) { return std::bit_cast(BigUInt<7>(x)); } uint64_t tlfloat_cast_u64_u128(const tlfloat_uint128_t_ x) { return (uint64_t)std::bit_cast>(x); } tlfloat_int128_t_ tlfloat_cast_i128_d_(const double x) { return std::bit_cast(BigInt<7>(x)); } double tlfloat_cast_d_i128(const tlfloat_int128_t_ x) { return (double)std::bit_cast>(x); } tlfloat_uint128_t_ tlfloat_cast_u128_d_(const double x) { return std::bit_cast(BigUInt<7>(x)); } double tlfloat_cast_d_u128(const tlfloat_uint128_t_ x) { return (double)std::bit_cast>(x); } tlfloat_int128_t_ tlfloat_cast_i128_q(const tlfloat_quad_ x) { return std::bit_cast(BigInt<7>((Quad)x)); } tlfloat_quad_ tlfloat_cast_q_i128(const tlfloat_int128_t_ x) { return (tlfloat_quad_)(Quad)std::bit_cast>(x); } tlfloat_uint128_t_ tlfloat_cast_u128_q(const tlfloat_quad_ x) { return std::bit_cast(BigUInt<7>((Quad)x)); } tlfloat_quad_ tlfloat_cast_q_u128(const tlfloat_uint128_t_ x) { return (tlfloat_quad_)(Quad)std::bit_cast>(x); } tlfloat_int128_t_ tlfloat_cast_i128_o(const tlfloat_octuple_ x) { return std::bit_cast(BigInt<7>((Octuple)x)); } tlfloat_octuple_ tlfloat_cast_o_i128(const tlfloat_int128_t_ x) { return (tlfloat_octuple_)(Octuple)std::bit_cast>(x); } tlfloat_uint128_t_ tlfloat_cast_u128_o(const tlfloat_octuple_ x) { return std::bit_cast(BigUInt<7>((Octuple)x)); } tlfloat_octuple_ tlfloat_cast_o_u128(const tlfloat_uint128_t_ x) { return (tlfloat_octuple_)(Octuple)std::bit_cast>(x); } int tlfloat_eq_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast>(x) == std::bit_cast>(y); } int tlfloat_ne_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast>(x) != std::bit_cast>(y); } int tlfloat_lt_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast>(x) < std::bit_cast>(y); } int tlfloat_le_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast>(x) <= std::bit_cast>(y); } int tlfloat_gt_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast>(x) > std::bit_cast>(y); } int tlfloat_ge_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast>(x) >= std::bit_cast>(y); } tlfloat_int128_t_ tlfloat_add_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast(std::bit_cast>(x) + std::bit_cast>(y)); } tlfloat_int128_t_ tlfloat_sub_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast(std::bit_cast>(x) - std::bit_cast>(y)); } tlfloat_int128_t_ tlfloat_mul_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast(std::bit_cast>(x) * std::bit_cast>(y)); } tlfloat_int128_t_ tlfloat_div_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast(std::bit_cast>(x) / std::bit_cast>(y)); } tlfloat_int128_t_ tlfloat_mod_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast(std::bit_cast>(x) % std::bit_cast>(y)); } tlfloat_int128_t_ tlfloat_and_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast(std::bit_cast>(x) & std::bit_cast>(y)); } tlfloat_int128_t_ tlfloat_or_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast(std::bit_cast>(x) | std::bit_cast>(y)); } tlfloat_int128_t_ tlfloat_xor_i128_i128(const tlfloat_int128_t_ x, const tlfloat_int128_t_ y) { return std::bit_cast(std::bit_cast>(x) ^ std::bit_cast>(y)); } tlfloat_int128_t_ tlfloat_not_i128(const tlfloat_int128_t_ x) { return std::bit_cast(~std::bit_cast>(x)); } tlfloat_int128_t_ tlfloat_shl_i128_i(const tlfloat_int128_t_ x, const int y) { return std::bit_cast(std::bit_cast>(x) << y); } tlfloat_int128_t_ tlfloat_shr_i128_i(const tlfloat_int128_t_ x, const int y) { return std::bit_cast(std::bit_cast>(x) >> y); } tlfloat_int128_t_ tlfloat_neg_i128(const tlfloat_int128_t_ x) { return std::bit_cast(-std::bit_cast>(x)); } int tlfloat_eq_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast>(x) == std::bit_cast>(y); } int tlfloat_ne_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast>(x) != std::bit_cast>(y); } int tlfloat_lt_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast>(x) < std::bit_cast>(y); } int tlfloat_le_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast>(x) <= std::bit_cast>(y); } int tlfloat_gt_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast>(x) > std::bit_cast>(y); } int tlfloat_ge_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast>(x) >= std::bit_cast>(y); } tlfloat_uint128_t_ tlfloat_add_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast(std::bit_cast>(x) + std::bit_cast>(y)); } tlfloat_uint128_t_ tlfloat_sub_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast(std::bit_cast>(x) - std::bit_cast>(y)); } tlfloat_uint128_t_ tlfloat_mul_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast(std::bit_cast>(x) * std::bit_cast>(y)); } tlfloat_uint128_t_ tlfloat_div_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast(std::bit_cast>(x) / std::bit_cast>(y)); } tlfloat_uint128_t_ tlfloat_mod_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast(std::bit_cast>(x) % std::bit_cast>(y)); } tlfloat_uint128_t_ tlfloat_and_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast(std::bit_cast>(x) & std::bit_cast>(y)); } tlfloat_uint128_t_ tlfloat_or_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast(std::bit_cast>(x) | std::bit_cast>(y)); } tlfloat_uint128_t_ tlfloat_xor_u128_u128(const tlfloat_uint128_t_ x, const tlfloat_uint128_t_ y) { return std::bit_cast(std::bit_cast>(x) ^ std::bit_cast>(y)); } tlfloat_uint128_t_ tlfloat_not_u128(const tlfloat_uint128_t_ x) { return std::bit_cast(~std::bit_cast>(x)); } tlfloat_uint128_t_ tlfloat_shl_u128_i(const tlfloat_uint128_t_ x, const int y) { return std::bit_cast(std::bit_cast>(x) << y); } tlfloat_uint128_t_ tlfloat_shr_u128_i(const tlfloat_uint128_t_ x, const int y) { return std::bit_cast(std::bit_cast>(x) >> y); } // float tlfloat_cbrtf(const float a) { return (float)cbrt(Float(a)); } double tlfloat_cbrt(const double a) { return (double)cbrt(Double(a)); } tlfloat_quad_ tlfloat_cbrtq(const tlfloat_quad_ a) { return (tlfloat_quad_)cbrt(Quad(a)); } tlfloat_octuple_ tlfloat_cbrto(const tlfloat_octuple_ a) { return (tlfloat_octuple_)cbrt(Octuple(a)); } float tlfloat_fmodf(const float x, const float y) { return (float)fmod(Float(x), Float(y)); } double tlfloat_fmod(const double x, const double y) { return (double)fmod(Double(x), Double(y)); } tlfloat_quad_ tlfloat_fmodq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)fmod(Quad(x), Quad(y)); } tlfloat_octuple_ tlfloat_fmodo(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)fmod(Octuple(x), Octuple(y)); } float tlfloat_remainderf(const float x, const float y) { return (float)remainder(Float(x), Float(y)); } double tlfloat_remainder(const double x, const double y) { return (double)remainder(Double(x), Double(y)); } tlfloat_quad_ tlfloat_remainderq(const tlfloat_quad_ x, const tlfloat_quad_ y) { return (tlfloat_quad_)remainder(Quad(x), Quad(y)); } tlfloat_octuple_ tlfloat_remaindero(const tlfloat_octuple_ x, const tlfloat_octuple_ y) { return (tlfloat_octuple_)remainder(Octuple(x), Octuple(y)); } float tlfloat_remquof(const float x, const float y, int *quo) { auto p = remquo(Float(x), Float(y)); if (quo) *quo = p.second & 0xffffffff; return (float)p.first; } double tlfloat_remquo(const double x, const double y, int *quo) { auto p = remquo(Double(x), Double(y)); if (quo) *quo = p.second & 0xffffffff; return (double)p.first; } tlfloat_quad_ tlfloat_remquoq(const tlfloat_quad_ x, const tlfloat_quad_ y, int *quo) { auto p = remquo(Quad(x), Quad(y)); if (quo) *quo = p.second & 0xffffffff; return (tlfloat_quad_)p.first; } tlfloat_octuple_ tlfloat_remquoo(const tlfloat_octuple_ x, const tlfloat_octuple_ y, int *quo) { auto p = remquo(Octuple(x), Octuple(y)); if (quo) *quo = p.second & 0xffffffff; return (tlfloat_octuple_)p.first; } } tlfloat-1.15.0/src/tlfloat/printf.cpp000066400000000000000000000430631477036600700175250ustar00rootroot00000000000000#include #include #include #include #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 14) #include #endif #include "suppress.hpp" #define TLFLOAT_NO_LIBSTDCXX #include "tlfloat/tlmath.hpp" #include "tlfloat/tlfloat.h" using namespace tlfloat; namespace { static int xvprintf(size_t (*consumer)(const char *ptr, size_t size, void *arg), void *arg, const char *fmt, va_list ap) { const int xbufsize = 5000; char *xbuf = (char *)calloc(xbufsize+10, 1); int outlen = 0; bool errorflag = false; while(*fmt != '\0' && !errorflag) { // Copy the format string until a '%' is read if (*fmt != '%') { do { outlen += (*consumer)(fmt++, 1, arg); } while(*fmt != '%' && *fmt != '\0'); if (*fmt == '\0') break; } const char *subfmtstart = fmt; if ((*++fmt) == '\0') { errorflag = true; outlen += (*consumer)("%", 1, arg); break; } if (*fmt == '%') { outlen += (*consumer)("%", 1, arg); fmt++; continue; } // Read flags bool flag_left = false, flag_sign = false, flag_blank = false; bool flag_alt = false, flag_zero = false, flag_upper = false, done = false; do { switch(*fmt) { case '-': flag_left = true; break; case '+': flag_sign = true; break; case ' ': flag_blank = true; break; case '#': flag_alt = true; break; case '0': flag_zero = true; break; default: done = true; break; } } while(!done && (*++fmt) != 0); // Read width int width = 0; bool readWidthFromArg = false; if (*fmt == '*') { readWidthFromArg = true; fmt++; } else { while(*fmt >= '0' && *fmt <= '9') { width = width*10 + *fmt - '0'; fmt++; } } // Read precision int precision = -1; bool readPrecFromArg = false; if (*fmt == '.') { precision = 0; fmt++; if (*fmt == '*') { readPrecFromArg = true; fmt++; } else { while(*fmt >= '0' && *fmt <= '9') { precision = precision*10 + *fmt - '0'; fmt++; } } } // Read size prefix bool subfmt_processed = false; int size_prefix = 0, nbits = 0; if (*fmt == '_') { char *eptr = NULL; nbits = strtol(fmt+1, &eptr, 10); if (eptr != fmt+1) { fmt = eptr; } else { nbits = 0; errorflag = true; } } else { int pl = 0; if (*fmt == 'h' || *fmt == 'l' || *fmt == 'j' || *fmt == 'z' || *fmt == 't' || *fmt == 'L' || *fmt == 'Q' || *fmt == 'P' || *fmt == 'O') { size_prefix = *fmt; pl = 1; } if ((*fmt == 'h' && *(fmt+1) == 'h') || (*fmt == 'l' && *(fmt+1) == 'l')) { size_prefix = *fmt + 256 * *(fmt+1); pl = 2; } fmt += pl; } // Call type-specific function va_list ap2; va_copy(ap2, ap); if (readWidthFromArg) width = va_arg(ap, int); if (width < 0) { width = -width; flag_left = true; } if (readPrecFromArg) precision = va_arg(ap, int); switch(*fmt) { case 'E': case 'F': case 'G': case 'A': flag_upper = true; // fall through case 'e': case 'f': case 'g': case 'a': { if (nbits == 0) { if (size_prefix == 'Q') { Quad value = std::bit_cast(va_arg(ap, tlfloat_quad_)); typedef decltype(decltype(value.getUnpacked())::xUnpackedFloat()) xUnpacked_t; int ret = snprint(xbuf, xbufsize, value.getUnpacked().cast((xUnpacked_t *)0), *fmt, width, precision, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; } else if (size_prefix == 'P') { Quad value = std::bit_cast(*(tlfloat_quad_ *)va_arg(ap, tlfloat_quad_ *)); typedef decltype(decltype(value.getUnpacked())::xUnpackedFloat()) xUnpacked_t; int ret = snprint(xbuf, xbufsize, value.getUnpacked().cast((xUnpacked_t *)0), *fmt, width, precision, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; } else if (size_prefix == 'O') { Octuple value = std::bit_cast(va_arg(ap, tlfloat_octuple_)); typedef decltype(decltype(value.getUnpacked())::xUnpackedFloat()) xUnpacked_t; int ret = snprint(xbuf, xbufsize, value.getUnpacked().cast((xUnpacked_t *)0), *fmt, width, precision, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; } else if (size_prefix == 0) { // double and long double va_arg(ap, double); } else if (size_prefix == 'L') { va_arg(ap, long double); } else errorflag = 1; } else { switch(nbits) { case 16: { typedef struct { uint16_t e; } arg_t; Half value = std::bit_cast(va_arg(ap, arg_t)); typedef decltype(decltype(value.getUnpacked())::xUnpackedFloat()) xUnpacked_t; int ret = snprint(xbuf, xbufsize, value.getUnpacked().cast((xUnpacked_t *)0), *fmt, width, precision, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; break; } case 32: { typedef struct { uint32_t e; } arg_t; Float value = std::bit_cast(va_arg(ap, arg_t)); typedef decltype(decltype(value.getUnpacked())::xUnpackedFloat()) xUnpacked_t; int ret = snprint(xbuf, xbufsize, value.getUnpacked().cast((xUnpacked_t *)0), *fmt, width, precision, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; break; } case 64: { typedef struct { uint64_t e[1]; } arg_t; Double value = std::bit_cast(va_arg(ap, arg_t)); typedef decltype(decltype(value.getUnpacked())::xUnpackedFloat()) xUnpacked_t; int ret = snprint(xbuf, xbufsize, value.getUnpacked().cast((xUnpacked_t *)0), *fmt, width, precision, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; break; } case 128: { typedef struct { uint64_t e[2]; } arg_t; Quad value = std::bit_cast(va_arg(ap, arg_t)); typedef decltype(decltype(value.getUnpacked())::xUnpackedFloat()) xUnpacked_t; int ret = snprint(xbuf, xbufsize, value.getUnpacked().cast((xUnpacked_t *)0), *fmt, width, precision, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; break; } case 256: { typedef struct { uint64_t e[4]; } arg_t; Octuple value = std::bit_cast(va_arg(ap, arg_t)); typedef decltype(decltype(value.getUnpacked())::xUnpackedFloat()) xUnpacked_t; int ret = snprint(xbuf, xbufsize, value.getUnpacked().cast((xUnpacked_t *)0), *fmt, width, precision, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; break; } default: errorflag = 1; break; } } } break; case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': { bool flag_unsigned = (*fmt == 'u') || (*fmt == 'o') || (*fmt == 'x') || (*fmt == 'X'); bool flag_ptr = false; if (*fmt == 'X') flag_upper = true; char const *prefix = ""; int base = 10; if (*fmt == 'o') { base = 8; prefix = "0"; } if (*fmt == 'x' || *fmt == 'X') { base = 16; prefix = flag_upper ? "0X" : "0x"; } if (nbits == 0) { if (size_prefix == 'Q') { #ifdef TLFLOAT_COMPILER_SUPPORTS_INT128 BigInt<7> value = std::bit_cast>(va_arg(ap, __int128_t)); #else BigInt<7> value = std::bit_cast>(va_arg(ap, tlfloat_int128_t_)); #endif int ret = BigInt<7>::snprint(xbuf, xbufsize, value, tolower(*fmt), width, precision, base, 1 << 7, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper, flag_unsigned, flag_ptr, prefix); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; } else { switch(size_prefix) { case 0: case 'h': case 'h' + 256*'h': va_arg(ap, int); break; case 'l': va_arg(ap, long int); break; case 'j': va_arg(ap, intmax_t); break; case 'z': va_arg(ap, size_t); break; case 't': va_arg(ap, std::ptrdiff_t); break; case 'l' + 256*'l': va_arg(ap, long long int); break; default: errorflag = 1; break; } } } else { switch(nbits) { case 8: case 16: case 32: case 64: { int64_t value = nbits == 64 ? va_arg(ap, int64_t) : va_arg(ap, int); int ret = BigInt<7>::snprint(xbuf, xbufsize, BigInt<7>(value), tolower(*fmt), width, precision, base, nbits, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper, flag_unsigned, flag_ptr, prefix); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; break; } case 128: { typedef struct { uint64_t e[2]; } arg_t; BigInt<7> value = std::bit_cast>(va_arg(ap, arg_t)); int ret = BigInt<7>::snprint(xbuf, xbufsize, value, tolower(*fmt), width, precision, base, nbits, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper, flag_unsigned, flag_ptr, prefix); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; break; } case 256: { typedef struct { uint64_t e[4]; } arg_t; BigInt<8> value = std::bit_cast>(va_arg(ap, arg_t)); int ret = BigInt<8>::snprint(xbuf, xbufsize, value, tolower(*fmt), width, precision, base, nbits, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper, flag_unsigned, flag_ptr, prefix); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; break; } case 512: { typedef struct { uint64_t e[8]; } arg_t; BigInt<9> value = std::bit_cast>(va_arg(ap, arg_t)); int ret = BigInt<9>::snprint(xbuf, xbufsize, value, tolower(*fmt), width, precision, base, nbits, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper, flag_unsigned, flag_ptr, prefix); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; break; } case 1024: { typedef struct { uint64_t e[16]; } arg_t; BigInt<10> value = std::bit_cast>(va_arg(ap, arg_t)); int ret = BigInt<10>::snprint(xbuf, xbufsize, value, tolower(*fmt), width, precision, base, nbits, flag_sign, flag_blank, flag_alt, flag_left, flag_zero, flag_upper, flag_unsigned, flag_ptr, prefix); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); subfmt_processed = true; break; } default: errorflag = 1; break; } } } break; case 'c': if (size_prefix == 0) { va_arg(ap, int); } else #if 0 if (size_prefix == 'l') { va_arg(ap, wint_t); // wint_t is not defined } else #endif errorflag = 1; break; case 's': if (size_prefix == 0 || size_prefix == 'l') { va_arg(ap, void *); } else errorflag = 1; break; case 'p': case 'n': { if ((*fmt == 'p' && size_prefix != 0) || size_prefix == 'L') { errorflag = 1; break; } va_arg(ap, void *); } break; default: errorflag = 1; } if (!subfmt_processed) { char *subfmt = (char *)calloc(fmt - subfmtstart + 2, 1); memcpy(subfmt, subfmtstart, fmt - subfmtstart + 1); subfmt[fmt - subfmtstart + 1] = 0; int ret = ::vsnprintf(xbuf, xbufsize, subfmt, ap2); free(subfmt); if (ret < 0) { errorflag = 1; break; } outlen += (*consumer)(xbuf, strlen(xbuf), arg); } fmt++; } free(xbuf); return errorflag ? -1 : outlen; } // struct stream_consumer_t { FILE *fp; }; static size_t stream_consumer(const char *ptr, size_t size, void *varg) { stream_consumer_t *arg = (stream_consumer_t *)varg; return fwrite(ptr, size, 1, arg->fp); } struct buf_consumer_t { char *buf; size_t pos, size; }; static size_t buf_consumer(const char *ptr, size_t size, void *varg) { buf_consumer_t *arg = (buf_consumer_t *)varg; size_t p = 0; while(p < size) { if (arg->pos >= arg->size - 1) break; arg->buf[arg->pos++] = ptr[p++]; } arg->buf[arg->pos] = '\0'; return size; } } // namespace extern "C" { int tlfloat_vfprintf(FILE *fp, const char *fmt, va_list ap) { stream_consumer_t arg = { fp }; return xvprintf(stream_consumer, &arg, fmt, ap); } int tlfloat_vprintf(const char *fmt, va_list ap) { return tlfloat_vfprintf(stdout, fmt, ap); } int tlfloat_fprintf(FILE *fp, const char *fmt, ...) { va_list ap; va_start(ap, fmt); int ret = tlfloat_vfprintf(fp, fmt, ap); va_end(ap); return ret; } int tlfloat_printf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); int ret = tlfloat_vfprintf(stdout, fmt, ap); va_end(ap); return ret; } int tlfloat_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { buf_consumer_t arg = { str, 0, size }; return xvprintf(buf_consumer, &arg, fmt, ap); } int tlfloat_snprintf(char *str, size_t size, const char *fmt, ...) { va_list ap; va_start(ap, fmt); int ret = tlfloat_vsnprintf(str, size, fmt, ap); va_end(ap); return ret; } // float tlfloat_strtof(const char *nptr, const char **endptr) { return (float)Float(nptr, endptr); } double tlfloat_strtod(const char *nptr, const char **endptr) { return (double)Double(nptr, endptr); } tlfloat_quad_ tlfloat_strtoq_(const char *nptr, const char **endptr) { return (tlfloat_quad_)Quad(nptr, endptr); } tlfloat_octuple_ tlfloat_strtoo_(const char *nptr, const char **endptr) { return (tlfloat_octuple_)Octuple(nptr, endptr); } // tlfloat_int128_t_ tlfloat_strtoi128(const char *nptr, const char **endptr, const int base) { BigInt<7> b = BigInt<7>(nptr, endptr, base); tlfloat_int128_t_ r; memcpy(&r, &b, sizeof(r)); return r; } tlfloat_uint128_t_ tlfloat_strtou128(const char *nptr, const char **endptr, const int base) { BigUInt<7> b = BigUInt<7>(nptr, endptr, base); tlfloat_uint128_t_ r; memcpy(&r, &b, sizeof(r)); return r; } #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 14) static int pa_quad = -1; static int printf_Qmodifier = -1, printf_Pmodifier = -1; static void tlfloat_quad_va(void *ptr, va_list *ap) { *(tlfloat_quad *)ptr = va_arg(*ap, tlfloat_quad_); } static int printf_arginfo(const struct printf_info *info, size_t n, int *argtypes, int *s) { if (info->user & printf_Qmodifier) { argtypes[0] = pa_quad; return 1; } else if (info->user & printf_Pmodifier) { argtypes[0] = PA_FLAG_PTR | pa_quad; return 1; } return -1; } static int printf_output(FILE *fp, const struct printf_info *info, const void *const *args) { if (!(info->user & printf_Qmodifier || info->user & printf_Pmodifier)) return -2; const int XBUFSIZE = 1000; char *xbuf = (char *)malloc(XBUFSIZE+10); int len = -1; len = snprint(xbuf, XBUFSIZE, Quad(**(const tlfloat_quad **)args[0]).getUnpacked(), tolower(info->spec), info->width, info->prec, info->showsign, info->space, info->alt, info->left, false, isupper(info->spec)); size_t wlen = fwrite(xbuf, 1, len, fp); free(xbuf); return (int)wlen; } #endif // #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 14) } #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 14) extern "C" { int tlfloat_registerPrintfHook() { if ((printf_Qmodifier = register_printf_modifier(L"Q")) == -1) return -1; if ((printf_Pmodifier = register_printf_modifier(L"P")) == -1) return -1; pa_quad = register_printf_type(tlfloat_quad_va); if (pa_quad == -1) return -2; if (register_printf_specifier('a', printf_output, printf_arginfo)) return -3; if (register_printf_specifier('e', printf_output, printf_arginfo)) return -4; if (register_printf_specifier('f', printf_output, printf_arginfo)) return -5; if (register_printf_specifier('g', printf_output, printf_arginfo)) return -6; if (register_printf_specifier('A', printf_output, printf_arginfo)) return -7; if (register_printf_specifier('E', printf_output, printf_arginfo)) return -8; if (register_printf_specifier('F', printf_output, printf_arginfo)) return -9; if (register_printf_specifier('G', printf_output, printf_arginfo)) return -10; return 0; } void tlfloat_unregisterPrintfHook() { register_printf_specifier('a', NULL, NULL); register_printf_specifier('e', NULL, NULL); register_printf_specifier('f', NULL, NULL); register_printf_specifier('g', NULL, NULL); register_printf_specifier('A', NULL, NULL); register_printf_specifier('E', NULL, NULL); register_printf_specifier('F', NULL, NULL); register_printf_specifier('G', NULL, NULL); } } #endif // #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 14) tlfloat-1.15.0/src/tlfloat/tlfloat.pc.in000066400000000000000000000004121477036600700201040ustar00rootroot00000000000000prefix=@CMAKE_INSTALL_PREFIX@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: TLFloat Description: C++ template library for floating point operations Version: @TLFLOAT_VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -ltlfloat tlfloat-1.15.0/src/tlfloat/tlfloatConfig.cmake.in000066400000000000000000000001731477036600700217140ustar00rootroot00000000000000@PACKAGE_INIT@ set(TLFLOAT_INCLUDE_DIR "@CMAKE_INSTALL_PREFIX@/include") set(TLFLOAT_LIB_DIR "@CMAKE_INSTALL_PREFIX@/lib") tlfloat-1.15.0/src/tlfloat/trig.cpp000066400000000000000000000070341477036600700171660ustar00rootroot00000000000000#include #include #include #include "suppress.hpp" #define TLFLOAT_NO_LIBSTDCXX #include "tlfloat/tlmath.hpp" #include "tlfloat/tlfloat.h" using namespace tlfloat; extern "C" { float tlfloat_sinf(const float x) { return (float)sin(Float(x)); } double tlfloat_sin(const double x) { return (double)sin(Double(x)); } tlfloat_quad_ tlfloat_sinq(const tlfloat_quad_ x) { return (tlfloat_quad_)sin(Quad(x)); } tlfloat_octuple_ tlfloat_sino(const tlfloat_octuple_ x) { return (tlfloat_octuple_)sin(Octuple(x)); } float tlfloat_cosf(const float x) { return (float)cos(Float(x)); } double tlfloat_cos(const double x) { return (double)cos(Double(x)); } tlfloat_quad_ tlfloat_cosq(const tlfloat_quad_ x) { return (tlfloat_quad_)cos(Quad(x)); } tlfloat_octuple_ tlfloat_coso(const tlfloat_octuple_ x) { return (tlfloat_octuple_)cos(Octuple(x)); } float tlfloat_tanf(const float x) { return (float)tan(Float(x)); } double tlfloat_tan(const double x) { return (double)tan(Double(x)); } tlfloat_quad_ tlfloat_tanq(const tlfloat_quad_ x) { return (tlfloat_quad_)tan(Quad(x)); } tlfloat_octuple_ tlfloat_tano(const tlfloat_octuple_ x) { return (tlfloat_octuple_)tan(Octuple(x)); } float tlfloat_sinpif(const float x) { return (float)sinpi(Float(x)); } double tlfloat_sinpi(const double x) { return (double)sinpi(Double(x)); } tlfloat_quad_ tlfloat_sinpiq(const tlfloat_quad_ x) { return (tlfloat_quad_)sinpi(Quad(x)); } tlfloat_octuple_ tlfloat_sinpio(const tlfloat_octuple_ x) { return (tlfloat_octuple_)sinpi(Octuple(x)); } float tlfloat_cospif(const float x) { return (float)cospi(Float(x)); } double tlfloat_cospi(const double x) { return (double)cospi(Double(x)); } tlfloat_quad_ tlfloat_cospiq(const tlfloat_quad_ x) { return (tlfloat_quad_)cospi(Quad(x)); } tlfloat_octuple_ tlfloat_cospio(const tlfloat_octuple_ x) { return (tlfloat_octuple_)cospi(Octuple(x)); } float tlfloat_tanpif(const float x) { return (float)tanpi(Float(x)); } double tlfloat_tanpi(const double x) { return (double)tanpi(Double(x)); } tlfloat_quad_ tlfloat_tanpiq(const tlfloat_quad_ x) { return (tlfloat_quad_)tanpi(Quad(x)); } tlfloat_octuple_ tlfloat_tanpio(const tlfloat_octuple_ x) { return (tlfloat_octuple_)tanpi(Octuple(x)); } void tlfloat_sincosf(const float x, float *s, float *c) { auto a = sincos(Float(x)); *s = (float)a.first; *c = (float)a.second; } void tlfloat_sincos(const double x, double *s, double *c) { auto a = sincos(Double(x)); *s = (double)a.first; *c = (double)a.second; } void tlfloat_sincosq(const tlfloat_quad_ x, tlfloat_quad_ *s, tlfloat_quad_ *c) { auto a = sincos(Quad(x)); *s = (tlfloat_quad_)a.first; *c = (tlfloat_quad_)a.second; } void tlfloat_sincoso(const tlfloat_octuple_ x, tlfloat_octuple_ *s, tlfloat_octuple_ *c) { auto a = sincos(Octuple(x)); *s = (tlfloat_octuple_)a.first; *c = (tlfloat_octuple_)a.second; } void tlfloat_sincospif(const float x, float *s, float *c) { auto a = sincospi(Float(x)); *s = (float)a.first; *c = (float)a.second; } void tlfloat_sincospi(const double x, double *s, double *c) { auto a = sincospi(Double(x)); *s = (double)a.first; *c = (double)a.second; } void tlfloat_sincospiq(const tlfloat_quad_ x, tlfloat_quad_ *s, tlfloat_quad_ *c) { auto a = sincospi(Quad(x)); *s = (tlfloat_quad_)a.first; *c = (tlfloat_quad_)a.second; } void tlfloat_sincospio(const tlfloat_octuple_ x, tlfloat_octuple_ *s, tlfloat_octuple_ *c) { auto a = sincospi(Octuple(x)); *s = (tlfloat_octuple_)a.first; *c = (tlfloat_octuple_)a.second; } } tlfloat-1.15.0/src/util/000077500000000000000000000000001477036600700150215ustar00rootroot00000000000000tlfloat-1.15.0/src/util/CMakeLists.txt000066400000000000000000000043431477036600700175650ustar00rootroot00000000000000if (BUILD_UTILS) if (LIB_MPFR) add_executable(mkrpitab mkrpitab.cpp) target_link_libraries(mkrpitab ${LIB_MPFR}) endif() add_executable(genmathcoef genmathcoef.cpp) endif() add_library(donothing OBJECT donothing.cpp) set_property(TARGET donothing PROPERTY INTERPROCEDURAL_OPTIMIZATION FALSE) if (BUILD_BENCH) add_executable(bench_tlfloat_quad bench.cpp) target_compile_options(bench_tlfloat_quad PRIVATE ${INLINE_CXX_FLAGS}) target_compile_definitions(bench_tlfloat_quad PRIVATE TLFLOAT_ENABLE_INLINING=1 CONFIG_TLFLOAT_QUAD=1) target_link_libraries(bench_tlfloat_quad donothing) add_executable(bench_tlfloat_octuple bench.cpp) target_compile_options(bench_tlfloat_octuple PRIVATE ${INLINE_CXX_FLAGS}) target_compile_definitions(bench_tlfloat_octuple PRIVATE TLFLOAT_ENABLE_INLINING=1 CONFIG_TLFLOAT_OCTUPLE=1) target_link_libraries(bench_tlfloat_octuple donothing) if (NOT TLFLOAT_COMPILER_SUPPORTS_FLOAT128) add_executable(bench_tlfloat_quad_capi bench.cpp) target_compile_options(bench_tlfloat_quad_capi PRIVATE ${INLINE_CXX_FLAGS}) target_compile_definitions(bench_tlfloat_quad_capi PRIVATE TLFLOAT_ENABLE_INLINING=1 CONFIG_TLFLOAT_QUAD_CAPI=1) target_link_libraries(bench_tlfloat_quad_capi tlfloat donothing) endif() add_executable(bench_tlfloat_octuple_capi bench.cpp) target_compile_options(bench_tlfloat_octuple_capi PRIVATE ${INLINE_CXX_FLAGS}) target_compile_definitions(bench_tlfloat_octuple_capi PRIVATE TLFLOAT_ENABLE_INLINING=1 CONFIG_TLFLOAT_OCTUPLE_CAPI=1) target_link_libraries(bench_tlfloat_octuple_capi tlfloat donothing) if (TLFLOAT_ENABLE_LIBQUADMATH) add_executable(bench_libquadmath bench.cpp) target_link_libraries(bench_libquadmath quadmath donothing) target_compile_options(bench_libquadmath PRIVATE ${INLINE_CXX_FLAGS}) target_compile_definitions(bench_libquadmath PRIVATE TLFLOAT_ENABLE_INLINING=1 CONFIG_LIBQUADMATH=1) endif() if (TLFLOAT_LONGDOUBLE_IS_FLOAT128) add_executable(bench_longdouble bench.cpp) target_compile_options(bench_longdouble PRIVATE ${INLINE_CXX_FLAGS}) target_compile_definitions(bench_longdouble PRIVATE TLFLOAT_ENABLE_INLINING=1 CONFIG_LONGDOUBLE=1) target_link_libraries(bench_longdouble donothing) endif() endif() tlfloat-1.15.0/src/util/bench.cpp000066400000000000000000000130371477036600700166100ustar00rootroot00000000000000#include #include #include #include #include #include using namespace std; #if defined(CONFIG_TLFLOAT_QUAD) #include #define CONFIG "tlfloat quad" using namespace tlfloat; typedef Quad real; #define FMA fma #define SQRT sqrt #define RINT rint #define SIN sin #define ATAN atan #define EXP exp #define LOG log #define POW pow #elif defined(CONFIG_TLFLOAT_OCTUPLE) #include #define CONFIG "tlfloat octuple" using namespace tlfloat; typedef Octuple real; #define FMA fma #define SQRT sqrt #define RINT rint #define SIN sin #define ATAN atan #define EXP exp #define LOG log #define POW pow #elif defined(CONFIG_TLFLOAT_QUAD_CAPI) #include #define CONFIG "tlfloat quad C API" typedef tlfloat_quad real; #define FMA tlfloat_fmaq #define SQRT tlfloat_sqrtq #define RINT tlfloat_rintq #define SIN tlfloat_sinq #define ATAN tlfloat_atanq #define EXP tlfloat_expq #define LOG tlfloat_logq #define POW tlfloat_powq #elif defined(CONFIG_TLFLOAT_OCTUPLE_CAPI) #include #define CONFIG "tlfloat octuple C API" typedef tlfloat_octuple real; #define FMA tlfloat_fmao #define SQRT tlfloat_sqrto #define RINT tlfloat_rinto #define SIN tlfloat_sino #define ATAN tlfloat_atano #define EXP tlfloat_expo #define LOG tlfloat_logo #define POW tlfloat_powo #elif defined(CONFIG_LIBQUADMATH) #define CONFIG "Libquadmath" #include typedef __float128 real; #define FMA fmaq #define SQRT sqrtq #define RINT rintq #define SIN sinq #define ATAN atanq #define EXP expq #define LOG logq #define POW powq #elif defined(CONFIG_LONGDOUBLE) #define CONFIG "Native long double" #include typedef long double real; #define FMA fmal #define SQRT sqrtl #define RINT rintl #define SIN sinl #define ATAN atanl #define EXP expl #define LOG logl #define POW powl #else #define CONFIG "Native double" #include typedef double real; #define FMA fma #define SQRT sqrt #define RINT rint #define SIN sin #define ATAN atan #define EXP exp #define LOG log #define POW pow #endif const int K = 256; struct { real W[K], X[K], Y[K], Z[K], H[K]; bool B[K]; } D; static void funcAddSub() { for(int i=0;i= D.Y[i+1]; } } static void funcFMA() { for(int i=0;i (chrono::system_clock::now() - chrono::system_clock::from_time_t(0)).count(); } void measure(const char* mes, void (*func)(void), int opPerCall, int64_t sec_us) { int64_t N = 10, t0, t1, t2, t3; for(;;) { t0 = timeus(); for(int64_t i=0;i 100000) break; N *= 2; } const int64_t M = N * sec_us / (t1 - t0); this_thread::sleep_for(chrono::microseconds(sec_us)); t2 = timeus(); for(int64_t i=0;i= 2) sec_us = int64_t(atof(argv[1]) * 1000000); for(int i=0;i #include #include #include "tlfloat/tlfloat.hpp" using namespace std; using namespace tlfloat; using namespace tlfloat::detail; typedef UnpackedFloat, BigUInt<9>, 0, 254> xoctuple; typedef UnpackedFloat, BigUInt<10>, 0, 510> xsedecuple; template struct yarray { T e[N]; int n() { return N; } }; template static yarray precomputeFactorial() { yarray a; a.e[0] = xsedecuple::castFromInt(1); for(unsigned i=1;i static yarray aFactorial = precomputeFactorial(); template static xsedecuple factorial(unsigned n) { return aFactorial.e[n]; } template static xsedecuple binomial(unsigned n, unsigned k) { return factorial(n)/(factorial(k)*factorial(n-k)); } template static xsedecuple binomial(const xsedecuple &x, unsigned k) { xsedecuple d = xsedecuple::castFromInt(1); for(unsigned i=0;i(k); } template static yarray precomputeBernoulli() { yarray a; a.e[0] = xsedecuple::castFromInt(1); for(unsigned n=1;n<=N;n++) { xsedecuple s = xsedecuple::castFromInt(0); for(unsigned k=0;k(n+1, k) * a.e[k]; a.e[n] = -s / xsedecuple::castFromInt(n + 1); } return a; } template static xsedecuple bernoulli(unsigned n) { const yarray pc = precomputeBernoulli(); return pc.e[n]; } template static yarray genSinCoef() { yarray a; for(unsigned i=0;i(i*2+1); return a; } template static yarray genCosCoef() { yarray a; for(unsigned i=0;i(i*2+0); return a; } template static yarray genTanCoef() { yarray a; for(unsigned k=1;k<=N;k++) { xsedecuple p4 = ldexp_(xsedecuple::castFromInt(1), 2*k); xsedecuple c = (p4 * (p4 - xsedecuple::castFromInt(1)) * bernoulli(2*k)) / factorial(2*k); if (!(k & 1)) c = -c; a.e[k-1] = c; } return a; } template static constexpr yarray genAtanCoef() { yarray a; for(unsigned i=0;i static constexpr yarray genExpCoef() { yarray a; for(unsigned i=0;i(i); return a; } template static constexpr yarray genLogCoef() { yarray a; for(unsigned i=0;i static constexpr yarray genCbrtCoef() { yarray a; for(unsigned i=0;i(xsedecuple::castFromInt(-1) / xsedecuple::castFromInt(3), i); return a; } int main(int argc, char **argv) { char buf[1024]; if (argc > 1) { xsedecuple x(argv[1]); snprint(buf, sizeof(buf), x, 'a', 0, -1); cout << "\"" << buf << "\", // " << to_double(x) << endl; x.mant &= ~((BigUInt<9>(1) << 250) - 1); snprint(buf, sizeof(buf), x, 'a', 0, -1); cout << "\"" << buf << "\", // " << to_double(x) << endl; return 0; } cout << "namespace tlfloat {" << endl; cout << " namespace detail {" << endl; { auto coef = genSinCoef<26>(); cout << " static constexpr const char *sinCoefStr[] = {" << endl; for(int i=0;i(1) << 250) - 1); snprint(buf, sizeof(buf), o, 'a', 0, -1); cout << " \"" << buf << "\", // " << to_double(o) << endl; } cout << " };" << endl; } cout << endl; { auto coef = genCosCoef<26>(); cout << " static constexpr const char *cosCoefStr[] = {" << endl; for(int i=0;i(1) << 250) - 1); snprint(buf, sizeof(buf), o, 'a', 0, -1); cout << " \"" << buf << "\", // " << to_double(o) << endl; } cout << " };" << endl; } cout << endl; { auto coef = genTanCoef<26>(); cout << " static constexpr const char *tanCoefStr[] = {" << endl; for(int i=0;i(1) << 250) - 1); snprint(buf, sizeof(buf), o, 'a', 0, -1); cout << " \"" << buf << "\", // " << to_double(o) << endl; } cout << " };" << endl; } cout << endl; { auto coef = genAtanCoef<22>(); cout << " static constexpr const char *atanCoefStr[] = {" << endl; for(int i=0;i(1) << 250) - 1); snprint(buf, sizeof(buf), o, 'a', 0, -1); cout << " \"" << buf << "\", // " << to_double(o) << endl; } cout << " };" << endl; } cout << endl; { auto coef = genExpCoef<36+1>(); cout << " static constexpr const char *expCoefStr[] = {" << endl; for(int i=0;i(1) << 250) - 1); snprint(buf, sizeof(buf), o, 'a', 0, -1); cout << " \"" << buf << "\", // " << to_double(o) << endl; } cout << " };" << endl; } cout << endl; { auto coef = genLogCoef<33+1>(); cout << " static constexpr const char *logCoefStr[] = {" << endl; for(int i=0;i(1) << 250) - 1); snprint(buf, sizeof(buf), o, 'a', 0, -1); cout << " \"" << buf << "\", // " << to_double(o) << endl; } cout << " };" << endl; } cout << endl; { auto coef = genCbrtCoef<4+1>(); cout << " static constexpr const char *cbrtCoefStr[] = {" << endl; for(int i=0;i(1) << 250) - 1); snprint(buf, sizeof(buf), o, 'a', 0, -1); cout << " \"" << buf << "\", // " << to_double(o) << endl; } cout << " };" << endl; } cout << endl; { cout << " static constexpr const char *gammaCoefStr[] = {" << endl; static const int N = 36; for(int i=1;i<=N;i++) { auto n = bernoulli(i*2); auto d = xsedecuple::castFromInt((2*i) * (2*i-1)); auto o = n / d; o.mant &= ~((BigUInt<9>(1) << 250) - 1); snprint(buf, sizeof(buf), o, 'a', 0, -1); cout << " \"" << buf << "\", // " << to_double(o) << endl; } cout << " };" << endl; } cout << " }" << endl; cout << "}" << endl; } tlfloat-1.15.0/src/util/mkrpitab.cpp000066400000000000000000000023031477036600700173340ustar00rootroot00000000000000#include #include #include #include #include #define N (1 << 19) int main(int argc, char **argv) { static uint8_t table[N / 8]; mpfr_set_default_prec(N); mpfr_t pi, m, n, o; mpfr_inits(pi, m, n, o, NULL); mpfr_const_pi(pi, GMP_RNDN); mpfr_d_div(n, 1.0, pi, GMP_RNDN); for(int e=0;e < N / 8;e++) { mpfr_set(m, n, GMP_RNDN); mpfr_set_ui_2exp(o, 1, e * 8, GMP_RNDN); mpfr_mul(m, m, o, GMP_RNDN); mpfr_frac(m, m, GMP_RNDN); mpfr_set_ui_2exp(o, 1, 8, GMP_RNDN); mpfr_mul(m, m, o, GMP_RNDN); mpfr_trunc(m, m); table[e] = (uint8_t)mpfr_get_d(m, GMP_RNDN); } mpfr_clears(pi, m, n, o, NULL); printf("#include \n"); printf("\n"); printf("namespace tlfloat {\n"); printf(" namespace detail {\n"); printf("#ifndef __CUDA_ARCH__\n"); printf(" static constexpr uint8_t tlfloat_rpitab[] = {\n"); printf("#else\n"); printf(" static __device__ constexpr uint8_t tlfloat_rpitab[] = {\n"); printf("#endif"); for(int i=0;i