一个整数测量4个字节.在我的例子中,我的数字为1 MB.如何快速将它们转换为人类可读的十进制数?
该数字出现在包含大小项的uint []数组中.
解决方法
我不知道这是否更快,但这里是delphi中的一个例子,我很久以前曾写过将大的int作为字符串处理(非常快速和脏) – 这是128bit uint但你可以无限延长
Function HexToBinShort(hex:integer):string; begin case hex of 0: result:='0000'; //convert each hex digit to binary string 1: result:='0001'; //could do this with high-nybble and low nybble 2: result:='0010'; //of each sequential byte in the array (mask and bit shift) 3: result:='0011'; //ie: binstring:=binstring + HexToBinShort(nybble[i]) 4: result:='0100'; //but must count DOWN for i (start with MSB!) 5: result:='0101'; 6: result:='0110'; 7: result:='0111'; 8: result:='1000'; 9: result:='1001'; 10: result:='1010'; 11: result:='1011'; 12: result:='1100'; 13: result:='1101'; 14: result:='1110'; 15: result:='1111'; end; end;
然后取出连接的二进制字符串,每次看到’1’时加上2的幂
Function BinToIntString(binstring:string):string; var i,j : integer; var calcHold,calc2 :string; begin calc2:=binstring[Length(binstring)]; // first bit is easy 0 or 1 for i := (Length(binstring) - 1) downto 1 do begin if binstring[i] = '1' then begin calcHold:=generateCard(Length(binstring)-i); calc2 := AddDecimalStrings(calcHold,calc2); end; end; result:=calc2; end;
generateCard用于创建2 ^ i的十进制字符串表示(对于i> 0)
Function generateCard(i:integer):string; var j : integer; var outVal : string; begin outVal := '2'; if i > 1 then begin for j := 2 to i do begin outVal:= MulByTwo(outVal); end; end; result := outVal; end;
和MulByTwo将十进制字符串乘以2
Function MulByTwo(val:string):string; var i : integer; var carry,hold : integer; var outHold : string; var outString :string; var outString2 : string; begin outString:= StringOfChar('0',Length(val) + 1); outString2:= StringOfChar('0',Length(val)); carry :=0; for i := Length(val) downto 1 do begin hold := StrToInt(val[i]) * 2 + carry; if hold >= 10 then begin carry := 1; hold := hold - 10; end else begin carry := 0; end; outHold := IntToStr(hold); outString[i+1] := outHold[1]; end; if carry = 1 then begin outString[1] := '1'; result := outString; end else begin for i := 1 to length(outString2) do outString2[i]:=outString[i+1]; result := outString2; end; end;
最后 – AddDecimalStrings ……好吧,它添加了两个十进制字符串:
Function AddDecimalStrings(val1,val2:string):string; var i,j :integer; var carry,hold,largest: integer; var outString,outString2,bigVal,smVal,outHold:string; begin if Length(val1) > Length(val2) then begin largest:= Length(val1); bigVal := val1; smVal := StringOfChar('0',largest); j:=1; for i := (largest - length(val2) +1) to largest do begin smVal[i] := val2[j]; j:=j+1; end; end else begin if length(val2) > Length(val1) then begin largest:=Length(val2); bigVal:=val2; smVal := StringOfChar('0',largest); j:=1; for i := (largest - length(val1) +1) to largest do begin smVal[i] := val1[j]; j:=j+1; end; end else begin largest:=length(val1); bigVal:=val1; smVal:=val2; end; end; carry:=0; outString:=StringOfChar('0',largest +1); outString2:=StringOfChar('0',largest); for i := largest downto 1 do begin hold := StrToInt(bigVal[i]) + StrToInt(smVal[i]) + carry; if hold >=10 then begin carry:=1; hold := hold - 10; end else begin carry:=0; end; outHold:= IntToStr(hold); outString[i+1]:=outHold[1]; end; if carry = 1 then begin outString[1] := '1'; result := outString; end else begin for i := 1 to length(outString2) do outString2[i]:=outString[i+1]; result := outString2; end; end;
这些函数允许您对几乎任意大的整数执行基本算术作为字符串.当然,当数字位数太大而无法索引数组时,你会碰到另一面墙.
这是一个除以二,顺便说一句(对于另一种方式很有用……).我这里不处理奇数.
Function DivByTwo(val:string):string; var i : integer; var hold : integer; var outHold : string; var outString,outString2 :string; begin outString:=StringOfChar('0',Length(val)); for i := Length(val) downto 1 do begin if StrToInt(val[i]) mod 2 = 0 then begin hold:= Math.Floor(StrToInt(val[i]) / 2); outHold:= IntToStr(hold); outString[i]:=outHold[1]; end else begin hold:= Math.Floor((StrToInt(val[i]) - 1) / 2); outHold:=IntToStr(hold); outString[i]:= outHold[1]; if i <> Length(val) then begin hold:= StrToInt(outString[i+1]) + 5; outHold:= IntToStr(hold); outString[i+1] := outHold[1]; end; end; end; outString2:=StringOfChar('0',Length(val)-1); if (outString[1] = '0') and (length(outString) > 1) then begin for i := 1 to length(outString2) do outString2[i]:=outString[i+1]; result:=outString2; end else begin result:=outString; end; end;
编辑:我刚用一个900万位长的二进制字符串尝试了这个,它很慢!真的,这并不奇怪.这是完全未经优化的代码,有很多低调的果实可供选择以加快速度.尽管如此,我还是忍不住觉得这是你可能想要在完全优化的装配中编写的问题的种类(或规模).个别操作很小但是必须多次完成 – 这些咒语要求组装.多线程当然也可以在这里使用.