Сообщение Re[2]: плавающая точка число +/-inf nan от 18.01.2023 11:19
Изменено 19.07.2023 8:19 netch80
Re[2]: плавающая точка число +/-inf nan
Здравствуйте, cppguard, Вы писали:
S>>Удобно ли что (nan == nan) == false ? Ведь партиал ордеринг звучит как излишнее усложнение...
C>Есть numbers и not-a-numbers. Для первых порядок определён полность, а вторым зачем порядок?
Например, чтобы не мучаться с тем, что нельзя даже формально сравнить два float где это надо, или отсортировать массив floatʼов.
Попробуй это сделать в Rust.
Компилируем:
А сделать ordered map по ним? То же самое.
Формально он прав, конечно.
Но после C/C++, которые плевали на то, что для float/double не определён полный порядок, и сортируют такое как хотят — выглядит дико и непривычно, приходится подставлять подпорки такие или такие.
Кстати, можешь сравнить сортировку двух массивов floatʼов с NaN внутри через std::sort и через qsort. В некоторых рантаймах они будут различны
S>>Я бы сделал что nan < -inf И что nan == nan
C>nan это такой способ всё сломать в вычислениях и fail fast. Если обрабатывать nan как число, то ошибка может раствориться.
А какое отношение это имеет к сравнению, когда одновременно оказываются ложными a<b,
a==b и a>b, если одно из них NaN? Тут ошибка не растворится, результат всё равно будет какой-то, и, вероятно, неправильный, если на это не заточились. Может пойти по некорректной ветке алгоритма и самим этим переходом замаскировать ошибку. Например, если условие D>=0 означает наличие корней уравнения, то написать алгоритм в виде
без проверки на NaN значит, что будет утвердительно выдан признак отсутствия, а что вычисления пошли неправильно, замаскируется...
S>>Удобно ли что (nan == nan) == false ? Ведь партиал ордеринг звучит как излишнее усложнение...
C>Есть numbers и not-a-numbers. Для первых порядок определён полность, а вторым зачем порядок?
Например, чтобы не мучаться с тем, что нельзя даже формально сравнить два float где это надо, или отсортировать массив floatʼов.
Попробуй это сделать в Rust.
fn main() {
let mut floats = vec![1.0, 2.0, 3.0];
floats.sort();
println!("{}", floats[0]);
println!("{}", floats[1]);
println!("{}", floats[2]);
}
Компилируем:
error[E0277]: the trait bound `{float}: Ord` is not satisfied
--> src/main.rs:3:5
|
3 | floats.sort();
| ^^^^^^ ---- required by a bound introduced by this call
| |
| the trait `Ord` is not implemented for `{float}`
А сделать ordered map по ним? То же самое.
Формально он прав, конечно.
Но после C/C++, которые плевали на то, что для float/double не определён полный порядок, и сортируют такое как хотят — выглядит дико и непривычно, приходится подставлять подпорки такие или такие.
Кстати, можешь сравнить сортировку двух массивов floatʼов с NaN внутри через std::sort и через qsort. В некоторых рантаймах они будут различны
S>>Я бы сделал что nan < -inf И что nan == nan
C>nan это такой способ всё сломать в вычислениях и fail fast. Если обрабатывать nan как число, то ошибка может раствориться.
А какое отношение это имеет к сравнению, когда одновременно оказываются ложными a<b,
a==b и a>b, если одно из них NaN? Тут ошибка не растворится, результат всё равно будет какой-то, и, вероятно, неправильный, если на это не заточились. Может пойти по некорректной ветке алгоритма и самим этим переходом замаскировать ошибку. Например, если условие D>=0 означает наличие корней уравнения, то написать алгоритм в виде
if (d >= 0) { записать корни; }
else { записать признак отсутствия корней; }
без проверки на NaN значит, что будет утвердительно выдан признак отсутствия, а что вычисления пошли неправильно, замаскируется...
Re[2]: плавающая точка число +/-inf nan
Здравствуйте, cppguard, Вы писали:
S>>Удобно ли что (nan == nan) == false ? Ведь партиал ордеринг звучит как излишнее усложнение...
C>Есть numbers и not-a-numbers. Для первых порядок определён полность, а вторым зачем порядок?
Например, чтобы не мучаться с тем, что нельзя даже формально сравнить два float где это надо, или отсортировать массив floatʼов.
Попробуй это сделать в Rust.
Компилируем:
А сделать ordered map по ним? То же самое.
Формально он прав, конечно.
Но после C/C++, которые плевали на то, что для float/double не определён полный порядок, и сортируют такое как хотят — выглядит дико и непривычно, приходится подставлять подпорки такие или такие.
Кстати, можешь сравнить в C++ сортировку двух массивов floatʼов с NaN внутри через std::sort и через qsort. В некоторых рантаймах они будут различны
S>>Я бы сделал что nan < -inf И что nan == nan
C>nan это такой способ всё сломать в вычислениях и fail fast. Если обрабатывать nan как число, то ошибка может раствориться.
А какое отношение это имеет к сравнению, когда одновременно оказываются ложными a<b,
a==b и a>b, если одно из них NaN? Тут ошибка не растворится, результат всё равно будет какой-то, и, вероятно, неправильный, если на это не заточились. Может пойти по некорректной ветке алгоритма и самим этим переходом замаскировать ошибку. Например, если условие D>=0 означает наличие корней уравнения, то написать алгоритм в виде
без проверки на NaN значит, что будет утвердительно выдан признак отсутствия, а что вычисления пошли неправильно, замаскируется...
S>>Удобно ли что (nan == nan) == false ? Ведь партиал ордеринг звучит как излишнее усложнение...
C>Есть numbers и not-a-numbers. Для первых порядок определён полность, а вторым зачем порядок?
Например, чтобы не мучаться с тем, что нельзя даже формально сравнить два float где это надо, или отсортировать массив floatʼов.
Попробуй это сделать в Rust.
fn main() {
let mut floats = vec![1.0, 2.0, 3.0];
floats.sort();
println!("{}", floats[0]);
println!("{}", floats[1]);
println!("{}", floats[2]);
}
Компилируем:
error[E0277]: the trait bound `{float}: Ord` is not satisfied
--> src/main.rs:3:5
|
3 | floats.sort();
| ^^^^^^ ---- required by a bound introduced by this call
| |
| the trait `Ord` is not implemented for `{float}`
А сделать ordered map по ним? То же самое.
Формально он прав, конечно.
Но после C/C++, которые плевали на то, что для float/double не определён полный порядок, и сортируют такое как хотят — выглядит дико и непривычно, приходится подставлять подпорки такие или такие.
Кстати, можешь сравнить в C++ сортировку двух массивов floatʼов с NaN внутри через std::sort и через qsort. В некоторых рантаймах они будут различны
S>>Я бы сделал что nan < -inf И что nan == nan
C>nan это такой способ всё сломать в вычислениях и fail fast. Если обрабатывать nan как число, то ошибка может раствориться.
А какое отношение это имеет к сравнению, когда одновременно оказываются ложными a<b,
a==b и a>b, если одно из них NaN? Тут ошибка не растворится, результат всё равно будет какой-то, и, вероятно, неправильный, если на это не заточились. Может пойти по некорректной ветке алгоритма и самим этим переходом замаскировать ошибку. Например, если условие D>=0 означает наличие корней уравнения, то написать алгоритм в виде
if (d >= 0) { записать корни; }
else { записать признак отсутствия корней; }
без проверки на NaN значит, что будет утвердительно выдан признак отсутствия, а что вычисления пошли неправильно, замаскируется...