I encountered a floating-point imprecision issue in Awk that I can't solve. Is there a simple solution to it?
Here is my example Awk script to replicate the floating-point imprecision issue.
BEGIN {
print "PREC = " PREC
print "OFMT = " OFMT
print "CONVFMT = " CONVFMT
a = 1.2 + 3.4
b = 8.9 - 4.3
print "a = " a
print "b = " b
if ( a == b )
print "a == b"
else
print "a != b"
c = 3.2 + 5.4
d = 9.8 - 1.2
print "c = " c
print "d = " d
if ( c == d )
print "c == d"
else
print "c != d"
}
Here is the output of the above script.
PREC = 53
OFMT = %.6g
CONVFMT = %.6g
a = 4.6
b = 4.6
a != b
c = 8.6
d = 8.6
c == d
Why is a != b even if both have same values? Yet, c == d works properly.
I assume Awk has some internal floating-point imprecision. FYI, I'm using Gawk 4.1.4.
I tried various values for PREC, OFMT & CONVFMT, but failed to find ones that would work.
E.g. Changed OFMT & CONVFMT to %.6f:
PREC = 53
OFMT = %.6f
CONVFMT = %.6f
a = 4.600000
b = 4.600000
a != b
c = 8.600000
d = 8.600000
c == d
E.g. Changed PREC to 16:
PREC = 16
OFMT = %.6g
CONVFMT = %.6g
a = 4.6
b = 4.6
a != b
c = 8.6
d = 8.6
c == d
Basically, I'm hoping for some settings inside BEGIN, instead of changing every expression where floating-point arithmetic & comparison are, since my actual Awk script is much longer than the example above.
E.g. I rather not having to use sprintf for each arithmetic & comparison expression, or to convert each input number to integer after scaling by 1e6 & convert each output number by 1e-6. Such approach would be very daunting.
FYI, floating-point numbers in input files will have maximum 6 decimal points, but they may be without decimal points, i.e. they range from 0 to 6 decimal points.
Thank you for your help.
HN