Почему Rust не реализует полное упорядочение через черту Ord для f64 и f32?

18

Пока все целые типы в Rust реализуют Ord , который подчеркивает общий порядок , типы с плавающей запятой реализуют PartialOrd . Это означает, что могут быть значения с плавающей запятой, которые нельзя сравнивать. Это сложно переварить, поскольку числа с плавающей запятой можно рассматривать как приближения к действительным числам, которые являются полностью упорядоченным множеством. Даже добавление положительной и отрицательной бесконечности позволяет полностью упорядочить множество действительных чисел. Почему этот странный выбор в Rust?

Это ограничение означает, что общий алгоритм сортировки / поиска может принимать только частичный порядок чисел. Стандарт IEEE 754, как представляется, обеспечивает общий предикат порядка .

Является ли проблема NaN проблемой общего кода?     

задан Shailesh Kumar 21.10.2014 в 16:52
источник

1 ответ

13

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

Определение обычных операторов сравнения IEEE 754 < , <= , ... делает их очень полезными вообще, если не тогда, когда вам нужен полный порядок. В частности, легко записать условия, чтобы входы ошибок были отправлены в ветвь ошибки:

if (!(x <= MAX)) { // NaN makes this condition true
  error();
}

if (!(x >= MIN)) { // NaN makes this condition true
  error();
}

Поскольку < и <= настолько полезны, они являются операциями, реализованными как единые быстрые инструкции в современных процессорах - предикат totalOrder от IEEE 754 обычно не реализован на аппаратном уровне. Языки программирования отображают быстрые инструкции для построения на языке и оставляют всех, кто исключительно нуждается в totalOrder, выбирать его из библиотеки или даже сами определять.

    
ответ дан Pascal Cuoq 21.10.2014 в 17:14
  • Я не знал, что предикат общего порядка не реализован в аппаратном обеспечении. –  Shailesh Kumar 21.10.2014 в 18:06
  • @ShaileshKumar Вы можете получить один полный предикат порядка (я не знаю, точно ли он такой же, как у IEEE 754), сначала сравнивая знаки значений (- <+), а затем, если значения одного и того же знака, сравнивая другие биты с целочисленной инструкцией по сравнению с битами представления. –  Pascal Cuoq 21.10.2014 в 18:23