与Ushort的结果混淆

本文关键字:结果 Ushort | 更新日期: 2023-09-27 18:26:46

考虑以下代码:

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张。怎样

任何明显的帮助。。。

与Ushort的结果混淆

因为60000^2是360000000,但int可以容纳的最大数字是2147483647,所以它从-2147483648开始。

ushort可以容纳65535,然后从0:开始

例如,这会打印0:

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

如果你把它分成几个步骤,就会更容易看到:

var B = A * A;

这实际上超过了int32的容量,因此它从-2147483648开始,因此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

因为它相当于

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

然后你有

-694967296 / 60000——它产生作为int的-11582,但当转换为ushort时产生53954——同样是因为底层的位模式。

实际上,这段代码需要在checked块中,因为正是因为这个原因,溢出错误才会导致大量问题。

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

原因是(40000^2)这是ushort的最高极限,因此它将转换为整数,因此不会截断!

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

试试40000

希望你能得到我的答案