Raymond Hettinger Profile picture
Chief trainer for Mutable Minds. Certified Public Accountant, Retired Python guru. Alloy & TLA⁺ enthusiast. Aspiring pianist. Former pilot. Born at 320 ppm CO₂.

Aug 31, 2020, 6 tweets

Another building block for a #Python floating point ninja toolset:

def veltkamp_split(x):
'Exact split into two 26-bit precision components'
t = x * 134217729.0
hi = t - (t - x)
lo = x - hi
return hi, lo

csclub.uwaterloo.ca/~pbarfuss/dekk…

Input: one signed 53-bit precision float

Output: two signed 26-bit precision floats

Invariant: x == hi + lo

Constant: 134217729.0 == 2.0 ** 27 + 1.0

Example:

>>> hi, lo = veltkamp_split(pi)
>>> hi + lo == pi
True
>>> hi.hex()
'0x1.921fb58000000p+1'
>>> lo.hex()
'-0x1.dde9740000000p-26'

Note all the trailing zeros and the difference between the two exponents. Also both the lo and hi values are signed.

Use case: The 26-bit precision components can be multiplied losslessly (without rounding):

# Four exact components of e * pi:
>>> pi_hi*e_hi
8.539734226211163
>>> pi_hi*e_lo
7.207993525551209e-08
>>> pi_lo*e_hi
-7.561753118743836e-08
>>> pi_lo*e_lo
-6.382525038592985e-16

The payoff for Veltkamp-Dekker splitting and piecewise multiplication is that you can build quad precision arithmetic out of everyday double precision arithmetic.

The part that is pure magic: How do you split a 53 bit number into two 26 bit numbers? Where did the extra bit go?

Answer: The extra bit is stored in the sign bit of the "lo" component.

53 bits + 1 sign = 26 bits + 1 sign + 26 bits + 1 sign

All bits accounted for.🧐

Cool!😏

Share this Scrolly Tale with your friends.

A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.

Keep scrolling