|
|
1.1 ! root 1: .\" Copyright (c) 1980 Regents of the University of California. ! 2: .\" All rights reserved. The Berkeley software License Agreement ! 3: .\" specifies the terms and conditions for redistribution. ! 4: .\" ! 5: .\" @(#)ch3.n 6.2 (Berkeley) 5/14/86 ! 6: .\" ! 7: ." $Header: ch3.n,v 1.3 83/06/21 13:00:48 sklower Exp $ ! 8: .Lc Arithmetic\ Functions 3 ! 9: .pp ! 10: This chapter describes ! 11: .Fr "'s" ! 12: functions for doing arithmetic. ! 13: Often the same function is known by many names. ! 14: For example, ! 15: .i add ! 16: is also ! 17: .i plus , ! 18: and ! 19: .i sum . ! 20: This is caused by our desire to be compatible with other Lisps. ! 21: The ! 22: .Fr ! 23: user should avoid using functions with names ! 24: such as \(pl and \(** unless ! 25: their arguments are fixnums. ! 26: The Lisp compiler takes advantage of these implicit declarations. ! 27: .pp ! 28: An attempt to divide or to generate a floating ! 29: point result outside of the range of ! 30: floating point numbers ! 31: will cause a floating exception signal ! 32: from the UNIX operating system. ! 33: The user can catch and process this interrupt if desired (see the ! 34: description of the ! 35: .i signal ! 36: function). ! 37: .sh 2 Simple\ Arithmetic\ Functions \n(ch 1 ! 38: .Lf add "['n_arg1 ...]" ! 39: .Lx plus "['n_arg1 ...]" ! 40: .Lx sum "['n_arg1 ...]" ! 41: .Lx \(pl "['x_arg1 ...]" ! 42: .Re ! 43: the sum of the arguments. If no arguments are given, 0 is returned. ! 44: .No ! 45: if the size of the partial sum exceeds the limit of a fixnum, the ! 46: partial sum will be converted to a bignum. ! 47: If any of the arguments are flonums, the partial sum will be ! 48: converted to a flonum when that argument is processed and the ! 49: result will thus be a flonum. ! 50: Currently, if in the process of doing the ! 51: addition a bignum must be converted into ! 52: a flonum an error message will result. ! 53: .Lf add1 'n_arg ! 54: .Lx 1+ 'x_arg ! 55: .Re ! 56: its argument plus 1. ! 57: .Lf diff "['n_arg1 ... ]" ! 58: .Lx difference "['n_arg1 ... ]" ! 59: .Lx \(mi "['x_arg1 ... ]" ! 60: .Re ! 61: the result of subtracting from n_arg1 all subsequent arguments. ! 62: If no arguments are given, 0 is returned. ! 63: .No ! 64: See the description of add for details on data type conversions and ! 65: restrictions. ! 66: .Lf sub1 "'n_arg" ! 67: .Lx 1\(mi "'x_arg" ! 68: .Re ! 69: its argument minus 1. ! 70: .Lf minus "'n_arg" ! 71: .Re ! 72: zero minus n_arg. ! 73: .Lf product "['n_arg1 ... ]" ! 74: .Lx times "['n_arg1 ... ]" ! 75: .Lx \(** "['x_arg1 ... ]" ! 76: .Re ! 77: the product of all of its arguments. ! 78: It returns 1 if there are no arguments. ! 79: .No ! 80: See the description of the function \fIadd\fP for details and restrictions to the ! 81: automatic data type coercion. ! 82: .Lf quotient "['n_arg1 ...]" ! 83: .Lx / "['x_arg1 ...]" ! 84: .Re ! 85: the result of dividing the first argument by succeeding ones. ! 86: .No ! 87: If there are no arguments, 1 is returned. ! 88: See the description of the function \fIadd\fP for details and restrictions ! 89: of data type coercion. ! 90: A divide by zero will cause a floating exception interrupt -- see ! 91: the description of the ! 92: .i signal ! 93: function. ! 94: .Lf *quo "'i_x 'i_y" ! 95: .Re ! 96: the integer part of i_x / i_y. ! 97: .Lf Divide "'i_dividend 'i_divisor" ! 98: .Re ! 99: a list whose car is the quotient and whose cadr is the remainder of the ! 100: division of i_dividend by i_divisor. ! 101: .No ! 102: this is restricted to integer division. ! 103: .Lf Emuldiv "'x_fact1 'x_fact2 'x_addn 'x_divisor" ! 104: .Re ! 105: a list of the quotient and remainder of this operation: ! 106: ((x_fact1\ *\ x_fact2)\ +\ (sign\ extended)\ x_addn)\ /\ x_divisor. ! 107: .No ! 108: this is useful for creating a bignum arithmetic package in Lisp. ! 109: .sh 2 predicates ! 110: .Lf numberp "'g_arg" ! 111: .Lf numbp "'g_arg" ! 112: .Re ! 113: t iff g_arg is a number (fixnum, flonum or bignum). ! 114: .Lf fixp "'g_arg" ! 115: .Re ! 116: t iff g_arg is a fixnum or bignum. ! 117: .Lf floatp "'g_arg" ! 118: .Re ! 119: t iff g_arg is a flonum. ! 120: .Lf evenp "'x_arg" ! 121: .Re ! 122: t iff x_arg is even. ! 123: .Lf oddp "'x_arg" ! 124: .Re ! 125: t iff x_arg is odd. ! 126: .Lf zerop "'g_arg" ! 127: .Re ! 128: t iff g_arg is a number equal to 0. ! 129: .Lf onep "'g_arg" ! 130: .Re ! 131: t iff g_arg is a number equal to 1. ! 132: .Lf plusp "'n_arg" ! 133: .Re ! 134: t iff n_arg is greater than zero. ! 135: .Lf minusp "'g_arg" ! 136: .Re ! 137: t iff g_arg is a negative number. ! 138: .Lf greaterp "['n_arg1 ...]" ! 139: .Lx > "'fx_arg1 'fx_arg2" ! 140: .Lx >& "'x_arg1 'x_arg2" ! 141: .Re ! 142: t iff the arguments are in a strictly decreasing order. ! 143: .No ! 144: In functions ! 145: .i greaterp ! 146: and ! 147: .i > ! 148: the function ! 149: .i difference ! 150: is used to compare adjacent values. ! 151: If any of the arguments are non-numbers, the error message will come ! 152: from the ! 153: .i difference ! 154: function. ! 155: The arguments to ! 156: .i > ! 157: must be fixnums or both flonums. ! 158: The arguments to ! 159: .i >& ! 160: must both be fixnums. ! 161: .Lf lessp "['n_arg1 ...]" ! 162: .Lx < "'fx_arg1 'fx_arg2" ! 163: .Lx <& "'x_arg1 'x_arg2" ! 164: .Re ! 165: t iff the arguments are in a strictly increasing order. ! 166: .No ! 167: In functions ! 168: .i lessp ! 169: and ! 170: .i < ! 171: the function \fIdifference\fP is used to compare adjacent values. ! 172: If any of the arguments are non numbers, the error message will come ! 173: from the \fIdifference\fP function. ! 174: The arguments to ! 175: .i < ! 176: may be either fixnums or flonums but must be the same type. ! 177: The arguments to ! 178: .i <& ! 179: must be fixnums. ! 180: .Lf \(eq "'fx_arg1 'fx_arg2" ! 181: .Lf \(eq& "'x_arg1 'x_arg2" ! 182: .Re ! 183: t iff the arguments have the same value. ! 184: The arguments to \(eq must be the either both fixnums or both flonums. ! 185: The arguments to \(eq& must be fixnums. ! 186: .sh 2 Trignometric\ Functions ! 187: .pp ! 188: Some of these funtcions are taken from the host math library, and ! 189: we take no further responsibility for their accuracy. ! 190: .Lf cos "'fx_angle" ! 191: .Re ! 192: the (flonum) cosine of fx_angle (which is assumed to be in radians). ! 193: .Lf sin "'fx_angle" ! 194: .Re ! 195: the sine of fx_angle (which is assumed to be in radians). ! 196: .Lf acos "'fx_arg" ! 197: .Re ! 198: the (flonum) arc cosine of fx_arg in the range 0 to \(*p. ! 199: .Lf asin "'fx_arg" ! 200: .Re ! 201: the (flonum) arc sine of fx_arg in the range \(mi\(*p/2 to \(*p/2. ! 202: .Lf atan "'fx_arg1 'fx_arg2" ! 203: .Re ! 204: the (flonum) arc tangent of fx_arg1/fx_arg2 in the range -\(*p to \(*p. ! 205: .sh 2 Bignum/Fixnum\ Manipulation ! 206: .Lf haipart "bx_number x_bits" ! 207: .Re ! 208: a fixnum (or bignum) which contains ! 209: the x_bits high bits of ! 210: \fI(abs\ bx_number)\fP if x_bits is positive, otherwise ! 211: it returns the \fI(abs\ x_bits)\fP low bits of \fI(abs\ bx_number)\fP. ! 212: .Lf haulong "bx_number" ! 213: .Re ! 214: the number of significant bits in bx_number. ! 215: .No ! 216: the result is equal to the least integer greater to or equal to the ! 217: base two logarithm of ! 218: one plus the absolute value of bx_number. ! 219: .Lf bignum-leftshift "bx_arg x_amount" ! 220: .Re ! 221: bx_arg shifted left by x_amount. If ! 222: x_amount is negative, bx_arg will be shifted right by the magnitude of ! 223: x_amount. ! 224: .No ! 225: If bx_arg is shifted right, it will be rounded to the nearest even number. ! 226: .Lf sticky-bignum-leftshift "'bx_arg 'x_amount" ! 227: .Re ! 228: bx_arg shifted left by x_amount. If ! 229: x_amount is negative, bx_arg will be shifted right by the magnitude of ! 230: x_amount and rounded. ! 231: .No ! 232: sticky rounding is done this way: after shifting, ! 233: the low order bit is changed to 1 ! 234: if any 1's were shifted off to the right. ! 235: .sh 2 Bit\ Manipulation ! 236: .Lf boole "'x_key 'x_v1 'x_v2 ..." ! 237: .Re ! 238: the result of the bitwise boolean operation as described in the following ! 239: table. ! 240: .No ! 241: If there are more than 3 arguments, then evaluation proceeds left to ! 242: right with each partial result becoming the new value of x_v1. ! 243: That is, ! 244: .br ! 245: \ \ \ \ \ \fI(boole\ 'key\ 'v1\ 'v2\ 'v3)\ \(==\ (boole\ 'key\ (boole\ 'key\ 'v1\ 'v2)\ 'v3)\fP. ! 246: .br ! 247: In the following table, \(** represents bitwise and, \(pl represents ! 248: bitwise or, \o'\(ci\(pl' represents bitwise xor and \(no represents ! 249: bitwise negation and is the highest precedence operator. ! 250: .ps 8 ! 251: .(b ! 252: .TS ! 253: center box ; ! 254: c s s s s s s s s ! 255: c c c c c c c c c. ! 256: (boole 'key 'x 'y) ! 257: ! 258: = ! 259: key 0 1 2 3 4 5 6 7 ! 260: result 0 x \(** y \(no x \(** y y x \(** \(no y x x \o'\(ci\(pl' y x \(pl y ! 261: ! 262: common ! 263: names and bitclear xor or ! 264: ! 265: _ ! 266: ! 267: key 8 9 10 11 12 13 14 15 ! 268: result \(no (x \(pl y) \(no(x \o'\(ci\(pl' y) \(no x \(no x \(pl y \(no y x \(pl \(no y \(no x \(pl \(no y -1 ! 269: common ! 270: names nor equiv implies nand ! 271: .TE ! 272: .)b ! 273: .ps 10 ! 274: .pp ! 275: .Lf lsh "'x_val 'x_amt" ! 276: .Re ! 277: x_val shifted left by x_amt if x_amt is positive. ! 278: If x_amt is negative, then ! 279: .i lsh ! 280: returns x_val shifted right by the magnitude if x_amt. ! 281: .No ! 282: This always returns a fixnum even for those numbers whose magnitude is ! 283: so large that they would normally be represented as a bignum, ! 284: i.e. shifter bits are lost. ! 285: For more general bit shifters, see ! 286: .i bignum-leftshift ! 287: and ! 288: .i sticky-bignum-leftshift. ! 289: .Lf rot "'x_val 'x_amt" ! 290: .Re ! 291: x_val rotated left by x_amt if x_amt is positive. ! 292: If x_amt is negative, then x_val is rotated right by the magnitude of x_amt. ! 293: .sh 2 Other\ Functions ! 294: .pp ! 295: As noted above, some of the following functions are inherited from the ! 296: host math library, with all their virtues and vices. ! 297: .Lf abs 'n_arg ! 298: .Lx absval 'n_arg ! 299: .Re ! 300: the absolute value of n_arg. ! 301: .Lf exp "'fx_arg" ! 302: .Re ! 303: .i e ! 304: raised to the fx_arg power (flonum) . ! 305: .Lf expt "'n_base 'n_power" ! 306: .Re ! 307: n_base raised to the n_power power. ! 308: .No ! 309: if either of the arguments are flonums, the calculation will be done using ! 310: .i log ! 311: and ! 312: .i exp . ! 313: .Lf fact "'x_arg" ! 314: .Re ! 315: x_arg factorial. (fixnum or bignum) ! 316: .Lf fix "'n_arg" ! 317: .Re ! 318: a fixnum as close as we can get to n_arg. ! 319: .No ! 320: \fIfix\fP will round down. ! 321: Currently, if n_arg is a flonum larger ! 322: than the size of a fixnum, this will fail. ! 323: .Lf float "'n_arg" ! 324: .Re ! 325: a flonum as close as we can get to n_arg. ! 326: .No ! 327: if n_arg is a bignum larger than the maximum size of a flonum, ! 328: then a floating exception will occur. ! 329: .Lf log "'fx_arg" ! 330: .Re ! 331: the natural logarithm of fx_arg. ! 332: .Lf max "'n_arg1 ... " ! 333: .Re ! 334: the maximum value in the list of arguments. ! 335: .Lf min "'n_arg1 ... " ! 336: .Re ! 337: the minimum value in the list of arguments. ! 338: .Lf mod "'i_dividend 'i_divisor" ! 339: .Lx remainder "'i_dividend 'i_divisor" ! 340: .Re ! 341: the remainder when i_dividend is divided by i_divisor. ! 342: .No ! 343: The sign of the result will have the same sign as i_dividend. ! 344: .Lf *mod "'x_dividend 'x_divisor" ! 345: .Re ! 346: the balanced representation of x_dividend modulo x_divisor. ! 347: .No ! 348: the range of the balanced representation is abs(x_divisor)/2 to ! 349: (abs(x_divisor)/2) \(mi x_divisor + 1. ! 350: .Lf random "['x_limit]" ! 351: .Re ! 352: a fixnum between 0 and x_limit \(mi 1 if x_limit is given. ! 353: If x_limit is not given, any fixnum, positive or negative, might be ! 354: returned. ! 355: .Lf sqrt "'fx_arg" ! 356: .Re ! 357: the square root of fx_arg.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.