Floating point precision issues#

Let’s quickly generate 10 numbers between -1.25 and 1.25 to see whats going on here.

Based on the algorithm used we expect the list of numbers to be completely symmetric around zero.

y_min, y_max = -1.25, 1.25
resolution = 10

y = [y_min + (y_max - y_min) / (resolution - 1) * index for index in range(resolution)]
y
[-1.25,
 -0.9722222222222222,
 -0.6944444444444444,
 -0.41666666666666663,
 -0.13888888888888884,
 0.13888888888888884,
 0.41666666666666674,
 0.6944444444444446,
 0.9722222222222223,
 1.25]
  • Numbers look the same at first glance.

  • Looking more closely though, they are not.

  • There are subtle changes at the precision limit.

  • This prevents effective use of the cache

There’s a simple way out though by enforcing true symmetry!

_y1 = [y_min + (y_max - y_min) / (resolution - 1) * index for index in range(resolution)]
_y2 = [-y for y in _y1[::-1]]
y = [(y1 + y2) / 2 for y1, y2 in zip(_y1, _y2)]
y
[-1.25,
 -0.9722222222222223,
 -0.6944444444444445,
 -0.4166666666666667,
 -0.13888888888888884,
 0.13888888888888884,
 0.4166666666666667,
 0.6944444444444445,
 0.9722222222222223,
 1.25]

Note

A more generalized implementation is doable but more complex. Find it in the mandel-bench source code.