Подтвердить что ты не робот

Integer Vs Long Confusion

Я видел, как многие верят в следующее

VBA преобразует все целочисленные значения в тип Long

Фактически даже статья

enter image description here

Как это возможно? Рассмотрим этот простой пример.

Sub Sample()
    Dim I As Integer
    I = 123456789
End Sub

Если VBA преобразует все значения Integer в тип Long , даже если они объявлены как тип Integer, то указанное выше никогда не должно давать вам ошибку Overflow!

Что мне здесь не хватает? Или я должен считать, что это утверждение неверно и серьезно обращать внимание на то, что ссылка говорит в начале

"Этот контент больше не поддерживается активно, он предоставляется как есть для тех, кто все еще может использовать эти технологии, без каких-либо гарантий или претензий относительно точности в отношении самой последней версии продукта или выпуска услуг".

ПРИМЕЧАНИЕ.. Я добавляю теги Excel-VBA/Powerpoint-VBA/Word-VBA/Access-VBA, надеясь, что эксперт VBA рассмотрит это, если эксперт не отслеживает только тег VBA. Я удалю эти ненужные теги после того, как будет найдено решение.

4b9b3361

Ответ 1

Целое число, объявленное как Integer, по-прежнему проверяется как Integer. Документация msdn ссылается на то, как переменная хранится внутри. В 32-битной системе Integer будет храниться в 32 байтах, тогда как в 16-битной системе он будет сохранен в 16. Следовательно, максимальный размер.

В VBA нет преобразования типов. Int - это int, а long - длинный, хотя теперь они занимают столько же места.

Ответ 2

Я потратил много времени на работу в среде VBA и имею все основания полагать, что претензия в этой статье, в лучшем случае, вводит в заблуждение.

Я никогда не сталкивался с ситуацией, когда сделано автоматическое неожиданное преобразование. Конечно, назначение по значению более крупному типу (например, Double или Long) будет неявным.

Одним из конкретных случаев, когда автоматическое преобразование было бы изменение смены, было бы присвоение типу Variant. Без преобразования тип VT_I2 с преобразованием VT_I4.

Передача целочисленного типа ByRef в функцию, ожидающую, что Long испускает несоответствие типа в Office 2013.

Я подозреваю, что они относятся к внутренней памяти Integer: очень вероятно, что они не выровнены по 16-битным словам в памяти (см. элемент структуры short в C/С++). Вероятно, они об этом говорят.

Ответ 3

Преобразование предназначено только для оптимизации памяти, а не для кода пользователя. Для программиста практически нет изменений, так как минимальные/максимальные пределы типов данных остаются неизменными.

Если вы возьмете этот пара в целом, вы поймете, что это утверждение относится только к производительности, а не к другому. Это связано с тем, что размер по умолчанию - Int32 или Int64 (в зависимости от того, является ли это 32-разрядной или 64-разрядной системой). Процессор может обрабатывать до этого большого количества за один раз. Если вы объявите меньшую единицу, чем это, компилятор должен уменьшить ее, и для этого требуется больше усилий, чем просто использовать тип по умолчанию. И у процессора тоже нет никакой выгоды. Поэтому, даже если вы объявляете свою переменную как Integer, компилятор выделяет ей память Long, потому что она знает, что ей нужно больше работать без какого-либо усиления.

Как программист VBA, для вас важно - Declare your variables as LONG instead of INTEGER even if you want to store small numbers in them.

Ответ 4

"Однако в последних версиях VBA преобразует все целочисленные значения в тип Long, даже если они объявлены как тип Integer."

Я не верю в документацию. Рассмотрим следующий простой пример (запустите в Excel 2010):

Sub checkIntegerVsLong()

    'Check the total memory allocation for an array
    Dim bits As Integer 'or long? :)
    Dim arrInteger() As Integer
    ReDim arrInteger(1 To 5)
    arrInteger(1) = 12
    arrInteger(2) = 456
    'get total memory allocation for integer in array
    bits = VarPtr(arrInteger(2)) - VarPtr(arrInteger(1))
    Debug.Print "For integer: " & bits & " bits and " & bits * 8 & " bytes."


    Dim arrLong() As Long
    ReDim arrLong(1 To 5)
    arrLong(1) = 12
    arrLong(2) = 456

    'get memory allocation for long
    bits = VarPtr(arrLong(2)) - VarPtr(arrLong(1))
    Debug.Print "For long: " & bits & " bits and " & bits * 8 & " bytes."

End Sub

Отпечатки:

Для целых чисел: 2 бита и 16 байтов.

Длительность: 4 бита и 32 байта.

Вы также можете проверить это на отдельных переменных, используя следующее:

Sub testIndividualValues()

    Dim j As Long
    Dim i As Integer
    Dim bits As Integer

    bits = LenB(i)
    Debug.Print "Length of integer: " & bits & " bits and " & bits * 8 & " bytes."
    bits = LenB(j)
    Debug.Print "Length of long: " & bits & " bits and " & bits * 8 & " bytes."



End Sub

который печатает

Длина целого числа: 2 бита и 16 байтов.

Длина длинной: 4 бит и 32 байта.

Наконец, вы можете использовать сравнение типов здесь:

Public Type myIntegerType
    a As Integer
    b As Integer
End Type
Public Type myLongType
    a As Long
    b As Long
End Type

Public Sub testWithTypes()
    Dim testInt As myIntegerType
    Dim testLong As myLongType
    Dim bits As Integer

    bits = VarPtr(testInt.b) - VarPtr(testInt.a)
    Debug.Print "For integer in types: " & bits & " bits and " & bits * 8 & " bytes."

    bits = VarPtr(testLong.b) - VarPtr(testLong.a)
    Debug.Print "For long in types: " & bits & " bits and " & bits * 8 & " bytes."

End Sub

который также печатает:

Для целых чисел в типах: 2 бита и 16 байтов.

Для длинных типов: 4 бита и 32 байта.

Это довольно убедительное доказательство того, что VBA действительно относится к Integer и Long по-разному.

Если VBA беззвучно преобразуется за кулисами, вы ожидаете, что те возвратят одинаковое количество бит/байтов для каждого из мест размещения указателей. Но в первом случае, с Integer, он выделяет только 16 бит, тогда как для Long-переменных он выделяет 32 бита.

Итак, что?

Итак, на ваш вопрос

Если VBA преобразует все значения Integer, чтобы ввести Long, даже если они объявлены как тип Integer, то указанное выше никогда не должно давать вам ошибку переполнения!

Совершенно очевидно, что вы получите ошибку переполнения, поскольку VBA фактически не выделил память для Long для объявления Integer.

Мне тоже было бы любопытно, если это вернет то же самое во всех версиях Office. Я могу тестировать только Office 2010 на 64-битной Windows 7.