Chermside, Michael wrote:
The only bit that seems tricky to me is determining the crossover value in pure C. How do we do that?
I think that's as simple as pow(FLT_RADIX, DBL_MAX_DIG).
So the comparison would go something like:
def cmp_floatvlong_positive(afloat, along): assert afloat >=0 and along >= 0 if along < FLT_RADIX**DBL_MANT_DIG:
# the long is representable as float return cmp(afloat, float(along)) elif afloat >= FLT_RADIX**DBL_MANT_DIG: # the float is representable as integer return cmp(long(afloat), along) else: # At this point we know: afloat < FLT_RADIX**DBL_MANT_DIG <= along return -1
def cmp_floatvlong(afloat, along): ures = cmp_floatvlong_positive(abs(afloat), abs(along)) if (afloat >= 0) != (along >= 0): return -ures else: return ures
Assuming FLT_RADIX is a power of 2, comparing the long to the crossover value can be implemented by counting bits of magnitude, replacing if along < FLT_RADIX*DBL_MANT_DIG: with if trunc(lg(along)) < lg(FLT_RADIX)DBL_MANT_DIG: The crossover value as a float can be (pre-)computed the straightforward way: pow(FLT_RADIX, DBL_MAX_DIG) will always be exact representable.