0xFFFFFFFF'FFFFFFFF
). This script utilizes pre-generated multiplication table. It does exactly the same what humans do to convert hexadecimal to decimal by hand. It grabs proper decimal values from the table (array) and saves it to a variable that I like to name add chain. As the assignment finishes, the script sums all the numbers from such an add chain.Seven powers of 16 are summed internally, using the
set /a
command. Why not eight? Take a sheet of paper and find out (hint: cmd.exe supports 32-bit signed integers from the range of -231 ... 231-1). These 7 numbers are summed the way they become one number in the add chain. If a number is greater than 264, then the script calculates further multiples of 16, till "the end".The latest stage of conversion is summing of values from the add chain by the
LargeInt_add
procedure.I can not guarantee the following script is 100% correct, neither did I check what's the biggest number it could handle. The multiple table has been generated using...
LargeInt_add
.
@echo off :h2d echo. set/p var=give hex value call:HexToDec var var0 echo. echo 0x%var% --^> %var0% goto h2d :HexToDec setlocal&set var=%% %1 %%&set var=%var: =%&call set var=%var% set sum=0 set exp=-1 set base=16 set pow16_0_=0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 set pow16_1_=16;256;4096;65536;1048576;16777216;268435456;4294967296;68719476736;1099511627776;17592186044416;281474976710656;4503599627370496;72057594037927936;1152921504606846976 set pow16_2_=32;512;8192;131072;2097152;33554432;536870912;8589934592;137438953472;2199023255552;35184372088832;562949953421312;9007199254740992;144115188075855872;2305843009213693952 set pow16_3_=48;768;12288;196608;3145728;50331648;805306368;12884901888;206158430208;3298534883328;52776558133248;844424930131968;13510798882111488;216172782113783808;3458764513820540928 set pow16_4_=64;1024;16384;262144;4194304;67108864;1073741824;17179869184;274877906944;4398046511104;70368744177664;1125899906842624;18014398509481984;288230376151711744;4611686018427387904 set pow16_5_=80;1280;20480;327680;5242880;83886080;1342177280;21474836480;343597383680;5497558138880;87960930222080;1407374883553280;22517998136852480;360287970189639680;5764607523034234880 set pow16_6_=96;1536;24576;393216;6291456;100663296;1610612736;25769803776;412316860416;6597069766656;105553116266496;1688849860263936;27021597764222976;432345564227567616;6917529027641081856 set pow16_7_=112;1792;28672;458752;7340032;117440512;1879048192;30064771072;481036337152;7696581394432;123145302310912;1970324836974592;31525197391593472;504403158265495552;8070450532247928832 set pow16_8_=128;2048;32768;524288;8388608;134217728;2147483648;34359738368;549755813888;8796093022208;140737488355328;2251799813685248;36028797018963968;576460752303423488;9223372036854775808 set pow16_9_=144;2304;36864;589824;9437184;150994944;2415919104;38654705664;618475290624;9895604649984;158329674399744;2533274790395904;40532396646334464;648518346341351424;10376293541461622784 set pow16_10_=160;2560;40960;655360;10485760;167772160;2684354560;42949672960;687194767360;10995116277760;175921860444160;2814749767106560;45035996273704960;720575940379279360;11529215046068469760 set pow16_11_=176;2816;45056;720896;11534336;184549376;2952790016;47244640256;755914244096;12094627905536;193514046488576;3096224743817216;49539595901075456;792633534417207296;12682136550675316736 set pow16_12_=192;3072;49152;786432;12582912;201326592;3221225472;51539607552;824633720832;13194139533312;211106232532992;3377699720527872;54043195528445952;864691128455135232;13835058055282163712 set pow16_13_=208;3328;53248;851968;13631488;218103808;3489660928;55834574848;893353197568;14293651161088;228698418577408;3659174697238528;58546795155816448;936748722493063168;14987979559889010688 set pow16_14_=224;3584;57344;917504;14680064;234881024;3758096384;60129542144;962072674304;15393162788864;246290604621824;3940649673949184;63050394783186944;1008806316530991104;16140901064495857664 set pow16_15_=240;3840;61440;983040;15728640;251658240;4026531840;64424509440;1030792151040;16492674416640;263882790666240;4222124650659840;67553994410557440;1080863910568919040;17293822569102704640 :loop_ if not defined _var ( set _var=%var:~-1% ) else ( set _var=%_var%;%var:~-1% ) set var=%var:~0,-1% if defined var (goto loop_) for %%A in (%_var%) do (call:loop %%A) set n_=0 for %%A in (%chain%) do (set/a n_+=1) if %n_% EQU 0 (goto:hextodec_out) if %n_% LEQ 7 (call:sum_lesser&for /f "tokens=2* delims=^=" %%G in ('set component_') do (set sum=%%G)) else (call:sum_bigger) :hextodec_out endlocal&set %2=%sum%&exit/b0 :sum_bigger call:sum_lesser set chain=%component_%;%chain% :sum_bigger_ for /f "tokens=1,2* delims=;" %%A in ("%chain%") do (set component=%%A&if "%%C" =="" (set chain=%%B) else (set chain=%%B;%%C)) if not "%component:~0,1%"=="0" (call:LargeInt_add sum component sum) if defined chain (goto sum_bigger_) exit/b0 :sum_lesser for /f "tokens=1,2,3,4,5,6,7 delims=;" %%A in ("%chain%") do (call:sum_smaller_components %%A %%B %%C %%D %%E %%F %%G) exit/b0 :sum_smaller_components set/a component_+=%1 for /f "tokens=2* delims=;" %%H in ("%chain%") do (set chain=%%H;%%I) shift if not "%1"=="" (goto sum_smaller_components) exit/b0 :loop set num_=%1 if /i "%num_%"=="A" (set num_=10) if /i "%num_%"=="B" (set num_=11) if /i "%num_%"=="C" (set num_=12) if /i "%num_%"=="D" (set num_=13) if /i "%num_%"=="E" (set num_=14) if /i "%num_%"=="F" (set num_=15) set/a exp+=1 if %exp% GTR 0 ( if %exp% LSS 16 ( for /f "tokens=2* delims=^=" %%A in ('set pow16_%num_%_') do (for /f "tokens=%exp% delims=;" %%C in ("%%A;%%B") do (set num=%%C)) ) if %exp% GTR 15 ( call:further_multiplies ) ) else (set num=%num_%) if defined chain ( set chain=%chain%;%num% ) else (set chain=%num%) exit/b0 :further_multiplies if not defined tokens (set tokens=15) for /f "tokens=2* delims=^=" %%G in ('set pow16_1_') do (for /f "tokens=%tokens% delims=;" %%H in ("%%G") do set pow16=%%H) call:LargeInt_mul pow16 base pow16 set pow16_1_=%pow16_1_%;%pow16% set/a tokens+=1 if "%num_%"=="0" (set num=0) else (call:LargeInt_mul num_ pow16 num) exit/b0 :handle_buff if %buff% GTR 9 (set buff=%buff:~-1%&set carry=%buff:~0,1%) else (set carry=) exit/b0 :LargeInt_mul setlocal set left=%% %1 %% set left=%left: =% call set left=%left% set right=%% %2 %% set right=%right: =% call set right=%right% if defined left (if defined right (goto lrgintmul)) set exitcode=1 goto lrgintmul_endproc :lrgintmul set upper_component=%left% set lower_component=%right% :lrgintmul_loop set temp_component_l= set temp_component_u= set temp_component_l=%lower_component:~-1% set temp_component_u=%upper_component:~-1% if defined temp_component_l ( if defined temp_component_u ( set/a buff=%temp_component_l%*%temp_component_u% if defined carry (set/a buff+=%carry%) call:handle_buff ) ) if "%suffix_added%"=="false" ( set subst=%buff%%subst%%suffix% ) else ( set subst=%buff%%subst% ) set suffix_added=true set upper_component=%upper_component:~0,-1% if not defined upper_component ( if defined carry ( set subst=%carry%%subst%&set carry= ) ) if not defined upper_component ( if not defined lower_component ( goto lrgintmul_opsucc ) set add_chain=%add_chain%;%subst% set subst= set upper_component=%left% set lower_component=%lower_component:~0,-1% set suffix_added=false set suffix=%suffix%0 ) if defined lower_component (goto lrgintmul_loop) set sum=0 for %%A in (%add_chain%) do (set component=%%A&call:LargeInt_add sum component sum) :lrgintmul_opsucc set exitcode=0 :lrgintmul_endproc call:ThrowErrorLevel exitcode %exitcode% endlocal&set %3=%sum%&exit/b%errorlevel% :LargeInt_add setlocal set left=%% %1 %% set left=%left: =% call set left=%left% set right=%% %2 %% set right=%right: =% call set right=%right% if defined left (if defined right (goto lrgintadd)) set exitcode=1 goto lrgintadd_endproc :lrgintadd set buff= set lastchar_l= set lastchar_r= if defined left (set lastchar_l=%left:~-1%) if defined right (set lastchar_r=%right:~-1%) if defined carry (set/a buff+=%carry%&set carry=) if defined lastchar_l (set/a buff+=%lastchar_l%) if defined lastchar_r (set/a buff+=%lastchar_r%) if %buff% GTR 9 ( set outvar=%buff:~-1%%outvar% set carry=%buff:~0,1% ) else ( set outvar=%buff%%outvar% ) if defined left (set left=%left:~0,-1%) if defined right (set right=%right:~0,-1%) if not defined left (if not defined right (set outvar=%carry%%outvar%&goto lrgintadd_opsucc)) goto lrgintadd :lrgintadd_opsucc set exitcode=0 :lrgintadd_endproc call:ThrowErrorLevel exitcode %exitcode% endlocal&set %3=%outvar%&exit/b%errorlevel% :ThrowErrorLevel if defined %1 set %1= exit/b%2
No comments:
Post a Comment