C#:无法从ulong转换为byte

时间:2009-03-26 13:17:27

标签: c# byte long-integer unsigned

奇怪的是我如何在C ++中完成它,而不是在C#中。

为了清楚起见,我将两个函数粘贴在C ++中,然后粘贴到C#中,并用C#代码标记有问题的行,并带有注释“// error”。 这两个函数的作用是对参数进行编码,然后将其添加到名为byte1seeds的全局变量中。

这些是C ++中的函数

//Global var:

unsigned char byte1seeds[3];

unsigned long GenerateValue( unsigned long * Ptr )
{
unsigned long val = *Ptr;
for( int i = 0; i < 32; i++ )
    val = (((((((((((val >> 2)^val) >> 2)^val) >> 1)^val) >> 1)^val) >> 1)^val)&1)|((((val&1) << 31)|(val >> 1))&0xFFFFFFFE);
return ( *Ptr = val );
}

void SetupCountByte( unsigned long seed )
{
if( seed == 0 ) seed = 0x9ABFB3B6;
unsigned long mut = seed;
unsigned long mut1 = GenerateValue( &mut );
unsigned long mut2 = GenerateValue( &mut );
unsigned long mut3 = GenerateValue( &mut );
GenerateValue( &mut );
unsigned char byte1 = (mut&0xFF)^(mut3&0xFF);
unsigned char byte2 = (mut1&0xFF)^(mut2&0xFF);
if( !byte1 ) byte1 = 1;
if( !byte2 ) byte2 = 1;
byte1seeds[0] = byte1^byte2;
byte1seeds[1] = byte2;
byte1seeds[2] = byte1;
}

现在是C#代码:

我已经改变了函数GenerateValue。它没有指针作为参数,它有一个ulong参数。

要调用它并更改我使用的两个值:

  1. ulong mut1 = GenerateValue(mut);
  2. mut = mut1;
  3. 以下是已翻译的函数(有问题的行标有“// error”);

    //Global var:
    public static byte[] byte1seeds = new byte[3];
    
    public static ulong GenerateValue(ulong val)
    {
        for( int i = 0; i < 32; i++ )
            val = (((((((((((val >> 2)^val) >> 2)^val) >> 1)^val) >> 1)^val) >> 1)^val)&1)|((((val&1) << 31)|(val >> 1))&0xFFFFFFFE);
        return val ;
    }
    
    public static void SetupCountByte( uint seed )
    {
        if( seed == 0 ) seed = 0x9ABFB3B6;
        ulong mut = seed;
        ulong mut1 = GenerateValue(mut);
        mut = mut1;
        ulong mut2 = GenerateValue(mut);
        mut = mut2;
        ulong mut3 = GenerateValue(mut);
        mut = mut3;
        mut = GenerateValue(mut);
        byte byte1 = (mut & 0xFF) ^ (mut3 & 0xFF); //error
        byte byte2 = (mut1 & 0xFF) ^ (mut2 & 0xFF); //error
        if( byte1 != 0 )
            byte1 = 1;
        if( byte2 != 0 )
            byte2 = 1;
        byte1seeds[0] = byte1^byte2; //error
        byte1seeds[1] = byte2;
        byte1seeds[2] = byte1;
    }
    

    错误是:

    无法将类型'ulong'隐式转换为'byte'。存在显式转换(您是否错过了演员?)

    编辑:有问题的第3行的错误是:

    无法将类型'int'隐式转换为'byte'。存在显式转换(您是否错过了演员?)

    问题是:如何解决这些错误?

    提前致谢!

5 个答案:

答案 0 :(得分:11)

添加(byte)进行投射。由于您可能会失去精度,您必须告诉编译器该值将适合一个字节,即

byte byte1 = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));
byte byte2 = (byte)((mut1 & 0xFF) ^ (mut2 & 0xFF));

答案 1 :(得分:2)

你可能会失去信息。除非您明确告诉他这样做,否则编译器不允许这种操作。所以尝试这样的事情:

byte result = ((byte)mut & 0xFF) ^ ((byte)mut3 & 0xFF);

这样,所有变量都是显式转换的,结果将是一个字节。或者你可以这样做:

byte result = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));

答案 2 :(得分:2)

症状

以下代码在C ++中编译但被C#编译器拒绝,第三行报告类型不兼容。

ulong mut = 5;
ulong mut3 = 6;
byte foo = (mut & 0xFF) ^ (mut3 & 0xFF);

说明

表达式(mut & 0xFF) ^ (mut3 & 0xFF)的类型为ulong,无法分配给byte类型的变量。

变量mutulong&的所有重载都需要操作数类型对称,因此在表达式(mut & 0xFF)中,值0xFF被提升为ulong,并且操作的结果具有类型{{ 1}}。

虽然类似的过程也会为第二个子表达式提供ulong类型,但这是偶然的,因为在较大的表达式ulong中,表达式A ^ B具有类型{{1会导致表达式A被提升。

因此,表达式ulong属于B类型,需要显式强制转换才能将其分配给(mut & 0xFF) ^ (mut3 & 0xFF)类型的变量。

解决方案

在分配之前明确地对整个表达式进行类型转换。

说明

人们会关闭警告而不是考虑它们,因为大多数C +库都充满了缺陷。如果你重新打开警告就会得到这么多,试图趟过它们是没用的,即使在混乱的某个地方也会有一个注释“需要潜在的有损隐式类型转换”。

如果您阅读C#语言规范,特别是运算符,您将学到很多有用的东西。例如,此代码将失败:

ulong

但这些都会成功:

byte

答案 3 :(得分:1)

“显式转换存在”表示您需要进行显式转换。在这种情况下,这将是:

byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );
byte byte2 = (byte) ( (mut1 & 0xFF) ^ (mut2 & 0xFF) );

答案 4 :(得分:1)

有一个MSDN Knowledge Base article深入解释了显式向下转换的必要性。错误消息中的“显式转换存在”一词旨在表明您必须使用强制转换显式转换数据类型。在您的具体情况下,这将是这样的:

byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );