进制转换

unit uBinOctDecHex;

{
    对负数以及小数的处理未做兼容,后续改进!!!!!


    2 8 10 16进制之间的转换

    要弄清楚进制转换,先需要清楚位运算符
    首先第一步一定都是将左右两边的数,先转换为二进制,然后同位比较
    and 同位都是1,则该位取1,否则取0
        举例说明
        100 -->  0110 0100
         99 -->  0110 0011
    ---------------------------------------
                 0110 0000,也就是96
    or 同位只要有1,则该位取1,都没有则取0
       举例说明
        100 -->  0110 0100
         99 -->  0110 0011
    ---------------------------------------
                 0110 0111,也就是103

    xor 同位相同取0,否则取1
      注意:从最大数的首位开始,最小的数如果缺0左边补0
      举例说明
        100 -->  0110 0100
          5 -->  0000 0101
    ---------------------------------------
                 0110 0001,也就是97

    shr 右移变小,每移动一位,除以2
      举例说明
          100 --> 01100100
    ---------------------------------------
          shr 2-> 00110010    --> 50
          shr 2-> 00011001    --> 25


    shl 左移变大 ,每移动一位,乘以2
      举例说明
            5 --> 00000101
    ---------------------------------------
          shl 1-> 00001010   --> 10
          shl 2-> 00010100   --> 20


------------------------------------------------------------------
    2-->8  三合一法,从右边开始,每三位合成一个八进制数,不够位数头部补零
      举例说明
         1011 1110   --> (010) (111) (110)  --> 2 7 6  --> 276


    2-->16 四合一法,从右边开始,每四位合成一个十六进制数,不够位数头部补零
      举例说明
         1011 1110   --> (1011) (1110)  --> b e  --> $be 或者 0xbe

    8-->2  一分三法。八进制的每一位,分成三个数,不足三位时高位补零
      举例说明
        276 -->  (010) (111) (110) --> 1011 1110
    16-->2 一份四法。每一位分成四个数,不足四位时高位补零
      举例说明
        $be --> (1011) (1110) --> 1011 1110

    10 --> 2 8 16  用小学的短除法,
      即每次除以x的倍数,商用于下一轮,余数作为权,一直除到商为0为止,
      然后反向将余数串起来,这就是最终结果

    举例说明
      10 --> 2
          100 / 2
        --> 50  ... 0
        --> 25  ... 0
        --> 12  ... 1
        -->  6  ... 0
        -->  3  ... 0
        -->  1  ... 1
        -->  0  ... 1
  -----------------------
                    1100100,也就是100


      2 8 16 --> 10 就是每一位的基数 * 指数的N此方,N是从左到右数出来的,下标从0开始
      举例说明
         2 --> 10
         0110 0100
         0 * 2^7 + 1 * 2^6 + 1 * 2^5 + 0 * 2^4 + 0 * 2^3 + 1 * 2^2 + 0 * 2^1 + 0 * 2^0

}

interface

uses
  System.Classes, Winapi.Windows, System.SysUtils, System.StrUtils, System.Math;


//10 --> 2 8 16
function IntToBinX(Value: Integer): string;

function IntToOctX(Value: Integer): Integer;

function IntToHexX(Value: Integer): string;

//2 --> 8 10 16
function BinToOctX(Value: string): Integer;

function BinToIntX(Value: string): Integer;

function BinToHexX(Value: string): string;

//8 --> 2 10 16
function OctToBinX(Value: Integer): string;

function OctToIntX(Value: Integer): Integer;

function OctToHexX(Value: Integer): string;

//16 --> 2 8 10
function HexToBinX(Value: string): string;

function HexToOctX(Value: string): Integer;

function HexToIntX(Value: string): Integer;

implementation

function IntToXX(Value: Integer; N: Integer): string;
var
  iMod: Integer;
begin
  Result := '';
  //短除法,后续再改别的方法实现
  repeat
    iMod := Value mod N;
    Value := Value div N;
    Result := IntToStr(iMod) + Result;
  until Value = 0;
end;

function IntToBinX(Value: Integer): string;
begin
  Result := IntToXX(Value, 2);
end;

function IntToOctX(Value: Integer): Integer;
var
  rlt: string;
begin
  rlt := IntToXX(Value, 8);
  Result := StrToInt(rlt);
end;

function IntToHexX(Value: Integer): string;
var
  sValue: string;
begin
  sValue := IntToHex(Value);   //调用系统函数
  if sValue = '' then
  begin
    Result := '';
    Exit;
  end;

  while Pos('0', sValue) = 1 do
    Delete(sValue, 1, 1);

  Result := '$' + LowerCase(sValue);
end;

function BinToXX(Value: string; Sets: string; GrpLen: Integer): string;
var
  pValue: PChar;
  iLen, iSetCnt, iSum, iMod: Integer;
begin
  Result := '';
  iLen := 0;
  iSum := 0;
  //首先把长度定下来
  iMod := Length(Value) mod GrpLen;
  iSetCnt := Length(Value) div GrpLen;
  if iMod > 0 then
  begin
    Value := Format('%.' + IntToStr(GrpLen - iMod) + 'd', [0]) + Value;   //先补全x的倍数,免得后面循环完了之后还要对iLen判断
    Inc(iSetCnt);
  end;
  //设置返回值长度
  SetLength(Result, iSetCnt);
  //如果pValue得不到值,那么就要检查数据类型是否匹配了。PChar-->string  PAnsiChar-->AnsiString
  pValue := PChar(Value) + Length(Value) - 1;  //获取字符串指针对象,并将指针指向字符串最后一位
  while pValue^ <> #0 do
  begin
    if pValue^ = '1' then
    begin
      case GrpLen of
        3:   //8进制
          begin
            case iLen of
              0..2:
                iSum := iSum + 1 shl iLen;
            end;
          end;
        4:   //16进制
          begin
            case iLen of
              0..3:
                iSum := iSum + 1 shl iLen;
            end;
          end;
      end;
    end;
    Dec(pValue);     //左移一位
    Inc(iLen);
    if iLen = GrpLen then  //从低到高,数到第x位开始合成一位
    begin
      Result[iSetCnt] := Sets[iSum + 1];  //求和后转换成sets对应的元素,sets有0的存在,要加1
      Dec(iSetCnt);
      iSum := 0;
      iLen := 0;
    end;
  end;
end;

function BinToOctX(Value: string): Integer;
const
  Sets = '01234567';
var
  rlt: string;
begin
  rlt := BinToXX(Value, Sets, 3);
  Result := StrToInt(rlt);
end;

function BinToIntX(Value: string): Integer;
var
  i: Integer;
  pValue: PChar;
begin
  Result := 0;
  pValue := PChar(Value) + Length(Value) - 1;
  i := 0;
  while pValue^ <> #0 do
  begin
    if pValue^ = '1' then
      Result := Result + (1 shl i);
    Inc(i);
    Dec(pValue);
  end;
end;

function BinToHexX(Value: string): string;
const
  Sets = '0123456789abcdef';
begin
  Result := BinToXX(Value, Sets, 4);

  while Pos('0', Result) = 1 do
    Delete(Result, 1, 1);

  if Result <> '' then
    Result := '$' + LowerCase(Result);
end;

function OctToBinX(Value: Integer): string;
const
  Sets: array[0..7] of string = ('000', '001', '010', '011', '100', '101', '110', '111');
var
  i, j: Integer;
  sValue: string;
begin
  Result := '';
  sValue := IntToStr(Value);
  for i := 1 to Length(sValue) do
  begin
    j := StrToInt(sValue[i]);
    Result := Result + Sets[j];
  end;
  while Pos('0', Result) = 1 do
    Delete(Result, 1, 1);
end;

function OctToIntX(Value: Integer): Integer;
var
  i, iValue: Integer;
  pValue: PChar;
  sValue: string;
begin
  Result := 0;
  sValue := IntToStr(Value);
  pValue := PChar(sValue) + Length(sValue) - 1;
  i := 0;
  while pValue^ <> #0 do
  begin
    iValue := StrToInt(pValue^);
    if iValue > 0 then
      Result := Result + (iValue shl (3 * i));      // 8 = 2^3
    Inc(i);
    Dec(pValue);
  end;
end;

function OctToHexX(Value: Integer): string;
var
  sBin: string;
begin
  //8-->2
  sBin := OctToBinX(Value);
  //2-->16
  Result := BinToHexX(sBin);
end;

function HexToBinX(Value: string): string;
const
  BIN: array[0..15] of string = ('0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111', '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111');
var
  i: integer;
begin
  if Copy(Value, 1, 1) = '$' then
    Delete(Value, 1, 1);

  for i := Length(Value) downto 1 do
    Result := BIN[StrToInt('$' + Value[i])] + Result;
end;

function HexToOctX(Value: string): Integer;
var
  sBin: string;
begin
  //16 --> 2
  sBin := HexToBinX(Value);
  //2 --> 8
  Result := BinToOctX(sBin);
end;

function HexToIntX(Value: string): Integer;
begin
  if Copy(Value, 1, 1) <> '$' then
    Value := '$' + Value;
  Result := StrToInt(Value);
end;

end.

 

posted @ 2023-02-18 11:54  王萧萧Xiao  阅读(19)  评论(0编辑  收藏  举报