MB : The subject of this page is to analyse the methods to round a double real value into an integer. The Tcl language provide 4 commands :
It is not obvious to see the effect of these operators on a given data, and that may generate bugs if the wrong operator is chosen. The following is a small Tcl script which shows the effect of the 4 operators on 8 real values from 0 to 2.
for {set i 0} {$i<9} {incr i} { set x [expr {double($i)/4.0}] set ceil [expr {ceil($x)}] set floor [expr {floor($x)}] set round [expr {round($x)}] set int [expr {int($x)}] puts "ceil($x)=\t $ceil, \t floor($x)=\t $floor, \t round($x)=\t $round, \t int($x)=\t $int" }
And this is the result.
ceil(0.0)= | 0.0, | floor(0.0)= | 0.0, | round(0.0)= | 0, | int(0.0)= | 0 |
ceil(0.25)= | 1.0, | floor(0.25)= | 0.0, | round(0.25)= | 0, | int(0.25)= | 0 |
ceil(0.5)= | 1.0, | floor(0.5)= | 0.0, | round(0.5)= | 1, | int(0.5)= | 0 |
ceil(0.75)= | 1.0, | floor(0.75)= | 0.0, | round(0.75)= | 1, | int(0.75)= | 0 |
ceil(1.0)= | 1.0, | floor(1.0)= | 1.0, | round(1.0)= | 1, | int(1.0)= | 1 |
ceil(1.25)= | 2.0, | floor(1.25)= | 1.0, | round(1.25)= | 1, | int(1.25)= | 1 |
ceil(1.5)= | 2.0, | floor(1.5)= | 1.0, | round(1.5)= | 2, | int(1.5)= | 1 |
ceil(1.75)= | 2.0, | floor(1.75)= | 1.0, | round(1.75)= | 2, | int(1.75)= | 1 |
ceil(2.0)= | 2.0, | floor(2.0)= | 2.0, | round(2.0)= | 2, | int(2.0)= | 2 |
The results of ceil() and floor() differ if an arbitrary precision value without direct floating point representation is supplied. Example:
set x 18014398509481983 % expr {ceil($x)} 18014398509481984.0 % expr {floor($x)} 18014398509481982.0
Both results in this case differ from round() because the latter does not convert to floating point and does not change value:
set x 18014398509481983 % expr {round($x)==ceil($x)} 0 % expr {round($x)==floor($x)} 0
See also