与Ushort的结果混淆

Mil*_*ara 6 c#

考虑以下代码:

ushort a = 60000;
a = (ushort)(a * a / a);
Console.WriteLine("A = " + a);  
Run Code Online (Sandbox Code Playgroud)

//这打印53954.为什么?

ushort a = 40000;
a = (ushort)(a * a / a);
Console.WriteLine("a = " + a.ToString());
Run Code Online (Sandbox Code Playgroud)

//这打印40000.怎么样?

任何帮助明显......

Osk*_*lin 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
Run Code Online (Sandbox Code Playgroud)

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

var B = A * A;
Run Code Online (Sandbox Code Playgroud)

这实际上超过了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
Run Code Online (Sandbox Code Playgroud)

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

ushort A = 40000;
var B = A * A; //1600000000
var C = B / A; //40000
ushort D = (ushort)(C); //40000
Run Code Online (Sandbox Code Playgroud)

uint 虽然可以容纳60000 ^ 2,所以这样做:

ushort A = 60000;
var B = (uint)A * A; //3600000000
var C = B / A; //60000
ushort D = (ushort)(C); //60000
Run Code Online (Sandbox Code Playgroud)

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

96
234
0
0
Run Code Online (Sandbox Code Playgroud)

而D的字节是:

96
234
Run Code Online (Sandbox Code Playgroud)

所以它们保持相同的后备字节,这就是为什么你得到53954和-11582