Skip to content

Instantly share code, notes, and snippets.

@tmathmeyer
Created October 14, 2017 18:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmathmeyer/00c6a6a31c34f5c5432abe4bd4fed4ce to your computer and use it in GitHub Desktop.
Save tmathmeyer/00c6a6a31c34f5c5432abe4bd4fed4ce to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>
#define EXP_HIGH_BIT 0x40000000
#define MANT_HIGH_BIT 0x00400000
#define VALUE_COUNT 100000000
float values[VALUE_COUNT];
float hack_result[VALUE_COUNT];
float real_result[VALUE_COUNT];
int main()
{
srand(928349);
for (size_t i = 0; i < VALUE_COUNT; i++)
{
do
{
uint32_t x;
x = rand() & 0xff;
x |= (rand() & 0xff) << 8;
x |= (rand() & 0xff) << 16;
x |= (rand() & 0xff) << 24;
uint32_t bits = (x & ~0x80000000) | EXP_HIGH_BIT;
values[i] = (float)&bits;
}
while (isnan(values[i]));
}
LARGE_INTEGER start, end;
QueryPerformanceCounter(&start);
for (size_t i = 0; i < VALUE_COUNT; i++)
{
real_result[i] = sqrt(values[i]);
}
QueryPerformanceCounter(&end);
uint64_t real_ticks = end.QuadPart - start.QuadPart;
printf("sqrt: %ld ticks\n", real_ticks);
QueryPerformanceCounter(&start);
for (size_t i = 0; i < VALUE_COUNT; i++)
{
uint32_t bits = (((uint32_t)&values[i] >> 1) ^ (EXP_HIGH_BIT | (EXP_HIGH_BIT >> 1))) & ~MANT_HIGH_BIT;
hack_result[i] = (float)&bits;
}
QueryPerformanceCounter(&end);
uint64_t hack_ticks = end.QuadPart - start.QuadPart;
printf("sqrt_hack: %ld ticks\n", hack_ticks);
printf("hack is %f%% faster\n", (float)real_ticks * 100 / hack_ticks - 100);
float error = 0;
float min = 1;
size_t buckets[100] = {0};
for (size_t i = 0; i < 1000000; i++)
{
float er = (hack_result[i] - real_result[i]) / real_result[i];
if (er < min) min = er;
er = fabs(er);
buckets[(int)(er * 100)]++;
error += er;
}
error /= 1000000;
printf("avg abs rel err: %f%%\n", error * 100);
printf("min rel err: %f%%\n", min * 100);
for (size_t i = 0; i < 100; i++) {
printf("%.1f%%: %d\n", (float)i, buckets[i]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment