লুয়ার উত্স কোডটি পড়ার সময় , আমি লক্ষ করেছি যে লুয়া একটি 32- বিটকে macro
গোল double
করতে একটি ব্যবহার করে int
। আমি এটি বের করেছি macro
এবং এটি দেখতে এরকম দেখাচ্ছে:
union i_cast {double d; int i[2]};
#define double2int(i, d, t) \
{volatile union i_cast u; u.d = (d) + 6755399441055744.0; \
(i) = (t)u.i[ENDIANLOC];}
এখানে বিস্তৃত ইন্ডিয়ানের জন্য , অ্যান্ডিয়ানেসের জন্য , আন্ডিয়াননেসENDIANLOC
হিসাবে সংজ্ঞায়িত করা হয়েছে । লুয়া সাবধানতার সাথে আধ্যাত্মিকতা পরিচালনা করে। পূর্ণসংখ্যা টাইপের জন্য দাঁড়ায়, যেমন বা ।0
1
t
int
unsigned int
আমি কিছুটা গবেষণা করেছি এবং এর একটি সহজ ফর্ম্যাট রয়েছে macro
যা একই চিন্তাভাবনাটি ব্যবহার করে:
#define double2int(i, d) \
{double t = ((d) + 6755399441055744.0); i = *((int *)(&t));}
অথবা একটি সি ++ - শৈলীতে:
inline int double2int(double d)
{
d += 6755399441055744.0;
return reinterpret_cast<int&>(d);
}
এই কৌশলটি আইইইই 754 ব্যবহার করে যে কোনও মেশিনে কাজ করতে পারে (যার অর্থ আজ প্রতিটি মেশিন বেশ)। এটি ইতিবাচক এবং নেতিবাচক উভয় সংখ্যার জন্যই কাজ করে এবং গোলটি ব্যাঙ্কারের নিয়ম অনুসরণ করে । (এটি আশ্চর্যজনক নয়, যেহেতু এটি আইইইই 754 অনুসরণ করে))
আমি এটি পরীক্ষা করার জন্য একটি ছোট প্রোগ্রাম লিখেছি:
int main()
{
double d = -12345678.9;
int i;
double2int(i, d)
printf("%d\n", i);
return 0;
}
এবং এটি ফলাফল হিসাবে -12345679, আশানুরূপ হিসাবে।
এই কৌশলটি কীভাবে macro
কাজ করে তা আমি বিশদে যেতে চাই । যাদু নম্বরটি 6755399441055744.0
আসলে 2^51 + 2^52
, বা 1.5 * 2^52
, এবং 1.5
বাইনারি হিসাবে উপস্থাপন করা যেতে পারে 1.1
। এই যাদু নম্বরটিতে যখন কোনও 32-বিট পূর্ণসংখ্যার যোগ করা হয়, ভাল, আমি এখান থেকে হারিয়েছি। এই কৌশলটি কীভাবে কাজ করে?
পিএস: এটি লুয়া সোর্স কোড, লিমিটস । হ'ল ।
আপডেট :
- @ মিস্টিটিয়াল পয়েন্ট হিসাবে, এই পদ্ধতিটি নিজেকে 32-বিটের মধ্যে সীমাবদ্ধ করে না , সংখ্যাটি 2 ^ 52 এর সীমাতে থাকা পর্যন্ত এটি
int
একটি 64- বিটেও প্রসারিত হতে পারেint
। (macro
কিছুটা পরিবর্তন দরকার)) - কিছু উপকরণ বলে যে এই পদ্ধতিটি ডিরেক্ট 3 ডি তে ব্যবহার করা যাবে না ।
X86 এর জন্য মাইক্রোসফ্ট এসেম্বলারের সাথে কাজ করার সময়, আরও একটি দ্রুত
macro
লিখিত আছেassembly
(এটি লুয়া উত্স থেকেও নেওয়া হয়):#define double2int(i,n) __asm {__asm fld n __asm fistp i}
একক নির্ভুলতার জন্য একই ধরণের ম্যাজিক নম্বর রয়েছে:
1.5 * 2 ^23
ftoi
। আপনি যদি এসএসইতে কথা বলছেন তবে কেন কেবল একক নির্দেশনা ব্যবহার করবেন না CVTTSD2SI
?
double -> int64
প্রকৃতপক্ষে 2^52
সীমার মধ্যে রয়েছে। ভাসমান-পয়েন্ট এফএফটি ব্যবহার করে পূর্ণসংখ্যার কনভোলিউশনগুলি সম্পাদন করার সময় এগুলি সাধারণত সাধারণ।