C# 协议缓冲区中的uint转换
我在中定义了颜色消息,如下所示:C# 协议缓冲区中的uint转换,c#,protocol-buffers,C#,Protocol Buffers,我在中定义了颜色消息,如下所示: message Color { fixed32 rgb = 1; } 我用C语言定义颜色如下: byte red = pixels[4 * index + 0]; byte green = pixels[4 * index + 1]; byte blue = pixels[4 * index + 2]; byte alpha = pixels[4 * index + 3]; Color color = new Color { Rg
message Color {
fixed32 rgb = 1;
}
我用C语言定义颜色如下:
byte red = pixels[4 * index + 0];
byte green = pixels[4 * index + 1];
byte blue = pixels[4 * index + 2];
byte alpha = pixels[4 * index + 3];
Color color = new Color
{
Rgb = (uint)((red << 16) | (green << 8) | blue)
};
byte red=像素[4*索引+0];
字节绿色=像素[4*索引+1];
字节蓝色=像素[4*索引+2];
字节alpha=像素[4*索引+3];
颜色=新颜色
{
Rgb=(uint)((红色是的,这非常有效。这里发生的是字节上的移位运算符(
)返回int
。因为……原因。实际上,字节上的几乎所有运算符都返回int
-“或”(
)两个字节
值之和也是一个int
编译器不喜欢盲目地让您将int
强制转换为uint
,因此它只希望您确认您正在这样做,这就是您添加的(uint)
所做的
因为我们知道您只填充前24位,所以我们知道该值始终为正,因此它将始终是可以安全地转换为无符号(uint
)的正整数
如果填充所有32位,则最终值可能为负值,但默认情况下,C#编译器在“未选中”状态下工作模式,所以:它不在乎。它会很高兴地将负的int
投射到uint
-8
变成4294967288
,例如。但是,作为命令行选项,“checked”可以启用模式-在这种情况下,您将得到一个溢出异常
。为了避免这种情况,可以使用未选中的
修饰符来告诉它显式不在乎,例如:
int i = -8;
uint u = unchecked((uint)i);
或
但是,几乎不需要使用checked
。人们通常在关心溢出的地方添加偶尔的checked
修饰符
最后总结:是的,你所拥有的一切都很好。非常感谢。换句话说,如果我也将包含alpha值的颜色定义为fixed32 rgba
,那么我最好添加以下rgba=unchecked((uint)(红色@RaviJoshi),除非你特意启用“checked mode”,则无所谓;如果您希望代码以相同的方式工作,而不管是否有人启用“选中模式”在构建中,我当然明白了。我在这里有点困惑。在上面的例子中,你提到了未检查的
,并解释了它在负数情况下很重要。但是,alpha是透明的,它永远不能是负数。我们事先就知道了。因此我真的需要使用“未检查的”?@Ravi作为两个补码二进制算术,如果最高有效位为1,则值为负。因此,如果alpha为128或更高,然后将其左移24位,则32位整数的最高有效位为1,为负。注意:如果不填充第4个字节,则根本不必担心它:无法获得负int32如果你只是将r,g和b组合成较低的24位,那么在你添加有意义的“alpha”之前,不需要取消选中。非常感谢。
int i = -8;
uint u = unchecked((uint)i);
unchecked
{
int i = -8;
uint u = (uint)i;
// ...
}