Problem
Is there a way to put a variable "to the power" of a number or other variable a batch file? Does a function exist for this? An example of this would be in Python where you can use ** for "to the power of".
EDIT
You can do maths in a batch file... http://en.wikipedia.org/wiki/Batch_file
The power to function is not available in batch scripting, as you may have already figured out from the answers.
One option is to use a loop. You can do the looping the way #Kirk Broadhurst did it last time he had to do the batch scripting, or you can use another way that has become available since then or otherwise may have gone unnoticed by Kirk:
:: calculate x^n
SET x=3
SET n=5
SET result=1
FOR /L %%i IN (1,1,%n%) DO SET /A result*=x
ECHO %result%
Another option is to use the approach described in this answer.
You don't have many maths functions / operators to work with, and you don't have proper loops either so you need to simulate these.
The basic algorithm for x^n
result = 1
for (i = 0 ; i < n; i++)
{
result = result * x;
}
In a batch file you'd need to use goto statements rather than a real loop.
set result=1
set i=1
:multiply
set /a result=result*x
set /a i=i+1
if %i% lss %n% goto multiply
This won't work for non-integer or negative / zero exponents, but you can work that out.
#echo off
:start
echo Set the value of the Base
set x=
set /p x=
echo set the power the Base is raised to
set n=
set /p n=
set y=%x%
If %n%==0 goto sol1
If %n%==1 goto solx
set /a n=%n%-1
set p=0
:eloop
set p=%P%
set /a p=%P%+1
set /a y=%y%*%x%
If %P%==%n% goto sol
goto :eloop
:sol1
set y=1
echo %y%
pause
goto :start
:solx
set y=%x%
echo %Y%
pause
goto start
:sol
set y=%y%
echo %y%
pause
goto start
This code works for all positive integers you select the base then the power the base is raised to it then loops the expression multiple times by adding 1 to a variable p until it matches a variable n multiplying x by itself each time then giving the solution it also gives a solution of %x% for n=1 and 1 for n=0.
I really like the answer by #Andriy, but I'd add one thing to make it a reusable function.
#echo off
CALL :pow 2 3 :: 8
CALL :pow 3 3 :: 27
CALL :pow 5 5 :: 3125
CALL :pow 256 3 :: 16777216
set /p=End of Script, press any key to exit...
GOTO :EOF
:: ----- Call Functions -----
:pow
SET pow=1
FOR /L %%i IN (1,1,%2) DO SET /A pow*=%1
ECHO %pow%
GOTO :EOF
P.S. You can also put the "functions" in files (for example "pow.bat", usage would be just "pow n n") and call them that way, which can be handy (especially if you start using the path variable). I've always found creating reusable functions in Batch to be the coolest but least known "feature" of the scripting language. Additionally, you'd be able to use the variable %pow% in your script (or assign it to another variable) until overwritten by calling the function again.
One last point I'd like to make is that while this is a fun exercise, there is a precision limitation to Batch.. I've found that batch fails to compute properly numbers greater than 2**31 (32 bit limitation).
Best!
Related
When generating a not explicitly generated version of a function, #ngenerate runs
eval(quote
local _F_
$localfunc # Definition of _F_ for the requested value of N
_F_
end)
Since eval runs in the scope of the current module, not the function, I wonder what is the effect of local in this context. As far as I know, the languange documentation only mentions the use of local inside function definitions.
To give some background why this question arose: I frequently need to code loops of the form
function foo(n::Int)
s::Int = 0
for i in 1:1000000000
for j in 1:n
s += 1
end
end
return s
end
where n <= 10 (of course, in my actual code the loops are such that they cannot just be reduced to O(1)). Because this code is very simple for the compiler but demanding at runtime, it turns out to be beneficial to simply recompile the loops with the required value of n each time foo is called.
function clever_foo(n::Int)
eval(quote
function clever_foo_impl()
s::Int = 0
for i in 1:1000000000
s += $(Expr(:call,:+,[1 for j in 1:n]...))
end
return s
end
end)
return clever_foo_impl()
end
However, I am not sure whether I am doing this the right way.
It's to prevent _F_ from being visible in the global method cache.
If you'll call clever_foo with the same n repeatedly, you can do even better by saving the compiled function in a Dict. That way you don't have to recompile it each time.
set /a var=2
(
set /a %var%=var * 2
set /a %var%=%var% * 2
set /a %var%*= 2
)
Why does it say its wrong?
I got messages like Missing operand and Missing operator.
Well, operator is there, though I don't know what's operand.
Yes I searched for answer in here, but non of all solves... St least ones that I saw.
You're misusing the % syntax. % means expand the contents of this variable, which is not what you want to do. You want to store the result of the calculation back into the variable. Just remove the % on the left side of the assignment operator.
Try this instead:
set /a var=2
#echo %var%
set /a var=%var% * 2
set /a var=%var% * 2
set /a var*= 2
#echo %var%
Thats all :)
set /a var=2
set /a var*=2
..value of %var% is 4.
see operand
I believe, that %var% is syntax for interpreter (shell) and it replaces %var% with value of that variable. And it should happen before any command is called.
Set works with environment variables, so it has to work with them and not their values.
Try set /a var = 2; set /a var = var * 2.
By the way, in "4 + 5" + is the operator and 4,5 are operands (arguments of operator).
I have a script where I am doing what appears to be the exact same thing, but it works in that one and not this one. I'm hoping that a few more pairs of eyes will be able to help me find out the issue, I've already spent an hour and a half on it.
I have a proc that edits the global var, it's more complex that this but I'll use this for simplicity's sake:
proc myCustomProc { var } {
global __myGlobal
set __myGlobal [ expr $__myGlobal + 1 ]
}
I have defined a variable globally in my "main" proc:
proc FOO {} {
global __myGlobal
...
...
myCustomProc 5
puts $__myGlobal
Then I get can't read "__myGlobal": no such variable
I have the exact code with a different varname working in a different script, so I'm stumped. Obviously it's NOT identical, I just cannot find the issue.
Edit: both procs are in the same .tcl file
You can't read from a variable that is unset, and that's true whether that variable is global or not. Thus, in the code:
set __myGlobal [ expr $__myGlobal + 1 ]
It first reads the value from the global variable, then adds one to that value, then writes the result back to the global variable. (Actually, it is interpreting the contents of the variable as an expression fragment, which I'd lay good money on being something you don't want as it is slow and unsafe; put the whole expression in braces please.)
For adding one to an integer (and from Tcl 8.5 onwards) you should just use the incr command instead, as that interprets a non-existent value as if it was zero:
incr __myGlobal
But if you're doing something more complex (or working in 8.4 or before), you should instead put a check with info exists like this in front:
if {![info exists __myGlobal]} {
set __myGlobal "the default value"; # Or whatever default you want
}
You could also use a more complex expression like this:
set __myGlobal [expr {[info exists __myGlobal] ? $__myGlobal+1 : 1}]
But I usually try to avoid the ternary operator; it's often not that readable.
The short answer is, you are using $__myGlobal in the expr command before it has been set.
I'm trying to write a batch file that performs operations depending on the result of a modulus operation performed on a set variable. However, I can't seem to get it quite right.
To first of all test my syntax for the mathematical operation, I've been trying to get a simpler script to produce desired results.
:START
SETLOCAL
SET /P Input-Num="Input Number: "
SET /A Input-Num=%Input-Num% %% 2
ECHO %Input-Num%
ENDLOCAL
PAUSE
:END
If I input 5, the expected output is 1. However, instead I get a message saying Missing operator. and then it outputs 5.
What am I doing wrong here?
Using SET /P is your problem, as 5 is no longer treated as a numerical value. Your example as above works as expected
Is it possible to have gdb log something to the terminal instead of breaking on it? For example I would like to set a 'breakpoint' on some method and have gdb print self as well as the parameters each time the method is invoked. Basically I want to insert print statements into arbitrary places without actually recompiling.
thanks for any suggestions
This is what i have so far after these helpful comments:
define logFoo
b fooMethod
commands
po self
end
end
GDB doesn't seem to like the nested end statements though. any thoughts?
You can use Breakpoint Command Lists. There is an example how to do it.
For example, here is how you could use
breakpoint commands to print the value
of x at entry to foo whenever x is
positive.
break foo if x>0
commands
silent
printf "x is %d\n",x
cont
end
Use a breakpoint as usual, and set a macro to log and continue:
define c
print "foo"
cont
c
end
No, this is not possible. You can only hook into the symbols of the code and machine code. If you want to log output you will need a logging functionality.
If you are tracing specific errors try conditional breakpoints and watch variables.
EDIT:
Even while not directly loggin it could be an alternative to use GDB command files