<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><LINK href="C:\Program Files\OE-QuoteFix\styles.css" rel=stylesheet>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2900.2802" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>I've been thinking 
about&nbsp;a function that was recently proposed at python-dev named 'areclose'. 
It is a function that is meant to tell whether two (or possible more) numbers 
are close to each other. It is&nbsp;a function similar to one that exists in 
Numeric.&nbsp;One such implementation is</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>def 
areclose(x,y,abs_tol=1e-8,rel_tol=1e-5):</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>&nbsp;&nbsp;&nbsp; diff = 
abs(x-y)</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>&nbsp;&nbsp;&nbsp; return diff 
&lt;= ans_tol or diff &lt;= rel_tol*max(abs(x),abs(y))</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>(This is the form given by 
Scott Daniels on python-dev.)</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>Anyway, one of 
the&nbsp;rationales for including such a function was:&nbsp;</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2></FONT></SPAN>&nbsp;</DIV>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
  <DIV><SPAN class=q0><FONT face="MS Mincho" size=2>When teaching some 
  programming to total newbies, a common frustration<BR>is how to explain why 
  a==b is False when a and b are floats computed<BR>by different routes which 
  ``should'' give the same results (if<BR>arithmetic had infinite precision). 
  &nbsp;Decimals can help, but another<BR>approach I've found useful is embodied 
  in Numeric.allclose(a,b) --<BR>which returns True if all items of the arrays 
  are ``close'' (equal to<BR>within certain absolute and relative 
  tolerances)</FONT></SPAN></DIV></BLOCKQUOTE>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>The problem with the above 
function, however,&nbsp;is that it *itself* has a comparison between floats and 
it will give undesired result for something like the following 
test:</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>###</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>&gt;&gt;&gt; print areclose(2, 
2.1, .1, 0) #see if 2 and 2.1 are within 0.1 of each other</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>False</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" 
size=2>&gt;&gt;&gt;</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>###</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>Here is an alternative that 
might be a nice companion to the repr() and round() functions: nice(). It is a 
combination of Tim Peter's delightful 'case closed' presentation in the thread, 
"Rounding to n significant digits?" [1]&nbsp;and the hidden magic of "prints" 
simplification of floating point numbers when being asked to show them. 
</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>It's default behavior is to 
return a number in the form that the number would have when being printed. An 
optional argument, however, allows the user to specify the number of digits to 
round the number to as counted from the most significant digit. (An alternative 
name, then, could be 'lround' but I think there is less baggage for the new user 
to think about if the name is something like nice()--a function that makes the 
floating point numbers "play nice." And I also think the name...sounds 
nice.)&nbsp;</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>Here it is in 
action:</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>###</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>&gt;&gt;&gt; 
3*1.1==3.3<BR>False<BR>&gt;&gt;&gt; 
nice(3*1.1)==nice(3.3)<BR>True<BR>&gt;&gt;&gt; x=3.21/0.65; print 
x<BR>4.93846153846</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>&gt;&gt;&gt; print 
nice(x,2)</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>4.9<BR>&gt;&gt;&gt; x=x*1e5; 
print nice(x,2)<BR>490000.0<BR>###</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>Here's the function: 
</FONT></SPAN><SPAN class=q0><FONT face="MS Mincho" size=2></FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>###</FONT></SPAN></DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>def 
nice(x,leadingDigits=0):<BR>&nbsp;"""Return x either as 'print' would show it 
(the default) or rounded to the<BR>&nbsp;specified digit as counted from the 
leftmost non-zero digit of the number,</FONT></SPAN></DIV>
<DIV><FONT face="MS Mincho" size=2></FONT>&nbsp;</DIV>
<DIV><SPAN class=q0><FONT face="MS Mincho" size=2>&nbsp;e.g. nice(0.00326,2) 
--&gt; 0.0033"""<BR></FONT></SPAN>&nbsp;assert leadingDigits&gt;=0<BR>&nbsp;if 
leadingDigits==0:<BR>&nbsp;&nbsp;return float(str(x)) #just give it back like 
'print' would give it<BR>&nbsp;leadingDigits=int(leadingDigits)<BR>&nbsp;return 
float('%.*e' % (leadingDigits,x)) #give it back as rounded by the %e 
format</FONT><BR><FONT face="MS Mincho" size=2>###</FONT></DIV>
<DIV><FONT face="MS Mincho" size=2></FONT><FONT face="MS Mincho" 
size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="MS Mincho" size=2>Might something like this be useful? For new 
users, no arguments are needed other than x and floating points suddenly seem to 
behave in tests made using nice() values. It's also useful for those computing 
who want to show a physically meaningful value that has been rounded to the 
appropriate digit as counted from the most significant digit rather than from 
the decimal point. </FONT></DIV>
<DIV><FONT face="MS Mincho" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="MS Mincho" size=2>Some time back I had worked on the 
significant digit problem and had several math calls to figure out what the 
exponent was. The beauty of Tim's solution is that you just use built in string 
formatting to do the work. Nice.</FONT></DIV>
<DIV><FONT face="MS Mincho" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="MS Mincho" size=2>/c</FONT></DIV>
<DIV><FONT face="MS Mincho" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="MS Mincho" size=2>[1] <A 
href="http://mail.python.org/pipermail/tutor/2004-July/030324.html">http://mail.python.org/pipermail/tutor/2004-July/030324.html</A></FONT></SPAN></DIV></DIV></BODY></HTML>