0.0039215689 คงที่คืออะไร


310

ฉันยังคงเห็นนี้คงปรากฏขึ้นในไฟล์ส่วนหัวกราฟิกต่างๆ

0.0039215689

ดูเหมือนว่าจะมีบางอย่างที่เกี่ยวกับสีอาจจะ?

นี่คือการโจมตีครั้งแรกใน Google :

void RDP_G_SETFOGCOLOR(void)
{
    Gfx.FogColor.R = _SHIFTR(w1, 24, 8) * 0.0039215689f;
    Gfx.FogColor.G = _SHIFTR(w1, 16, 8) * 0.0039215689f;
    Gfx.FogColor.B = _SHIFTR(w1, 8, 8) * 0.0039215689f;
    Gfx.FogColor.A = _SHIFTR(w1, 0, 8) * 0.0039215689f;
}

void RDP_G_SETBLENDCOLOR(void)
{
    Gfx.BlendColor.R = _SHIFTR(w1, 24, 8) * 0.0039215689f;
    Gfx.BlendColor.G = _SHIFTR(w1, 16, 8) * 0.0039215689f;
    Gfx.BlendColor.B = _SHIFTR(w1, 8, 8) * 0.0039215689f;
    Gfx.BlendColor.A = _SHIFTR(w1, 0, 8) * 0.0039215689f;

    if(OpenGL.Ext_FragmentProgram && (System.Options & BRDP_COMBINER)) {
        glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, Gfx.BlendColor.R, Gfx.BlendColor.G, Gfx.BlendColor.B, Gfx.BlendColor.A);
    }
}

//...more like this

หมายเลขนี้หมายถึงอะไร ทำไมดูเหมือนไม่มีใครประกาศว่าเป็นกลุ่ม?

ฉันไม่พบสิ่งใดบน Google ที่อธิบายไว้


16
มีเหตุผลใดที่ซอร์สโค้ดจะเขียนแทน(1.f/255)?
MM

53
อืม ... ถ้ามีเพียงวิธีการที่จะหลีกเลี่ยงตัวเลขเวทย์มนตร์ ....
Paul Draper

12
1/255 == 0.00(3921568627450980)- parens หมายถึงการทำซ้ำ
jfs

82
ด้วยหมายเลขเวทมนต์ถัดไปของคุณลองถาม Wolfram Alpha
AakashM

12
เหตุผลใดที่ใช้จำนวนมายากลโดยไม่มีการจัดเก็บเอกสารวัตถุประสงค์คือเทห์มาก
ไอแซก Rabinovitch

คำตอบ:


378

0.00392156891/255จะประมาณเท่ากับ

เห็นว่านี่คือ OpenGL ประสิทธิภาพอาจมีความสำคัญ ดังนั้นจึงอาจปลอดภัยที่จะคาดเดาว่าสิ่งนี้ทำขึ้นเพื่อเหตุผลด้านประสิทธิภาพ

การคูณด้วยส่วนกลับจะเร็วกว่าการหาร 255 ซ้ำ ๆ


หมายเหตุด้านข้าง:

หากคุณสงสัยว่าทำไมการเพิ่มประสิทธิภาพขนาดเล็กดังกล่าวไม่ได้ถูกรวมอยู่ในคอมไพเลอร์นั่นเป็นเพราะเป็นการเพิ่มประสิทธิภาพจุดลอยตัวที่ไม่ปลอดภัย ในคำอื่น ๆ :

x / 255  !=  x * (1. / 255)

เนื่องจากข้อผิดพลาดในการปัดเศษทศนิยม

ดังนั้นในขณะที่คอมไพเลอร์สมัยใหม่อาจฉลาดพอที่จะทำการเพิ่มประสิทธิภาพนี้พวกเขาไม่ได้รับอนุญาตให้ทำเว้นแต่คุณจะบอกพวกเขาอย่างชัดแจ้งผ่านธงคอมไพเลอร์

ที่เกี่ยวข้อง: เหตุใด GCC จึงไม่เพิ่มประสิทธิภาพ a * a * a * a * a ถึง (a * a * a) * (a * a * a)


10
จริง ๆ แล้วฉันไม่รู้ว่ามันคืออะไรเมื่อฉันเห็นครั้งแรก แต่เมื่อเห็นถึงวิธีการใช้งานฉันสงสัยว่ามันเป็นการเพิ่มประสิทธิภาพแบบทวีคูณซึ่งกันและกัน ดังนั้นฉันจึงตรวจสอบในเครื่องคิดเลขของฉันและแน่นอน - ฉันเดาถูก
Mysticial

55
ฉันคาดว่าจะเห็นมันเขียนเป็นa = b * (1.0f / 255); คอมไพเลอร์ยังคงพับอย่างต่อเนื่องใช่ไหม?
Ilmari Karonen

9
@IlmariKaronen ใช่พวกเขายังคงพับอย่างต่อเนื่อง จริงๆแล้วมันจำเป็นสำหรับบางสิ่งเช่นการแก้ปัญหาเทมเพลตและเช่นนั้น แต่ฉันจะดึงมันออกมาเป็นค่าคงที่หรือมาโคร แต่เฮ้ไม่ใช่รหัสทั้งหมดจะถูกเขียนอย่างสมบูรณ์แบบ :)
Mysticial

5
@hippietrail ตอนแรกฉันสงสัยในสิ่งเดียวกัน แต่ถ้าคุณใช้ 256 ก็จะไต่จากแทนที่ต้องการ0.0 - 0.996 0.0 - 1.0( 0.996 = 255/256ซึ่ง255เป็นจำนวนเต็ม 8 บิตที่ใหญ่ที่สุด)
Mysticial

7
และแน่นอนเพื่อตอบคำถามของฉันเองมันเป็นเพราะตัวเลขสองตัวไม่สามารถแสดงเป็น C มาตรฐานลอยได้ ลอยถัดไปต่ำกว่า 0.0039215689 คือ 0.0039215684
Daniel Waechter

79

การคูณด้วยการ0.0039215689fแปลงความเข้มสีที่มีค่าจำนวนเต็มในช่วง 0 ถึง 255 เป็นความเข้มสีที่มีมูลค่าจริงในช่วง 0 ถึง 1

ตามที่ Ilmari Karonen ชี้ให้เห็นแม้ว่านี่เป็นการเพิ่มประสิทธิภาพ แต่ก็เป็นการแสดงออกที่ไม่ดีเลยทีเดียว (1.0f/255)มันจะเป็นที่ชัดเจนมากที่จะคูณด้วย


5
หรืออาจจะดีกว่าที่กำหนดไว้เป็นค่าคงที่?
Johny

9
@Johny กำหนดไว้แน่นอนว่าเป็นค่าคงที่ จุดที่ไม่ใช่ค่าเวทย์มนตร์
David Heffernan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.