IEEE 754: why predicates == and != are not signaling? - ieee-754

Note: understanding IEEE 754. Please be patient.
IEEE 754-2008:
Table 5.2 lists five unordered-signaling predicates and their negations that cause an invalid operation exception when the relation is unordered. That invalid operation exception defends against unexpected quiet NaNs arising in programs written using the
standard predicates {<, <=, >=, >} and their negations, without considering the possibility of a quiet NaN operand.
Question: why == and != predicates are not in the {} list? The unexpected quiet NaNs can arise in programs written using predicates == and != as well.

Question: why == and != predicates are not in the {} list?
Because it is a list of traditionally-signaling predicates, and the == and != operations are traditionally quiet. The {} list is not a parenthetical -- it is an enumeration of the operations being described. The spec does define signaling equal and notEqual predicates, and these are listed in table 5.2, but they simply are not what the quoted sentence is talking about. The spec also defines quiet versions of Greater, etc. (listed in table 5.3); these are of course not what the quoted sentence is talking about either.
All the signaling versions, including compareSignalingEqual() and compareSignalingNotEqual(), have the property that they are
intended for use by programs not written to take into
account the possibility of NaN operands
(introduction to table 5.2; emphasis in the original).

Related

Material Conditional and Equivalence in Programming

I have just started reading into propositional calculus/logic, and have realised that a lot of the foundational concepts in this area are similar to those encountered in programming. That is, propositions/sentences in logic (due to the fact that they have truth-values), are similar to Booleans in programming. Furthermore, most of the sentential connectives are reflected in the logical operators adopted in programming. For instance, in C++, !, &&, and || behave in the same way that ¬, ∧, and ∨ behave, respectively, in logic.
My question is whether there are (say, C++) "equivalents" for the logical operators of implication (->) and equivalence (<->)? If so, what are they? If not, what is the reason they have they not been adopted? So, although I cannot think of any reason why they would be adopted, I would like to know if there is a specific reason that they are omitted.
Implication can be replaced with <=, and equivalence is ==.
However, unlike && and ||, those don't convert their arguments to bool (since they're not inherently boolean operators).

C++: My program compiles perfectly but doesn't run [duplicate]

A question was posted about chained comparison operators and how they are interpreted in different languages.
Chaining comparison operators means that (x < y < z) would be interpreted as ((x < y) && (y < z)) instead of as ((x < y) < z).
The comments on that question show that Python, Perl 6, and Mathematica support chaining comparison operators, but what other languages support this feature and why is it not more common?
A quick look at the Python documentation shows that this feature has been since at least 1996. Is there a reason more languages have not added this syntax?
A statically typed language would have problems with type conversion, but are there other reasons this is not more common?
It should be more common, but I suspect it is not because it makes parsing languages more complex.
Benefits:
Upholds the principle of least surprise
Reads like math is taught
Reduces cognitive load (see previous 2 points)
Drawbacks:
Grammar is more complex for the language
Special case syntactic sugar
As to why not, my guesses are:
Language author(s) didn't think of it
Is on the 'nice to have' list
Was decided that it wasn't useful enough to justify implementing
The benefit is too small to justify complicating the language.
You don't need it that often, and it is easy to get the same effect cleanly with a few characters more.
Scheme (and probably most other Lisp family languages) supports multiple comparison efficiently within its grammar:
(< x y z)
This can be considered an ordinary function application of the < function with three arguments. See 6.2.5 Numerical Operations in the specification.
Clojure supports chained comparison too.
Chained comparison is a feature of BCPL, since the late 1960s.
I think ICON is the original language to have this, and in ICON it falls out of the way that booleans are handled as special 'fail' tags with all other values being treated as true.

Is there a sensible scenario, where the == operator is not the negation of the !=

As a follow-up to my previous question (Does overriding the operator == for a class automatically override the operator !=),
is there a scenario, where you would override the == and != operators to not be the negation of each other,
where the negation would be defined as:
(!(a == b)) == (a != b)
or
(a == b) == (!(a != b))
No, in a broad sense. Stepanov would say that if you don’t follow this rule of logic then you get what you deserve. That is why in C++20 they will be by default defined by each other just like he wanted.
In practice, yes, there are at least two scenarios.
NaN (not-a-number) in IEEE floating point numbers. Two NaN are different and not not equal at the same time.
As noted in the comment. The logical inconsistency is not exactly between == and !=, but it is related: you can do a = b; assert( a != b); or have assert( a != a ).
Expression constructs, aka expression templates, aka DSL. == and != create two independent expressions. Logically, they should be still be opposites but not in the sense that they are simple Boolean values. Take a look at Boost.Phoenix or Boost.Spirit. These libraries wouldn’t be possible if the language forces to return bools for these operations and one as the negation of the other.
In both cases you can reinterpret the situation to "restore" the logical rule. For example 1) you can say that once there is a NaN in your system the program is not in a logical state anymore. 2) you can say that the "expression" a != b should be also generated by !(a == b) even if they are not immediately bools.
So, even if the language lets you, you shouldn’t play with the rules of logic.
There is also the myth that supposedly sometimes checking for inequality should be faster than checking for equality or vise versa, as an excuse to implement them separately which can lead to logical inconsistency.
This is nonsense given the short circuiting of logical operations that are fundamental to C++ and should be of any system built on top of C++.
This happens all the time when working with databases, where a NULL value fails every comparison.
So, if you're implementing objects that model data that comes from a database, and you have an object that represents a NULL value, comparing something for equality with the NULL value will be false. Comparing it for inequality with a NULL value will also be false. Every kind of comparison will be false. And, the icing on the cake: comparing a NULL value for equality with another NULL value is also false.
Any scenarios where people decided to use === (triple equal) operator to check for equality indicate that if you assume
(!(a === b)) == (a != b)
then your == is not a negation of !=.
Note that I am not implying that there is a === operator in C++! I am illustrating a scenario, as was asked in the question.

The argument of the nan() function

Sometimes there is a need to get NaN value (for example, to return it from a function as an error value). С++11 provides the double nan(const char* tagp); function to get NaN see doc. This function gets C-string argument tagp which:
can be used by library implementations to distinguish different NaN
values in a implementation-specific manner. If this is an empty string (""), the function returns a generic NaN value
I want to understand this function more deeply. Could someone explain in more detail
What tagp values can be used besides empty string ""? Where can I find a list of possible values?
What happens if the passed tagp argument is wrong or not supported by the compiler?
Is it safe to use this implementation-specific function in cross-platform code?
С++11 provides the double nan(const char* tagp);
Some C chapter and verse (C17 § 7.12.11.2)
Description
2 The nan, nanf, and nanl functions convert the string pointed to by tagp according to the following rules. The call nan("n-char-sequence") is equivalent to strtod("NAN(n-char-sequence)", (char**)NULL); the call nan("") is equivalent to strtod("NAN()",(char**)NULL). If tagp does not point to an n-char sequence or an empty string, the call is equivalent to strtod("NAN",(char**)NULL). ...
Returns
3 The nan functions return a quiet NaN, if available, with content indicated through tagp. If the implementation does not support quiet NaNs, the functions return zero.
What tagp values can be used besides empty string ""? Where can I find a list of possible values?
tagp points to a sequence of 0-9, A-Z, a-z, _ characters.
What happens if the passed tagp argument is not supported by the compiler?
If not supported by C/C++ spec, "the call is equivalent to strtod("NAN",(char**)NULL)". This leads to an implementation defined result.
Is it safe to use this implementation-specific function in cross-platform code?
Yes, safe in that undefined behavior is not expected. Yet the meaning and NANs derived are implementation specific.
Interpretation of the n-char-sequence as decimal representation of the NAN payload is a possible outcome subject to limitations above.
See also What uses do floating point NaN payloads have? and wiki NaN

Z3 optimization: detect unboundedness via API

I am experiencing difficulties in detecting unboundedness of an optimization problem. As stated in the examples and in some answers here, the printed result of an unbounded optimization problem equals to something like "oo", which has to be interpreted (via string compare?).
My question is: Is there any way to use the API to detect this?
I've searched for some time now and the only function, which might do what I want is Z3_mk_fpa_is_infinite(Z3_context c, Z3_ast t) which returns some Z3_ast object. The problem is: Is this the right approach and how do I get the unbounded property out of that Z3_ast object?
There is currently no built-in way to extract unbounded values or infinitesimals.
The optimization engine uses ad-hoc constants called "epsilon" (of type Real) and "oo" (of type Real or Integer) when representing maximal/minimal that
are unbounded or at a strict bound. There is no built-in recognizer for these constants and formally, they don't belong to the domain of Reals. They belong to an extension field. So formally, I would have to return an expression over a different number field or return what amounts to a triple of numerals (epsilon, standard numeral, infinite). For example, a standard numeral 5.6 would be represented as (0, 5.6, 0), and a numeral that comes just below 5.6 is represented as (-1, 5.6, 0), and a numeral that is +infinity is (0, 0, 1). Returning three values instead of one seemed no more satisfactory a solution to me as returning an expression. I am leaving it to users to post-process the expressions that are returned and indeed match for symbols "oo" and "epsilon" to decompose the values if they need so.