Bit Patterns of Float
quuxplusone.github.io
quuxplusone.github.io
Also worth adding is that NaN comparisons will break catastrophically when using gcc's -ffast-math`.
(So the fact that a binary value is a NaN is portable, but not the distinction between qNaN and sNaN.)
A quiet NaN bit string should be encoded with the first bit (d1) of the trailing significand field T being 1. A signaling NaN bit string should be encoded with the first bit of the trailing significand field being 0
That does use “should” (not “shall”) and is described as a “preferred encoding”, so it’s standards-compliant to do something else, but it’s not recommended.
-x => x xor 0b100…00
abs(x) => x and 0b011…11Code using that hardware was not portable, because each FP unit did things subtly (and sometimes not that subtly) different.
All those already existing hardware units were already doing this type of bit trickery. That's one of the main things that differentiated units from each other.
The people that developed these units all had a stake and were involved in the IEEE process.
That's what "standardization" used to mean. Once you have enough implementations of something that compatibility is an issue, then, with the hindsight of all those implementations, you create a standard.
Today, the meaning of "standardization" is lost. I've seen so many standards that are based on zero actual experience, that had no implementations before the process began, and that 10 years later after many people invested thousands of man hours into a standard document, still have no implementation, some of which, like OpenCL 2 and OpenCL 3 have ended up being "retracted" and we are back to OpenCL 1.
This is particularly true for Khronos standards, Vulkan being the most recent exception. Khronos failures include OpenCL 2, OpenCL 3, OpenMP, SyCL (getting first implementations now, 5-6 years before the first standard was written....). Even for the relatively widely used OpenMP standard, now at version 5, there are still so many features of OpenMP3 that have never been implemented and are arguably useless, that it isn't even funny. Same for OpenMP4 and 5 which mainly added "useless" GPU support (GPU support is important, but the way it was added makes it useless).
The reason Khronos standard suck is because "designers" that can't program hello world write some idea on toilet paper, and sign it off as a standard. Then they ask "the community" to implement it for them, and either nobody cares, or the problem the standard solves are problems nobody has, or the ideas are just wishful thinking that aren't implementable, etc.
The C++ standard is going the same route with signing off on tons of stuff that has little implementation experience, zero proven actual practical value delivered to users.
The best C++ standard spectacular failure example is Concepts. 15 years and thousands of man years invested in designing Concepts, a feature whose main goal is to improve template error messages. Turns out, concepts actually make template error messages worse. They aren't completely useless, but still... who would have thought, right? Well, turns out that every standard that was standardizing standard practice would have... known this... you know... from actual experience...
Clang concepts error messages are longer that the same error message without concepts.
99% of the error in both cases is just garbage.
I generally agree with your posts but concepts have definitely improved my code, I would never in a lifetime go back to SFINAE trickeries.
Concepts are more of a disappointment but they still technically work... I experimented with porting our codebase over to use concepts and all it does is substitute one mess for another mess. That said at the very least with concepts there is now a "standardized" mess that one can use as opposed to the ad-hoc situation that precedes it.
I'd say modules are a bigger example of an actual failure. There were two proposals for modules, clang's and Microsoft's. Clang's built off of Objective-C modules which is widely used on iOS and has a working implementation. Microsoft's modules were built off of... nothing. You can guess which one got standardized.
This along with all kinds of political bickering over the ABI is why clang has stepped down from its various roles in the standardization process and it's a really unfortunate outcome not only for C++ standardization but also for the broader C++ community.
The main goal of modules is to improve compilation times, but if you already have a modularized code base, and are using PCH, then modules don't improve compile-time, at all.
Migrating from PCH to modules is quite a lot of work, for minimal added value, and a lot of disappointment.
Kahan also had experience because of his work for Intel on FP coprocessing. He couldn’t talk about the then not-yet-released parts, but he pushed hard for implementation decisions that other committee members said were too expensive but that he knew had been solved at Intel.
One of the well-known people in this research area is Bill Kahan, and on his webpage (http://people.eecs.berkeley.edu/~wkahan/) he has a bunch of, uhm, rants about floating-point arithmetic. If you read some of them, you can find clear explicit examples of arithmetic that's not IEEE-compliant, and does weird hard-to-understand confusing things that don't really happen any more. (For example, p.4 of http://people.eecs.berkeley.edu/~wkahan/Mind1ess.pdf, and you can dig around his page for more examples; none of these were done out of malice by programmers, they just didn't think things through, which is what Kahan is writing about)
https://stackoverflow.com/a/47466459/164234
According to that, this was added in C++20 and means
> There’s a new three-way comparison operator, <=>. The expression a <=> b returns an object that compares <0 if a < b, compares >0 if a > b, and compares ==0 if a and b are equal/equivalent.
I first saw this in Perl a long time ago and according to Wikipedia it is in Perl, Ruby, Apache Groovy, PHP, Eclipse Ceylon as well as C++ now.
Isn't 127-127 = 0, so it should be 2^0