Numéricos inteiros - Delphi
a) function ProcessaNumero(value: Byte): integer; overload;
b) function ProcessaNumero(value: ShortInt): integer; overload;
c) function ProcessaNumero(value: word): integer; overload;
d) function ProcessaNumero(value: Cardinal): integer; overload;
e) function ProcessaNumero(value: Double): integer; overload;
var
ZnNumber: Integer;
begin
ZnNumber := ProcessaNumero(-1);
end;
Na maioria das linguagens de programação vc vai ter tipos numéricos inteiros de 8 , 16, 32 e 64 bits, no Delphi não é diferente. O chamado grupo dos tipos “Integer types” apresentam algumas características que devem ser observadas. No que tange a sinalização, exceto o de 64 bits, esses grupos se dividem em sinalizados e não sinalizados. Ou seja, tipos numéricos cujo tamanho reservado para ele será de 8 bits, sinalizado (positivo e negativo) e não sinalizado (apenas positivos). O mesmo para os de 16, bem como para os de 32 bits. Esses tipos, que se enquadram dentro desse contexto, sinalizados e não, quem são eles?
8 bits:
Byte – Não sinalizado.
Shortint – Sinalizado.
16 bits:
Word - Não sinalizado.
Smallint – Sinalizado.
32 bits:
Longword - Não sinalizado.
Longint - Sinalizado.
Antes de responder, gostaria que vc me respondesse: Qual é o tamanho do Integer? 32 bits, seria a sua resposta? Qual o tamanho do Cardinal? 32 bits, seria a sua resposta? Pois bem amigo, o Integer, bem como o Cardinal, variam de tamanho de acordo com a versão do Delphi. Em outras palavras, se Delphi 16 bits, então Integer e Cardinal possuem tamanho de 16 bits, o mesmo vale para o Delphi 32 bits. Isso acontece para compatibilidade com arquitetura do processador e o sistema operacional. Portanto, não me surpreenderia se o Integer, a partir do Delphi 64 bits, que virá em breve, novamente tenha seu tamanho adaptado a nova arquitetura. Portanto, o Integer e o LongInt não são exatamente a mesma coisa. Do mesmo modo o Cardinal e o Longword, são a partir desse ponto de vista, são tipos distintos. Observe que o Integer e Cardinal são usados com freqüência pq eles correspondem a representação numérica nativa da CPU.
Sinalizados: Shortint, smallin, longint e Integer.
Não sinalizados: Byte, Word, Longword, Cardinal.
Generic integer types
Type | Range | Format .NET | Type Mapping |
Integer | -2147483648..2147483647 | signed 32-bit | System.Int32 |
Cardinal | 0..4294967295 | unsigned 32-bit | System.UInt32 |
Fundamental integer types include Shortint, Smallint, Longint, Int64, Byte, Word, and Longword.
Fundamental integer types
Type | Range | Format | .NET Type Mapping |
Shortint | -128..127 | signed 8-bit | System.SByte |
Smallint | -32768..32767 | signed 16-bit | System.Int16 |
Longint | -2147483648..2147483647 | signed 32-bit | System.Int32 |
Int64 | -2^63..2^63-1 | signed 64-bit | System.Int64 |
Byte | 0..255 | unsigned 8-bit | System.Byte |
Word | 0..65535 | unsigned 16-bit | System.UInt16 |
Longword | 0..4294967295 | unsigned 32-bit | System.UInt32 |
Um retorno de 64 bits apenas é possível quando um ou mais operadores sejam Int64
A seguir, um exemplo de código que produzirá um resultado incorreto.
function ResultadoIncorreto(Value: Integer): Int64;
var
Aux: Integer;
Begin
(* Atribuindo o máximo valor de um numérico sinalizado de 32 bits *)
Aux := High(Value);
(* ao somar mais um, estou ultrapassando a faixa de tamanho para esse tipo.
Ou seja, supostamente estou forçando um resultado cujo o tipo seja de
64 bits *)
result := Aux + 1; // contudo, o resultado não é o esperado ... hehhehehhe
end;
procedure TForm1.Button1Click(Sender: TObject);
const
Msg = 'Resultado %d';
begin
self.Caption := Format(Msg, [ResultadoIncorreto(200)]);
end;
A forma correta para se chegar ao resultado esperado seria utilizando um cast para 64 bits:
function ResultadoIncorreto(Value: Integer): Int64;
var
Aux: Integer;
begin
(* Atribuindo o máximo valor de um numérico sinalizado de 32 bits *)
Aux := High(Value);
(* ao somar mais um, estou ultrapassando a faixa de tamanho para esse tipo.
Contudo, para que meu resultado seja capaz de suportar este número preciso
fazer um cast para que resultado da operação seja de 64 bits *)
result := Int64(Aux) + 1; // Agora sim conseguirei o resultado esperado.
end;
Obs:
procedure TForm1.Button1Click(Sender: TObject);
var
I: Shortint;
begin
I := High(Shortint);
I := I + 1;
Self.Caption := Format('%d', [i])
end;
Ordinal Types
Um Ordinal Type, define um conjunto de valores no qual cada valor, exceto o primeiro, possui obrigatoriamente um único predecessor. Bem como, cada valor, exceto o último possui um único sucessor.
Function | Parameter | Return value | Remarks |
Ord | ordinal expression | ordinality of expression's value | Does not take Int64 arguments. |
Pred | ordinal expression | predecessor of expression's value |
|
Succ | ordinal expression | successor of expression's value |
|
High | ordinal type identifier or variable of ordinal type | highest value in type | Also operates on short-string types and arrays. |
Low | ordinal type identifier or variable of ordinal type | lowest value in type | Also operates on short-string types and arrays. |
Exemplo:
A) High(Byte) retorna 255, pq o maior valor possível num tipo byte é 255.
B) Succ(5) retorna 6. Pq 5 é um tratado pelo compilador como um tipo Integer, logo, o inteiro sucessor de 5 é o 6.
C) No caso de booleanos é correto a expressão: Succ(False) = True;
As procedures Inc() e Dec(), incrementam e decrementam valores cujo o tipo pertença ao conjunto dos Ordinal Types. Por exemplo
Inc(I);// é equivalente a Succ(i), ou I := I + 1;
Nenhum comentário:
Postar um comentário