10eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 20eae32dcSDimitry Andric // 30eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60eae32dcSDimitry Andric // 70eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 80eae32dcSDimitry Andric 90eae32dcSDimitry Andric // Copyright (c) Microsoft Corporation. 100eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 110eae32dcSDimitry Andric 120eae32dcSDimitry Andric // Copyright 2018 Ulf Adams 130eae32dcSDimitry Andric // Copyright (c) Microsoft Corporation. All rights reserved. 140eae32dcSDimitry Andric 150eae32dcSDimitry Andric // Boost Software License - Version 1.0 - August 17th, 2003 160eae32dcSDimitry Andric 170eae32dcSDimitry Andric // Permission is hereby granted, free of charge, to any person or organization 180eae32dcSDimitry Andric // obtaining a copy of the software and accompanying documentation covered by 190eae32dcSDimitry Andric // this license (the "Software") to use, reproduce, display, distribute, 200eae32dcSDimitry Andric // execute, and transmit the Software, and to prepare derivative works of the 210eae32dcSDimitry Andric // Software, and to permit third-parties to whom the Software is furnished to 220eae32dcSDimitry Andric // do so, all subject to the following: 230eae32dcSDimitry Andric 240eae32dcSDimitry Andric // The copyright notices in the Software and this entire statement, including 250eae32dcSDimitry Andric // the above license grant, this restriction and the following disclaimer, 260eae32dcSDimitry Andric // must be included in all copies of the Software, in whole or in part, and 270eae32dcSDimitry Andric // all derivative works of the Software, unless such copies or derivative 280eae32dcSDimitry Andric // works are solely in the form of machine-executable object code generated by 290eae32dcSDimitry Andric // a source language processor. 300eae32dcSDimitry Andric 310eae32dcSDimitry Andric // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 320eae32dcSDimitry Andric // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 330eae32dcSDimitry Andric // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 340eae32dcSDimitry Andric // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 350eae32dcSDimitry Andric // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 360eae32dcSDimitry Andric // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 370eae32dcSDimitry Andric // DEALINGS IN THE SOFTWARE. 380eae32dcSDimitry Andric 390eae32dcSDimitry Andric #ifndef _LIBCPP_SRC_INCLUDE_RYU_COMMON_H 400eae32dcSDimitry Andric #define _LIBCPP_SRC_INCLUDE_RYU_COMMON_H 410eae32dcSDimitry Andric 420eae32dcSDimitry Andric // Avoid formatting to keep the changes with the original code minimal. 430eae32dcSDimitry Andric // clang-format off 440eae32dcSDimitry Andric 4581ad6265SDimitry Andric #include <__assert> 4606c3fb27SDimitry Andric #include <__config> 4706c3fb27SDimitry Andric #include <cstring> 480eae32dcSDimitry Andric 490eae32dcSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 500eae32dcSDimitry Andric 510eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __decimalLength9(const uint32_t __v) { 520eae32dcSDimitry Andric // Function precondition: __v is not a 10-digit number. 530eae32dcSDimitry Andric // (f2s: 9 digits are sufficient for round-tripping.) 540eae32dcSDimitry Andric // (d2fixed: We print 9-digit blocks.) 55*5f757f3fSDimitry Andric _LIBCPP_ASSERT_INTERNAL(__v < 1000000000, ""); 560eae32dcSDimitry Andric if (__v >= 100000000) { return 9; } 570eae32dcSDimitry Andric if (__v >= 10000000) { return 8; } 580eae32dcSDimitry Andric if (__v >= 1000000) { return 7; } 590eae32dcSDimitry Andric if (__v >= 100000) { return 6; } 600eae32dcSDimitry Andric if (__v >= 10000) { return 5; } 610eae32dcSDimitry Andric if (__v >= 1000) { return 4; } 620eae32dcSDimitry Andric if (__v >= 100) { return 3; } 630eae32dcSDimitry Andric if (__v >= 10) { return 2; } 640eae32dcSDimitry Andric return 1; 650eae32dcSDimitry Andric } 660eae32dcSDimitry Andric 670eae32dcSDimitry Andric // Returns __e == 0 ? 1 : ceil(log_2(5^__e)). 680eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline int32_t __pow5bits(const int32_t __e) { 690eae32dcSDimitry Andric // This approximation works up to the point that the multiplication overflows at __e = 3529. 700eae32dcSDimitry Andric // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater 710eae32dcSDimitry Andric // than 2^9297. 72*5f757f3fSDimitry Andric _LIBCPP_ASSERT_INTERNAL(__e >= 0, ""); 73*5f757f3fSDimitry Andric _LIBCPP_ASSERT_INTERNAL(__e <= 3528, ""); 740eae32dcSDimitry Andric return static_cast<int32_t>(((static_cast<uint32_t>(__e) * 1217359) >> 19) + 1); 750eae32dcSDimitry Andric } 760eae32dcSDimitry Andric 770eae32dcSDimitry Andric // Returns floor(log_10(2^__e)). 780eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow2(const int32_t __e) { 790eae32dcSDimitry Andric // The first value this approximation fails for is 2^1651 which is just greater than 10^297. 80*5f757f3fSDimitry Andric _LIBCPP_ASSERT_INTERNAL(__e >= 0, ""); 81*5f757f3fSDimitry Andric _LIBCPP_ASSERT_INTERNAL(__e <= 1650, ""); 820eae32dcSDimitry Andric return (static_cast<uint32_t>(__e) * 78913) >> 18; 830eae32dcSDimitry Andric } 840eae32dcSDimitry Andric 850eae32dcSDimitry Andric // Returns floor(log_10(5^__e)). 860eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow5(const int32_t __e) { 870eae32dcSDimitry Andric // The first value this approximation fails for is 5^2621 which is just greater than 10^1832. 88*5f757f3fSDimitry Andric _LIBCPP_ASSERT_INTERNAL(__e >= 0, ""); 89*5f757f3fSDimitry Andric _LIBCPP_ASSERT_INTERNAL(__e <= 2620, ""); 900eae32dcSDimitry Andric return (static_cast<uint32_t>(__e) * 732923) >> 20; 910eae32dcSDimitry Andric } 920eae32dcSDimitry Andric 930eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __float_to_bits(const float __f) { 940eae32dcSDimitry Andric uint32_t __bits = 0; 9506c3fb27SDimitry Andric std::memcpy(&__bits, &__f, sizeof(float)); 960eae32dcSDimitry Andric return __bits; 970eae32dcSDimitry Andric } 980eae32dcSDimitry Andric 990eae32dcSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __double_to_bits(const double __d) { 1000eae32dcSDimitry Andric uint64_t __bits = 0; 10106c3fb27SDimitry Andric std::memcpy(&__bits, &__d, sizeof(double)); 1020eae32dcSDimitry Andric return __bits; 1030eae32dcSDimitry Andric } 1040eae32dcSDimitry Andric 1050eae32dcSDimitry Andric _LIBCPP_END_NAMESPACE_STD 1060eae32dcSDimitry Andric 1070eae32dcSDimitry Andric // clang-format on 1080eae32dcSDimitry Andric 1090eae32dcSDimitry Andric #endif // _LIBCPP_SRC_INCLUDE_RYU_COMMON_H 110