vba VBA中Long数据类型的误解

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/316312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 09:29:48  来源:igfitidea点击:

Misunderstanding of Long data type in VBA

vba

提问by inglesp

From the help for the Overflow Error in VBA, there's the following examples:

从 VBA 中溢出错误的帮助中,有以下示例:

Dim x As Long
x = 2000 * 365 ' gives an error

Dim x As Long
x = CLng(2000) * 365 ' fine

I would have thought that, since the Long data type is supposed to be able to hold 32-bit numbers, that the first example would work fine.

我原以为,由于 Long 数据类型应该能够保存 32 位数字,因此第一个示例可以正常工作。

I ask this because I have some code like this:

我问这个是因为我有一些这样的代码:

Dim Price as Long
Price = CLng(AnnualCost * Months / 12)

and this throws an Overflow Error when AnnualCost is 5000 and Months is 12.

当AnnualCost 为5000 且Months 为12 时,这会引发溢出错误。

What am I missing?

我错过了什么?

回答by Robert Gamble

2000 and 365 are Integer values. In VBA, Integers are 16-bit signed types, when you perform arithmetic on 2 integers the arithmetic is carried out in 16-bits. Since the result of multiplying these two numbers exceeds the value that can be represented with 16 bits you get an exception. The second example works because the first number is first converted to a 32-bit type and the arithmetic is then carried out using 32-bit numbers. In your example, the arithmetic is being performed with 16-bit integers and the result is then being converted to long but at that point it is too late, the overflow has already occurred. The solution is to convert one of the operands in the multiplication to long first:

2000 和 365 是整数值。在 VBA 中,整数是 16 位有符号类型,当您对 2 个整数执行算术时,算术以 16 位进行。由于这两个数字相乘的结果超过了可以用 16 位表示的值,因此您会得到一个例外。第二个示例有效,因为第一个数字首先转换为 32 位类型,然后使用 32 位数字执行算术。在您的示例中,正在使用 16 位整数执行算术运算,然后将结果转换为 long,但此时为时已晚,溢出已经发生。解决方案是先将乘法中的一个操作数转换为 long:

Dim Price as Long
Price = CLng(AnnualCost) * Months / 12

回答by dbb

The problem is that the multiplication is happening inside the brackets, before the type conversion. That's why you need to convert at least one of the variables to Long first, before multiplying them.

问题是乘法发生在括号内,在类型转换之前。这就是为什么您需要先将至少一个变量转换为 Long,然后再将它们相乘。

Presumably you defined the variables as Integer. You might consider using Long instead of Integer, partly because you will have fewer overflow problems, but also because Longs calculate (a little) faster than Integers on 32 bit machines. Longs do take more memory, but in most cases this is not a problem.

大概您将变量定义为整数。您可能会考虑使用 Long 而不是 Integer,部分原因是您会遇到较少的溢出问题,还因为 Longs 在 32 位机器上的计算速度(稍微)比 Integers 快。多头确实需要更多的内存,但在大多数情况下,这不是问题。

回答by dbb

In VBA, literals are integer by default (as mentioned). If you need to force a larger datatype on them you can recast them as in the example above or just append a type declaration character. (The list is here: http://support.microsoft.com/kb/191713) The type for Long is "&" so you could just do:

在 VBA 中,文字默认为整数(如前所述)。如果您需要对它们强制使用更大的数据类型,您可以像上面的示例一样重新转换它们,或者只附加一个类型声明字符。(列表在这里:http: //support.microsoft.com/kb/191713) Long 的类型是“&”,所以你可以这样做:

Price = CLng(AnnualCost * Months / 12&)

And the 12 would be recast as a long. However it is generally good practice to avoid literals and use constants. In which case you can type the constant in it's declaration.

并且 12 将被改写为 long。然而,避免文字和使用常量通常是一种很好的做法。在这种情况下,您可以在它的声明中键入常量。

Const lngMonths12_c as Long = 12
Price = CLng(AnnualCost * Months / lngMonths12_c)