/* File: UFloat8.h Contains: Unsigned 8 bit floating point numbers. Verified to be idempotent, and each quantum is the average of the range it represents. 4 significand bits yields a range of 507904 ~ 524287 = 2^19-1 5 significand bits yields a range of 4032 ~ 4095 = 2^12-1 6 significand bits yields a range of 508 ~ 511 = 2^ 9-1 Written by: Ken Turkowski, turk__AT__computer.org Copyright: (C) 2004-2005 Ken Turkowski. All rights reserved. Warranty Information Even though I have reviewed this software, I make no warranty or representation, either express or implied, with respect to this software, its quality, accuracy, merchantability, or fitness for a particular purpose. As a result, this software is provided "as is," and you, its user, are assuming the entire risk as to its quality and accuracy. This code may be used and freely distributed as long as it includes this copyright notice and the above warranty information. Change History (most recent first): $Log: UFloat8.h,v $ Revision 1.2 2004/05/07 19:02:13 turk fix type with name of NormalizedL1UCharVectorFromUFloat8 Revision 1.1 2004/03/12 08:43:27 turk new To Do: */ #ifndef __UFLOAT8__ #define __UFLOAT8__ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef unsigned char UFloat8; /* Convert to/from integer */ unsigned int ToIntFromUFloat8(UFloat8 u, unsigned int sigBits); UFloat8 FromIntToUFloat8(unsigned int i, unsigned int sigBits); /* Convert to/from float */ float ToFloatFromUFloat8(UFloat8 u, unsigned int sigBits); UFloat8 FromFloatToUFloat8(float f, unsigned int sigBits); /* Normalize a vector */ void NormalizedL1FloatVectorFromUFloat8(unsigned int n, unsigned int sigBits, const UFloat8 *u, float *f); void NormalizedL1UCharVectorFromUFloat8(unsigned int n, unsigned int sigBits, const UFloat8 *u, unsigned char *c); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __UFLOAT8__ */ /////////////////////////////////// CUT HERE ///////////////////////////// /* File: UFloat8.c Contains: Unsigned 8 bit floating point numbers. Verified to be idempotent, and each quantum is the average of the range it represents. 4 significand bits yields a range of 507904 ~ 524287 = 2^19-1 5 significand bits yields a range of 4032 ~ 4095 = 2^12-1 6 significand bits yields a range of 508 ~ 511 = 2^ 9-1 Written by: Ken Turkowski, turk__AT__computer.org Copyright: (C) 2004-2005 Ken Turkowski. All rights reserved. Warranty Information Even though I have reviewed this software, I make no warranty or representation, either express or implied, with respect to this software, its quality, accuracy, merchantability, or fitness for a particular purpose. As a result, this software is provided "as is," and you, its user, are assuming the entire risk as to its quality and accuracy. This code may be used and freely distributed as long as it includes this copyright notice and the above warranty information. Change History (most recent first): $Log: UFloat8.c,v $ Revision 1.3 2004/05/07 19:02:13 turk fix type with name of NormalizedL1UCharVectorFromUFloat8 Revision 1.2 2004/03/16 10:08:42 turk UFloat8.c Revision 1.1 2004/03/12 08:42:58 turk new To Do: */ /* #include "UFloat8.h" */ /******************************************************************************** * ToIntFromUFloat8 ********************************************************************************/ unsigned int ToIntFromUFloat8(UFloat8 u, unsigned int sigBits) { int e, s; s = u & ((1 << sigBits) - 1); if ((e = u >> sigBits) != 0) { s += (1 << sigBits); /* Insert hidden 1 */ s <<= (e - 1); /* Shift */ } return s; } /******************************************************************************** * FromIntToUFloat8 ********************************************************************************/ UFloat8 FromIntToUFloat8(unsigned int i, unsigned int sigBits) { unsigned int max, e; max = (1 << (sigBits + 1)) - 1; if (i > max) { for (e = 2, max = (max << 1) + 1; i > max; e++) max <<= 1; i = (((i >> (e - 2)) + 1) >> 1) + ((e - 1) << sigBits); } if (i > 255) i = 255; return (UFloat8)i; } /******************************************************************************** * ToFloatFromUFloat8 ********************************************************************************/ float ToFloatFromUFloat8(UFloat8 u, unsigned int sigBits) { return((float)ToIntFromUFloat8(u, sigBits)); } /******************************************************************************** * FromFloatToUFloat8 ********************************************************************************/ UFloat8 FromFloatToUFloat8(float f, unsigned int sigBits) { UFloat8 u; if (f >= 2147483647.0f) u = 255; else if (f <= 0) u = 0; else u = FromIntToUFloat8((int)f, sigBits); return u; } /******************************************************************************** * NormalizedL1FloatVectorFromUFloat8 ********************************************************************************/ void NormalizedL1FloatVectorFromUFloat8(unsigned int n, unsigned int sigBits, const UFloat8 *u, float *f) { float mag; unsigned int i; for (i = n, mag = 0; i--; ) mag += (*f++ = (float)ToIntFromUFloat8(*u++, sigBits)); for (i = n, f -= n, mag = 1.0f / mag; i--; ) *f++ *= mag; } /******************************************************************************** * NormalizedL1UCharVectorFromUFloat8 ********************************************************************************/ #define MAGBITS 12 void NormalizedL1UCharVectorFromUFloat8(unsigned int n, unsigned int sigBits, const UFloat8 *u, unsigned char *c) { unsigned int mag; unsigned int i; for (i = n, mag = 0; i--; ) mag += ToIntFromUFloat8(*u++, sigBits); for (i = n, u -= n, mag = (255 << MAGBITS) / mag; i--; ) *c++ = (UFloat8)((ToIntFromUFloat8(*u++, sigBits) * mag + (1 << (MAGBITS - 1))) >> MAGBITS); } /******************************************************************************** Only 4, 5 and 6 significand bits are useful. Here are the quanta: -4- -5- -6- 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 10 10 10 11 11 11 12 12 12 13 13 13 14 14 14 15 15 15 16 16 16 17 17 17 18 18 18 19 19 19 20 20 20 21 21 21 22 22 22 23 23 23 24 24 24 25 25 25 26 26 26 27 27 27 28 28 28 29 29 29 30 30 30 31 31 31 32 32 32 34 33 33 36 34 34 38 35 35 40 36 36 42 37 37 44 38 38 46 39 39 48 40 40 50 41 41 52 42 42 54 43 43 56 44 44 58 45 45 60 46 46 62 47 47 64 48 48 68 49 49 72 50 50 76 51 51 80 52 52 84 53 53 88 54 54 92 55 55 96 56 56 100 57 57 104 58 58 108 59 59 112 60 60 116 61 61 120 62 62 124 63 63 128 64 64 136 66 65 144 68 66 152 70 67 160 72 68 168 74 69 176 76 70 184 78 71 192 80 72 200 82 73 208 84 74 216 86 75 224 88 76 232 90 77 240 92 78 248 94 79 256 96 80 272 98 81 288 100 82 304 102 83 320 104 84 336 106 85 352 108 86 368 110 87 384 112 88 400 114 89 416 116 90 432 118 91 448 120 92 464 122 93 480 124 94 496 126 95 512 128 96 544 132 97 576 136 98 608 140 99 640 144 100 672 148 101 704 152 102 736 156 103 768 160 104 800 164 105 832 168 106 864 172 107 896 176 108 928 180 109 960 184 110 992 188 111 1024 192 112 1088 196 113 1152 200 114 1216 204 115 1280 208 116 1344 212 117 1408 216 118 1472 220 119 1536 224 120 1600 228 121 1664 232 122 1728 236 123 1792 240 124 1856 244 125 1920 248 126 1984 252 127 2048 256 128 2176 264 130 2304 272 132 2432 280 134 2560 288 136 2688 296 138 2816 304 140 2944 312 142 3072 320 144 3200 328 146 3328 336 148 3456 344 150 3584 352 152 3712 360 154 3840 368 156 3968 376 158 4096 384 160 4352 392 162 4608 400 164 4864 408 166 5120 416 168 5376 424 170 5632 432 172 5888 440 174 6144 448 176 6400 456 178 6656 464 180 6912 472 182 7168 480 184 7424 488 186 7680 496 188 7936 504 190 8192 512 192 8704 528 194 9216 544 196 9728 560 198 10240 576 200 10752 592 202 11264 608 204 11776 624 206 12288 640 208 12800 656 210 13312 672 212 13824 688 214 14336 704 216 14848 720 218 15360 736 220 15872 752 222 16384 768 224 17408 784 226 18432 800 228 19456 816 230 20480 832 232 21504 848 234 22528 864 236 23552 880 238 24576 896 240 25600 912 242 26624 928 244 27648 944 246 28672 960 248 29696 976 250 30720 992 252 31744 1008 254 32768 1024 256 34816 1056 260 36864 1088 264 38912 1120 268 40960 1152 272 43008 1184 276 45056 1216 280 47104 1248 284 49152 1280 288 51200 1312 292 53248 1344 296 55296 1376 300 57344 1408 304 59392 1440 308 61440 1472 312 63488 1504 316 65536 1536 320 69632 1568 324 73728 1600 328 77824 1632 332 81920 1664 336 86016 1696 340 90112 1728 344 94208 1760 348 98304 1792 352 102400 1824 356 106496 1856 360 110592 1888 364 114688 1920 368 118784 1952 372 122880 1984 376 126976 2016 380 131072 2048 384 139264 2112 388 147456 2176 392 155648 2240 396 163840 2304 400 172032 2368 404 180224 2432 408 188416 2496 412 196608 2560 416 204800 2624 420 212992 2688 424 221184 2752 428 229376 2816 432 237568 2880 436 245760 2944 440 253952 3008 444 262144 3072 448 278528 3136 452 294912 3200 456 311296 3264 460 327680 3328 464 344064 3392 468 360448 3456 472 376832 3520 476 393216 3584 480 409600 3648 484 425984 3712 488 442368 3776 492 458752 3840 496 475136 3904 500 491520 3968 504 507904 4032 508 ********************************************************************************/ /******************************************************************************** ******************************************************************************** ******************************************************************************** ***** TESTING ***** ******************************************************************************** ******************************************************************************** ********************************************************************************/ //#define TEST #ifdef TEST #include #include static void PrintQuanta(int sigBits) { int i; for (i = 0; i < 256; i++) { printf("%u\n", ToIntFromUFloat8(i, sigBits)); } } static void PrintAllQuanta(void) { int i; for (i = 0; i < 256; i++) { printf("%6u%6u%6u\n", ToIntFromUFloat8(i, 4), ToIntFromUFloat8(i, 5), ToIntFromUFloat8(i, 6)); } } static void TestIdempotency(int sigBits) { int i, j; for (i = 0; i < 256; i++) { j = FromIntToUFloat8(ToIntFromUFloat8(i, sigBits), sigBits); if (i != j) printf("%u != %u\n", i, j); } } static void PrintProjection(int sigBits) { unsigned int max = ToIntFromUFloat8(255, sigBits); unsigned int i, j; int lastfp = -1; for (i = 0; i <= max; i++) { j = FromIntToUFloat8(i, sigBits); if (j != lastfp) { if (lastfp != -1) { printf(", %u]\n", i-1); } printf("%6u == %u <-- [%u", j, ToIntFromUFloat8(j, sigBits), i); } lastfp = j; } printf(", %u]\n", i-1); } int main(int argc, char **argv) { int sigBits = 0; if (argc > 1) sigBits = atoi(argv[1]); if (sigBits != 0) PrintQuanta(sigBits); else PrintAllQuanta(); TestIdempotency(4); TestIdempotency(5); TestIdempotency(6); PrintProjection(4); PrintProjection(5); PrintProjection(6); } #endif /* TEST */