summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-02-26 07:33:09 -0800
committerKaz Kylheku <kaz@kylheku.com>2017-02-26 07:33:09 -0800
commita66888b6e07dbfd6b22dcd7fa9e240692c17a039 (patch)
tree251e76409dbe78994bd4eb9ed4ea7237020bd47e
parent0f32fe85728e4ee35a25094d99bdf7b3ff1630a7 (diff)
downloadtxr-a66888b6e07dbfd6b22dcd7fa9e240692c17a039.tar.gz
txr-a66888b6e07dbfd6b22dcd7fa9e240692c17a039.tar.bz2
txr-a66888b6e07dbfd6b22dcd7fa9e240692c17a039.zip
New floor-rem, ceil-rem and round-rem.
* arith.c (trunc_rem): Move function to below round function. Make second argument optional, defaulting to one. (floor_rem, ceil_rem, round_rem): New functions. * eval.c (eval_init): Registration of trunc-rem altered for optional argument. New registrations for floor-rem, ceil-rem, round=rem. * txr.1: Documented for new functions folded with trunc-rem.
-rw-r--r--arith.c35
-rw-r--r--eval.c5
-rw-r--r--lib.h5
-rw-r--r--txr.132
4 files changed, 59 insertions, 18 deletions
diff --git a/arith.c b/arith.c
index 483efa15..1dff8eb6 100644
--- a/arith.c
+++ b/arith.c
@@ -1090,13 +1090,6 @@ divzero:
uw_throw(numeric_error_s, lit("mod: division by zero"));
}
-val trunc_rem(val anum, val bnum)
-{
- val quot = trunc(anum, bnum);
- val rem = minus(anum, mul(quot, bnum));
- return list(quot, rem, nao);
-}
-
val floordiv(val anum, val bnum)
{
if (missingp(bnum))
@@ -1312,6 +1305,34 @@ val roundiv(val anum, val bnum)
}
}
+val trunc_rem(val anum, val bnum)
+{
+ val quot = trunc(anum, bnum);
+ val rem = minus(anum, mul(quot, if3(missingp(bnum), one, bnum)));
+ return list(quot, rem, nao);
+}
+
+val floor_rem(val anum, val bnum)
+{
+ val quot = floordiv(anum, bnum);
+ val rem = minus(anum, mul(quot, if3(missingp(bnum), one, bnum)));
+ return list(quot, rem, nao);
+}
+
+val ceil_rem(val anum, val bnum)
+{
+ val quot = ceildiv(anum, bnum);
+ val rem = minus(anum, mul(quot, if3(missingp(bnum), one, bnum)));
+ return list(quot, rem, nao);
+}
+
+val round_rem(val anum, val bnum)
+{
+ val quot = roundiv(anum, bnum);
+ val rem = minus(anum, mul(quot, if3(missingp(bnum), one, bnum)));
+ return list(quot, rem, nao);
+}
+
val wrap_star(val start, val end, val num)
{
val modulus = minus(end, start);
diff --git a/eval.c b/eval.c
index bc58d303..62c24170 100644
--- a/eval.c
+++ b/eval.c
@@ -5693,7 +5693,6 @@ void eval_init(void)
reg_fun(intern(lit("abs"), user_package), func_n1(abso));
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));
reg_fun(intern(lit("wrap*"), user_package), func_n3(wrap_star));
reg_fun(intern(lit("/"), user_package), func_n1v(divv));
@@ -5705,6 +5704,10 @@ void eval_init(void)
reg_fun(intern(lit("floor"), user_package), func_n2o(floordiv, 1));
reg_fun(intern(lit("ceil"), user_package), func_n2o(ceildiv, 1));
reg_fun(intern(lit("round"), user_package), func_n2o(roundiv, 1));
+ reg_fun(intern(lit("trunc-rem"), user_package), func_n2o(trunc_rem, 1));
+ reg_fun(intern(lit("floor-rem"), user_package), func_n2o(floor_rem, 1));
+ reg_fun(intern(lit("ceil-rem"), user_package), func_n2o(ceil_rem, 1));
+ reg_fun(intern(lit("round-rem"), user_package), func_n2o(round_rem, 1));
reg_fun(intern(lit("sin"), user_package), func_n1(sine));
reg_fun(intern(lit("cos"), user_package), func_n1(cosi));
reg_fun(intern(lit("tan"), user_package), func_n1(tang));
diff --git a/lib.h b/lib.h
index 590a912d..9e64ba89 100644
--- a/lib.h
+++ b/lib.h
@@ -636,7 +636,6 @@ val mulv(struct args *);
val divv(val dividend, struct args *);
val trunc(val anum, val bnum);
val mod(val anum, val bnum);
-val trunc_rem(val anum, val bnum);
val wrap_star(val start, val end, val num);
val wrap(val start, val end, val num);
val divi(val anum, val bnum);
@@ -683,6 +682,10 @@ val floordiv(val, val);
val ceili(val);
val ceildiv(val anum, val bnum);
val roundiv(val anum, val bnum);
+val trunc_rem(val anum, val bnum);
+val floor_rem(val anum, val bnum);
+val ceil_rem(val anum, val bnum);
+val round_rem(val anum, val bnum);
val sine(val);
val cosi(val);
val tang(val);
diff --git a/txr.1 b/txr.1
index 2045cf21..8a1e77ae 100644
--- a/txr.1
+++ b/txr.1
@@ -31902,25 +31902,39 @@ then generalized into the floating point domain. For instance the expression
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
+.coNP Functions @, trunc-rem @, floor-rem @ ceil-rem and @ round-rem
.synb
-.mets (trunc-rem < dividend << divisor )
+.mets (trunc-rem < dividend <> [ divisor ])
+.mets (floor-rem < dividend <> [ divisor ])
+.mets (ceil-rem < dividend <> [ divisor ])
+.mets (round-rem < dividend <> [ divisor ])
.syne
.desc
-The
-.code trunc-rem
-function returns a list of two values: a
+These functions, respectively, perform the same division operation
+as
+.codn trunc ,
+.codn floor ,
+.codn ceil ,
+and
+.codn round ,
+referred to here as the respective target functions.
+
+If the
+.meta divisor
+is missing, it defaults to 1.
+
+Each 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.
+is exactly the same value as what would be returned by the
+respective target function for the same inputs.
+
The
.meta remainder
-obeys the following identity:
+value obeys the following identity:
.cblk
.mets (eql < remainder (- < dividend >> (* divisor << quotient )))