Skip to content

Instantly share code, notes, and snippets.

@stedolan
Created April 28, 2020 15:55
Show Gist options
  • Save stedolan/e408d2b05faf6dd0ce00ee61586f9143 to your computer and use it in GitHub Desktop.
Save stedolan/e408d2b05faf6dd0ce00ee61586f9143 to your computer and use it in GitHub Desktop.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
static uint32_t mulhi(uint32_t a, uint32_t b) {
return (uint32_t)(((uint64_t)a * (uint64_t)b) >> 32);
}
// x in (0, 1). computes an approximation of -log2(x)
float approx_log2(uint32_t x) {
uint32_t k;
x |= 1;
k = 1 + __builtin_clz(x);
x <<= k;
x = mulhi(mulhi(0x55555555, x), -x) + x;
x = (((k-1) << 24) | ((-x) >> 8));
x = x < 29350 ? 0 : x - 29350;
return x * 5.960464477539063e-08f;
}
int main() {
float maxerr = 0;
float toterr = 0;
uint32_t i = 0, maxbad=0;
do {
float g = (i|1)*2.3283064365386962890625e-10;
float err = -logf(g)/logf(2) - approx_log2(i);
toterr += err;
if (fabs(err) > fabs(maxerr)) maxerr = err, maxbad = i;
i++;
} while (i);
printf("max err: %.10f [%08x]\navg err: %.10f\n", fabs(maxerr), maxbad, toterr/(double)(1ull << 32));
}
max err: 0.0079612732 [0000269e]
avg err: -0.0000610352
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment