常数0.0039215689代表什么?

cru*_*ush 308 c floating-point constants magic-numbers

我一直看到这个常量弹出各种图形头文件

0.0039215689
Run Code Online (Sandbox Code Playgroud)

它似乎与颜色有关吗?

这是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
Run Code Online (Sandbox Code Playgroud)

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

我无法在Google上找到解释它的任何内容.

Mys*_*ial 377

0.0039215689差不多等于1/255.

看到这是OpenGL,性能可能很重要.所以可以安全地猜测这是出于性能原因而做的.

乘以倒数比重复除以255要快.


边注:

如果您想知道为什么这样的微优化不会留给编译器,那是因为它是一种不安全的浮点优化.换一种说法:

x / 255  !=  x * (1. / 255)
Run Code Online (Sandbox Code Playgroud)

由于浮点舍入错误.

因此,虽然现代编译器可能足够聪明以进行此优化,但除非您通过编译器标志明确告诉它们,否则不允许它们执行此操作.

相关: 为什么GCC没有优化a*a*a*a*a*a到(a*a*a)*(a*a*a)?

  • 我希望看到它写成`a = b*(1.0f/255)`; 编译器仍然不断折叠,不是吗? (54认同)
  • 我第一次看到它时其实并不知道它是什么.但是看到它的使用方式,我怀疑这是多次互补的优化.所以我检查了我的计算器,果然 - 我猜对了. (10认同)
  • @IlmariKaronen是的,他们仍然不断折叠.它实际上需要一些东西,如模板分辨率等.但我会把它作为一个常数或一个宏来拉出来.但是,嘿,并非所有代码都是完美的.:) (9认同)
  • 当然,要回答我自己的问题,这是因为其他两个数字不能表示为标准C浮点数.0.0039215689下方的下一个浮动汇率为0.0039215684. (7认同)
  • @hippietrail最初,我想知道同样的事情.但是如果你使用256,它将从`0.0 - 0.996`扩展而不是所需的'0.0 - 1.0`.(`0.996 = 255/256`其中`255`是最大的8位整数) (5认同)
  • 当然,编写头文件的更好的程序员会定义一个常量并按名称使用它. (5认同)
  • 一个有趣的问题可能是 - 为什么不是0.0039215686或0.0039215687,它们是在相同精度水平上更接近的近似值? (4认同)
  • @Bohemian IIRC,该标准允许一些余地,因为浮点表达式的中间结果可以以更高的精度完成.`strictfp`将其关闭.但要进行需要关联性的不安全浮点优化([例如](http://stackoverflow.com/questions/6430448/why-doesnt-gcc-optimize-aaaaaa-to-aaaaaa)),你需要告诉编译器来做到这一点.(在GCC中,它将是`-ffast-math`.) (2认同)
  • @Bohemian`ptrictff`不是C标准的一部分.它存在于Java中,但不应混淆Java和C关于浮点的讨论,它们各自都很复杂(并且完全不同). (2认同)

Dav*_*nan 79

该乘法通过0.0039215689f将0到255范围内的整数值颜色强度转换为0到1范围内的实值颜色强度.

正如Ilmari Karonen指出的那样,即使这是一个优化,它也是一个相当糟糕的表达.繁殖会更加清晰(1.0f/255).

  • @Johny当然定义为常数.这一点不是神奇的价值. (9认同)
  • 或者更好,定义为常数? (5认同)