C#:无法从 ulong 转换为 byte
奇怪的是我可以在 C++ 中做到这一点,但在 C# 中却不行。
为了清楚起见,我将在 C++ 中粘贴这两个函数,然后在 C# 中粘贴,并用注释“//error”标记 C# 代码中有问题的行。 这两个函数的作用是对参数进行编码,然后将其添加到名为 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 参数。
要调用它并更改我使用的两个值:
- ulong mut1 =GenerateValue(mut);
- mut = mut1;
以下是翻译后的函数(有问题的行标有“//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”。 存在显式转换(您是否缺少强制转换?)
问题来了:如何解决这些错误?
提前致谢!
Strange how I can do it in C++,but not in C#.
To make it clear,i'll paste the two functions in C++ and then in C# and mark the problematic lines in the C# code with a comment "//error".
What the two function does is encoding the parameter and then add it in to a global variable named byte1seeds.
These are the functions in 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;
}
Now the C# code:
I've changed the function GenerateValue.Instead of having a pointer as a parameter, it has a ulong parameter.
To call it and change both values i use:
- ulong mut1 = GenerateValue(mut);
- mut = mut1;
Here are the translated functions(the problematic lines are marked with "//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;
}
The error is:
Cannot implicitly convert type 'ulong' to 'byte'. An explicit conversion exists (are you missing a cast?)
edit:the error at problematic line 3 is:
Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)
Here comes the question: How to solve those errors?
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
添加一个
(byte)
来转换它。 由于您可能会失去精度,因此您必须告诉编译器该值将适合一个字节,即Add a
(byte)
to cast it. As you could lose precision, you have to tell the compiler that the value will fit into a byte, i.e.您可能会丢失信息。 编译器不允许这种操作,除非你明确告诉他这样做。 所以尝试这样的事情:
这样,所有变量都被显式转换,结果将是一个字节。 或者你可以这样做:
You could loose informations. The compiler doesn't allow this kind of operations unless you explicitly tell him to do so. So try something like this:
This way, all variables are explicitly casted and the result will be a byte. Or you can do this:
“存在显式转换”表示您需要进行显式转换。 在这种情况下,会是这样的:
"explicit conversion exists" indicates that you need to do an explicit cast. In this case that would be something like:
有一篇MSDN 知识库文章深入解释了显式向下转型的必要性。 错误消息中的“存在显式转换”一词旨在提示您必须使用强制转换显式转换数据类型。 在您的具体情况下,它看起来像这样:
There's a MSDN Knowledge Base article that explains in depth the need for the explicit downcast. The words "explicit conversion exists" in the error message are intended to be the clue that you must explicitly convert the data type by using a cast. In your specific case, that would look like this:
症状
以下代码可以在 C++ 中编译,但被 C# 编译器拒绝,并在第三行报告类型不兼容。
说明
表达式
(mut & 0xFF) ^ (mut3 & 0xFF)
的类型为ulong
,不能分配给byte
类型的变量>。变量
mut
是一个ulong
。&
的所有重载都要求操作数类型对称,因此在表达式(mut & 0xFF)
中,值0xFF
提升为ulong
,操作结果的类型为ulong
。虽然类似的过程也为第二个子表达式提供了类型
ulong
,但这是偶然的,因为在较大的表达式A ^ B
中,表达式A
code> 的类型为ulong
会导致表达式B
被提升。因此,表达式
(mut & 0xFF) ^ (mut3 & 0xFF)
的类型为ulong
,并且需要显式转换才能将其分配给类型的变量字节
。解决方案
在赋值之前显式地对整个表达式进行类型转换。
备注
人们会关闭警告而不是考虑它们,因为大多数 C+ 库都充满缺陷。 如果你重新打开警告,你会收到如此多的警告,尝试费力地浏览它们是没有用的,即使在混乱的某个地方会有一个注释,说明“需要潜在有损的隐式类型转换”。
如果您阅读 C# 语言规范,特别是运算符,您将学到很多有用的东西。 例如,此代码将失败:
但这些代码将成功:
Symptom
The following code compiles in C++ but is rejected by a C# compiler, with the third line reporting type incompatibility.
Explanation
The expression
(mut & 0xFF) ^ (mut3 & 0xFF)
is of typeulong
and cannot be assigned to a variable of typebyte
.The variable
mut
is aulong
. All overloads of&
require operand type symmetry, so in the expression(mut & 0xFF)
, the value0xFF
is promoted toulong
, and the result of the operation has the typeulong
.While a similar process does also give the second subexpression the type
ulong
, this is incidental because in the larger expressionA ^ B
, the fact that expressionA
has the typeulong
would cause expressionB
to be promoted.Thus, the expression
(mut & 0xFF) ^ (mut3 & 0xFF)
is of typeulong
and requires an explicit cast before it can be assigned to a variable of typebyte
.Solution
Explicitly typecast the entire expression prior to assignment.
Remarks
People turn off warnings instead of thinking about them because most C+ libraries are riddled with defects. If you switch warnings back on you get so many it's useless trying to wade through them, even though somewhere in the mess there'll be a note to the effect of "a potentially lossy implicit typecast was required".
If you read the C# language specification, with particular regard to operators, you will learn a great many useful things. For example, this code will fail:
but these will succeed: