ekmett / intervals

Interval Arithmetic
http://hackage.haskell.org/package/intervals
BSD 2-Clause "Simplified" License
27 stars 13 forks source link

Add `div'`, `mod'`, `quot'`, and `rem'`. #10

Closed ekmett closed 7 years ago

ekmett commented 10 years ago

We can't really implement Integral, because of toInteger, but the other methods in there are sane. We could have our own copies.

echatav commented 8 years ago

I needed these and used the NumB and IntegralB class from Boolean.

ekmett commented 8 years ago

Not really comfortable incurring the dep here, but it is good to know there was a way to work around it.

echatav commented 8 years ago

That's fine. Would you still want these functions in the library outside of a typeclass? I think they are

  quot (I l u) (I l' u') =
    if l' <= 0 && 0 <= u' then throw DivideByZero else I
      (minimum [a `Prelude.quot` b | a <- [l,u], b <- [l',u']])
      (maximum [a `Prelude.quot` b | a <- [l,u], b <- [l',u']])
  rem (I l u) (I l' u') =
    if l' <= 0 && 0 <= u' then throw DivideByZero else I
      (minimum [0, signum l * (abs u' - 1), signum l * (abs l' - 1)])
      (maximum [0, signum u * (abs u' - 1), signum u * (abs l' - 1)])
  div (I l u) (I l' u') =
    if l' <= 0 && 0 <= u' then throw DivideByZero else I
      (min (l `Prelude.div` max 1 l') (u `Prelude.div` min (-1) u'))
      (max (u `Prelude.div` max 1 l') (l `Prelude.div` min (-1) u'))
  mod _ (I l' u') =
    if l' <= 0 && 0 <= u' then throw DivideByZero else
      I (min (l'+1) 0) (max 0 (u'-1))
ekmett commented 8 years ago

That seems reasonable.

On Wed, Aug 17, 2016 at 4:44 PM, Eitan Chatav notifications@github.com wrote:

That's fine. Would you still want these functions in the library outside of a typeclass? I think they are

quot (I l u) (I l' u') = if l' <= 0 && 0 <= u' then throw DivideByZero else I (minimum [a Prelude.quot b | a <- [l,u], b <- [l',u']]) (maximum [a Prelude.quot b | a <- [l,u], b <- [l',u']]) rem (I l u) (I l' u') = if l' <= 0 && 0 <= u' then throw DivideByZero else I (minimum [0, signum l * (abs u' - 1), signum l * (abs l' - 1)]) (maximum [0, signum u * (abs u' - 1), signum u * (abs l' - 1)]) div (I l u) (I l' u') = if l' <= 0 && 0 <= u' then throw DivideByZero else I (min (l Prelude.div max 1 l') (u Prelude.div min (-1) u')) (max (u Prelude.div max 1 l') (l Prelude.div min (-1) u')) mod _ (INT (Interval.I l' u')) = if l' <= 0 && 0 <= u' then throw DivideByZero else I (min (l'+1) 0) (max 0 (u'-1))

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ekmett/intervals/issues/10#issuecomment-240541757, or mute the thread https://github.com/notifications/unsubscribe-auth/AASmEbwAJk2GfUFpF6W3J38SIy-DTEXxks5qg3KRgaJpZM4BsEAH .