[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Real number arithmetic in eclipse (further info)
- Subject: Real number arithmetic in eclipse (further info)
- From: brad@cs.adelaide.edu.au (Bradley Alexander)
- Date: 18 Nov 1994 06:20:12 +0100
Hi,
I've looked a little further into the problem of implementing
real number arithmetic in Centaur and I've arrived at a stop-gap
solution.
The original problem was with typol definitions such as:
mulreal(AV, BV, CV)
----------------
(times(), realn BV, realn AV -> realn CV);
Where mulreal is from a file called func.sp and imported by the
sentence:
import ..., mulreal(_,_,_), ... from func;
The real numbers are implemented as strings in typol
which are interpreted as atoms in Eclipse prolog.
So the number 3.307 will be converted to the Eclipse
term '3.307' which is treated as an atom.
To perform arithmetic the atom must be converted to a
real number. The arithmetic must be performed and then
the real number must be reconverted to an atom. Calls
to these conversion routines can be integrated into
the prolog rule so "mulreal" looks like:
func$mulreal(A,B,X) :- conv_atom(A,D), conv_atom(B,E),C is D * E, real_atom(C,X).
where conv_atom(_,_) does the atom-> real conversion and
real_atom does the real->atom conversion.
The definitions of conv_atom and real_atom are:
-------------------- begin code --------------------
conv_atom(A,X) :- atom_list(A,B), conv_chars(B,X).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%atom string and string-list are built-in predicates
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
atom_list(A,X) :- atom_string(A,B), string_list(B,X).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%check to see if the number is negative
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
conv_chars([B|BS],X) :- B =:= 45,conv_iter(BS,0,C),-(C,X).
conv_chars(B,X) :- conv_iter(B,0,X).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%standard integer string to real-number conversions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
conv_iter([B|BS],N,X) :- -(B,48,C), <(C,0), conv_dec(BS,0.1,0,D), +(N,D,X).
conv_iter([B|BS],N,X) :- -(B,48,C), >=(C,0), *(N,10,D), +(D,C,E),
conv_iter(BS,E,X).
conv_iter([],N,N).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%code to convert the chars to the right of the decimal place to
%a real decimal number`
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
conv_dec([B|BS],N,T,X) :- -(B,48,C), *(C,N,D), /(N,10,E), +(D,T,F),
conv_dec(BS,E,F,X).
conv_dec([],N,T,T).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%convert real numbers to atoms for use by centaur
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
real_atom(A,X) :- first_part(A,B), second_part(A,D),
concat_atoms(B,'.',F), concat_atoms(F,D,X).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%first part deals with the numbers to the right of decimal point
%second part with numbers to the left
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
second_part(N,X):- abs(N,A),floor(A,B),C is A - B, second_iter(C,1,X).
second_iter(N,M,''):- *(N,M,A),A =:= floor(A).
second_iter(N,M,X):- *(10,M,B), get_digit(N,B,A),second_iter(N,B,C),
integer_atom(A,D),concat_atoms(D,C,X).
get_digit(N,M,X):- *(N,M,A),fix(A,B),//(B,10,C),*(C,10,D),-(B,D,X).
first_part(A,X) :- abs(A) < 1, fix(A,B), integer_atom(B,C),
concat_atoms('-',C,X).
first_part(A,X) :- fix(A,B), integer_atom(B,X).
------------------ end code -------------------------------
This works but it doesn't seem to be the cleanest way of implementing
these conversions (some of the code above is implemented to
prevent some of the rounding errors you get by repeatedly multiplying
real numbers).
Are there any built-in eclipse routines
that I could have used instead or any way of getting
centaur to use an alternative representation for real numbers?
Brad