I have removed some bugs, converted the functions to macros, and split the source into two files:
- floaty.bat (the test cases; the source is at the bottom of this post)
- loadFloat.bat (that contains the macros)
So if you want to use the float functions in your batch file you only need to call "loadFloat.bat" once
and then just use the macros; make sure the extensions are enabled (default on most systems):
Code: Select all
@echo off
setlocal enableExtensions
:: load all macros, and exit if it has failed for whatever reasons
call "loadFloat.bat"
if errorLevel 1 exit /b 1
:: use the macros (names are similar to the function names)
for %%a in (operand1 operand2 result string) do set "%%~a="
%$str2float% "10" operand1
%$str2float% "4" operand2
%$floatAdd% "%operand1%" "%operand2%" result
%$float2str% "%result%" string
echo("10" + "4" = "%string%"
%$floatSub% "%operand1%" "%operand2%" result
%$float2str% "%result%" string
echo("10" - "4" = "%string%"
%$floatMul% "%operand1%" "%operand2%" result
%$float2str% "%result%" string
echo("10" * "4" = "%string%"
endlocal
If you want to read the source (more easily), this "toSource.bat" may help:
Code: Select all
@echo off
setlocal enableExtensions disableDelayedExpansion
call loadFloat.bat
2>nul md "macros"
for %%a in (str2float float2str floatAdd floatSub floatMul intToHex) do (
(
set "firstLine=true"
for /F "tokens=1* delims=:" %%b in ('set $%%~a ^| findstr /N "^"') do (
if defined firstLine (
set "firstLine="
for /F "tokens=1* delims==" %%d in ("%%c") do (
set line=%%~e
echo(
)
) else (
set line=%%~c
)
setlocal enableExtensions enableDelayedExpansion
set "line=!line:%%=%%%%!"
echo(!line!
endlocal
)
) > "macros\%%~a.txt"
)
endlocal
This "floaty.bat" contains the test cases (exceeded the maximum number of allowed characters: 60000):
Code: Select all
@echo off
setlocal enableExtensions disableDelayedExpansion
call loadFloat.bat
if errorLevel 1 (set error=true)
if defined error exit /b 1
call :floatTest ".e "
call :floatTest ".e3 "
call :floatTest ".2e "
call :floatTest "1.e "
call :floatTest "+.e "
call :floatTest "+1.e "
call :floatTest "-.e "
call :floatTest "-1.e "
call :floatTest "NaN "
call :floatTest "+NaN "
call :floatTest "-NaN "
call :floatTest "+NaN(7FFFFFFF) "
call :floatTest "-NaN(7FFFFFFF) "
call :floatTest "+NaN(FFFFFFFF) "
call :floatTest "-NaN(FFFFFFFF) "
call :floatTest "+NaN(FF83FFFF) "
call :floatTest "-NaN(FF83FFFF) "
call :floatTest "+NaN(FF83FFFF) "
call :floatTest "-NaN(FF83FFFF) "
call :floatTest "inf "
call :floatTest "+inf "
call :floatTest "-inf "
call :floatTest "0.0 "
call :floatTest "-0.0 "
call :floatTest "0x01234567 "
call :floatTest "+0x01234567 "
call :floatTest "-0x01234567 "
call :floatTest "1000.0 "
call :floatTest "1000.00006 "
call :floatTest "0.000001 "
call :floatTest "1.4e-45 "
call :floatTest "4.2E-45 "
call :floatTest "1.1754945E-38 "
call :floatTest "5.877472E-39 "
call :floatTest "12.375 "
call :floatTest "0.0001 "
call :floatTest "0.001 "
call :floatTest "0.01 "
call :floatTest "0.1 "
call :floatTest "1 "
call :floatTest "10 "
call :floatTest "100 "
call :floatTest "1000 "
call :floatTest "10000 "
call :floatTest "100000 "
call :floatTest "1000000 "
call :floatTest "10000000 "
call :floatTest "68.123 "
call :floatTest "1.17549434E-38 "
call :floatTest "5.877472E-39 "
call :floatTest "-1.0e-6 "
call :floatTest "1.763241500000E-38"
call :floatTest "1.14794E-41 "
call :floatTest "1.4E-45 "
call :floatTest "1.0e10 "
call :floatTest "+1.0e+10 "
call :floatTest "- 1.0 e -10 "
echo(
call :floatTest Add "45.0000" "-45.3000"
call :floatTest Add "100" "0.006"
call :floatTest Add "1.4E-45" "1.1754942E-38"
call :floatTest Add "1.4E-45" "1.4E-45"
call :floatTest Add "1" "2"
echo(
call :floatTest Sub "100" "0.006"
call :floatTest Sub "1.4E-45" "1.1754942E-38"
call :floatTest Sub "1.4E-45" "1.4E-45"
call :floatTest Sub "1" "2"
echo(
call :floatTest Mul "100" "0.1"
call :floatTest Mul "100" "0.05"
call :floatTest Mul "100" "0.005"
call :floatTest Mul "1.4E-45" "1"
call :floatTest Mul "2.8E-45" "0.5"
endlocal
endlocal
goto :eof
:floatTest (overloaded)
::
:: one arguments version: converts the string to a float and back, displaying the results
:: %~1 float string
::
:: three arguments version: performs operand1 operator operand2, displays the result in hex/string
:: %~1 float operator in { "add", "sub", "mul" } (other operators are ignored)
:: %~2 float string operand2
:: %~3 float string operand1
::
setlocal enableDelayedExpansion
set "op=%~1"
set "A=%~2"
set "B=%~3"
if %2. == . (
for %%a in ("float", "hex", "string") do set "%%~a="
%$str2float% "%~1%" float
%$intToHex% "!float!" hex
%$float2str% "!float!" string
echo(!hex! ^<-- "%~1" --^> "!string!"
) else (
for %%a in ("op", "value1", "value2", "float1", "float2", "float3", "hex1", "hex2", "hex3", "string1") do set "%%~a="
set "op[add]=+"
set "op[sub]=-"
set "op[mul]=*"
set "op=!op[%~1]!"
set "value1=%~2"
set "value2=%~3"
%$str2float% "!value1!" "float1"
%$str2float% "!value2!" "float2"
if /I "%~1" == "add" (
%$floatAdd% "!float1!" "!float2!" "float3"
) else if /I "%~1" == "sub" (
%$floatSub% "!float1!" "!float2!" "float3"
) else if /I "%~1" == "mul" (
%$floatMul% "!float1!" "!float2!" "float3"
) else (
endlocal
goto :eof
)
%$intToHex% "!float1!" "hex1"
%$intToHex% "!float2!" "hex2"
%$intToHex% "!float3!" "hex3"
%$float2str% "!float3!" "string1"
echo !value1! !op! !value2! = !float1! !op! !float2! == !hex1! !op! !hex2! == !hex3! == !float3! == !string1!
)
endlocal
goto :eof
penpen