gaR*_*Rex 7 c c++ casting rounding floor
最近我在webkit源代码中发现了这个有趣的东西,与颜色转换有关(hsl到rgb):
http://osxr.org/android/source/external/webkit/Source/WebCore/platform/graphics/Color.cpp#0111
const double scaleFactor = nextafter(256.0, 0.0); // it's here something like 255.99999999999997
// .. some code skipped
return makeRGBA(static_cast<int>(calcSomethingFrom0To1(blablabla) * scaleFactor),
Run Code Online (Sandbox Code Playgroud)
同样我在这里找到:http://www.filewatcher.com/p/kdegraphics-4.6.0.tar.bz2.5101406/kdegraphics-4.6.0/kolourpaint/imagelib/effects/kpEffectHSV.cpp.html
(int)(value * 255.999999)
Run Code Online (Sandbox Code Playgroud)
完全使用这种技术是否正确?为什么不直接使用圆形(blabla*255)?它是C/C++的功能吗?正如我所看到的那样,严格来说将返回并不总是正确的结果,在27例中为100.请参阅电子表格,网址为https://docs.google.com/spreadsheets/d/1AbGnRgSp_5FCKAeNrELPJ5j9zON9HLiHoHC870PwdMc/edit?usp=sharing
有人请解释 - 我认为它应该是基本的东西.
leo*_*loy 25
通常我们希望x将(闭合)区间中的实际值映射[0,1] 到j该范围内的整数值[0 ...255].
并且我们希望以"公平"的方式进行,因此,如果实数均匀分布在范围内,则离散值将近似等概率:256个离散值中的每一个应该得到"相同的份额"(1/256)从[0,1]间隔.也就是说,我们想要这样的映射:
[0 , 1/256) -> 0
[1/256, 2/256) -> 1
...
[254/256, 255/256) -> 254
[255/256, 1] -> 255
Run Code Online (Sandbox Code Playgroud)
我们并不太关心过渡点[*],但我们确实希望覆盖整个范围[0,1].怎么做到这一点?
如果我们只是这样做j = (int)(x *255):值255几乎永远不会出现(仅当时x=1); 其余的值0...254将分别获得间隔的1/255.无论极限点的舍入行为如何,这都是不公平的.
如果我们改为j = (int)(x * 256):这个分区是公平的,除了一个sngle问题:当x=1[**] 时我们会得到值256(超出范围!)
这就是为什么j = (int)(x * 255.9999...)(255.9999...实际上最小的双倍小于256)将会这样做.
另一种实施方式(也是合理的,几乎相当的)将是
j = (int)(x * 256);
if(j == 256) j = 255;
// j = x == 1.0 ? 255 : (int)(x * 256); // alternative
Run Code Online (Sandbox Code Playgroud)
但这会更笨拙,可能效率更低.
round()在这里没有帮助.例如,对于j = (int)round(x * 255)整数给出1/255的份额j=1...254,给极值点给出一半的值j=0,j=255.

[*]我的意思是:我们对3/256的"小"邻域中发生的事情并不十分感兴趣:四舍五入可能会给出2或3,这没关系.但我们感兴趣的极值:我们希望得到0和255,用于x=0和x=1分别.
[**] IEEE浮点标准保证这里没有舍入歧义:整数允许精确的浮点表示,产品将是精确的,并且转换将始终为256.此外,我们保证1.0 * z = z.
一般来说,我认为(int)(blabla * 255.99999999999997)比使用更正确round().
为什么?
因为round(),0和255只有1-254的"半"范围.如果你round(),则0-0.00196078431被映射到0,而0.00196078431-0.00588235293被映射到1.这意味着1的发生概率比0高200%,严格来说,这是一种不公平的偏见.
如果,isntead,一个乘以255.99999999999997然后floor(这是一个整数的转换,因为它截断),那么从0到255的每个整数都是相同的.
如果以小数百分比计算,您的电子表格可能会更好地显示(例如,如果它每次计算0.01%而不是1%).我已经制作了一个简单的电子表格来展示这一点.如果你看一下那个电子表格,你会看到0在进行时是不公平的偏见round(),但是使用其他方法,事情是公平和平等的.