1 XEROX COMMON LISP DESIGN DOCUMENT CMLNUM 1 CMLNUM 6 Kelly Roach 8-APR-86 Covering part of Section 12.6. Type conversions and component extractions on numbers. SPNUM.SLISP defines FLOAT RATIONAL RATIONALIZE NUMERATOR DENOMINATOR GCD LCM LOGCOUNT DECODE-FLOAT SCALE-FLOAT FLOAT-RADIX FLOAT-SIGN FLOAT-DIGITS FLOAT-PRECISION INTEGER-DECODE-FLOAT ISQRT COMPLEX REALPART IMAGPART but does not include FLOOR, CEILING, TRUNCATE, ROUND, MOD, REM, FFLOOR, FCEILING, FTRUNCATE, FROUND. 2 Issues 1 (.5) Common Lisp FLOAT has &OPTIONAL arg: (FLOAT NUMBER &OPTIONAL OTHER). (1) NUMERATOR, DENOMINATOR, RATIONAL, and RATIONALIZE require that rationals are already implemented. (2) Will need reading and printing support from reader/printer implementors. May need BIGNUM-like typemasking. Microcode needs to punt on rationals. Will need to implement all of rational arithmetic. All these items are apparently my items. (3) INTEGER-DECODE-FLOAT and DECODE-FLOAT require that multiple values are already implemented. (4) Common Lisp has (GCD &REST INTEGERS) and Interlisp has (GCD N1 N2). (5) ISQRT described in section 12.5. (6) SPNUM.SLISP and CMLNUM don't implement all of 12.6. (7) Interlisp already has a declaration for RATIONAL, but it is a RECORD not a DATATYPE or DEFSTRUCT. Printing has to be able to recognize a RATIONAL from a LISTP. (8) CMLARITH COMPLEX defstruct wrong. Defines REALPART and IMAGPART to be accessors, but in fact, REALPART and IMAGPART are functions that apply to any kind of number. Defines COMPLEX to be a constructor, but in fact, COMPLEX is a function that can return a number that isn't complex. (9) MAX and MIN have to be extended to handle rationals. (MAX 1/2 1 3/4) = 3/4. (10) Comparisons on numbers have to be extended to handle rationals. = /= < > <= >=. 2 Decisions 1 (.5) The first release of Xerox Common Lisp will only be supporting one kind of floating point number, SINGLE-FLOAT. Therefore, FLOAT does not need to pay attention to &OPTIONAL OTHER. There are no code changes to FLOAT other than to change its argument list to include &OPTIONAL OTHER which it will not pay attention to. (1) NUMERATOR DENOMINATOR I think come from the DEFSTRUCT accessor methods. Postpone till rationals are implemented. Will have to implement rationals. Rational arithmetic will be integrated into arithmetic UFNs alongside complexs and BIGNUMs. See design doc about rationals and complexes CMLNUMBERS.TEDIT (to be written). (2) Since all problems with RATIONALS are mine, will implement COMPLEXs of CMLIRRAT first to explore the reading-printing-typemasking-microcode issues that are involved in implementing a new kind of number. After COMPLEXs work well, use what I've learned to implement rationals. (3) Go ahead and code. Larry will implement multiple values. May have to recompile later. Larry believes multiple values work. There's a performance argument that we need separate single-value functions for multiple-valued ones that are frequently called only for their first value. (4) Define CL:GCD first and do a MOVD of CL:GCD on to GCD in CMLNUM filecoms. When confident that CL:GCD works, CL:GCD replaces GCD. There is no point in having separate IL:GCD and CL:GCD since CL:GCD will be a backwards compatible extension of IL:GCD. (5) Find out why Spice Lisp put ISQRT in SPNUM.SLISP instead of SPIRRAT.SLISP. If there is no good reason, move ISQRT from CMLNUM to CMLIRRAT. (6) Implement the half corresponding to SPNUM.SLISP for now. Consider file mergers later. (7) Going to declare RATIO datatype. Later, it will necessary to examine instances of RATIONAL record in places like INTERPRESS. (8) Going to declare COMPLEX datatype and define functions COMPLEXP, REALPART, IMAGPART, and COMPLEX without the help (in this case unwelcome) of DEFSTRUCT. If we did make COMPLEX be a defstruct, we would have to change the field names to other than REALPART, IMAGPART or change (:CONC-NAME NIL). We would have to change (:CONSTRUCTOR COMPLEX). (9) So they shall be. (10) So they shall be. 2 Design overview 1 (1) Implement integer fns GCD, LCM, and LOGCOUT first. (2) With record declarations from LLFLOAT, implement floating fns FLOAT-SIGN FLOAT-DIGITS FLOAT-PRECISION FLOAT-RADIX INTEGER-DECODE-FLOAT DECODE-FLOAT SCALE-FLOAT ISQRT. (3) After rationals implemented, implement NUMERATOR, DENOMINATOR, RATIONAL, and RATIONALIZE. 2 Data Structures and Algorithms 1 (1) LLFLOAT records to describe FLOATPs. (2) BIGNUM-like technology to implement rationals. (3) Adapt code out of SPNUM.SLISP, throwing away parts having to do with BIGNUMs which Larry has already implemented. Dependencies 1 (1) I will be implementing rationals. Find out if BIGNUM-like technology is needed. (2) Need reading and printing support for rationals. Performance points 1 Compiler / evaluator: Compiler should understand RATIONAL declarations. If a variable X is declared to be a FLOATP, then (FLOAT-SIGN X) (FLOAT-DIGITS X) (FLOAT-PRECISION X) (FLOAT-RADIX X) compile openly? Why should the compiler understand RATIONAL declarations? Why should FLOAT-SIGN etc compile open? Optimizer macros: CONSTANTEXPRESSIONP should knowthat all of NUMERATOR DENOMINATOR RATIONAL RATIONALIZE GCD LCM LOGCOUNT FLOAT-SIGN FLOAT-DIGITS FLOAT-PRECISION FLOAT-RADIX INTEGER-DECODE-FLOAT DECODE-FLOAT SCALE-FLOAT ISQRT are side effect free. Microcode: Needs to punt when encounter rational args. Microcode already punts when it encounters rationals (anything it doesn't know). Environment support 1 Environmental impact (tools needed, etc.): None. Tasks 1 (1) Integer fns. GCD LCM LOGCOUNT (2) Floating fns. FLOAT-SIGN FLOAT-DIGITS FLOAT-PRECISION FLOAT-RADIX INTEGER-DECODE-FLOAT DECODE-FLOAT SCALE-FLOAT ISQRT (3) Rational fns. NUMERATOR DENOMINATOR RATIONAL RATIONALIZE Testing issues 1 Potential edges in algorithms and structures: 2 Phasing and Timing 1 Implementation is phased: (1), (2), (3) as in Tasks section above. Time estimate: 1 month. Dependencies: Rationals must be implemented to implment rational fns in CMLNUM. 2 Appendix 1 FLOAT RATIONAL RATIONALIZE NUMERATOR DENOMINATOR GCD LCM LOGCOUNT DECODE-FLOAT SCALE-FLOAT FLOAT-RADIX FLOAT-SIGN FLOAT-DIGITS FLOAT-PRECISION INTEGER-DECODE-FLOAT ISQRT (FLOAT NUMBER &OPTIONAL OTHER) (RATIONAL NUMBER) (RATIONALIZE NUMBER) (NUMERATOR RATIONAL) (DENOMINATOR RATIONAL) p202 (GCD &REST INTEGERS) p202 (LCM INTEGER &REST MORE-INTEGERS) p224 (LOGCOUNT INTEGER) (DECODE-FLOAT FLOAT) (SCALE-FLOAT FLOAT INTEGER) (FLOAT-SIGN FLOAT1 &OPTIONAL FLOAT2) (FLOAT-DIGITS FLOAT) (FLOAT-PRECISION FLOAT) (INTEGER-DECODE-FLOAT FLOAT) p205 (ISQRT INTEGER) (LIST ((PAGE NIL (PAPERSIZE Letter FOLIOINFO (ARABIC)) (0 0 612 792) ((HEADING NIL (HEADINGTYPE FOOTINGR) (72 27 540 36) NIL) (TEXT NIL NIL (72 72 504 648) NIL))) (PAGE NIL (PAPERSIZE Letter FOLIOINFO (ARABIC)) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD RIGHT) CHARLOOKS (SUPERSCRIPT 0 INVISIBLE OFF SELECTPOINT OFF PROTECTED OFF SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF EXPANSION REGULAR SLOPE REGULAR WEIGHT MEDIUM INVERTED OFF USERINFO NIL STYLE NIL) FORMATINFO (ARABIC)) (288 12 288 36) NIL) (HEADING NIL (HEADINGTYPE FOOTINGR) (72 27 540 36) NIL) (HEADING NIL (HEADINGTYPE RECTOHEAD) (72 762 540 36) NIL) (TEXT NIL NIL (72 72 504 648) NIL))) (PAGE NIL (PAPERSIZE Letter FOLIOINFO (ARABIC)) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD RIGHT) CHARLOOKS (SUPERSCRIPT 0 INVISIBLE OFF SELECTPOINT OFF PROTECTED OFF SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF EXPANSION REGULAR SLOPE REGULAR WEIGHT MEDIUM INVERTED OFF USERINFO NIL STYLE NIL) FORMATINFO (ARABIC)) (288 12 288 36) NIL) (HEADING NIL (HEADINGTYPE FOOTINGR) (72 27 540 36) NIL) (HEADING NIL (HEADINGTYPE RECTOHEAD) (72 762 540 36) NIL) (TEXT NIL NIL (72 72 504 648) NIL))))) /``T/T/ T)T)2T(`` )``T)`` TB PAGEHEADING RECTOHEADA PAGEHEADINGFOOTINGR HELVETICAMODERN MODERNMODERNMODERN   HRULE.GETFNMODERN  "   HRULE.GETFNMODERN  HRULE.GETFNMODERNl667 g HRULE.GETFNMODERN HRULE.GETFNMODERNJf`H%8 QV HRULE.GETFNMODERN  HRULE.GETFNMODERNDGl[] HRULE.GETFNMODERN HRULE.GETFNMODERN7^ HRULE.GETFNMODERN HRULE.GETFNMODERN)3v  HRULE.GETFNMODERN U5 HRULE.GETFNMODERN a8P HRULE.GETFNMODERN 1 HRULE.GETFNMODERN (C HRULE.GETFNMODERN . HRULE.GETFNMODERN HRULE.GETFNMODERN.P HRULE.GETFNMODERN  HRULE.GETFNMODERN667 '%Lz