[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Writing rational numbers
From: |
Hans Aberg |
Subject: |
Re: Writing rational numbers |
Date: |
Sat, 5 May 2001 22:53:33 +0200 |
At 05:49 +1000 2001/05/06, Kevin Ryde wrote:
>> The second toggle, when set true, will write rational numbers of the form
>> n p/q, where n, p, q are integers. (Here, n is dropped if 0. If n != 0,
>> only n can be negative, and if n == 0, only p can be negative.) For example
>> 22/7 will be written as 3 1/7, and -5/2 will be written as -2 1/2.
>
>I'll put that on a list as a gmp_printf possibility, if/when that
>routine ever gets done. Perhaps 3+1/7 or -2-1/2 would be possible
>too, to avoid spaces in numbers.
It might be a good idea. I thought of variations like 3_1/7 or -2_1/2. But
it depends who shall read it, or rather which type of computer program:
If one writes a new program parsing rational numbers, then it turns out
that the forms 3 1/7 and -2 1/2, with a single space, parses well with a
rule that strips out white-space. In my Flex lexer, I used the rules:
rational {sign}?({digits}" ")?{digits}"/"{digits}
%%
[[:space:]]+ { /* Skip white-space. */ }
Because Flex generated parsers always look for the longest match, it does
not have any problem combining such rules.
So the 3+1/7, -2-1/2 forms are for older parsers that cannot handle this
(humans I do not think will ever have any problems).
Also not the "{sign}?" on "rational" is somewhat unusual: In C/C++, one
strictly speaking only has positive numbers, and "-2" is parsed as "- 2",
the unary negation of 2. This way for example "2 -5" becomes illegal as
there is no binary operation between "2" and "-5"; one must write "2 + -5"
or "2 - 5".
I did this in order to be able to be sure that I can test all library
functions that I write. -- In a calculator or a compiler, I would do it
differently.
>> I gather a reading function may use similar toggles, but I use Flex to
>> parse numbers, so I only made sure that my function could read n p/q
>> formats, not bothering about the details (as the Flex parser will take care
>> of that).
>
>Also in the pipeline is an mpq_set_str which accepts either "p" or
>"p/q". I don't think "n p/q" can work, since the p and q will be
>parsed the same as mpz_set_str, which means all white space is ignored
>(I'm not saying that's a good thing, but it's how it is at the
>moment).
Possibly one might need a toggle, if one should it make work here. The way
I used in in my praser was by writing a function that can read "n p/q"
formats. Then the Flex parser distinguishes between the following:
%{
#define get_text(pos) yylval.text = std::string(yytext + (pos), yyleng - (pos))
%}
sign [+-]
integer {sign}?[1-9][[:digit:]]*
binary_integer {sign}?"0"[bB][01]+
octal_integer {sign}?"0"[0-7]+
hexadecimal_integer {sign}?"0"[xX][[:xdigit:]]+
rational {sign}?({digits}" ")?{digits}"/"{digits}
%%
[[:space:]]+ { /* Skip white-space. */ }
{integer} { get_text(yytext[0] == '+'); return integer_value; }
{binary_integer} { get_text(yytext[0] == '+'); return integer_value; }
{octal_integer} { get_text(yytext[0] == '+'); return integer_value; }
{hexadecimal_integer} { get_text(yytext[0] == '+'); return integer_value; }
{rational} { get_text(yytext[0] == '+'); return rational_value; }
As Flex has all rules at hand, there is no problem generating a parser that
can distinguish integers from rational numbers of the form "n p/q".
-- I am right now using GMP in writing a Groebner basis package for
polynomials with rational number coefficients (as I might need it in
writing a CLP program). In that context, rational numbers can easily become
big even if the input does not have that, which calls for multi-precision.
Hans Aberg