2012-02-08 115 views
2

的目负我期待此行的C代码转换为C#:无符号整数

const u64 a = 1, b = -a; 

所以我的理解是,这两个常量是64位无符号整数。如果是这样,结果会是什么样子?

或者是实际提升的第二个常量,因此定义为有符号整数?

+0

你问你在C中运行的结果是什么,或者等价的C#应该是什么? – 2012-02-08 02:26:34

+0

为什么你想否定一个unsigned int?这不是破坏目的吗? – 2012-02-08 02:27:18

+0

@Chris:我在问两个。 – RoadWarrior 2012-02-08 02:28:16

回答

1

由于behaviour of negating unsigned integers-(u64)1表示是全1。于是,经过如下:

const u64 a = 1, b = -a; 

// a is now 0x0000000000000001 
// b is now 0xffffffffffffffff 

当然,0xffffffffffffffff(2^64) -1,这是18446744073709551615.

在我看来,那将是更清晰了原来的程序员,而不是写:

const u64 a = 1, b = ~(u64)0; 

我不是一个C#程序员,但我怀疑下面就为你工作:

const ulong b = ~(ulong)0; 
+0

我认为'〜0'依赖于与'-1'相同的未定义行为(将'int'强制转换为'uint64')。 '〜(u64)0'应该解决这个问题。 – 2012-02-08 02:48:51

+0

@Banthar:谢谢,更新:) – 2012-02-08 02:54:39

+0

C中不是UD。标准清楚地定义了将带符号的负整数转换为无符号整数的结果。但我们在这里甚至没有。 '1'是带符号的正数,它被转换为无符号(到'a'的类型)而没有改变。 'a'是无符号的,因为它被定义为无符号。 “-a”也是如此。请参阅[此问题和答案](http://stackoverflow.com/q/8026694/968261) – 2012-02-08 02:57:49

0

由于-1作为无符号类型是不可能的,因此您会得到模糊的调用错误(请参见下面的注释)。你将不得不使用Int64作为类型(等于long)。

当使用long作为类型时,结果将是a = 1,b = -1和两个long。

+0

如果b没有签名,b怎么能是-1?对不起,无法在家中检查,因为我只有C#版本的Visual Studio Express。 – RoadWarrior 2012-02-08 02:27:28

+0

如果这是关于C,这里没有错误,即使在数学上-1不能是非负数。唯一的错误可能是程序员不知道他在做什么。 – 2012-02-08 03:03:23

4

这将是等价的C#:

const ulong a = 1, b = unchecked((ulong)-1); 

或者更简单地说:

const ulong a = 1, b = 18446744073709551615; 
+0

啊哈 - 非常感谢!所以C代码实际上导致溢出(在C#中)UInt64.MaxValue? – RoadWarrior 2012-02-08 02:33:11

+0

如果你想要最大值'const ulong b =〜(ulong)0;'也可以工作 – PostMan 2012-02-08 02:36:19

+0

@RoadWarrior - 结果不是由于溢出,只是转换为无符号的64位int。详情请参阅我的回答。 – 2012-02-08 02:37:44

1

C#编译器会尽力保护您意外negiting一个无符号整数,但可以迫使它这样的:

ulong a = 1; 
ulong b = (ulong)-(long)a; 

结果将是完全一样的一群位的否定有符号整数时,如(即2的补码),唯一的区别是这些位是如何被解释为的

+0

谢谢,这回答了我的另一个问题。 – RoadWarrior 2012-02-08 02:53:36