Domanda

I'm using NS-3 (written in c++) to simulate a network environment.

I'm using its flowmonitor class to record performance metrics from a wireless link.

One thing I am collecting is the time variance between the current and previous packet delay or "jitter".

To get this I am subtracting the time value (converted to a double variable) of one packet delay to the previous value.

i.e

0.0159051 - 0.0158002 = 0.0001049

However, after a while the math seems to act very strangely such as:

0.0159003 - 0.0158007 = 9.95972e-05

when the answer should clearly be 0.0000996

To elaborate further, I initially used a diff function to find the difference.

template <typename T1, typename T2>
double diff(const T1& lhs, const T2& rhs)
{
  std::cout << lhs << " - " << rhs << std::endl;
  return lhs - rhs;
}

But since i discovered the error, I tried straight subtraction but I get the same error.

È stato utile?

Soluzione

Floating point format uses binary representation of a mantissa and exponent, it can't precisely express every decimal (decadic) numeric fraction, and it's precision is limited, so be sure to check if the double format can represent your values precisely. More about double format here on wikipedia. There is more questions about floating point precision on stack overflow, check this one and other related to it.

There are some consequences:

  1. you can't count on that you'll get precise value of your desired numbers
  2. you can't simply compare numbers for equality, (1.0+2.0)==3.0 could work, but any more complex calculation with fractions could not compare equal...
  3. precision of floating point number is limited, when you sum or multiply many numbers together, especially with different exponent, you'll accumuate large error in computation (see Kahan summation algorithm)

Altri suggerimenti

Real numbers extend from + infinity to - infinity with infinitesimally small gaps between numbers. This is impossible to represent all real numbers in finite storage.

to get round this problem a computer stores the magnitude of the number (as an exponent) and a number of significant digits (the mantissa). This is similar to writing a number as 1.043 X 10 ^ -5.

Because the storage is not exact, you will get round-off errors and these round-off errors may sometimes be significant. It does mean that you cannot meaningfully compare two real numbers on a computer. At best you can say that they lie closer than a given tolerance.

To illustrate the point, take 1.000 an divide by 3 and then multiply by 3, you should return back to 1.000 but since 1.000 /3 = 0.333 to 3 decimal places, do not be surprised if the result is 0.999. (Computers use binary (base 2) so this might work out differently but the point still stands)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top