PInt64 — Тип Delphi


Содержание

PInt64 — Тип Delphi

А если отключить оптимизацию?

Добавлено спустя 4 минуты 56 секунд:
Вообще, результат законен. При вычитании большего из меньшего и должно получиться такое громадное число, если не используется информация о переполнении регистра. Есть подозрение, что излишне ретивый оптимизатор эту проверку убирает, считая, что за этим должен следить программист.

Re: Проблемы с Uint64

Re: Проблемы с Uint64

Re: Проблемы с Uint64

Re: Проблемы с Uint64

Re: Проблемы с Uint64

CRobin , ты нет. А вот компилятор (оптимизатор) вполне.
по ссылке пример для языка С++, но, на самом деле, проблема может возникнуть для любого языка.
https://habrahabr.ru/post/307702/

Ах, да. именно во избежание подобных бяк и не люблю использовать беззнаковые типы, хотя иногда и можно было бы.

Re: Проблемы с Uint64

UInt64 расшифровывается как Unsigned (беззнаковый) Integer на 64 бита. Как и полагается беззнаковому типу, он не может хранить отрицательные числа
Код: Выделить всё begin
Writeln(‘UInt64 of -2 = ‘, UInt64(-2));
end.

Код: Выделить всё UInt64 of -2 = 18446744073709551614

Т.е. сейчас указанная вами проблема про вычитание не является ошибкой, а если ранее вы наблюдали -2 в UInt64, то это было что-то странное.

Re: Проблемы с Uint64

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

Re: Проблемы с Uint64

Re: Проблемы с Uint64

Паскаль допускает относительно свободное обращение с типами, например складывать и челочисленные и дробные типы. В моем случае операция вычитания беззнаковых типов применялась в условии
Код: Выделить всё if a — b > c then изза этого возникала ошибка самого алгоритма. Решил проблему явным указанием типа Код: Выделить всё if int64(a — b) > c then . Вообще говоря, меня пугает не то что надо приводить тип, а непредсказукемость алгоритма, поскольку ранее поведение этих проверок было другое.

Re: Проблемы с Uint64

Дож , в паскале много неявного приведения, которое в код добавляет компилятор.

CRobin , всякое бывает. Иногда и не знаешь где аукнется.

Re: Проблемы с Uint64

Вообще-то операция «if a — b > c then» с беззнаковыми типами, если «b» больше «a» является грубой логической ошибкой программиста, а не компилятора. Раньше, когда по молодости делал такие же ошибки в Borland Pascal или Delphi, то при выполнении программа вылетала с ошибкой типа, по-моему, «Run time Error 201 . «.

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

Re: Проблемы с Uint64

alexey38
Давайие сразу сажать за такое))
Обычная ошибка, не лучше не хуже других.

Мерилом в подобных случаях у разрабов является делфи. Раньше было както посвоему, теперь стало как в делфи.
Сейчас (в транке fpc) например такой код работает поразному в делфи\фпц
Код: Выделить всё program Project1;

var
a,b:longword;
begin
a:=1;b:=2;
if (a-b)>0 then
Writeln(‘Passed’);
readln;
end.
Напишет ктонить багрепорт и CRobin еще раз удивится))
>>Вообще говоря, меня пугает не то что надо приводить тип, а непредсказукемость алгоритма
Алгоритм тут совершенно непричем,

Re: Проблемы с Uint64

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

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

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

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

Reproduce UInt64 in Delphi 3

I am trying to «redefine» the UInt64 type for the Delphi 3 compiler. The reason for that is that I do not use system.pas nor sysinit.pas . So I only have native var types like Integer , Cardinal etc. How could I reproduce the UInt64 ?

2 Answers 2

Delphi 7 doesn’t have an unsigned 64-bit integer type. You can tell from its Windows.pas, where ULARGE_INTEGER is defined as a variant record holding either two unsigned 32-bit integers, or one signed 64-bit integer, which makes little sense, until you realise that that’s simply the least bad alternative if you really need something that’s binary compatible with unsigned 64-bit integer types from another system.

An unsigned 64-bit integer type requires compiler support, which your compiler lacks, so you cannot create it, sorry. Newer Delphi versions do have compiler support for it, so you might consider upgrading.

Delphi 3 is even worse, it doesn’t have any 64-bit integer type, not even a signed one. Int64 was added in Delphi 4, and that might be sufficient to avoid the need for a working 64-bit unsigned integer type, but if you’re stuck on Delphi 3, not even that will work.

As a side note, seemingly contrary to this answer, Delphi 7 does have a UInt64 type. However, this is highly misleading. It’s a signed 64-bit integer type in this version, just like Int64 .

PInt64 — Тип Delphi

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

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

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

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

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

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

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

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

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

Название

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

PInt64 — Тип 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);

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

Есть ли целочисленный тип данных, диапазон которого больше Int64

Существует ли целочисленный тип данных, диапазон которого больше диапазона Int64, и с которым можно было бы обращаться так же, как и с обычными Int и Int64 (выполнять действия (такие как +,-,*,/) без использования функций)? Знаю, что в Delphi нет, но существует ли подобный тип данных в интернете, написанный другими людьми?

P.S. «Выполнять действия (такие как +,-,*,/) без использования функций», т.е. с которыми можно обращаться так:

16.11.2007, 16:22 #1
03.07.2014, 05:38

Как сделать тип данных или уже есть такой тип данных который состоит из всех печатыемых символов?
Как сделать тип данных или уже есть такой тип данных который состоит из всех печатыемых символов.

Целочисленный тип данных для 10^50
Существует ли в C++ целочисленный тип данных, который вмещает 10^50?

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

Cуществует ли тип int64 в cmd?
дело в том что значения переменной «a» могут быть до 10^18 . и поэтому такой код не проходит. .

Использование процедур и функций в Delphi

Скобки

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

Возможность перегрузки

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

procedure Test (I: integer); overload;
procedure Test (S: string); overload;
procedure Test (D: double); overload;

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

Передача параметров

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

Передача параметров по значению

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

procedure Test(s: string);

При вызове указанной процедуры будет создана копия передаваемой ей в качестве параметра строки s, с которой и будет работать процедура Test. При этом все внесенные в строку изменения никак не отразятся на исходной переменной s.


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

Передача параметров по ссылке

Pascal позволяет также передавать параметры в функции или процедуры по ссылке — такие параметры называются параметрами-переменными. Передача параметра по ссылке означает, что функция или процедура сможет изменить полученные значения параметров. Для передачи параметров по ссылке используется ключевое слово var, помещаемое в список параметров вызываемой процедуры или функции.

procedure ChangeMe(var x: longint);
begin
x := 2; // Параметр х изменен вызванной процедурой
end;

Вместо создания копии переменной x, ключевое слово var требует передачи адреса самой переменной x, что позволяет процедуре непосредственно изменять ее значение.

Передача параметров констант

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

procedure Test(const s: string );

Передача открытых массивов

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

function AddEmUp(A: array of integer): integer;

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

Для получения информации о фактически передаваемом массиве параметров в функции или процедуре могут использоваться функции High, Low и SizeOf.

Object Pascal также поддерживает тип array of const, который позволяет передавать в одном массиве данные различных типов. Синтаксис объявления функций или процедур, использующих такой массив для получения параметров, следующий:

procedure WhatHaveIGot( A: array of const );

Вызвать объявленную выше функцию можно, например, с помощью такого оператора:

procedure WhatHaveIGot( [‘Text’, 10, 5.5, @WhatHaveIGot, 3.14, true, ‘c’] );

При передаче функции или процедуре массива констант все передаваемые параметры компилятор неявно конвертирует в тип TVarRec. Тип данных TVarRec объявлен в модуле System следующим образом:

PVarRec = ^TVarRec;
TVarRec = record
case Byte of
vtInteger: (VInteger: Integer; VType: Byte);
vtBoolean: (VBoolean: Boolean);
vtChar: (VChar: Char);
vtExtended: (VExtended: PExtended);
vtString: (VString: PShortString);
vtPointer: (VPointer: Pointer);
vtPChar: (VPChar: PChar);
vtObject: (VObject: TObject);
vtClass: (VClass: TClass);
vtWideChar: (VWideChar: WideChar);
vtPWideChar: (VPWideChar: PWideChar);
vtAnsiString: (VAnsiString: Pointer);
vtCurrency: (VCurrency: PCurrency);
vtVariant: (VVariant: PVariant);
vtInterface: (VInterface: Pointer);
vtWideString: (VWideString: Pointer);
vtInt64: (VInt64: PInt64);
end;

Поле VType определяет тип содержащихся в данном экземпляре записи TVarRec данных и может принимать одно приведенных значений.

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

procedure WhatHaveIGot( A: array of const );
var
i: integer;
TypeStr: string;
begin
for i := Low(A) to High(A) do
begin
case A[i].VType of
vtInteger : TypeStr := ‘Integer’;
vtBoolean : TypeStr := ‘Boolean’;
vtChar : TypeStr := ‘Char’;
vtExtended : TypeStr := ‘Extended’;
vtString : TypeStr := ‘String’;
vtPointer : TypeStr := ‘Pointer’;
vtPChar : TypeStr := ‘PChar’;
vtObject : TypeStr := ‘Object’;
vt ;
vtW ;
vtPW ;
vtAnsiString : TypeStr := ‘AnsiString’;
vtCurrency : TypeStr := ‘Currency’;
vtVariant : TypeStr := ‘Variant’;
vtInterface : TypeStr := ‘Interface’;
vtW ;
vtInt64 : TypeStr := ‘Int64’;
end;
ShowMessage( Format( ‘Array item %d is a %s’, [i, TypeStr] ) );
end;
end;

Значения параметров по умолчанию

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

procedure HasDefVal( s: string; i: integer = 0 );

Подобное объявление означает, что процедура HasDefVal может быть вызвана двумя путями. В первом случае — как обычно, с указанием обоих параметров:

procedure HasDefVal( ‘Hello’, 26 );

Во втором случае можно задать только значение параметра s, а для параметра i использовать значение, установленное по умолчанию:

procedure HasDefVal( ‘Hello’ );

При использовании значении параметров по умолчанию следует помнить о нескольких приведенных ниже правилах:

  • Параметры, имеющие значения по умолчанию, должны располагаться в конце списка параметров. Параметр без значения по умолчанию не должен встречаться в списке после параметра, имеющего значение по умолчанию.
  • Значения по умолчанию могут присваиваться только параметрам обычных типов, указателям или множествам.
  • Значение по умолчанию может передаваться только по значению либо с модификатором const. Оно не может быть ссылкой или нетипизированным параметром.

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

function Add( I1, I2: integer ): integer;
begin
Result := I1 + I2;
end;

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

function Add( I1, I2: integer; I3: integer = 0 ): integer;
begin
Result := I1 + I2 + I3;
end;

Директива

Директива <$X->запрещает вызов функций как процедур (с игнорированием возвращаемого результата). По умолчанию этот режим включен (<$X+>). Так вот, запомните, использование переменной Result недопустимо при сброшенном флажке опции Extended Syntax, расположенном во вкладке Compiler диалогового окна Project Options, или при указании директивы компилятора <$X->.

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

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

Воспроизводите UInt64 в Delphi 3

Я пытаюсь «переопределить» тип UInt64 для компилятора Delphi 3. Причина в том, что я не использую system.pas и sysinit.pas . Поэтому у меня есть только собственные типы var, такие как Integer , Cardinal и т.д. Как я могу воспроизвести UInt64 ?

В Delphi 7 нет неподписанного 64-битного целочисленного типа. Вы можете узнать из своего Windows.pas, где ULARGE_INTEGER определяется как вариантная запись, содержащая либо два беззнаковых 32-битных целых числа, либо одно подписанное 64-битное целое число, что мало смысла, пока вы не поймете, что это просто наименее плохая альтернатива, если вам действительно нужно что-то бинарное, совместимое с неподписанными 64-битными целыми типами из другой системы.

Для неподписанного 64-разрядного целочисленного типа требуется поддержка компилятора, которого не хватает вашему компилятору, поэтому вы не можете его создать, извините. У более новых версий Delphi есть поддержка компилятора, поэтому вы можете рассмотреть возможность обновления.

Delphi 3 еще хуже, у него нет 64-битного целочисленного типа, даже не подписанного. Int64 был добавлен в Delphi 4, и этого может быть достаточно, чтобы избежать необходимости работать с 64-битным беззнаковым целочисленным типом, но если вы застряли на Delphi 3, даже это не сработает.

Как замечание, похоже, противоречит этому ответу, Delphi 7 имеет тип UInt64 . Однако это очень вводит в заблуждение. Это подписанный 64-битный целочисленный тип в этой версии, как и Int64 .

Как я объяснил в комментариях, что действительно важно здесь, какие операции вы хотите поддержать. Тип данных достаточно прост. Вы представляете его как два смежных 32-битных целых числа. Но сложность заключается в реализации операций над этим типом данных.

На 32-битной машине вы не можете работать непосредственно с 64-битными целыми числами, поэтому вам нужно построить 64-битные операции, используя функциональность 32-битного процессора.

Ниже приведен пример того, как реализовать приращение 64-битного целого числа без знака с помощью 32-битного целого числа.

cdq частью этой функции является инструкция cdq . Этот знак расширяет подписанное двойное слово в eax до подписанного четырехзначного слова в edx:eax .

Внедрение других операций в целом аналогично. Очевидно, что добавление является самым простым. Умножение становится немного сложнее.

В комментариях вы заявляете:

Я пытаюсь загрузить последнюю версию BTMemoryModule.pas, чтобы она работала без UInt64 . Он использует UInt64 поэтому он поддерживает x64, но мне он нужен только для x86.

Поскольку вам нужна только поддержка x86, потому что ваш компилятор 32 бит, то я не думаю, что вам действительно нужны операции UInt64 . Вы заменяете эти переменные Cardinal .

PInt64 — Тип Delphi

Основы Delphi: 4. Операции над целыми числами

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

32-битный микропроцессор оптимально работает с 32-битными значениями, поэтому в языке Delphi рекомендуется использовать типы integer и cardinal для операций с целыми числами. Однако, остальные целочисленные типы также могут быть использованы, если необходимо особым образом определить некую область памяти.

Далее представлены все целочисленные типы языка Delphi. В таблице указано сколько памяти занимает значение того или иного типа:

Тип Описание Размер памяти Значения
byte Беззнаковое целое 1 байт 0..255
shortint Знаковое целое 1 байт -128..127
word Беззнаковое целое 2 байта 0..65535
smallint Знаковое целое 2 байта -32768..32767
cardinal
longword
Беззнаковое целое 4 байта 0..4294967295
или 0..2 32 -1
integer
longint
Знаковое целое 4 байта -2147483648..2147483647
или -2 31 ..2 31 -1
int64 Знаковое целое 8 байт -9223372036854775808..9223372036854775807
или -2 63 ..2 63 -1
uint64 Беззнаковое целое 8 байт 0..18446744073709551615
или 0..2 64 -1

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

begin
WriteLn( ‘byte: ‘ ,SizeOf(byte));
WriteLn( ‘word: ‘ ,SizeOf(word));
WriteLn( ‘cardinal: ‘ ,SizeOf(cardinal));
WriteLn( ‘uint64: ‘ ,SizeOf(uint64));

Структура целочисленного значения

Для типа byte со структурой все понятно: занимает один байт, от 0 до 255, т.е. от 00000000 до 11111111 в двоичном виде. В структуре числа нет информации о знаке числа, поэтому тип и называется — беззнаковый.

Для знакового типа shortint необходимо сохранять информацию о знаке — для этого достаточно одного старшего (первого слева) бита. Если он равен 0, то число — положительное (или равное нулю) и его значения варьируются от 0 до 127, т.е. от 00000000 до 01111111. Если старший бит равен 1, то число — отрицательно, и оставшиеся 7 бит являются разностью между числом 128 и модулем искомого числа (так называемый дополнительный код числа). Например:

-1 11111111
-2 11111110
-3 11111101
-128 10000000

Остальные целочисленные типы требуют больше, чем 1 байт памяти. Для удобства байты значения в памяти записывают в обратном порядке. Например число 123456 типа integer, которое в двоичном и шестнадцатиричном виде записывается как

в памяти будет представлено в виде

01000000 11100010 00000001 00000000

Чтобы убедиться в том, что байты значения в памяти записываются в обратном порядке можно провести эксперимент. Возьмем у числа 789 (или 0000001100010101) типа word только первый байт, и он должен равняться 21 (или 00010101), а не 3 (или 00000011) при прямом порядке:

begin
A := 789 ;
P := @A; // указатель на область памяти переменной A

WriteLn( A );
WriteLn( PByte(P)^ ); // выводим первый байт области памяти
// на который указывает P
ReadLn;
end .

Операции над целыми числами можно разделить на арифметические и побитовые. Арифметические операции представлены в следующей таблице:

Знак Операция Пример Результат
+ Сложение 7 + 4 11
Вычитание 7 — 4 3
* Умножение 7 * 4 28
/ Деление 7 / 4 1.75 (всегда вещественное)
div Деление без остатка 7 div 4 1 (всегда целое)
mod Остаток от деления 7 mod 4 3

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

Знак Операция Пример Результат
not Отрицание not 5 (¬ 00000101) -6 (11111010)
and Побитовое логическое «И» 5 and 7 (00000101 ^ 00000111) 5 (00000101)
or Побитовое логическое «ИЛИ» 5 or 7 (00000101 v 00000111) 7 (00000111)
xor Побитовое логическое «исключающее ИЛИ» 5 xor 7 (00000101 xor 00000111) 2 (00000010)
shl Сдвиг битов влево 22 shl 2 (00010110) 88 (01011000)
shr Сдвиг битов вправо 22 shr 2 (00010110) 5 (00000101)

Значения одного целочисленного типа приводятся к другому целочисленному типу без каких либо проблем. Следует учесть, что если новый тип занимает в памяти меньше байт, чем старый тип, то лишние байты просто отсекаются. Это также удобно, если необходимо получить первые несколько байт целочисленного значение (например, первый байт значения типа word или первые два байта значения типа cardinal). Однако, если тип значения знаковый, а само значение отрицательное, то приведение к типу, занимающему меньше памяти, может привести к положительному результату. Например, приводя значение -1000 (11111100 00011000) типа smallint к типу shortint, в результате получим 24 (00011000).

Значение результата какой-либо целочисленной операции всегда имеет тип, который занимает в памяти максимум из типов операндов. Например, integer + word = integer, int64 — byte = int64. Это может создать проблемы при операции умножения, когда результат необходимо получить с типом int64. В конструкции

выражение (a * b) имеет тип integer, а не int64, и значение может переполниться. В этом случае следует привести один из операндов к типу int64. Явное приведение к какому-либо типу описывается следующим образом:

В таком случае, текст программы выглядит так:

DelphiComponent.ru — бесплатно видеоуроки по Delphi, статьи, исходники

Вещественные типы (Действительные типы) в Delphi XE

Значение переменных вещественного типа всегда приблизительные, по­этому их нельзя проверять на равенство!

-2.9×10 -39 ..1.7×10 38

-1.5×10 -45 ..3.4×10 38

-5.0×10 -324 ..1.7×10 3U8

-3.6×10 -4951 «1.1×10 4y32

-2×10 63 +1 ..2×10 63 -1

Тип Real 48 оставлен только для совместимости с предыдущими версиями Delphi , поэтому его не следует использовать.

Типы Comp и Currency используются только в денежных операциях.


Обычно для расчётов хватает точности типа Single , но вычисления произ­водятся быстрее с типом Real (он же Double ).

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

Для очень больших и очень маленьких чисел больше подходит второй способ. Сначала записывается однозначное число с десятичной точкой, за­тем буква E (или е) и целое число, которое равно степени десятки. Напри­мер,

Объявление переменных вещественного типа:

Вещественные числа часто используются для «технических» расчётов, а при необходимости их можно округлить до целых чисел (тип результата — int 64) с помощью функций trunc и round .

Целым переменным нельзя присваивать действительные значения!

Функция trunc просто отсекает дробную часть числа:

Функция round округляет действительное число до ближайшего целого:

Чтобы было легче понять, как действует функция round , выразим её через trunc :

Взаимодействие с другими языками

Соответствие типов С++ и Delphi

C Data Type | Object Pascal | Description

LPSTR PAnsiChar; String >pointer

LPCSTR PAnsiChar; String >pointer

DWORD Integer; Whole numbers

BOOL LongBool; Boolean values

PBOOL ^BOOL; Pointer to a Boolean value

Pbyte ^Byte; Pointer to a byte value

PINT ^Integer; Pointer to an integer value

Psingle ^Single; Pointer to a single (floating point) value

PWORD ^Word; Pointer to a 16-bit value

PDWORD ^DWORD; Pointer to a 32-bit value

LPDWORD PDWORD; Pointer to a 32-bit value

UCHAR Byte; 8-bit values (can represent characters)

PUCHAR ^Byte; Pointer to 8-bit values

SHORT Smallint; 16-bit whole numbers

UINT Integer; 32-bit whole numbers. Traditionally,

this was used to represent unsigned integers,

but Object Pascal does not have a true

unsigned integer data type.

PUINT ^UINT; Pointer to 32-bit whole numbers

ULONG Longint; 32-bit whole numbers. Traditionally,

this was used to represent unsigned integers,

but Object Pascal does not have a true

unsigned integer data type.

PULONG ^ULONG; Pointer to 32-bit whole numbers

PLongint ^Longint; Pointer to 32-bit values

PInteger ^Integer; Pointer to 32-bit values

PSmallInt ^Smallint; Pointer to 16-bit values

PDouble ^Double; Pointer to double (floating point) values

LCID DWORD; A local identifier

LANGID Word; A language identifier

THandle Integer; An object handle. Many Windows API functions return a value

of type THandle, which identobject ifies that object within

Windows’internal object tracking tables.

PHandle ^THandle; A pointer to a handle

WPARAM Longint; A 32-bit message parameter. Under earlier versions of Windows,

this was a 16-bit data type.

LPARAM Longint; A 32-bit message parameter

LRESULT Longint; A 32-bit function return value

HWND Integer; A handle to a window. All windowed controls, child windows,

main windows, etc., have a corresponding window handle that

identifies them within Windows’internal tracking tables.

HHOOK Integer; A handle to an installed Windows system hook

ATOM Word; An index into the local or global atom table for a string

HGLOBAL THandle; A handle identifying a globally allocated dynamic memory object.

Under 32-bit Windows, there is no distinction between globally

and locally allocated memory.

HLOCAL THandle; A handle identifying a locally allocated dynamic memory object.

Under 32-bit Windows, there is no distinction between globally

and locally allocated memory.

FARPROC Pointer; A pointer to a procedure, usually used as a parameter type in

functions that require a callback function

HGDIOBJ Integer; A handle to a GDI object. Pens, device contexts, brushes, etc.,

all have a handle of this type that identifies them within

Windows’internal tracking tables.

HBITMAP Integer; A handle to a Windows bitmap object

HBRUSH Integer; A handle to a Windows brush object

HDC Integer; A handle to a device context

HENHMETAFILE Integer; A handle to a Windows enhanced metafile object

HFONT Integer; A handle to a Windows logical font object

HICON Integer; A handle to a Windows icon object

HMENU Integer; A handle to a Windows menu object

HMETAFILE Integer; A handle to a Windows metafile object

HINST Integer; A handle to an instance object

HMODULE HINST; A handle to a module

HPALETTE Integer; A handle to a Windows color palette

HPEN Integer; A handle to a Windows pen object

HRGN Integer; A handle to a Windows region object

HRSRC Integer; A handle to a Windows resource object

HKL Integer; A handle to a keyboard layout

HFILE Integer; A handle to an open file

HCURSOR HICON; A handle to a Windows mouse cursor object

COLORREF DWORD; A Windows color reference value, containing values

for the red, green, and of ;bsp;blue components of a color

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