常数0.0039215689代表什么?

314

我看到这个常数在各种图形头文件中不断出现。

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

这个数字代表什么?为什么似乎没有人将它声明为const?

我在谷歌上找不到任何解释。


16
源代码为什么要写成这样(1.f/256)而不是(1.f/255) - M.M
58
嗯嗯……如果有办法避免魔数就好了。 - Paul Draper
12
1/255 == 0.00(3921568627450980) 翻译为:1除以255等于0.00(3921568627450980),括号表示重复。 - jfs
85
请尝试使用下一个魔法数字,访问Wolfram Alpha - AakashM
15
无论出于什么原因,使用魔数而不说明其目的是非常不酷的。 - Isaac Rabinovitch
显示剩余12条评论
2个回答

387

0.0039215689 大约等于 1/255

鉴于这是OpenGL,性能可能很重要。因此可以猜测这是为了提高性能而做的。

乘以倒数比反复除以255更快。


附注:

如果你想知道为什么这样的微小优化不留给编译器处理,那是因为它是一种不安全的浮点优化。换句话说:

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

由于浮点数舍入误差的原因。

因此,虽然现代编译器可能足够聪明以执行这种优化,但除非您通过编译器标志显式告诉它们,否则它们不允许这样做。

相关:为什么GCC不将a*a*a*a*a*a优化为(a*a*a)*(a*a*a)?


10
当我第一次看到它时,实际上我不知道它是什么。但看到它的使用方式,我怀疑它是倒数乘优化。所以我在计算器中进行了确认,果然——我猜对了。 - Mysticial
57
我本来希望看到写成 a = b * (1.0f / 255);编译器现在还会做常量折叠,不是吗? - Ilmari Karonen
9
@IlmariKaronen 大家好,他们仍在进行常数折叠。这实际上对一些操作比如模板分辨率是必须的。但我可能会将其作为常量或宏来提取。不过,嘿,并不是所有的代码都是完美的编写。 :) - Mysticial
7
当然,回答我的问题,是因为另外两个数字无法用标准的C浮点数表示。比0.0039215689小的下一个浮点数是0.0039215684。 - Daniel Waechter
6
当然,一位更好的程序员在编写头文件时会定义一个常量,并使用其名称。 - Jack Aidley
显示剩余15条评论

79

这个乘以0.0039215689f的操作将范围在0到255之间的整数颜色强度转换为范围在0到1之间的实数颜色强度。

正如Ilmari Karonen指出的那样,即使这是一种优化,但表述不够清晰。最好乘以(1.0f/255)


5
或许更好的定义是“常数”? - Johny
11
@Johny 的意思是将其定义为一个常数,重点在于它不是一个神奇的值。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接