(←) предыдущая запись ; следующая запись (→)
Очень мне нравится показывать, как абстракции, на которые мы привыкли полагаться, оказываются дырявыми и нарушают все наши ожидания. Вот простой пример, который я показывал школьникам про то, что вещественные числа ведут себя не так как кажется.
Пишем сортировку чисел пузырьком. Тут нечему сломаться, да?
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]`