Hehe, it's not explanations, it's just that Chinese labels were used. With Chinese labels, even explanations can be omitted!
Union site: www.cn-dos.net Forum site: www.cn-dos.net/forum
DOS stands for freedom, openness and progress. Let us work hard, learn from the openness and GNU spirit of FreeDOS and Linux, and together build and grow a free GNU GPL world!
DigestI
View 41,140 Replies 136
Originally posted by qwe1234567 at 2006-10-23 03:55:
Hehe, it's not explanations, it's just that Chinese labels were used. With Chinese labels, even explanations can be omitted!
Originally posted by qwe1234567 at 2006-10-23 04:18:
This is also my first time using Chinese labels. I think there probably isn't a limit on the number
Originally posted by namejm at 2006-10-4 21:08:
So far, everyone has already found two methods for calculating floating-point numbers under CMD:
Method 1: Calculate the integer part and the fractional part separately. The process is: the integer parts can just be added directly; the fractional part is a bit more troublesome: if the numbers of digits after the decimal point are not the same, then use the one with the most digits as the standard, pad zeros onto the fractional part of the other number, and then perform integer addition on the fractional parts; if the number of digits in the sum exceeds the longest original fractional length, then carry 1 to the integer part, and the highest digit of the fractional part must be reduced by 1 accordingly;
Method 2: Recombine the integer part and fractional part into a new number, then perform addition on the new number, and finally insert the decimal point back into its original position;
The respective advantages and disadvantages of the two methods:
Method 1: Advantage: the range of floating-point numbers it can handle is very large; as long as the result of the addition is between (2^32-1.2^32-1) and -(2^32-1.2^32-1), it can handle it; disadvantage: most problems appear in the fractional part, for example, if the highest digit of the fractional part is 08 or 09, errors may occur, and these two cases need separate handling; if the digit length of the fractional sum exceeds the longest original length, then the integer part must be incremented by 1 and the highest fractional digit must be decremented by 1; if this is extended to addition of three or more floating-point numbers, the carry problem becomes even more complicated;
Method 2: Advantage: there is no need to separately handle the 08 and 09 cases, and no need to consider carry problems (after reading pengfei's analysis below, I found that this description is a bit problematic; for details please refer to the explanation below); disadvantage: the range of floating-point numbers it can handle is relatively small; it only succeeds when the range of the new value formed by removing the decimal point from the sum is between (2^32-1.2^32-1) and -(2^32-1.2^32-1).

@echo off
set aa=%1
set bb=%2
::Call floating-point multiplication function
call :mul cc aa bb %3
echo %cc%
goto :eof
:mul
::Floating-point multiplication function, leading and trailing zeros are allowed, supports products of: 49 integer digits, 49 fractional digits.
::The first parameter is the receiving variable name, the second and third are the names of the multiplicand variables, the fourth specifies how many decimal places to keep
@echo off&setlocal enabledelayedexpansion
set cc=0
set ka=!%2:*.=!
set kb=!%3:*.=!
set maa=!%2:.=!
set mb=!%3:.=!
for /l %%a in (0,1,49) do if not "!maa:~%%a,1!"=="0" (set maa=!maa:~%%a!&goto :maaok)
:maaok
for /l %%a in (0,1,49) do if not "!mb:~%%a,1!"=="0" (set mb=!mb:~%%a!&goto :mbok)
:mbok
if "!kb!."=="!%3!." set kb=
if "!ka!."=="!%2!." set ka=
set kab=!kb!!ka!#
for /l %%a in (0,1,49) do if "!kab:~%%a,1!"=="#" (set kab=%%a&goto :lp1)
:lp1
if defined mb (set al=!mb:~-4!
if "!al:~0,1!"=="0" set/a al=1!al!-10000
set mb=!mb:~0,-4!
) else (goto :endmul)
set ma=!maa!
set zero=!mz!
set mz=!mz!0000
for /l %%a in (1,1,12) do (
if defined ma (set bl=!ma:~-4!
if "!bl:~0,1!"=="0" set/a bl=1!bl!-10000
set/a bl*=al&set ma=!ma:~0,-4!
) else (goto :end1)
set bl=!bl!!zero!
set zero=!zero!0000
call :add cc cc bl
)
:end1
goto :lp1
:endmul
if not %kab%==0 (
set ka=00000000000000000000000000000000000000000000000000%cc%
if "!cc:~0,-%kab%!"=="" (set cc=0.!ka:~-%kab%,%4!) else (set cc=!cc:~0,-%kab%!.!cc:~-%kab%,%4!)
)
endlocal&set %1=%cc%&goto :eof
:add
set xa=%cc%
set xb=%bl%
set cc=
set zz=0
set zy=
for /l %%a in (9,9,81) do (
if "!xa!!xb!"=="" goto :end
set cc=!zy!!cc!
if defined xa (set "aa=000000000!xa:~-9!"&set xa=!xa:~0,-9!) else (set aa=000000000)
if defined xb (set "bb=000000000!xb:~-9!"&set xb=!xb:~0,-9!) else (set bb=000000000)
set/a zz=!zz:~0,-9!+1!bb:~-9!-1000000000+1!aa:~-9!-1000000000
set zy=000000000!zz!
set zy=!zy:~-9!
)
:end
set cc=%zz%%cc%
if not %cc% gtr 0 goto :endok
if "%cc:~0,2%"=="0." goto :endok
for /l %%a in (0,1,36) do if not "!cc:~%%a,1!"=="0" (set cc=!cc:~%%a!&goto :endok)
:endok
goto :eof@echo off
set aa=%1
set bb=%2
::Call the floating-point multiplication function
echo %time%
call :mul cc aa bb %3
echo %time%
echo %cc%
goto :eof
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
:mul <接收变量名> <被乘数> <乘数>
::
::Floating-point multiplication function; leading and trailing 0s are both allowed, supports a product of: 49 integer digits and 49 decimal digits.
::The first parameter is the receiving variable name, the second and third are the variable names to be multiplied, the fourth specifies how many decimal places to keep
::Calculating the maximum number of digits takes only 12 milliseconds
::Don't let the code length fool you, the speed is definitely not slow
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off&setlocal enabledelayedexpansion
set cc=0
set ka=!%2:*.=!
set kb=!%3:*.=!
set maa=!%2:.=!
set mb=!%3:.=!
for /l %%a in (0,1,49) do if not "!maa:~%%a,1!"=="0" (set maa=!maa:~%%a!&goto :maaok)
:maaok
for /l %%a in (0,1,49) do if not "!mb:~%%a,1!"=="0" (set mb=!mb:~%%a!&goto :mbok)
:mbok
if "!kb!."=="!%3!." set kb=
if "!ka!."=="!%2!." set ka=
set kab=!kb!!ka!#
for /l %%a in (0,1,49) do if "!kab:~%%a,1!"=="#" (set kab=%%a&goto :lp1)
set mz=
:lp1
if defined mb (set al=!mb:~-4!
if "!al:~0,1!"=="0" set/a al=1!al!-10000
set mb=!mb:~0,-4!
) else (goto :endmul)
set ma=!maa!
set "cl= "
for /l %%a in (1,4,91) do (
if not defined ma (goto :end1)
set bl=!ma:~-4!
if "!bl:~0,1!"=="0" set/a bl=1!bl!-10000
set/a bl=!cl:~0,-%%a!+bl*al
set ma=!ma:~0,-4!
set cl=0000!cl:~-%%a!
set cl=!bl!!cl:~-%%a!
)
:end1
set cl=%cl:~0,-1%%mz%
set mz=!mz!0000
set xa=%cc%
set xb=%cl%
set cc=
set zz=0
set zy=
for /l %%a in (9,9,81) do (
if "!xa!!xb!"=="" goto :end2
set cc=!zy!!cc!
if defined xa (set "aa=000000000!xa:~-9!"&set xa=!xa:~0,-9!) else (set aa=000000000)
if defined xb (set "bb=000000000!xb:~-9!"&set xb=!xb:~0,-9!) else (set bb=000000000)
set/a zz=!zz:~0,-9!+1!bb:~-9!-1000000000+1!aa:~-9!-1000000000
set zy=000000000!zz!
set zy=!zy:~-9!
)
:end2
set cc=%zz%%cc%
if not %cc% gtr 0 goto :lp1
for /l %%a in (0,1,36) do if not "!cc:~%%a,1!"=="0" (set cc=!cc:~%%a!&goto :lp1)
goto :lp1
:endmul
if not %kab%==0 (
set ka=00000000000000000000000000000000000000000000000000%cc%
if "!cc:~0,-%kab%!"=="" (set cc=0.!ka:~-%kab%,%4!) else (set cc=!cc:~0,-%kab%!.!cc:~-%kab%,%4!)
)
endlocal&set %1=%cc%&goto :eof