2

I am new in tcl. I am trying to check if a given number is a whole number but can't seem to find a simple way to do this.

So I have a number2 which is checking if it is on grid. If not a whole number then it is not on grid.

set numberOne 7.5
set grid 2.5
set numberTwo [expr ($numberOne/$grid) ]

if {[string is integer -strict $numberTwo} {
    do something
} else {
    do something else
}

The above code does not work for me since the numberTwo is going to be returned as a floating point number (3.0 in this case)

Python has something like this:

x = 7.5
y = 2.5
z = x/y

if z%1 == 0
   then do something
else
   do something else

Is there a way to do something similar in tcl? If not another alternative could be -

  • take the decimal value of the numberTwo and check if it is 0 or non-0

So something that takes 6.555 returns 555 and takes 6.0 and returns 0. I can then do:

if {$value == 0} {then do something} else {do something else}
Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
Rumman
  • 113
  • 1
  • 3
  • 8
  • 1
    Beware! Though most of the numbers you are using in your question _are_ exactly represented in floating point, many are not (e.g., 0.1, 6.555). Determining if a number is “exactly a whole number” is really extremely difficult because you usually don't have an exact number to start with. This isn't a Tcl issue, this is a floating point number issue (and Tcl happens to use floating point numbers for math and a few other things). – Donal Fellows Nov 01 '12 at 12:22
  • hi, yes I understand. that is why even if my floor value is the same as my value (when value is a whole number). Because of the floating point calculation if {value == floor(value)} isnt working for me. It works in some case, but not in other cases. For example 1750.0 == 1750.0 is true but another time 1775.0 == 1775.0 is NOT because often 1775.0 could be saved as 1775.000000000001 in the system? – Rumman Nov 01 '12 at 13:11

2 Answers2

3

It seems you may not know about Tcl math functions.

if {$value == floor($value)} {

    // ...
}
Andrew Cheong
  • 29,362
  • 15
  • 90
  • 145
  • 1
    The `int()`, `ceil()` or `round()` functions would also work. – Donal Fellows Nov 01 '12 at 12:17
  • Thanks to both. in my case, $value is calculated from a few calculations involving floating points, For example: set value [expr (($someFloat * $anotherFloat) / $anotherNum)] put “value is $value” //for example it could be exactly 1750.0 set floorValue [expr floor($value)] put “floor of value is $floorValue” //this is also 1750.0 Now if I do: if {$value == floor($value)} { put “this is on grid” } else {not on grid} This doesn’t always work because of the floating point number issue you talking about. Is there a way to get around? – Rumman Nov 01 '12 at 13:06
  • @acheong87 - I think i managed to fix the issue. I multiplied the $numberOne by a large number (numberOne is always in x1e-6) so if I multiply it by 1e6 or 1e9 and also multiply the grid value by the name multiplicator, then the method you suggested works. this is strange since the numbers themselves don't change as after multiplication. so before it was something like: numberOne = 8.885x1e-6, grid = 0.005x1e-6, so value = 1777 now: numberOne = 8.885, grid = 0.005, so value = 1777. Before, it failed to recognise value == floor(value) but now it recognises correctly. must be a floating issue – Rumman Nov 02 '12 at 15:54
2

This actually is the solution many people are looking for ;)

proc is_float_whole { float } {
  return [expr abs($float - int($float)) > 0 ? 0 : 1]
}