A posit advantage for decimal character I/O

171 views
Skip to first unread message

John L. Gustafson

unread,
Oct 27, 2019, 8:55:55 AM10/27/19
to Unum Computing
I recently noticed that the tapered precision of posit arithmetic has an unexpected advantage over floats when converting binary to decimal strings, or decimal strings to binary (like the printf and scanf functions in C): Despite having higher accuracy than floats for most posit values, and comparable (32-bit) or better (16-bit) dynamic range, the text strings needed to uniquely express a posit have a maximum length that is shorter than the maximum text string needed to express a float.

The reason is that an exponential notation, like "1.609e-19" takes character spaces away from the significant digits… but for posits, that happens when there are fewer significant digits anyway, because the magnitudes are so large or so small! As a result, easy-to-read output is possible with slightly fewer bytes for posits than for floats. Or at least, the extra accuracy of posits doesn't add burden to the decimal character output needed to express the values.

For example, 16-bit IEEE floats require 5 significant figures to print, if they are to preserve the meaning of every bit. That is, a binary converted to a 5-digit decimal with scaling, when converted back to binary, suffice to guarantee you get back the original bits of the float without rounding error. To print out a 16-bit IEEE float, you need a maximum of 

  5 decimals,
  1 sign character (always needed for negative significands, otherwise optional)
  1 decimal point
  1 "E" or "e" or whatever symbol precedes the exponent
  1 sign character for the exponent (always needed for negative exponents, otherwise optional)
  1 digit for the exponent (only one, since IEEE 16-bit magnitudes never need double-digit decimals for the power of 10)
____________
10 characters total.

Of course, for a value like "2.7183", the string could take as few as six characters (you should always show a decimal point even if the value is an integer, to clarify that the format is for approximating real numbers and not an exact integer). If storing a large array as formatted data, you probably pick a fixed size for each output that suffices for the maximum character space needed, and for IEEE floats that means 10 bytes for each 2-byte value. Or you can bear the overhead of variable-size strings delimited by the sign character (space, "+", or "–") and use as few as three characters for a value like " 0."

With 16-bit posits, 5 decimals again suffice (barely), but outside the magnitude range 1e–2 to 1e2, 4 or fewer decimals suffice. Outside the magnitude range 1e–5 to 1e5, 3 or fewer decimals suffice. I've done the exhaustive test, and 9 characters suffice to express every 16-bit posit (with es = 1). They are heartbreakingly close to being expressible uniquely using only 8 characters, except for a tiny range of posit values:

0000 0000 1011 0101 1.116e–4
0000 0000 1011 0110 ⟶ 1.125e–4
0000 0000 1011 0111 ⟶ 1.135e–4
0000 0000 1011 1000 ⟶ 1.144e–4

Those require 8 characters to disambiguate them, or 9 characters if they are negative numbers and need a leading "–" sign.

While there are no 8-bit floats, all the 8-bit posits can be uniquely expressed with 5 decimal characters, and those 5 characters will convert back to the original binary without error.

For 32-bit values, IEEE floats require 8 significant decimal digits to represent perfectly for round-trip conversion. 32-bit posits require 10 significant digits. You would think posits would thus need more bulk than floats to create I/O that preserves information. But 32-bit floats require a maximum of 15 characters, and 32-bit posits (with es = 2) require a maximum of 14 characters. 

For 64-bit values, IEEE floats require 17 significant decimal digits and posits require 20 decimal digits (I really hope people stop using 64-bit values, whether float or posit, as the default precision for all variables) but my analysis so far shows that 24 characters suffice to describe, in decimal, both 64-bit floats and 64-bit posits (with es = 3). No I/O storage advantage for posits, but you get a lot more accuracy without having to pay a price in the I/O formatting, so taking that into account, I think it's a win for posits.

What do you think of the idea of putting a fixed character size in the Draft Posit Standard? All 8-bit posits take 5 characters, etc. This greatly simplifies the task of expressing real-value I/O, perhaps enough that it could even be put into the language standards instead of sweeping I/O under the rug the way so many computer languages do, saying "It's not part of the language". Thoughts?

John



Important: This email is confidential and may be privileged. If you are not the intended recipient, please delete it and notify us immediately; you should not copy or use it for any purpose, nor disclose its contents to any other person. Thank you.

Theodore Omtzigt

unread,
Nov 7, 2019, 6:30:51 AM11/7/19
to Unum Computing
Hi John: 

I don't have a strong opinion on the decimal representation, although conceptually constraining the decimal string to reflect the precision of the number I think is valuable. The problem I think you'll face is that the C and C++ and Java and everything historically has decoupled the printing width of a number from its representation. Simply look at the printf and ostream APIs, and since those design decisions of the language then trickle down to application development, you are going to break a lot of report writers that depend on control of the width by the format string.

I do have a strong opinion about communicating the exact value contained in the posit so that serialization and collaboration of data sets is repeatable. In the Universal library we implemented a hex format for posits that carries the posit configuration so that the data set can be serialized and shared among arbitrary precision applications.

The format is <nbits.es>x[HEX DIGITS]p

Here is an example of this format for posit<40,3>

Lossless serialization of posit values
a : 40.3x40f03290a3p
b : 40.3xbf0fcd6f5dp
c : 40.3x8000000000p

The benefits of this format are:
1- lossless in terms of information
2- easy to parse
3- fixed format
4- consistent for adaptive precision algorithms

This format is intended for printf and ostream serialization. For data set serialization you would want to use a binary format and potentially additional compression.

Denis Bredelet

unread,
Jan 29, 2022, 7:07:17 PM1/29/22
to Unum Computing
Does it matter how many bits is the binary value? As long as your target variable has enough bits, you can decode it (assuming a size multiple of four for hexadecimal of course!)
And you can just count the digits if you need the information.
Example:

a : 3x40f03290a3p
b : 3xbf0fcd6f5dp
c : 3x8000000000p

Theodore Omtzigt

unread,
Jan 30, 2022, 7:22:00 AM1/30/22
to Unum Computing
The representation density has not been a pain point. 

We are using the facility mainly for two use-cases:
1- obtaining patterns for quickly interpreting the posits segments: If you work with the format long enough you can see the regime and ULP behaviors without having to dive deeper
2- for communicating interim computations between humans.

For use-case #2, the format is too verbose as for every element in the matrix we carry the posit configuration information, which tends to be a constant. But we haven't really felt any impact as compression will remove those commonalities. Furthermore, If you really need to exchange a TB matrix, you would use a binary format and communicate the posit configuration in a side band channel.

MitchAlsup

unread,
Feb 2, 2022, 10:20:07 PM2/2/22
to Unum Computing
I want to (ever so slightly) complain about the phrase; "for most posit values,"

If you append the phrase "encountered in practice", we are in complete agreement.

John Gustafson

unread,
Feb 3, 2022, 9:35:22 AM2/3/22
to MitchAlsup, Unum Computing
I agree. I'll be more careful to say "for most posit values encountered in practice" in the future, thanks.

John

--
You received this message because you are subscribed to the Google Groups "Unum Computing" group.
To unsubscribe from this group and stop receiving emails from it, send an email to unum-computin...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/unum-computing/0056e462-0e77-4688-b5b5-baeb1d207d55n%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages