mIRC Home    About    Download    Register    News    Help

Print Thread
#271020 11/11/22 09:25 AM
Joined: Jan 2004
Posts: 1,944
maroon Offline OP
Hoopy frood
OP Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,944
This snippet is something I've used for a long time, which lets me get the result of math calculations from an editbox /command. I've updated it to also show the results from bigfloat mode. All it does is feed $1- to $calc, so things like mis-matched parenthesis can be why the answer is wrong. So, you can use a formula on the command line and see the results under doubles and bigfloat calculations. Here's an example showing 355/113 as an approximation of PI that's so close that doubles mode thinks they're the same. But bigfloat mode has enough precision to detect the difference.

/calc 355/113-$pi

I used [ ] instead of $eval() because the command line being 1/$pi returns the fraction from $calc( [ $1- ] ) but doesn't from $calc( $eval($1-,2) ) unless you make sure the /$ don't touch. There can be some differences caused by using double // instead of /. So the different result for the bigfloat row from "//calc 1/$log(2)" and "/calc 1/$log(2)" is because using // causes the identifier to evaluate in the editbox which lives in doubles mode, before the alias even sees the $1-, which causes the bigfloat calculations to only see the the 6 digit fraction. i.e. the result of in bf mode is different for 1/$log(2) than for 1/0.693147

And as always, be careful about what you do with the $calc output when using [] or $eval, as described at wikichip. i.e. //var %password 123foobar | calc %password

The bigfloat mode result for $bytes(number,b) is the same as the doubles mode result, which means "//echo -a %null.bf $bytes($calc(2^64),b)" would show zeroes in the lowest digits differently from the normal calculation, and the result for 2^1024 and above is '1'. So I used a regex pattern to modify the bigfloat 'num' string by adding the commas in the $bytes style, and I did the same the doubles mode result too, even though it probably doesn't change the result.

There are various behaviors that you may wish to change:
  • You can rename it to something shorter like /e for convenience
    .
  • Change the -gas if you want to go only to -ga active or -gs status window.
    .
  • I used green and red to identify the doubles and bigfloat results, because those seem to work well with background white or black, so your background color allows other choices
    .
  • If you ONLY want the more accurate results for numbers outside the 2^53 doubles range, you can comment-out the doubles rows, though it can be helpful in debugging scripts to see what doubles-mode thinks thinks the 'num' answer is, so you can decide which if any calculations need to be done as .bf variables
    .
  • If you don't want the hex results, that's why they call it a script editor.
    .
  • For a delimiter for fractions, I used reverse-colors for 2 reasons. First, I'm not aware of an actual convention for formatting fractions, but also this avoids altering copypaste.
    .
  • For the hex rows, I left-padded non-negatives to show them as byte even-length strings. If you don't like that, comment out the rows having the \\ in them.
    .
  • For a hex delimiter, I didn't want to use the same comma used by normal base10, so I ended up using apostrophes instead. Unless anyone knows of a different style for hex that's commonly used. While hyphens have been used for hex, I didn't want to use that if the output can be negative. These extra hex rows are likely to be the least useful for most users, and I just use them to get an eye-ball estimate of how they get split into 16-bit and 32-bit values. If you want to see them split into uint64's, that's easily done by cloning the row formatted for groups of 8 hex digits and change those to 16's.
  • The log_base2() result is there to get an estimate for the size of hex numbers, and also shows the effect that doubles-mode rounding has on the result. Both from the truncated log(num) result but also dividing by truncated log(2).


Code
alias calc {
  ; Editbox Calculator by maroon: /calc <string goes here>
  echo -agc notice /calc result of: $ $+ calc( $chr(91) $1- $chr(93) )
  ; avoids wrong result due to pasting from source containing tabs:
  var %1- $regsubex($1-,/([\s])/g,$chr(32))
  var %result.bx  $calc( [ %1- ] ) , %hex.bf $base(%result.bx,10,16)
  var %str  $gettok(%result.bx,1,46) , %frac $gettok(%result.bx,2,46)
  var %hex1 $gettok(   %hex.bf,1,46) , %hex2 $gettok(   %hex.bf,2,46)
  if ( (2 \\ $len(%hex1)) && (-* !iswm %hex1) ) var %hex1 0 $+ %hex1
  echo 3 -gas doubles num: %result.bx
  echo 3 -gas doubles byt: $regsubex(%str,/([0-9])(?=([0-9]{3})+$)/g,\1 $+ $chr(44)) $+ $iif(%frac,. $+ $regsubex($v1,/(.{3})(?=.)/g,\t $+ $chr(22)) )
  if ($+($version,.,$beta) >= 7.71.3337 ) echo 3 -gas doubles lg2: $calc( $log(%result.bx) / $log(2) )
  echo 3 -gas doubles hex: %hex1 $+ $iif(%hex2,. $+ $v1)
  echo 3 -gas doubles hx4: $regsubex(%hex1,/([0-9A-Faf])(?=([0-9A-Faf]{4})+$)/g,\1') $+ $iif(%hex2,. $+ $regsubex($v1,/(.{4})(?=.)/g,\t $+ $chr(22)) )
  echo 3 -gas doubles hx8: $regsubex(%hex1,/([0-9A-Faf])(?=([0-9A-Faf]{8})+$)/g,\1') $+ $iif(%hex2,. $+ $regsubex($v1,/(.{8})(?=.)/g,\t $+ $chr(22)) )
  var %result.bf $calc( [ %1- ] ) , %hex.bf $base(%result.bf,10,16)
  var %str  $gettok(%result.bf,1,46) , %frac $gettok(%result.bf,2,46)
  var %hex1 $gettok(   %hex.bf,1,46) , %hex2 $gettok( %hex.bf,2,46)
  if ( (2 \\ $len(%hex1)) && (-* !iswm %hex1) ) var %hex1 0 $+ %hex1
  echo 4 -gas bigfloat num: %result.bf
  echo 4 -gas bigfloat byt: $regsubex(%str,/([0-9])(?=([0-9]{3})+$)/g,\1 $+ $chr(44)) $+ $iif(%frac,. $+ $regsubex($v1,/(.{3})(?=.)/g,\t $+ $chr(22)) )
  if ($+($version,.,$beta) >= 7.71.3337) echo 4 -gas bigfloat lg2: $log2(%result.bf)
  echo 4 -gas bigfloat hex: %hex1 $+ $iif(%hex2,. $+ $v1)
  echo 4 -gas bigfloat hx4: $regsubex(%hex1,/([0-9A-Faf])(?=([0-9A-Faf]{4})+$)/g,\1') $+ $iif(%hex2,. $+ $regsubex($v1,/(.{4})(?=.)/g,\t $+ $chr(22)) )
  echo 4 -gas bigfloat hx8: $regsubex(%hex1,/([0-9A-Faf])(?=([0-9A-Faf]{8})+$)/g,\1') $+ $iif(%hex2,. $+ $regsubex($v1,/(.{8})(?=.)/g,\t $+ $chr(22)) )
  return
}

Joined: Jan 2004
Posts: 1,944
maroon Offline OP
Hoopy frood
OP Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,944
Minor change to the calculator script. The problem affected only the cases where your math matched the kind of /set or /var math that they've done for years. The %result.bf was not being evaluated in bigfloat mode if the command line was: number operator number
... where the operator was any of +-*/^&%
And the fix is changing 1 line:

old:
Code
var %result.bf $calc( [ %1- ] ) , %hex.bf $base(%result.bf,10,16)

new:
Code

var %1-.bf $regsubex($1-,/([\s])/g,$chr(32)) , %result.bf $calc( [ %1-.bf ] ) , %hex.bf $base(%result.bf,10,16)



Link Copied to Clipboard