[erlang-questions] Proposal regarding integer arithmetic
Masatake Daimon
daimon@REDACTED
Tue Nov 22 08:27:30 CET 2011
Thank you very much for your reply! I wasn't expecting anyone to
comment to my proposal ;)
On 11/22/11 11:08, Richard O'Keefe wrote:
> Hardware implementations of integer division often provide
> both the quotient and the remainder. (See the x86 DIV and IDIV
> instructions, for example.) Software implementations of bignum
> division also commonly compute both the quotient and the remainder,
> discarding one at the last minute.
Yes, you are right. I just omitted mentioning that to make my proposal
shorter, to raise the probability of getting it (at least partially)
accepted, even if only slightly.
> Pop-2's integer division provided both quotient and remainder.
> Common Lisp's
>
> (floor N D) => floor(N/D), N-D*floor(N/D)
> (ceiling N D) => ceiling(N/D), N-D*ceiling(N/D)
> (truncate N D) => truncate(N/D), N-D*truncate(N/D)
> (round N D) => round(N/D), N-D*round(N/D)
>
> have long struck me as the right thing to do.
>
> If we had a bunch of functions similar to
> truncate(N, D) when integer(N), integer(D), D =/= 0 ->
> {N div D, N rem D}.
> then the apparent inefficiency in
> {Q,_} = truncate(N, D)
> or {_,R} = truncate(N, D)
> need only be apparent, not real.
That sounds better than "divfloor". I like it.
> The one argument against returning both the quotient and the remainder
> is Knuth's argument for defining X mod 0 to be X.
Hmm... I think Knuth's definition is fairly reasonable, yet it might
be somewhat surprising for some people. Either way is fine with me.
> One operation I've wanted is 'lac' (short for 'lacuna' and letter-shift
> related to 'mod'):
> N lac D = D*ceiling(N/D) - N.
> That answers the question "how much do I need to add to N to make it
> a multiple of D?"
That seems handy, but probably it should go into some module rather
than to be added as an operator. integer: module?
> Masatake Daimon is right that 'div' and 'mod' should be precisely
> documented. Back when the formal specification of Erlang was being
> written, there was a proposal that it should be linked to LIA-1.
> Masatake Daimon may be pleased to hear that LIA-1 has recently been
> revised and that truncating division has been either deprecated or
> removed from the standard, I'm not sure which.
I haven't heard of LIA-1 but I think there are situations where
truncating division is actually needed :)
>>> *** Proposal for new BIFs, math:floor/1 and math:ceil/1 ***
>>>
>>> Why not having math:floor/1 and math:ceil/1? They truncate the
>>> argument towards negative and positive infinity, respectively. Here is
>>> an implementation in Erlang but these should be BIFs:
>>>
>>> -spec floor(number()) -> integer().
>>> floor(X) ->
>>> Y = trunc(X),
>>> case X - Y of
>>> Neg when Neg< 0 -> Y - 1;
>>> _ -> Y
>>> end.
>>>
>>> -spec ceil(number()) -> integer().
>>> ceil(X) ->
>>> Y = trunc(X),
>>> case X - Y of
>>> Pos when Pos> 0 -> Y + 1;
>>> _ -> Y
>>> end.
>
> There is a question about what floor/1 and ceil[ing]/1 should return.
> The floor() and ceil() functions in C return floats.
> Erlang _can_ return integers because it has bignums.
>
> But there are reasons why Common Lisp has ffloor, fceiling, fround, and
> ftruncate as well as floor, ceiling, round, and truncate.
For efficiency? But erlang:trunc/1 does convert float() to
integer(). I don't know how it's implemented though...
>>> *** Proposal for an improvement of the function math:pow/2 ***
>>>
>>> Currently math:pow/2 always returns float() for any arguments, but it
>>> should compute the result in integer() when the base is integer() and
>>> the exponent is non_neg_integer().
>
> Floating point exponentiation and raising to an integer power are just
> plain DIFFERENT FUNCTIONS and should not be overloaded on the same name.
>
> Smalltalk has _ raisedTo: _ and _ raisedToInteger: _
> Haskell has
> (^) :: (Num a, Integral b) => a -> b -> a
> (**) :: (Floating a) => a -> a -> a
>
> I think it would be better if math: remained a predominantly floating-point
> resource, and a new integer: module were added.
I don't think they are mathematically different but I like your idea
of adding integer: module. Unchanged math:pow/2 and new integer:pow/2?
That's totally fine.
>>>
>>> *** Proposal for a new BIF, math:gcd/2 ***
>
> This and lcm also belong in the integer: module, not the math: module.
I agree with you.
Thanks,
Masatake Daimon
--
大門 正岳 <daimon@REDACTED>
More information about the erlang-questions
mailing list