Numeric Overflow management in C#, Java, JavaScript and Python
Tags: dotnet, javascript, java, python
Published: 2022-10-25 10:34:17

Do you now what happens when you increment by one the maximum value of a number? 

The most common and logic answer: I get a **Numeric Overflow Exception**!

*But the real answer is not always or probably never!*

If you don't know how your compiler manage this kind of situation you could design bad algorithms with wrong solutions.

Let's prove that!

## C\# 
In C\# when you increment a max value you don't get a numeric overflow exception (this is a default behavior). Take a look to the following snippet, where the max integer value (2147483647) is incremented by one.

```
int count=int.MaxValue;
Console.WriteLine($"count is {++count}");
```
in this case the output will be **-2147483648** that is clearly an overflow because we get a negative number after an increment of positive number.This happens because the increment rises the most significant bit of the number, the sign bit (+/-).

To trigger an overflow/underflow exception we need to put the operation in a **checked** block like this:

```
int count = int.MaxValue;
checked
{
    Console.WriteLine($"count is {++count}");
}
``` 

Here we go, the exception is served! 
`'System.OverflowException' in overflow-dotnet.dll: 'Arithmetic operation resulted in an overflow.'`

In **C\# compiler** you can enable the option [CheckForOverflowUnderflow](CheckForOverflowUnderflow) where *the default context is a checked context and overflow checking is enabled* (and complementary you can use the keyword **unchecked** to uncheck the context).

## Java

In Java the behavior is very similar to what happens in C#, take a look to the following snippet!

```
Integer count=Integer.MAX_VALUE; // 2147483647
System.out.println(String.format("count is %d",++count));
```
in this case the output will be **-2147483648** that is clearly an overflow like in previous example.

From Java 8 **[Math](https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html)** class provides a set of operations (decrementExact, addExact,multiplyExact, etc. ) for  "checked" arithmetic operations against numeric overflow/underflow.

To trigger an overflow exception we need to use **[Math.incrementExact](https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#incrementExact-int-)** *that returns the argument incremented by one, throwing an exception if the result overflows an int*.

```
Integer count=Integer.MAX_VALUE; // 2147483647
Math.incrementExact(count);
```
here we go, the exception is served:

`Exception in thread "main" java.lang.ArithmeticException: integer overflow at java.base/java.lang.Math.incrementExact(Math.java:964)
	at Main.main(Main.java:12)`


## JavaScript

In JavaScript too we don't have an overflow exception if we increment a maximum value of a number and, at moment of writing, there is no way to detect a numeric overflow exception unless you write a custom function to reach this goal.

Let's prove that.

```
let counter=Number.MAX_VALUE;
console.log(++counter);
```

In the previous snippet we are incrementing by one the maximum value of [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) represented by the constant **Number.MAX_VALUE**. The output of this snippet is **1.7976931348623157e+308** the original value of the variable _counter_ (so the increment has non effect).

But how detect an numeric overflow/underflow JavaScript?

In this [article from algotech.solutions](https://www.algotech.solutions/blog/javascript/handle-number-overflow-javascript/) there are good arithmetic considerations that bring to implement custom functions to detect numeric overflow/underflow.


## Python

In Python 3 integers haven't fixed size ([this article explain how they are structured](https://www.techbeamers.com/why-python-integer-size-bigger-than-c/)) and the only limit is the available memory. For this reason the following code could never stop until the memory is available.

```
from time import sleep

count=int(0)
step = int(10**10000)
while(True):
    count+=step
    sleep(0.2)
```

If we want have more control about the dimension of the integers we can use **[NumPy](https://numpy.org)**

```
import sys
import numpy as np

count=np.int64(sys.maxsize)
count+=1
```
Here we go the exception is served:
`RuntimeWarning: overflow encountered in long_scalars
  count+=1
-9223372036854775808`


## Conclusions

Detecting a _numeric overflow/underflow_ is **expensive** and for this reason many programming languages have as default behavior to ignore it and leave to the programmer to decide if check or uncheck an arithmetic operation. 

What's really matters is the knowledge of the problem and how the implementation of the programming language approaches to this kind of situations. Ignoring or overlooking the problem could lead to an **unexpected results** and **security flaws** (in some scenarios). 

This article has been written because many years ago I wrote an algorithm for a challenge on **[Hackerrank](https://www.hackerrank.com/)** and a silent overflow made fail it (long story short I wasted a lot of time to figure out the nature of the problem).

Suggestions and corrections are welcome.

See you

AM