13
13
namespace Langulus
14
14
{
15
15
16
- // / Number of digits in a value
16
+ // / Count digits in real numbers
17
+ // / The dot in the real number is considered a digit, too
17
18
// / Credit goes to http://stackoverflow.com/questions/1489830
18
- NOD () constexpr LANGULUS (INLINED) Count CountDigits(uint8_t x) noexcept {
19
- return (x < 10u ? 1 : (x < 100u ? 2 : 3 ));
20
- }
21
-
22
- NOD () constexpr LANGULUS (INLINED) Count CountDigits(int8_t x) noexcept {
23
- return CountDigits (static_cast <uint8_t >(::std::abs (x)));
24
- }
25
-
26
- NOD () constexpr LANGULUS (INLINED) Count CountDigits(uint16_t x) noexcept {
27
- return (x < 10u ? 1 : (x < 100u ? 2 : (x < 1000u ? 3 : (x < 10000u ? 4 : 5 ))));
28
- }
29
-
30
- NOD () constexpr LANGULUS (INLINED) Count CountDigits(int16_t x) noexcept {
31
- return CountDigits (static_cast <uint16_t >(::std::abs (x)));
32
- }
33
-
34
- NOD () constexpr LANGULUS (INLINED) Count CountDigits(uint32_t x) noexcept {
35
- return
36
- (x < 10u ? 1 :
37
- (x < 100u ? 2 :
38
- (x < 1000u ? 3 :
39
- (x < 10000u ? 4 :
40
- (x < 100000u ? 5 :
41
- (x < 1000000u ? 6 :
42
- (x < 10000000u ? 7 :
43
- (x < 100000000u ? 8 :
44
- (x < 1000000000u ? 9 : 10 )))))))));
45
- }
46
-
47
- NOD () constexpr LANGULUS (INLINED) Count pcNumDigits(int32_t x) noexcept {
48
- return CountDigits (static_cast <uint32_t >(::std::abs (x)));
49
- }
50
-
51
- NOD () constexpr LANGULUS (INLINED) Count CountDigits(uint64_t x) noexcept {
52
- return
53
- (x < 10ull ? 1 :
54
- (x < 100ull ? 2 :
55
- (x < 1000ull ? 3 :
56
- (x < 10000ull ? 4 :
57
- (x < 100000ull ? 5 :
58
- (x < 1000000ull ? 6 :
59
- (x < 10000000ull ? 7 :
60
- (x < 100000000ull ? 8 :
61
- (x < 1000000000ull ? 9 :
62
- (x < 10000000000ull ? 10 :
63
- (x < 100000000000ull ? 11 :
64
- (x < 1000000000000ull ? 12 :
65
- (x < 10000000000000ull ? 13 :
66
- (x < 100000000000000ull ? 14 :
67
- (x < 1000000000000000ull ? 15 :
68
- (x < 10000000000000000ull ? 16 :
69
- (x < 100000000000000000ull ? 17 :
70
- (x < 1000000000000000000ull ? 18 :
71
- (x < 10000000000000000000ull ? 19 : 20
72
- )))))))))))))))))));
73
- }
74
-
75
- NOD () constexpr LANGULUS (INLINED) Count CountDigits(int64_t x) noexcept {
76
- // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs
77
- int const mask = x >> (sizeof (int64_t ) * 8 - 1 );
78
- return CountDigits (static_cast <uint64_t >((x + mask) ^ mask));
19
+ // / @param x - real number to count digits of
20
+ template <CT::Integer T> NOD () LANGULUS(INLINED)
21
+ constexpr Count CountDigits(T x) noexcept {
22
+ if constexpr (CT::UnsignedInteger8<T>)
23
+ return (x < 10u ? 1 : (x < 100u ? 2 : 3 ));
24
+ else if constexpr (CT::SignedInteger8<T>)
25
+ return CountDigits (static_cast <uint8_t >(::std::abs (x)));
26
+ else if constexpr (CT::UnsignedInteger16<T>)
27
+ return (x < 10u ? 1 : (x < 100u ? 2 : (x < 1000u ? 3 : (x < 10000u ? 4 : 5 ))));
28
+ else if constexpr (CT::SignedInteger16<T>)
29
+ return CountDigits (static_cast <uint16_t >(::std::abs (x)));
30
+ else if constexpr (CT::UnsignedInteger32<T>) {
31
+ return
32
+ (x < 10u ? 1 :
33
+ (x < 100u ? 2 :
34
+ (x < 1000u ? 3 :
35
+ (x < 10000u ? 4 :
36
+ (x < 100000u ? 5 :
37
+ (x < 1000000u ? 6 :
38
+ (x < 10000000u ? 7 :
39
+ (x < 100000000u ? 8 :
40
+ (x < 1000000000u ? 9 : 10 )))))))));
41
+ }
42
+ else if constexpr (CT::SignedInteger32<T>)
43
+ return CountDigits (static_cast <uint32_t >(::std::abs (x)));
44
+ else if constexpr (CT::UnsignedInteger64<T>) {
45
+ return
46
+ (x < 10ull ? 1 :
47
+ (x < 100ull ? 2 :
48
+ (x < 1000ull ? 3 :
49
+ (x < 10000ull ? 4 :
50
+ (x < 100000ull ? 5 :
51
+ (x < 1000000ull ? 6 :
52
+ (x < 10000000ull ? 7 :
53
+ (x < 100000000ull ? 8 :
54
+ (x < 1000000000ull ? 9 :
55
+ (x < 10000000000ull ? 10 :
56
+ (x < 100000000000ull ? 11 :
57
+ (x < 1000000000000ull ? 12 :
58
+ (x < 10000000000000ull ? 13 :
59
+ (x < 100000000000000ull ? 14 :
60
+ (x < 1000000000000000ull ? 15 :
61
+ (x < 10000000000000000ull ? 16 :
62
+ (x < 100000000000000000ull ? 17 :
63
+ (x < 1000000000000000000ull ? 18 :
64
+ (x < 10000000000000000000ull ? 19 : 20
65
+ )))))))))))))))))));
66
+ }
67
+ else if constexpr (CT::SignedInteger64<T>) {
68
+ // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs
69
+ int const mask = x >> (sizeof (int64_t ) * 8 - 1 );
70
+ return CountDigits (static_cast <uint64_t >((x + mask) ^ mask));
71
+ }
72
+ else static_assert (false , " Unimplemented integer" );
79
73
}
80
74
81
- // / Count digits in real numbers
82
- // / The dot in the real number is considered a digit, too
83
- // / @param x - real number to cound digits of
84
- template <CT::Real T>
85
- NOD () constexpr LANGULUS (INLINED) Count CountDigits(T x) noexcept {
75
+ // / Count digits in integer numbers
76
+ // / @param x - integer number to count digits of
77
+ template <CT::Real T> NOD () LANGULUS(INLINED)
78
+ constexpr Count CountDigits(T x) noexcept {
86
79
T floored;
87
80
T fraction {::std::abs (::std::modf (x, &floored))};
88
81
if (fraction == 0 )
@@ -104,8 +97,8 @@ namespace Langulus
104
97
// / @param lhs - left number
105
98
// / @param rhs - right number
106
99
// / @return the concatenation of the two numbers
107
- template <CT::Number T>
108
- NOD () LANGULUS(INLINED) T ConcatenateNumbers (const T& lhs, const T& rhs) {
100
+ template <CT::Number T> NOD () LANGULUS(INLINED)
101
+ T ConcatenateNumbers(const T& lhs, const T& rhs) {
109
102
T result {lhs};
110
103
result *= ::std::pow (T {10 }, static_cast <T>(CountDigits (rhs)));
111
104
result += rhs;
0 commit comments