> Posit32 fails on (respectively) 21%, 71%, 91%, 97%, 99%, 99.9%, 99.97%, 99.99% of the cases. Float32 fails on 0 of them. Julia code at the bottom.

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.

I'm not very fond of having only 2 exponent bits on the standard posit32. It makes the region with significant precision loss a lot bigger. But if you give a posit exactly two fewer exponent bits than a float, it shouldn't do worse than that float by more than one bit anywhere. I think that would be a better apples-to-apples comparison. Standard posit32 is tuned much more toward having bonus precision near 1.0, and other tests would show it beating float32 for many tasks.

> Posit even fails on simple integer multiplication so often that you'd be terribly pressed to know ahead of time when it happens. For example, take integers 1 to 40 for i and j, multiple as posit16 and as float16, an see how they do. Posit fails 1.75% of the values, float fails none.

Posit16 starts failing to represent odd numbers at 1024. Float16 starts failing to represent odd numbers at 2048.

Not ideal but not a big issue.

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

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.

> Posits of all sizes make errors when multiplying by powers of two that floats do not make (die to their inability to keep digits). For example, in posit8, 2.0 * 1.03125 returns 2.0, 10 * 2 returns 16, and examples this bad can be found for any size posit.

What's your chosen IEEE competitor?

The example on wikipedia has 3 bits of mantissa. It also says 2.0 * 33/32 == 2.0

And while that format can represent 20, it only has a third of the dynamic range. Tradeoffs. No 8 bit format is going to be good.

What kind of float would pass the 1.03125 test, anyway? You'd need 5 bits of mantissa to represent that. In an 8 bit float, that means you have a... 2 bit exponent? No, that would be ridiculous, it would have to be a 3 bit exponent with no sign bit? That would imply the smallest normal value is 1/4 and the largest value is 15.75

If we face that against an 8 bit unsigned posit with es=1, then it would have 5 bits of mantissa in [1/4, 4), 4 bits of mantissa in [4, 16), and 3 bits of mantissa in [16, 64).

That means this posit would be able to represent both 2.0 * 1.03125 and 20, and it would have four times as much as dynamic range.

I wasn't expecting such a blowout until I started doing the math. Wow, congrats posit.

> To see this, take 1e6 random values in 0-100, mult by 2, then divide by 2, and see how many made it round trip. All float16 values do. 4% of posit16 values do not round trip. These are small numbers - the entire computation stays in the range 0-200, and this is even the base of the underlying number. Posit32 has the same failure rate for the same reason: posits lose precision even under small multiplications.

Yes, they lose one bit of precision if you cross certain thresholds. That is a cost to keep in mind. But look at which values fail to round-trip. It should mostly be numbers between 8 and 16, I think? Those numbers started with 11 bits of mantissa, and they were reduced to 10. Float16 is always 10. This is not a problem. For posit32 it's even more stark. Those numbers start with 27 bits of mantissa, and get reduced to 26 bits. Float32 is always 23.

> 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?

What can happen is that k*x - k*y=0 even though x!=y. With normal floating point that can't happen when k is a power of 2, but it can happen with lots of values of k. 4/3 * 3 - 4/3 * 3.0000000000000004 = 0, with normal floating point. In fact every third pair of adjacent floats incorrectly returns 0.