Annotation of researchv10dc/vol2/Dc/dc.ms, revision 1.1.1.1

1.1       root        1: .so ../ADM/mac
                      2: .XX 25 417 "\f2Dc\fP \(em An Interactive Desk Calculator"
                      3: .ds dc \fIdc\fP
                      4: .ds dC \f4dc\fP
                      5: .TL
                      6: \f4Dc\fP \(em An Interactive Desk Calculator
                      7: .AU "MH 2C-524" 3878
                      8: Robert Morris
                      9: Lorinda Cherry
                     10: .AI
                     11: .MH
                     12: .AB
                     13: .PP
                     14: .I Dc
                     15: is an interactive desk calculator program implemented
                     16: on the
                     17: .UX
                     18: time-sharing system to do arbitrary-precision
                     19: integer arithmetic.
                     20: It has provision for manipulating scaled fixed-point numbers and
                     21: for input and output in bases other than decimal.
                     22: .PP
                     23: The size of numbers that can be manipulated is limited
                     24: only by available core storage.
                     25: On typical implementations of
                     26: .UX ,
                     27: the size of numbers that
                     28: can be handled varies from several hundred digits on the smallest
                     29: systems to several thousand on the largest.
                     30: .AE
                     31: .2C
                     32: .NH 1
                     33: Introduction
                     34: .PP
                     35: .I Dc
                     36: is an arbitrary precision arithmetic package implemented
                     37: on the
                     38: .UX
                     39: time-sharing system
                     40: in the form of an interactive desk calculator.
                     41: It works like a stacking calculator using reverse Polish notation.
                     42: Ordinarily \*(dc operates on decimal integers, but one may
                     43: specify an input base, output base, and a number of fractional
                     44: digits to be maintained.
                     45: .PP
                     46: A language called \fIbc\fP|reference(cherry morris)
                     47: has been developed which accepts
                     48: programs written in the familiar style of higher-level
                     49: programming languages and compiles output which is
                     50: interpreted by \*(dc.
                     51: Some of the commands described below were designed
                     52: for the compiler interface and are not easy for a human user
                     53: to manipulate.
                     54: .PP
                     55: Numbers that are typed into \*(dc are put on a push-down
                     56: stack.
                     57: .I Dc
                     58: commands work by taking the top number or two
                     59: off the stack, performing the desired operation, and pushing the result
                     60: on the stack.
                     61: If an argument is given,
                     62: input is taken from that file until its end,
                     63: then from the standard input.
                     64: .NH 1
                     65: Synoptic Description
                     66: .PP
                     67: Here we describe the \*(dc commands that are intended
                     68: for use by people.  The additional commands that are
                     69: intended to be invoked by compiled output are
                     70: described in the detailed description.
                     71: .PP
                     72: Any number of commands are permitted on a line.
                     73: Blanks and new-line characters are ignored except within numbers
                     74: and in places where a register name is expected.
                     75: .PP
                     76: The following constructions are recognized:
                     77: .de c1
                     78: .IP "\f(CW\\$1\fR"
                     79: ..
                     80: .LP
                     81: .I number
                     82: .IP
                     83: The value of the number is pushed onto the main stack.
                     84: A number is an unbroken string of the digits
                     85: .CW 0-9
                     86: and the capital letters
                     87: .CW A\-F
                     88: which are treated as digits
                     89: with values 10\-15
                     90: respectively.
                     91: The number may be preceded by an underscore
                     92: .CW _
                     93: to input a
                     94: negative number.
                     95: Numbers may contain decimal points.
                     96: .LP
                     97: .CW "+  \-  *  %  ^"
                     98: .IP
                     99: The
                    100: top two values on the stack are added
                    101: (\f(CW+\fP),
                    102: subtracted
                    103: (\f(CW\-\fP),
                    104: multiplied (\f(CW*\fP),
                    105: divided (\f(CW/\fP),
                    106: remaindered (\f(CW%\fP),
                    107: or exponentiated (\f(CW^\fP).
                    108: The two entries are popped off the stack;
                    109: the result is pushed on the stack in their place.
                    110: The result of a division is an integer truncated toward zero.
                    111: See the detailed description below for the treatment of
                    112: numbers with decimal points.
                    113: An exponent must not have any digits after the decimal point.
                    114: .c1 s\fIx\fR
                    115: The
                    116: top of the main stack is popped and stored into
                    117: a register named
                    118: .I x ,
                    119: where
                    120: .I x
                    121: may be any character.
                    122: If the
                    123: .CW s
                    124: is capitalized,
                    125: .I x
                    126: is treated as a stack and the value is pushed onto it.
                    127: Any character, even blank or new-line, is a valid register name.
                    128: .c1 l\fIx
                    129: The
                    130: value in register
                    131: .I x
                    132: is pushed onto the stack.
                    133: The register
                    134: .I x
                    135: is not altered.
                    136: If the
                    137: .CW l
                    138: is capitalized,
                    139: register
                    140: .I x
                    141: is treated as a stack and its top value is popped onto the main stack.
                    142: .IP
                    143: All registers start with empty value which is treated as a zero
                    144: by the command
                    145: .CW l
                    146: and is treated as an error by the command
                    147: .CW L .
                    148: .c1 d
                    149: The
                    150: top value on the stack is duplicated.
                    151: .c1 p
                    152: The top value on the stack is printed.
                    153: The top value remains unchanged.
                    154: .c1 f
                    155: All values on the stack and in registers are printed.
                    156: .c1 x
                    157: treats the top element of the stack as a character string,
                    158: removes it from the stack, and
                    159: executes it as a string of \*(dc commands.
                    160: .LP
                    161: .CW "[ ... ]"
                    162: .IP
                    163: puts the bracketed character string onto the top of the stack.
                    164: .c1 q
                    165: exits the program.
                    166: If executing a string, the recursion level is
                    167: popped by two.
                    168: If
                    169: .CW q
                    170: is capitalized,
                    171: the top value on the stack is popped and the string execution level is popped
                    172: by that value.
                    173: .LP
                    174: .CW "<\fIx\fP  >\fIx\fP  =\fIx\fP  !<\fIx\fP  !>\fIx\fP  !=\fIx\fP"
                    175: .IP
                    176: The
                    177: top two elements of the stack are popped and compared.
                    178: Register
                    179: .I x
                    180: is executed if they obey the stated
                    181: relation.
                    182: Exclamation point is negation.
                    183: .LP
                    184: .CW v
                    185: .IP
                    186: replaces the top element on the stack by its square root.
                    187: The square root of an integer is truncated to an integer.
                    188: For the treatment of numbers with decimal points, see
                    189: the detailed description below.
                    190: .c1 !
                    191: interprets the rest of the line as a
                    192: .UX
                    193: command.
                    194: Control returns to \*(dc
                    195: when the
                    196: .UX
                    197: command terminates.
                    198: .c1 c
                    199: All values on the stack are popped; the stack becomes empty.
                    200: .c1 i
                    201: The top value on the stack is popped and used as the
                    202: number radix for further input.
                    203: If
                    204: .CW i
                    205: is capitalized, the value of
                    206: the input base is pushed onto the stack.
                    207: No mechanism has been provided for the input of arbitrary
                    208: numbers in bases less than 1 or greater than 16.
                    209: .c1 o
                    210: The top value on the stack is popped and used as the
                    211: number radix for further output.
                    212: If
                    213: .CW o
                    214: is capitalized, the value of the output
                    215: base is pushed onto the stack.
                    216: .c1 k
                    217: The top of the stack is popped, and that value is used as
                    218: a scale factor
                    219: that influences the number of decimal places
                    220: that are maintained during multiplication, division, and exponentiation.
                    221: The scale factor must be greater than or equal to zero and
                    222: less than 100.
                    223: If
                    224: .CW k
                    225: is capitalized, the value of the scale factor
                    226: is pushed onto the stack.
                    227: .c1 z
                    228: The value of the stack level is pushed onto the stack.
                    229: .c1 ?
                    230: A line of input is taken from the input source (usually the console)
                    231: and executed.
                    232: .NH 1
                    233: Detailed Description
                    234: .NH 2
                    235: Internal Representation of Numbers
                    236: .PP
                    237: Numbers are stored internally using a dynamic storage allocator.
                    238: Numbers are kept in the form of a string
                    239: of digits to the base 100 stored one digit per byte
                    240: (centennial digits).
                    241: The string is stored with the low-order digit at the
                    242: beginning of the string.
                    243: For example, the representation of 157
                    244: is 57,1.
                    245: After any arithmetic operation on a number, care is taken
                    246: that all digits are in the range 0\-99 and that
                    247: the number has no leading zeros.
                    248: The number zero is represented by the empty string.
                    249: .PP
                    250: Negative numbers are represented in the 100's complement
                    251: notation, which is analogous to two's complement notation for binary
                    252: numbers.
                    253: The high order digit of a negative number is always \-1
                    254: and all other digits are in the range 0\-99.
                    255: The digit preceding the high order \-1 digit is never a 99.
                    256: The representation of \-157 is 43,98,\-1.
                    257: We shall call this the canonical form of a number.
                    258: The advantage of this kind of representation of negative
                    259: numbers is ease of addition.  When addition is performed digit
                    260: by digit, the result is formally correct.  The result need only
                    261: be modified, if necessary, to put it into canonical form.
                    262: .PP
                    263: Because the largest valid digit is 99 and the byte can
                    264: hold numbers twice that large, addition can be carried out
                    265: and the handling of carries done later when
                    266: that is convenient, as it sometimes is.
                    267: .PP
                    268: An additional byte is stored with each number beyond
                    269: the high order digit to indicate the number of
                    270: assumed decimal digits after the decimal point.  The representation
                    271: of .001 is 1,\fI3\fP
                    272: where the scale has been italicized to emphasize the fact that it
                    273: is not the high order digit.
                    274: The value of this extra byte is called the
                    275: .B "scale factor"
                    276: of the number.
                    277: .NH 2
                    278: The Allocator
                    279: .PP
                    280: .I Dc
                    281: uses a dynamic string storage allocator
                    282: for all of its internal storage.
                    283: All reading and writing of numbers internally is done through
                    284: the allocator.
                    285: Associated with each string in the allocator is a four-word header containing pointers
                    286: to the beginning of the string, the end of the string,
                    287: the next place to write, and the next place to read.
                    288: Communication between the allocator and \*(dc
                    289: is done via pointers to these headers.
                    290: .PP
                    291: The allocator initially has one large string on a list
                    292: of free strings.  All headers except the one pointing
                    293: to this string are on a list of free headers.
                    294: Requests for strings are made by size.
                    295: The size of the string actually supplied is the next higher
                    296: power of 2.
                    297: When a request for a string is made, the allocator
                    298: first checks the free list to see if there is
                    299: a string of the desired size.
                    300: If none is found, the allocator finds the next larger free string and splits it repeatedly until
                    301: it has a string of the right size.
                    302: Left-over strings are put on the free list.
                    303: If there are no larger strings,
                    304: the allocator tries to coalesce smaller free strings into
                    305: larger ones.
                    306: Since all strings are the result
                    307: of splitting large strings,
                    308: each string has a neighbor that is next to it in core
                    309: and, if free, can be combined with it to make a string twice as long.
                    310: This is an implementation of the `buddy system' of allocation
                    311: described in |reference(spe pic).
                    312: .PP
                    313: Failing to find a string of the proper length after coalescing,
                    314: the allocator asks the system for more space.
                    315: The amount of space on the system is the only limitation
                    316: on the size and number of strings in \*(dc.
                    317: If at any time in the process of trying to allocate a string, the allocator runs out of
                    318: headers, it also asks the system for more space.
                    319: .PP
                    320: There are routines in the allocator for reading, writing, copying, rewinding,
                    321: forward-spacing, and backspacing strings.
                    322: All string manipulation is done using these routines.
                    323: .PP
                    324: The reading and writing routines
                    325: increment the read pointer or write pointer so that
                    326: the characters of a string are read or written in
                    327: succession by a series of read or write calls.
                    328: The write pointer is interpreted as the end of the
                    329: information-containing portion of a string and a call
                    330: to read beyond that point returns an end-of-string indication.
                    331: An attempt to write beyond the end of a string
                    332: causes the allocator to
                    333: allocate a larger space and then copy
                    334: the old string into the larger block.
                    335: .NH 2
                    336: Internal Arithmetic
                    337: .PP
                    338: All arithmetic operations are done on integers.
                    339: The operands (or operand) needed for the operation are popped
                    340: from the main stack and their scale factors stripped off.
                    341: Zeros are added or digits removed as necessary to get
                    342: a properly scaled result from the internal arithmetic routine.
                    343: For example, if the scale of the operands is different and decimal
                    344: alignment is required, as it is for
                    345: addition, zeros are appended to the operand with the smaller
                    346: scale.
                    347: After performing the required arithmetic operation,
                    348: the proper scale factor is appended to the end of the number before
                    349: it is pushed on the stack.
                    350: .PP
                    351: A register called \fBscale\fP plays a part
                    352: in the results of most arithmetic operations.
                    353: \fBscale\fP is the bound on the number of decimal places retained in
                    354: arithmetic computations.
                    355: \fBscale\fP may be set to the number on the top of the stack
                    356: truncated to an integer with the
                    357: .CW k
                    358: command.
                    359: .CW K
                    360: may be used to push the value of \fBscale\fP on the stack.
                    361: \fBscale\fP must be greater than or equal to 0 and less than 100.
                    362: The descriptions of the individual arithmetic operations will
                    363: include the exact effect of \fBscale\fP on the computations.
                    364: .NH 2
                    365: Addition and Subtraction
                    366: .PP
                    367: The scales of the two numbers are compared and trailing
                    368: zeros are supplied to the number with the lower scale to give both
                    369: numbers the same scale.  The number with the smaller scale is
                    370: multiplied by 10 if the difference of the scales is odd.
                    371: The scale of the result is then set to the larger of the scales
                    372: of the two operands.
                    373: .PP
                    374: Subtraction is performed by negating the number
                    375: to be subtracted and proceeding as in addition.
                    376: .PP
                    377: Finally, the addition is performed digit by digit from the
                    378: low order end of the number.  The carries are propagated
                    379: in the usual way.
                    380: The resulting number is brought into canonical form, which may
                    381: require stripping of leading zeros, or for negative numbers
                    382: replacing the high-order configuration 99,\-1 by the digit \-1.
                    383: In any case, digits which are not in the range 0\-99 must
                    384: be brought into that range, propagating any carries or borrows
                    385: that result.
                    386: .NH 2
                    387: Multiplication
                    388: .PP
                    389: The scales are removed from the two operands and saved.
                    390: The operands are both made positive.
                    391: Then multiplication is performed in
                    392: a digit by digit manner that exactly mimics the hand method
                    393: of multiplying.
                    394: The first number is multiplied by each digit of the second
                    395: number, beginning with its low order digit.  The intermediate
                    396: products are accumulated into a partial sum which becomes the
                    397: final product.
                    398: The product is put into the canonical form and its sign is
                    399: computed from the signs of the original operands.
                    400: .PP
                    401: The scale of the result is set equal to the sum
                    402: of the scales of the two operands.
                    403: If that scale is larger than the internal register
                    404: .B scale
                    405: and also larger than both of the scales of the two operands,
                    406: then the scale of the result is set equal to the largest
                    407: of these three last quantities.
                    408: .NH 2
                    409: Division
                    410: .PP
                    411: The scales are removed from the two operands.
                    412: Zeros are appended or digits removed from the dividend to make
                    413: the scale of the result of the integer division equal to
                    414: the internal quantity
                    415: \fBscale\fP.
                    416: The signs are removed and saved.
                    417: .PP
                    418: Division is performed much as it would be done by hand.
                    419: The difference of the lengths of the two numbers
                    420: is computed.
                    421: If the divisor is longer than the dividend,
                    422: zero is returned.
                    423: Otherwise the top digit of the divisor is divided into the top
                    424: two digits of the dividend.
                    425: The result is used as the first (high-order) digit of the
                    426: quotient.
                    427: It may turn out be one unit too low, but if it is, the next
                    428: trial quotient will be larger than 99 and this will be
                    429: adjusted at the end of the process.
                    430: The trial digit is multiplied by the divisor and the result subtracted
                    431: from the dividend and the process is repeated to get
                    432: additional quotient digits until the remaining
                    433: dividend is smaller than the divisor.
                    434: At the end, the digits of the quotient are put into
                    435: the canonical form, with propagation of carry as needed.
                    436: The sign is set from the sign of the operands.
                    437: .NH 2
                    438: Remainder
                    439: .PP
                    440: The division routine is called and division is performed
                    441: exactly as described.  The quantity returned is the remains of the
                    442: dividend at the end of the divide process.
                    443: Since division truncates toward zero, remainders have the same
                    444: sign as the dividend.
                    445: The scale of the remainder is set to 
                    446: the maximum of the scale of the dividend and
                    447: the scale of the quotient plus the scale of the divisor.
                    448: .NH 2
                    449: Square Root
                    450: .PP
                    451: The scale is stripped from the operand.
                    452: Zeros are added if necessary to make the
                    453: integer result have a scale that is the larger of
                    454: the internal quantity
                    455: \fBscale\fP
                    456: and the scale of the operand.
                    457: .PP
                    458: The method used to compute sqrt(y) is Newton's method
                    459: with successive approximations by the rule
                    460: .EQ
                    461: x sub {n+1} ~=~ half ( x sub n + y over x sub n )
                    462: .EN
                    463: The initial guess is found by taking the integer square root
                    464: of the top two digits.
                    465: .NH 2
                    466: Exponentiation
                    467: .PP
                    468: Only exponents with zero scale factor are handled.  If the exponent is
                    469: zero, then the result is 1.  If the exponent is negative, then
                    470: it is made positive and the base is divided into one.  The scale
                    471: of the base is removed.
                    472: .PP
                    473: The integer exponent is viewed as a binary number.
                    474: The base is repeatedly squared and the result is
                    475: obtained as a product of those powers of the base that
                    476: correspond to the positions of the one-bits in the binary
                    477: representation of the exponent.
                    478: Enough digits of the result
                    479: are removed to make the scale of the result the same as if the
                    480: indicated multiplication had been performed.
                    481: .NH 2
                    482: Input Conversion and Base
                    483: .PP
                    484: Numbers are converted to the internal representation as they are read
                    485: in.
                    486: The scale stored with a number is simply the number of fractional digits input.
                    487: Negative numbers are indicated by preceding the number with a
                    488: .CW _ .
                    489: The hexadecimal digits
                    490: .CW A\-F
                    491: correspond to the numbers 10\-15
                    492: regardless of input base.
                    493: The
                    494: .CW i
                    495: command can be used to change the base of the input numbers.
                    496: This command pops the stack, truncates the resulting number to an integer,
                    497: and uses it as the input base for all further input.
                    498: The input base is initialized to 10 but may, for example be changed to
                    499: 8 or 16 to do octal or hexadecimal to decimal conversions.
                    500: The command
                    501: .CW I
                    502: will push the value of the input base on the stack.
                    503: .NH 2
                    504: Output Commands
                    505: .PP
                    506: The command
                    507: .CW p
                    508: causes the top of the stack to be printed.
                    509: It does not remove the top of the stack.
                    510: All of the stack and internal registers can be output
                    511: by typing the command
                    512: .CW f .
                    513: The
                    514: .CW o
                    515: command can be used to change the output base.
                    516: This command uses the top of the stack, truncated to an integer as
                    517: the base for all further output.
                    518: The output base in initialized to 10.
                    519: It will work correctly for any base.
                    520: The command
                    521: .CW O
                    522: pushes the value of the output base on the stack.
                    523: .NH 2
                    524: Output Format and Base
                    525: .PP
                    526: The input and output bases only affect
                    527: the interpretation of numbers on input and output; they have no
                    528: effect on arithmetic computations.
                    529: Large numbers are output with 70 characters per line; a
                    530: .CW \e
                    531: indicates a continued line.
                    532: All choices of input and output bases work correctly, although not all are
                    533: useful.
                    534: A particularly useful output base is 100000, which has the effect of
                    535: grouping digits in fives.
                    536: Bases of 8 and 16 can be used for decimal-octal or decimal-hexadecimal
                    537: conversions.
                    538: .NH 2
                    539: Internal Registers
                    540: .PP
                    541: Numbers or strings may be stored in internal registers or loaded on the stack
                    542: from registers with the commands
                    543: .CW s
                    544: and
                    545: .CW l .
                    546: The command
                    547: .CW s\fIx\fP
                    548: pops the top of the stack and
                    549: stores the result in register
                    550: .I x ;
                    551: .I x
                    552: can be any character.
                    553: .CW l\fIx\fP
                    554: puts the contents of register
                    555: .I x
                    556: on the top of the stack.
                    557: The
                    558: .CW l
                    559: command has no effect on the contents of register
                    560: .I x .
                    561: The
                    562: .CW s
                    563: command, however, is destructive.
                    564: .NH 2
                    565: Stack Commands
                    566: .PP
                    567: The command
                    568: .CW c
                    569: clears the stack.
                    570: The command
                    571: .CW d
                    572: pushes a duplicate of the number on the top of the stack
                    573: on the stack.
                    574: The command
                    575: .CW z
                    576: pushes the stack size on the stack.
                    577: The command
                    578: .CW X
                    579: replaces the number on the top of the stack
                    580: with its scale factor.
                    581: The command
                    582: .CW Z
                    583: replaces the top of the stack
                    584: with its length.
                    585: .NH 2
                    586: Subroutine Definitions and Calls
                    587: .PP
                    588: Enclosing a string in
                    589: .CW []
                    590: pushes the ascii string on the stack.
                    591: The
                    592: .CW q
                    593: command quits or in executing a string, pops the recursion levels by two.
                    594: .NH 2
                    595: Internal Registers \- Programming \*(dC
                    596: .PP
                    597: The load and store
                    598: commands together with
                    599: .CW []
                    600: to store strings,
                    601: .CW x
                    602: to execute
                    603: and the testing commands
                    604: .CW < ,
                    605: .CW > ,
                    606: .CW = ,
                    607: .CW !< ,
                    608: .CW !> ,
                    609: .CW !=
                    610: can be used to program \*(dc.
                    611: The
                    612: .CW x
                    613: command assumes the top of the stack is an string of \*(dc commands
                    614: and executes it.
                    615: The testing commands compare the top two elements on the stack and if the relation holds, execute the register
                    616: that follows the relation.
                    617: For example, to print the numbers 0-9,
                    618: .P1
                    619: [lip1+  si  li10>a]sa
                    620: 0si  lax
                    621: .P2
                    622: .NH 2
                    623: Push-Down Registers and Arrays
                    624: .PP
                    625: These commands were designed for used by a compiler, not by
                    626: people.
                    627: They involve push-down registers and arrays.
                    628: In addition to the stack that commands work on, \*(dc can be thought
                    629: of as having individual stacks for each register.
                    630: These registers are operated on by the commands
                    631: .CW S
                    632: and
                    633: .CW L .
                    634: .CW S\fIx\fP
                    635: pushes the top value of the main stack onto the stack for
                    636: the register
                    637: .I x .
                    638: .CW L\fIx\fP
                    639: pops the stack for register
                    640: .I x
                    641: and puts the result on the main stack.
                    642: The commands
                    643: .CW s
                    644: and
                    645: .CW l
                    646: also work on registers but not as push-down stacks.
                    647: .CW l
                    648: doesn't effect the top of the
                    649: register stack, and
                    650: .CW s
                    651: destroys what was there before.
                    652: .PP
                    653: The commands to work on arrays are
                    654: .CW :
                    655: and
                    656: .CW ; .
                    657: .CW :\fIx\fP
                    658: pops the stack and uses this value as an index into
                    659: the array
                    660: .I x .
                    661: The next element on the stack is stored at this index in
                    662: .I x .
                    663: An index must be greater than or equal to 0 and
                    664: less than 2048.
                    665: .CW ;\fIx\fP
                    666: is the command to load the main stack from the array
                    667: .I x .
                    668: The value on the top of the stack is the index
                    669: into the array
                    670: .I x
                    671: of the value to be loaded.
                    672: .NH 2
                    673: Miscellaneous Commands
                    674: .PP
                    675: The command
                    676: .CW !
                    677: interprets the rest of the line as a 
                    678: .UX
                    679: command and passes
                    680: it to 
                    681: .UX
                    682: to execute.
                    683: One other compiler command is
                    684: .CW Q .
                    685: This command uses the top of the stack as the number of levels of recursion to skip.
                    686: .NH 1
                    687: Design Choices
                    688: .PP
                    689: The real reason for the use of a dynamic storage allocator was
                    690: that a general purpose program could be (and in fact has been)
                    691: used for a variety of other tasks.
                    692: The allocator has some value for input and for compiling (i.e.
                    693: the bracket
                    694: .CW [...]
                    695: commands) where it cannot be known in advance
                    696: how long a string will be.
                    697: The result was that at a modest
                    698: cost in execution time, all considerations of string allocation
                    699: and sizes of strings were removed from the remainder of the program
                    700: and debugging was made easier.  The allocation method
                    701: used wastes approximately 25% of available space.
                    702: .PP
                    703: The choice of 100 as a base for internal arithmetic
                    704: seemingly has no compelling advantage.  Yet the base cannot
                    705: exceed 127 because of hardware limitations and at the cost
                    706: of 5% in space, debugging was made a great deal easier and
                    707: decimal output was made much faster.
                    708: .PP
                    709: The reason for a stack-type arithmetic design was
                    710: to permit all \*(dc commands from addition to subroutine execution
                    711: to be implemented in essentially the same way.  The result
                    712: was a considerable degree of logical separation of the final
                    713: program into modules with very little communication between
                    714: modules.
                    715: .PP
                    716: The rationale for the lack of interaction between the scale and the bases
                    717: was to provide an understandable means of proceeding after
                    718: a change of base or scale when numbers had already been entered.
                    719: An earlier implementation which had global notions of
                    720: scale and base did not work out well.
                    721: If the value of
                    722: .ft B
                    723: scale
                    724: .ft
                    725: were to be interpreted in the current
                    726: input or output base,
                    727: then a change of base or scale in the midst of a
                    728: computation would cause great confusion in the interpretation
                    729: of the results.
                    730: The current scheme has the advantage that the value of
                    731: the input and output bases
                    732: are only used for input and output, respectively, and they
                    733: are ignored in all other operations.
                    734: The value of
                    735: scale
                    736: is not used for any essential purpose by any part of the program
                    737: and it is used only to prevent the number of
                    738: decimal places resulting from the arithmetic operations from
                    739: growing beyond all bounds.
                    740: .PP
                    741: The design rationale for the choices for the scales of
                    742: the results of arithmetic were that in no case should
                    743: any significant digits be thrown away if, on appearances, the
                    744: user actually wanted them.  Thus, if the user wants
                    745: to add the numbers 1.5 and 3.517, it seemed reasonable to
                    746: return the result 5.017 without requiring the
                    747: rather obvious requirement for precision.
                    748: .PP
                    749: On the other hand, multiplication and exponentiation produce
                    750: results with many more digits than their operands and it
                    751: seemed reasonable to give as a minimum the number of decimal
                    752: places in the operands but not to give more than that
                    753: number of digits
                    754: unless the user asked for them by specifying a value for \fBscale\fP.
                    755: Square root can be handled in just the same way as multiplication.
                    756: The operation of division gives arbitrarily many decimal places
                    757: and there is simply no way to guess how many places the user
                    758: wants.
                    759: In this case only, the user must
                    760: specify a \fBscale\fP to get any decimal places at all.
                    761: .PP
                    762: The scale of remainder was chosen to make it possible
                    763: to recreate the dividend from the quotient and remainder.
                    764: This is easy to implement; no digits are thrown away.
                    765: .NH 1
                    766: References
                    767: .LP
                    768: |reference_placement

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.