I am attaching a file that tries to "do the right thing" for Clojure's
other numeric types, for inclusion in the contribs, or possibly the
core. I have sent in a contributor agreement, but am unfamiliar with
the submission process. Do I just attach the file here, or is there
somewhere I'm supposed to upload them? Are there standards for
documenting and including test cases that I need to follow?
I started with expt, because the lack of expt was the biggest nuisance
for me. If you give it an exact number (i.e., not a floating point),
and an integer exponent, it will give you a precise result, otherwise
it calls Java's double version of pow. I posted this the other day,
but it is included again here, with a couple minor tweaks.
Next, I did floor, ceiling, and round. All of these functions yield
an integer if the input is an exact number, otherwise they do whatever
Java's double version does (Java's floor and ceiling yield doubles,
and round yields an integer or the max int if out of range). round is
a round-up to mimic Java's behavior (I think that in Scheme, round is
usually a round-to-even, so this is a potential gotcha to be aware
of).
Those are the additions that I consider most essential.
While I was at it, I added implementations for abs and mod, which are
standard in most languages, and gcd which is standard in Scheme.
Also, I added a version of sqrt that gives an exact answer whenever
there is an exact answer (works on integers, decimals, and fractions),
otherwise it gives you whatever Java's sqrt produces. I don't know
how generally useful this is, but it's the behavior I've come to
expect from working with Scheme.
I hope everyone finds these functions as useful as I do.
P.S. While writing these functions, I really liked working with
Clojure's multimethod system, and found it very intuitive to set up
functions that do the right things. For example, expressing a custom
version of expt when the base is "exact" and the power is "some kind
of integer type" was a snap.
Ideally I'd also like that, but since complex numbers aren't part of
Clojure's numeric tower, and since there isn't one official Java
implementation of complex numbers (as far as I know), I just do what
Java's sqrt function does (i.e., return NaN).