Л - не логика, а lua
> nan
nil
> a=0/0
> a
-nan
> a==nill
false
> a==nan
false
> a==-nan
stdin:1: attempt to perform arithmetic on a nil value (global 'nan')
stack traceback:
stdin:1: in main chunk
[C]: in ?
После присматривания к результатам... в целом, претензия только к выводу nan как nil.
no subject
no subject
С точки зрения логики, мы точно знаем, что 0/0 не равен 0/0. Можно применить иезуитство и сказать, что мы точно знаем, что 0/0 не не равен 0/0, но для практических целей достаточно, что 0/0 != 0/0 (или любая другая такая штука, типа inf - inf).
Задача: выполнить вычисления и не дать ложных результатов.
Для желающих можно включить исключительные ситуации и упасть, но часто бывает, что проще продолжать считать, и просто "poison" результаты. Если оно не расползётся, результаты можно большей частью использовать. Если расползётся, ну, хотя бы мы это знаем.
С точки зрения типов, это что-то типа такого:
Either<f64, poisoned>
причём все poisoned все операции f64 поддерживает, но возвращает poisoned.
Так же poisoned.cmd(poisoned) == False.
Так же:
>>> math.nan < math.nan
False
>>> math.nan > math.nan
False
>>> math.nan >= math.nan
False
и т.д.
no subject
no subject
А вот ты уверен? Прости, я не могу писать угловыми скобками, пусть будут квардратные.
Option[f64] = (Some(f64), None)
poison (он же NaN) => None.
Теперь у нас есть код:
if min_x <= x <= max_x {
...
}
Если у тебя Option, то у тебя None == None, и условие выполняется (если все три nan).
Предположим, в min_x оказалось nan (то есть poison). Инженерный подход - nan сам себе не равен. Так, чтобы если у нас есть такое выражение, то оно было бы false в случае nan на любой позиции.
Option эту проблему не решает.
no subject
someResult match case None => println("no result") case Some(result) => println(s"Success: $result")Работать не будет. Вообще интуиционистской логики не построить. Там равенство определяется как классификатор диагонали. Так что нельзя будет определять, например, подобъекты.
В принцпе, NaN нахер не нужен при вычислениях - это сигнал, что результата нет, т.к. функция частичная. Ну, например, кольцо целых чисел не является полем. Ну и чо? На хрена?
no subject
Бонус: мы видим, какие данные были повреждены, потому что nan'ы заразны (кроме bool'ов, для которых я бы тоже предпочёл poison, но там уже семантика if'ов ползёт). Это всё было придумано практиками, "чтобы считало", а не пришло из теории, насколько я понимаю.
Наверное, где-то есть более формальное и точное описание этой логики (всёж, IEEE стандарт).
Я тут робота послал, он нашёл вот это:
Bagnara, R., Bagnara, A., Biselli, F., Chiari, M. & Gori, R. «Correct Approximation of IEEE 754 Floating-Point Arithmetic for Program Verification». arXiv:1903.06119 (2019).
https://arxiv.org/abs/1903.06119
Brain, M., Tinelli, C., Rümmer, P. & Wahl, T. «An Automatable Formal Semantics for IEEE-754 Floating-Point Arithmetic». 22nd IEEE Symposium on Computer Arithmetic (ARITH 2015): 160–167.
https://dblp.dagstuhl.de/rec/conf/arith/BrainTRW15.html
Но я это уже понять не могу в силу мощности моего семантического многообразия.
no subject
no subject
Да, вычисления на float'ах отличаются от тех, которые тебе хотелось бы видеть. Я вот тоже не люблю комплексные числа. И?
-Inf, Inf, -0, +0, Nan - и они образуют интересную структуру, в которой есть делители нуля.
no subject
no subject
no subject
no subject
В плавучей арифметике сложение и умножение в общем случае не ассоциативно и без всяких NaN’ов, чисто за счёт ограниченной битности мантиссы. Примерно в духе (2^N + 1) + 1 = 2^N + 1 = 2^N, но 2^N + (1 + 1) = 2^N + 2.
no subject
Короче да, это не математика, а ближе к химии.
no subject
no subject
no subject
(смотрю в сторону java-отдела, которому в очередной раз подняли лимиты до 300Гб по памяти)