Я использую следующую функцию для преобразования AnsiString в Uint32. AnsiString состоит из символов битового потока 0 и 1.
Я использую Делфи 12.1.
function BinaryStringToUInt32(const binaryStr: AnsiString): UInt32;
var
i: Integer;
begin
Result := 0;
// Convert the binary value to an integer
for i := 1 to Length(binaryStr) do
begin
Result := Result * 2 + Ord(binaryStr[i]) - Ord('0');
end;
end;
Однако я получаю переполнение Interger для высоких значений, близких к максимальному диапазону uint32. Как это возможно?
Если я изменю код на следующий, он будет работать нормально:
function BinaryStringToUInt32(const binaryStr: AnsiString): UInt32;
var
i: Integer;
test: UInt64;
begin
test := 0;
// Convert the binary value to an integer
for i := 1 to Length(binaryStr) do
begin
test := test * 2 + Ord(binaryStr[i]) - Ord('0');
end;
Result := UInt32(test);
end;
этот код, вероятно, более эффективен и тоже работает:
function BinaryStringToUInt32(const binaryStr: AnsiString): UInt32;
var
i: Integer;
begin
// Ensure input string length does not exceed 32 characters
if Length(binaryStr) > 32 then
raise Exception.Create('Input string exceeds 32 characters');
Result := 0;
// Convert the binary value to an integer
for i := 1 to Length(binaryStr) do
begin
Result := Result shl 1; // Shift result left by one bit
if binaryStr[i] = '1' then
Result := Result or 1; // Set the least significant bit if current bit is '1'
end;
end;
Ваш расчет
Result := Result * 2 + Ord(binaryStr[i]) - Ord('0');
оценивается слева направо. Поэтому может случиться так, что добавление Ord(binaryStr[i])
переполнится раньше, чем Ord('0')
вычитается.
Если заключить Ord(binaryStr[i]) - Ord('0')
в скобки, это сработает.
Result := Result * 2 + (Ord(binaryStr[i]) - Ord('0'));