correct round of reals?

Edward Jason Riedy ejr at lotus.CS.Berkeley.EDU
Fri May 12 12:37:56 EDT 2000


And Peter Schneider-Kamp writes:
 - 
 - What is the Right Way(TM) to do it?

Almost a religious question.  The IEEE Right Way depends on
the hardware's rounding mode.  In round-to-+inf, it should 
act like ceil.  Round-to--inf gives floor.  Round-to-zero will
be like the r_int in f2c's sources [(x>0)? floor(x) : -floor(-x)].
In between...

 - IEEE standard seems to be rounding towards the next
 - even integer in .5-cases. How do I do that?

Only in round-to-nearest mode.  What's wrong with straight-forward 
way?  Given MAX_POS_INT and MAX_NEG_INT bounds for the integers...

def rint_to_nearest(x):
	"rint for round-to-nearest mode"
	if not x == x: return x # x is a NaN, return it
	# now deal with +/- Inf, and corner cases that could wrap
	if x > MAX_POS_INT:
		return MAX_POS_INT
	if x < MAX_NEG_INT:
		return MAX_NEG_INT

	if x < 0: s = -1 # save sign
	else: s = 1
	x = abs(x)
	rounding_diff = x - floor(x)
	ix = int(x)
	if rounding_diff < 0.5:
		return s*ix
	elif rounding_diff > 0.5:
		return s*(ix+1)
	else:
		return s*(ix + ix%2)

That should work on any modern machine, I think, but I haven't run it.  
Well, ok, signalling NaNs will do strange things, but they always do
strange things.  There may be some ancient machines that are buggy in 
neat ways and kill it, but I'm not an expert on those.  

Don't try to push performance in this.  If performance is necessary for
a given platform, the platform will probably provide primitives you can
use to make this faster, or you can use binary ops rather than floating-
point ones for that platform's fp layout.  Push correctness and robustness 
first.

Jason



More information about the Python-list mailing list