Hacker News new | ask | show | jobs
by SideQuark 1252 days ago
>A lot of those are only losing a bit or two of precision, though, and many of them are happening in a region where posit32 has more bits of precision than float32 to start with.

Most aren't in those regions. Posits only have more precision for small numbers compared to most of those in this test. Numbers in these ranges are common in computing - write a mapper, or any physics sim, or a CAD tool, or a video game, or nearly anything, and you'll soon find numbers needed over many orders of (decimal) magnitude. Posits simply don't handle any of these cases well.

And losing "only a few bit or two" when doing two operations leads to massive loss in long calculations with even less stable operations. That these lose so much immediately is absolutely terrible for things that do actual numerical work. Things like BLAS, which underlie huge amounts of computing, have plenty of papers on analysis of what happens in actual practice, and posits will not handle much at all of it.

>1052 vs. 1053 is definitely not a "crazy bad problem"!

Really? When it shows up in spreadsheets in various forms I expect people will think otherwise. The Intel floating point fiasco and Excel bugs with vastly less error certainly caused major problems.

>And on the other hand, consider multiplying numbers from 1 to 400. Around the high end of the results, posit16 will store numbers below 65k with 8 bits of mantissa, and numbers above 65k with 7 bits of mantissa. Float16 will store numbers below 65k with 10 bits of mantissa, and everything above 65k becomes infinity.

Both overflow - float16 to inf (denotes overflow, correct), posit16 to NaR (not a real, incorrect - the result is a real number). float16 also then says 0 < inf, correct. Posit16 says NaR < 0, which is not correct.

>Standard posit32 is tuned much more toward having bonus precision near 1.0,

Congrats if you only have calcs that stay near 1.0. If that is your use case, then a format tuned specifically to that case will outperform posits (like lots of things being tried in ML).

>What kind of float would pass the 1.03125 test, anyway?

All of the IEEE formats - multiplying or dividing by two never loses precision until overflow or underflow since it's merely incrementing/decrementing the exponent. Posits with changing precisions loses significance over it's entire range. A fundamental rule in scientific computing is to keep the same precision - if you know something with D digits (or bits) of accuracy, you should keep that precision, otherwise you simply get bad answers. This is taught in elementary schools if I recall.

Also why did you ignore the 10*2 = 16 posit case? And these happen for all size posits for reasonable ranges, but none of the IEEE formats. The values I gave were for examples. Run your own checks and you'll find them all over the map for any size posit.

>> As a result, posits fail at x-y=0 means x=y, which is also pretty fundamental, is it not?

>I don't think that would happen. Do you have an example number?

It's a fundamental property of IEEE 754 that the difference (or sum) of two representable values is itself representable in the same IEEE 754 format (and it's also true for mult and div, all of which allows multiprecision like double-double to exist). These properties are fundamental in proving theorems and are used by compilers to optimize code. It's also a theorem for posits that none of these fundamental properties hold, with the conclusion that there exist values violating it.

Examples where the error in addition is not representable are a= Posit16(0x0001)=2^-114, a+a should be 2^-113, not representable as posit16, a+a as posit 16 gives 2^-112, with error from correct of 2^-113, not representable. For Posit32 this happens for example at Posit32(0x0...03). I gave plenty of examples above from which you can compute that posit errors are not posit representable, making plenty of algorithm impossible without significant more computation.

IEEE was ratified in 1985 and had already been incorporated into hardware from major vendors (using pre-draft). bfloat was invented around 2018 and has significant major hardware vendor support (Google, Intel (even in Xeon processors), FPGAs, ARMv8.6, AMD ROC, and NVidia CUDA among others). Unums were invented in 2015 and have what major hardware support do they have? None? There's even plenty of other float formats adopted in microcontrollers and other hardware used in practice. I've seen none that implement posits. Usually when something is really good it gets incorporated into hardware quite rapidly. Posits have not.

Why do you think that is?

1 comments

> Most aren't in those regions.

If you're only looking at places where posit is worse than float, and ignoring the places where it's better, you should use a posit with a longer exponent where none of the values lose more than a single bit of precision. (There will be low-precision values, but they will be numbers that are completely unrepresentable in the equivalent float)

> Really? When it shows up in spreadsheets in various forms I expect people will think otherwise. The Intel floating point fiasco and Excel bugs with vastly less error certainly caused major problems.

Surely 2257 vs. 2258 is roughly as bad? But float16 has the exact same problem with those numbers. It's not "crazy bad" that the threshold is in a slightly different spot. 16 bit numbers are not appropriate for spreadsheets no matter what format.

> Both overflow - float16 to inf (denotes overflow, correct), posit16 to NaR (not a real, incorrect - the result is a real number). float16 also then says 0 < inf, correct. Posit16 says NaR < 0, which is not correct.

posit16 most certainly does not overflow on 400x400. It doesn't overflow on 4000x4000 either, or 4 million x 4 million.

And if you treat "infinity" literally it's not correct at all. If you're going to say "denotes overflow, correct" then it's only fair to say the same thing about NaR. Pretend it's "not a result" maybe? It's just a name.

> All of the IEEE formats - multiplying or dividing by two never loses precision until overflow or underflow since it's merely incrementing/decrementing the exponent.

Let me rephrase. What 8 bit float can represent 1.03125 in the first place?

> Also why did you ignore the 10*2 = 16 posit case? And these happen for all size posits for reasonable ranges, but none of the IEEE formats. The values I gave were for examples. Run your own checks and you'll find them all over the map for any size posit.

There is no standard 8 bit IEEE format as far as I know.

I didn't ignore that case. I pointed out how the standard posit8 fails it. But if we're using some kind of weird custom float with no sign bit, I think it's valid to use a better-balanced posit. Posit8_1 is the best competitor to a custom float with 5 mantissa bits. If you also remove the sign bit, then it can do 10 * 2 = 20.

> It's a fundamental property of IEEE 754 that the difference (or sum) of two representable values is itself representable in the same IEEE 754 format

Except when you hit infinity.

> Examples where the error in addition is not representable are a= Posit16(0x0001)=2^-114, a+a should be 2^-113, not representable as posit16, a+a as posit 16 gives 2^-112, with error from correct of 2^-113, not representable.

1. Such aggressive rounding only happens in the last couple values next to 0. If you were using float16 you wouldn't be able to represent that value, it would just be 0.

2. Does that give you x - y = 0 for different x and y, the thing I asked about?

> Why do you think that is?

I have no idea how hard it is to implement, to be honest. But adding a few more bits is easy in comparison. And it's not that different from normal floating point, so who wants to bother?

bfloat is just truncating differently; I'm not surprised it was very quickly implemented.