[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;
}



More information about the cairo mailing list