Re: RFC: More accurate color conversion

Wolfgang Draxinger <[email protected]>
Newsgroups gmane.comp.lib.cairo
Organization DraxIT
Message-ID <[email protected]>
On Sun, 06 Oct 2013 03:38:43 +0200
[email protected] (Søren Sandmann) wrote:

> Wolfgang Draxinger <[email protected]> writes:
> 
> > I'd like to throw in this little paper, discussing the problem of
> > floating point <-> integer range conversion at depth: 
> >
> > http://kaba.hilvi.org/homepage/programming/range/RangeConversion.pdf
> 
> In terms of that paper, f(x) is fixed to be x / 65535.0, 

I don't see where you pulled that particular 2**16 - 1 from. The paper
discusses range conversions [0, 1] <-> [0, 2**n - 1] which is the
typical problem when confronted with conversion between floating point
and integer.

> hopefully x == g(f(x)) for all x.

Not if you're converting between floating point and integers. That's
numerics 101. The numbers represented by floats are m * 2**p.
But that can be trivially rewritten as m << p. Floating point means
nothing else than floating shift when it comes to the binary
representation. Which means, that for any exponent p > 0 there are 2**p
different integers that map to the same float and that for any exponent
p < 0 there are 2**p floating point values that map to the same integer.

Your typical float has 23 bits for the mantissa and 8 bits for the
exponent. Which means that for integer ranges [-2**23 + 1, 2**23 - 1]
you can have a bijective mapping. Outside of that you need an exponent
=/=0, so good luck.

You can quickly test it with this program, which doesn't even do a
range conversion:

#include <stdio.h>
#include <limits.h>

#define RANGE (1<<25)

void float_int(float f, int const i)
{
	if( (int)f != i ) {
		fprintf(stderr, "%f =/= %d\n", f, i);
	}
}

int main(int const argc, char const * const argv[])
{
	int i;
	for( i = -RANGE + 1; i < RANGE - 1; i++ ) {
		float_int(i, i);
	}
	return 0;
}

Typical output

-33537332.000000 =/= -33537331
-33537328.000000 =/= -33537329
-33537328.000000 =/= -33537327
-33537324.000000 =/= -33537325
-33537324.000000 =/= -33537323
-33537320.000000 =/= -33537321
-33537320.000000 =/= -33537319
-33537316.000000 =/= -33537317
-33537316.000000 =/= -33537315
-33537312.000000 =/= -33537313
-33537312.000000 =/= -33537311
-33537308.000000 =/= -33537309
-33537308.000000 =/= -33537307
-33537304.000000 =/= -33537305
-33537304.000000 =/= -33537303
-33537300.000000 =/= -33537301
-33537300.000000 =/= -33537299
-33537296.000000 =/= -33537297
-33537296.000000 =/= -33537295
-33537292.000000 =/= -33537293
-33537292.000000 =/= -33537291
-33537288.000000 =/= -33537289
-33537288.000000 =/= -33537287
-33537284.000000 =/= -33537285
-33537284.000000 =/= -33537283
-33537280.000000 =/= -33537281
-33537280.000000 =/= -33537279
-33537276.000000 =/= -33537277
-33537276.000000 =/= -33537275
-33537272.000000 =/= -33537273
-33537272.000000 =/= -33537271
-33537268.000000 =/= -33537269
-33537268.000000 =/= -33537267
-33537264.000000 =/= -33537265

As you can see that each some integer values are "bordered" by +1, -1
of them, which however map to the same floating point value. Which
suggests that the least significant bit gets dropped. Which is exactly
what happens, the mantissa of those values is > 2**23 


Wolfgang
-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.