2

奇怪我怎么能在 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. 穆特=穆特1;

这是翻译后的函数(有问题的行用“//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”。存在显式转换(您是否缺少演员表?)

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

提前致谢!

4

5 回答 5

11

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

byte byte1 = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));
byte byte2 = (byte)((mut1 & 0xFF) ^ (mut2 & 0xFF));
于 2009-03-26T13:19:53.110 回答
2

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

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

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

byte result = (byte)((mut & 0xFF) ^ (mut3 & 0xFF));
于 2009-03-26T13:20:36.680 回答
2

症状

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

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

解释

表达式(mut & 0xFF) ^ (mut3 & 0xFF)是 type 的ulong,不能分配给 type 的变量byte

变量mut是一个ulong。所有的重载都&要求操作数类型对称,所以在表达式(mut & 0xFF)中,值0xFF被提升为ulong,并且操作的结果具有类型ulong

虽然类似的过程也确实给第二个子表达式 type ulong,但这是偶然的,因为在更大的表达式中, expression具有 typeA ^ B的事实会导致 expression被提升。AulongB

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

解决方案

在赋值之前显式地对整个表达式进行类型转换。

评论

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

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

byte b = 0xF0 | 0x0E; //b should contain 0xFE

但这些会成功:

byte b1 = (byte)(0xF0 | 0x0E); //typecast fixes it
byte b2 = 0xF0;
b2 |= 0x0E; //reflexive operator typed by target variable
于 2009-03-26T14:04:34.250 回答
1

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

byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );
byte byte2 = (byte) ( (mut1 & 0xFF) ^ (mut2 & 0xFF) );
于 2009-03-26T13:20:48.973 回答
1

有一篇MSDN 知识库文章深入解释了显式向下转换的必要性。错误消息中的“存在显式转换”一词旨在提示您必须使用强制转换显式转换数据类型。在您的具体情况下,它看起来像这样:

byte byte1 = (byte) ( (mut & 0xFF) ^ (mut3 & 0xFF) );
于 2009-03-26T13:35:06.660 回答