Comment #1
> y = (x * 63.66667)/128
The difference between this and
y = (x * 64)/128
Is about 0.5%
Put it this way, if y is an integer, then x has to be >= 384 before the real answer (191) becomes different from the approximate answer (192).
So this simply becomes
y = x / 2;
But if you compare the result of y = (x * 63.66667)/128 with the result of y = x / 2, and want them to match, then that 0.5% is critical to the calculation. The x / 2 approximation only produces a match for odd values less than 191 and zero (at least in my little experiment).
Code:
#include <stdio.h>
int main(void)
{
int x, y, z, a = 0, b = 0, c = 0;
for ( x = 0; x < 110000; ++x )
{
z = y = (x * 63.66667) / 128; /* uses floating point */
y = x / 2;
if ( y == z )
{
++a;
printf("x = %d, y = x / 2 = %d, z = %d (match)\n", x, y, z);
}
y = (x * 191) / 384;
if ( y == z )
{
++b;
}
else
{
printf("x = %d, y = (x * 191) / 384 = %d, z = %d (doesn't match)\n", x, y, z);
}
y = ( (x << 6) - (x / 3) ) >> 7;
if ( y == z )
{
++c;
}
else
{
printf("x = %d, y = ( (x << 6) - (x / 3) ) >> 7 = %d, z = %d (doesn't match)\n", x, y, z);
}
}
printf("%s accuracy: %d/%d (%f%%)\n", "y = x / 2", a, x, 100.0 * a / x);
printf("%s accuracy: %d/%d (%f%%)\n", "y = (x * 191) / 384", b, x, 100.0 * b / x);
printf("%s accuracy: %d/%d (%f%%)\n", "y = ( (x << 6) - (x / 3) ) >> 7", c, x, 100.0 * c / x);
return 0;
}
With the loop messages removed, the end results I obtained are as follows.
Code:
y = x / 2 accuracy: 97/110000 (0.088182%)
y = (x * 191) / 384 accuracy: 109974/110000 (99.976364%)
y = ( (x << 6) - (x / 3) ) >> 7 accuracy: 109453/110000 (99.502727%)
Note that I chose 110000 as the end because y = (x * 191) / 384 matches the result of y = (x * 63.66667) / 128 accurately only up to around 100000. Beyond 100000, the difference between 63.66667 and the fraction 191/384 becomes significant, and the overall accuracy decreases.
The y = ( (x << 6) - (x / 3) ) >> 7 differs at 2 and and about every 192 thereafter.
Comment #2
x and y are 32 bit numbers. Floating point operation is not acceptable.
How exactly does this not use floating point?