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

Ладно… Давайте теперь сломаем сортировку ещё чуть-чуть. Предположим, что у вас есть неупорядоченный набор координат иксов, в котором нет никаких NaN. Вы решили их упорядочить и отрезочками нарисовать по ним гиперболу. Она состоит из двух ветвей, нарисуем их отдельно, чтобы было точнее. Казалось бы, что может пойти не так?

xs = [4, -4, 2, -2, 1, -1, 0.5, -0.5, 0.25, -0.25, 0.0, -0.0]

````xs.sort!
ys = xs.map{|x| 1.0 / x }
points` =

xs.zip(ys)

puts(“Points with x < 0”)
left_side_points = points.select{|x, y| x < 0 }
left_side_points.each{|x,y| puts ”(#{x}, #{y})” }

puts(“Points with x >= 0”)
right_side_points = points.select{|x, y| x >= 0 }
right_side_points.each{|x,y| puts ”(#{x}, #{y})” }

 

Points with x < 0
(-4, -0.25)
(-2, -0.5)
(-1, -1.0)
(-0.5, -2.0)
(-0.25, -4.0)

Points with x >= 0
(0.0, Infinity)
(-0.0, -Infinity)
(0.25, 4.0)
(0.5, 2.0)
(1, 1.0)
(2, 0.5)
(4, 0.25)

```И вот мы получили правую ветвь гиперболы 1/x, которая от +∞ ныряет в -∞, и затем выскакивает в точку (0.25, 4) снизу, а не сверху. Глупость какая-то!

Обратите внимание на список иксов. Там есть x = 0, причём дважды. В некоторых языках (например, в ruby) деление на ноль разрешено. Стандарт разрешает не бросать исключение при такой операции. Ненулевое число, делённое на ноль — это бесконечность. Вот только стандарт определяет две разные бесконечности: положительную и отрицательную. И нулей тоже есть два разных (хотя и равных): +0.0 и -0.0.
При сортировке они могут оказаться в любом порядке, ведь они равны.

[1, +0.0, -1, -0.0].sort # => [-1, 0.0, -0.0, 1]


```Ещё раз подчеркну, что это разные числа, которые по-разному себя ведут: `1 / 0.0 = +Infinity`, а `1 / -0.0 = -Infinity`.
Именно поэтому мы получили «отсортированный» набор иксов, идущих сначала в +0.0, затем в -0.0. И гипербола вслед за иксами уходит в соответствующую область.