Consider next code:
#include <cmath>
unsigned int nump=12u;
auto inner=2.5;
auto outer=6.0;
auto single=2*3.14159265359/nump;
auto avg=0.5*inner+0.5*outer;
for (auto i=0u;i<nump;++i){
auto theta=i*single;
auto px=avg*sin(theta);
auto py=avg*cos(theta);
auto tw=17.;
int v1=std::round(1+px-tw/2.0);
int v2=std::round(2+py-tw/2.0);
std::cout<<"#"<<i<<":"<<v1<<";"<<v2<<std::endl;
}
it produces output like this:
#0:-8;-2
#1:-5;-3
#2:-4;-4
#3:-3;-7
#4:-4;-9
#5:-5;-10
#6:-8;-11
#7:-10;-10
#8:-11;-9
#9:-12;-6
#10:-11;-4
#11:-10;-3
Now let's modify this code by replacing most of "auto" with "float":
#include <cmath>
unsigned int nump=12u;
float inner=2.5;
float outer=6.0;
float single=2*3.14159265359/nump;
float avg=0.5*inner+0.5*outer;
for (unsigned int i=0u;i<nump;++i){
float theta=i*single;
float px=avg*sin(theta);
float py=avg*cos(theta);
float tw=17.;
int v1=std::round(1+px-tw/2.0);
int v2=std::round(2+py-tw/2.0);
std::cout<<"#"<<i<<":"<<v1<<","<<v2<<std::endl;
}
and here's the second output:
#0:-8,-2
#1:-5,-3
#2:-4,-4
#3:-3,-7
#4:-4,-9
#5:-5,-10
#6:-8,-11
#7:-10,-10
#8:-11,-9
#9:-12,-7
#10:-11,-4
#11:-10,-3
As one can see in line 9 values are different.
Any explanation?
PS. OS X 10.12 c++11 and c++14, Apple LLVM 8.1; however was observed also on linux platform with C++17.
UPDATE
As people suggested I modified the code by adding "f" suffix to floating-point values.
unsigned int nump=12u;
auto inner=2.5f;
auto outer=6.0f;
auto single=2.f*3.14159265359f/nump;
auto avg=0.5f*inner+0.5f*outer;
for (auto i=0u;i<nump;++i){
auto theta=i*single;
auto px=avg*sin(theta);
auto py=avg*cos(theta);
auto tw=17.f;
int v1=std::round(1.f+px-tw/2.0f);
int v2=std::round(2.f+py-tw/2.0f);
std::cout<<"#"<<i<<":"<<v1<<";"<<v2<<std::endl;
}
versus
unsigned int nump=12u;
float inner=2.5f;
float outer=6.0f;
float single=2.f*3.14159265359f/nump;
float avg=0.5f*inner+0.5f*outer;
for (unsigned int i=0u;i<nump;++i){
float theta=i*single;
float px=avg*sin(theta);
float py=avg*cos(theta);
float tw=17.f;
int v1=std::round(1.f+px-tw/2.0f);
int v2=std::round(2.f+py-tw/2.0f);
std::cout<<"#"<<i<<":"<<v1<<";"<<v2<<std::endl;
}
The result is exactly the same.