(←) предыдущая запись ; следующая запись (→)

Очень мне нравится показывать, как абстракции, на которые мы привыкли полагаться, оказываются дырявыми и нарушают все наши ожидания. Вот простой пример, который я показывал школьникам про то, что вещественные числа ведут себя не так как кажется.

Пишем сортировку чисел пузырьком. Тут нечему сломаться, да?

def inplace_bubble_sort(arr):
    if len(arr) <=1:
        return arr
    for i in range(len(arr) - 1, -1, -1):
        for j in range(i):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
    return arr


```Проверяем, что работает

inplace_bubble_sort([1,4,2,9,-5,3,7,0]) # [-5, 0, 1, 2, 3, 4, 7, 9]

 

nan = float(‘nan’) # nan — ‘Not a Number’ floating point number
inplace_bubble_sort([1,4,2,9,nan,-5,3,7,0]) # [1, 2, 4, 9, nan, -5, 0, 3, 7]

для любого `x` сравнения дают `(x < nan)` — False,  `(nan < x)` — False, `(nan == x)` — False и даже `(nan == nan)` — False.
«Благодаря» этим свойствам `nan` не просто не двигается с места, но и не пропускает другие элементы. В массиве появляются как бы «перегородки». Между перегородками элементы отсортированы, но между блоками элементы не смешиваются.
 
Что замечательно, NaN ломает не только нашу доморощенную сортировку, но и встроенную питоновскую сортировку. И... число `4` оказалось левее чем `3`.
`sorted([1,4,2,nan,9,2,-5,3,7,0]) # => [-5, 0, 1, 2, 2, 4, nan, 3, 7, 9]`