carlos-montiers / enhancedbatch

Enhances your windows command prompt https://www.enhancedbatch.com
Other
5 stars 1 forks source link

Enhanced math support #28

Open DaveBenham opened 4 years ago

DaveBenham commented 4 years ago

I have no idea how it would be implemented, but it would be nice if SET /A could be patched or an @extension could be made to provide support for 64 bit integers and or floating point math.

adoxa commented 4 years ago

That's what I'm doing next, probably next week. Still not sure exactly what I'm going to do, but variables that start and end with a bracket will be evaluated as an expression: echo %(2+2)%. The library I'm using has both 64-bit and double support. The intention is to read floats using either . or , as the separator; output will use @decsep. Haven't decided on digits, yet, either another variable to define the format (probably just a straight printf-style format), and/or something after the closing bracket.

DaveBenham commented 4 years ago

I suppose putting expressions within "expansion" can work. But having the ability to assign values to variables within the expression is mighty handy. Also, the ability to reference variables without expansion is also great.

The SET /A syntax and capabilities is one of the best implemented features of cmd.exe in my opinion, and worthy of emulating when adding long and/or floating point capability. I can't say that about any other cmd features.

For example, I was delighted to discover that something like

set /a "var4=((var1+=1)+(var2+=1))/(var3*=2)"

works exactly as expected.

Maybe you could add additional options to the existing SET command. Like /L for 64 bit computations, and /F for floating point. And automatic variable expansion could recognize environment variables, heap variables, and @extension values without the need for ! or % expansion.

adoxa commented 4 years ago

Variables are part of the calculator library, so that expression should work, too. Conditionals are there, too, so you could do something like if %(var >= 1.5)% == 1 .... Hm, I might even be able to hook IF and allow if (cond) ... so then you could simply use: if (var >= 1.5) ....

I was initially going to do something like that (but with /I for integer, or maybe just /C for calculator), but it depends how much hassle it's going to be to hook SET.

DaveBenham commented 4 years ago

I have often implemented crude conditionals by intentionally dividing by zero,

For example, issue new line every 5th iteration:

2>nul set /a "1/((n+=1)%%5)" || echo(

Or do an additional computation only every 5th iteration

2>nul set /a "1/((n+=1)%%5), a+=1"

But this does not support multiple conditions or else branches within the expression. A more elegant conditional construct would be welcome.

Another nice addition would be logical operators.

~, &, |, and ^ do bitwise logic.

There is the logical ! operator to convert any 0 value to 1 and non-zero to 0. It is trivial to use !! to convert any value into a boolean (0 stays 0, and non-zero becomes 1).

It would be nice to have logical &&, ||, and ^^, where each side would be converted to 0 or 1 before performing the operation, which would always result with 0 or 1.

adoxa commented 4 years ago

I think the calculator has boolean operators, but adding them to IF is way too complicated, unfortunately. Hm, I'll have to see about adding string comparisons to the calculator, that might be a simple workaround.