Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/expr?V=149
QUERY_STRINGV=149
CONTENT_TYPE
DOCUMENT_URI/revision/expr
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.69.58.213
REMOTE_PORT14960
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR3.15.149.45
HTTP_CF_RAY88636fd1b99b10f6-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_CF_CONNECTING_IP3.15.149.45
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

Body


Error

Unknow state transition: LINE -> END

-code

1

-level

0

-errorstack

INNER {returnImm {Unknow state transition: LINE -> END} {}} CALL {my render_wikit expr **\ Summary\ **\n\n'''expr'''\ -\ Evaluate\ an\ expression\n\n**\ Synopsis\ **\n\n'''expr'''\ ''arg''\ ?''arg\ arg\ ...''?\n\n\n\ \ \ \[http://www.tcl.tk/man/tcl/TclCmd/expr.htm%|%officieal\ reference\]:\ \ \ \n\[http://purl.org/tcl/home/man/tcl8.4/TclCmd/expr.htm%|%expr(n)\ manpage\]\ (Tcl\ 8.4)\n\ \ \ \[tcl_precision\]:\ \ \ \n\[http://purl.org/tcl/home/man/tcl8.5/TclCmd/expr.htm%|%expr(n)\ manpage\],\n\[http://purl.org/tcl/home/man/tcl8.5/TclCmd/mathfunc.htm%|%mathfunc(n)\ manpage\],\n\[http://purl.org/tcl/home/man/tcl8.5/TclCmd/mathop.htm%|%mathop(n)\ manpage\]\ \ (all\ Tcl\ 8.5)\n\n\n`expr`\ \[concat%|%concatentates\]\ its\ arguments,\ evaluates\ this\ result\ as\ a\ Tcl\ \n\[\[expr\]\]\ implements\ a\ mini\ language\ that\ has\ a\ syntax\ separate\ from\ the\ Tcl\nsyntax.\ \ It\ supports\ some\ of\ the\ same\ constructs\ as\ Tcl,\ such\ as\ variable\nsubstitution,\ command\ substitution,\ and\ braces.\ \ It\ adds\ additional\ syntax\ for\nmathematical\ operators\ and\ functions,\ and\ unlike\ Tcl,\ does\ not\ accept\ character\nstrings\ that\ are\ not\ enclosed\ in\ double\ quotes\ or\ brackets.\n`expr`\ implements\ a\ \[little\ language\]\ that\ has\ a\ syntax\ separate\ from\ \[Tcl\].\nexpr\ conditions\ (like\ those\ used\ in\ \[if\]\ or\ \[while\])\ take\ 0\ to\ mean\ false\ and\nall\ other\ numbers\ to\ mean\ true.\ In\ addition,\ the\ following\ string\ constants\ can\nbe\ used:\nA\ value\ recognized\ as\ boolean\ by\ `\[string\ is\]\ boolean...`\ can\ be\ used\ directly,\n\ \ \ *\ true,\ on,\ yes\n\ \ \ *\ false,\ off,\ no\nFunctions\ take\ the\ form,\nman\ Tcl_GetBoolean:\ \"Any\ of\ these\ values\ may\ be\ abbreviated,\ and\ upper-case\nspellings\ are\ also\ acceptable.\"\n\nBeware\ that\ if\ you\ need\ code\ to\ run\ in\ Tcl\ releases\ as\ old\ as\ 8.3,\ you\ have\ to\nquote\ these\ if\ you\ use\ them\ directly\ as\ constants,\ as\ \[Donald\ Porter\]\ noted:\n''\[\[expr\]\]\ tries\ to\ interpret\ \"bare\"\ strings\ as\ function\ names,\ such\ as\ncos(\$x).\ \ You\ must\ quote\ the\ string\ \"true\".\ \ Then\ it\ behaves\ as\ you\ expect\ in\n8.3.3.''\ \ \n\ \ \ \ :\ \ \ ''name''`(`''argument''`,`''argument\ ...'')`\nRefer\ to\ the\ Operands\ section\ of\ the\n\[http://www.tcl.tk/man/tcl8.4/TclCmd/expr.htm#M5%|%expr\ man\ page%|%\]\ for\ the\nsyntax\ rules.\n\n\n======\n'''expr'''\ \[concat\]enates\ each\ ''arg''\ (adding\ separator\nspaces\ between\ them),\ evaluates\ the\ result\ as\ a\ \[Tcl\]\ expression,\ and\ returns\nthe\ value.\ The\ operators\ permitted\ in\ Tcl\ expressions\ include\ most\ of\ the\noperators\ permitted\ in\ \[C\]\ expressions\ and\ a\ few\ aditional\ ones,\ \ and\ they\ have\nthe\ same\ meaning\ and\ precedence\ as\ the\ corresponding\ C\ operators.\ Expressions\nalmost\ always\ yield\ numeric\ results\ (integer\ or\ floating-point\ values).\ For\nexample,\ the\ expression:\n\nset\ val1\ 8.2\nset\ val2\ 6\nexpr\ \{\$val1\ +\ \$val2\}\nexpr\ \{\$val1\}\ +\ \$\{val2\}\n\nevaluates\ to\ 14.2.\n======\nThis\ is\ an\ equivalent\ way\ of\ writing\ the\ previous\ \[\[expr\]\]\ command:\nIn\ most\ cases,\ it's\ best\ to\ \[Brace\ your\ Expr-essions%|%brace\]\ or\ otherwise\nexpr\ \{\$val1+\$val2\}\n======\n\nThis\ allows\ `expr`\ to\ do\ the\ interpretation,\ rather\ than\ having\ Tcl\ interpret\nAny\ argument\ that\ can\ be\ interpreted\ in\ some\ way,\ e.g.,\ variable\ or\ a\ command\nexpansion,\ should\ be\ enclosed\ in\ brackets.\ \ This\ allows\ the\ \[\[expr\]\]\ command\ to\ndo\ the\ interpretation,\ rather\ than\ having\ the\ caller\ interpret\ the\ arguments\nbefore\ handing\ them\ off\ to\ \[\[expr\]\].\ \ See\ below\ for\ more\ details.\n`expr`\ expressions\ differ\ from\ \[C\]\ expressions\ in\ the\ way\ that\ operands\ are\n\[Tcl\]\ expressions\ differ\ from\ C\ expressions\ in\ the\ way\ that\noperands\ are\ specified.\ \ They\ also\ include\ some\ non-numeric\ operators\ for\nstrings\ (comparison)\ and\ lists\ (membership).\n\n\n\nSince\ Tcl\ 8.5,\ many\ operators\ have\ command-equivalents\ in\ the\nIn\ spite\ of\ the\ name\ '''mathop''',\ some\ of\ the\ operators\ are\ string-oriented,\ rather\nNote\ that\ many\ operators\ have\ command-equivalents\ in\ the\ \[namespace\]\ '''::\[tcl::mathop\]'''\ from\ Tcl\ 8.5\ onwards.\nThe\ following\ is\ a\ chart\ of\ operators,\ in\ order\ of\ precedence\ (tightest-binding\n\[\[The\ term\ '''mathop'''\ is\ a\ misnomer,\ since\ some\ of\ the\ operators\ included\ in\ this\ namespace\ are\ string,\ rather\ than\ math,\ oriented...\]\]\n&|\ \[-\]\ \[+\]\ \[~\]\ \[!\]\ |\ Unary\ operators\;\ specifically\ a\ negation\ operation,\ a\ non-negation\ operation,\ a\ bit-wise\ NOT\ operation\ (every\ bit\ in\ the\ input\ value\ gets\ replaced\ by\ its\ inverse)\ and\ a\ logical\ NOT\ operation\ (non-zero\ maps\ to\ zero,\ and\ zero\ maps\ to\ one).\ |&\nThe\ '''expr'''\ operators,\ in\ order\ of\ precedence\ (tightest-binding\ to\ least-tight\ binding),\ are:\n\n&|\ \[-\]\ \[+\]\ \[~\]\ \[!\]\ |\ Unary\ operators\;\ specifically\ a\ negation\ operation,\ a\ non-negation\ operation\ (I\ see\ little\ point\ in\ this\ one),\ a\ bit-wise\ NOT\ operation\ (every\ bit\ in\ the\ input\ value\ gets\ replaced\ by\ its\ inverse)\ and\ a\ logical\ NOT\ operation\ (non-zero\ maps\ to\ zero,\ and\ zero\ maps\ to\ one.)\ |&\n&|\ \[+\]\ \[-\]\ |\ Addition\ and\ subtraction.\ |&\n&|\ \[<<\]\ \[>>\]\ |\ Left\ and\ right\ shift.\ \ Equivalent\ to\ multiplying\ or\ dividing\ by\ a\ suitable\ power\ of\ two,\ and\ then\ reducing\ the\ result\ to\ the\ range\ representable\ in\ an\ integer\ on\ the\ host\ platform.\ |&\n&|\ \[<\]\ \[>\]\ \[<=\]\ \[>=\]\ |\ Ordering\ relations:\ \ less\ than,\ greater\ than,\ less\ than\ or\ equal,\ greater\ than\ or\ equal.\ \ These\ operations\ work\ on\ strings\ as\ well\ as\ numbers,\ but\ where\ string\ comparison\ is\ intended,\ it\ is\ advisable\ to\ use\ the\ dedicated\ string\ comparison\ operators\ or\ \[string\ compare\]\ or\ \[string\ equal\]\ instead,\ \ as\ those\ are\ \ more\ predictable\ in\ the\ case\ of\ a\ string\ that\ looks\ like\ a\ number.\ \ For\ example,\ \[string\ equal\]\ considers\ \"6\"\ and\ \"06\"\ to\ be\ different\ strings,\ but\ the\ `expr`'\ operator\ `==`\ considers\ them\ to\ be\ equivalent\ numbers.|&\n&|\ \[<\]\ \[>\]\ \[<=\]\ \[>=\]\ |\ Ordering\ relations\ (less\ than,\ greater\ than,\ less\ than\ or\ equal,\ greater\ than\ or\ equal.)\ \ \ Note\ that\ these\ operations\ work\ on\ strings\ as\ well\ as\ numbers,\ but\ you\ are\ probably\ better\ off\ testing\ the\ result\ of\ \[string\ compare\]\ instead\ as\ that\ is\ more\ predictable\ in\ the\ case\ of\ a\ string\ that\ looks\ like\ a\ number.\ |&\n&|\ \[==\]\ \[!=\]\ |\ Equality\ and\ inequality.\ \ \ Note\ that\ these\ operations\ work\ on\ strings\ as\ well\ as\ numbers,\ but\ you\ are\ probably\ better\ off\ testing\ the\ result\ of\ \[string\ equal\]\ instead\ as\ that\ is\ more\ predictable\ in\ the\ case\ of\ a\ string\ that\ looks\ like\ a\ number.\ \ For\ example,\ \[string\ equal\]\ considers\ \"6\"\ and\ \"06\"\ to\ be\ different\ strings,\ but\ expr's\ ==\ considers\ them\ to\ be\ equivalent\ numbers.\ |&\n&|\ \[eq\]\ \[ne\]\ |\ (2004-07-08\ added):\ From\ Tcl\ 8.4\ on.\ The\ same\ as\ before,\ but\ arguments\ only\ strings.\ Will\ find\ \"6\"\ and\ \"06\"\ (as\ well\ as\ 1\ and\ 1.0)\ to\ be\ different.\ |&\n&|\ \[**\]\ |\ exponential.\ From\ Tcl\ 8.5\ on\ |&\n&|\ \[in\]\ \[ni\]\ |\ Item\ (argument\ 1)\ in/not\ in\ list\ (argument\ 2).\ New\ in\ Tcl\ 8.5\ |&\n&|\ \[^\]\ |\ Bit-wise\ exclusive\ OR.\ \ A\ bit\ is\ set\ in\ the\ result\ when\ the\ corresponding\ bit\ is\ set\ in\ ''precisely\ one''\ of\ the\ arguments.\ |&\n&|\ \[<<pipe>>\]\ |\ Bit-wise\ OR.\ \ \ A\ bit\ is\ set\ in\ the\ result\ when\ the\ corresponding\ bit\ is\ set\ in\ either\ of\ the\ arguments.\ |&\n&|\ \[&&\]\ |\ Logical\ AND.\ \ \ The\ result\ is\ `1`\ when\ both\ of\ the\ arguments\ true.\ and\ `0`\ otherwise.\ \ This\ operation\ is\ a\ ''short-circuiting''\ operation,\ and\ will\ only\ evaluate\ its\ second\ argument\ when\ the\ first\ argument\ is\ non-zero.\ \ This\ includes\ the\ expansion\ of\ Tcl\ commands\ in\ square\ brackets.\ \ Where\ Tcl\ seems\ not\ to\ be\ behaving\ as\ describe\ here,\ see\ \[double\ substitution\].\ |&\n&|\ \[&&\]\ |\ Logical\ AND.\ \ \ The\ result\ is\ a\ one\ (true)\ when\ both\ of\ the\ arguments\ are\ non-zero\ (true),\ and\ zero\ (false)\ otherwise.\ \ Note\ that\ this\ operation\ is\ a\ ''short-circuiting''\ operation,\ and\ will\ only\ evaluate\ its\ second\ argument\ when\ the\ first\ argument\ is\ non-zero.\ \ This\ includes\ the\ expansion\ of\ Tcl\ commands\ in\ square\ brackets,\ but\ this\ delay\ in\ evaluation\ only\ occurs\ if\ the\ whole\ expression\ is\ enclosed\ in\ curly\ braces.\ |&\n&|\ \[<<pipe>><<pipe>>\]\ |\ Logical\ OR.\ \ \ The\ result\ is\ a\ zero\ (false)\ when\ both\ of\ the\ arguments\ are\ zero\ (false),\ and\ one\ (true)\ otherwise.\ \ Note\ that\ this\ operation\ is\ a\ ''short-circuiting''\ operation,\ and\ will\ only\ evaluate\ its\ second\ argument\ when\ the\ first\ argument\ is\ zero.\ \ This\ includes\ the\ expansion\ of\ Tcl\ commands\ in\ square\ brackets,\ but\ this\ delay\ in\ evaluation\ only\ occurs\ if\ the\ whole\ expression\ is\ enclosed\ in\ curly\ braces.\ |&\n&|\ x'''?'''y''':'''z\ |\ If-then-else,\ as\ in\ C\ (where\ x,y,z\ are\ expressions).\ \ \ If\ the\ value\ x\ is\ non-zero\ (true)\ then\ the\ expression\ y\ is\ evaluated\ to\ produce\ the\ result,\ and\ otherwise\ the\ expression\ z\ is\ evaluated\ to\ produce\ the\ result.\ \ Note\ that\ this\ operation\ is\ a\ ''short-circuiting''\ operation,\ and\ will\ not\ evaluate\ expression\ y\ if\ x\ is\ zero\ (false)\ and\ will\ not\ evaluate\ expression\ z\ if\ x\ is\ non-zero\ (true).\ \ This\ includes\ the\ expansion\ of\ Tcl\ commands\ in\ square\ brackets,\ but\ this\ delay\ in\ evaluation\ only\ occurs\ if\ the\ whole\ expression\ is\ enclosed\ in\ curly\ braces.\ \ It\ is\ usually\ clearer\ and\ easier\ to\ maintain\ (and\ no\ slower\ -\ the\ generated\ bytecode\ is\ identical)\ to\ use\ the\ Tcl\ \[if\]\ command\ instead\ of\ this.\ |&\n\n\n\nSee\ the\ \[http://www.tcl.tk/man/tcl/TclCmd/mathfunc.htm%|%mathfunc\ man\ page\].\nSee\ the\ mathfunc\ man\ page,\ listed\ above,\ for\ the\ Tcl\ 8.5\ man\ page\ information\ on\ '''expr'''\ builtin\ functions.\nThe\ following\ is\ a\ list\ of\ builtin\ functions:\n***\ BUILTIN\ FUNCTIONS\ ***\n\ \ \ '''\[abs\]'''(x):\ \ \ Absolute\ value\ (negate\ if\ negative).\n\ \ \ '''\[abs\]'''(x):\ \ \ Absolute\ value\ (negate\ if\ negative.)\n\ \ \ '''\[acos\]'''(x):\ \ \ Inverse\ cosine\ (result\ in\ radians.)\n\ \ \ '''\[asin\]'''(x):\ \ \ Inverse\ sine\ (result\ in\ radians.)\n\ \ \ '''\[atan\]'''(x):\ \ \ Inverse\ tangent\ (result\ in\ radians.)\n\ \ \ '''\[atan2\]'''(y,x):\ \ \ Inverse\ tangent.\ \ Can\ handle\ cases\ which\ plain\ atan()\ can't\ (due\ to\ division\ by\ zero)\ and\ has\ a\ larger\ output\ range\ (result\ in\ radians.)\n\ \ \ '''\[bool\]'''(x):\ \ \ Accept\ any\ numeric\ value\ or\ string\ (acceptable\ to\ \[string\]\ is\ boolean),\ and\ return\ the\ corresponding\ boolean\ value\ 0\ or\ 1\n\n\ \ \ '''\[cos\]'''(x):\ \ \ Cosine\ (input\ in\ radians.)\n\ \ \ '''\[cosh\]'''(x):\ \ \ Hyperbolic\ cosine.\n\n\ \ \ '''\[entier\]'''(x):\ \ \ Take\ any\ numeric\ value\ and\ return\ the\ integer\ part\ of\ the\ argument,\ as\ an\ unlimited\ value\ string\n\ \ \ '''\[exp\]'''(x):\ \ \ Exponential\ function.\ \ Returns\ e**inputValue\ (using\ the\ FORTRAN-style\ notation)\ where\ e\ is\ the\ base\ of\ natural\ logarithms.\n\ \ \ '''\[floor\]'''(x):\ \ \ Floor\ (defined\ over\ floating\ point\ numbers.)\ \ If\ the\ input\ value\ is\ not\ a\ whole\ number,\ return\ the\ next\ ''smaller''\ whole\ number.\ '''Surprise''':\ The\ return\ value\ is\ a\ float,\ not\ an\ integer.\n\ \ \ '''\[fmod\]'''(x,\ y):\ \ \ Floating\ point\ remainder\ of\ x\ divided\ by\ y.\n\ \ \ '''\[hypot\]'''(x,y):\ \ \ Hypotenuse\ calculator.\ \ If\ the\ projection\ of\ a\ straight\ line\ segment\ onto\ the\ X\ axis\ is\ x\ units\ long,\ and\ the\ projection\ of\ that\ line\ segment\ onto\ the\ Y\ axis\ is\ y\ units\ long,\ then\ the\ line\ segment\ is\ hypot(x,y)\ units\ long\ (assuming\ boring\ old\ Euclidean\ geometry.)\ \ Equivalent\ to\ sqrt(x*x+y*y).\n\ \ \ '''\[int\]'''(x):\ \ \ Convert\ number\ to\ integer\ by\ truncation.\n\ \ \ '''\[isqrt\]'''(x):\ \ \ Compute\ the\ integer\ part\ of\ the\ square\ root\ of\ x.\n\n\n\ \ \ '''\[max\]'''(x,...):\ \ \ Return\ the\ one\ argument\ with\ the\ greatest\ value\n\ \ \ '''\[min\]'''(x,...):\ \ \ Return\ the\ one\ argument\ with\ the\ least\ value\n\ \ \ '''\[pow\]'''(x,y):\ \ \ Power\ function.\ \ In\ FORTRAN\ notation,\ x\[**\]y.\n\n\n\ \ \ '''\[sin\]'''(x):\ \ \ Sine\ (input\ in\ radians.)\n\n\ \ \ '''\[sqrt\]'''(x):\ \ \ Square\ root\ (well,\ the\ positive\ square\ root\ only.\ \ And\ Tcl\ doesn't\ do\ complex\ math,\ so\ the\ input\ had\ better\ be\ positive...)\n\n\n\n\n\n\n**\ Mathematical\ Expressions\ **\n\n\nSimple\ addition:\n\n======\nset\ a\ \[expr\ \{1\ +\ 2\}\]\n======\n\nmathematical\ functions\n\n======\nset\ a\ \[expr\ \{sqrt(4)\}\]\n======\n\n\[martin\ Lemburg\]:\ The\ following\ returns\ `1`\ because\ `\"\ 2\ \"`\ will\ be\ interpreted\n\[martin\ Lemburg\]:\ returns\ 1,\ because\ \[\[expr\]\]\ \"\ 2\ \"\ will\ be\ converted\ to\ 2\n======\nset\ a\ \[expr\ \{\"\ 2\ \"\ ==\ \[string\ trim\ \"\ 2\ \"\]\}\]\n======\n\nTo\ ensure\ that\ expression\ evaluates\ to\ a\ floating\ point\ number,\ use\ `double()`\nTo\ ensure\ that\ expression\ evaluates\ to\ a\ floating\ point\ number,\ use\ an\ \[\[expr\]\]\nlike\ ''double()'':\nset\ a\ 1\nset\ b\ 2\nexpr\ \{double(\$a)/\$b\}\n======\n\nor,\ to\ get\ an\ integer:\n\nexpr\ \{entier(\$a/\$b)\}\n======\n\n`int()`\ would\ also\ have\ worked,\ but\ `entier()`\ is\ more\ general\n''int()''\ would\ also\ have\ worked,\ but\ ''entier()''\ is\ more\ general\n\n\nThe\ following\ returns\ returns\ 4,\ rather\ than\ -4\ as\ some\ might\ expect:\n\n======\nset\ a\ \[expr\ \{-2**2\}\]\n======\n\nThe\ following\ returns\ `1`\ because\ `2==2`\ is\ evaluated\ first:\nreturns\ 1\ because\ 2==2\ is\ evaluated\ first\nset\ a\ \[expr\ \{5&2==2\}\]\n======\n\n\[AMG\]:\ The\ order\ of\ bitwise\ operations\ (`|`,\ `&`,\ and\ `^`)\ may\ seem\ totally\ bogus,\ but\ it's\ inherited\ from\ \[C\],\ which\ in\ turn\ inherited\ it\ from\ an\ early\ prototype\ version\ of\ C\ which\ lacked\ separate\ logical\ operators\ (`&&`\ and\ `||`)\ \[http://cm.bell-labs.com/who/dmr/chist.html\].\ I\ wouldn't\ cry\ if\ a\ new\ language\ (not\ Tcl)\ decided\ to\ break\ compatibility\ with\ C\ in\ this\ respect.\n**\ String\ Operands\ **\n\n\[\[expr\]\]\ tries\ to\ interpret\ operands\ as\ numeric\ values,\ but\ it\ does\ not\ try\ to\nrecognize\ complete\ numeric\ epxressons,\ so\ a\ value\ \"2*3\"\ will\ be\ interpreted\ as\na\ string:\n======\nset\ y\ 2*3\;\ expr\ \{\$y\}\ \ \ \;#\ ==>\ 2*3\nset\ y\ 2*3\;\ puts\ \[expr\ \{\$y\}\]\ \;#\ \ ==>\ 2*3\nset\ y\ 2*3\;\ puts\ \[expr\ \{\$y+0\}\]\ \;#\ ==>\ can't\ use\ non-numeric\ string\ as\ operand\ of\ \"+\"\n\nTo\ pass\ a\ complete\ expression\ stored\ in\ a\ variable,\ omit\ the\ braces\ so\ that\ Tcl\n\n`expr`\ implements\ a\ little\ language\ distinct\ from\ the\ language\ described\ in\ \[dodekalogue%|%the\ rules\ of\ Tcl\].\ \ One\n\[expr\]\ implements\ a\ little\ language\ distinct\ from\ standard\ Tcl.\ \ One\ difference\nis\ that\ \[expr\]\ requires\ strings\ to\ be\ quoted:\n======none\n%\ \ if\ \{joe\ eq\ mike\}\ \{puts\ wow\}\nsyntax\ error\ in\ expression\ \"joe\ eq\ mike\":\ variable\ references\ require\ preceding\ \$\n%\ \ if\ \{\"joe\"\ eq\ \"mike\"\}\ \{puts\ wow\}\n%\ \ if\ \{\"joe\"\ eq\ \"mike\"\}\ \{puts\ \"wow\"\}\n%\ \ if\ \{\{joe\}\ eq\ \{mike\}\}\ \{puts\ \{wow\}\}\n%\n\nTo\ insert\ a\ literal\ value\ when\ templating\ an\ expression,\ use\ an\ \[identity\nIf\ \[expr\]\ syntax\ was\ the\ same\ as\ Tcl\ syntax,\ a\ Tcl\ ''bareword''\ string\ would\ be\ accepted,\ but\ it\ is\ not.\n\nNormal\ Tcl\ syntax,\ of\ course,\ does\ not\ requireThere\ are\ other\ cases\ in\ Tcl\nwhere\ this\ quoting\ need\ not\ happen.\n======\n%\ puts\ wow\nwow\n%\ set\ a\ abc\nabc\n%\n======\n\nIf\ you\ prefer\ consistency,\ then\ always\ quote\ the\ strings,\ but\ note\ that\ at\ some\npoint\ \[expr\]\ may\ grow\ the\ feature\ of\ accepting\ bareword\ strings.\n\n\n\nIf\ the\ return\ value\ of\ `expr`\ is\ numeric,\ it\ is\ transformed\ into\ a\ canonical\nIf\ the\ value\ of\ an\ \[expr\]\ is\ numeric,\ it\ will\ transformed\ into\ a\ canoncial\ numeric\ form:\n======\nset\ val\ 0x10\nputs\ \$val\ \;#\ 0x10\nset\ val\ \[expr\ \{\$val\}\]\nputs\ \$val\ \;#\ 16\n======\n\n======\n\nputs\ \[expr\ \{\[join\ \{0\ x\ 1\ 0\}\ \{\}\]\}\]\ \;#\ 16\n======\n\n\nIn\ other\ words,\ `expr`\ may\ mutate\ strings\ that\ can\ be\ interpreted\ as\nIn\ other\ words,\ \[expr\]\ may\ mutate\ strings\ that\ can\ be\ interpreted\ as\ numbers,\nwhich\ is\ a\ potential\ gotcha\ for\ the\ programmer\ using\ string\ functions\ of\ \[expr\]\nwhile\ not\ considering\ that\ they\ may\ have\ a\ numeric\ interpretation.\n\n\n`expr`\ uses\ floating\ point\ arithmetic,\ so\ strings\ representing\ decimal\n\[\[expr\]\]\ usese\ floating\ point\ arithmetic,\ so\ strings\ representing\ decimal\nto\ a\ close-enough\ representation.\ \ In\ the\ following\ example,\ `36.37`\ gets\ a\nto\ a\ close-enough\ floating-point\ representation.\ \ In\ the\ following\ example,\n\"36.37\"\ gets\ a\ floating-point\ representation\ that\ approaches\ 36.37:\ \n======\nexpr\ \{int(36.37*100)\}\n======\n\nIf\ that\ value\ is\ subsequently\ used\ as\ a\ string,\ it\ becomes\ necessary\ to\ somehow\nconvert\ it.\ \ Over\ the\ years,\ the\ default\ string\ conversion\ has\ varied.\ \ For\ Tcl\nversion\ 8.5.13,\ it\ looks\ like\n\n======none\n3636.9999999999995\n======\n\n\[RS\]\ points\ out\ that\ version\ 8.4.9\ provided\ the\ following\ results,\ and\ that\n\[RS\]\ points\ out\ that\ for\ version\ 8.4.9,\ provided\ the\ following\ results,\ and\nthat\ that\ braced\ or\ not,\ \[expr\]\ returns\ the\ same\ (string\ rep\ of)\ double\ as\ well\nas\ int()\ result,\ so\ the\ issue\ of\ bracing\ one's\ expressions\ is\ not\ relevant\ to\nthe\ issue\ of\ floating-point\ to\ string\ conversion.\n======none\n%\ expr\ 36.37*100\n3637.0\ \;#--\ good\ enough...\n%\ expr\ \{36.37*100\}\n3637.0\ \;#--\ the\ same\n%\ expr\ \{int(36.37*100)\}\n3636\ \ \ \;#--\ Hmm\n%\ expr\ int(36.37*100)\n3636\ \ \ \;#--\ the\ same\n%\ info\ pa\n8.4.9\n======\n\nOne\ way\ to\ get\ `3637`\ would\ be\ to\ use\ `round()`:\nOne\ way\ to\ get\ \"3637\"\ would\ be\ to\ use\ ''round()'':\n======\nexpr\ \{round(36.37*100)\}\n======\n\n`\[format\]`\ can\ also\ be\ useful,\ but\ the\ main\ point\ is\ to\ remain\nThe\ \[\[\[format\]\]\]\ command\ can\ also\ be\ useful,\ but\ the\ main\ point\ is\ that\ the\nprogrammer\ must\ be\ aware\ of\ their\ context\ and\ decide\ if\ and\ how\ to\ use\nfloating-point\ operations\ the\ context\ of\ the\ program.\n\[LV\]:\ \ My\ response\ on\ \[comp.lang.tcl\]\ was\ that\ I\ thought\ it\ was\ a\ shame\n\[LV\]\ My\ response\ on\ \[comp.lang.tcl\]\ was\ that\ I\ thought\ it\ was\ a\ shame\nthat\ expr\ (or\ perhaps\ it\ is\ Tcl)\ didn't\ use\ the\ same\ mechanism\ for\nbe\ consistent.\ \ Even\ if\ they\ were\ consistently\ '''wrong''',\ one\ would\nbe\ able\ to\ at\ least\ to\ live\ within\ the\ ''law\ of\ least\ surprise''.\nAs\ it\ is,\ until\ one\ experiments,\ one\ won't\ know\ which\ way\ that\ Tcl\nis\ going\ to\ ''round''\ results.\n\n\[EPSJ\]:\ \ This\ may\ be\ a\ side\ effect\ of\ the\ IEEE\ floating\ point\ standard.\ This\ is\n\[EPSJ\]\ This\ may\ be\ a\ side\ effect\ of\ the\ IEEE\ floating\ point\ standard.\ This\ is\nalgorithms.\ The\ rule\ is\ that\ the\ mantissa\ of\ a\ floating\ point\ number\ must\ be\nrounded\ to\ the\ nearest\ even\ number.\ As\ 36.37\ cannot\ be\ represented\ exactly\ in\nfloat\ point\ it\ ends\ up\ being\ a\ small\ fraction\ below\ the\ intended\ number.\ On\ the\nother\ side\ 36.38\ moves\ on\ the\ other\ direction.\ Look\ the\ following\ result:\n\n======none\n\ ()\ 60\ %\ expr\ int(36.380*100)\n\ 3638\n\ ()\ 61\ %\ expr\ int(36.370*100)\n\ 3636\nx86\ floating\ point\ hardware\ allows\ this\ to\ be\ configurable\ to\ nearest\ even,\nnearest\ odd,\ and\ a\ few\ more\ options.\ But\ usually\ nearest\ even\ is\ the\ default.\nThe\ result\ may\ seem\ inconsistent,\ but\ it\ is\ intentional.\n\n\n**\ pow()\ vs\ **\n**\ pow()\ vs\ **\ **\n\[LES\]\ 2005-07-23:\n\[LES\]\ on\ July\ 23\ 2005:\n\ %\ expr\ pow(5,6)\n\ 15625.0\n======none\n\ %\ expr\ 5**6\n\ 15625\n%\ expr\ 5**6\nTwo\ syntaxes,\ two\ slightly\ different\ results.\ Is\ that\ intentional?\ \[RS\]\ Yes\ -\ while\ pow()\ always\ goes\ for\ double\ logarithms,\ '**'\ tries\ to\ do\ integer\ exponentiation\ where\ possible.\nTwo\ syntaxes,\ two\ slightly\ different\ results.\ Is\ that\ intentional?\n\n\[davou\]:\ What\ is\ the\ precision\ of\ functions\ in\ `expr`,\ and\ how\ can\ it\ be\n\[davou\]\ what\ is\ the\ precision\ of\ expr's\ functions,\ and\ how\ can\ it\ be\ expanded\ upon?\n\[Lars\ H\]:\ That's\ generally\ determined\ by\ the\ \[C\]\ library\ functions\ that\nimplement\ them.\ It\ depends\ on\ where\ (and\ against\ what)\ Tcl\ is\ compiled.\ \ For\nimplement\ them,\ i.e.,\ it\ depends\ on\ where\ (and\ against\ what)\ Tcl\ is\ compiled.\nFor\ \"real\"\ numbers\ that\ means\ '''double'''s,\ which\ are\ floating-point\ numbers\nof\ typically\ about\ 17\ decimal\ digits\ precision\ (but\ how\ many\ of\ these\ are\ncorrect\ varies\ between\ functions\ and\ platforms).\ For\ integers\ Tcl\ has\ntraditionally\ used\ '''long'''s,\ which\ in\ most\ cases\ means\ 32-bit\ two's\ncomplement\ integers\ (\$tcl_platform(wordSize)\ tells\ you\ the\ actual\ number\ of\nbytes),\ but\ as\ of\ Tcl\ 8.5\ it\ supports\ (almost)\ arbitrarily\ large\ integers\n(\[googol\ magnitude\]\ is\ no\ problem\ anymore,\ whereas\ googolplex\ magnitude\nwouldn't\ fit\ in\ the\ computer\ memory\ anyway).\ As\ for\ extending\ what\ the\ core\nprovides,\ \[tcllib\]\ provides\ math::bignum\ and\ \[math::bigfloat\].\n\n**\ \[Nan\]\ and\ \[Inf\]\ **\n\n\nAt\ least\ as\ of\ Tcl\ 8.5,\ \[NaN\]\ and\ \[Inf\]\ are\ potential\ values\ returning\ from\nAt\ least\ as\ of\ Tcl\ 8.5,\ \[NaN\]\ and\ \[Inf\]\ are\ potential\ values\ returning\ from\ expr.\n\[Philip\ Smolen\]\ I've\ never\ seen\ expr\ return\ NaN.\ \ I\ wish\ it\ would!\n======\n**\ Interactions\ with\ \[locale\]\ **\n\n**\ Interactions\ with\ `\[locale\]`\ **\nexpr's\ parsing\ of\ decimals\ may\ be\ hampered\ by\ \[locale\]\ -\ you\ might\ get\ an\n\n\n\n`expr`\ concatenates\ its\ arguments\ into\ an\ expression.\ \ Consider\ the\ following\n\[expr\]\ resolves\ variables\ in\ the\ context\ of\ its\ caller,\ and\ each\ variable\ value\nbecomes\ exactly\ one\ operand\ in\ the\ expression.\ \ Consider\ the\ following\n======\nexpr\ 5\ >\ \{\}\ \;#\ ->\ missing\ operand\ at\ _@_\nset\ color2\ green\n\nexpr\ \{\$color1\}\ eq\ \{\$color2\}\ \;#\ 1\n\nConcatenated,\ the\ arguments\ form\ the\ script,\ `green\ eq\ green`,\ in\ which\ the\ two\nBut\ if\ the\ arguments\ are\ not\ bracketed,\ there\ is\ an\ error\ in\ the\ expression\ syntax:\nAnother\ example\ illustrating\ the\ same\ point:\n======\n#wrong\nexpr\ \$color1\ eq\ \$color2\n======\n======none\ninvalid\ bareword\ \"green\"\nin\ expression\ \"green\ eq\ green\"\;\nshould\ be\ \"\$green\"\ or\ \"\{green\}\"\ or\ \"green(...)\"\ or\ ...\n======\n\nThis\ is\ because\ in\ \[\[expr\]\]\ syntax,\ strings\ should\ be\ quoted\ or\ bracketed\n\n\n======none\nset\ a\ \"abc\"\nexpr\ \$a\ in\ \$b\n#\ invalid\ bareword\ \"abc\"\n#\ in\ expression\ \"abc\ in\ 123\ abcd\ xyz\ lmnop\"\;\n#\ should\ be\ \"\$abc\"\ or\ \"\{abc\}\"\ or\ \"abc(...)\"\ or\ ...\n\nexpr\ \{\$a\ in\ \$b\}\ \;#->\ 0\nexpr\ \{\$a\ in\ \$b\}\n#\ 0\nexpr\ \{\$a\ ni\ \$b\}\ \;#->\ 1\nexpr\ \{\$a\ ni\ \$b\}\n#\ 1\n======\n%\ expr\ \$a\ ==\ \"foo\"\ ?\ true\ :\ false\n%\ expr\ \{\$a\ eq\ \"foo\"\ ?\ true\ :\ false\}\n%\ expr\ \{\$a\ ==\ \"foo\"\ ?\ true\ :\ false\}\n======\n\n\n\n\nWhen\ exactly\ one\ unconcatenated\ value\ is\ passed\ to\ `expr`,\ the\ argument\ can\ be\n\nIn\ addition,\ \[\[expr\]\]\ is\ usually\ much\ more\ performant\ when\ its\ non-literal\narguments\ are\ braced,\ since\ this\ allows\ byte-compilation.\n'''Fast:'''\n======\n\n\[AMG\]:\ The\ security\ problems\ of\ unbraced\ `expr`essions\ are\ very\ similar\ to\n\n\[AMG\]:\ The\ security\ problems\ of\ unbraced\ \[expr\]\ expressions\ are\ very\ similar\ to\n\[SQL\]\ injection\ attacks.\ \ Notice\ how\ \[sqlite\]'s\ \[Tcl\]\ binding\ does\ its\ own\nthis\ problem\ as\ well\ because\ the\ default\ is\ to\ apply\ multiple\ passes\ of\ninterpretation.\n\nSee\ also\ \[double\ substitution\].\n\n\ninput:\n\n======\n#DON'T\ EXECUTE\ THIS\ SCRIPT!!!\nset\ x\ \{\[exec\ format\ C:\\\\\]\}\nset\ j\ \{\[puts\ Sucker!\]\}\n#C:\\\ get\ formatted\ in\ the\ next\ command\nset\ k\ \[expr\ \$x\ /\ \$j.\]\n======\n\nOn\ the\ other\ hand,\n\n======\nset\ k\ \[expr\ \{\ \$x\ /\ double(\$j)\ \}\]\n======\n\ngives\ a\ much\ more\ reasonable\ result:\n\n======none\nargument\ to\ math\ function\ didn't\ have\ numeric\ value\n\ \ \ while\ executing\n\"expr\ \{\ \$x\ /\ double(\$y)\ \}\"\n\ \ \ invoked\ from\ within\n\"set\ k\ \[expr\ \{\ \$x\ /\ double(\$y)\ \}\]\n\"\n\ \ \ \ (file\ \"foo.tcl\"\ line\ 3)\n\n======\n\n\n\n**\ The\ \"Dot\"\ Trick\ for\ Unbraced\ Expressions\ **\nUnless\ you\ know\ exactly\ what\ you\ are\ doing,\ unbraced\ expressions\ are\ not\nrecommended.\ \ Nevertheles...\n\nWith\ unbraced\ expressions,\ `.`\ (`\\x2e`)\ can\ be\ appended\ to\ a\ variable\ to\ get\ `expr`\nWith\ unbraced\ expressions,\ a\ \".\"\ can\ be\ appended\ to\ a\ variable\ to\ get\ \[\[expr\]\]\nto\ interpret\ the\ value\ as\ a\ float,\ but\ the\ ''double()''\ function\ is\ a\ better\nalternative:\n======\nset\ x\ 1\;\ set\ j\ 2\n\n#\ works\ (but\ don't\ do\ this)\nexpr\ \$x/\$j.\n\n#an\ accepted\ way\ to\ do\ it\nexpr\ \{double(\$x)/\$j\}\n\n#\ error:\ syntax\ error\ in\ expression\ \"\$x/\$j.\"\ \ (expr\ parser)\nexpr\ \{\$x/\$j.\}\n======\n\nIt's\ faster,\ too:\n\n======\nset\ script1\ \{\n\ \ \ set\ x\ 1\n\ \ \ set\ j\ 2\n\ \ \ set\ k\ \[expr\ \$x\ /\ \$j.\]\n\}\nset\ script2\ \{\n\ \ \ set\ x\ 1\n\ \ \ set\ j\ 2\n\ \ \ set\ k\ \[expr\ \{\ \$x\ /\ double(\$j)\ \}\]\n\}\nforeach\ v\ \{script1\ script2\}\ \{\nforeach\ v\ \{\ script1\ script2\ \}\ \{\n\}\n\n#script1:\ 38\ microseconds\ per\ iteration\n#script2:\ 9\ microseconds\ per\ iteration\n\n#\[pyk\]\ 2012-11-28:\ what\ a\ difference\ a\ few\ years\ makes\ (an\ \"old\"\ 3.06Ghz\ Intel\ Core\ 2\ Duo):\n#script1:\ 4.4767364\ microseconds\ per\ iteration\n#script2:\ 0.7374299\ microseconds\ per\ iteration\n======\n\n----\n\n\[RS\]:\ This\ was\ just\ to\ demonstrate\ the\ differences\ between\ the\ regular\ Tcl\ parser\nand\ ''expr'''s\ parser,\ not\ recommended\ practice.\ Another\ example\ is\n\n======\nset\ op\ +\nset\ op\ \"+\"\n9\nexpr\ \{4\ \$op\ 5\}\nsyntax\ error\ in\ expression\ \"4\ \$op\ 5\"\n======\n\nSee\ the\ \[for\]\ page\ on\ a\ case\ where\ that\ helped.\nSee\ the\ `\[for\]`\ page\ on\ a\ case\ where\ that\ helped.\n**\ Bytecode\ compilation\ and\ performance\ **\n\n\nIn\ \[http://groups.google.com/group/comp.lang.tcl/browse_thread/thread/f873d6fab9f0e304%|%Embedded\ vs.\ separate\ commands\],\ 1992-12-38,\ \[JO\]\ published\ the\ voting\ results\ 37:8\ in\ favor\ of\ embedded\ functions()\ vs.\ separate\ \[\[commands\]\]\nOn\ 1992-12-28\ \[JO\]\ published\ the\ voting\ results\ 37\ :\ 8\ in\ favor\ of\ embedded\ functions()\ vs.\ separate\ \[\[commands\]\]\ -\ \[http://groups.google.com/groups?q=group:comp.lang.tcl+author:ousterhout&start=900&hl=de&lr=&newwindow=1&scoring=d&selm=1hn9tvINNqod%40agate.berkeley.edu&rnum=922\]\n\n**\ Dustbin\ **\nAddition\n'''(Outdated)\ Expr\ \[Gotchas\]'''\n\n\n======none\n\ %\ expr\ (1<<31)-1\n\ 2147483647\n%\ expr\ 2147483647\ +\ 2147483647\n\ %\ expr\ 2147483647\ +\ 2147483647\n\ -2\nMultiplication\n\n======none\n\ %\ expr\ sqrt((1<<31)-1)\n\ 46340.9500011\nexpr\ 46341*46341\n\ expr\ 46341*46341\n\ -2147479015\nThese\ are\ results\ of\ Tcl\ 8.4\ and\ older\ versions\ using\ a\ 32-bit\ representation\nThese\ are\ results\ of\ Tcl\ 8.4\ and\ older\ versions\ using\ a\ 32-bit\ representation\ for\ integers.\ \ Check\ out\ http://tip.tcl.tk/237\ ,\ an\ implemented\ \[TIP\]\ describing\ arbitrary-precision\ Integers\ for\ Tcl.\ This\ is\ available\ in\ Tcl\ 8.5.\nTcl\ 8.5\ features\ abritrary-precision\ integers.\ \ See\n\n\n**\ See\ Also\ **\n\n\n\ \ \ \[if\]:\ \ \ \n\ \ \ \[for\]:\ \ \ \n\ \ \ \[while\]:\ \ \ \n\ \ \ \[Brace\ your\ expr-essions\]:\ \ \ \n\ \ \ \[DebuggingExprCalls\]:\ \ \ \[rwm\]\ sometimes\ it\ is\ difficult\ to\ debug\ expr\ calls\ where\ the\ operands\ are\ variables.\ \[DebuggingExprCalls\]\ explains\ how\ to\ wrap\ expr\ to\ help\ with\ these\ cases.\n\ \ \ \[expr\ problems\ with\ int\]:\ \ \ limits\ of\ number\ representation\ (both\ integer\ and\ float)\ inherited\ from\ C\n\ \ \ \[Importing\ expr\ functions\]:\ \ \ use\ expr's\ functions\ without\ explicitly\ calling\ that,\ see\ \[Importing\ expr\ functions\].\n\ \ \ \[A\ real\ problem\]:\ \ \ \n\ \ \ \[Math\ function\ help\]:\ \ \ \n\ \ \ \[How\ can\ I\ do\ math\ in\ Tcl\]:\ \ \ \n\ \ \ \[Additional\ math\ functions\]:\ \ \ \n\ \ \ \[double\ substitution\]:\ \ \ \n\ \ \ \[Modeling\ COND\ with\ expr\]:\ \ \ Braced\ expressions\ can\ span\ several\ lines\n\ \ \ \[A\ little\ math\ language\]:\ \ \ adds\ features\ &\ sugar\ to\ expr\n\ \ \ \[compute\]:\ \ \ more\ sugar\ for\ expr\n\ \ \ \[Tcl\ help\]:\ \ \ \n\ \ \ \[Numerical\ Analysis\ in\ Tcl\]:\ \ \ \n\ \ \ TIP\ #123\ \[http://tip.tcl.tk/123\]:\ \ \ Adding\ an\ Exponentiation\ Operator\ to\ the\ expr\ Command\n\ \ \ TIP\ #174\ \[http://tip.tcl.tk/174\]:\ \ \ \[Math\ Operators\ as\ Commands\]\n\ \ \ TIP\ #182\ \[http://tip.tcl.tk/182\]:\ \ \ Add\ 'expr\ bool'\ Math\ Function\n\ \ \ TIP\ #201\ \[http://tip.tcl.tk/201\]:\ \ \ Add\ 'in'\ Operator\ to\ expr\n\ \ \ TIP\ #232\ \[http://tip.tcl.tk/232\]:\ \ \ Creating\ New\ Math\ Functions\ for\ the\ 'expr'\ Command\ (\[tcl::mathfunc\])\n\ \ \ TIP\ #237\ \[http://tip.tcl.tk/237\]:\ \ \ Arbitrary-Precision\ Integers\ for\ Tcl\n\n**\ Half-Bakery\ **\n\n\[RS\]\ suggests\ expr's\ arguments\ could\ be\ reparsed\ so\ that\ full\ mathematical\n\n\[RS\]\ 2003-04-24:\ Here's\ a\ tiny\ wrapper\ for\ friends\ of\ infix\ assignment:\n\n======none\nproc\ let\ \{var\ =\ args\}\ \{\n\ \ \ \ uplevel\ 1\ set\ \$var\ \\\[expr\ \$args\\\]\n\}\ \;#RS\n======\n\n======none\n%\ let\ i\ =\ 1\n1\n%\ let\ j\ =\ \$i\ +\ 1\n2\n%\ let\ k\ =\ \{\$i\ +\ \$j\}\n3\n======\n\n======\nset\ y\ 2*3\;\ puts\ \[expr\ \$y+0\]\ \;#\ ==>\ 6\n======\n\n\[AM\]:\ The\ problem\ with\ variables\ whose\ values\ are\ actually\ expressions\ is\ that\n\[AM\]\ The\ problem\ with\ variables\ whose\ values\ are\ actually\ expressions\ is\ that\nfor\ caching\ the\ parsed\ expression\ will\ then\ be\ lost.\n\n\[AMG\]:\ This\ reopens\ the\ door\ to\ all\ the\ security,\ performance,\ and\ correctness\ problems\ solved\ by\ bracing\ one's\ expressions.\n**\ Discussion\ **\n\[Wookie\]:\ \ I\ had\ some\ trouble\ recently\ using\ `expr`\ to\ calculate\ time\n----\n\[RS\]\ 2006-06-19\ A\ word\ of\ warning:\ \[expr\]\ may\ normalize\ strings\ that\ look\ like\ octals\ to\ decimal,\ even\ if\ no\ arithmetic\ operation\ was\ performed\ on\ them:\n\ %set\ bond\ james\n\ %\ expr\ \{\$bond\ eq\ \"\"?\ \"-\":\ \"\$bond\"\}\n\ james\n\ %\ set\ bond\ 0070\n\ %\ expr\ \{\$bond\ eq\ \"\"?\ \"-\":\ \"\$bond\"\}\n\ 56\nBut\ no\ complaints\ if\ the\ string\ cannot\ be\ parsed\ as\ octal:\n\ %\ set\ bond\ 008\n\ %\ expr\ \{\$bond\ eq\ \"\"?\ \"-\":\ \"\$bond\"\}\n\ 008\nIn\ such\ cases\ it's\ better\ and\ more\ robust\ to\ use\ \[if\]:\n\ if\ \{\$bond\ eq\ \"\"\}\ \{set\ bond\ -\}\n\n\[HE\]\ 2006-06-20\ Strange\ behavior!\ The\ manpage\ of\ expr\ says:\n\ eq\ ne\n\ \ Boolean\ string\ equal\ and\ string\ not\ equal.\n\ \ Each\ operator\ produces\ a\ zero/one\ result.\n\ \ The\ operand\ types\ are\ interpreted\ only\ as\ strings.\nThere\ is\ no\ mention\ about\ this\ behavior.\ (I\ remember\ weakly\ this\ two\ operators\ are\ added\ exactly\ to\ avoid\ this\ problem)\nMore\ interesting:\ The\ manpage\ of\ if\ says:\n\ The\ if\ command\ evaluates\ expr1\ as\ an\ expression\ (in\ the\ same\ way\ that\ expr\ evaluates\ its\ argument).\nIs\ there\ something\ wrong?\n\n\[JMN\]\ 2006-10-19\nNot\ really..\ This\ normalization\ isn't\ occurring\ in\ the\ 'eq'\ operation\ -\ it\ happens\ when\ expr\ returns\ the\ result.\nThis\ may\ make\ it\ clearer:\n\n\ %expr\ \{\$bond\ eq\ \"\"?\ \"-\":\ \"hello\ \$bond\"\}\n\ hello\ 0070\n\ %expr\ \{\$bond\}\n\ 56\n\ %expr\ \{\$bond\ eq\ 56\}\n\ 0\n\ %expr\ \{\$bond\ ==\ 56\}\n\ 1\n\n\[LV\]\ Note\ the\ previous\ discussions\ on\ this\ page\ regarding\ the\ precautions\ one\ should\ keep\ in\ mind\ when\ using\ eq\ on\ tcl\ variables\ which\ contain\ numeric\ values.\ I\ am\ not\ certain\ I\ can\ think\ of\ a\ case\ where\ one\ would\ use\ eq\ when\ comparing\ numeric\ values...\n\n----\n\n\[Wookie\]\ I\ had\ some\ trouble\ recently\ using\ expr\ to\ calculate\ time\ offsets.\ I\ had\ 2\ time\ stamps\ in\ the\ form\ hh:mm\nSo\ I\ had\ 4\ variables\ h1,\ m1,\ h2,\ m2\ and\ one\ of\ my\ `expr`\ functions\ was\nSo\ I\ had\ 4\ variables\ h1,\ m1,\ h2,\ m2\ and\ one\ of\ my\ expr\ functions\ was\n======\nset\ result\ \[expr\ \{\$m1\ +\ \$m2\}\]\nset\ result\ \[expr\ (\$m1\ +\ \$m2)\]\n\nAs\ many\ of\ you\ may\ be\ thinking,\ you\ fool!\ what\ about\ 08\ and\ 09,\ which\ will\ get\nAs\ many\ of\ you\ may\ be\ thinking,\ you\ fool!\ what\ about\ 08\ and\ 09,\ which\ will\ get\ treated\ as\ invalid\ octal.\ So\ after\ some\ grumbling\ I\ thought\ okay\ so\ I\ have\ to\ trimleft\ them.\ Bit\ verbose\ but\ who\ cares:\n======\nset\ m1\ \[string\ trimleft\ \$m1\ 0\]\nset\ m2\ \[string\ trimleft\ \$m2\ 0\]\nset\ result\ \[expr\ (\$m1\ +\ \$m2)\]\n======\n\nNow\ what\ could\ possibly\ go\ wrong\ with\ that...\ well\ obviously\ 00\ becomes\ the\nNow\ what\ could\ possibly\ go\ wrong\ with\ that...\ well\ obviously\ 00\ becomes\ \"\",\ which\ causes\ unexpected\ closed\ parameter\ in\ the\ expr.\ So\ now\ I\ have\ to\ check\ for\ \"\".\ So...\n======\nset\ m1\ \[string\ trimleft\ \$m1\ 0\]\nif\ \{\$m1==\{\}\}\ \{set\ m1\ 0\}\nif\ \{\$m1==\"\"\}\ \{\ set\ m1\ 0\ \}\nset\ m2\ \[string\ trimleft\ \$m2\ 0\]\nif\ \{\$m2==\{\}\}\ \{set\ m2\ 0\}\nif\ \{\$m2==\"\"\}\ \{\ set\ m2\ 0\ \}\nset\ result\ \[expr\ \{\$m1\ +\ \$m2\}\]\nset\ result\ \[expr\ (\$m1\ +\ \$m2)\]\n\n...\ and\ then\ repeat\ it\ for\ the\ hours.\ It\ all\ seemed\ very\ clumsy.\ So\ I\ came\ up\n...\ and\ then\ repeat\ it\ for\ the\ hours.\ It\ all\ seemed\ very\ clumsy.\ So\ I\ came\ up\ with\ this,\ which\ may\ solve\ many\ of\ the\ conversion\ issues\ in\ this\ section.\n======\nscan\ \"\$h1:\$m1\ \$h2:\$m2\"\ \"%d:%d\ %d:%d\"\ h1\ m1\ h2\ m2\nset\ result\ \[expr\ \{\$m1\ +\ \$m2\}\]\nset\ result\ \[expr\ (\$m1\ +\ \$m2)\]\n\nAll\ the\ conversions\ to\ int\ have\ been\ done\ and\ leading\ 0's\ have\ been\ stripped\nAll\ the\ conversions\ to\ int\ have\ been\ done\ and\ leading\ 0's\ have\ been\ stripped\ and\ returns\ 0\ if\ the\ value\ is\ all\ 0s.\ This\ works\ for\ float\ and\ probably\ double\ (though\ I've\ not\ tried).\ Can\ anyone\ see\ any\ problems\ with\ this\ approach?\n\[glennj\]:\ No,\ `\[scan\]`\ is\ definitely\ the\ way\ to\ parse\ numbers\ out\ of\ dates\n\[glennj\]\ No,\ \[scan\]\ is\ definitely\ the\ way\ to\ parse\ numbers\ out\ of\ dates\ and\ times.\ \ However,\ for\ date\ arithmetic,\ nothing\ beats\ \[clock\].\ \ \n======\n#\ adding\ a\ delta\ to\ a\ time\nset\ h1\ 12\;\ set\ m1\ 45\nset\ h2\ 3\;\ set\ m2\ 30\nclock\ format\ \[clock\ add\ \[clock\ scan\ \"\$h1:\$m1\"\ -format\ \"%H:%M\"\]\ \$h2\ hours\ \$m2\ minutes\]\ -format\ %T\ \;#\ ==>\ 16:15:00\n======\n\n\n regexp2} CALL {my render expr **\ Summary\ **\n\n'''expr'''\ -\ Evaluate\ an\ expression\n\n**\ Synopsis\ **\n\n'''expr'''\ ''arg''\ ?''arg\ arg\ ...''?\n\n\n\ \ \ \[http://www.tcl.tk/man/tcl/TclCmd/expr.htm%|%officieal\ reference\]:\ \ \ \n\[http://purl.org/tcl/home/man/tcl8.4/TclCmd/expr.htm%|%expr(n)\ manpage\]\ (Tcl\ 8.4)\n\ \ \ \[tcl_precision\]:\ \ \ \n\[http://purl.org/tcl/home/man/tcl8.5/TclCmd/expr.htm%|%expr(n)\ manpage\],\n\[http://purl.org/tcl/home/man/tcl8.5/TclCmd/mathfunc.htm%|%mathfunc(n)\ manpage\],\n\[http://purl.org/tcl/home/man/tcl8.5/TclCmd/mathop.htm%|%mathop(n)\ manpage\]\ \ (all\ Tcl\ 8.5)\n\n\n`expr`\ \[concat%|%concatentates\]\ its\ arguments,\ evaluates\ this\ result\ as\ a\ Tcl\ \n\[\[expr\]\]\ implements\ a\ mini\ language\ that\ has\ a\ syntax\ separate\ from\ the\ Tcl\nsyntax.\ \ It\ supports\ some\ of\ the\ same\ constructs\ as\ Tcl,\ such\ as\ variable\nsubstitution,\ command\ substitution,\ and\ braces.\ \ It\ adds\ additional\ syntax\ for\nmathematical\ operators\ and\ functions,\ and\ unlike\ Tcl,\ does\ not\ accept\ character\nstrings\ that\ are\ not\ enclosed\ in\ double\ quotes\ or\ brackets.\n`expr`\ implements\ a\ \[little\ language\]\ that\ has\ a\ syntax\ separate\ from\ \[Tcl\].\nexpr\ conditions\ (like\ those\ used\ in\ \[if\]\ or\ \[while\])\ take\ 0\ to\ mean\ false\ and\nall\ other\ numbers\ to\ mean\ true.\ In\ addition,\ the\ following\ string\ constants\ can\nbe\ used:\nA\ value\ recognized\ as\ boolean\ by\ `\[string\ is\]\ boolean...`\ can\ be\ used\ directly,\n\ \ \ *\ true,\ on,\ yes\n\ \ \ *\ false,\ off,\ no\nFunctions\ take\ the\ form,\nman\ Tcl_GetBoolean:\ \"Any\ of\ these\ values\ may\ be\ abbreviated,\ and\ upper-case\nspellings\ are\ also\ acceptable.\"\n\nBeware\ that\ if\ you\ need\ code\ to\ run\ in\ Tcl\ releases\ as\ old\ as\ 8.3,\ you\ have\ to\nquote\ these\ if\ you\ use\ them\ directly\ as\ constants,\ as\ \[Donald\ Porter\]\ noted:\n''\[\[expr\]\]\ tries\ to\ interpret\ \"bare\"\ strings\ as\ function\ names,\ such\ as\ncos(\$x).\ \ You\ must\ quote\ the\ string\ \"true\".\ \ Then\ it\ behaves\ as\ you\ expect\ in\n8.3.3.''\ \ \n\ \ \ \ :\ \ \ ''name''`(`''argument''`,`''argument\ ...'')`\nRefer\ to\ the\ Operands\ section\ of\ the\n\[http://www.tcl.tk/man/tcl8.4/TclCmd/expr.htm#M5%|%expr\ man\ page%|%\]\ for\ the\nsyntax\ rules.\n\n\n======\n'''expr'''\ \[concat\]enates\ each\ ''arg''\ (adding\ separator\nspaces\ between\ them),\ evaluates\ the\ result\ as\ a\ \[Tcl\]\ expression,\ and\ returns\nthe\ value.\ The\ operators\ permitted\ in\ Tcl\ expressions\ include\ most\ of\ the\noperators\ permitted\ in\ \[C\]\ expressions\ and\ a\ few\ aditional\ ones,\ \ and\ they\ have\nthe\ same\ meaning\ and\ precedence\ as\ the\ corresponding\ C\ operators.\ Expressions\nalmost\ always\ yield\ numeric\ results\ (integer\ or\ floating-point\ values).\ For\nexample,\ the\ expression:\n\nset\ val1\ 8.2\nset\ val2\ 6\nexpr\ \{\$val1\ +\ \$val2\}\nexpr\ \{\$val1\}\ +\ \$\{val2\}\n\nevaluates\ to\ 14.2.\n======\nThis\ is\ an\ equivalent\ way\ of\ writing\ the\ previous\ \[\[expr\]\]\ command:\nIn\ most\ cases,\ it's\ best\ to\ \[Brace\ your\ Expr-essions%|%brace\]\ or\ otherwise\nexpr\ \{\$val1+\$val2\}\n======\n\nThis\ allows\ `expr`\ to\ do\ the\ interpretation,\ rather\ than\ having\ Tcl\ interpret\nAny\ argument\ that\ can\ be\ interpreted\ in\ some\ way,\ e.g.,\ variable\ or\ a\ command\nexpansion,\ should\ be\ enclosed\ in\ brackets.\ \ This\ allows\ the\ \[\[expr\]\]\ command\ to\ndo\ the\ interpretation,\ rather\ than\ having\ the\ caller\ interpret\ the\ arguments\nbefore\ handing\ them\ off\ to\ \[\[expr\]\].\ \ See\ below\ for\ more\ details.\n`expr`\ expressions\ differ\ from\ \[C\]\ expressions\ in\ the\ way\ that\ operands\ are\n\[Tcl\]\ expressions\ differ\ from\ C\ expressions\ in\ the\ way\ that\noperands\ are\ specified.\ \ They\ also\ include\ some\ non-numeric\ operators\ for\nstrings\ (comparison)\ and\ lists\ (membership).\n\n\n\nSince\ Tcl\ 8.5,\ many\ operators\ have\ command-equivalents\ in\ the\nIn\ spite\ of\ the\ name\ '''mathop''',\ some\ of\ the\ operators\ are\ string-oriented,\ rather\nNote\ that\ many\ operators\ have\ command-equivalents\ in\ the\ \[namespace\]\ '''::\[tcl::mathop\]'''\ from\ Tcl\ 8.5\ onwards.\nThe\ following\ is\ a\ chart\ of\ operators,\ in\ order\ of\ precedence\ (tightest-binding\n\[\[The\ term\ '''mathop'''\ is\ a\ misnomer,\ since\ some\ of\ the\ operators\ included\ in\ this\ namespace\ are\ string,\ rather\ than\ math,\ oriented...\]\]\n&|\ \[-\]\ \[+\]\ \[~\]\ \[!\]\ |\ Unary\ operators\;\ specifically\ a\ negation\ operation,\ a\ non-negation\ operation,\ a\ bit-wise\ NOT\ operation\ (every\ bit\ in\ the\ input\ value\ gets\ replaced\ by\ its\ inverse)\ and\ a\ logical\ NOT\ operation\ (non-zero\ maps\ to\ zero,\ and\ zero\ maps\ to\ one).\ |&\nThe\ '''expr'''\ operators,\ in\ order\ of\ precedence\ (tightest-binding\ to\ least-tight\ binding),\ are:\n\n&|\ \[-\]\ \[+\]\ \[~\]\ \[!\]\ |\ Unary\ operators\;\ specifically\ a\ negation\ operation,\ a\ non-negation\ operation\ (I\ see\ little\ point\ in\ this\ one),\ a\ bit-wise\ NOT\ operation\ (every\ bit\ in\ the\ input\ value\ gets\ replaced\ by\ its\ inverse)\ and\ a\ logical\ NOT\ operation\ (non-zero\ maps\ to\ zero,\ and\ zero\ maps\ to\ one.)\ |&\n&|\ \[+\]\ \[-\]\ |\ Addition\ and\ subtraction.\ |&\n&|\ \[<<\]\ \[>>\]\ |\ Left\ and\ right\ shift.\ \ Equivalent\ to\ multiplying\ or\ dividing\ by\ a\ suitable\ power\ of\ two,\ and\ then\ reducing\ the\ result\ to\ the\ range\ representable\ in\ an\ integer\ on\ the\ host\ platform.\ |&\n&|\ \[<\]\ \[>\]\ \[<=\]\ \[>=\]\ |\ Ordering\ relations:\ \ less\ than,\ greater\ than,\ less\ than\ or\ equal,\ greater\ than\ or\ equal.\ \ These\ operations\ work\ on\ strings\ as\ well\ as\ numbers,\ but\ where\ string\ comparison\ is\ intended,\ it\ is\ advisable\ to\ use\ the\ dedicated\ string\ comparison\ operators\ or\ \[string\ compare\]\ or\ \[string\ equal\]\ instead,\ \ as\ those\ are\ \ more\ predictable\ in\ the\ case\ of\ a\ string\ that\ looks\ like\ a\ number.\ \ For\ example,\ \[string\ equal\]\ considers\ \"6\"\ and\ \"06\"\ to\ be\ different\ strings,\ but\ the\ `expr`'\ operator\ `==`\ considers\ them\ to\ be\ equivalent\ numbers.|&\n&|\ \[<\]\ \[>\]\ \[<=\]\ \[>=\]\ |\ Ordering\ relations\ (less\ than,\ greater\ than,\ less\ than\ or\ equal,\ greater\ than\ or\ equal.)\ \ \ Note\ that\ these\ operations\ work\ on\ strings\ as\ well\ as\ numbers,\ but\ you\ are\ probably\ better\ off\ testing\ the\ result\ of\ \[string\ compare\]\ instead\ as\ that\ is\ more\ predictable\ in\ the\ case\ of\ a\ string\ that\ looks\ like\ a\ number.\ |&\n&|\ \[==\]\ \[!=\]\ |\ Equality\ and\ inequality.\ \ \ Note\ that\ these\ operations\ work\ on\ strings\ as\ well\ as\ numbers,\ but\ you\ are\ probably\ better\ off\ testing\ the\ result\ of\ \[string\ equal\]\ instead\ as\ that\ is\ more\ predictable\ in\ the\ case\ of\ a\ string\ that\ looks\ like\ a\ number.\ \ For\ example,\ \[string\ equal\]\ considers\ \"6\"\ and\ \"06\"\ to\ be\ different\ strings,\ but\ expr's\ ==\ considers\ them\ to\ be\ equivalent\ numbers.\ |&\n&|\ \[eq\]\ \[ne\]\ |\ (2004-07-08\ added):\ From\ Tcl\ 8.4\ on.\ The\ same\ as\ before,\ but\ arguments\ only\ strings.\ Will\ find\ \"6\"\ and\ \"06\"\ (as\ well\ as\ 1\ and\ 1.0)\ to\ be\ different.\ |&\n&|\ \[**\]\ |\ exponential.\ From\ Tcl\ 8.5\ on\ |&\n&|\ \[in\]\ \[ni\]\ |\ Item\ (argument\ 1)\ in/not\ in\ list\ (argument\ 2).\ New\ in\ Tcl\ 8.5\ |&\n&|\ \[^\]\ |\ Bit-wise\ exclusive\ OR.\ \ A\ bit\ is\ set\ in\ the\ result\ when\ the\ corresponding\ bit\ is\ set\ in\ ''precisely\ one''\ of\ the\ arguments.\ |&\n&|\ \[<<pipe>>\]\ |\ Bit-wise\ OR.\ \ \ A\ bit\ is\ set\ in\ the\ result\ when\ the\ corresponding\ bit\ is\ set\ in\ either\ of\ the\ arguments.\ |&\n&|\ \[&&\]\ |\ Logical\ AND.\ \ \ The\ result\ is\ `1`\ when\ both\ of\ the\ arguments\ true.\ and\ `0`\ otherwise.\ \ This\ operation\ is\ a\ ''short-circuiting''\ operation,\ and\ will\ only\ evaluate\ its\ second\ argument\ when\ the\ first\ argument\ is\ non-zero.\ \ This\ includes\ the\ expansion\ of\ Tcl\ commands\ in\ square\ brackets.\ \ Where\ Tcl\ seems\ not\ to\ be\ behaving\ as\ describe\ here,\ see\ \[double\ substitution\].\ |&\n&|\ \[&&\]\ |\ Logical\ AND.\ \ \ The\ result\ is\ a\ one\ (true)\ when\ both\ of\ the\ arguments\ are\ non-zero\ (true),\ and\ zero\ (false)\ otherwise.\ \ Note\ that\ this\ operation\ is\ a\ ''short-circuiting''\ operation,\ and\ will\ only\ evaluate\ its\ second\ argument\ when\ the\ first\ argument\ is\ non-zero.\ \ This\ includes\ the\ expansion\ of\ Tcl\ commands\ in\ square\ brackets,\ but\ this\ delay\ in\ evaluation\ only\ occurs\ if\ the\ whole\ expression\ is\ enclosed\ in\ curly\ braces.\ |&\n&|\ \[<<pipe>><<pipe>>\]\ |\ Logical\ OR.\ \ \ The\ result\ is\ a\ zero\ (false)\ when\ both\ of\ the\ arguments\ are\ zero\ (false),\ and\ one\ (true)\ otherwise.\ \ Note\ that\ this\ operation\ is\ a\ ''short-circuiting''\ operation,\ and\ will\ only\ evaluate\ its\ second\ argument\ when\ the\ first\ argument\ is\ zero.\ \ This\ includes\ the\ expansion\ of\ Tcl\ commands\ in\ square\ brackets,\ but\ this\ delay\ in\ evaluation\ only\ occurs\ if\ the\ whole\ expression\ is\ enclosed\ in\ curly\ braces.\ |&\n&|\ x'''?'''y''':'''z\ |\ If-then-else,\ as\ in\ C\ (where\ x,y,z\ are\ expressions).\ \ \ If\ the\ value\ x\ is\ non-zero\ (true)\ then\ the\ expression\ y\ is\ evaluated\ to\ produce\ the\ result,\ and\ otherwise\ the\ expression\ z\ is\ evaluated\ to\ produce\ the\ result.\ \ Note\ that\ this\ operation\ is\ a\ ''short-circuiting''\ operation,\ and\ will\ not\ evaluate\ expression\ y\ if\ x\ is\ zero\ (false)\ and\ will\ not\ evaluate\ expression\ z\ if\ x\ is\ non-zero\ (true).\ \ This\ includes\ the\ expansion\ of\ Tcl\ commands\ in\ square\ brackets,\ but\ this\ delay\ in\ evaluation\ only\ occurs\ if\ the\ whole\ expression\ is\ enclosed\ in\ curly\ braces.\ \ It\ is\ usually\ clearer\ and\ easier\ to\ maintain\ (and\ no\ slower\ -\ the\ generated\ bytecode\ is\ identical)\ to\ use\ the\ Tcl\ \[if\]\ command\ instead\ of\ this.\ |&\n\n\n\nSee\ the\ \[http://www.tcl.tk/man/tcl/TclCmd/mathfunc.htm%|%mathfunc\ man\ page\].\nSee\ the\ mathfunc\ man\ page,\ listed\ above,\ for\ the\ Tcl\ 8.5\ man\ page\ information\ on\ '''expr'''\ builtin\ functions.\nThe\ following\ is\ a\ list\ of\ builtin\ functions:\n***\ BUILTIN\ FUNCTIONS\ ***\n\ \ \ '''\[abs\]'''(x):\ \ \ Absolute\ value\ (negate\ if\ negative).\n\ \ \ '''\[abs\]'''(x):\ \ \ Absolute\ value\ (negate\ if\ negative.)\n\ \ \ '''\[acos\]'''(x):\ \ \ Inverse\ cosine\ (result\ in\ radians.)\n\ \ \ '''\[asin\]'''(x):\ \ \ Inverse\ sine\ (result\ in\ radians.)\n\ \ \ '''\[atan\]'''(x):\ \ \ Inverse\ tangent\ (result\ in\ radians.)\n\ \ \ '''\[atan2\]'''(y,x):\ \ \ Inverse\ tangent.\ \ Can\ handle\ cases\ which\ plain\ atan()\ can't\ (due\ to\ division\ by\ zero)\ and\ has\ a\ larger\ output\ range\ (result\ in\ radians.)\n\ \ \ '''\[bool\]'''(x):\ \ \ Accept\ any\ numeric\ value\ or\ string\ (acceptable\ to\ \[string\]\ is\ boolean),\ and\ return\ the\ corresponding\ boolean\ value\ 0\ or\ 1\n\n\ \ \ '''\[cos\]'''(x):\ \ \ Cosine\ (input\ in\ radians.)\n\ \ \ '''\[cosh\]'''(x):\ \ \ Hyperbolic\ cosine.\n\n\ \ \ '''\[entier\]'''(x):\ \ \ Take\ any\ numeric\ value\ and\ return\ the\ integer\ part\ of\ the\ argument,\ as\ an\ unlimited\ value\ string\n\ \ \ '''\[exp\]'''(x):\ \ \ Exponential\ function.\ \ Returns\ e**inputValue\ (using\ the\ FORTRAN-style\ notation)\ where\ e\ is\ the\ base\ of\ natural\ logarithms.\n\ \ \ '''\[floor\]'''(x):\ \ \ Floor\ (defined\ over\ floating\ point\ numbers.)\ \ If\ the\ input\ value\ is\ not\ a\ whole\ number,\ return\ the\ next\ ''smaller''\ whole\ number.\ '''Surprise''':\ The\ return\ value\ is\ a\ float,\ not\ an\ integer.\n\ \ \ '''\[fmod\]'''(x,\ y):\ \ \ Floating\ point\ remainder\ of\ x\ divided\ by\ y.\n\ \ \ '''\[hypot\]'''(x,y):\ \ \ Hypotenuse\ calculator.\ \ If\ the\ projection\ of\ a\ straight\ line\ segment\ onto\ the\ X\ axis\ is\ x\ units\ long,\ and\ the\ projection\ of\ that\ line\ segment\ onto\ the\ Y\ axis\ is\ y\ units\ long,\ then\ the\ line\ segment\ is\ hypot(x,y)\ units\ long\ (assuming\ boring\ old\ Euclidean\ geometry.)\ \ Equivalent\ to\ sqrt(x*x+y*y).\n\ \ \ '''\[int\]'''(x):\ \ \ Convert\ number\ to\ integer\ by\ truncation.\n\ \ \ '''\[isqrt\]'''(x):\ \ \ Compute\ the\ integer\ part\ of\ the\ square\ root\ of\ x.\n\n\n\ \ \ '''\[max\]'''(x,...):\ \ \ Return\ the\ one\ argument\ with\ the\ greatest\ value\n\ \ \ '''\[min\]'''(x,...):\ \ \ Return\ the\ one\ argument\ with\ the\ least\ value\n\ \ \ '''\[pow\]'''(x,y):\ \ \ Power\ function.\ \ In\ FORTRAN\ notation,\ x\[**\]y.\n\n\n\ \ \ '''\[sin\]'''(x):\ \ \ Sine\ (input\ in\ radians.)\n\n\ \ \ '''\[sqrt\]'''(x):\ \ \ Square\ root\ (well,\ the\ positive\ square\ root\ only.\ \ And\ Tcl\ doesn't\ do\ complex\ math,\ so\ the\ input\ had\ better\ be\ positive...)\n\n\n\n\n\n\n**\ Mathematical\ Expressions\ **\n\n\nSimple\ addition:\n\n======\nset\ a\ \[expr\ \{1\ +\ 2\}\]\n======\n\nmathematical\ functions\n\n======\nset\ a\ \[expr\ \{sqrt(4)\}\]\n======\n\n\[martin\ Lemburg\]:\ The\ following\ returns\ `1`\ because\ `\"\ 2\ \"`\ will\ be\ interpreted\n\[martin\ Lemburg\]:\ returns\ 1,\ because\ \[\[expr\]\]\ \"\ 2\ \"\ will\ be\ converted\ to\ 2\n======\nset\ a\ \[expr\ \{\"\ 2\ \"\ ==\ \[string\ trim\ \"\ 2\ \"\]\}\]\n======\n\nTo\ ensure\ that\ expression\ evaluates\ to\ a\ floating\ point\ number,\ use\ `double()`\nTo\ ensure\ that\ expression\ evaluates\ to\ a\ floating\ point\ number,\ use\ an\ \[\[expr\]\]\nlike\ ''double()'':\nset\ a\ 1\nset\ b\ 2\nexpr\ \{double(\$a)/\$b\}\n======\n\nor,\ to\ get\ an\ integer:\n\nexpr\ \{entier(\$a/\$b)\}\n======\n\n`int()`\ would\ also\ have\ worked,\ but\ `entier()`\ is\ more\ general\n''int()''\ would\ also\ have\ worked,\ but\ ''entier()''\ is\ more\ general\n\n\nThe\ following\ returns\ returns\ 4,\ rather\ than\ -4\ as\ some\ might\ expect:\n\n======\nset\ a\ \[expr\ \{-2**2\}\]\n======\n\nThe\ following\ returns\ `1`\ because\ `2==2`\ is\ evaluated\ first:\nreturns\ 1\ because\ 2==2\ is\ evaluated\ first\nset\ a\ \[expr\ \{5&2==2\}\]\n======\n\n\[AMG\]:\ The\ order\ of\ bitwise\ operations\ (`|`,\ `&`,\ and\ `^`)\ may\ seem\ totally\ bogus,\ but\ it's\ inherited\ from\ \[C\],\ which\ in\ turn\ inherited\ it\ from\ an\ early\ prototype\ version\ of\ C\ which\ lacked\ separate\ logical\ operators\ (`&&`\ and\ `||`)\ \[http://cm.bell-labs.com/who/dmr/chist.html\].\ I\ wouldn't\ cry\ if\ a\ new\ language\ (not\ Tcl)\ decided\ to\ break\ compatibility\ with\ C\ in\ this\ respect.\n**\ String\ Operands\ **\n\n\[\[expr\]\]\ tries\ to\ interpret\ operands\ as\ numeric\ values,\ but\ it\ does\ not\ try\ to\nrecognize\ complete\ numeric\ epxressons,\ so\ a\ value\ \"2*3\"\ will\ be\ interpreted\ as\na\ string:\n======\nset\ y\ 2*3\;\ expr\ \{\$y\}\ \ \ \;#\ ==>\ 2*3\nset\ y\ 2*3\;\ puts\ \[expr\ \{\$y\}\]\ \;#\ \ ==>\ 2*3\nset\ y\ 2*3\;\ puts\ \[expr\ \{\$y+0\}\]\ \;#\ ==>\ can't\ use\ non-numeric\ string\ as\ operand\ of\ \"+\"\n\nTo\ pass\ a\ complete\ expression\ stored\ in\ a\ variable,\ omit\ the\ braces\ so\ that\ Tcl\n\n`expr`\ implements\ a\ little\ language\ distinct\ from\ the\ language\ described\ in\ \[dodekalogue%|%the\ rules\ of\ Tcl\].\ \ One\n\[expr\]\ implements\ a\ little\ language\ distinct\ from\ standard\ Tcl.\ \ One\ difference\nis\ that\ \[expr\]\ requires\ strings\ to\ be\ quoted:\n======none\n%\ \ if\ \{joe\ eq\ mike\}\ \{puts\ wow\}\nsyntax\ error\ in\ expression\ \"joe\ eq\ mike\":\ variable\ references\ require\ preceding\ \$\n%\ \ if\ \{\"joe\"\ eq\ \"mike\"\}\ \{puts\ wow\}\n%\ \ if\ \{\"joe\"\ eq\ \"mike\"\}\ \{puts\ \"wow\"\}\n%\ \ if\ \{\{joe\}\ eq\ \{mike\}\}\ \{puts\ \{wow\}\}\n%\n\nTo\ insert\ a\ literal\ value\ when\ templating\ an\ expression,\ use\ an\ \[identity\nIf\ \[expr\]\ syntax\ was\ the\ same\ as\ Tcl\ syntax,\ a\ Tcl\ ''bareword''\ string\ would\ be\ accepted,\ but\ it\ is\ not.\n\nNormal\ Tcl\ syntax,\ of\ course,\ does\ not\ requireThere\ are\ other\ cases\ in\ Tcl\nwhere\ this\ quoting\ need\ not\ happen.\n======\n%\ puts\ wow\nwow\n%\ set\ a\ abc\nabc\n%\n======\n\nIf\ you\ prefer\ consistency,\ then\ always\ quote\ the\ strings,\ but\ note\ that\ at\ some\npoint\ \[expr\]\ may\ grow\ the\ feature\ of\ accepting\ bareword\ strings.\n\n\n\nIf\ the\ return\ value\ of\ `expr`\ is\ numeric,\ it\ is\ transformed\ into\ a\ canonical\nIf\ the\ value\ of\ an\ \[expr\]\ is\ numeric,\ it\ will\ transformed\ into\ a\ canoncial\ numeric\ form:\n======\nset\ val\ 0x10\nputs\ \$val\ \;#\ 0x10\nset\ val\ \[expr\ \{\$val\}\]\nputs\ \$val\ \;#\ 16\n======\n\n======\n\nputs\ \[expr\ \{\[join\ \{0\ x\ 1\ 0\}\ \{\}\]\}\]\ \;#\ 16\n======\n\n\nIn\ other\ words,\ `expr`\ may\ mutate\ strings\ that\ can\ be\ interpreted\ as\nIn\ other\ words,\ \[expr\]\ may\ mutate\ strings\ that\ can\ be\ interpreted\ as\ numbers,\nwhich\ is\ a\ potential\ gotcha\ for\ the\ programmer\ using\ string\ functions\ of\ \[expr\]\nwhile\ not\ considering\ that\ they\ may\ have\ a\ numeric\ interpretation.\n\n\n`expr`\ uses\ floating\ point\ arithmetic,\ so\ strings\ representing\ decimal\n\[\[expr\]\]\ usese\ floating\ point\ arithmetic,\ so\ strings\ representing\ decimal\nto\ a\ close-enough\ representation.\ \ In\ the\ following\ example,\ `36.37`\ gets\ a\nto\ a\ close-enough\ floating-point\ representation.\ \ In\ the\ following\ example,\n\"36.37\"\ gets\ a\ floating-point\ representation\ that\ approaches\ 36.37:\ \n======\nexpr\ \{int(36.37*100)\}\n======\n\nIf\ that\ value\ is\ subsequently\ used\ as\ a\ string,\ it\ becomes\ necessary\ to\ somehow\nconvert\ it.\ \ Over\ the\ years,\ the\ default\ string\ conversion\ has\ varied.\ \ For\ Tcl\nversion\ 8.5.13,\ it\ looks\ like\n\n======none\n3636.9999999999995\n======\n\n\[RS\]\ points\ out\ that\ version\ 8.4.9\ provided\ the\ following\ results,\ and\ that\n\[RS\]\ points\ out\ that\ for\ version\ 8.4.9,\ provided\ the\ following\ results,\ and\nthat\ that\ braced\ or\ not,\ \[expr\]\ returns\ the\ same\ (string\ rep\ of)\ double\ as\ well\nas\ int()\ result,\ so\ the\ issue\ of\ bracing\ one's\ expressions\ is\ not\ relevant\ to\nthe\ issue\ of\ floating-point\ to\ string\ conversion.\n======none\n%\ expr\ 36.37*100\n3637.0\ \;#--\ good\ enough...\n%\ expr\ \{36.37*100\}\n3637.0\ \;#--\ the\ same\n%\ expr\ \{int(36.37*100)\}\n3636\ \ \ \;#--\ Hmm\n%\ expr\ int(36.37*100)\n3636\ \ \ \;#--\ the\ same\n%\ info\ pa\n8.4.9\n======\n\nOne\ way\ to\ get\ `3637`\ would\ be\ to\ use\ `round()`:\nOne\ way\ to\ get\ \"3637\"\ would\ be\ to\ use\ ''round()'':\n======\nexpr\ \{round(36.37*100)\}\n======\n\n`\[format\]`\ can\ also\ be\ useful,\ but\ the\ main\ point\ is\ to\ remain\nThe\ \[\[\[format\]\]\]\ command\ can\ also\ be\ useful,\ but\ the\ main\ point\ is\ that\ the\nprogrammer\ must\ be\ aware\ of\ their\ context\ and\ decide\ if\ and\ how\ to\ use\nfloating-point\ operations\ the\ context\ of\ the\ program.\n\[LV\]:\ \ My\ response\ on\ \[comp.lang.tcl\]\ was\ that\ I\ thought\ it\ was\ a\ shame\n\[LV\]\ My\ response\ on\ \[comp.lang.tcl\]\ was\ that\ I\ thought\ it\ was\ a\ shame\nthat\ expr\ (or\ perhaps\ it\ is\ Tcl)\ didn't\ use\ the\ same\ mechanism\ for\nbe\ consistent.\ \ Even\ if\ they\ were\ consistently\ '''wrong''',\ one\ would\nbe\ able\ to\ at\ least\ to\ live\ within\ the\ ''law\ of\ least\ surprise''.\nAs\ it\ is,\ until\ one\ experiments,\ one\ won't\ know\ which\ way\ that\ Tcl\nis\ going\ to\ ''round''\ results.\n\n\[EPSJ\]:\ \ This\ may\ be\ a\ side\ effect\ of\ the\ IEEE\ floating\ point\ standard.\ This\ is\n\[EPSJ\]\ This\ may\ be\ a\ side\ effect\ of\ the\ IEEE\ floating\ point\ standard.\ This\ is\nalgorithms.\ The\ rule\ is\ that\ the\ mantissa\ of\ a\ floating\ point\ number\ must\ be\nrounded\ to\ the\ nearest\ even\ number.\ As\ 36.37\ cannot\ be\ represented\ exactly\ in\nfloat\ point\ it\ ends\ up\ being\ a\ small\ fraction\ below\ the\ intended\ number.\ On\ the\nother\ side\ 36.38\ moves\ on\ the\ other\ direction.\ Look\ the\ following\ result:\n\n======none\n\ ()\ 60\ %\ expr\ int(36.380*100)\n\ 3638\n\ ()\ 61\ %\ expr\ int(36.370*100)\n\ 3636\nx86\ floating\ point\ hardware\ allows\ this\ to\ be\ configurable\ to\ nearest\ even,\nnearest\ odd,\ and\ a\ few\ more\ options.\ But\ usually\ nearest\ even\ is\ the\ default.\nThe\ result\ may\ seem\ inconsistent,\ but\ it\ is\ intentional.\n\n\n**\ pow()\ vs\ **\n**\ pow()\ vs\ **\ **\n\[LES\]\ 2005-07-23:\n\[LES\]\ on\ July\ 23\ 2005:\n\ %\ expr\ pow(5,6)\n\ 15625.0\n======none\n\ %\ expr\ 5**6\n\ 15625\n%\ expr\ 5**6\nTwo\ syntaxes,\ two\ slightly\ different\ results.\ Is\ that\ intentional?\ \[RS\]\ Yes\ -\ while\ pow()\ always\ goes\ for\ double\ logarithms,\ '**'\ tries\ to\ do\ integer\ exponentiation\ where\ possible.\nTwo\ syntaxes,\ two\ slightly\ different\ results.\ Is\ that\ intentional?\n\n\[davou\]:\ What\ is\ the\ precision\ of\ functions\ in\ `expr`,\ and\ how\ can\ it\ be\n\[davou\]\ what\ is\ the\ precision\ of\ expr's\ functions,\ and\ how\ can\ it\ be\ expanded\ upon?\n\[Lars\ H\]:\ That's\ generally\ determined\ by\ the\ \[C\]\ library\ functions\ that\nimplement\ them.\ It\ depends\ on\ where\ (and\ against\ what)\ Tcl\ is\ compiled.\ \ For\nimplement\ them,\ i.e.,\ it\ depends\ on\ where\ (and\ against\ what)\ Tcl\ is\ compiled.\nFor\ \"real\"\ numbers\ that\ means\ '''double'''s,\ which\ are\ floating-point\ numbers\nof\ typically\ about\ 17\ decimal\ digits\ precision\ (but\ how\ many\ of\ these\ are\ncorrect\ varies\ between\ functions\ and\ platforms).\ For\ integers\ Tcl\ has\ntraditionally\ used\ '''long'''s,\ which\ in\ most\ cases\ means\ 32-bit\ two's\ncomplement\ integers\ (\$tcl_platform(wordSize)\ tells\ you\ the\ actual\ number\ of\nbytes),\ but\ as\ of\ Tcl\ 8.5\ it\ supports\ (almost)\ arbitrarily\ large\ integers\n(\[googol\ magnitude\]\ is\ no\ problem\ anymore,\ whereas\ googolplex\ magnitude\nwouldn't\ fit\ in\ the\ computer\ memory\ anyway).\ As\ for\ extending\ what\ the\ core\nprovides,\ \[tcllib\]\ provides\ math::bignum\ and\ \[math::bigfloat\].\n\n**\ \[Nan\]\ and\ \[Inf\]\ **\n\n\nAt\ least\ as\ of\ Tcl\ 8.5,\ \[NaN\]\ and\ \[Inf\]\ are\ potential\ values\ returning\ from\nAt\ least\ as\ of\ Tcl\ 8.5,\ \[NaN\]\ and\ \[Inf\]\ are\ potential\ values\ returning\ from\ expr.\n\[Philip\ Smolen\]\ I've\ never\ seen\ expr\ return\ NaN.\ \ I\ wish\ it\ would!\n======\n**\ Interactions\ with\ \[locale\]\ **\n\n**\ Interactions\ with\ `\[locale\]`\ **\nexpr's\ parsing\ of\ decimals\ may\ be\ hampered\ by\ \[locale\]\ -\ you\ might\ get\ an\n\n\n\n`expr`\ concatenates\ its\ arguments\ into\ an\ expression.\ \ Consider\ the\ following\n\[expr\]\ resolves\ variables\ in\ the\ context\ of\ its\ caller,\ and\ each\ variable\ value\nbecomes\ exactly\ one\ operand\ in\ the\ expression.\ \ Consider\ the\ following\n======\nexpr\ 5\ >\ \{\}\ \;#\ ->\ missing\ operand\ at\ _@_\nset\ color2\ green\n\nexpr\ \{\$color1\}\ eq\ \{\$color2\}\ \;#\ 1\n\nConcatenated,\ the\ arguments\ form\ the\ script,\ `green\ eq\ green`,\ in\ which\ the\ two\nBut\ if\ the\ arguments\ are\ not\ bracketed,\ there\ is\ an\ error\ in\ the\ expression\ syntax:\nAnother\ example\ illustrating\ the\ same\ point:\n======\n#wrong\nexpr\ \$color1\ eq\ \$color2\n======\n======none\ninvalid\ bareword\ \"green\"\nin\ expression\ \"green\ eq\ green\"\;\nshould\ be\ \"\$green\"\ or\ \"\{green\}\"\ or\ \"green(...)\"\ or\ ...\n======\n\nThis\ is\ because\ in\ \[\[expr\]\]\ syntax,\ strings\ should\ be\ quoted\ or\ bracketed\n\n\n======none\nset\ a\ \"abc\"\nexpr\ \$a\ in\ \$b\n#\ invalid\ bareword\ \"abc\"\n#\ in\ expression\ \"abc\ in\ 123\ abcd\ xyz\ lmnop\"\;\n#\ should\ be\ \"\$abc\"\ or\ \"\{abc\}\"\ or\ \"abc(...)\"\ or\ ...\n\nexpr\ \{\$a\ in\ \$b\}\ \;#->\ 0\nexpr\ \{\$a\ in\ \$b\}\n#\ 0\nexpr\ \{\$a\ ni\ \$b\}\ \;#->\ 1\nexpr\ \{\$a\ ni\ \$b\}\n#\ 1\n======\n%\ expr\ \$a\ ==\ \"foo\"\ ?\ true\ :\ false\n%\ expr\ \{\$a\ eq\ \"foo\"\ ?\ true\ :\ false\}\n%\ expr\ \{\$a\ ==\ \"foo\"\ ?\ true\ :\ false\}\n======\n\n\n\n\nWhen\ exactly\ one\ unconcatenated\ value\ is\ passed\ to\ `expr`,\ the\ argument\ can\ be\n\nIn\ addition,\ \[\[expr\]\]\ is\ usually\ much\ more\ performant\ when\ its\ non-literal\narguments\ are\ braced,\ since\ this\ allows\ byte-compilation.\n'''Fast:'''\n======\n\n\[AMG\]:\ The\ security\ problems\ of\ unbraced\ `expr`essions\ are\ very\ similar\ to\n\n\[AMG\]:\ The\ security\ problems\ of\ unbraced\ \[expr\]\ expressions\ are\ very\ similar\ to\n\[SQL\]\ injection\ attacks.\ \ Notice\ how\ \[sqlite\]'s\ \[Tcl\]\ binding\ does\ its\ own\nthis\ problem\ as\ well\ because\ the\ default\ is\ to\ apply\ multiple\ passes\ of\ninterpretation.\n\nSee\ also\ \[double\ substitution\].\n\n\ninput:\n\n======\n#DON'T\ EXECUTE\ THIS\ SCRIPT!!!\nset\ x\ \{\[exec\ format\ C:\\\\\]\}\nset\ j\ \{\[puts\ Sucker!\]\}\n#C:\\\ get\ formatted\ in\ the\ next\ command\nset\ k\ \[expr\ \$x\ /\ \$j.\]\n======\n\nOn\ the\ other\ hand,\n\n======\nset\ k\ \[expr\ \{\ \$x\ /\ double(\$j)\ \}\]\n======\n\ngives\ a\ much\ more\ reasonable\ result:\n\n======none\nargument\ to\ math\ function\ didn't\ have\ numeric\ value\n\ \ \ while\ executing\n\"expr\ \{\ \$x\ /\ double(\$y)\ \}\"\n\ \ \ invoked\ from\ within\n\"set\ k\ \[expr\ \{\ \$x\ /\ double(\$y)\ \}\]\n\"\n\ \ \ \ (file\ \"foo.tcl\"\ line\ 3)\n\n======\n\n\n\n**\ The\ \"Dot\"\ Trick\ for\ Unbraced\ Expressions\ **\nUnless\ you\ know\ exactly\ what\ you\ are\ doing,\ unbraced\ expressions\ are\ not\nrecommended.\ \ Nevertheles...\n\nWith\ unbraced\ expressions,\ `.`\ (`\\x2e`)\ can\ be\ appended\ to\ a\ variable\ to\ get\ `expr`\nWith\ unbraced\ expressions,\ a\ \".\"\ can\ be\ appended\ to\ a\ variable\ to\ get\ \[\[expr\]\]\nto\ interpret\ the\ value\ as\ a\ float,\ but\ the\ ''double()''\ function\ is\ a\ better\nalternative:\n======\nset\ x\ 1\;\ set\ j\ 2\n\n#\ works\ (but\ don't\ do\ this)\nexpr\ \$x/\$j.\n\n#an\ accepted\ way\ to\ do\ it\nexpr\ \{double(\$x)/\$j\}\n\n#\ error:\ syntax\ error\ in\ expression\ \"\$x/\$j.\"\ \ (expr\ parser)\nexpr\ \{\$x/\$j.\}\n======\n\nIt's\ faster,\ too:\n\n======\nset\ script1\ \{\n\ \ \ set\ x\ 1\n\ \ \ set\ j\ 2\n\ \ \ set\ k\ \[expr\ \$x\ /\ \$j.\]\n\}\nset\ script2\ \{\n\ \ \ set\ x\ 1\n\ \ \ set\ j\ 2\n\ \ \ set\ k\ \[expr\ \{\ \$x\ /\ double(\$j)\ \}\]\n\}\nforeach\ v\ \{script1\ script2\}\ \{\nforeach\ v\ \{\ script1\ script2\ \}\ \{\n\}\n\n#script1:\ 38\ microseconds\ per\ iteration\n#script2:\ 9\ microseconds\ per\ iteration\n\n#\[pyk\]\ 2012-11-28:\ what\ a\ difference\ a\ few\ years\ makes\ (an\ \"old\"\ 3.06Ghz\ Intel\ Core\ 2\ Duo):\n#script1:\ 4.4767364\ microseconds\ per\ iteration\n#script2:\ 0.7374299\ microseconds\ per\ iteration\n======\n\n----\n\n\[RS\]:\ This\ was\ just\ to\ demonstrate\ the\ differences\ between\ the\ regular\ Tcl\ parser\nand\ ''expr'''s\ parser,\ not\ recommended\ practice.\ Another\ example\ is\n\n======\nset\ op\ +\nset\ op\ \"+\"\n9\nexpr\ \{4\ \$op\ 5\}\nsyntax\ error\ in\ expression\ \"4\ \$op\ 5\"\n======\n\nSee\ the\ \[for\]\ page\ on\ a\ case\ where\ that\ helped.\nSee\ the\ `\[for\]`\ page\ on\ a\ case\ where\ that\ helped.\n**\ Bytecode\ compilation\ and\ performance\ **\n\n\nIn\ \[http://groups.google.com/group/comp.lang.tcl/browse_thread/thread/f873d6fab9f0e304%|%Embedded\ vs.\ separate\ commands\],\ 1992-12-38,\ \[JO\]\ published\ the\ voting\ results\ 37:8\ in\ favor\ of\ embedded\ functions()\ vs.\ separate\ \[\[commands\]\]\nOn\ 1992-12-28\ \[JO\]\ published\ the\ voting\ results\ 37\ :\ 8\ in\ favor\ of\ embedded\ functions()\ vs.\ separate\ \[\[commands\]\]\ -\ \[http://groups.google.com/groups?q=group:comp.lang.tcl+author:ousterhout&start=900&hl=de&lr=&newwindow=1&scoring=d&selm=1hn9tvINNqod%40agate.berkeley.edu&rnum=922\]\n\n**\ Dustbin\ **\nAddition\n'''(Outdated)\ Expr\ \[Gotchas\]'''\n\n\n======none\n\ %\ expr\ (1<<31)-1\n\ 2147483647\n%\ expr\ 2147483647\ +\ 2147483647\n\ %\ expr\ 2147483647\ +\ 2147483647\n\ -2\nMultiplication\n\n======none\n\ %\ expr\ sqrt((1<<31)-1)\n\ 46340.9500011\nexpr\ 46341*46341\n\ expr\ 46341*46341\n\ -2147479015\nThese\ are\ results\ of\ Tcl\ 8.4\ and\ older\ versions\ using\ a\ 32-bit\ representation\nThese\ are\ results\ of\ Tcl\ 8.4\ and\ older\ versions\ using\ a\ 32-bit\ representation\ for\ integers.\ \ Check\ out\ http://tip.tcl.tk/237\ ,\ an\ implemented\ \[TIP\]\ describing\ arbitrary-precision\ Integers\ for\ Tcl.\ This\ is\ available\ in\ Tcl\ 8.5.\nTcl\ 8.5\ features\ abritrary-precision\ integers.\ \ See\n\n\n**\ See\ Also\ **\n\n\n\ \ \ \[if\]:\ \ \ \n\ \ \ \[for\]:\ \ \ \n\ \ \ \[while\]:\ \ \ \n\ \ \ \[Brace\ your\ expr-essions\]:\ \ \ \n\ \ \ \[DebuggingExprCalls\]:\ \ \ \[rwm\]\ sometimes\ it\ is\ difficult\ to\ debug\ expr\ calls\ where\ the\ operands\ are\ variables.\ \[DebuggingExprCalls\]\ explains\ how\ to\ wrap\ expr\ to\ help\ with\ these\ cases.\n\ \ \ \[expr\ problems\ with\ int\]:\ \ \ limits\ of\ number\ representation\ (both\ integer\ and\ float)\ inherited\ from\ C\n\ \ \ \[Importing\ expr\ functions\]:\ \ \ use\ expr's\ functions\ without\ explicitly\ calling\ that,\ see\ \[Importing\ expr\ functions\].\n\ \ \ \[A\ real\ problem\]:\ \ \ \n\ \ \ \[Math\ function\ help\]:\ \ \ \n\ \ \ \[How\ can\ I\ do\ math\ in\ Tcl\]:\ \ \ \n\ \ \ \[Additional\ math\ functions\]:\ \ \ \n\ \ \ \[double\ substitution\]:\ \ \ \n\ \ \ \[Modeling\ COND\ with\ expr\]:\ \ \ Braced\ expressions\ can\ span\ several\ lines\n\ \ \ \[A\ little\ math\ language\]:\ \ \ adds\ features\ &\ sugar\ to\ expr\n\ \ \ \[compute\]:\ \ \ more\ sugar\ for\ expr\n\ \ \ \[Tcl\ help\]:\ \ \ \n\ \ \ \[Numerical\ Analysis\ in\ Tcl\]:\ \ \ \n\ \ \ TIP\ #123\ \[http://tip.tcl.tk/123\]:\ \ \ Adding\ an\ Exponentiation\ Operator\ to\ the\ expr\ Command\n\ \ \ TIP\ #174\ \[http://tip.tcl.tk/174\]:\ \ \ \[Math\ Operators\ as\ Commands\]\n\ \ \ TIP\ #182\ \[http://tip.tcl.tk/182\]:\ \ \ Add\ 'expr\ bool'\ Math\ Function\n\ \ \ TIP\ #201\ \[http://tip.tcl.tk/201\]:\ \ \ Add\ 'in'\ Operator\ to\ expr\n\ \ \ TIP\ #232\ \[http://tip.tcl.tk/232\]:\ \ \ Creating\ New\ Math\ Functions\ for\ the\ 'expr'\ Command\ (\[tcl::mathfunc\])\n\ \ \ TIP\ #237\ \[http://tip.tcl.tk/237\]:\ \ \ Arbitrary-Precision\ Integers\ for\ Tcl\n\n**\ Half-Bakery\ **\n\n\[RS\]\ suggests\ expr's\ arguments\ could\ be\ reparsed\ so\ that\ full\ mathematical\n\n\[RS\]\ 2003-04-24:\ Here's\ a\ tiny\ wrapper\ for\ friends\ of\ infix\ assignment:\n\n======none\nproc\ let\ \{var\ =\ args\}\ \{\n\ \ \ \ uplevel\ 1\ set\ \$var\ \\\[expr\ \$args\\\]\n\}\ \;#RS\n======\n\n======none\n%\ let\ i\ =\ 1\n1\n%\ let\ j\ =\ \$i\ +\ 1\n2\n%\ let\ k\ =\ \{\$i\ +\ \$j\}\n3\n======\n\n======\nset\ y\ 2*3\;\ puts\ \[expr\ \$y+0\]\ \;#\ ==>\ 6\n======\n\n\[AM\]:\ The\ problem\ with\ variables\ whose\ values\ are\ actually\ expressions\ is\ that\n\[AM\]\ The\ problem\ with\ variables\ whose\ values\ are\ actually\ expressions\ is\ that\nfor\ caching\ the\ parsed\ expression\ will\ then\ be\ lost.\n\n\[AMG\]:\ This\ reopens\ the\ door\ to\ all\ the\ security,\ performance,\ and\ correctness\ problems\ solved\ by\ bracing\ one's\ expressions.\n**\ Discussion\ **\n\[Wookie\]:\ \ I\ had\ some\ trouble\ recently\ using\ `expr`\ to\ calculate\ time\n----\n\[RS\]\ 2006-06-19\ A\ word\ of\ warning:\ \[expr\]\ may\ normalize\ strings\ that\ look\ like\ octals\ to\ decimal,\ even\ if\ no\ arithmetic\ operation\ was\ performed\ on\ them:\n\ %set\ bond\ james\n\ %\ expr\ \{\$bond\ eq\ \"\"?\ \"-\":\ \"\$bond\"\}\n\ james\n\ %\ set\ bond\ 0070\n\ %\ expr\ \{\$bond\ eq\ \"\"?\ \"-\":\ \"\$bond\"\}\n\ 56\nBut\ no\ complaints\ if\ the\ string\ cannot\ be\ parsed\ as\ octal:\n\ %\ set\ bond\ 008\n\ %\ expr\ \{\$bond\ eq\ \"\"?\ \"-\":\ \"\$bond\"\}\n\ 008\nIn\ such\ cases\ it's\ better\ and\ more\ robust\ to\ use\ \[if\]:\n\ if\ \{\$bond\ eq\ \"\"\}\ \{set\ bond\ -\}\n\n\[HE\]\ 2006-06-20\ Strange\ behavior!\ The\ manpage\ of\ expr\ says:\n\ eq\ ne\n\ \ Boolean\ string\ equal\ and\ string\ not\ equal.\n\ \ Each\ operator\ produces\ a\ zero/one\ result.\n\ \ The\ operand\ types\ are\ interpreted\ only\ as\ strings.\nThere\ is\ no\ mention\ about\ this\ behavior.\ (I\ remember\ weakly\ this\ two\ operators\ are\ added\ exactly\ to\ avoid\ this\ problem)\nMore\ interesting:\ The\ manpage\ of\ if\ says:\n\ The\ if\ command\ evaluates\ expr1\ as\ an\ expression\ (in\ the\ same\ way\ that\ expr\ evaluates\ its\ argument).\nIs\ there\ something\ wrong?\n\n\[JMN\]\ 2006-10-19\nNot\ really..\ This\ normalization\ isn't\ occurring\ in\ the\ 'eq'\ operation\ -\ it\ happens\ when\ expr\ returns\ the\ result.\nThis\ may\ make\ it\ clearer:\n\n\ %expr\ \{\$bond\ eq\ \"\"?\ \"-\":\ \"hello\ \$bond\"\}\n\ hello\ 0070\n\ %expr\ \{\$bond\}\n\ 56\n\ %expr\ \{\$bond\ eq\ 56\}\n\ 0\n\ %expr\ \{\$bond\ ==\ 56\}\n\ 1\n\n\[LV\]\ Note\ the\ previous\ discussions\ on\ this\ page\ regarding\ the\ precautions\ one\ should\ keep\ in\ mind\ when\ using\ eq\ on\ tcl\ variables\ which\ contain\ numeric\ values.\ I\ am\ not\ certain\ I\ can\ think\ of\ a\ case\ where\ one\ would\ use\ eq\ when\ comparing\ numeric\ values...\n\n----\n\n\[Wookie\]\ I\ had\ some\ trouble\ recently\ using\ expr\ to\ calculate\ time\ offsets.\ I\ had\ 2\ time\ stamps\ in\ the\ form\ hh:mm\nSo\ I\ had\ 4\ variables\ h1,\ m1,\ h2,\ m2\ and\ one\ of\ my\ `expr`\ functions\ was\nSo\ I\ had\ 4\ variables\ h1,\ m1,\ h2,\ m2\ and\ one\ of\ my\ expr\ functions\ was\n======\nset\ result\ \[expr\ \{\$m1\ +\ \$m2\}\]\nset\ result\ \[expr\ (\$m1\ +\ \$m2)\]\n\nAs\ many\ of\ you\ may\ be\ thinking,\ you\ fool!\ what\ about\ 08\ and\ 09,\ which\ will\ get\nAs\ many\ of\ you\ may\ be\ thinking,\ you\ fool!\ what\ about\ 08\ and\ 09,\ which\ will\ get\ treated\ as\ invalid\ octal.\ So\ after\ some\ grumbling\ I\ thought\ okay\ so\ I\ have\ to\ trimleft\ them.\ Bit\ verbose\ but\ who\ cares:\n======\nset\ m1\ \[string\ trimleft\ \$m1\ 0\]\nset\ m2\ \[string\ trimleft\ \$m2\ 0\]\nset\ result\ \[expr\ (\$m1\ +\ \$m2)\]\n======\n\nNow\ what\ could\ possibly\ go\ wrong\ with\ that...\ well\ obviously\ 00\ becomes\ the\nNow\ what\ could\ possibly\ go\ wrong\ with\ that...\ well\ obviously\ 00\ becomes\ \"\",\ which\ causes\ unexpected\ closed\ parameter\ in\ the\ expr.\ So\ now\ I\ have\ to\ check\ for\ \"\".\ So...\n======\nset\ m1\ \[string\ trimleft\ \$m1\ 0\]\nif\ \{\$m1==\{\}\}\ \{set\ m1\ 0\}\nif\ \{\$m1==\"\"\}\ \{\ set\ m1\ 0\ \}\nset\ m2\ \[string\ trimleft\ \$m2\ 0\]\nif\ \{\$m2==\{\}\}\ \{set\ m2\ 0\}\nif\ \{\$m2==\"\"\}\ \{\ set\ m2\ 0\ \}\nset\ result\ \[expr\ \{\$m1\ +\ \$m2\}\]\nset\ result\ \[expr\ (\$m1\ +\ \$m2)\]\n\n...\ and\ then\ repeat\ it\ for\ the\ hours.\ It\ all\ seemed\ very\ clumsy.\ So\ I\ came\ up\n...\ and\ then\ repeat\ it\ for\ the\ hours.\ It\ all\ seemed\ very\ clumsy.\ So\ I\ came\ up\ with\ this,\ which\ may\ solve\ many\ of\ the\ conversion\ issues\ in\ this\ section.\n======\nscan\ \"\$h1:\$m1\ \$h2:\$m2\"\ \"%d:%d\ %d:%d\"\ h1\ m1\ h2\ m2\nset\ result\ \[expr\ \{\$m1\ +\ \$m2\}\]\nset\ result\ \[expr\ (\$m1\ +\ \$m2)\]\n\nAll\ the\ conversions\ to\ int\ have\ been\ done\ and\ leading\ 0's\ have\ been\ stripped\nAll\ the\ conversions\ to\ int\ have\ been\ done\ and\ leading\ 0's\ have\ been\ stripped\ and\ returns\ 0\ if\ the\ value\ is\ all\ 0s.\ This\ works\ for\ float\ and\ probably\ double\ (though\ I've\ not\ tried).\ Can\ anyone\ see\ any\ problems\ with\ this\ approach?\n\[glennj\]:\ No,\ `\[scan\]`\ is\ definitely\ the\ way\ to\ parse\ numbers\ out\ of\ dates\n\[glennj\]\ No,\ \[scan\]\ is\ definitely\ the\ way\ to\ parse\ numbers\ out\ of\ dates\ and\ times.\ \ However,\ for\ date\ arithmetic,\ nothing\ beats\ \[clock\].\ \ \n======\n#\ adding\ a\ delta\ to\ a\ time\nset\ h1\ 12\;\ set\ m1\ 45\nset\ h2\ 3\;\ set\ m2\ 30\nclock\ format\ \[clock\ add\ \[clock\ scan\ \"\$h1:\$m1\"\ -format\ \"%H:%M\"\]\ \$h2\ hours\ \$m2\ minutes\]\ -format\ %T\ \;#\ ==>\ 16:15:00\n======\n\n\n} CALL {my revision expr} CALL {::oo::Obj1808164 process revision/expr} CALL {::oo::Obj1808162 process}

-errorcode

NONE

-errorinfo

Unknow state transition: LINE -> END
    while executing
"error $msg"
    (class "::Wiki" method "render_wikit" line 6)
    invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
    (class "::Wiki" method "render" line 8)
    invoked from within
"my render $name $C"
    (class "::Wiki" method "revision" line 31)
    invoked from within
"my revision $page"
    (class "::Wiki" method "process" line 56)
    invoked from within
"$server process [string trim $uri /]"

-errorline

4