diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-02-25 22:00:50 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-02-25 22:00:50 -0800 |
commit | 0f32fe85728e4ee35a25094d99bdf7b3ff1630a7 (patch) | |
tree | 568160ac3679e3cc202b28bf2fd262786187871f | |
parent | 56f0df1ea9282f1c050e23c78fed47f321ff8d06 (diff) | |
download | txr-0f32fe85728e4ee35a25094d99bdf7b3ff1630a7.tar.gz txr-0f32fe85728e4ee35a25094d99bdf7b3ff1630a7.tar.bz2 txr-0f32fe85728e4ee35a25094d99bdf7b3ff1630a7.zip |
Second argument optional in trunc.
* arith.c (trunc1): New static function.
(trunc): Detect a missing second argument and call func1.
* eval.c (eval_init): Update registration of trunc
intrinsic to make second arg optional.
* txr.1: Describe optional argument of trunc. Trunc documentation
is merged with the floor, ceil and round section.
The mod and trunc-rem functions are split off into their own
sections, leaving the / function described by itself.
The documentation of / is substantially revised.
-rw-r--r-- | arith.c | 21 | ||||
-rw-r--r-- | eval.c | 2 | ||||
-rw-r--r-- | txr.1 | 158 |
3 files changed, 106 insertions, 75 deletions
@@ -803,8 +803,29 @@ tail: uw_throwf(error_s, lit("*: invalid operands ~s ~s"), anum, bnum, nao); } +static val trunc1(val num) +{ + switch (type(num)) { + case NUM: + case BGNUM: + return num; + case FLNUM: + { + double n = c_flo(num); + return flo(n - fmod(n, 1.0)); + } + case RNG: + return rcons(trunc1(from(num)), trunc1(to(num))); + default: + break; + } + uw_throwf(error_s, lit("trunc: invalid operand ~s"), num); +} + val trunc(val anum, val bnum) { + if (missingp(bnum)) + return trunc1(anum); tail: switch (TAG_PAIR(tag(anum), tag(bnum))) { case TAG_PAIR(TAG_NUM, TAG_NUM): @@ -5691,7 +5691,7 @@ void eval_init(void) reg_fun(intern(lit("-"), user_package), func_n1v(minusv)); reg_fun(intern(lit("*"), user_package), func_n0v(mulv)); reg_fun(intern(lit("abs"), user_package), func_n1(abso)); - reg_fun(intern(lit("trunc"), user_package), func_n2(trunc)); + reg_fun(intern(lit("trunc"), user_package), func_n2o(trunc, 1)); reg_fun(intern(lit("mod"), user_package), func_n2(mod)); reg_fun(intern(lit("trunc-rem"), user_package), func_n2(trunc_rem)); reg_fun(intern(lit("wrap"), user_package), func_n3(wrap)); @@ -31617,87 +31617,35 @@ A character may not be an operand of multiplication. .PP -.coNP Functions @, / @ trunc, @ mod and @ trunc-rem +.coNP Function @ / .synb -.mets (/ <> [ dividend ] << divisor *) -.mets (trunc < dividend << divisor ) -.mets (mod < dividend << divisor ) -.mets (trunc-rem < dividend << divisor ) +.mets (/ << divisor ) +.mets (/ < dividend << divisor *) .syne .desc -The arguments to these functions are numbers. Characters are not permitted. - The .code / function performs floating-point division. Each operands is first -converted to floating-point type, if necessary. If -.meta dividend -is omitted, -then it is taken to be -.code 1.0 -and the function calculates the reciprocal. Of these division functions, -only this one may be called with just one argument, or with more than two -arguments. If there are more than two arguments, then each additional argument -is treated as an additional divisor which further divides the result of the -division by the previous divisors. - -The -.code trunc -function performs a division of +converted to floating-point type, if necessary. In the one-argument +form, the .meta dividend -by -.meta divisor -whose result -is truncated to integer toward zero. If both operands are integers, then an -integer division is performed and the result is an integer. If either operand -is a floating point value, a floating point division occurs, and the result is -truncated toward zero to a floating-point integral value. - -The -.code mod -function performs a modulus operation. Firstly, the absolute value -of +argument is omitted. An implicit dividend is present, whose value is +.codn 1.0 , +such that the one-argument form +.code "(/ x)" +is equivalent to the two-argument form +.codn "(/ 1.0 x)" . + +If there are two or more arguments, explicitly or by the above equivalence, +then a cumulative division is performed. The .meta divisor -is taken to be a modulus. Then a residue of -.meta dividend -with respect to -.meta modulus -is calculated. The residue's sign follows -that of the sign of -.metn divisor . -That is, it is the smallest magnitude -(closest to zero) residue of -.meta dividend -with respect to the absolute -value of -.metn divisor , -having the same sign as -.metn divisor . -If the operands are integer, the result is an integer. If either operand -is of type float, then the result is a float. The modulus operation is -then generalized into the floating point domain. For instance the expression -.code "(mod 0.75 0.5)" -yields a residue of 0.25 because 0.5 "goes into" 0.75 only -once, with a "remainder" of 0.25. - -The -.code trunc-rem -function returns a list of two values: a -.meta quotient -and a -.metn remainder . -The -.meta quotient -is exactly the same value as what -.code trunc -would return for the same inputs. -The -.meta remainder -obeys the following identity: - -.cblk -.mets (eql < remainder (- < dividend >> (* divisor << quotient ))) -.cble +value is taken into consideration, and divided by the first +.codn divisor . +If another +.code divisor +follows, then that value is divided by that subsequent divisor. +This process repeats until all divisors are exhausted, and the +value of the last division is returned. .coNP Functions @ wrap and @ wrap* .synb @@ -31838,14 +31786,16 @@ is positive, it is returned. If is negative, its additive inverse is returned: a positive number of the same type with exactly the same magnitude. -.coNP Functions @, floor @ ceil and @ round +.coNP Functions @, trunc @, floor @ ceil and @ round .synb +.mets (trunc < dividend <> [ divisor ]) .mets (floor < dividend <> [ divisor ]) .mets (ceil < dividend <> [ divisor ]) .mets (round < dividend <> [ divisor ]) .syne .desc The +.codn trunc , .codn floor , .code ceiling and @@ -31880,6 +31830,10 @@ and the result is a range composed of these two individual quotients. When the quotient is a scalar value, +.code trunc +returns the closest integer, in the zero direction, +from the value of the quotient. +The .code floor function returns the highest integer which does not exceed the value of the quotient. That is to say, the division is @@ -31916,6 +31870,62 @@ harmonizes with the semantics of the .code round function in the C language. +.coNP Function @ mod +.synb +.mets (mod < dividend << divisor ) +.syne +.desc +The +.code mod +function performs a modulus operation. Firstly, the absolute value +of +.meta divisor +is taken to be a modulus. Then a residue of +.meta dividend +with respect to +.meta modulus +is calculated. The residue's sign follows +that of the sign of +.metn divisor . +That is, it is the smallest magnitude +(closest to zero) residue of +.meta dividend +with respect to the absolute +value of +.metn divisor , +having the same sign as +.metn divisor . +If the operands are integer, the result is an integer. If either operand +is of type float, then the result is a float. The modulus operation is +then generalized into the floating point domain. For instance the expression +.code "(mod 0.75 0.5)" +yields a residue of 0.25 because 0.5 "goes into" 0.75 only +once, with a "remainder" of 0.25. + +.coNP Function @ trunc-rem +.synb +.mets (trunc-rem < dividend << divisor ) +.syne +.desc +The +.code trunc-rem +function returns a list of two values: a +.meta quotient +and a +.metn remainder . +The +.meta quotient +is exactly the same value as what +.code trunc +would return for the same inputs. +The +.meta remainder +obeys the following identity: + +.cblk +.mets (eql < remainder (- < dividend >> (* divisor << quotient ))) +.cble + .coNP Functions @, sin @, cos @, tan @, asin @, acos @ atan and @ atan2 .synb .mets (sin << radians ) |