完美解决VB中int to short溢出问题

 

工作笔记,英文烂没办法,如果不幸被你看到,请勿喷。。。

Summary:

  1. To unsigned type: just do And operator, or 2st method.

Eg. Dim a As Byte = CByte(300 And &HFF)

 

  1. To signed type: left shift n bits, then right shift n bits, which is to expand the signed bit. n = (sizeof(type1) - sizeof(type2)) * 8   or VB:use Len(New type) instead of sizeof(type)

 

Eg. Dim a As Short = CShort(34042 << 16 >> 16)

 

You can ignore the following information in case you don't want to know the detail.

 

int a = 34042;

short a1 = a;

 

You would got an error as follow:  

 

Language compilers do not perform this conversion automatically because it can involve data loss. Instead, they perform the conversion only if a casting operator (in C#) or a conversion function (such as CType or CShort in Visual Basic) is used. Otherwise, they display a compiler error.

 

In C#, we can use a casting operator:

int a = 34042;

short a1 = (short)a;

 

 

In VB, we should use a conversion function:

Dim a As Integer = 100

Dim a1 As Short = CShort(a)

  

 

But issues occurred when the value is beyond the rang of short type in VB.

' Short: -32768 ~ 32767( 0FFFF8000H ~ 7FFFH)       

Dim a As Integer = 34042

Dim a1 As Short = CShort(a)

 

 

In the 1st C# code, it works fine. But according to the value, how can we get -31494 from 34042? And why the VB code would catch an overflow exception(although it actually does)?

 

In fact, (short)a would generate IL:conv.i2  in C#. But CShort(a) would generate IL:conv.ovf.i2 in VB, and which might throw an overflow exception.

 

So, what we want to do is just to find out the rules of conversion.

 

conv.i2=Converts the value on top of the evaluation stack to int16, then extends (pads) it to int32.

 

Ok, let's follow it.

 

' Short: -32768 ~ 32767( FFFF8000H ~ 7FFFH)       

Dim a As Integer = 34042

'Dim a1 As Short = CShort(a)

Dim a2 As Short = CShort(a And &HFFFF)

 

But unfortunately failed again, and got the same exception.

 

Actually, a And &HFFFF is still an integer but grater than Short.MaxValue, so it failed again.

 

Short is a 16-bit signed integer type so that it only contains 15 data-bit and 1 signed-bit.

 

Short.MaxValue and Short.MinValue:

00000000 00000000 01111111 11111111

11111111 11111111 10000000 00000000

 

So, after you do the "And" operator, you must expand another 16 bits according to the signed bit.

 

My solution is that: Left shift 16 bits, and then right shift 16 bits.

' Short: -32768 ~ 32767( FFFF8000H ~ 7FFFH)       

Dim a As Integer = 34042

'Dim a1 As Short = CShort(a)

'Dim a2 As Short = CShort(a And &HFFFF)

Dim a3 As Short = CShort((a And &HFFFF) << 16 >> 16)

 

 

Let's see what happened.

a

84FAH

a And &HFFFF

84FAH

(a And &HFFFF) << 16

84FA 0000H

(a And &HFFFF) << 16 >> 16

FFFF 84FAH

 

Actually you can skip the And operator step.

Dim a3 As Short = CShort(a << 16 >> 16)

 

You can get these hex value by : Console.WriteLine("{0:X}", a) ...

 

Now it's all clear!

 

You can expand this method to other similar conversion, such as long to int( can use Fix()), long to short, etc.

转载于:https://www.cnblogs.com/liujq007/archive/2010/12/04/1896059.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值