←back to thread

232 points Twirrim | 2 comments | | HN request time: 0.397s | source
Show context
favorited ◴[] No.41875023[source]
Previously, in JF's "Can we acknowledge that every real computer works this way?" series: "Signed Integers are Two’s Complement" <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p09...>
replies(1): >>41875200 #
jsheard ◴[] No.41875200[source]
Maybe specifying that floats are always IEEE floats should be next? Though that would obsolete this Linux kernel classic so maybe not.

https://github.com/torvalds/linux/blob/master/include/math-e...

replies(9): >>41875213 #>>41875351 #>>41875749 #>>41875859 #>>41876173 #>>41876461 #>>41876831 #>>41877394 #>>41877730 #
FooBarBizBazz ◴[] No.41875749[source]
Whether double floats can silently have 80 bit accumulators is a controversial thing. Numerical analysis people like it. Computer science types seem not to because it's unpredictable. I lean towards, "we should have it, but it should be explicit", but this is not the most considered opinion. I think there's a legitimate reason why Intel included it in x87, and why DSPs include it.
replies(2): >>41875950 #>>41876023 #
stephencanon ◴[] No.41876023[source]
Numerical analysis people do not like it. Having _explicitly controlled_ wider accumulation available is great. Having compilers deciding to do it for you or not in unpredictable ways is anathema.
replies(1): >>41876108 #
bee_rider ◴[] No.41876108[source]
It isn’t harmful, right? Just like getting a little accuracy from a fused multiply add. It just isn’t useful if you can’t depend on it.
replies(3): >>41876218 #>>41876269 #>>41876272 #
Negitivefrags ◴[] No.41876269[source]
It can be harmful. In GCC while compiling a 32 bit executable, making an std::map< float, T > can cause infinite loops or crashes in your program.

This is because when you insert a value into the map, it has 80 bit precision, and that number of bits is used when comparing the value you are inserting during the traversal of the tree.

After the float is stored in the tree, it's clamped to 32 bits.

This can cause the element to be inserted into into the wrong order in the tree, and this breaks the assumptions of the algorithm leaidng to the crash or infinite loop.

Compiling for 64 bits or explicitly disabling x87 float math makes this problem go away.

I have actually had this bug in production and it was very hard to track down.

replies(4): >>41876310 #>>41876377 #>>41876406 #>>41876590 #
kmeisthax ◴[] No.41876590[source]
What use case do you have that requires indexing a hashmap by a floating point value? Keep in mind, even with a compliant implementation that isn't widening your types behind your back, you still have to deal with NaN.

In fact, Rust has the Eq trait specifically to keep f32/f64s out of hash tables, because NaN breaks them really bad.

replies(2): >>41877086 #>>41877111 #
1. meindnoch ◴[] No.41877086[source]
std::map is not a hash map. It's a tree map. It supports range queries, upper and lower bound queries. Quite useful for geometric algorithms.
replies(1): >>41877815 #
2. tialaramex ◴[] No.41877815[source]
Rust's BTreeMap, which is much closer to what std::map is, also requires Ord (ie types which claim to possess total order) for anything you can put in the map.

However, Ord is an ordinary safe trait. So while we're claiming to be totally ordered, we're allowed to be lying, the resulting type is crap but it's not unsafe. So as with sorting the algorithms inside these container types, unlike in C or C++ actually must not blow up horribly when we were lying (or as is common in real software, simply clumsy and mistaken)

The infinite loop would be legal (but I haven't seen it) because that's not unsafe, but if we end up with Undefined Behaviour that's a fault in the container type.

This is another place where in theory C++ gives itself license to deliver better performance at the cost of reduced safety but the reality in existing software is that you get no safety but also worse performance. The popular C++ compilers are drifting towards tacit acceptance that Rust made the right choice here and so as a QoI decision they should ship the Rust-style algorithms.