Question

I'm working on adding multi-precision integers to the suite of numeric types in my APL interpreter, but I'm not sure what to do about the odd type-combinations that now arise. I now have the following types:

IMM "atomic" small integer
FIX full-width integer
FLO floating-point double
MPI multi-precision integer

I have a variable which controls which larger type to use for integer overflow, either FLO or MPI. Mixed MPI/IMM/FIX operations, since they're all integers, can simply promote to the widest type and produce a result of that type. And mixed FLO/IMM/FIX operations can follow the same pattern since a double can comfortably accommodate all the values of a 32-bit integer. This covers most of the cases. But it leaves me with these type combinations which don't have an obvious (to me) rule to follow.

FLO {+-*/} MPI
MPI {+-*/} FLO

Having written this out, I suppose there really is an obvious solution (multi-precision floating-point). But I don't want to do that right now. Is there a sensible shortcut I can take (for now)?

As a "worst case" scenario that at least delivers some kind of result, I can implement conversions between these two types. But there's potential loss of data each way.

FLO -> MPI loses fractional part of floating-point number
MPI -> FLO loses precision from integer
Was it helpful?

Solution

Another option is to add a rational number type. This is stored as two integers, which usually will need to be multi-precision, and can represent any floating point value including the result of an operation between floating point and a multi-precision integer.

This way there is no loss of information. But there is a lot of work involved and should only be done if the user wants it.

OTHER TIPS

As a start, if we begin to consider the actual quantities involved then some subcases might be handled easily. It might also depend upon the operation we want to do.

MPI {+-} FLO
FLO {+-} MPI

If the FLO has a zero fractional part, then it can be converted to MPI losslessly. If it does have a fraction, then we probably want to keep the fraction and we ought to convert the MPI to FLO and cope with the loss of precision somehow.

MPI * FLO
FLO * MPI

Now here, we might want to perform a scaling operation on the MPI, so perhaps a little algebra can wiggle us out a result.

FLO = int + (1/frac)
R = MPI * FLO
  = MPI * (int + (1/frac))
  = (MPI * int) + (MPI/frac)

All of this seems to lead to a user-configurable parameter that selects which type to yield.

Or if the MPI is exactly representable as a double, then it can be converted without fear. Although the result may lose precision if the values are near the representation limits.

Licensed under: CC-BY-SA with attribution
scroll top