Sese Framework  x.y.z
A cross-platform framework
载入中...
搜索中...
未找到
Number.h
浏览该文件的文档.
1// Copyright 2024 libsese
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
19
20
21#pragma once
22
25#include <sese/Util.h>
26#include <cmath>
27
28#ifdef SESE_PLATFORM_WINDOWS
29#pragma warning(disable: 4146)
30#endif
31
32namespace sese::text {
34class Number final : public NotInstantiable {
35public:
36 Number() = delete;
37
38 static std::string toHex(uint64_t number, bool upper_case = true) noexcept;
39
40 static std::string toHex(int64_t number, bool upper_case = true) noexcept;
41
42 static std::string toOct(uint64_t number) noexcept;
43
44 static std::string toOct(int64_t number) noexcept;
45
46 static std::string toBin(uint64_t number) noexcept;
47
48 static std::string toBin(int64_t number) noexcept;
49
50 static std::string toString(double number, uint16_t placeholder) noexcept;
51
52 template<typename T>
53 static void toString(StringBuilder &builder, T number, int radix, bool upper_case) noexcept {
54 if (number < 0) {
55 builder.append('-');
56 number = -number;
57 }
58 int count = 0;
59 constexpr auto DIGIT_UP = "0123456789ABCDEF";
60 constexpr auto DIGIT_DOWN = "0123456789abcdef";
61 const auto DIGIT = upper_case ? DIGIT_UP : DIGIT_DOWN;
62 do {
63 int index = number % radix;
64 builder.append(DIGIT[index]);
65 number /= radix;
66 count += 1;
67 } while (number > 0);
68
69 // 直接反转 builder 中部分内存
70 std::reverse(static_cast<char *>(builder.buf()) + builder.length() - count, static_cast<char *>(builder.buf()) + builder.length());
71 }
72
73 template<typename T>
74 static void toString(StringBuilder &builder, T number, uint16_t placeholder) noexcept {
75 auto int_part = static_cast<int64_t>(number);
76 double frac = number - int_part;
77 double rounding_factor = std::pow(10, placeholder);
78 auto rounded_part = static_cast<int64_t>(frac * rounding_factor);
79
80 if (static_cast<double>(rounded_part) >= rounding_factor) {
81 int_part += 1;
82 rounded_part -= static_cast<int64_t>(rounding_factor);
83 }
84
85 toString(builder, int_part, 10, true);
86 if (placeholder > 0) {
87 builder.append('.');
88 if (rounded_part < 0) {
89 rounded_part = -rounded_part;
90 }
91 toString(builder, rounded_part, 10, true);
92 auto len = number2StringLength(rounded_part, 10);
93 if (len < placeholder) {
94 builder.append(std::string(placeholder - len, '0'));
95 }
96 }
97 }
98
99private:
100 static std::string toStringWithNoLeadingZeros(const std::string &number) noexcept;
101};
102} // namespace sese::text