zell
zell

Reputation: 10204

How could I determine the number of unique floating-point numbers in between two arbitrary a and b?

How could I write a generic C routine num(a,b) that calculates the number of floating-point number in between a and b? Assume both a and b are of type double.

For example, num(0,1e-17) should return the number of doubles in between 0 and 1e-17.

Upvotes: 3

Views: 68

Answers (2)

chux
chux

Reputation: 153650

@Pascal Cuoq well explains the lmitations of double representaiton, endian, etc.

Below is a variation on how to extract a sequence number for the double.

unsigned long long SequenceNumber(double d) {
  assert(sizeof(double) == sizeof(uint64_t));
  union {
    double d;
    uint64_t u64;
    int64_t i64;
  } x = {d};
  uint64_t y;

  if (x.i64 < 0) {
    y = 0xFFFFFFFFFFFFFFFF - x.u64;
  } else {
    y = 0x8000000000000000 + x.u64;
  }
  return y;
}

unsigned long long SequenceDiff(double a, double b) {
  unsigned long long sna = SequenceNumber(a);
  unsigned long long snb = SequenceNumber(b);
  return sna > snb ? sna - snb : snb - sna;
}

Upvotes: 3

Pascal Cuoq
Pascal Cuoq

Reputation: 80305

This answer assumes in addition to “both a and b are of type double” that double maps to IEEE 754 double-precision, and that its representation, accessed as a uint64_t integer, is interpreted with the same endianness as floating-point numbers. This is the case on mainstream compilation platforms.

Under these hypotheses, the representations of positive and negative floating-point numbers are consecutive 64-bit integers. So in order to compute how many numbers there are between two floating-point numbers of the same sign, compute the number of integers between their representations interpreted as 64-bit unsigned integers:

double a, b;
…
uint64_t a1, b1;
memcpy(&a1, &a, 8);
memcpy(&b1, &b, 8);
int64_t d = a1 - b1;
if (d<0) d = -d;
d++; /* account for both a and b e.g. if a==b, they enclose one FP number */

If the floating-point numbers do not have the same sign, compute the number of floating-point numbers between the negative one and -0.0, and the number of floating-point numbers between the positive one and +0.0, using the above method. Then sum these two parts.

Upvotes: 7

Related Questions