43 lines
1.6 KiB
Tcl
43 lines
1.6 KiB
Tcl
catch {namespace delete test_almost_equal_string} ;# Start with a clean namespace
|
|
|
|
namespace eval test_almost_equal_string {
|
|
package require Tcl 8.4 ;# ?Maybe earlier?
|
|
array set yesno {1 Yes 0 No} ;# For nice output
|
|
|
|
proc isClose {a b {prec 9}} {
|
|
proc toCoeff {n prec} {
|
|
set repr 40 ;# Chosen to be arbitrarily large to handle most cases
|
|
set long [format %0.${repr}f $n] ;# Take out of scientific notation
|
|
set map [string map {. {}} $long] ;# Remove decimal point
|
|
set trim [string trimleft $map 0] ;# Remove leading zeros
|
|
# restore string for comparison
|
|
set len [string length $trim]
|
|
if {$len < $prec} {
|
|
set trim "${trim}[string repeat 0 [expr ($prec+1)-$len]]"
|
|
}
|
|
# Round last decimal place
|
|
set rounded [format %0.f "[string range $trim 0 [expr {$prec-1}]].[string index $trim $prec]"]
|
|
return $rounded
|
|
}
|
|
set a_coeff [toCoeff $a $prec]
|
|
set b_coeff [toCoeff $b $prec]
|
|
|
|
return [expr {$a_coeff == $b_coeff}]
|
|
}
|
|
|
|
set data {
|
|
{100000000000000.01 100000000000000.011}
|
|
{100.01 100.011}
|
|
{[expr {10000000000000.001 / 10000.0}] 1000000000.0000001000}
|
|
{0.001 0.0010000001}
|
|
{0.000000000000000000000101 0.0}
|
|
{[expr { sqrt(2) * sqrt(2)}] 2.0}
|
|
{[expr {-sqrt(2) * sqrt(2)}] -2.0}
|
|
{3.14159265358979323846 3.14159265358979324}
|
|
}
|
|
set data [subst $data] ;# resolves expressions in the list
|
|
|
|
foreach {a b} [join $data] {
|
|
puts [format "Is %26s ≈ %21s ? %4s." $a $b $yesno([isClose $a $b])]
|
|
}
|
|
}
|