24 #include "ppl-config.h"
57 case '0': n = 0;
break;
58 case '1': n = 1;
break;
59 case '2': n = 2;
break;
60 case '3': n = 3;
break;
61 case '4': n = 4;
break;
62 case '5': n = 5;
break;
63 case '6': n = 6;
break;
64 case '7': n = 7;
break;
65 case '8': n = 8;
break;
66 case '9': n = 9;
break;
67 case 'a':
case 'A': n = 10;
break;
68 case 'b':
case 'B': n = 11;
break;
69 case 'c':
case 'C': n = 12;
break;
70 case 'd':
case 'D': n = 13;
break;
71 case 'e':
case 'E': n = 14;
break;
72 case 'f':
case 'F': n = 15;
break;
73 case 'g':
case 'G': n = 16;
break;
74 case 'h':
case 'H': n = 17;
break;
75 case 'i':
case 'I': n = 18;
break;
76 case 'j':
case 'J': n = 19;
break;
77 case 'k':
case 'K': n = 20;
break;
78 case 'l':
case 'L': n = 21;
break;
79 case 'm':
case 'M': n = 22;
break;
80 case 'n':
case 'N': n = 23;
break;
81 case 'o':
case 'O': n = 24;
break;
82 case 'p':
case 'P': n = 25;
break;
83 case 'q':
case 'Q': n = 26;
break;
84 case 'r':
case 'R': n = 27;
break;
85 case 's':
case 'S': n = 28;
break;
86 case 't':
case 'T': n = 29;
break;
87 case 'u':
case 'U': n = 30;
break;
88 case 'v':
case 'V': n = 31;
break;
89 case 'w':
case 'W': n = 32;
break;
90 case 'x':
case 'X': n = 33;
break;
91 case 'y':
case 'Y': n = 34;
break;
92 case 'z':
case 'Z': n = 35;
break;
99 return static_cast<int>(n);
111 bool b_neg,
unsigned long b_mod) {
112 if (a_neg == b_neg) {
118 else if (a_mod >= b_mod) {
123 a_mod = b_mod - a_mod;
136 enum anonymous_enum { BASE, INTEGER, FRACTIONAL, EXPONENT } state = BASE;
139 bool empty_exponent =
true;
140 bool empty_mantissa =
true;
141 long exponent_offset = 0;
142 unsigned exponent_offset_scale = 1;
163 if (c ==
'i' || c ==
'I') {
181 if (c !=
'a' && c !=
'A') {
182 goto unexpected_char;
187 if (c !=
'n' && c !=
'N') {
188 goto unexpected_char;
197 if (c !=
'n' && c !=
'n') {
198 goto unexpected_char;
203 if (c !=
'f' && c !=
'F') {
204 goto unexpected_char;
208 if (state != FRACTIONAL) {
210 goto unexpected_char;
213 if (c ==
'0' && !is.get(d).fail()) {
214 if (d ==
'x' || d ==
'X') {
231 if (c !=
'0' || !numer.
mantissa.empty()) {
234 empty_mantissa =
false;
242 goto unexpected_char;
245 for (std::string::const_iterator
248 if (numer.
base > 36) {
249 goto unexpected_char;
252 if (numer.
base < 2) {
253 goto unexpected_char;
257 empty_mantissa =
true;
264 if (c !=
'0' || !numer.
mantissa.empty()) {
267 empty_mantissa =
false;
279 if (c !=
'0' || !numer.
mantissa.empty()) {
282 empty_mantissa =
false;
286 if (empty_mantissa) {
287 goto unexpected_char;
289 if (c ==
'e' || c ==
'E') {
292 if (c ==
'p' || c ==
'P') {
293 if (numer.
base == 16) {
295 exponent_offset_scale = 4;
299 goto unexpected_char;
307 goto unexpected_char;
311 PPL_ASSERT(numer.
base >= 2);
313 max_exp_div =
static_cast<unsigned long>(l_max) / numer.
base;
314 max_exp_rem = static_cast<int>(l_max % static_cast<long>(numer.
base));
332 empty_exponent =
false;
334 || (numer.
exponent == max_exp_div && d > max_exp_rem)) {
340 if (empty_exponent) {
341 goto unexpected_char;
347 }
while (!is.fail());
349 if (empty_mantissa || is.bad()) {
355 std::string::size_type n = numer.
mantissa.size();
356 while (n > 0 && numer.
mantissa[n - 1] ==
'0') {
362 if (exponent_offset < 0) {
364 exponent_offset = -exponent_offset;
370 neg, static_cast<unsigned long>(exponent_offset) * exponent_offset_scale);
434 is.setstate(is.failbit);
437 is.clear(is.rdstate() & ~is.failbit);
441 if (denom_struct.
base != 0 && denom_struct.
mantissa.empty()) {
444 if (numer_struct.
mantissa.empty()) {
448 const mpz_ptr numer = to.get_num().get_mpz_t();
449 const mpz_ptr denom = to.get_den().get_mpz_t();
450 mpz_set_str(numer, numer_struct.
mantissa.c_str(),
451 static_cast<int>(numer_struct.
base));
452 if (denom_struct.
base != 0) {
454 mpz_neg(numer, numer);
456 mpz_set_str(denom, denom_struct.
mantissa.c_str(),
457 static_cast<int>(denom_struct.
base));
466 mpz_mul(denom, denom, z);
469 mpz_mul(numer, numer, z);
476 mpz_mul(numer, numer, z);
479 mpz_mul(denom, denom, z);
487 mpz_neg(numer, numer);
501 mpz_mul(numer, numer, z);
504 mpz_set_ui(denom, 1);
515 const mpz_ptr n = q.get_num().get_mpz_t();
516 const mpz_ptr d = q.get_den().get_mpz_t();
517 const unsigned long decimals = mpz_sizeinbase(d, 2) - 1;
519 mpz_ui_pow_ui(d, 5, decimals);
522 size_t bufsize = mpz_sizeinbase(n, 10);
523 if (bufsize < decimals) {
524 bufsize = decimals + 4;
530 mpz_get_str(buf, 10, n);
532 const size_t len = strlen(buf);
533 if (decimals < len) {
534 memmove(&buf[len - decimals + 1], &buf[len - decimals], decimals + 1);
535 buf[len - decimals] =
'.';
538 const size_t zeroes = decimals - len;
539 memmove(&buf[2 + zeroes], &buf[0], len + 1);
542 memset(&buf[2],
'0', zeroes);
int get_digit(char c, unsigned int base=10)
Returns the integer value associated with the ASCII code c, in the base base positional number system...
The computed result is exact.
std::string float_mpq_to_string(mpq_class &q)
Not_A_Number NOT_A_NUMBER
unsigned irrational_precision
Holds the precision parameter used for irrational calculations.
Result
Possible outcomes of a checked arithmetic computation.
bool is_space(char c)
Returns true if c is any kind of space character.
Negative infinity result.
Converting from unknown string.
Result parse_number(std::istream &is, number_struct &numer, number_struct &denom)
Reads a number from is writing it into numer, the numerator, and denom, the denominator; the appropri...
Plus_Infinity PLUS_INFINITY
unsigned int base_for_exponent
The entire library is confined to this namespace.
Minus_Infinity MINUS_INFINITY
Result input_mpq(mpq_class &to, std::istream &is)
Positive infinity result.
bool sum_sign(bool &a_neg, unsigned long &a_mod, bool b_neg, unsigned long b_mod)
Adds the number represented (in the modulus-and-sign representation) by b_neg and b_mod to the number...
Result parse_number_part(std::istream &is, number_struct &numer)
Helper function for parse_number(): reads the numerator or denominator part of a number from is into ...
#define PPL_UNINITIALIZED(type, name)