Line data Source code
1 : // Copyright (c) 2021 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 snap
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 : #pragma GCC diagnostic ignored "-Wstrict-overflow"
47 2022 : std::string to_string(__int128 x)
48 : {
49 2022 : char buf[42];
50 :
51 2022 : int idx(sizeof(buf));
52 2022 : unsigned __int128 y(x < 0
53 2022 : ? static_cast<unsigned __int128>(-x)
54 : : static_cast<unsigned __int128>(x));
55 2022 : constexpr unsigned __int128 const limit(9);
56 36014 : while(y > limit)
57 : {
58 16996 : --idx;
59 16996 : buf[idx] = y % 10 + '0';
60 16996 : y /= 10;
61 : }
62 2022 : --idx;
63 2022 : buf[idx] = y + '0';
64 2022 : if(x < 0)
65 : {
66 1011 : --idx;
67 1011 : buf[idx] = '-';
68 : }
69 :
70 2022 : return std::string(buf + idx, sizeof(buf) - idx);
71 : }
72 : #pragma GCC diagnostic pop
73 :
74 :
75 : /** \brief Convert an unsigned __int128 to a string.
76 : *
77 : * This function converts an unsigned __int128 to a string.
78 : *
79 : * \param[in] x An unsigned __int128 number.
80 : *
81 : * \return A string representing that unsigned __int128 number.
82 : */
83 : #pragma GCC diagnostic push
84 : #pragma GCC diagnostic ignored "-Wpedantic"
85 1 : std::string to_string(unsigned __int128 x)
86 : {
87 1 : char buf[42];
88 :
89 1 : int idx(sizeof(buf));
90 77 : while(x > 9)
91 : {
92 38 : --idx;
93 38 : buf[idx] = x % 10 + '0';
94 38 : x /= 10;
95 : }
96 1 : --idx;
97 1 : buf[idx] = x + '0';
98 :
99 1 : return std::string(buf + idx, sizeof(buf) - idx);
100 : }
101 : #pragma GCC diagnostic pop
102 :
103 : }
104 :
105 :
106 :
107 : //namespace snap -- no namespace for such definitions, it works better that way
108 :
109 :
110 : /** \brief Output an __int128 number.
111 : *
112 : * \warning
113 : * This implementation does not offer proper formatting.
114 : * It will first generate a string then output that string
115 : * which means the result is not what you'd expect if you
116 : * used formatting such as std::hex and std::setw().
117 : *
118 : * \param[in] os The output stream.
119 : * \param[in] x The value to be output in \p os.
120 : *
121 : * \return A reference to \p os.
122 : */
123 : #pragma GCC diagnostic push
124 : #pragma GCC diagnostic ignored "-Wpedantic"
125 2022 : std::ostream & operator << (std::ostream & os, __int128 x)
126 : {
127 2022 : return os << snap::to_string(x);
128 : }
129 : #pragma GCC diagnostic pop
130 :
131 :
132 : /** \brief Output an unsigned __int128 number.
133 : *
134 : * \warning
135 : * This implementation does not offer proper formatting.
136 : * It will first generate a string then output that string
137 : * which means the result is not what you'd expect if you
138 : * used formatting such as std::hex and std::setw().
139 : *
140 : * \param[in] os The output stream.
141 : * \param[in] x The value to be output in \p os.
142 : *
143 : * \return A reference to \p os.
144 : */
145 : #pragma GCC diagnostic push
146 : #pragma GCC diagnostic ignored "-Wpedantic"
147 1 : std::ostream & operator << (std::ostream & os, unsigned __int128 x)
148 : {
149 1 : return os << snap::to_string(x);
150 : }
151 : #pragma GCC diagnostic pop
152 :
153 :
154 : // vim: ts=4 sw=4 et
|