Problem Statement
I'm importing a set of coordinate from an unknown source, which I don't have privilege to look into.
set yMin [lindex [lindex $bbox 0] 1]
puts "yMin: <$yMin>"
It works normally.
yMin: <-6.149999999999999e-02>
The brackets are used to check if there are any spaces or even hidden tabs. However, if yMin is multiplied by any number such as 0.5, it goes wrong.
set Y2 [expr {0.5 * $yMin}]
can't use empty string as operand of "*"
while executing "expr {0.5 * $yMin}"
invoked from within "set Y2 [expr {0.5 * $yMin}]"
Even if only yMin is printed, it still has the empty-operand error.
set Y1 [expr $yMin]
puts "Y1: <$Y1>"
empty expression in expression "" (parsing expression "")
invoked from within "expr $yMin"
invoked from within "set Y1 [expr $yMin]"
But there's an interesting test. It works if curly braces are added!
set Y1 [expr {$yMin}]
puts "Y1: <$Y1>"
Y1: <-0.06149999999999999>
How to reproduce the problem
Thanks to Glenn Jackman (see replies below),
% set bbox {{-4.599999999999999e-02 -6.149999999999999e-02} {8.000000000000002e-02 6.149999999999999e-02}}
{-4.599999999999999e-02 -6.149999999999999e-02} {8.000000000000002e-02 6.149999999999999e-02}
% set yMin [lindex [lindex $bbox 0] 1]
-6.149999999999999e-02
% expr {1 + $yMin}
0.9385
Actually, this seems to be not able to reproduce the problem (this is why I have this post). But it could be a template at least.
Trial and Error
The following code is used to check if it's really empty. It turns out not to be empty.
if {$yMin eq {}} {
puts "Empty records"
exit 1
} else {
puts "yMin is not empty: <$yMin>
}
yMin is not empty: <-6.149999999999999e-02>
Finally, I tried trim, map and regsub to remove any spaces and tabs but none of them works.
set trim_yMin [string trim $yMin]
puts "trim_yMin: <$trim_yMin>"
set map_yMin [string map {" " ""} $yMin]
puts "map_yMin: <$map_yMin>"
regsub -all {\s} $yMin {} reg_yMin
puts "reg_yMin: <$reg_yMin>"
if {$trim_yMin eq {} || $map_yMin eq {} || $reg_yMin eq {}} {
puts "Empty records"
exit 1
} else {
puts "trim_yMin is not empty: <$reg_yMin>"
puts "map_yMin is not empty: <$reg_yMin>"
puts "reg_yMin is not empty: <$reg_yMin>"
}
trim_yMin: <-6.149999999999999e-02>
map_yMin: <-6.149999999999999e-02>
reg_yMin: <-6.149999999999999e-02>
trim_yMin is not empty: <-6.149999999999999e-02>
map_yMin is not empty: <-6.149999999999999e-02>
reg_yMin is not empty: <-6.149999999999999e-02>
Here I only shows the result of regsub. Others' results are the same.
set reg_Y2 [expr {0.5 * $reg_yMin}]
puts "0.5 * reg_yMin: $reg_Y2"
can't use empty string as operand of "*"
while executing "expr {0.5 * $reg_yMin}"
invoked from within "set reg_Y2 [expr {0.5 * $reg_yMin}]"
Could you please help me? I really have no idea about what else I can try. Thanks in advance.
Updates and Replies
To Ergwun:
puts $bbox;
set yMin [lindex [lindex $bbox 0] 1]
puts "yMin: <$yMin>"
{-4.599999999999999e-02 -6.149999999999999e-02} {8.000000000000002e-02 6.149999999999999e-02}
yMin: <-6.149999999999999e-02>
set Y2 [expr {0.5 * $yMin}]
puts $Y2
can't use empty string as operand of "*"
while executing "expr {0.5 * $yMin}"
invoked from within "set Y2 [expr {0.5 * $yMin}]"
To benaja:
puts [tcl::unsupported::representation $yMin]
value is a string with a refcount of 4, object pointer at 0x44ed0910, internal representation 0x450d6120:(nil), string representation "-6.14999999999...."
To Shawn,
puts [tcl::unsupported::representation $yMin]
puts [binary encode hex $yMin]
puts [tcl::unsupported::representation $yMin]
puts [string is double -strict $yMin]
puts [tcl::unsupported::representation $yMin]
value is a string with a refcount of 4, object pointer at 0x44ed6030, internal representation 0x450de4b0:(nil), string representation "-6.1499999999..."
2d362e313439393939393939393939393939652d3032
value is a bytearray with a refcount of 4, object pointer at 0x44ed6030, internal representation 0x44ee0dc0:(nil), string representation "-6.1499999999..."
1
value is a double with a refcount of 4, object pointer at 0x44ed6030, internal representation 0xbfaf7ced916872af:(nil), string representation "-6.1499999999..."
set Y2 [expr {0.5 * -6.149999999999999e-02}]
puts "Y2: $Y2"
set new_Y2 [expr {0.5*-6.149999999999999e-02}]
puts "new_Y2: $new_Y2"
Y2: -0.030749999999999996
new_Y2: -0.030749999999999996
To Schelte Bron,
The error message is changed! Maybe it indicates something?
puts [tcl::unsupported::representation $yMin]
set yMin " $yMin"
puts [tcl::unsupported::representation $yMin]
set Y2 [expr {0.5 * $yMin}]
puts $Y2
value is a string with a refcount of 4, object pointer at 0x44ec28a0, internal representation 0x450be540:(nil), string representation "-6.1499999999..."
value is a string with a refcount of 2, object pointer at 0x446bbc70, internal representation 0x44695fd0:(nil), string representation " -6.149999999..."
can't use non-numeric string as operand of "*"
while executing "expr {0.5 * $yMin}"
invoked from within
"set Y2 [expr {0.5 * $yMin}]"
If the calculation still fails after the value has changed to a double after string is double -strict $yMin, then take the result of binary encode hex $yMin, convert it back to a string (using binary decode hex) and use that in the calculation.
puts "Is yMin double? : [string is double -strict $yMin]"
set binary_yMin [binary encode hex $yMin]
set double_binary_yMin [binary decode hex $binary_yMin]
puts "yMin: $yMin"
puts "Binary of double yMin: $binary_yMin"
puts "Double binary double: $double_binary_yMin"
set Y2 [expr {0.5 * $double_binary_yMin}]
puts $Y2
Is yMin double? : 1
yMin: -6.149999999999999e-02
Binary of double yMin: 2d362e313439393939393939393939393939652d3032
Double binary double: -6.149999999999999e-02
can't use empty string as operand of "*"
while executing "expr {0.5 * $double_binary_yMin}"
invoked from within "set Y2 [expr {0.5 * $double_binary_yMin}]"
What do you get with tcl::mathop::* 0.5 $yMin?
puts [tcl::mathop::* 0.5 $yMin]
can't use empty string as operand of "*"
while executing
"tcl::mathop::* 0.5 $yMin"
invoked from within
"puts [tcl::mathop::* 0.5 $yMin]"
Relevant Posts
- Why do Tcler suggest to brace your
expr
essions? - What does it mean -can't use empty string as operand of "*" on tcl-? how to resolve
- How to strip whitespace in string in TCL?
- Removing space from string after reading it from file using TCL
- missing operand at @ in tcl script
- Determine type of a variable in Tcl