Purpose: To discuss the various kinds of numbers that Tcl can recognize.
The obvious first place to begin on this topic is the integer. An integer is a whole name. For Tcl before version 8.5, a variable could be expected to hold a positive, negative, or zero value equal to what would be held in a C long variable.
To set a Tcl variable to an integer is pretty simple.
% set zero 0 0 % set positive 12345 12345 % set negative -12345 -12345
% set octal 0123 0123 % expr $octal + 1 84 % set hex 0xfeed 0xfeed % expr $hex + 1 65262 % set binary 0b10110100 ;# since 8.6 (TIP#343) 0b10110100 % expr $binary + 1 181
In the older Tcl, there were some unfortunate consequences of representing the number using C data types. One consequence is this - when a variable's value grew large enough, it would eventually raise a Tcl error indicating that the value was too large to be represented as an integer. There were also cases where unexpected results might be seen:
set i 9223372030000100000 ;# see i incrementing set j 9900000000000000000 ;# see i considered < 0 set k 99000000000000000000 ;# see i considered too large proc count {i} { while { $i > 0 } { incr i if {[ expr {$i % 100000}] == 0 } { puts $i } } return $i } puts "final value [count $i]" puts "final value [count $j]" puts "final value [count $k]"
on a SPARC Solaris 9 system using Tcl 8.4.7 reported:
9223372030000200000
:
9900000000000000000 integer value too large to represent while executing "incr i" (procedure "count" line 3) invoked from within "count $i" invoked from within "puts "final value [count $i]"" (file "/tmp/.lwv/tstint.tcl" line 15)
Notice in the initial set commands above, there are two that result in something that the beginner might find unexpected.
Why did the expr using $octal return an 84 when the developer set it to 0123? That's because, in older Tcl's, a value with a leading zero was treated as a base 8 (also known as octal) value. [add pointer to the hazards of octal, the raging debates on how tcl should treat such values, etc.]
And what about the $hex value? That assignmend had one numeric digit - 0 and the rest alphabetic characters! The leading 0x indicates that the remainder of the string should be treated as if it were a base 16 (or hexadecimal) value.
In Tcl 8.5, a literal octal string will be able to be represented with a leading 0o and a literal binary string will be able to be represented with a leading 0b.
If a developer is reading in data from a user, a socket, a file, etc. then it is their responsibility to make use of scan or some other method to get the string converted from the appropriate base into a decimal value for Tcl.
Next there are floating point values.
% set a 1.1 1.1 % expr $a + 1 2.1 % set a 1.0e10 1.0e10 % expr $a + 1 10000000001.0
[Add comments here about the dangers of floating point, and add references to wiki pages extolling the various numerical methods for using binary floating numbers in comparisons, calculations, etc.]