Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion doc/spec.txt
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,6 @@ Numbers
- *procedure:* atan z
- *procedure:* atan y x
- *procedure:* sqrt z
- *procedure:* expt z1 z2
- *procedure:* make-rectangular x1 x2
- *procedure:* make-polar x3 x4
- *procedure:* real-part z
Expand Down
28 changes: 28 additions & 0 deletions src/number.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
=======================================*/
#define ERRMSG_DIV_BY_ZERO "division by zero"
#define ERRMSG_REQ_1_ARG "at least 1 argument required"
#define ERRMSG_NEGATIVE_EXP "negative exponent"

/*=======================================
File Local Type Definitions
Expand Down Expand Up @@ -417,3 +418,30 @@ scm_p_remainder(ScmObj _n1, ScmObj _n2)

return MAKE_INT(n1 % n2);
}

SCM_EXPORT ScmObj
scm_p_expt(ScmObj _base, ScmObj _expo)
{
scm_int_t base, expo, result;
DECLARE_FUNCTION("expt", procedure_fixed_2);

ENSURE_INT(_base);
ENSURE_INT(_expo);

base = SCM_INT_VALUE(_base);
expo = SCM_INT_VALUE(_expo);

/* SigScheme only implements integer numbers, so negative
exponents are not allowed. */
if (expo < 0) ERR(ERRMSG_NEGATIVE_EXP);
Copy link
Copy Markdown
Member

@kou kou Nov 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment why we return an error here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, done!


result = 1;
while (expo > 0) {
if (expo % 2 == 1)
result *= base;
base *= base;
expo /= 2;
}

return MAKE_INT(result);
}
1 change: 1 addition & 0 deletions src/sigscheme.h
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,7 @@ SCM_EXPORT ScmObj scm_p_abs(ScmObj _n);
SCM_EXPORT ScmObj scm_p_quotient(ScmObj _n1, ScmObj _n2);
SCM_EXPORT ScmObj scm_p_modulo(ScmObj _n1, ScmObj _n2);
SCM_EXPORT ScmObj scm_p_remainder(ScmObj _n1, ScmObj _n2);
SCM_EXPORT ScmObj scm_p_expt(ScmObj _n1, ScmObj _n2);
#endif /* SCM_USE_NUMBER */

/* number-io.c */
Expand Down
8 changes: 8 additions & 0 deletions test/test-number-arith.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1843,5 +1843,13 @@
-9223372036854775808))"))
(else
(assert-fail (tn) "unknown int bitwidth")))
(tn "expt")
(assert-equal? (tn) 9 (expt 3 2))
(assert-equal? (tn) 9 (expt -3 2))
(assert-equal? (tn) 27 (expt 3 3))
(assert-equal? (tn) -27 (expt -3 3))
(assert-equal? (tn) 1 (expt -3 0))
(assert-equal? (tn) 0 (expt 0 11))
(assert-error (tn) (lambda () (expt 3 -2)))

(total-report)