خطأ C # تشمل الزوجي والأعداد الصحيحة
سؤال
for (iy = 0; iy < h; iy++)
{
double angy = (camera.fov_y / h) * iy;
for (ix = 0; ix < w; ix++)
{
double angx = (camera.fov_x / w) * ix;
//output[ix,iy].r = (int)Math.Round(255 * (angy / camera.fov_y);
//output[ix,iy].b = (int)Math.Round(255 * (angy / camera.fov_y);
double tr = (angx / camera.fov_x) * 255D;
double tb = (angy / camera.fov_y) * 255D;
Console.Write("({0},{1})",Math.Round(tr),Math.Round(tb));
output.SetPixel(ix, iy, Color.FromArgb(Convert.ToInt32(tr), 0, Convert.ToInt32(tb)) );
Console.Write(".");
}
Console.WriteLine();
}
هل يمكن لأي شخص أن يرى أي مشاكل فورية مع هذا الرمز؟ المتغيرات tr
و tb
دائما تقييم إلى 0.
أنا سعيد بتقديم المزيد من المعلومات إذا كانت هناك حاجة إليها.
المحلول
لم تعط الأنواع من المتغيرات الأخرى - على وجه الخصوص، ما هي أنواع camera.fov_x
و camera.fov_y
ب إذا كانوا على حد سواء أعداد صحيحة، فسيتم تهيئة الخطوط angx
و angy
سيتم تقييمها باستخدام الحساب الصحيحة.
يمكن إصلاح ذلك عن طريق صب إحدى المعاملات:
double angy = ((double) camera.fov_y / h) * iy;
ال fovy
و fovx
المتغيرات تتضاعف بالفعل، هذه ليست هي المشكلة.
هل يمكن أن تعطي مثالا كاملا على هذا، والذي يمكننا ترجمةه واختبر أنفسنا؟
تحرير: تحرير Koistya Navin هو مبالغة. تحتاج فقط إلى معامل واحد من التعبير ليكون مزدوجا لحساب كل شيء باستخدام حسابي مزدوج. (يجب أن يكون التعبير الصحيح رغم ذلك - إذا قمت بذلك (a/b) * c
و cast. c
مزدوج، وسيتم الانتهاء من الضرب بحساب مزدوج ولكن A / B قد لا يزال يحدث كعضات صحيحة.)
هنا تم تغيير القائمة بشكل مناسب للتأكد من استخدام الحساب المزدوج في كل مكان يجب أن يكون:
// Changed loops to declare the variable, for stylistic purposes
for (int iy = 0; iy < h; iy++)
{
// Changed here - cast camera.fov_y
double angy = ((double) camera.fov_y / h) * iy;
for (int ix = 0; ix < w; ix++)
{
// Changed here - cast camera.fov_x
double angx = ((double) camera.fov_x / w) * ix;
//output[ix,iy].r = (int)Math.Round(255 * (angy / camera.fov_y);
//output[ix,iy].b = (int)Math.Round(255 * (angy / camera.fov_y);
double tr = (angx / camera.fov_x) * 255D;
double tb = (angy / camera.fov_y) * 255D;
Console.Write("({0},{1})", Math.Round(tr), Math.Round(tb));
output.SetPixel(ix, iy, Color.FromArgb(Convert.ToInt32(tr),
0,
Convert.ToInt32(tb)) );
Console.Write(".");
}
Console.WriteLine();
}
نصائح أخرى
إنه يعرف أنه ليس جزءا من سؤالك الأصلي، ولكن باستخدام SetPixel (..) ليس فعالا للغاية ويمكن أن يكون مشكلة إذا كنت تخطط لاستخدامه في محرك راي.
قد ترغب في استخدام طريقة Lockbits ()، راجع هذا إجابه و هذا لمزيد من التفاصيل. إنهم بطريقة أخرى للذهاب هو الوصول إلى البيانات باستخدام رمز "غير آمن" C #، والذي يسمح لك باستخدام مؤشرات إلى البيانات. يرى هذا السؤال لمزيد من المعلومات، حصلت على سرعة ~ x2 باستخدام رمز "غير آمن".
لا تنس أن يلقي الأعداد الصحيحة الخاصة بك للتضاعف. علي سبيل المثال:
for (iy = 0; iy < h; iy++)
{
double angy = ((double) camera.fov_y / h) * iy;
for (ix = 0; ix < w; ix++)
{
double angx = ((double) camera.fov_x / (double) w) * (double) ix;
output[ix,iy].r = (int) Math.Round(255 * (angy / camera.fov_y);
output[ix,iy].b = (int) Math.Round(255 * (angy / camera.fov_y);
double tr = (angx / camera.fov_x) * 255D;
double tb = (angy / camera.fov_y) * 255D;
Console.Write("({0},{1})",Math.Round(tr), Math.Round(tb));
output.SetPixel(ix, iy, Color.FromArgb(
Convert.ToInt32(tr), 0, Convert.ToInt32(tb)) );
Console.Write(".");
}
Console.WriteLine();
}
مرجع سريع:
int * double = double
int / double = double
double * int = double
double / int = double
int * int = int
int / int = int // be carefull here!
1 / 10 = 0 (not 0.1D)
10 / 11 = 0 (not 1)
1D / 10 = 0.1D
1 / 10D = 0.1D
1D / 10D = 0.1D