
Module: ppl/ppl Branch: master Commit: c00c6ad02ef68fb19f2692ff0ff0d290d203673b URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=c00c6ad02ef68...
Author: Enea Zaffanella zaffanella@cs.unipr.it Date: Tue Aug 31 22:20:12 2010 +0200
Let the input routine for checked numbers accepts C99 hexadecimal float syntax.
---
src/Checked_Number.defs.hh | 6 +++--- src/checked.cc | 29 ++++++++++++++++++++++------- tests/Polyhedron/numberinput1.cc | 2 ++ 3 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/src/Checked_Number.defs.hh b/src/Checked_Number.defs.hh index 514732d..5bef261 100644 --- a/src/Checked_Number.defs.hh +++ b/src/Checked_Number.defs.hh @@ -960,9 +960,9 @@ num : unum | '+' | SIGN unum ;
unum : unum1 EXP : 'e' - | HEX unum1 | '*^' - | base BASE unum1 ; - ; + | HEX unum1 | 'p' + | base BASE unum1 | '*^' + ; ; POINT : '.' unum1 : mantissa ; | mantissa EXP exponent diff --git a/src/checked.cc b/src/checked.cc index 9e32beb..c3ba12f 100644 --- a/src/checked.cc +++ b/src/checked.cc @@ -40,6 +40,7 @@ struct number_struct { bool neg_mantissa; bool neg_exponent; std::string mantissa; + unsigned int base_for_exponent; unsigned long exponent; };
@@ -100,7 +101,9 @@ parse_number_part(std::istream& is, number_struct& num) { bool empty_exponent = true; bool empty_mantissa = true; long exponent_offset = 0; + long exponent_offset_scale = 1; num.base = 10; + num.base_for_exponent = 10; num.neg_mantissa = false; num.neg_exponent = false; num.mantissa.erase(); @@ -144,6 +147,7 @@ parse_number_part(std::istream& is, number_struct& num) { int d = is.get(); if (d == 'x' || d == 'X') { num.base = 16; + num.base_for_exponent = 16; state = INTEGER; c = is.get(); } @@ -179,6 +183,7 @@ parse_number_part(std::istream& is, number_struct& num) { } if (num.base < 2) goto error; + num.base_for_exponent = num.base; num.mantissa.erase(); empty_mantissa = true; state = INTEGER; @@ -210,7 +215,16 @@ parse_number_part(std::istream& is, number_struct& num) { if (empty_mantissa) goto error; if (c == 'e' || c == 'E') - goto exp; + goto exp; + if (c == 'p' || c == 'P') { + if (num.base == 16) { + num.base_for_exponent = 2; + exponent_offset_scale = 4; + goto exp; + } + else + goto error; + } if (c == '*') { c = is.get(); if (c != '^') @@ -263,7 +277,7 @@ parse_number_part(std::istream& is, number_struct& num) { else neg = false; sum_sign(num.neg_exponent, num.exponent, - neg, exponent_offset); + neg, exponent_offset * exponent_offset_scale); return V_EQ; }
@@ -292,7 +306,8 @@ parse_number(std::istream& is, number_struct& num, number_struct& den) { r = parse_number_part(is, den); if (r != V_EQ) return V_CVT_STR_UNK; - if (num.base == den.base) { + if (num.base == den.base + && num.base_for_exponent == den.base_for_exponent) { if (sum_sign(num.neg_exponent, num.exponent, !den.neg_exponent, den.exponent)) { if (num.neg_exponent) { @@ -333,14 +348,14 @@ input_mpq(mpq_class& to, std::istream& is) { mpz_t z; mpz_init(z); if (num_struct.exponent) { - mpz_ui_pow_ui(z, num_struct.base, num_struct.exponent); + mpz_ui_pow_ui(z, num_struct.base_for_exponent, num_struct.exponent); if (num_struct.neg_exponent) mpz_mul(den, den, z); else mpz_mul(num, num, z); } if (den_struct.exponent) { - mpz_ui_pow_ui(z, den_struct.base, den_struct.exponent); + mpz_ui_pow_ui(z, den_struct.base_for_exponent, den_struct.exponent); if (den_struct.neg_exponent) mpz_mul(num, num, z); else @@ -355,13 +370,13 @@ input_mpq(mpq_class& to, std::istream& is) { if (num_struct.exponent) { if (num_struct.neg_exponent) { // Add the negative exponent as a denominator. - mpz_ui_pow_ui(den, num_struct.base, num_struct.exponent); + mpz_ui_pow_ui(den, num_struct.base_for_exponent, num_struct.exponent); goto end; } // Multiply the exponent into the numerator. mpz_t z; mpz_init(z); - mpz_ui_pow_ui(z, num_struct.base, num_struct.exponent); + mpz_ui_pow_ui(z, num_struct.base_for_exponent, num_struct.exponent); mpz_mul(num, num, z); mpz_clear(z); } diff --git a/tests/Polyhedron/numberinput1.cc b/tests/Polyhedron/numberinput1.cc index e98a2f7..cdc43f1 100644 --- a/tests/Polyhedron/numberinput1.cc +++ b/tests/Polyhedron/numberinput1.cc @@ -192,6 +192,8 @@ test07() { && aux_test("0xx", "nan", "x", V_CVT_STR_UNK) && aux_test("0x0.f", "15/16", "", V_EQ) && aux_test("0x.f", "15/16", "", V_EQ) + && aux_test("0x.fp3", "15/2", "", V_EQ) + && aux_test("0x100p-9", "1/2", "", V_EQ) && aux_test("0x.f*^1", "15", "", V_EQ) && aux_test("0x-f", "nan", "-f", V_CVT_STR_UNK) && aux_test("0xfa", "250", "", V_EQ)