与Ushort的结果混淆

时间:2012-03-05 08:55:09

标签: c#

考虑以下代码:

ushort a = 60000;
a = (ushort)(a * a / a);
Console.WriteLine("A = " + a);  

//打印53954.为什么??

ushort a = 40000;
a = (ushort)(a * a / a);
Console.WriteLine("a = " + a.ToString());

//这打印40000.怎么??

任何有用的帮助......

3 个答案:

答案 0 :(得分:7)

因为60000 ^ 2是3600000000,但是int可以容纳的最大数字是2,147,483,647,所以它从-2,147,483,648开始。

一个ushort可以保持65,535,然后从0开始:

例如,这会打印0:

ushort myShort = 65535;
myShort++;
Console.WriteLine(myShort); //0

如果将其分解为步骤,则更容易看到这一点:

var B = A * A;

实际上超过了int32的容量,因此它从-2,147,483,648开始,因此b等于-694967296 然后,当你分割B / A时,你会得到:-11582,当被投入到一个ushort中时变为53954。

ushort A = 60000;
var B = A * A; //-694967296
var C = B / A; //-11582
ushort D = (ushort)(C); //53954

40000工作的原因是它不超过int32的容量。

ushort A = 40000;
var B = A * A; //1600000000
var C = B / A; //40000
ushort D = (ushort)(C); //40000

uint可以容纳60000 ^ 2,所以这可行:

ushort A = 60000;
var B = (uint)A * A; //3600000000
var C = B / A; //60000
ushort D = (ushort)(C); //60000

将C转换为ushort yeilds 53954的原因是因为C的字节是:

96
234
0
0

D的字节是:

96
234

所以他们持有相同的后备字节,这就是你获得53954和-11582

的原因

答案 1 :(得分:3)

因为它相当于

A * A = -694967296因为结果以int结尾,而short上的溢出给出了一个产生负结果的位模式。最终60000 * 60000无法存储在ushort中。在调试模式下添加一个手表,你会看到这个。

然后你有

-694967296 / 60000 - 产生-11582作为int,但当转换为ushort时产生53954 - 再次因为基础位模式。

实际上,此代码需要位于checked块中,因为溢出错误会导致大量问题。

答案 2 :(得分:1)

第一个好问题!现在让我告诉你一件事如果你尝试40000它会工作正常。

原因是(40000 ^ 2)这是ushort的最高限制所以它会转换成整数所以它不会被截断!

如果您使用 60000 ,它会!由于限制限制!

尝试 40000

希望你能得到答案