我正在编写基本转换器,因为我很快就会进行测试,我需要转换3个不同基数的二进制数:八进制,十进制和十六进制。我已经编写了将二进制字符串转换为十进制和十六进制的代码。
function bintodec(Value:string;dec:TEdit;hexadec:TEdit): Integer;
var //dec and hexadec are the TEdits where I will put the result
i, iValueSize: Integer;
Edit2,f:TEdit;
begin
Result := 0;
iValueSize := Length(Value);
for i := iValueSize downto 1 do
begin
if Value[i] = '1' then Result := Result + (1 shl (iValueSize - i));
end;
dec.Text:=(IntToStr(Result)); //dec. number
hexadec.Text:=(IntToHex(Result,8)); //hexadec. number
end;
正如你在这里看到的那样,函数接受一个字符串(例如10101001)并输入2个不同的编辑结果。
我已经创建了一个将十进制数转换为八进制数的函数,但是当我按下SpeedButton Calc.
时出现错误。它说project1引发了一个类异常'External:SIGSEGV'然后接近Unit1我看到了页面control.inc。我在谷歌上搜索了一个解决方案,但我找不到有用的答案。
function dec2oct(mystring:Integer): String;
var
a: String;
getal_met_rest : Double;
Edit2:TEdit;
begin
while mystring> 0 do
begin
getal_met_rest := getal / 8;
a:= a + IntToStr(mystring - (trunc(getal_met_rest)*8));
getal := trunc(getal_met_rest);
end;
dec2oct:=ReverseString(a);
Edit2.text:=dec2oct
end;
我没有找到二进制八进制转换的方法,所以一旦我从二进制转换为十进制,我就调用函数dec2oct
。我用这种方式调用函数:
var a:smallint;
begin
bintodec(Edit1.Text,Edit3,Edit4);
dec2oct(Edit3.Text); //Edit3 contains the number on base 10
end;
你可以帮帮我吗?
答案 0 :(得分:3)
我通常会使用字符串或字符数组和位算术进行此类转换。例如:
function Int2Oct(invalue: integer): ShortString;
const
tt: array[0..7] of char = ('0', '1', '2', '3', '4', '5', '6', '7');
var
tempval: integer;
begin
Result := '';
tempval := invalue;
if tempval = 0 then
Result := '0'
else
while (tempval <> 0) do
begin
Result := tt[(tempval and $7)] + Result;
tempval := (tempval shr 3);
end;
end;
只要您不希望它处理负数,似乎只在我测试它的短时间内工作。编辑:它现在处理零。
答案 1 :(得分:3)
这里的函数有点像C运行时库的itoa
函数,将正整数值(Delphi中的Cardinal
)转换为2到36之间的指定基数。它已在Delphi 2007下测试过和XE4。
type
TRadixRange = 2..36;
function ConvertIntToBase(value : Cardinal; Radix : TRadixRange) : string;
const
Digits: array[0..35] of Char = ('0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'A', 'B',
'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z');
var
nIndex : Integer;
begin
Result := '';
repeat
nIndex := value mod radix;
Result := Digits[nIndex] + Result;
Value := Value div radix;
until Value = 0;
end;
为了好玩,我决定写一个函数来“撤销”转换(从另一个基数转换回十进制(基数为10))。它也在C RTL函数atoi
之后(非常宽松地)建模,除了它要求你传入传递的数字的基数。
function ConvertBaseToInt(const Value: string; const Radix: TRadixRange): Cardinal;
var
i: Integer;
Increment: Byte;
begin
Result := 0;
for i := 1 to Length(Value) do
begin
case Value[i] of
'0'..'9': Increment := Ord(Value[i]) - Ord('0');
'A'..'Z',
'a'..'z': Increment := Ord(Value[i]) - Ord('A') + 10;
else
Increment := 0;
end;
end;
Result := Result * Radix + Increment;
end;
请注意ConvertIntToBase
已使用许多数字输入进行了测试,但我只能在程序员模式下验证Windows Calculator支持的那些基数(二进制(基数2),八进制(基数8),十进制(基数10,其中)我没有测试)和hex(base 16)),因为我没有一个支持其他基数值的计算器,并且不想手工完成这项工作。 ; - )
ConvertBaseToInt
通过传递ConvertIntToBase
的测试值进行测试,并确认进入其中的内容是从另一个中回来的内容; IOW,ConvertIntToBase
转换为二进制的数字在通过ConvertBaseToInt
运行时会产生相同的数字。
您可以在控制台应用程序中使用类似的内容对其进行测试:
var
TempStr: string;
Reversed: Integer;
i: Integer;
Base: Byte;
const
FmtStr = 'Value (base %d): %d %s and back %d';
begin
for i := 0 to 16 do
begin
for Base in [2, 8, 16] do
begin
// Test bin, oct, and hex for a range of values from 0..65536
TempStr := ConvertIntToBase(1 shl i, Base);
Reversed := ConvertBaseToInt(TempStr, Base);
Writeln(Format(FmtStr, [Base, 1 shl i, TempStr, Reversed]));
end;
end;
Readln;
end.
答案 2 :(得分:2)
program project1;
uses
SysUtils, StrUtils;
begin
// StrToInt function supports constants syntax:
// & - octal notation
// $ - hexadecimal notation
// % - binary notation
Writeln(StrToInt('123'));
Writeln(StrToInt('&173'))
Writeln(StrToInt('$7B'));
Writeln(StrToInt('%01111011'));
// There are three functions for converting integer value to decimal, hexadecimal and binary notation
Writeln(IntToStr(123));
Writeln(IntToHex(123, 2));
Writeln(intToBin(123, 8));
Readln;
end.
对于其他基础,Ken White的回答非常有用。
但是在单元StrUtils中已经存在这样的函数:
Dec2Numb
Synopsis: Convert a decimal number to a string representation, using given a base.
Declaration: function Dec2Numb(N: LongInt;Len: Byte;Base: Byte) : string
Visibility: default
Description: Dec2Numb converts N to its representation using base Base. The resulting string is left-padded
with zeroes till it has length Len. Base must be in the range 2-36 to be meaningful, but no checking
on this is performed.
Errors: If Base is out of range, the resulting string will contain unreadable (non-alphanumeric) characters.
Numb2Dec
Synopsis: Converts a string representation of a number to its numerical value, given a certain base.
Declaration: function Numb2Dec(S: string;Base: Byte) : LongInt
Visibility: default
Description: Numb2Dec converts the number in string S to a decimal value. It assumes the number is represented
using Base as the base. No checking is performed to see whether S contains a valid number using
base Base.
Errors: None.