[转载]VBA乘法溢出错误的解决
原⽂地址:VBA乘法溢出错误的解决作者:⼯控⼩飞侠
先介绍VB常⽤数据类型:
Byte  1字节,范围0-255,没有负数
Integer 整形,2字节,范围为 -32,768 到 32,767
Long 长整型,4字节,范围从 -2,147,483,648 到 2,147,483,647
Single 单精度浮点数,4字节,范围:负数:-3.4E38~ -1.4E-45;正数:1.4E-45~3.4E38
Double 双精度浮点数,8字节,范围:负数:-1.79E-308~-4.9E-324;正数:4.9E-324~1.79E308
Date 变量存储为 IEEE 64 位(8 个字节)
Boolean 变量存储为 16 位(2 个字节)
Variant 是⼀种特殊的数据类型,除了定长 String 数据及⽤户定义类型外,可以包含任何种类的数据。Vari
ant 也可以包含Empty、Error、Nothing 及 Null等特殊值。可以⽤ VarType 函数或 TypeName 函数来决定如何处理 Variant 中的数据。
当两个整数相乘,如果结果超过数据类型的表⽰范围,则会产⽣溢出错误。
VB⼤致是按如下⽅法进⾏乘法运算的:
从左⾄右进⾏运算,相乘的结果暂存于临时变量中,最终结果再赋值给结果。⽐如乘法X=A*B*C,运算时先进⾏T=A*B,在进⾏T*C运算。临时变量为T,临时变量的类型与A或者B中占字长最⼤的⼀致,⽐如A是Integer,B是Long,则临时变量是Long型,若A和B都是Integer,则临时变量也是Integer。若运算结果超过临时变量所能表⽰的范围则产⽣溢出错误。解决的修正的⽅法是给表达式中的左边第⼀个常数指定⼀个类型标识符,或者使⽤CInt或者CLng函数将左边第⼀个变量转换类型。⽐如常数相乘:
dim x as long
x=1000& * 1000 或者 x=CLng(1000) * 1000
再如变量相乘:
dim a as integer, b as integer, c as long
c=CLng(a) * b
字符串长度不能超过32位以下情况会出现溢出错误:
dim a as byte : print a*a
dim a as byte : a=负数
dim a as long : a=1000 * 1000
以下是VB常⽤数据类型标识符
数据类型类型标识符
Integer    %
Long        &
Single      !
Double    #
Currency  @
String      $
声明变量时可以直接⽤类型符,⽐如Dim a As Integer可以直接写成Dim a%
附:32位浮点数的⼆进制表⽰⽅法(转载):
⼀个单精度浮点数在内存中占4个字节,即32个⼆进制bit,从低位到⾼位依次叫第0位到第31位。这32位可以分为3个部分:符号位(第31位)+ 阶码(第30位到第23位共8位)+ 尾数(最低23位)。
1、符号位。最⾼位也就是第31位表⽰这个实数是正数还是负数,为0表⽰正数或0,为1表⽰负数.
2、阶码。第30位到第23位这8个⼆进制位表⽰该实数转化为规格化的⼆进制实数后的指数与127(127即所谓偏移量)之和即所谓阶码. 规格化的⼆进制实数的指数只能在-127~+127之间,所以,⼀个float型数的最⼤值在+2^127即+3.4*10^38,最⼩值在-
2^127即-3.4*10^38.
3、尾数。其他最低的23位即第22位到第0位表⽰该实数转化为规格化的⼆进制实数后⼩数点以后的其余各位即所谓尾数.(注意红字,是⼩数点以后,因为⼩数点前总是1个1,所以省略掉了)
例如,将⼗进制178.125表⽰成机器内的32个字节的⼆进制形式.
第⼀步:将128.125表⽰成⼆进制数:(178.125)(⼗进制数)=(10110010.001)(⼆进制形式);
第⼆步:将⼆进制形式的浮点实数转化为规格化的形式:(⼩数点向左移动7个⼆进制位可以得到)
10110010.001=1.0110010001*2^7 因⽽产⽣了以下三项:
符号位:该数为正数,故第31位为0,占⼀个⼆进制位.
阶码:指数为7,故其阶码为127+7=134=(10000110)(⼆进制),占从第30到第23共8个⼆进制位.
尾数为⼩数点后的部分, 即0110010001.因为尾数共23个⼆进制位,在后⾯补13个0,即01100100010000000000000
所以,178.125在内存中的实际表⽰⽅式为:
0 10000110 01100100010000000000000
再如,将-0.15625表⽰成机器内的32个字节的形式.
第⼀步:将-0.15625表⽰成⼆进制形式: (-0.15625)(⼗进制数)=(-0.00101)(⼆进制形式);
第⼆步:将⼆进制形式的浮点数转化为规格化的形式:(⼩数点向右移动3个⼆进制位可以得到)
-0.00101=-1.01*2^(-3) 同样,产⽣了三项:
符号位:该数为负数,故第31位为1,占⼀个⼆进制位;
阶码:指数为-3,故其阶码为127+(-3)=124=01111100,占从第30到第23共8个⼆进制位;
尾数为⼩数点后的01,当然后⾯要补21个0;
所以,-0.15625在内存中的实际表⽰形式为:
1 01111100 01000000000000000000000
双精度的浮点数的⼆进制格式如下
(⾼位)符号位阶码尾数(低位)
Double          1        11        52
再举个double的例⼦:
将100分别转化为single型和double型的⼆进制表达。
100=(1+1/2+1/16)*2^6  即1.1001 *2^6
转为single型为
100为正数,符号位为0,
阶码,⼀共8位,因为指数可以为负,为了便于计算,规定都先加上127,在这⾥6+127=133转为⼆进制为10000101
尾数转为1.1001,因为最⾼位的1 不写⼊内存,则尾数转为23位⼆进制为10010000000000000000000
合在⼀起就是01000010110010000000000000000000
转为double型为
100为正数,符号位为0,
阶码,⼀共11位,因为指数可以为负,为了便于计算,规定都先加上1023,在这⾥6+1023=1029转为⼆进制为10000000101尾数转为1.1001,因为最⾼位的1 不写⼊内存,则尾数转为52位⼆进制为1001000
00000000000000000 0000000000000000000000000000
合在⼀起就是0100000001011001000000000000000000000000000000000000000000000000
⽇期时间Date格式
date/time格式的数据实际上是个双精度浮点数,它的整数部分代表该⽇期距离1899年12⽉31⽇的总天数,⼩数部分则是当前时间在24⼩时中所占的百分⽐(⽐如中午12点整就是0.5),因此 1999年12⽉30⽇5时38分47秒这个时间在数据库中的实际存储数据为36524.2352662037。
字符串String
VB内部的字符串是Unicode的BSTR,可以包括字符。字符串长度是由字符数据⾸址之前4字节存储的数据值记录。。
分为定长字符串和变长字符串
1.变长字符串:
长度为字符串实际长度
例:
dim a as string
a="123"
a="456789“
2.定长字符串
长度为规定长度。对于定长字符串,当字符长度低于规定长度,即⽤空格填满,当字符长度多于规定长度,则截去多余的字符。
例:
dim a as string * 10
Boolean类型
在内存中占2个字节。
只有两个可能的值:True(真) False(假)
若将逻辑型数据转换成数值型,则:
True(真)为1
False(假)为 0
当数值型数据转换为
Boolean
型数据时:⾮0的数据转换为true,0为false

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。