# Arithmethic overflow should not raise an exception

**URL:** <https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006>\
**Category:** Crystal Contrib\
**Created:** [April 26, 2020, 11:30am UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006 "2020-04-26T11:30:00Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![IEatReturnValues4](https://avatars.discourse-cdn.com/v4/letter/i/ecae2f/32.png) [@IEatReturnValues4](https://forum.crystal-lang.org/u/IEatReturnValues4)\
**Post date:** [April 26, 2020, 11:30am UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/1 "2020-04-26T11:30:00Z")

</div>

Arithmetic overflow shouldn’t cause an exception, it should just resort to the default max value.

There’s another overflow problem

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [April 26, 2020, 1:35pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/2 "2020-04-26T13:35:18Z")

</div>

> [@IEatReturnValues4](#):
>
> Arithmetic overflow shouldn’t cause an exception, it should just resort to the default max value.

That would be really terrible! If an arithmetic value can’t be expressed in the designated type, this is a clear example of undefined state which can’t be simply recovered by assigning some default value.

---

<div class="post-metadata">

**Author:** ![IEatReturnValues4](https://avatars.discourse-cdn.com/v4/letter/i/ecae2f/32.png) [@IEatReturnValues4](https://forum.crystal-lang.org/u/IEatReturnValues4)\
**Post date:** [April 26, 2020, 2:19pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/3 "2020-04-26T14:19:51Z")

</div>

Not having an exception, but a value returning the MAX value of an Int type is not a “undefined state”, it’s just a way of not slapping the developer in the face with an exception.

It’s not “assigning **some** default value”, it’s the default value of the type explicitly set by the developer…

---

<div class="post-metadata">

**Author:** ![jhass](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jhass/32/1779_2.png) [@jhass](https://forum.crystal-lang.org/u/jhass)\
**Post date:** [April 26, 2020, 2:30pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/4 "2020-04-26T14:30:23Z")

</div>

Then how does the developer tell whether an addition overflowed or just ended up on the max value? How to tell these two states apart?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [April 26, 2020, 2:38pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/5 "2020-04-26T14:38:28Z")

</div>

If you don’t want an exception you can use the wrapping versions of [https://crystal-lang.org/reference/syntax\_and\_semantics/operators.html#arithmetic-operators](https://crystal-lang.org/reference/syntax_and_semantics/operators.html#arithmetic-operators). They wont raise, but just wrap as they did before overflow detection was implemented.

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [April 26, 2020, 2:58pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/6 "2020-04-26T14:58:47Z")

</div>

I’m starting to think we should disallow unions of primitive numbers

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [April 26, 2020, 3:09pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/7 "2020-04-26T15:09:24Z")

</div>

> [@IEatReturnValues4](#):
>
> Not having an exception, but a value returning the MAX value of an Int type is not a “undefined state”

You’re mixing cause and consequence. The cause is that the result doesn’t fit in the data type. That’s an undefined state. In order to resolve that undefined state state you can take different courses of action. One is assigning an arbitrary value (like the max value of the data type). But in most general cases, raising an exception is certainly the best solution because. It disrupts normal execution because it can’t seriously continue without a way to properly express the return value.

> [@IEatReturnValues4](#):
>
> it’s just a way of not slapping the developer in the face with an exception.

This is actually a very strong case for a situation that requires a slap in the face. Otherwise you would maybe never discover there’s a bug in your code. An arithmetic overflow is very clearly a bug and needs to be resolved.

---

<div class="post-metadata">

**Author:** ![bcardiff](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/bcardiff/32/3_2.png) [@bcardiff](https://forum.crystal-lang.org/u/bcardiff)\
**Post date:** [April 26, 2020, 3:40pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/8 "2020-04-26T15:40:43Z")

</div>

There are some scenarios were saturation arithmetic operations are needed/prefered.

Overflowing (`+`) and modulo (`&+`) are more common IME, and so they have designated operators.

For saturating the LLVM intrinsics can be declared and used. [https://llvm.org/docs/LangRef.html#saturation-arithmetic-intrinsics](https://llvm.org/docs/LangRef.html#saturation-arithmetic-intrinsics)

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [April 26, 2020, 8:30pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/9 "2020-04-26T20:30:45Z")

</div>

> [@asterite](#):
>
> I’m starting to think we should disallow unions of primitive numbers

I tried it, it’s a bit impossible to do. Discarding the idea.

---

<div class="post-metadata">

**Author:** ![RespiteSage](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/respitesage/32/793_2.png) [@RespiteSage](https://forum.crystal-lang.org/u/RespiteSage)\
**Post date:** [April 27, 2020, 2:36pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/10 "2020-04-27T14:36:35Z")

</div>

Rust has a structure for representing saturating math operations (see [here](https://rust-num.github.io/num/num/trait.Saturating.html)). I worked a bit on what that might look like in Crystal a bit ago, but I didn’t think people had a use-case for it, so I didn’t try to make a proper shard out of it. I might do that now. An important note, though, is that it’s necessary to _make_ numeric types saturating; that’s not a way that other languages (as far as I know) work by default, and it’s certainly not a way that normal math usually works.

---

<div class="post-metadata">

**Author:** ![IEatReturnValues4](https://avatars.discourse-cdn.com/v4/letter/i/ecae2f/32.png) [@IEatReturnValues4](https://forum.crystal-lang.org/u/IEatReturnValues4)\
**Post date:** [April 27, 2020, 6:33pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/11 "2020-04-27T18:33:58Z")

</div>

Assume there is a class which has `property gold = 0`. This gold can increase through various ways. The developer already knows the max value will be `2147483647`. However, if that ivar `gold` increases by just one number, there is an exception. It’s already implied that should be the max value. A max value of a number is a perfect relationship with its type.

It’s not a “undefined state” at all. It’s redundant error checking that’s forced on the developer.

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [April 27, 2020, 7:46pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/12 "2020-04-27T19:46:58Z")

</div>

> [@IEatReturnValues4](#):
>
> The developer already knows the max value will be `2147483647`

So later when the client reclaims the amount of gold to the bank, the bank says “Oh, you knew from the beginning that you can only have max 2147483647 gold, right?”.

It seems like if I’m the bank, I’d like to **immediately** know the client is missing money so we later don’t get into trouble.

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [April 27, 2020, 7:51pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/13 "2020-04-27T19:51:15Z")

</div>

(though as a bank it’s very unlikely to make the jump straight from Cobol to Crystal, but…)

---

<div class="post-metadata">

**Author:** ![IEatReturnValues4](https://avatars.discourse-cdn.com/v4/letter/i/ecae2f/32.png) [@IEatReturnValues4](https://forum.crystal-lang.org/u/IEatReturnValues4)\
**Post date:** [April 27, 2020, 7:54pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/14 "2020-04-27T19:54:48Z")

</div>

Okay, I’ll litter my codebase with if statements every time my int value increases, to protect it from an exception. Definitely seems worth it! Wait, let me create a custom method `give_gold` and just use this everywhere! Oh wait, now I’ll need to create a custom method `give_xxx` for each different `ivar`. Got to make sure that int value doesn’t crash my program!

If it was for a bank, your point makes sense. But we’d be using a different type and have limits set already in place as well. For a game, or a int value in hobby programming, it’s insanely annoying.

---

<div class="post-metadata">

**Author:** ![jhass](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jhass/32/1779_2.png) [@jhass](https://forum.crystal-lang.org/u/jhass)\
**Post date:** [April 27, 2020, 7:59pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/15 "2020-04-27T19:59:51Z")

</div>

You sure must be insanely annoyed by a lot of programming languages. Seems exhausting to get upset so much, I wouldn’t want to have to trade with you!

---

<div class="post-metadata">

**Author:** ![IEatReturnValues4](https://avatars.discourse-cdn.com/v4/letter/i/ecae2f/32.png) [@IEatReturnValues4](https://forum.crystal-lang.org/u/IEatReturnValues4)\
**Post date:** [April 27, 2020, 8:04pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/16 "2020-04-27T20:04:24Z")

</div>

Seems exhausting to add one line if statements everywhere to protect an int from raising an exception, yes.

```auto
class Klass
  property gold = 0
end

p = Klass.new

p.gold += Int32::MAX
p.gold += 1
pp p.gold

```

LOL

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [April 27, 2020, 8:06pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/17 "2020-04-27T20:06:20Z")

</div>

> [@IEatReturnValues4](#):
>
> Arithmetic overflow shouldn’t cause an exception, it should just resort to the default max value.

> [@IEatReturnValues4](#):
>
> However, if that ivar `gold` increases by just one number, there is an exception.

Is that not better then silently capping the amount of gold someone can have? Otherwise they would be putting in effort to get more gold but ever have their bank account go up anymore.

The exception makes it more clear there is a bug, and forces you to handle it.

> [@IEatReturnValues4](#):
>
> Seems exhausting to add one line if statements everywhere to protect an int from raising an exception, yes.

I’m confused why you would need to do this? Is it not better to just change the type of the number if it’s possible for it to overflow? Or add in some validation of these values.

Also do remember you can use the wrapping operators, however then you could end up with negative money…

---

<div class="post-metadata">

**Author:** ![IEatReturnValues4](https://avatars.discourse-cdn.com/v4/letter/i/ecae2f/32.png) [@IEatReturnValues4](https://forum.crystal-lang.org/u/IEatReturnValues4)\
**Post date:** [April 27, 2020, 8:15pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/18 "2020-04-27T20:15:36Z")

</div>

> [@Blacksmoke16](#):
>
> The exception makes it more clear there is a bug, and forces you to handle it.

There is no bug, though. The value is simply trying to be added to another value of a type that has a MAX VALUE. If it has reached a max value, it should be set to that max value, not throw an exception.

> [@Blacksmoke16](#):
>
> Is that not better then silently capping the amount of gold someone can have?

I’d argue having the value be set to the max value is far better than an app crashing (assuming they forgot to rescue it)

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [April 27, 2020, 8:28pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/19 "2020-04-27T20:28:57Z")

</div>

> [@IEatReturnValues4](#):
>
> The value is simply trying to be added to another value of a type that has a MAX VALUE

Right, is this not something that should be prevented by some validation before ever reaching the point where the addition happens?

Following on the game example, I as a user spend hours and hours farming for loot to sell. I currently am near the `Int32` max (unbeknownst to me). I then go to the market the sell my spoils. After selling it all I notice I only got 100k gold, when i should have got another 400k, but my gold was capped at the `Int32` max, and I lost the items, and didn’t get compensated for them. How would this not be a bug?

I would expect something to happen when the user tries to sell the loot, saying “hey you reached the max amount of gold, how about sharing the wealth?”, and not allowing that transaction to go through.

> [@IEatReturnValues4](#):
>
> I’d argue having the value be set to the max value is far better than an app crashing (assuming they forgot to rescue it)

Silently ignoring an issue because one did not properly validate user input and/or allowed the game to get into an unhandled state sounds like not the best idea.

---

<div class="post-metadata">

**Author:** ![IEatReturnValues4](https://avatars.discourse-cdn.com/v4/letter/i/ecae2f/32.png) [@IEatReturnValues4](https://forum.crystal-lang.org/u/IEatReturnValues4)\
**Post date:** [April 27, 2020, 8:32pm UTC](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006/20 "2020-04-27T20:32:52Z")

</div>

> [@Blacksmoke16](#):
>
> Silently ignoring an issue because one did not properly validate user input and/or allowed the game to get into an unhandled state sounds like not the best idea.

Crashing an application instead of defaulting a value to its MAX VALUE is not the best idea.

> [@Blacksmoke16](#):
>
> I would expect something to happen when the user tries to sell the loot, saying “hey you reached the max amount of gold, how about sharing the wealth?”, and not allowing that transaction to go through.

Sure, that’s a good system in place! However, the system doesn’t need to raise an exception, it could just be an in-game bug, or a suggestion a player can create.

[Next page](https://forum.crystal-lang.org/t/arithmethic-overflow-should-not-raise-an-exception/2006.md?page=2)
