Line data Source code
1 : // Copyright (c) 2021-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/snapdev
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 : #pragma once
20 :
21 : /** \file
22 : * \brief Print large integers to any iostream.
23 : *
24 : * This function prints large integers (128 bits) to the specified iostream.
25 : */
26 :
27 : // C++ lib
28 : //
29 : #include <ostream>
30 : #include <sstream>
31 :
32 :
33 : namespace snapdev
34 : {
35 :
36 : /** \brief Convert an __int128 to a string.
37 : *
38 : * This function converts an __int128 to a string.
39 : *
40 : * \param[in] x An __int128 number.
41 : *
42 : * \return A string representing that __int128 number.
43 : */
44 : #pragma GCC diagnostic push
45 : #pragma GCC diagnostic ignored "-Wpedantic"
46 2022 : std::string to_string(__int128 x)
47 : {
48 2022 : char buf[42];
49 :
50 2022 : int idx(sizeof(buf));
51 2022 : unsigned __int128 y(x < 0
52 2022 : ? -static_cast<unsigned __int128>(x)
53 : : static_cast<unsigned __int128>(x));
54 2022 : constexpr unsigned __int128 const limit(9);
55 36054 : while(y > limit)
56 : {
57 17016 : --idx;
58 17016 : buf[idx] = y % 10 + '0';
59 17016 : y /= 10;
60 : }
61 2022 : --idx;
62 2022 : buf[idx] = y + '0';
63 2022 : if(x < 0)
64 : {
65 1011 : --idx;
66 1011 : buf[idx] = '-';
67 : }
68 :
69 2022 : return std::string(buf + idx, sizeof(buf) - idx);
70 : }
71 : #pragma GCC diagnostic pop
72 :
73 :
74 : /** \brief Convert an unsigned __int128 to a string.
75 : *
76 : * This function converts an unsigned __int128 to a string.
77 : *
78 : * \param[in] x An unsigned __int128 number.
79 : *
80 : * \return A string representing that unsigned __int128 number.
81 : */
82 : #pragma GCC diagnostic push
83 : #pragma GCC diagnostic ignored "-Wpedantic"
84 1 : std::string to_string(unsigned __int128 x)
85 : {
86 1 : char buf[42];
87 :
88 1 : int idx(sizeof(buf));
89 77 : while(x > 9)
90 : {
91 38 : --idx;
92 38 : buf[idx] = x % 10 + '0';
93 38 : x /= 10;
94 : }
95 1 : --idx;
96 1 : buf[idx] = x + '0';
97 :
98 1 : return std::string(buf + idx, sizeof(buf) - idx);
99 : }
100 : #pragma GCC diagnostic pop
101 :
102 : } //namespace snap
103 :
104 :
105 : // no namespace for operators, it's easier that way
106 :
107 :
108 : /** \brief Output an __int128 number.
109 : *
110 : * \warning
111 : * This implementation does not offer proper formatting.
112 : * It will first generate a string then output that string
113 : * which means the result is not what you'd expect if you
114 : * used formatting such as std::hex and std::setw().
115 : *
116 : * \param[in] os The output stream.
117 : * \param[in] x The value to be output in \p os.
118 : *
119 : * \return A reference to \p os.
120 : */
121 : #pragma GCC diagnostic push
122 : #pragma GCC diagnostic ignored "-Wpedantic"
123 2022 : std::ostream & operator << (std::ostream & os, __int128 x)
124 : {
125 2022 : return os << snapdev::to_string(x);
126 : }
127 : #pragma GCC diagnostic pop
128 :
129 :
130 : /** \brief Output an unsigned __int128 number.
131 : *
132 : * \warning
133 : * This implementation does not offer proper formatting.
134 : * It will first generate a string then output that string
135 : * which means the result is not what you'd expect if you
136 : * used formatting such as std::hex and std::setw().
137 : *
138 : * \param[in] os The output stream.
139 : * \param[in] x The value to be output in \p os.
140 : *
141 : * \return A reference to \p os.
142 : */
143 : #pragma GCC diagnostic push
144 : #pragma GCC diagnostic ignored "-Wpedantic"
145 1 : std::ostream & operator << (std::ostream & os, unsigned __int128 x)
146 : {
147 1 : return os << snapdev::to_string(x);
148 : }
149 : #pragma GCC diagnostic pop
150 :
151 :
152 : // vim: ts=4 sw=4 et
|