[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