Skip to content

Instantly share code, notes, and snippets.

@dankogai
Last active June 6, 2018 03:53
Show Gist options
  • Save dankogai/bedd2265fc29146c54e46ff42f1748aa to your computer and use it in GitHub Desktop.
Save dankogai/bedd2265fc29146c54e46ff42f1748aa to your computer and use it in GitHub Desktop.
cbrt() of Linux libm seems buggy
#include <dlfcn.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#define DBL_ULPOFONE 0x1p-52
void *load_cbrt(void **dlhp, char *path){
*dlhp = dlopen(path, RTLD_LAZY);
if (*dlhp == NULL) {
fprintf(stderr, "%s\n", dlerror());
exit(-1);
}
void *fptr = dlsym(*dlhp, "cbrt");
if (fptr == 0) {
fprintf(stderr, "%s\n", dlerror());
exit(-1);
}
return fptr;
}
// typedef unsigned long int uint;
int main(int argc, char *argv[]){
if (argc < 3) {
fprintf(stderr, "usage:a.out /path/to/libm.so double\n");
exit(-1);
}
void *dlh;
double (*my_cbrt)(const double) = load_cbrt(&dlh, argv[1]);
double d = atof(argv[2]);
printf("my_cbrt(%.17g) = %.17g (@%p)\n", d, my_cbrt(d), my_cbrt);
printf(" cbrt(%.17g) = %.17g (@%p)\n", d, cbrt(d), cbrt);
return dlclose(dlh);
}
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]){
if (argc < 2) {
fprintf(stderr, "usage:a.out double\n");
exit(-1);
}
double d = atof(argv[1]);
return printf("cbrt(%.17g) = %.17g\n", d, cbrt(d));
}
@dankogai
Copy link
Author

dankogai commented Jun 6, 2018

try this on Linux

$ cc -Wall -O2 cbrttest.c -ldl -lm && ./a.out /lib/x86_64-linux-gnu/libm.so.6 0x1.ffffffffffffep-1

and you get

my_cbrt(0.99999999999999978) = 1.0000000000000002 (@0x7f163ac519e0)
   cbrt(0.99999999999999978) = 1.0000000000000002 (@0x400810)

on linux.

@dankogai
Copy link
Author

dankogai commented Jun 6, 2018

cbrttest_simple.c is simple and portable that compiles with:

$ cc -Wall -O2 cbrttest_simple.c -lm

correct platforms should print:

$ ./a.out 0x1.ffffffffffffep-1
cbrt(0.99999999999999978) = 0.99999999999999989

but Linux prints:

$ ./a.out 0x1.ffffffffffffep-1
cbrt(0.99999999999999978) = 1.0000000000000002

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment