Ign*_*cia 27 .net c# vb.net math
我认为这是不可能的,因为Int32有1位符号并且有31位数字信息,Int16有1位符号和15位数字信息,这导致有2位符号和30位信息.
如果这是真的那么我就不能有一Int32到两个Int16.这是真的?
提前致谢.
附加信息:使用Vb.Net,但我认为我可以毫无问题地翻译C#答案.
我最初想要做的是将一个转换UInt32为两个,UInt16因为这是一个与基于WORD的机器交互的库.然后我意识到这Uint不符合CLS,并试图用Int32和做同样的事情Int16.
EVEN WORSE:a = CType(c And &HFFFF, Int16);投掷OverflowException.我期望该语句与a = (Int16)(c & 0xffff);(不抛出异常)相同.
Jon*_*eet 36
这当然可以在不丢失信息的情况下完成.在这两种情况下,最终都会得到32位信息.它们是否用于符号位是无关紧要的:
int original = ...;
short firstHalf = (short) (original >> 16);
short secondHalf = (short) (original & 0xffff);
int reconstituted = (firstHalf << 16) | (secondHalf & 0xffff);
Run Code Online (Sandbox Code Playgroud)
在这里,reconstituted将始终相等original,因此不会丢失任何信息.
现在两条短路符号的含义是另一回事 - firstHalfiff original为负时secondHalf将为负,但如果设置了第15位(计数0-31),original则为负,这在原始形式中不是特别有意义.
小智 13
这应该工作:
int original = ...;
byte[] bytes = BitConverter.GetBytes(original);
short firstHalf = BitConverter.ToInt16(bytes, 0);
short secondHalf = BitConverter.ToInt16(bytes, 2);
Run Code Online (Sandbox Code Playgroud)
编辑:
用0x7FFFFFFF测试,它的工作原理
byte[] recbytes = new byte[4];
recbytes[0] = BitConverter.GetBytes(firstHalf)[0];
recbytes[1] = BitConverter.GetBytes(firstHalf)[1];
recbytes[2] = BitConverter.GetBytes(secondHalf)[0];
recbytes[3] = BitConverter.GetBytes(secondHalf)[1];
int reconstituted = BitConverter.ToInt32(recbytes, 0);
Run Code Online (Sandbox Code Playgroud)
Jon的答案,翻译成Visual Basic,没有溢出:
Module Module1
Function MakeSigned(ByVal x As UInt16) As Int16
Dim juniorBits As Int16 = CType(x And &H7FFF, Int16)
If x > Int16.MaxValue Then
Return juniorBits + Int16.MinValue
End If
Return juniorBits
End Function
Sub Main()
Dim original As Int32 = &H7FFFFFFF
Dim firstHalfUnsigned As UInt16 = CType(original >> 16, UInt16)
Dim secondHalfUnsigned As UInt16 = CType(original And &HFFFF, UInt16)
Dim firstHalfSigned As Int16 = MakeSigned(firstHalfUnsigned)
Dim secondHalfSigned As Int16 = MakeSigned(secondHalfUnsigned)
Console.WriteLine(firstHalfUnsigned)
Console.WriteLine(secondHalfUnsigned)
Console.WriteLine(firstHalfSigned)
Console.WriteLine(secondHalfSigned)
End Sub
End Module
Run Code Online (Sandbox Code Playgroud)
结果:
32767
65535
32767
-1
Run Code Online (Sandbox Code Playgroud)
在.NET中CType(&Hffff, Int16)导致溢出,并(short)0xffff给出-1(没有溢出).这是因为默认情况下C#编译器使用未经检查的操作并检查VB.NET.
就个人而言,我喜欢Agg的答案,因为我的代码更复杂,并且Jon会在检查环境中导致溢出异常.
我还根据类代码创建了另一个答案,BitConverter针对此特定任务进行了优化.但是,它使用不安全的代码.