canonical_number.cc
Go to the documentation of this file.
1 
2 // ======================================================================
3 //
4 // canonical_number: Transform a number string into a canonical form
5 //
6 // "Number string" is defined by the following regular expression:
7 // ^[-+]?([0-9]*\.?[0-9]+|[0-9]+\.?[0-9]*)([eE][-+]?[0-9]+)?$
8 //
9 // ======================================================================
10 
12 #include "cetlib/base_converter.h"
13 
14 #include <cctype>
15 #include <cstdlib>
16 
17 using std::abs;
18 
19 bool
21  std::string::const_iterator it = value.begin();
22  std::string::const_iterator const end = value.end();
23 
24  // 0x or 0X leaded hex number
25  if (value.size() > 2 && value[0] == '0' && toupper(value[1]) == 'X') {
26  it += 2;
27 
28  // extract the whole part
29  static std::string const hexallowed("0123456789ABCDEFabcdef");
31  for (; it != end && hexallowed.find(*it) != std::string::npos; ++it)
32  hex.append(1, toupper(*it));
33 
34  // consumed all?
35  if (it != end)
36  return false;
37 
38  // convert to decimal
40  try {
41  dec = base_converter::hex_to_dec(hex);
42  }
43  catch (...) {
44  return false;
45  }
46 
47  // canonical form for the unsigned decimal number
48  return canonical_number(dec, result);
49  }
50 
51  // 0b or 0B leaded binary numbers
52  if (value.size() > 2 && value[0] == '0' && toupper(value[1]) == 'B') {
53  it += 2;
54 
55  // extract the whole part
56  static std::string const binallowed("01");
58  for (; it != end && binallowed.find(*it) != std::string::npos; ++it)
59  bin.append(1, *it);
60 
61  // consumed all?
62  if (it != end)
63  return false;
64 
65  // convert to decimal
67  try {
68  dec = base_converter::bin_to_dec(bin);
69  }
70  catch (...) {
71  return false;
72  }
73 
74  // canonical form for the unsigned decimal number
75  return canonical_number(dec, result);
76  }
77 
78  // extract sign, if any
79  std::string sign(*it == '-' ? "-" : "");
80  if (*it == '+' || *it == '-')
81  ++it;
82 
83  // extract optional whole part
84  std::string whole;
85  for (; it != end && std::isdigit(*it); ++it)
86  whole.append(1, *it);
87 
88  // extract fraction part
89  std::string fraction;
90  if (it != end && *it == '.') {
91  while (++it != end && std::isdigit(*it))
92  fraction.append(1, *it);
93  }
94 
95  // exponent part
96  std::string exponent;
97  if (it != end && (*it == 'E' || *it == 'e')) {
98  if (++it == end)
99  return false;
100  if (*it == '+' || *it == '-') {
101  exponent = *it;
102  if (++it == end)
103  return false;
104  }
105  for (; it != end && std::isdigit(*it); ++it)
106  exponent.append(1, *it);
107  }
108 
109  // consumed everything?
110  if (it != end)
111  return false;
112 
113  // require at least one digit
114  std::string digits = whole + fraction;
115  if (digits.empty())
116  return false;
117  std::size_t ndig = digits.size();
118 
119  // calculate exponent as if decimal point were at left
120  long exp = std::atoi(exponent.c_str()) + whole.size();
121 
122  // discard trailing zeroes
123  while (ndig > 1 && digits[ndig - 1] == '0')
124  digits.erase(--ndig, 1);
125  // discard leading zeroes
126  for (; ndig > 1 && digits[0] == '0'; --exp, --ndig)
127  digits.erase(0, 1);
128 
129  // produce result
130  if (digits == "0") {
131  result.append(digits);
132  return true;
133  }
134  result.append(sign);
135  if (long(ndig) <= exp && exp <= 6L) { // non-neg exp < e6?
136  result.append(digits).append(exp - ndig, '0');
137  } else {
138  if (ndig > 1)
139  digits.insert(digits.begin() + 1, '.');
140  --exp;
141  result.append(digits);
142  if (exp != 0) {
143  result.append(1, 'e').append(std::to_string(exp));
144  }
145  }
146  return true;
147 }
148 catch (...) {
149  return false;
150 } // canonical_number()
151 
152 // ======================================================================
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
bool canonical_number(std::string const &value, std::string &result)
static QCString result
std::string string
Definition: nybbler.cc:12
intermediate_table::const_iterator const_iterator
QTextStream & hex(QTextStream &s)
T abs(T value)
QTextStream & dec(QTextStream &s)
int sign(double val)
Definition: UtilFunc.cxx:104
QTextStream & bin(QTextStream &s)
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34