Stream: contributing

Topic: divFloor vs divRound vs divTrunc


view this post on Zulip Kevin Gillette (Apr 14 2022 at 05:03):

Looking at compiler/builtins/docs/Num.roc:784-805, // is documented as desugaring to Num.divRound (which isn't actually defined/implemented). In TUTORIAL.md:1944, and roc-for-elm-programmers.md:1297, it's defined as desugaring to Num.divFloor.

The present behavior is clearly divTrunc(ate), which doesn't appear to have an corresponding, precisely-named function. We had internal references to a "NUM_DIV_INT" which was accurate but perhaps whose naming is too circular ("integer division has the behavior that integer division has"). I had mistakenly conflated flooring division with truncating division in https://github.com/rtfeldman/roc/pull/2840.

» 23 // 13

1 : Int *

» -23 // 11

-2 : Int *

» 23 // -11

-2 : Int *

If the behavior were Num.divRound, we'd expect 23 // 13 == 2, and if it were Num.divFloor (at least, iiuc, following the mathematical meaning of floor, i.e. "towards negative infinity"), we'd expect -23 // 11 == -3.

I'm assuming C as well as the integer signed division operation in most modern hardware "truncates towards zero," thus is the behavior most programmers would expect across the broadest swath of languages.

Further, I suspect most programmers share in my weakness of not being great at internalizing edge cases involving negative numbers. We may think of a flooring operation as "going towards zero" since that's what it does for positive results (even though more precisely we'd call it a "truncating" operation); likewise we might incorrectly/casually think of a ceiling operation as "going away from zero." Mathematically, ceiling should be going towards positive infinity, again, iiuc.

» Num.divCeil -5 2

-2 : Int *

» Num.divFloor -5 2

-2 : Int *

In any case, these should never produce the same answer when there's a non-zero remainder.

I propose the following:

  1. Num.divFloor is renamed to Num.divTruncate (since that's the behavior it implements already).
  2. // is redefined as desugaring to Num.divTruncate.
  3. We decide if we want to implement Num.divRound.
  4. We decide if we want to implement a true Num.divFloor (Num.divCeil is correct but actually no longer has a paired opposite-rounding variant).
  5. We evaluate whether we want Num.divRoundAwayFromZero (a more succinct yet equally precise name to be determined). If we decide we want it, that may suggest the name of Num.divTruncate should actually be something like Num.divRoundTowardsZero.

view this post on Zulip Brendan Hansknecht (Apr 14 2022 at 05:16):

I agree that the default should be that integer division goes towards zero, which would match what c++ does and most other languages. It also is likely easier to reason about for most people.

I think that if we have a divCeil we should also have a divFloor. I think that these should go towards positive and negative infinity respectively. Otherwise, I think the naming would be very confusing because they wouldn't match what ceil and floor normally do.

I think that divTruncate is an ok name. Though maybe we want to to be part of the group of rounding specific functions something like divRoundIn, divRoundOut, divRound. Of course those aren't great names, but divRoundUp and divRoundDown are ambiguous so in and out are my best thoughts so far if we want explicit rounding options.

view this post on Zulip Kevin Gillette (Apr 14 2022 at 05:18):

ooh, I like divRoundIn. Very concise and technically unambiguous (if the implied relative anchor is correctly inferred by the reader, that is).

view this post on Zulip Kevin Gillette (Apr 14 2022 at 05:20):

Up, Down, In, and Out, taken together, sounds a bit like subatomic particle (quark) naming (https://global.jaxa.jp/article/interview/vol43/img/photo_04_e.gif)... probably not something we want to replicate.

view this post on Zulip Brendan Hansknecht (Apr 14 2022 at 05:22):

So we want divRoundStrange and divRoundCharm? I think that would be a good feature to have only enabled on april fools day.

view this post on Zulip Kevin Gillette (Apr 14 2022 at 05:23):

And leap day.

view this post on Zulip Richard Feldman (Apr 14 2022 at 11:16):

good catch @Kevin Gillette!

I agree, we should rename the current divFloor to divTrunc :thumbs_up:

view this post on Zulip Richard Feldman (Apr 14 2022 at 11:16):

also should probably get rid of divRound and divFloor in the docs, and consider re-adding them later if there's demand

view this post on Zulip Kevin Gillette (Apr 14 2022 at 13:34):

Richard Feldman said:

I agree, we should rename the current divFloor to divTrunc :thumbs_up:

Sounds good. I'll do that as part of the non-div aspects of https://github.com/rtfeldman/roc/issues/2826, which I should be able to wrap up soon (the issue isn't actually properly complete yet, as only the "div" changes are merged).

view this post on Zulip Kevin Gillette (Apr 17 2022 at 22:18):

https://github.com/rtfeldman/roc/pull/2883 should be ready.


Last updated: Jul 06 2025 at 12:14 UTC