Here is what happens (experiments repeated with identical results with OpenBSD 5.1 both on x86_64 and sparc64):
-bash-4.2$ cat bug.cc #include <cmath> #include <cstdlib> #include <cstdio> int main(int argc, char **argv) { long double x = strtold(argv[1], 0); long double y = std::floor(x); printf("%.1000Lg\n%.1000Lg\n", x, y); } -bash-4.2$ g++ bug.cc -bash-4.2$ ./a.out 13311002825915415087 13311002825915415087 13311002825915414528 -bash-4.2$ As you can see, std::floor(x) returns a wrong result. An equivalent C program does the right thing: -bash-4.2$ cat bug.c #include <math.h> #include <stdlib.h> #include <stdio.h> int main(int argc, char **argv) { long double x = strtold(argv[1], 0); long double y = floorl(x); printf("%.1000Lg\n%.1000Lg\n", x, y); } -bash-4.2$ gcc bug.c -lm -bash-4.2$ ./a.out 13311002825915415087 13311002825915415087 13311002825915415087 -bash-4.2$ But not if it is linked with -lstdc++ instead of -lm: -bash-4.2$ gcc bug.c -lstdc++ -bash-4.2$ ./a.out 13311002825915415087 13311002825915415087 13311002825915414528 -bash-4.2$ The reason why libstdc++ on OpenBSD exports a bogus version of floorl() probably lies with the following piece of code: #ifndef HAVE_FLOORL long double floorl(long double x) { return floor((double) x); } #endif It would seem that, on OpenBSD, libstdc++ is compiled with HAVE_FLOORL not defined. -- Roberto Bagnara BUGSENG srl http://bugseng.com mailto:roberto.bagn...@bugseng.com