-2

I am currently working on a game in batch script and in one place, I need to make a multiplication of decimals. The problem is, the end result is always 0.

This is the code:

@echo off 
echo Calcultating New Values
echo ...
ping localhost -n 2 >nul
set /p coal_price_buy_brt=<coal_price_buy_brt.wss
set /p coal_ind_buy=<coal_ind_buy.wss
cls
echo First Values :
echo ################################
echo ## Coal Price Brutto  ##  %coal_price_buy_brt%  ##
echo ################################
echo ## Coal Index Buy ## %coal_ind_buy% ##
echo ################################
ping localhost -n 3 >nul
echo %coal_price_buy_brt%
echo %coal_ind_buy%
set ENABLEDELAYEDEXPANSION=coal_price_buy_net
set /p coal_price_buy_net=<calc %coal_price_buy_brt%*%coal_ind_buy%
echo Complete Table :
echo ################################
echo ## Coal Price Brutto  ##  %coal_price_buy_brt%  ##
echo ################################
echo ## Coal Index Buy ## %coal_ind_buy% ##
echo ################################
echo ## Coal Price Netto ## %coal_price_buy_net% ##
echo ################################

The file data are:

coal_price_buy_brt = 150
coal_ind_buy = 0.84

EDIT : 4 years after this post, i'm now in IT Studies and realize that there is a difference between integers and floats in coding... Thanks for having helped me back then !

ratouney
  • 49
  • 2
  • 9

5 Answers5

2

The arithmetic operations of SET /A command can only manage integer numbers. Imagine you have a calculator that does NOT have the key for decimal point. How could you achieve this operation: 150*0.84? Well, if you know that the second value is always less than one with two decimals, you may execute 150*84 instead and insert a decimal point before the second digit (from right to left) of the result:

@echo off
set coal_price_buy_brt=150
set coal_ind_buy=0.84

rem Convert coal_ind_buy to integer
set coal_ind_buy=%coal_ind_buy:0.=%

rem Execute the multiplication
set /A result=coal_price_buy_brt*coal_ind_buy

echo Result as integer: %result%
echo Result as fixed point with two decimals: %result:~0,-2%.%result:~-2%

If the values may have integer part, then you may achieve the appropriate conversion to integer values, execute the multiplication, and insert the decimal point in the right place; however, you always must select a fixed number of decimal places ("fixed point arithmetic"), unless you want to convert the values to floating point (with an exponent of ten) and achieve all the apropriate conversions!

For further details about fixed point arithmetic operations in Batch, see: http://www.dostips.com/forum/viewtopic.php?f=3&t=2704&p=12523#p12523

Aacini
  • 65,180
  • 12
  • 72
  • 108
2

You can call this batch file to do a mathematical evaluation.

Name it vbs.bat and then use call vbs 150*0.84 and the result will be in a variable called %val%

@echo off
>"%temp%\VBS.vbs" echo Set fso = CreateObject("Scripting.FileSystemObject") : Wscript.echo (%*)
for /f "delims=" %%a in ('cscript /nologo "%temp%\VBS.vbs"') do set "val=%%a"
del "%temp%\VBS.vbs"
foxidrive
  • 40,353
  • 10
  • 53
  • 68
2

I know this is an older question, but I have had a similar question come up with some scripting of my own. Perhaps my answer can still help someone out there with the same/similar question. My question to myself was, "How can use floating point decimal numbers in my batch script?" After much pondering and researching other personal questions on StackOverflow, I came up with the following example script. It pretty much converts a floating point number into a fraction in the form of two variables that can be used in the rest of your script. It can be used in tandem with this answer https://stackoverflow.com/a/20531384/2464491 to a similar question.

@echo off
setlocal EnableExtensions
setlocal EnableDelayedExpansion

REM This is how I do a block comment.
goto SOF
========Begin Comment========
Title:  deciTest.bat

This batch script checks to see if the number inputed is an interger or a floating point number.
If it is a floating point number, it determines to how many decimal places up to 4096 places.
It then informes the user of how to use the floating point number in arithmatic equations.
Of course, if you include within your script, you can simply call upon the !intOut! and
!multiplier! variables elswhere in your script.
=========End Comment=========


:SOF

REM Check to see if the user supplied a number.
if "%1"=="" (
    REM If not, tell them how to use the file.
    echo Usage: deciTest.bat [number]
    echo.
    echo [number]   The number to check.  Enter either an integer
    echo            or a floating point number.
    echo.
    goto eof
)

REM Assign the user input to variable decNum
set decNum=%1

REM Plop the number into a file
echo !decNum!>decNum.tmp

REM Check to see if there is a decimal point
findstr /c:"." decNum.tmp >null

REM If it is found, the number is a floating point number
REM So lets make it so we can use it.
if %errorlevel%==0 (
    REM Separate our Characteristic (before the .) and Mantissa (after the .)
    for /f "tokens=1-18* delims=." %%a in (decNum.tmp) do (
        REM Count the length of our Mantissa (How may decimal places?)
        set "s=%%b"
        set "s=!s!#"
        set "decPlaces=0"
        for %%P in (4096 2048 1024 512 128 64 32 16 8 4 2 1) do (
            if "!s:~%%P,1!" NEQ "" (
                set /a "decPlaces+=%%P"
                set "s=!S:~%%P!"
            )
        )
        REM Inform the user of our findings.
        echo %%a.%%b is a floating point number with !decPlaces! decimal places
        call :Integrate
        echo.
        REM Create the variable !intOUt! for use elswhere in the code
        set /a intOut=%%a*!multiple!+%%b
        REM Tell the user how to use this particular floating number
        echo Your batch file can use !intOut! in your arithmatic equations.
        echo Simply divide your result by !multiple!.
    )
) else (
    REM If it aint floatin', it's an integer
    echo %1 is an integer
)

goto eof

:Integrate  REM Create the !multiple! variable to be used elsewhere in the script
set count=!decPlaces!
set multiple=1

:startloop
    set /a multiple*=10
    set /a count-=1
    if not !count!==0 goto startloop

:eof

The code demonstrates how to handle floating point numbers. Essentially, it turns floating point numbers into fractions (!intOut!/!multipler!). If you adjust your arithmetic a bit. Multiply by !intOut!, then send !intOut!/!multiplier! with however many decimal places you want to the example script found here: https://stackoverflow.com/a/20531384/2464491

I hope this helps anyone who has run into the same problem when trying to work with floating point numbers in a batch script. Sure it's not designed to work with such numbers, but you can always script your way around the problem.

Community
  • 1
  • 1
1

Batch mathematics is INTEGER, hence 0.84 will either be interpreted as 0 or as an invalid number.

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • 2
    this is an integer --> `84` , and this is a decimal number --> `0.84` . `cmd` doesnt work with decimal numbers. – Endoro Jul 18 '13 at 17:16
1

You may use an hybrid Batch-JScript file as described in this answer: looking for a way to calculate logarithm in a DOS batch file

This method allows you to evaluate any floating point operation, including logarithms, square roots, etc.

@if (@CodeSection == @Batch) @then
@echo off

rem Evaluate floating point expressions via JScript, for example:
call :Expr result=%coal_price_buy_brt%*%coal_ind_buy%
echo %result%
goto :EOF

:Expr result=expression
for /F "delims=" %%a in ('Cscript //nologo //E:JScript "%~F0" "%2"') do set "%1=%%a"
exit /B

@end
WScript.Echo(eval(WScript.Arguments.Unnamed.Item(0)));

For further details on available JScript mathemathic operations, see: http://msdn.microsoft.com/en-us/library/ie/b272f386(v=vs.94).aspx

Community
  • 1
  • 1
Aacini
  • 65,180
  • 12
  • 72
  • 108