# [cairo] Re: Clamping to 16 bits

Bill Spitzak spitzak at d2.com
Fri Aug 12 13:03:53 PDT 2005

```Here is code to convert to 16.16 form and detect clamping, avoiding the
slow int FP converter. I'm assumming the legal range is -32768 to 32767,
it is also possible to modify it so the range is 0..65535.

/*
Copyright (c) 2005 by Bill Spitzak
Permission is hereby granted to use this code in any manner.
*/

#include <stdio.h>
#include <stdlib.h>

#if __BIG_ENDIAN_
#define iman_ 1
#else
#define iman_ 0
#endif

/**
Fast version of XDoubleToFixed(f)
Works for -32768.0 .. 32767.99999
Requires IEEE floating point.
*/
inline int fast_DoubleToFixed(double val) {
val = val + (68719476736.0*1.5);
return ((long*)&val)[iman_];
}

/**
Puts fast_DoubleToFixed() into *out.
Returns true if out of range error.
Requires IEEE floating point.
*/
inline int checkDoubleToFixed(double val, int* out) {
val = val + (32768+68719476736.0*1.5);
*out = ((int*)&val)[iman_]^0x80000000;
return ((int*)&val)[1-iman_] != 0x42380000;
}

#define XFixedToDouble(f)    (((double) (f)) / 65536)

int main(int argc, char** argv) {
int i, j;
double f;
if (argc < 2) {
fprintf(stderr, "Return fast_DoubleToFixed(x) for each argument\n");
return 1;
}
for (i = 1; i < argc; i++) {
f = strtod(argv[i],0);
j = fast_DoubleToFixed(f);
printf("fast_DoubleToFixed(%g) == %.10g (0x%08x)\n", f,
XFixedToDouble(j), j);
if (checkDoubleToFixed(f, &j)) {
printf("checkDoubleToFixed(%g) == FAIL\n", f);
} else {
printf("checkDoubleToFixed(%g) == %.10g (0x%08x)\n", f,
XFixedToDouble(j), j);
}
}
return 0;
}

```