Today I learned a new thing that forced me to reckon my understanding of Python. It is about `//`. It is just not a double slash or typo. It is an operator called integer division. The detail about how this operator works is mentioned in PEP 238. So I came across the Code Signal test and stuck at this question:

I thought that the result of both snippets should be the same. Because in Python, it uses // and in Java, it uses `int` data type. I don’t want to judge alone; you see that the question itself was downvoted a lot. Well, I downvoted it too!

I tried to run the Java (or C++) snippet with an online C++ compiler and played with a random number, but no clue. However, I know that the problem lies in how the rounding process. Maybe Java and C++ round the number to ceil instead of the floor, or vice versa. Fortunately, I gave up quickly and look at `//` instead. As everybody knows, me included, that `//` yields an integer:

``````5//4
# 1
1.25
3//2
# 1
17//3
# 5
``````

while the `/` yields a floating-point number:

``````5/4
#1.25
3/2
# 1.5
17/3
# 5.666666666666667
``````

But I don’t know that `//` is using `floor` division! as mentioned on PEP 238 page:

Floor division will be implemented in all the Python numeric types and will have the semantics of:

``````a // b == floor(a/b)
``````

Except that the result type will be the common type into which a and b are coerced before the operation.

https://www.python.org/dev/peps/pep-0238/#semantics-of-floor-division

Meh, maybe you already guess that, from two snippets before you noticed that `17//3` is `5`, instead of `6`. You may also think that it is maybe `truncate`. But did you know that in negative numbers for example `17//-3`, the result is not `-5`, but `-6`? I did not, at least until today. This stuff is easy if you take a look at the image below:

I just realized that when dealing with a negative number, the `floor` is toward greater digits, in a negatively way. Pun intended. That makes sense. Why `17//-3` is equal to `-6`. Here are other examples:

``````import numpy

np.ceil((-1.9, -1.5, -1.1, 0, 1.1, 1.5, 1.9))
# array([-1., -1., -1.,  0.,  2.,  2.,  2.])

np.floor((-1.9, -1.5, -1.1, 0, 1.1, 1.5, 1.9))
# array([-2., -2., -2.,  0.,  1.,  1.,  1.])

np.round_((-1.9, -1.5, -1.1, 0, 1.1, 1.5, 1.9))
# array([-2., -2., -1.,  0.,  1.,  2.,  2.])
``````

Now it is clear how `//` works.

After digging the rabbit’s hole deeper, I can’t ignore how the `round` function works. Just in case. Let’s take a look at the `round` function. It is a bit tricky they said:

Note The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float. See Floating Point Arithmetic: Issues and Limitations for more information.

https://docs.python.org/3/library/functions.html#round

This is totally understandable since it is an unavoidable technical error about how a computer represents a floating-point number 1. Nevertheless, it is only matters if we work with something that requires cautious number operation.

NumPy also posted a special note about how NumPy `round_()` (equivalent with `around()`) function works:

For values exactly halfway between rounded decimal values, NumPy rounds to the nearest even value. Thus 1.5 and 2.5 round to 2.0, -0.5 and 0.5 round to 0.0, etc.

https://numpy.org/doc/stable/reference/generated/numpy.around.html#numpy.around

This blog post certainly will help me to remember that I should do a test when dealing with division and negative floating-point numbers. I hope it will help you too.