[cairo] _cairo_color_compute_shorts fails with FPU set to single precision

Carlo Wood carlo at alinoe.com
Wed Aug 30 04:56:19 PDT 2006


On Tue, Aug 29, 2006 at 11:00:18PM -0700, Carl Worth wrote:
> So, we've instead been attempting to implement the first approach,
> with equally-sized divisions of the floating-point range. Something
> that is very close to correct is:
> 
> 	i = floor (f * (N+1))
> 
> This is correct for all input values in [0.0, 1.0). But given a value
> f of 1.0 this function will return N+1 rather than N as desired, (and
> that N+1 value will be truncated down to 0 if we're choosing N as to
> use every last bit available in i).

This seems to work:

uint16_t convert(double dc)
{
  uint32_t tmp = dc * 65536;
  if (tmp == 0x10000)
    tmp = 65535;
  return tmp;
}

Or if you don't want the branch for cache hit reasons:

uint16_t convert(double dc)
{
  uint32_t tmp = dc * 65536;
  uint32_t correction = tmp >> 16;
  tmp -= correction;
  return tmp;
}

However, with the right compiler options, the first version
should use a conditional move - which doesn't cause a cache hit.
On the other hand, the last one only adds three integer
assembly instructions, and that way you're sure you don't have
a branch.

-- 
Carlo Wood <carlo at alinoe.com>


More information about the cairo mailing list