如何将一个很长的二进制数转换为十进制数?
How do I convert a very long binary number to decimal?
我有一个表示为 11.1111111 的二进制数(. 类似于小数点)。点前有2位,点后有1024位。这是一个以高精度计算 e 的练习,但现在我不知道如何将它转换为十进制。
以防万一你们想知道这个数字,这里是:
10.1011011111100001010100010110001010001010111011010010101001101010101111110111000101011000100000001001110011110100111100111100011101100010111001110001011000001111001110001011010011011010010101101010011110000100110110010000010001010001100100001100111111101111001100100100111001110111001110001001001001101100111110111110010111110100101111111000110110001101100011000011000111010111011000111101101000000110110010000000101010111011000100011000010111101011010011110111110001111011010101110101011111110101100101011000010010010000110011111101010001111101011111000001100110111011010000100001010110001101100101010101010011110111101101000110101111001110110101010101110001001101011110011111110101011111001001001101011001100001001111000011000111000011100000111001101000101101110111111000101010011010001001110110101111001111101111111010000111001000011101111100010101100010100001001101101010110111100111001101010011000010101100110010100100111101001000001110100111100101111010101111000000101010110001100000101011001100100100111110110011101011
如何将其转换为 2.718....(小数点后应有 309 位左右)
我不能简单地将每一位乘以 2^x,因为过一会儿,数字 2^x 将 = 0,即使使用双精度浮点数也是如此。我使用的是 Visual Basic,所以我不确定是否存在更大的变量。
[Spektre 编辑]
只需要 运行 你的字符串和我的代码(基于我评论中的 link),结果是:
e(bigdecimal)=2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750924476146066808226480016847741185374234544243710753907774499206955170189257927265177296267786175561825444670874889747782175809270565601486538810885558129926100522647929865142359038501319247028975364903531383896590857864585070203793060262761378008328322397393650711101939331201
e (text)=2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750924476146066808226480016847741185374234544243710753907774499206955170189
e (reference)=2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551702761838606261331384583000752044933826560297606737113200709328709127443747047230696977209310141692836819025515108657463772111252389784425056953696770785449969967946864454905987931636889230098793127736178215424999229576351482208269895193668033182528869398496465105820939239829488793320362509443117301238197068416140397019837679320683282376464804295311802328782509819455815301756717361332069811250996181881593041690351598888519345807273866738589422879228499892086805825749279610484198444363463244968487560233624827041978623209002160990235304369941849146314093431738143640546253152096183690888707016768396424378140592714563549061303107208510383750510115747704171898610687396965521267154688957035035402123407849819334321068170121005627880235193033224745015853904730419957777093503660416997329725088687696640355570716226844716256079882651787134195124665201030592123667719432527867539855894489697096409754591856956380236370162112047742722836489613422516445078182442352948636372141740238893441247963574370263755294448337998016125492278509257782562092622648326277933386566481627725164019105900491644998289315056604725802778631864155195653244258698294695930801915298721172556347546396447910145904090586298496791287406870504895858671747985466775757320568128845920541334053922000113786300945560688166740016984205580403363795376452030402432256613527836951177883863874439662532249850654995886234281899707733276171783928034946501434558897071942586398772754710962953741521115136835062752602326484728703920764310059584116612054529703023647254929666938115137322753645098889031360205724817658511806303644281231496550704751025446501172721155519486685080036853228183152196003735625279449515828418829478761085263981395599006737648292244375287184624578036192981971399147564488262603903381441823262515097482798777996437308997038886778227138360577297882412561190717663946507063304527954661855096666185664709711344474016070462621568071748187784437143698821855967095910259686200235371858874856965220005031173439207321139080329363447972735595527734907178379342163701205005451326383544000186323991490705479778056697853358048966906295119432473099587655236812859041383241160722602998330535370876138939639177957454016137223618789365260538155841587186925538606164779834025435128
首先是从文本转换为我的 arbnum
数据类型,然后再转换回文本,中间是纯文本到文本的转换(就像在 link 中转换为十六进制之前那) 最后是 reference e
这里是二进制字符串的十六进制字符串:
e (hex) =2.B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF324E7738926CFBE5F4BF8D8D8C31D763DA06C80ABB1185EB4F7C7B5757F5958490CFD47D7C19BB42158D9554F7B46BCED55C4D79FD5F24D6613C31C3839A2DDF8A9A276BCFBFA1C877C56284DAB79CD4C2B3293D20E9E5EAF02AC60ACC93ECEBh
我 t运行 降低了十进制半字节的大小,因此最后可能还有 1,2 或 3 位未处理 ...
您可以使用 System.Numerics BigInteger。它可以容纳大量的数字。
https://msdn.microsoft.com/en-us/library/system.numerics.biginteger%28v=vs.110%29.aspx
编辑:
我以为小数点后的二进制是照常计算的。因此,最后一位将是 2^1,其中 1 将一直增加到点。这会呈现一个类似于 1.2*10^308 的数字。然后将截断为 2.12 ......
但实际上是小数点后的第一个位被算作2^-1,-1减为2^-1024。因此呈现一个无法用 BigInteger 表示的 0.x 数字。
小数点后每位二进制数代表2^-n的十进制权重,从n=1开始。
这可以使用霍纳方法使用任何 bignum 库进行评估,如下所示:
(这只是伪代码)
power_of_five = 1;
digits = 0;
while digits_left
digits = digits * 10;
power_of_five = power_of_five * 5;
if (next_digit_is_set)
digits = digits + power_of_five;
end
这将产生一个 1024 位的大数字,其中只有前 309 位有效。
将二进制字符串转换为十六进制
整数部分很容易"10." -> "2."
小数部分也很容易:
10.1011011111100001010100010110 bin
10.1011 0111 1110 0001 0101 0001 0110 bin
2.B 7 E 1 5 1 6 hex
如您所见,每个 nibel 整数值也是十六进制数字 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
这里是一些 C++ 代码:
int i,j,l; char *t16="0123456789ABCDEF";
AnsiString s0="10.your binary number",s1="2.";
for (i=4,l=s0.Length();i<=l;)
{
j=0;
if ((i<=l)&&(s0[i]=='1')) j+=8; i++;
if ((i<=l)&&(s0[i]=='1')) j+=4; i++;
if ((i<=l)&&(s0[i]=='1')) j+=2; i++;
if ((i<=l)&&(s0[i]=='1')) j+=1; i++;
s1+=char(t16[j]);
} // here s1 holds the hex string
通过预分配生成的 s1 大小可以显着加快速度
运行 hex to dec
字符串转换
AnsiString str_hex2dec(const AnsiString &hex)
{
char c;
AnsiString dec="",s;
int i,j,l,ll,cy,val;
int i0,i1,i2,i3,sig;
sig=+1; l=hex.Length();
if (l) { c=hex[l]; if (c=='h') l--; if (c=='H') l--; }
i0=0; i1=l; i2=0; i3=l;
for (i=1;i<=l;i++) // scan for parts of number
{
char c=hex[i];
if (c=='-') sig=-sig;
if ((c=='.')||(c==',')) i1=i-1;
if ((c>='0')&&(c<='9')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; }
if ((c>='A')&&(c<='F')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; }
if ((c>='a')&&(c<='f')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; }
}
l=0; s=""; if (i0) for (i=i0;i<=i1;i++)
{
c=hex[i];
if ((c>='0')&&(c<='9')) c-='0';
else if ((c>='A')&&(c<='F')) c-='A'-10;
else if ((c>='a')&&(c<='f')) c-='A'-10;
for (cy=c,j=1;j<=l;j++)
{
val=(s[j]<<4)+cy;
s[j]=val%10;
cy =val/10;
}
while (cy>0)
{
l++;
s+=char(cy%10);
cy/=10;
}
}
if (s!="")
{
for (j=1;j<=l;j++) { c=s[j]; if (c<10) c+='0'; else c+='A'-10; s[j]=c; }
for (i=l,j=1;j<i;j++,i--) { c=s[i]; s[i]=s[j]; s[j]=c; }
dec+=s;
}
if (dec=="") dec="0";
if (sig<0) dec="-"+dec;
if (i2)
{
dec+='.';
s=hex.SubString(i2,i3-i2+1);
l=s.Length();
for (i=1;i<=l;i++)
{
c=s[i];
if ((c>='0')&&(c<='9')) c-='0';
else if ((c>='A')&&(c<='F')) c-='A'-10;
else if ((c>='a')&&(c<='f')) c-='A'-10;
s[i]=c;
}
ll=((l*1234)>>10); // num of decimals to compute
for (cy=0,i=1;i<=ll;i++)
{
for (cy=0,j=l;j>=1;j--)
{
val=s[j];
val*=10;
val+=cy;
s[j]=val&15;
cy=val>>4;
}
dec+=char(cy+'0');
for (;;)
{
if (!l) break;;
if (s[l]) break;
l--;
}
if (!l) break;;
}
}
return dec;
}
此 C++/VCL 代码基于 dec to/from hex string conversion in C++
这里有一些完整的结果(没有 t运行cating):
e (number)=2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517018925792726517729626778617556182544467087488974778217580927056560148653881088555812992610052264792986514235903850131924702897536490353138389659085786458507020379306026276137800832832239739365071110193933120100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
e (text) =2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551701892
e (const) =2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551702761838606261331384583000752044933826560297606737113200709328709127443747047230696977209310141692836819025515108657463772111252389784425056953696770785449969967946864454905987931636889230098793127736178215424999229576351482208269895193668033182528869398496465105820939239829488793320362509443117301238197068416140397019837679320683282376464804295311802328782509819455815301756717361332069811250996181881593041690351598888519345807273866738589422879228499892086805825749279610484198444363463244968487560233624827041978623209002160990235304369941849146314093431738143640546253152096183690888707016768396424378140592714563549061303107208510383750510115747704171898610687396965521267154688957035035402123407849819334321068170121005627880235193033224745015853904730419957777093503660416997329725088687696640355570716226844716256079882651787134195124665201030592123667719432527867539855894489697096409754591856956380236370162112047742722836489613422516445078182442352948636372141740238893441247963574370263755294448337998016125492278509257782562092622648326277933386566481627725164019105900491644998289315056604725802778631864155195653244258698294695930801915298721172556347546396447910145904090586298496791287406870504895858671747985466775757320568128845920541334053922000113786300945560688166740016984205580403363795376452030402432256613527836951177883863874439662532249850654995886234281899707733276171783928034946501434558897071942586398772754710962953741521115136835062752602326484728703920764310059584116612054529703023647254929666938115137322753645098889031360205724817658511806303644281231496550704751025446501172721155519486685080036853228183152196003735625279449515828418829478761085263981395599006737648292244375287184624578036192981971399147564488262603903381441823262515097482798777996437308997038886778227138360577297882412561190717663946507063304527954661855096666185664709711344474016070462621568071748187784437143698821855967095910259686200235371858874856965220005031173439207321139080329363447972735595527734907178379342163701205005451326383544000186323991490705479778056697853358048966906295119432473099587655236812859041383241160722602998330535370876138939639177957454016137223618789365260538155841587186925538606164779834025435128
e (hex) =2.B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF324E7738926CFBE5F4BF8D8D8C31D763DA06C80ABB1185EB4F7C7B5757F5958490CFD47D7C19BB42158D9554F7B46BCED55C4D79FD5F24D6613C31C3839A2DDF8A9A276BCFBFA1C877C56284DAB79CD4C2B3293D20E9E5EAF02AC60ACC93ECEBh
AnsiString
只是 VCL 字符串 class 具有自动重新分配,因此您可以通过 +,+=
运算符简单地添加字符串 ...
[Edit1] hex2dec 字符串转换说明
好的,我们有 hex
包含十六进制格式数字的字符串,并且想要计算 dec
,它应该在末尾包含十进制格式的相同数字。
扫描部分号码
这只是用单个 O(n)
循环扫描 hex
字符串并记住特殊字符在哪里:
i0
第一个整数位
i1
最后一位整数(小数点前)
i2
第一个小数位(小数点后)
i3
最后一个小数位
sig
从一开始就设置为 +1
如果检测到 -
则设置为 -1
表示数字的符号
所以我们可以使用后者来更简单地提取数字。
转换整数部分
整数部分是通过对十六进制数字值求和计算得出的,例如:
51Ah = 500h + 10h + Ah = 5*16^2 + 1*16^1 + 10*16^0 = 1306
通常这样改写:
51Ah = (((5)*16 +1)*16 +10) = 1306
你可以把它想象成你在源 BASE(10) 算术中将数字乘以目标 BASE(16)。
所以你先从最高位开始读。将其值添加到数字。如果没有其他整数数字出现,则停止,否则将十进制字符串乘以 16 和 read/add 下一个数字。这就是第二个 for 循环所做的。
if (i0) for (i=i0;i<=i1;i++)
如果存在的整数部分遍历其所有数字
c
设置为处理数字的十进制值 <0,F>hex -> <0,15>dec
嵌套的 for (cy=c,j=1;j<=l;j++)
只是将整数十进制字符串 s
乘以 16
。在 s=""; l=0;
开头,其中 s
是十进制结果字符串,但数字顺序相反,没有用 ASCII 编码,而是数字值直接在那里,所以 {0,1,2,...9}
而不是 {"0","1",...}
和 l
是 s
中的位数。 VCL 字符串是从 1
索引的,所以这就是为什么 for
以 1
而不是 0
开头的原因。那么如何将十进制字符串乘以 16?
123*16= 100*16 + 20*16 + 3*16
=1600 + 320 + 48
所以再次将数字十进制值 <0,9>
(从最低有效位开始)读入 val
。将它乘以 16(或向左移位 4 位,即 <<4
与 *16
相同)并根据需要添加前一位的进位 cy
(它设置为十六进制从开始的数字值所以它也添加了......)。现在结果通常超过进位的 1 位数。因此,将 s
的结果数字设置为 s[j]=val%10
并将进位设置为 val/10
您可以忽略 10^(j-1)
因为当您处理 s[j] 时,表示 10 的幂按 j
位置,所以如果你存储回 s[j] ,该数字的值已经被供电......这必须从最低有效数字开始,因为较高的数字在计算时仍在变化。
此后 while (cy>0)
只是将新数字添加到 s
如果结果需要额外的数字。
在此之后只是 s
按正常顺序从数字值转换为 ASCII(不再反转)复制到最终 dec
字符串并在需要时添加符号。这就是整数部分的全部内容。
小数部分以if (i2)
开头
通过将分数乘以源 BASE(16) 算术中的目标 BASE(10),将分数转换为另一个 BASE。所以乘以 10=Ah
在六角算术中...
------------
0.B7Eh -> B7Eh
------------
B7Eh * Ah = 7 2ECh
2ECh * Ah = 1 D38h
D38h * Ah = 8 430h
430h * Ah = 2 9E0h
-------------
0.B7Eh -> 0.7182 dec
------------
如果存在小数部分,则确定添加到最后的 dec
字符串小数点 .
。并将所有小数十六进制数字提取到 s
字符串中(最重要的数字在前)从 ASCII 转换为十六进制数字值 <0,15>
并将 l
设置为小数位数。然后计算 ll
这是由 l
六进制小数 ll=l*1234/1024
表示的小数位数所以 ll
告诉什么时候停止...
转换在 ll
计算之后开始。 for (cy=0,i=1;i<=ll;i++)
只是循环遍历所有要计算的结果数字。在每次迭代中,s
都乘以 10
,但这次是十六进制算术。这就是 s[j]=val%16
和 cy=val/16
的原因。我改用位运算 AND
和 Bit-shift
但结果是一样的。乘法后,进位包含十进制小数位,因此将其添加到最终结果中。
最后一个 for
只是检查 s
中的子结果是否不以零结尾,如果是则将其切断(通过 l--
),如果没有更多有效数字左停止进程。这大大加快了处理大量数据的速度...
希望对您来说已经足够了...
我有一个表示为 11.1111111 的二进制数(. 类似于小数点)。点前有2位,点后有1024位。这是一个以高精度计算 e 的练习,但现在我不知道如何将它转换为十进制。 以防万一你们想知道这个数字,这里是:
10.1011011111100001010100010110001010001010111011010010101001101010101111110111000101011000100000001001110011110100111100111100011101100010111001110001011000001111001110001011010011011010010101101010011110000100110110010000010001010001100100001100111111101111001100100100111001110111001110001001001001101100111110111110010111110100101111111000110110001101100011000011000111010111011000111101101000000110110010000000101010111011000100011000010111101011010011110111110001111011010101110101011111110101100101011000010010010000110011111101010001111101011111000001100110111011010000100001010110001101100101010101010011110111101101000110101111001110110101010101110001001101011110011111110101011111001001001101011001100001001111000011000111000011100000111001101000101101110111111000101010011010001001110110101111001111101111111010000111001000011101111100010101100010100001001101101010110111100111001101010011000010101100110010100100111101001000001110100111100101111010101111000000101010110001100000101011001100100100111110110011101011
如何将其转换为 2.718....(小数点后应有 309 位左右) 我不能简单地将每一位乘以 2^x,因为过一会儿,数字 2^x 将 = 0,即使使用双精度浮点数也是如此。我使用的是 Visual Basic,所以我不确定是否存在更大的变量。
[Spektre 编辑]
只需要 运行 你的字符串和我的代码(基于我评论中的 link),结果是:
e(bigdecimal)=2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750924476146066808226480016847741185374234544243710753907774499206955170189257927265177296267786175561825444670874889747782175809270565601486538810885558129926100522647929865142359038501319247028975364903531383896590857864585070203793060262761378008328322397393650711101939331201
e (text)=2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750924476146066808226480016847741185374234544243710753907774499206955170189
e (reference)=2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551702761838606261331384583000752044933826560297606737113200709328709127443747047230696977209310141692836819025515108657463772111252389784425056953696770785449969967946864454905987931636889230098793127736178215424999229576351482208269895193668033182528869398496465105820939239829488793320362509443117301238197068416140397019837679320683282376464804295311802328782509819455815301756717361332069811250996181881593041690351598888519345807273866738589422879228499892086805825749279610484198444363463244968487560233624827041978623209002160990235304369941849146314093431738143640546253152096183690888707016768396424378140592714563549061303107208510383750510115747704171898610687396965521267154688957035035402123407849819334321068170121005627880235193033224745015853904730419957777093503660416997329725088687696640355570716226844716256079882651787134195124665201030592123667719432527867539855894489697096409754591856956380236370162112047742722836489613422516445078182442352948636372141740238893441247963574370263755294448337998016125492278509257782562092622648326277933386566481627725164019105900491644998289315056604725802778631864155195653244258698294695930801915298721172556347546396447910145904090586298496791287406870504895858671747985466775757320568128845920541334053922000113786300945560688166740016984205580403363795376452030402432256613527836951177883863874439662532249850654995886234281899707733276171783928034946501434558897071942586398772754710962953741521115136835062752602326484728703920764310059584116612054529703023647254929666938115137322753645098889031360205724817658511806303644281231496550704751025446501172721155519486685080036853228183152196003735625279449515828418829478761085263981395599006737648292244375287184624578036192981971399147564488262603903381441823262515097482798777996437308997038886778227138360577297882412561190717663946507063304527954661855096666185664709711344474016070462621568071748187784437143698821855967095910259686200235371858874856965220005031173439207321139080329363447972735595527734907178379342163701205005451326383544000186323991490705479778056697853358048966906295119432473099587655236812859041383241160722602998330535370876138939639177957454016137223618789365260538155841587186925538606164779834025435128
首先是从文本转换为我的 arbnum
数据类型,然后再转换回文本,中间是纯文本到文本的转换(就像在 link 中转换为十六进制之前那) 最后是 reference e
这里是二进制字符串的十六进制字符串:
e (hex) =2.B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF324E7738926CFBE5F4BF8D8D8C31D763DA06C80ABB1185EB4F7C7B5757F5958490CFD47D7C19BB42158D9554F7B46BCED55C4D79FD5F24D6613C31C3839A2DDF8A9A276BCFBFA1C877C56284DAB79CD4C2B3293D20E9E5EAF02AC60ACC93ECEBh
我 t运行 降低了十进制半字节的大小,因此最后可能还有 1,2 或 3 位未处理 ...
您可以使用 System.Numerics BigInteger。它可以容纳大量的数字。 https://msdn.microsoft.com/en-us/library/system.numerics.biginteger%28v=vs.110%29.aspx
编辑: 我以为小数点后的二进制是照常计算的。因此,最后一位将是 2^1,其中 1 将一直增加到点。这会呈现一个类似于 1.2*10^308 的数字。然后将截断为 2.12 ......
但实际上是小数点后的第一个位被算作2^-1,-1减为2^-1024。因此呈现一个无法用 BigInteger 表示的 0.x 数字。
小数点后每位二进制数代表2^-n的十进制权重,从n=1开始。
这可以使用霍纳方法使用任何 bignum 库进行评估,如下所示: (这只是伪代码)
power_of_five = 1;
digits = 0;
while digits_left
digits = digits * 10;
power_of_five = power_of_five * 5;
if (next_digit_is_set)
digits = digits + power_of_five;
end
这将产生一个 1024 位的大数字,其中只有前 309 位有效。
将二进制字符串转换为十六进制
整数部分很容易
"10." -> "2."
小数部分也很容易:10.1011011111100001010100010110 bin 10.1011 0111 1110 0001 0101 0001 0110 bin 2.B 7 E 1 5 1 6 hex
如您所见,每个 nibel 整数值也是十六进制数字
0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
这里是一些 C++ 代码:int i,j,l; char *t16="0123456789ABCDEF"; AnsiString s0="10.your binary number",s1="2."; for (i=4,l=s0.Length();i<=l;) { j=0; if ((i<=l)&&(s0[i]=='1')) j+=8; i++; if ((i<=l)&&(s0[i]=='1')) j+=4; i++; if ((i<=l)&&(s0[i]=='1')) j+=2; i++; if ((i<=l)&&(s0[i]=='1')) j+=1; i++; s1+=char(t16[j]); } // here s1 holds the hex string
通过预分配生成的 s1 大小可以显着加快速度
运行
hex to dec
字符串转换AnsiString str_hex2dec(const AnsiString &hex) { char c; AnsiString dec="",s; int i,j,l,ll,cy,val; int i0,i1,i2,i3,sig; sig=+1; l=hex.Length(); if (l) { c=hex[l]; if (c=='h') l--; if (c=='H') l--; } i0=0; i1=l; i2=0; i3=l; for (i=1;i<=l;i++) // scan for parts of number { char c=hex[i]; if (c=='-') sig=-sig; if ((c=='.')||(c==',')) i1=i-1; if ((c>='0')&&(c<='9')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; } if ((c>='A')&&(c<='F')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; } if ((c>='a')&&(c<='f')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; } } l=0; s=""; if (i0) for (i=i0;i<=i1;i++) { c=hex[i]; if ((c>='0')&&(c<='9')) c-='0'; else if ((c>='A')&&(c<='F')) c-='A'-10; else if ((c>='a')&&(c<='f')) c-='A'-10; for (cy=c,j=1;j<=l;j++) { val=(s[j]<<4)+cy; s[j]=val%10; cy =val/10; } while (cy>0) { l++; s+=char(cy%10); cy/=10; } } if (s!="") { for (j=1;j<=l;j++) { c=s[j]; if (c<10) c+='0'; else c+='A'-10; s[j]=c; } for (i=l,j=1;j<i;j++,i--) { c=s[i]; s[i]=s[j]; s[j]=c; } dec+=s; } if (dec=="") dec="0"; if (sig<0) dec="-"+dec; if (i2) { dec+='.'; s=hex.SubString(i2,i3-i2+1); l=s.Length(); for (i=1;i<=l;i++) { c=s[i]; if ((c>='0')&&(c<='9')) c-='0'; else if ((c>='A')&&(c<='F')) c-='A'-10; else if ((c>='a')&&(c<='f')) c-='A'-10; s[i]=c; } ll=((l*1234)>>10); // num of decimals to compute for (cy=0,i=1;i<=ll;i++) { for (cy=0,j=l;j>=1;j--) { val=s[j]; val*=10; val+=cy; s[j]=val&15; cy=val>>4; } dec+=char(cy+'0'); for (;;) { if (!l) break;; if (s[l]) break; l--; } if (!l) break;; } } return dec; }
此 C++/VCL 代码基于 dec to/from hex string conversion in C++
这里有一些完整的结果(没有 t运行cating):
e (number)=2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517018925792726517729626778617556182544467087488974778217580927056560148653881088555812992610052264792986514235903850131924702897536490353138389659085786458507020379306026276137800832832239739365071110193933120100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
e (text) =2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551701892
e (const) =2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551702761838606261331384583000752044933826560297606737113200709328709127443747047230696977209310141692836819025515108657463772111252389784425056953696770785449969967946864454905987931636889230098793127736178215424999229576351482208269895193668033182528869398496465105820939239829488793320362509443117301238197068416140397019837679320683282376464804295311802328782509819455815301756717361332069811250996181881593041690351598888519345807273866738589422879228499892086805825749279610484198444363463244968487560233624827041978623209002160990235304369941849146314093431738143640546253152096183690888707016768396424378140592714563549061303107208510383750510115747704171898610687396965521267154688957035035402123407849819334321068170121005627880235193033224745015853904730419957777093503660416997329725088687696640355570716226844716256079882651787134195124665201030592123667719432527867539855894489697096409754591856956380236370162112047742722836489613422516445078182442352948636372141740238893441247963574370263755294448337998016125492278509257782562092622648326277933386566481627725164019105900491644998289315056604725802778631864155195653244258698294695930801915298721172556347546396447910145904090586298496791287406870504895858671747985466775757320568128845920541334053922000113786300945560688166740016984205580403363795376452030402432256613527836951177883863874439662532249850654995886234281899707733276171783928034946501434558897071942586398772754710962953741521115136835062752602326484728703920764310059584116612054529703023647254929666938115137322753645098889031360205724817658511806303644281231496550704751025446501172721155519486685080036853228183152196003735625279449515828418829478761085263981395599006737648292244375287184624578036192981971399147564488262603903381441823262515097482798777996437308997038886778227138360577297882412561190717663946507063304527954661855096666185664709711344474016070462621568071748187784437143698821855967095910259686200235371858874856965220005031173439207321139080329363447972735595527734907178379342163701205005451326383544000186323991490705479778056697853358048966906295119432473099587655236812859041383241160722602998330535370876138939639177957454016137223618789365260538155841587186925538606164779834025435128
e (hex) =2.B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF324E7738926CFBE5F4BF8D8D8C31D763DA06C80ABB1185EB4F7C7B5757F5958490CFD47D7C19BB42158D9554F7B46BCED55C4D79FD5F24D6613C31C3839A2DDF8A9A276BCFBFA1C877C56284DAB79CD4C2B3293D20E9E5EAF02AC60ACC93ECEBh
AnsiString
只是 VCL 字符串 class 具有自动重新分配,因此您可以通过 +,+=
运算符简单地添加字符串 ...
[Edit1] hex2dec 字符串转换说明
好的,我们有 hex
包含十六进制格式数字的字符串,并且想要计算 dec
,它应该在末尾包含十进制格式的相同数字。
扫描部分号码
这只是用单个
O(n)
循环扫描hex
字符串并记住特殊字符在哪里:i0
第一个整数位i1
最后一位整数(小数点前)i2
第一个小数位(小数点后)i3
最后一个小数位sig
从一开始就设置为+1
如果检测到-
则设置为-1
表示数字的符号
所以我们可以使用后者来更简单地提取数字。
转换整数部分
整数部分是通过对十六进制数字值求和计算得出的,例如:
51Ah = 500h + 10h + Ah = 5*16^2 + 1*16^1 + 10*16^0 = 1306
通常这样改写:
51Ah = (((5)*16 +1)*16 +10) = 1306
你可以把它想象成你在源 BASE(10) 算术中将数字乘以目标 BASE(16)。
所以你先从最高位开始读。将其值添加到数字。如果没有其他整数数字出现,则停止,否则将十进制字符串乘以 16 和 read/add 下一个数字。这就是第二个 for 循环所做的。
if (i0) for (i=i0;i<=i1;i++)
如果存在的整数部分遍历其所有数字c
设置为处理数字的十进制值<0,F>hex -> <0,15>dec
嵌套的
for (cy=c,j=1;j<=l;j++)
只是将整数十进制字符串s
乘以16
。在s=""; l=0;
开头,其中s
是十进制结果字符串,但数字顺序相反,没有用 ASCII 编码,而是数字值直接在那里,所以{0,1,2,...9}
而不是{"0","1",...}
和l
是s
中的位数。 VCL 字符串是从1
索引的,所以这就是为什么for
以1
而不是0
开头的原因。那么如何将十进制字符串乘以 16?123*16= 100*16 + 20*16 + 3*16 =1600 + 320 + 48
所以再次将数字十进制值
<0,9>
(从最低有效位开始)读入val
。将它乘以 16(或向左移位 4 位,即<<4
与*16
相同)并根据需要添加前一位的进位cy
(它设置为十六进制从开始的数字值所以它也添加了......)。现在结果通常超过进位的 1 位数。因此,将s
的结果数字设置为s[j]=val%10
并将进位设置为val/10
您可以忽略10^(j-1)
因为当您处理 s[j] 时,表示 10 的幂按j
位置,所以如果你存储回 s[j] ,该数字的值已经被供电......这必须从最低有效数字开始,因为较高的数字在计算时仍在变化。此后
while (cy>0)
只是将新数字添加到s
如果结果需要额外的数字。在此之后只是
s
按正常顺序从数字值转换为 ASCII(不再反转)复制到最终dec
字符串并在需要时添加符号。这就是整数部分的全部内容。小数部分以
开头if (i2)
通过将分数乘以源 BASE(16) 算术中的目标 BASE(10),将分数转换为另一个 BASE。所以乘以
10=Ah
在六角算术中...------------ 0.B7Eh -> B7Eh ------------ B7Eh * Ah = 7 2ECh 2ECh * Ah = 1 D38h D38h * Ah = 8 430h 430h * Ah = 2 9E0h ------------- 0.B7Eh -> 0.7182 dec ------------
如果存在小数部分,则确定添加到最后的
dec
字符串小数点.
。并将所有小数十六进制数字提取到s
字符串中(最重要的数字在前)从 ASCII 转换为十六进制数字值<0,15>
并将l
设置为小数位数。然后计算ll
这是由l
六进制小数ll=l*1234/1024
表示的小数位数所以ll
告诉什么时候停止...转换在
ll
计算之后开始。for (cy=0,i=1;i<=ll;i++)
只是循环遍历所有要计算的结果数字。在每次迭代中,s
都乘以10
,但这次是十六进制算术。这就是s[j]=val%16
和cy=val/16
的原因。我改用位运算AND
和Bit-shift
但结果是一样的。乘法后,进位包含十进制小数位,因此将其添加到最终结果中。最后一个
for
只是检查s
中的子结果是否不以零结尾,如果是则将其切断(通过l--
),如果没有更多有效数字左停止进程。这大大加快了处理大量数据的速度...
希望对您来说已经足够了...