// Copyright 2018 The Abseil Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_ #define ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_ #include <algorithm> #include <cstdint> #include <iostream> #include <string> #include "absl/base/config.h" #include "absl/strings/ascii.h" #include "absl/strings/internal/charconv_parse.h" #include "absl/strings/string_view.h" namespace absl { ABSL_NAMESPACE_BEGIN namespace strings_internal { // The largest power that 5 that can be raised to, and still fit in a uint32_t. constexpr int kMaxSmallPowerOfFive = …; // The largest power that 10 that can be raised to, and still fit in a uint32_t. constexpr int kMaxSmallPowerOfTen = …; ABSL_DLL extern const uint32_t kFiveToNth[kMaxSmallPowerOfFive + 1]; ABSL_DLL extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1]; // Large, fixed-width unsigned integer. // // Exact rounding for decimal-to-binary floating point conversion requires very // large integer math, but a design goal of absl::from_chars is to avoid // allocating memory. The integer precision needed for decimal-to-binary // conversions is large but bounded, so a huge fixed-width integer class // suffices. // // This is an intentionally limited big integer class. Only needed operations // are implemented. All storage lives in an array data member, and all // arithmetic is done in-place, to avoid requiring separate storage for operand // and result. // // This is an internal class. Some methods live in the .cc file, and are // instantiated only for the values of max_words we need. template <int max_words> class BigUnsigned { … }; // Compares two big integer instances. // // Returns -1 if lhs < rhs, 0 if lhs == rhs, and 1 if lhs > rhs. template <int N, int M> int Compare(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { … } template <int N, int M> bool operator==(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { … } template <int N, int M> bool operator!=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { … } template <int N, int M> bool operator<(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { … } template <int N, int M> bool operator>(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { … } template <int N, int M> bool operator<=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { … } template <int N, int M> bool operator>=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { … } // Output operator for BigUnsigned, for testing purposes only. template <int N> std::ostream& operator<<(std::ostream& os, const BigUnsigned<N>& num) { … } // Explicit instantiation declarations for the sizes of BigUnsigned that we // are using. // // For now, the choices of 4 and 84 are arbitrary; 4 is a small value that is // still bigger than an int128, and 84 is a large value we will want to use // in the from_chars implementation. // // Comments justifying the use of 84 belong in the from_chars implementation, // and will be added in a follow-up CL. extern template class BigUnsigned<4>; extern template class BigUnsigned<84>; } // namespace strings_internal ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_