Int64 — Тип Delphi


Содержание

Delphi 7: ошибка размера int64?

Я написал небольшую функцию для преобразования MB в байты, но, похоже, ошибка в int64. Согласно документации, int64 варьируется от -9223372036854775808 до 9223372036854775807, но мои результаты отличаются. много:

Использование значения 67100 для FreeSpace приводит к значению 1639972864 вместо 70359449600. Очевидно, что конверсия закончилась и обернулась. Фактический размер int64 составляет 70359449600 — 1639972864 = 68719476736 = 2 ^ 36, тогда как он должен быть 2 ^ 63-1. Показатель 36 выглядит довольно странно. Может ли это быть крутым в компиляторе?

Кроме того, использование следующей альтернативы дает ошибку «Переполнение в преобразовании или арифметическую операцию», хотя это не должно:

С другой стороны, работает следующая альтернатива:

Это нормальное поведение, и если да, то в чем причина всего этого?

Весь код, который вы включаете в вопрос, отлично работает в Delphi 7.

Вывод

Ваш фактический код отличается от того, что вы заявили в вопросе. Фактически, FreeSpace объявляется как 32-битный тип в вашем коде, возможно, Integer . Например, и мне нужно угадать немного здесь:

Вывод

Если мы включим проверку переполнения, тогда код умножения приведет к исключению переполнения, как вы сообщаете.

Теперь рассмотрим FreeSpace shl 20 когда FreeSpace является целым числом. Компилятор интерпретирует это как 32-битное целочисленное действие и сдвигает более значимые биты с конца 32-битного регистра. Тот факт, что вы назначаете целое число из 64 бит, не имеет отношения к делу. Важны типы данных в выражении. Вы можете заставить код вести себя так, как хотите, включив при этом в Int64 с правой стороны.

Вывод

Для более полного обсуждения я отсылаю вас к Барри Келли на другой вопрос.

У меня нет D7 в этой системе, но у меня есть Delphi 2007 и в этом, этот код:

Я использую Delphi XE7. Я думаю, проблема заключается в смещении 32-разрядного целого числа в 64-битное целое число. Если я использую ваш код, я получаю то же самое, что и вы. Но если я сначала придумаю FreeSpace для int64, т.е.

Const FreeSpace: int64 = 67100;

Я получаю правильный результат.

Хорошо, так что эта строка не работает → FreeSpaceConverted: = FreeSpace shl 20;

Возможно, вам стоит посмотреть эту часть → FreeSpace shl 20;

Да, FreeSpace shl 20, и вы можете посмотреть это → const → FreeSpace = 67100;

Возможно, D7 считает FreeSpace постоянной Integer 32? Если это так, вы можете изменить свой код на что-то вроде этого → const → FreeSpace: Int64 = 67100;

Здесь вам не нужна нетипированная константа, если вы не хотите делать что-то вроде этого массива: A: array [0..FreeSpace] Integer, кроме того, что вам не нужна нетипизированная константа.

Дополнительная информация В Pascal нетипизированная константа похожа на замену текстового редактора. Вы можете использовать нетипизированную константу, где вы используете номер. Он не требует ссылки на память, это просто ЗАМЕНА ТЕКСТОВОГО РЕДАКТОРА. Вы не можете выполнить какую-либо операцию в этом примере: const A: Integer = 10; B = 20;

begin Inc (A); //работает Inc (B); // не только это не сработает, но и создает ошибку компиляции;

Сравнение Untyped Constant Типовая константа С#define A 20 long a = 20;
Pascal const A = 20; const A: Integer = 20;
Сборка A equ 20 A dd 20; двойное слово, целое число 32; эквивалент в сборке

Программирование на языке паскаль

Реклама на сайте

Опрос

Рубрики

Подписка

Тип – конструкция языка, используемая как образец для создания других элементов программы. Тип определяет для элемента программы:

  • Объем памяти для размещения. По типу компилятор определяет размер памяти для размещения значений элемента.
  • Допустимое множество операций над ними.

Типы могут быть:

  • Стандартные, не требуют объявления.
  • Пользователя. Тип пользователя должен быть объявлен в разделе типов type.

Все переменные имеют тип. FPC поддерживает такой же набор типов, как и Turbo Pascal, и еще некоторые типы из Delphi. Программист может объявлять свои собственные типы, что в основном определяет идентификатор, который можно использовать, чтобы обозначить этот пользовательский тип при объявлении переменных далее в исходном тексте.

Вот главные классы типов:

  • Простой.
  • Строковый.
  • Структурированный.
  • Указатель.
  • Процедурный.
  • Шаблон (или Дженерик).
  • Специализированный.
  • Идентификатор типа.

Последний класс – идентификатор типа – просто означает присвоение другого имени типу. Это способ сделать типы независимыми от платформы: использовать только эти типы, а потом объявить эти типы индивидуально для каждой платформы. Программист, использующий эти модули, не должен волноваться о размерах типа и т.п.

Базовые (простые) типы

Простые типы во FPC такие же, как типы из Delphi. Различают простые типы:

Порядковые типы

За исключением типов int64, QWord и типов Real, все базовые типы являются порядковыми. Порядковые типы имеют следующие характеристики:

  • Они счётные и упорядоченные. Это свойство делает возможным операции Inc (от англ. increment – увеличение), Ord (от англ. order – порядок), Dec (от англ. decrement – уменьшение) над ними.
  • Они имеют минимальный и минимальный диапазон/значение.

Для выражений порядкового типа определены следующие функции:

Функция Значение
Ord (x) Порядковый номер для x.
Pred (x) Предшествующее значение для x.
Succ (x) Cледующее значение для x.
High(x) Максимально возможное значение для x.
Low(x) Минимально возможное значение для x..

Следует отметить, что функции Pred и Succ не определены для самого меньшего и самого большего значения.

Целочисленные типы

Применяются для работы с целыми числами. Отличаются друг от друга диапазоном и размером памяти. Имеются две подгруппы таких типов: для чисел без знака, для чисел со знаком.

Тип Диапазон значений Байт в памяти Примечание
Без знака
Byte 0..255 1 Байт, 8 бит
Word 0..65535 2 Слово, 16 бит
LongWord 0..4294967295 4 Двойное слово, 32 бита
QWord 0..18446744073709551615 8 Квадро слово, 64 бита
Со знаком
Shortint -128…127 1 Короткое целое, 8 бит
Smallint -32768..32767 2 Малое целое, 16 бит
Longint -2147483648..

2147483647

4 Длинное целое, 32 бита
Int64 -9223372036854775808..

9223372036854775807

8 Целое, 64 бита
Указываемые
Cardinal Word, LongWord, QWord 2, 4 или 8 Целое без знака
Integer Smallint, Longint, Int64 2, 4 или 8 Целое со знаком

Нужно отметить, что типы qword и int64 не являются истинно порядковыми, поэтому некоторые языковые конструкции не будут работать с этими целыми типами.

Тип integer указывает на тип smallint по умолчанию во FPC. Он указывает на longint или int64 in режиме Delphi или Objfpc. Тип cardinal используется на данный момент как тип longword. Определения типов cardinal и integer могут изменяться от одной архитектуры к другой и от одного компилятора к другому. Они обычно имеют тот же размер, что и целевая архитектура.

FPC поддерживает автоматическую конвертацию типов, если используются разные целочисленные типы.

В памяти целочисленные типы занимают 1..8 байт (1..64 бита) и имеют структуру:

Значащая часть Числа без знака
Знак Значащая часть Числа со знаком. Признак отрицательного числа ( 1 ) в бите знака, размещенном в старшем (левом) разряде.

Для 32-разрядного процессора скорость работы максмальная с типами integer (для чисел со знаком) и cardinal (для чисел без знака), имеющие размер в 4 байта (32=8*4).

Логические (Булевые) типы

Имеют два значения: true (истина) и false (ложь).

Тип Перевод Байт Ord(true) Примечание
Boolean Булевый 1 1 Предпочтительно рекомендуется.
ByteBool Байт Буль 1 Не 0 Для совместимости с другими системами программирования.
WordBool Слово Буль 2 Не 0
LongBool Длинный Буль 4 Не 0

Вещественные (действительные) типы

Вещественные (или действительные) числа – это числа с дробной частью. В памяти вещественные типы в зависимости от точности преставления занимают 4..10 байт (32..80 бита) и имеют структуру:

Знак Порядок со знаком Мантисса

Вещественные числа по желанию программиста отображаются двумя способами:

  • С фиксированной точкой: 3.145, – 0.25.
  • С плавающей точкой: 2.8E12, – 1.2E-8

Определены следующие вещественные типы:

Тип Диапазон Знач. цифр Байтs Перевод
Single -45..+38 7..8 4 Ординарный
Double 5.0E-324..1.7E308 15..16 8 Двойной
Real Single, Double . 4 или 8 Вещественный
Extended 1.9E-4951..1.1E4932 19..20 10 Расширенный
Currency ±(16 цифр).(4 цифры) 19..20 8 Валюта
Comp -2E64+1..2E63-1 19..20 8 Композитный

FPC использует математический сопроцессор (или эмуляцию) для всех вычислений с плавающей точкой. Размер стандартного типа Real зависит от процессора и является либо Single, либо Double. Поддерживаются только IEEE типы с плавающей точкой, и они зависят от целевого процессора и параметров эмуляции.

Comp = Int64. Это тип целых чисел, но он не является порядковым и поэтому отнесен к вещественным типам. Соседние числа этого типа имеют нули в младших разрядах. Фактически это целые числа с округлениями. К этому типу не применимы процедуры Inc, Dec. Тип Comp является 64-битным целым и недоступен на всех платформах

Функции и процедуры Delphi. Справочник.

Функция StrToInt64( const S: string ): Int64;

Описание
Функция преобразовывает строковое представление десятичного или шестнадцатеричного целого числа в значение типа Int64.
Если строка содержит запись числа в недопустимом виде, то функция вызывает исключение EConvertError.

Пример
var
X: Int64;
begin
try
X:= StrToInt64(Edit1.text);
except
MessageDlg(‘Ошибка ввода!’, mtInformation, [mbOk], 0);
end;
end;

Int64 Структура

Определение

Представляет 64-разрядное целое число со знаком. Represents a 64-bit signed integer.

Комментарии

Int64является неизменяемым типом значения, представляющим целые числа со знаком в диапазоне от отрицательных до 9223372036854775808 (которые представлены Int64.MinValue константой) до положительного 9 223 372 036 854 775 807 (что представлено Int64.MaxValue константа. Int64 is an immutable value type that represents signed integers with values that range from negative 9,223,372,036,854,775,808 (which is represented by the Int64.MinValue constant) through positive 9,223,372,036,854,775,807 (which is represented by the Int64.MaxValue constant. .NET Framework также содержит неподписанный 64-разрядный целочисленный тип UInt64значения, который представляет значения в диапазоне от 0 до 18446744073709551615. The .NET Framework also includes an unsigned 64-bit integer value type, UInt64, which represents values that range from 0 to 18,446,744,073,709,551,615.

Создание экземпляра значения Int64 Instantiating an Int64 Value

Создать экземпляр значения Int64 можно несколькими способами: You can instantiate an Int64 value in several ways:

Можно объявить переменную типа Int64 и присвоить ей значение целочисленного литерала, находящееся в диапазоне типа данных Int64. You can declare an Int64 variable and assign it a literal integer value that is within the range of the Int64 data type. В следующем примере объявляются две переменные Int64 и им присваиваются значения описанным способом. The following example declares two Int64 variables and assigns them values in this way.

Можно присвоить значение целочисленного типа, диапазон которого является подмножеством Int64 типа. You can assign the value of an integral type whose range is a subset of the Int64 type. Такое присвоение является расширяющим преобразованием, для которого не требуется оператор приведения в C# или метод преобразования в Visual Basic. This is a widening conversion that does not require a cast operator in C# or a conversion method in Visual Basic.

Можно присвоить значение числового типа с более широким диапазоном, чем у типа Int64. You can assign the value of a numeric type whose range exceeds that of the Int64 type. Такое преобразование является сужающим, поэтому для него требуется оператор приведения в C# и метод преобразования в Visual Basic, если оператор Option Strict включен. This is a narrowing conversion, so it requires a cast operator in C# and a conversion method in Visual Basic if Option Strict is on. Если числовое значение имеет тип Single, Double или Decimal, содержащий дробную часть, обработка его дробной части зависит от компилятора, выполняющего преобразование. If the numeric value is a Single, Double, or Decimal value that includes a fractional component, the handling of its fractional part depends on the compiler performing the conversion. В следующем примере при присвоении нескольким переменным типа Int64 числовых значений выполняются сужающие преобразования. The following example performs narrowing conversions to assign several numeric values to Int64 variables.

Можно вызвать метод класса Convert для преобразования любого поддерживаемого типа в значение Int64. You can call a method of the Convert class to convert any supported type to an Int64 value. Это возможно, так как Int64 реализует интерфейс IConvertible. This is possible because Int64 supports the IConvertible interface. В следующем примере показано преобразование массива значений Decimal в значения типа Int64. The following example illustrates the conversion of an array of Decimal values to Int64 values.

Можно вызвать метод Parse или TryParse для преобразования строкового представления значения Int64 в тип Int64. You can call the Parse or TryParse method to convert the string representation of an Int64 value to an Int64. Строка может содержать либо десятичные, либо шестнадцатеричные цифры. The string can contain either decimal or hexadecimal digits. В следующем примере показан вызов метода Parse с использованием десятичной и шестнадцатеричной строк. The following example illustrates the parse operation by using both a decimal and a hexadecimal string.

Выполнение операций с значениями Int64 Performing Operations on Int64 Values

Тип Int64 поддерживает стандартные операции, такие как сложение, вычитание, деление, умножение, отрицание и унарное отрицание. The Int64 type supports standard mathematical operations such as addition, subtraction, division, multiplication, negation, and unary negation. Как и другие целочисленные типы, тип Int64 также поддерживает битовые операторы AND , OR , XOR и операторы правого и левого сдвига. Like the other integral types, the Int64 type also supports the bitwise AND , OR , XOR , left shift, and right shift operators.

Можно использовать стандартные числовые операторы для сравнения двух значений Int64 либо вызвать метод CompareTo или Equals. You can use the standard numeric operators to compare two Int64 values, or you can call the CompareTo or Equals method.

Также можно вызывать члены Math класса для выполнения широкого спектра числовых операций, включая получение абсолютного значения числа, вычисление частного и остатка от целочисленного деления, определение максимального или минимального значения двух длинные целые числа, получение знака числа и округление числа. You can also call the members of the Math class to perform a wide range of numeric operations, including getting the absolute value of a number, calculating the quotient and remainder from integral division, determining the maximum or minimum value of two long integers, getting the sign of a number, and rounding a number.

Представление Int64 в виде строки Representing an Int64 as a String

Тип Int64 полностью поддерживает строки стандартных и настраиваемых числовых форматов (дополнительные сведения см. The Int64 type provides full support for standard and custom numeric format strings. в разделах Типы форматирования, Строки стандартных числовых форматов и Строки настраиваемых числовых форматов). (For more information, see Formatting Types, Standard Numeric Format Strings, and Custom Numeric Format Strings.)

Для форматирования значения Int64 как целочисленной строки без начальных нулей можно вызвать метод ToString() без параметров. To format an Int64 value as an integral string with no leading zeros, you can call the parameterless ToString() method. С помощью описателя формата «D» можно также включить указанное число начальных нулей в строковом представлении. By using the «D» format specifier, you can also include a specified number of leading zeros in the string representation. С помощью описателя формата «N» можно включить разделители групп и указать количество цифр дробной части для отображения в строковом представлении числа. By using the «N» format specifier, you can include group separators and specify the number of decimal digits to appear in the string representation of the number. С помощью описателя формата «X» можно представить значение Int64 в виде шестнадцатеричной строки. By using the «X» format specifier, you can represent an Int64 value as a hexadecimal string. Следующий пример форматирует элементы массива значений Int64 описанными четырьмя способами. The following example formats the elements in an array of Int64 values in these four ways.

Также можно форматировать значение Int64 в виде двоичной, восьмеричной, десятичной или шестнадцатеричной строки, вызвав метод ToString(Int64, Int32) и передав вторым параметром основание системы счисления. You can also format an Int64 value as a binary, octal, decimal, or hexadecimal string by calling the ToString(Int64, Int32) method and supplying the base as the method’s second parameter. В следующем примере этот метод используется для отображения двоичного, восьмеричного и шестнадцатеричного представлений массива целочисленных значений. The following example calls this method to display the binary, octal, and hexadecimal representations of an array of integer values.

Работа с 32-разряднымм целыми числами как с недесятичными значениями Working with Non-Decimal 32-Bit Integer Values

Помимо работы с отдельными длинными целыми числами в виде десятичных значений, может потребоваться выполнить побитовые операции с длинными целочисленными значениями или работать с двоичными или шестнадцатеричными представлениями длинных целых значений. In addition to working with individual long integers as decimal values, you may want to perform bitwise operations with long integer values, or work with the binary or hexadecimal representations of long integer values. Int64значения представлены в 63 битах, а 60-четвертый бит используется как бит знака. Int64 values are represented in 63 bits, with the sixty-fourth bit used as a sign bit. Положительные значения представлены в виде знака и абсолютной величины. Positive values are represented by using sign-and-magnitude representation. Отрицательные значения представлены в дополнительном коде. Negative values are in two’s complement representation. Это важно помнить при выполнении побитовых операции со значениями Int64 или при работе с отдельными их битами. This is important to keep in mind when you perform bitwise operations on Int64 values or when you work with individual bits. Для выполнения числовых, логических операций или операции сравнения с двумя недесятичными значениями, оба значения должны использовать одно и то же представление. In order to perform a numeric, Boolean, or comparison operation on any two non-decimal values, both values must use the same representation.

Представляет наибольшее возможное значение типа Int64 . Represents the largest possible value of an Int64 . Это поле является константой. This field is constant.

Представляет наименьшее возможное значение типа Int64 . Represents the smallest possible value of an Int64 . Это поле является константой. This field is constant.

Методы

Сравнивает данный экземпляр с заданным 64-битовым целым числом со знаком и возвращает значение, указывающее, как соотносятся их значения. Compares this instance to a specified 64-bit signed integer and returns an indication of their relative values.

Сравнивает этот экземпляр с заданным объектом и возвращает значение, указывающее, как соотносятся значения этих объектов. Compares this instance to a specified object and returns an indication of their relative values.

Возвращает значение, указывающее, равен ли этот экземпляр заданному значению типа Int64. Returns a value indicating whether this instance is equal to a specified Int64 value.

Возвращает значение, показывающее, равен ли данный экземпляр заданному объекту. Returns a value indicating whether this instance is equal to a specified object.

Возвращает хэш-код данного экземпляра. Returns the hash code for this instance.

Возвращает TypeCode для типа значения Int64. Returns the TypeCode for value type Int64.

Преобразует строковое представление числа в эквивалентное ему 64-битовое целое число со знаком. Converts the string representation of a number to its 64-bit signed integer equivalent.

Преобразует строковое представление числа в указанном формате, соответствующем языку и региональным параметрам, в эквивалентное ему 64-битовое целое число со знаком. Converts the string representation of a number in a specified culture-specific format to its 64-bit signed integer equivalent.

Преобразует строковое представление числа в указанном формате в эквивалентное ему 64-битовое целое число со знаком. Converts the string representation of a number in a specified style to its 64-bit signed integer equivalent.

Преобразует строковое представление числа в формате, соответствующем языку и региональным параметрам, в эквивалентное ему 64-битовое целое число со знаком. Converts the string representation of a number in a specified style and culture-specific format to its 64-bit signed integer equivalent.

Преобразовывает числовое значение данного экземпляра в эквивалентное ему строковое представление. Converts the numeric value of this instance to its equivalent string representation.

Преобразует числовое значение данного экземпляра в эквивалентное ему строковое представление с использованием указанных сведений об особенностях форматирования для данного языка и региональных параметров. Converts the numeric value of this instance to its equivalent string representation using the specified culture-specific format information.

Преобразует числовое значение данного экземпляра в эквивалентное строковое представление с использованием указанного формата. Converts the numeric value of this instance to its equivalent string representation, using the specified format.

Преобразует числовое значение данного экземпляра в эквивалентное ему строковое представление с использованием указанного формата и сведений об особенностях форматирования для данного языка и региональных параметров. Converts the numeric value of this instance to its equivalent string representation using the specified format and culture-specific format information.

Преобразует строковое представление числа в эквивалентное ему 64-битовое целое число со знаком. Converts the string representation of a number to its 64-bit signed integer equivalent. Возвращает значение, указывающее, успешно ли выполнено преобразование. A return value indicates whether the conversion succeeded or failed.

Преобразует строковое представление числа в формате, соответствующем языку и региональным параметрам, в эквивалентное ему 64-битовое целое число со знаком. Converts the string representation of a number in a specified style and culture-specific format to its 64-bit signed integer equivalent. Возвращает значение, указывающее, успешно ли выполнено преобразование. A return value indicates whether the conversion succeeded or failed.

Явные реализации интерфейса

Описание этого члена см. в разделе ToBoolean(IFormatProvider). For a description of this member, see ToBoolean(IFormatProvider).

Описание этого члена см. в разделе ToByte(IFormatProvider). For a description of this member, see ToByte(IFormatProvider).

Описание этого члена см. в разделе ToChar(IFormatProvider). For a description of this member, see ToChar(IFormatProvider).

Данное преобразование не поддерживается. This conversion is not supported. При попытке использовать этот метод выбрасывается исключение InvalidCastException. Attempting to use this method throws an InvalidCastException.

Описание этого члена см. в разделе ToDecimal(IFormatProvider). For a description of this member, see ToDecimal(IFormatProvider).

Описание этого члена см. в разделе ToDouble(IFormatProvider). For a description of this member, see ToDouble(IFormatProvider).

Описание этого члена см. в разделе ToInt16(IFormatProvider). For a description of this member, see ToInt16(IFormatProvider).

Описание этого члена см. в разделе ToInt32(IFormatProvider). For a description of this member, see ToInt32(IFormatProvider).

Описание этого члена см. в разделе ToInt64(IFormatProvider). For a description of this member, see ToInt64(IFormatProvider).

Описание этого члена см. в разделе ToSByte(IFormatProvider). For a description of this member, see ToSByte(IFormatProvider).

Описание этого члена см. в разделе ToSingle(IFormatProvider). For a description of this member, see ToSingle(IFormatProvider).

Описание этого члена см. в разделе ToType(Type, IFormatProvider). For a description of this member, see ToType(Type, IFormatProvider).

Описание этого члена см. в разделе ToUInt16(IFormatProvider). For a description of this member, see ToUInt16(IFormatProvider).

Описание этого члена см. в разделе ToUInt32(IFormatProvider). For a description of this member, see ToUInt32(IFormatProvider).

Описание этого члена см. в разделе ToUInt64(IFormatProvider). For a description of this member, see ToUInt64(IFormatProvider).

Применяется к

Потокобезопасность

Все члены этого типа являются потокобезопасными. All members of this type are thread safe. Члены, которые могут изменить состояние экземпляра, в действительности возвращают новый экземпляр, инициализированный новым значением. Members that appear to modify instance state actually return a new instance initialized with the new value. Как с любым другим типом, чтение и запись общей переменной, которая содержит экземпляр этого типа, должны быть защищены блокировкой для обеспечения потокобезопасности. As with any other type, reading and writing to a shared variable that contains an instance of this type must be protected by a lock to guarantee thread safety.

Int64 — Тип Delphi

Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда — alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Форум программистов > Delphi > Общие вопросы Delphi
Delphi и int64
Регистрация
Поиск по форуму
Расширенный поиск
К странице.

Здесь нужно купить рекламу за 25 тыс руб в месяц! ) пишите сюда — alarforum@yandex.ru

Подскажите пожалуйста, как в Delphi правильно работать с 64-битными int64.

Вот например мне нужно обменять местами старшие и младшие 32 бита.
Пробовал
x:=(y shl 32) or (y shr 32)
не работает

Даже не хочет выделять 32 бита из 64 (например x:=y shl 32);

Помогите пожалуйста!
Или может быть хотя бы ссылку на статью существующую подскажите.
(надеюсь, я в правильной ветке форума задал вопрос)

Delphi 7: int64 size bug?

I wrote a small function to convert MB to Bytes, however, there seems to be a bug in int64. According to the documentation, int64 ranges from -9223372036854775808 to 9223372036854775807, but my results differ. a lot:

Using a value of 67100 for FreeSpace results in a value of 1639972864 instead of 70359449600. It’s obvious that the conversion ran out of space and wrapped around. The actual size of int64 seems to be 70359449600 — 1639972864 = 68719476736 = 2^36 while it should be 2^63-1. An exponent of 36 looks rather strange. Could it be a number twist in the compiler itself??

Also, using the following alternative gives the error «Overflow in conversion or arithmetic operation» even though it shouldn’t:

On the other hand, the following alternative does work:

Is this normal behavior and if so, what’s the reason for all of this?

4 Answers 4

All the code you include in the question works fine in Delphi 7.

Output

Your actual code is different from what you have stated in the question. In fact, FreeSpace is declared as a 32 bit type in your code, probably Integer . For example, and I’m having to guess a little here:

Output

If we enable overflow checking then the multiplication code results in an overflow exception, as you report.

Now consider FreeSpace shl 20 when FreeSpace is an integer. The compiler interprets this as a 32 bit integer operation and shifts the more significant bits off the end of the 32 bit register. The fact that you are assigning to a 64 bit integer is not relevant. What matters are the data types in the expression. You can make the code behave the way you want by including a cast to Int64 on the right hand side.

Output

For a fuller discussion I refer you to Barry Kelly’s answer to another question.

I don’t happen to have D7 on this system but I do have Delphi 2007 and in that, this code:

I’m using Delphi XE7. I think the problem is with shifting a 32-bit integer into a 64-bit integer. If I use the your code, I get the same thing you do. But if I first typecast FreeSpace to int64, i.e.

Const FreeSpace : int64 = 67100;

I get the correct result.

Okay, so this line doesn’t work -> FreeSpaceConverted := FreeSpace shl 20;

Perhaps you should watch this part -> FreeSpace shl 20;

Yes, FreeSpace shl 20, and you may want to look this -> const -> FreeSpace = 67100;

Perhaps D7 considers FreeSpace as Integer 32 constant? If so, you might want to change your code into something like this -> const -> FreeSpace: Int64 = 67100;

You don’t need untyped constant here, unless you want to do something like this var A: array [0..FreeSpace] of Integer Other than that you don’t need untyped constant.

Further information In Pascal untyped constant is like a text editor replacement. You can use untyped constant where you use number. It doesn’t take any memory reference, it’s just a TEXT EDITOR REPLACEMENT. You can’t make any operation in that Example: const A: Integer = 10; B = 20;

begin Inc(A); // it works Inc(B); // not only it won’t work, it also generates compile error end;

Comparison Untyped Constant Typed constant C #define A 20 long a = 20;
Pascal const A = 20; const A: Integer = 20;
Assembly A equ 20 A dd 20 ; double word, integer 32 ; equivalent in assembly

Заметки о Pascal, Delphi и Lazarus

Следует ожидать переводов разделов справочной системы Delphi, компиляций из учебников, переводы статей, «путевые заметки» и прочие интересности. Блог прежде всего ориентирован на студентов, но опытных людей я тоже буду рад видеть;-)

среда, 27 апреля 2011 г.

Простые типы данных

Простые типы включают в себя порядковые типы данных и типы данных для хранения дробных чисел. Простые типы определяют порядковые множества значений.

Порядковые типы

Порядковые типы включают в себя целочисленные, символьные, булевские, перечисляемые и подмножественные типы данных. Порядковый тип определяет упорядоченное множество значений, в котором для каждого значения имеется уникальный предыдущий (для всех значений за исключением первого) и последующий (для всех значений за исключением последнего) элемент. Кроме того, каждое значение имеет порядковый номер, который определяет порядок следования значений в типе данных. В большинстве случаев, если значение имеет порядковый номер n, предыдущее значение будет иметь порядковый номер n-1, а последующее – n+1.

Для целочисленных типов порядковый номер равен значению эелемента.

Подмножественные типы сохраняют порядковые номера своих базовых типов.

Для всех порядковых типов по умолчанию первое значение имеет порядковый номер 0, следующее значение – 1 и так далее. Объявление перечислимого типа может перекрывать порядковые номера по умолчанию.

Несколько предопределенных функций могут работать с порядковыми значениями и идентификаторами типов. Самые важные из них приведены в таблице:

16.11.2007, 16:22 #1
Функция Параметры Возвращаемое значение Комментарий
Ord Порядковое выражение Порядковый номер значения выражения Не принимает аргументы типа Int64.
Pred Порядковое выражение Предыдущее значение в порядковом типе
Succ Порядковое выражение Последующее значение в порядковом типе
High Идентификатор или переменная порядкового типа Наибольшее значение в типе Так же работает с ShortString и массивами.
Low Идентификатор или переменная порядкового типа Наименьшее значение в типе Так же работает с ShortString и массивами.

Например:

Стандартные процедуры Inc и Dec увеличивают и уменьшают значение переменной порядкового типа. Например:

Целочисленные типы

Целочисленные типы представляют подмножество целых чисел. Обобщенные типы данных – это Integer и Cardinal; ими следует пользоваться, если это возможно, поскольку они обеспечивают лучшую производительность с базовыми ЦПУ и ОС. Далее в таблице приведены диапазоны значений и форматы хранения для компилятора Delphi.

Обобщенные целочисленные типы

Тип Диапазон Формат
Integer -2147483648..2147483647 32 бит со знаком
Cardinal 0..4294967295 32 бит без знака

Фундаментальные целочисленные типы:

Тип Диапазон Формат
Shortint -128..127 8 бит со знаком
Smallint -32768..32767 16 бит со знаком
Longint -2147483648..2147483647 32 бит со знаком
Int64 -2^63..2^63-1 64 бит со знаком
Byte 0..255 8 бит без знака
Word 0..65535 16 бит без знака
Longword 0..4294967295 32 бит без знака
UInt64 0..2^64-1 64 бит без знака

В общем случае арифметические операции над целыми числами возвращают значения типа Integer, которые эквивалентны 32 битному типу Longint. Операции возвращают тип Int64 только когда выполняются над одним или более операнде типа Int64. То есть, следующий код будет выдавать некорректный результат:

var I: Integer; J: Int64; . I := High(Integer); J := I + 1;

Чтобы в этом примере получить возвращаемое значение с типом Int64 следует преобразовать тип I в Int64:

Замечание: некоторые стандартные подпрограммы, принимающие целочисленные аргументы обрезают значения типа Int64 до 32 бит. Тем не менее, подпрограммы High, Low, Succ, Pred, Inc, Dec, IntToStr, and IntToHex полностью поддерживают аргументы типа Int64. Кроме того, функции Round, Trunc, StrToInt64 и StrToInt64Def возвращают значения типа Int64. Некоторые подпрограммы вообще не могут принимать значения типа Int64.

Когда вы увеличиваете последнее или уменьшаете первое значение в целочисленном типе, результат «оборачивается» вокруг начала или конца диапазона. Например, тип Shortint имеет диапазон -128..127, после выполнения кода:

значение I будет -128. В том случае, если опция проверки диапазонов у компилятора включена, этот код вызовет ошибку при выполнении программы.

Символьные типы

Фундаментальные символьные типы – это AnsiChar и WideChar. Значения типа AnsiChar имеют размер 1 байт (8 бит). Символы упорядочены в соответствии с локальным набором символов (который может быть мультибайтовым).

Символы WideChar используют более чем один байт для представления символов. В текущей реализации WideChar имеет размер слова (16 бит), символы упорядочены в соответствии с набором символов Unicode (следует учесть, что он может стать длиннее в последующих реализациях). Первые 256 символов 256 Unicode соответствуют символам ANSI.

Обобщенный символьный тип – это Char, который на текущий момент эквивалентен WideChar, поскольку строковым типом по умолчанию является тип UnicodeString. Поскольку реализация типа Char может измениться, при программировании приложений, обрабатывающих символы различных размеров, вместо фиксированной константы рекомендуется использовать стандартную функцию SizeOf.

Строковая константа с длиной 1, например, ‘A’ может определять символьное значение. Предопределенная функция Chr возвращает символьное значение для любого числа в диапазоне AnsiChar; например, Chr(65) возвращает букву ‘A’.

Значения AnsiChar и WideChar, как и целые числа, при уменьшении или увеличении значения в начале или конце диапазона значений (в том случае, если контроль диапазона значений включен) «оборачиваются» вокруг конца диапазона. Например:

Булевские типы

Есть четыре предопределенных булевских типа данных: Boolean, ByteBool, WordBool и LongBool. Boolean – это предпочтительный тип. Остальные существуют для обеспечения совместимости с другими языками и библиотеками операционных систем.

Переменные типов Boolean и ByteBool занимают один байт памяти, переменная типа WordBool занимает два байта (одно слово), а переменная типа LongBool – четыре байта (два слова).

Булевские значения определяются предопределнными константами True и False. Имеют место следующие взаимосвязи:

Boolean ByteBool, WordBool, LongBool
False True
Ord(False) = 0 Ord(False) = 0
Ord(True) = 1 Ord(True) <> 0
Succ(False) = True Succ(False) = True
Pred(True) = False Pred(False) = True

Значения типа ByteBool, LongBool или WordBool рассматриваются как как True, когда их порядковый номер не равен нулю. Если такое значение оказывается в контексте, где ожидается значение типа Boolean, компилятор автоматически преобразует значения с ненулевыми порядковыми номерами в True.

Это замечание относится к порядковым номерам булевских значений, но не к значениям как таковым. В Delphi, выражения типа Boolean не могут быть приравняны к целым или дробным числам. То есть, если X – это целочисленная переменная, то инструкция:

вызовет ошибку компиляции. Преобразование значения переменной к булевскому типу ненадежно, но любая из следующих альтернатив будет компилироваться:

Перечисляемые типы

Перечисляемый тип определяет упорядоченное множество значений при помощи обычного перечисления идентификаторов, по которым возможен доступ к этим значениям. Эти значения не имеют дополнительного смысла. Для объявления перечисляемого типа, следует использовать синтаксис:

где typeName и каждый эелемент val – допустимые идентификаторы. Например, объявление:

определяет перечисляемый тип с именем Suit и с возможными значениями Club, Diamond, Heart и Spade, где Ord(Club) возвращает 0, Ord(Diamond) возвращает 1 и так далее.

Когда вы объявляете перечисляемый тип, вы заявляете, что каждый элемент val является константой типа typeName. Если идентификаторы val в этой же области видимости будут использованы по другому, — возникнет конфликт имен. Например, предположим, вы объявили тип:

К сожалению, Click является методом, определенным для TControl и всех объектов VCL, которые являются его наследниками. Если вы пишете приложение и создаете обработчик события следующего вида:

вы получите ошибку компиляции, поскольку в этой области видимости компилятор интерпретирует Click как обращение к методу TForm Click. Вы можете исправить это, специфицирую идентификатор. Так, если TSound объявлен в MyUnit, вы можете написать:

Однако лучшим решением будет выбрать имена констант, которые не будут конфликтовать с остальными идентификаторами. Например:

Вы можете использовать конструкцию (val1, . valn) непосредственно при объявлении переменных так, как будто это имя типа:

Но, если вы таким способом объявите MyCard, вы не сможете объявить в этой же области видимости другую переменную, использующую эти же идентификаторы:

вызовет ошибку компиляции, но:

будет скомпилировано аналогично объявлению:

Перечисляемые типы с явно обозначенным порядком

По умолчанию порядок перечисляемых значений начинается с ноля и следует последовательности, в которой идентификаторы перечислены в объявлении типа. Вы можете переопределить это явно указав порядок некоторых или всех значений в объявлении. Для назначения порядка значению после идентификатора должно следовать = constantExpression, где constantExpression – константное выражение, возвращающее целочисленное значение. Например:

определяет тип с именем Size, чьи возможные значения включают Small, Medium и Large, для которых Ord(Small) возвращает 5, Ord(Medium) возвращает 10, а Ord(Large) возвращает 15.

Перечисляемый тип фактически является поддиапазоном, наименьшие и наибольшие значения которого соответствуют наименьшим и наибольшим порядковым номерам констант в объявлении. В предыдущем примере тип Size имеет 11 возможных значений, порядковые номера которых находятся в диапазоне от 5 до 15 (так, тип array[Size] of Char будет представлять массив из 11 символов.) Только три из этих значений имеют имена, а остальные элементы доступны через преобразование типво и такие подпрограммы как Pred, Succ, Inc и Dec. В следующем примере «анонимные» значения в диапазоне Size назначаются переменной X.

Любое значение, которое не имеет явно назначенного порядка, будет иметь порядок, на единицу превышающий порядок предыдущего значения в списке. Если первому значению не назначен порядок, то он приравнивается к нулю.

SomeEnum имеет только два возможных значения: Ord(e1) возвращает 0, Ord(e2) возвращает 1, Ord(e3) также возвращает 1. Поскольку e2 и e3 имеют одинаковый порядок они представляют одинаковое значение.

Перечисляемый тип без явно указанных значений имеет RTTI:

А перечислямые константы с определенными значениями не имеют RTTI:

Специфицируемые перечисления

Вы можете пользоваться специфицируемыми перечислениями в программном коде Delphi при включении директивы компилятора $SCOPEDENUMS.

Специфицируемые перечисления получаются путем указания имени перечисляемого типа перед ссылкой на элемент этого типа. В следующем примере модуля и программы вы можете видеть, как специфицируемое обращение к перечисляемому типу TMyEnum разрешает присваивание значения переменной Value, в то время как обращение к First без спецификатора вызовет ошибку совместимости типа.

Поддиапазонные типы

Поддиапазонные типы представляют собой подмножества значений из некоторого порядкового типа (который называется базовым). Любая конструкция вида Low..High, где Low and High – это константные выражения одного и того же порядкового типа, и Low меньше High, определяет поддиапазонный тип, который включает все значения между Low и High. Например, если вы объявляете перечисляемый тип:

Вы можете определить поддиапазонный тип:

Здесь TMyColors включает значения Green,Yellow, Orange, Purple и White.

Для определения поддиапазонных типов вы можете использовать числовые константы и символы (строковые константы с длиной 1):

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

Конструкция LowerBound..UpperBound сама по себе действует как имя типа, то есть вы можете использовать ее непосредственно при объявлении переменных. Например:

объявляет целочисленную переменную, которая может принимать значения от 1 до 500.

Порядковый номер каждого значения в поддиапазоне устанавливается в соответствии с порядком базового типа (в первом примере: если Color – это переменная, которая содержит значение Green, Ord(Color) возвращает 2 безотносительно от того, к какому типу относится Color, к TColors или TMyColors). Значения не «оборачиваются» вокруг начала или конца диапазона, даже в тех случаях, когда базовым типом является integer или символьный тип. Увеличение или уменьшение значения с переходом за границу поддиапазона просто преобразовывает значение в базовый тип. То есть:

Вызовет ошибку. Следующий код:

Присваивает I значение 100 (хотя опция контроля диапазона компилятора включена).

Использование константных выражений в объявлениях поддиапазонов представляет синтаксическую сложность. При объявлении любого типа, когда первый значащий символ после знака «=» является открывающей скобкой, компилятор предполагает, что начинается объявление перечисляемого типа. То есть, код:

вызовет ошибку. Для решения этой проблемы перепишите объявление типа таким образом, чтобы оно не начиналось с открывающей скобки:

Вещественные типы данных

Вещественный тип определяет множество чисел, которые могут быть представлены в нотации с плавающей точкой. Далее в таблице приведены диапазоны значений и форматы хранения фундаментальных вещественных типов для платформы Win32.

Тип Диапазон значений Значимые цифры Размер в байтах
Real48 2.9 x 10^-39 .. 1.7 x 10^38 11-12 6
Single 1.5 x 10^-45 .. 3.4 x 10^38 7-8 4
Double 5.0 x 10^-324 .. 1.7 x 10^308 15-16 8
Extended 3.6 x 10^-4951 .. 1.1 x 10^4932 10-20 10
Comp -2^63+1 .. 2^63-1 10-20 8
Currency -922337203685477.5808.. 922337203685477.5807 10-20 8

Обобщенный тип Real в текущей реализации эквивалентен Double.

Тип Диапазон значений Значимые цифры Размер в байтах
Real -5.0 x 10^-324 .. 1.7 x 10^308 15-16 8

Замечание: Шестибайтовый тип Real48 назывался Real в ранних версиях Object Pascal. Если вы перекомпилируете в Delphi код, который использует старый шестибайтовый тип Real, вы возможно захотите изменить его на Real48. Вы также можете воспользоваться директивой компилятора <$REALCOMPATIBILITY ON>для переключения типа Real назад, в шестибайтовый формат.

Следующие замечания относятся к фундаментальным вещественным типам:

  • Real48 поддерживается для обратной совместимости. Поскольку формат хранения этого типа данных не является естественным для архитектуры процессоров Intel, применение этого типа данных вызовет снижение производительности в сравнении с остальными вещественными типами.
  • Extended позволяет вести вычисления с высокой точностью (в сравнении с остальными вещественными типами), но он в меньшей степени переносим. Будьте внимательны при использовании типа Extended при создании файлов с данными, которые вы планируете использовать на других платформах.
  • Тип Comp (computational — вычислительный) является естественным для процессоров с архитектурой Intel и представляет 64-битное целое число. Тип классифицируется как вещественный, поскольку его поведение отличается от порядковых типов (например, вы не можете увеличить или уменьшить значение типа Comp(см. примечание)). Comp поддерживается только для обратной совместимости. Для улучшения производительности используйте тип Int64.
  • Currency — это тип данных с фиксированной точкой, который минимизирует ошибки округления при финансовых вычислениях. На платформе Win32 он хранится как масштабируемое целое число, содержащее четыре минимально значимые цифры, представляющие десятичные знаки. При смешивании с прочими вещественными типами в выражениях и при присваивании, значения типа Currency автоматически делятся и умножаются на10000.

Целые типы

Список предопределенных целочисленных типов представлен в таблице (3.1).

Таблица 3.1: Предопределенные целочисленные типы

Целочисленные типы, и их диапазоны и размеры, предопределены во Free Pascal , и перечислены в таблице (3.2). Пожалуйста, отметьте, что типы QWord и Int64 не истинно перечисляемые, таким образом, некоторые конструкции языка Pascal не будут работать с этими двумя целочисленными типами.

Таблица 3.2: Предопределенные целочисленные типы

Размер в байтах

или SmallInt или LongInt

По умолчанию во Free Pascal тип Integer соответствует типу SmallInt . И типу LongInt в любом из двух режимов Delphi или ObjFPC . Тип Cardinal сейчас всегда соответствует типу LongWord .

Все десятичные константы, которые не входят в диапазон -2147483648 .. 2147483647 начиная с версии 1.9.0 , автоматически обрабатываются как 64 -разрядные целые константы. Более ранние версии будут конвертировать их в вещественные типизированные константы.

Free Pascal делает автоматическое преобразование типов в выражениях, где используются различные виды целочисленных типов:

1. Каждая платформа имеет родной размер целого числа, в зависимости от того, платформа 8 -бит, 16 -бит, 32 -бит или 64 -бит. например, на AVR это 8 -разрядная платформа.

2. Каждое целое число меньшее, родного размера повышается до базовой версии родного размера. Целые равные родному размеру сохраняют их разрядность.

3. Результат двоичных арифметических операций (+, –, * и т.д.) , определяется следующим образом:

a. Если по крайней мере один из операндов больше, чем нативный (родной) размер целого, то результатом выбирается наименьший тип, который охватывает диапазон типов обоих операндов. Это означает, что смешивание типа без знака с меньшим или равным по размеру знакового типа, даст тип, который больше, чем оба из них.

b. Если оба операнда имеют один и тот же тип (размер), то результатом будет такой-же тип. Единственным исключением является вычитание (–) : если один из типов без знаковой, операция вычитания даёт знаковый тип FPC (как и в Delphi , но не в TP7 ) .

c. Смешивние знаковых и беззнаковых типов родного целого типа — даёт тип, больший по размеру, и со знаком. Это означает, что при смешивании типов LongInt и LongWord на 32 -разрядных платформах будет производить Int64 . Аналогично, при смешивании типа Byte и ShortInt на 8 -разрядных платформах ( AVR ) , результатом будет тип SmallInt .

Как определить 64-разрядное целое число без знака в Delphi7?

В Delphi 7 int64 подписываются, если я пытаюсь объявить шестнадцатеричную константу, превышающую 8000000000000000 (например, что на самом деле является uint64), я получаю ошибку. Можете ли вы посоветовать некоторые обходные пути, пожалуйста?

3 ответа

Вы можете сделать вариант записи так

Теперь вы можете просто использовать кардиналы, чтобы заполнить ваш uint64 неподписанными данными.

Другой вариант — использовать такой код:

Без поддержки компилятора у вас не так много вариантов.

Я предполагаю, что вы хотите передать значение функции в какой-то внешней DLL. Вы должны будете объявить параметр как 64-разрядное целое число со Int64 , Int64 . Затем все, что вы можете сделать, это передать значение со знаком, имеющее тот же битовый шаблон, что и требуемое значение без знака. Создайте небольшой инструмент для конвертации с компилятором, который поддерживает 64-разрядные целые числа без знака.

Традиционно реализации Broland сталкивались с проблемами совместимости из-за отсутствия большого числа неподписанных, поддерживаемого целевой платформой. Я помню, что использовал значения LongInt вместо DWORD и ждал неприятностей с самых ранних дней Turbo Pascal для Windows. Тогда было Cardinal счастье, но нет, D4 ввел наибольшее целое число Int64 в своей подписанной форме. Снова.

Таким образом, ваш единственный вариант — положиться на подписанный фундаментальный тип Int64 и молиться . подождите, нет, просто используйте приведение типов Int64Rec для выполнения арифметики по меньшей мере и по наиболее значимой части отдельно .

Вернуться к постоянному объявлению:

К сожалению, другой обходной путь — изменить ваш компилятор. Free Pascal всегда синхронизирует подписанные и неподписанные типы.

Этот фрагмент кода компилируется и дает правильный результат в Borland Delphi Version 15.0 (он же Delphi 7).

Int64 — Тип Delphi

Школа программирования Delphi

Портал DelphiSchool является бесплатным проектом, обеспечивающим пользователям быстрый и легкий доступ к урокам программирования на Delphi. Сайт позволяет научиться программировать на Делфи любому, кто хочеть писать свои программы, игры, Android приложения, программы для MAC OC или IOS. Кроме уроков Delphi и статей Delphi, на сайте доступны также и видеоуроки. Практически к каждому уроку, пользователю доступен исходник, изучив который, он сможет наглядно посмотреть как работает та или иная программа, написанная на Делфи. Кроме того мы постараемся прилагать к каждому материалу (статье, уроку, видеоуроку) файлы Delphi, которые будут помогать изучить предоставленный материал.

Каждый кто решил написать свою программу, создать свое приложение, научиться программировать и т.д., найдет на DelphiSchool статьи Delphi, уроки Delphi, видеоуроки Delphi, исходники Delphi, файлы Delphi, изучит компоненты Delphi, посмотрит Delphi примеры и многое другое абсолютно бесплатно. Все о Delphi программировании теперь собрано на одном сайте.
DelphiSchool

В языке программирования Delphi все должно иметь свой тип. Delphi требует явного указания всех типов. Существует четыре простых типа данных: целые числа, вещественные числа (дробные), строки и булевые значения.

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

В переменных целого типа, информация представляется в виде чисел, которые не имеют дробной части. Такие числа используются для математических вычислений и любых других операций, в которых требуется работа с числами.

Существует несколько видов целых типов данных. В основном они отличаются только размером отводимой переменным памяти для хранения данных.

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

Таблица. Типы целочисленных переменных

Название

Размер памяти для хранения данных

Илон Маск рекомендует:  Размер заголовка в em
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL