The cppreference documentation states that std::round will specifically round away from zero in "halfway cases." While this is true with the literal 0.5, it's not true with std::sin(pi/6). I thought this might be a floating point error, so I printed the value but it's exactly 0.5. After inspecting the binary representation however, I can see that they are indeed represented differently. I've provided the code I used to make these inspections below.
#include <iostream>
#include <stdio.h>
#include <cmath>
int main(int argc, char * argv[])
{
double const pi = std::acos(-1);
double const a = std::sin(pi/6);
double const b = 0.5;
std::cout << "round(" << a << ") = " << std::round(a) << "\n";
auto pa = reinterpret_cast<const unsigned char *>(&a);
auto pb = reinterpret_cast<const unsigned char *>(&b);
std::cout << "a = 0x";
for (size_t i = 0; i != sizeof(double); ++i) {
printf("%02x", pa[i]);
}
std::cout << "\nb = 0x";
for (size_t i = 0; i != sizeof(double); ++i) {
printf("%02x", pb[i]);
}
std::cout << "\n";
}
round(0.5) = 0
round(0.5) = 1
a = 0xffffffffffffdf3f
b = 0x000000000000e03f
So my question is this rounding behavior a part of the c++ specification or is this a bug? And in any case, is there some general way that I can "correct" the representation of the value returned by sin? I'm not sure what format it's in because based off what I know of IEEE-754, it looks like it should be NaN. Although from what I understand, c++ doesn't guarantee IEEE-754 floating point representation?