double pi = 3.14159;C++ does not perform this converting from double to it automatically, because it requires the rounding off and you should be aware that you lost the fractial part of the number.
int x = int (pi);
So? In a library that works with OpenGL I see this strange code:
__inline GLfixedWhy this line with *((GLuint*)&b) should be so complicated?
Fixedf(GLfloat a)
{
GLfloat b = a;
GLuint d = *((GLuint*)&b) + 0x08000000;
return (GLfixed)(*((GLfloat*)&d));
}
In order to see what's going on I wrote few lines:
int main()
{
double x1 = 123.456;
double x2 = 321.654;
int y1 = (int)x1;
int y2 = static_cast<int>(x1);
int y3 = *(int*)&x2;
int y4 = *reinterpret_cast<int*>(&x2);
return 0;
}
In the debug mode I switched to the disassember:
I'm not a guru in such things, but looks like this line:
int y3 = *(int*)&x2;seems "complicated" only in C++. In Assembler it looks trivial:
mov eax,dword ptr [x2]You can compare it with:
mov dword ptr [y3],eax
fld qword ptr [x1]generated from usual:
call @ILT+215(__ftol2_sse) (4110DCh)
mov dword ptr [y1],eax
int y1 = (int)x1;
But the result is absolutely different:
That's not what I need.
In Anti-Grain Geometry Library I found:
#pragma warning(push)
#pragma warning(disable : 4035) //Disable warning "no return value"
inline int iround(double v) //-------iround
{
int t;
__asm fld qword ptr [v]
__asm fistp dword ptr [t]
__asm mov eax, dword ptr [t]
}
inline unsigned uround(double v) //-------uround
{
unsigned t;
__asm fld qword ptr [v]
__asm fistp dword ptr [t]
__asm mov eax, dword ptr [t]
}
#pragma warning(pop)
So it is possible to use:
int y5 = iround(x1);
The result will be correct:
No comments:
Post a Comment