Зачем использовать целое число вместо длинного?

47

Я часто вижу вопросы, связанные с ошибками Overflow с .

Мой вопрос, почему использовать integer переменную декларацию вместо того, чтобы просто определить все числовые переменные ( за исключением double и т.д.), как long?

Если вы не выполняете операцию, подобную циклу for, где вы можете гарантировать, что значение не превысит ограничение 32 767, это повлияет на производительность или что-то еще, что будет диктовать отсутствие использования long?

Теги:
integer
long-integer
integer-overflow

6 ответов

98
Лучший ответ

Целочисленные переменные сохраняются как 16-разрядные (2-байтовые) номера

MSDN

Длинные (длинные целочисленные) переменные сохраняются как подписанные 32-разрядные (4-байтовые) номера

MSDN

Таким образом, преимущество в сокращении объема памяти. Целое число занимает половину памяти, которая длится долго. Теперь мы говорим о 2 байтах, поэтому это не будет иметь особого значения, если вы не храните TON целых чисел.

НО в 32- битной системе 16-битное целое число беззвучно преобразуется в длинный, без использования большего диапазона чисел для работы. Переполнение все еще происходит, и требуется столько же памяти. Производительность может даже пострадать, потому что тип данных должен быть преобразован (на очень низком уровне).

Не ссылка, которую я искал, но....

Я понимаю, что базовый движок VB преобразует целые числа в длинные, даже если он объявлен как целое. Поэтому можно отметить небольшое снижение скорости. Я верил в это какое-то время и, возможно, это также объясняется тем, что было сделано выше, я не просил рассуждать.

Форумы

Это ссылка, которую я искал.

Короткий ответ, в 32-битных системах 2 байтовых целых числа преобразуются в 4 байта Longs. Нет другого способа, чтобы соответствующие биты правильно выстраивались в линию для любой формы обработки. Рассмотрим следующее

MsgBox Hex(-1) = Hex(65535) ' = True

Очевидно, что -1 не равен 65535, но компьютер возвращает правильный ответ, а именно "FFFF" = "FFFF",

Однако если бы мы принудили -1 к первому долгу, мы бы получили правильный ответ (65535, превышающий 32k, автоматически длинный)

MsgBox Hex(-1&) = Hex(65535) ' = False

"FFFFFFFF" = "FFFF"

Как правило, в VBA нет смысла объявлять "как целое" в современных системах, за исключением, возможно, для некоторых устаревших API, которые ожидают получить Integer.

Форум по pcreview

И наконец я нашел документацию msdn, которую я действительно искал.

Традиционно программисты VBA использовали целые числа для хранения небольших чисел, потому что им требовалось меньше памяти. Однако в последних версиях VBA преобразует все целочисленные значения в тип Long, даже если они объявлены как тип Integer. Таким образом, больше нет преимущества производительности для использования переменных Integer; Фактически, длинные переменные могут быть немного быстрее, потому что VBA не нужно их преобразовывать.

Итак, в итоге, в наши дни почти нет оснований использовать тип Integer. Если вам не нужно взаимодействовать со старым вызовом API, который ожидает 16-битный int.

Следует отметить, что некоторые старые функции API могут ожидать параметры, которые представляют собой 16-битные (2-байтовые) целые числа, и если вы находитесь на 32-битном и пытаетесь передать Integer (это уже 4-байтовый) по ссылке он не будет работать из-за разницы в длине байтов.

Благодаря Vba4All для указания этого.

  • 4
    Стоит отметить, что некоторые старые функции API могут ожидать параметры, которые являются 16-разрядными (2-байтовыми) целыми числами, и если вы используете 32-разрядный код и пытаетесь передать целое число (это уже 4-байтовый код) по ссылке он не будет работать из-за разницы в длине байтов.
  • 2
    @ Я бы не поняла, что это так. Если вы передадите Long по ref в функцию, которая ожидает Integer по ref, он будет использовать первые два байта, а поскольку числа хранятся в порядке с прямым порядком байтов, он будет работать (при условии, что значимы только два младших байта, но вполне вероятно, что этот Long является просто целым числом, хранящимся в 32 битах).
Показать ещё 5 комментариев
11

Как отмечено в других ответах, реальная разница между int и long - это размер его пространства памяти и, следовательно, размер числа, которое он может удерживать.

вот полная документация по этим типам данных http://msdn.microsoft.com/en-us/library/office/ms474284(v=office.14).aspx

a Integer - 16 бит и может представлять значение от -32,768 до 32,768

a Длинный - 32 бита и может представлять -2,147,483,648 до 2,147,483,648

и есть LongLong, который имеет 64 бита и может обрабатывать как 9 pentilion

Одна из самых важных вещей, которые следует помнить об этом, - это то, что типы данных различаются как языком, так и операционной системой/платформой. В вашем мире VBA длинное 32 бита, но в С# на 64-битном процессоре длинное 64 бит. Это может привести к значительной путанице.

Хотя VBA не поддерживает его, когда вы переходите на любой другой язык в .net или java или другом, я предпочитаю использовать системные типы данных int16, int32 и int64, что позволяет мне намного более прозрачно относиться к значениям, которые могут храниться в этих типах данных.

7

У VBA много исторического багажа.

An Integer имеет ширину 16 бит и является хорошим цифровым типом по умолчанию, когда были распространены 16-битные архитектуры/размеры слов.

A Long имеет ширину 32 бита и (IMO) следует использовать там, где это возможно.

4

Несмотря на то, что этому сообщению четыре года, мне было интересно об этом и провела несколько тестов. Самое главное отметить, что кодер должен ВСЕГДА объявить переменную как ЧТО-ТО. Необъявленные переменные явно выполняли худшие (необъявленные технически Variant)

Long работал быстрее, поэтому я должен думать, что рекомендация Microsoft всегда использовать Long вместо Integer имеет смысл. Я предполагаю то же самое, что и у Byte, но большинство кодеров не используют это.

РЕЗУЛЬТАТЫ НА ОКОНЧАТЕЛЬСТВЕ 64 БИТ WINDOWS 10

Изображение 3760

Используемый код:

Sub VariableOlymics()
'Run this macro as many times as you'd like, with an activesheet ready for data
'in cells B2 to D6
Dim beginTIME As Double, trials As Long, i As Long, p As Long

    trials = 1000000000
    p = 0

    beginTIME = Now
    For i = 1 To trials
        Call boomBYTE
    Next i
    Call Finished(p, Now - beginTIME, CDbl(trials))
    p = p + 1

    beginTIME = Now
    For i = 1 To trials
        Call boomINTEGER
    Next i
    Call Finished(p, Now - beginTIME, CDbl(trials))
    p = p + 1


    beginTIME = Now
    For i = 1 To trials
        Call boomLONG
    Next i
    Call Finished(p, Now - beginTIME, CDbl(trials))
    p = p + 1


    beginTIME = Now
    For i = 1 To trials
        Call boomDOUBLE
    Next i
    Call Finished(p, Now - beginTIME, CDbl(trials))
    p = p + 1


    beginTIME = Now
    For i = 1 To trials
        Call boomUNDECLARED
    Next i
    Call Finished(p, Now - beginTIME, CDbl(trials))
    p = p + 1

End Sub


Private Sub boomBYTE()
Dim a As Byte, b As Byte, c As Byte

    a = 1
    b = 1 + a
    c = 1 + b
    c = c + 1

End Sub


Private Sub boomINTEGER()
Dim a As Integer, b As Integer, c As Integer

    a = 1
    b = 1 + a
    c = 1 + b
    c = c + 1

End Sub


Private Sub boomLONG()
Dim a As Long, b As Long, c As Long

    a = 1
    b = 1 + a
    c = 1 + b
    c = c + 1

End Sub


Private Sub boomDOUBLE()
Dim a As Double, b As Double, c As Double

    a = 1
    b = 1 + a
    c = 1 + b
    c = c + 1

End Sub


Private Sub boomUNDECLARED()

    a = 1
    b = 1 + a
    c = 1 + b
    c = c + 1

End Sub

Private Sub Finished(i As Long, timeUSED As Double, trials As Double)

    With Range("B2").Offset(i, 0)
            .Value = .Value + trials
            .Offset(0, 1).Value = .Offset(0, 1).Value + timeUSED
            .Offset(0, 2).FormulaR1C1 = "=ROUND(RC[-1]*3600*24,0)"
    End With

End Sub
  • 1
    Необъявленная переменная является вариантом. Dim a as Variant, b as Variant, c As Variant должен дать тот же результат, что и вовсе не "затемнение".
  • 3
    Ухоженная! Рад видеть, что кто-то сделал некоторые тесты!
Показать ещё 2 комментария
3

Это проблема space vs необходимость.

В некоторых ситуациях требуется необходимость использовать длинный. Если вы перебираете строки в большом файле excel, переменная, содержащая номер строки, должна быть длинной.

Однако иногда вы узнаете, что целое число может справиться с вашей проблемой, и использование длинной будет пустой тратой пространства (память). Отдельные переменные действительно не имеют большого значения, но когда вы начинаете разбираться с массивами, это может иметь большое значение.

  • В VBA7 целые числа составляют 2 байта, а longs - 4 байта.

  • Если у вас есть массив из 1 миллиона номеров между 1 и 10, использование массива Integer займет около 2 МБ ОЗУ, по сравнению с примерно 4 МБ ОЗУ для длинного массива.

  • 1
    Для массива чисел от 1 до 10 вы могли бы вместо этого использовать массив BYTE, но я понимаю, что вы делаете.
  • 0
    Вероятно, это было правдой около 15 лет назад, но теперь ответ действительно устарел.
Показать ещё 3 комментария
-7

Возможно, CS grad может объяснить это лучше, но да целому числу требуется меньше памяти для хранения (может быть, не очень важно в очень простом VBA script).

Он также гарантирует/подтверждает, что переменная всегда будет целочисленной (не десятичной). Я уверен, что если вы сохраните 6.7 как целое число, оно будет преобразовано в число 7 в VBA.

Возможно, это не лучшая практика, но могут быть случаи, когда это необходимо. Я считаю, что главная цель - проверка достоверности данных. В частности, да, для циклов, где что-то должно произойти Х количество раз - десятичное значение не имеет смысла.

Первичное различие - память, хотя - если я помню длинный бит 64 бит, а целое - 32 бит.

  • 3
    Это место для хранения .Net, а не VBA.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню