https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63269
--- Comment #5 from Dominik Vogt <vogt at linux dot vnet.ibm.com> --- regarding 1) My earlier explanation of the problem was wrong. Multiply and add is not generated; it probably only was in the artificial test case that I made and certainly did not compile with -ffp-contract=off. In this calculation in log2(), Log(frac)*(1/Ln2) + float64(exp) Gcc does constant folding for (1/Ln2) and generates a multiply instruction and then adds the second term. Same result if you write "*Log2E" instead of "*(1/Ln2)"). But with Log(frac)/Ln2 + float64(exp) it generates a divide instruction. The multiplication and the division yield results that differ in the least significant bit, and I don't see how this could be prevented in general; it's just an artifact of the floating point format. I've verified that the constants Ln2, 1/Ln2 and Log2E are bit correct. The "easy" way to fix this is increasing the allowed tolerance as my patch does (note that the arguments of the veryclose() call need to be swapped, see previous comment). The "right" way to fix this is to calculate platform specific ULPs for all the algorithms from the math library and use these. That's what glibc does.