title: Floating point rounding error moves reported result inside range
body: <p>I am working on a function to report test results together with lower and upper limit for that specific test result. These three values will be converted with a specified formula (aX + b)/c where X is testResult/lowerLimit/upperLimit and a,b and c are floating point numbers.</p>
  
  <p>If the reported test result is inside/outside the specified limits before the conversion it shall also be inside/outside the limit after the conversion in order to ensure the validity of the reported results.</p>
  
  <p>I have identified two cases where an invalid test result will move inside the range after the conversion but I have yet to find a case where the test result is inside the range before the conversion and will be outside the specified limits after conversion. Can this case even occur? I don't believe so? Can it?</p>
  
  <p>Below is some code that produces the two cases that I mentioned together with corrections to ensure the validity of the reported test result.</p>
  
  <p>TLDR: Can the ((TRUE == insideLimitBefore) &amp;&amp; (FALSE == insideLimitAfter)) case in the code below happen?</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdint.h&gt;
  
  #define TRUE    (uint8_t)0x01
  #define FALSE   (uint8_t)0x00
  
  int32_t LinearMapping(const int32_t input);
  void Convert(int32_t testResult, int32_t lowerLimit, int32_t upperLimit);
  
  int main(void)
  {
  
      int32_t lowerLimit = 504;
      int32_t testResult = 503;
      int32_t upperLimit = 1000;
  
      printf("INPUT:\n\tLower limit:\t%d\t\n\tTest result:\t%d\t\n\tUpper limit:\t%d\t\n", lowerLimit, testResult, upperLimit);
      Convert(testResult, lowerLimit, upperLimit);
  
      lowerLimit = 500;
      testResult = 504;
      upperLimit = 503;
  
      printf("INPUT:\n\tLower limit:\t%d\t\n\tTest result:\t%d\t\n\tUpper limit:\t%d\t\n", lowerLimit, testResult, upperLimit);
      Convert(testResult, lowerLimit, upperLimit);
  
      return 0;
  }
  
  int32_t LinearMapping(const int32_t input)
  {
      float retVal;
  
      const float a = 1.0;
      const float b = 1.0;
      const float c = 2.3;
  
      retVal = a * input;
      retVal += b;
      retVal /= c;
  
      return (int32_t)retVal;
  }
  
  void Convert(int32_t testResult, int32_t lowerLimit, int32_t upperLimit)
  {
      uint8_t insideLimitAfter;
      uint8_t belowLowerLimit;
      uint8_t insideLimitBefore = ((lowerLimit &lt;= testResult) &amp;&amp; (testResult &lt;= upperLimit)) ? TRUE : FALSE;
  
      if (FALSE == insideLimitBefore)
      {
          /* testResult is either below or above lowerLimit/upperLimit respectively */
          if (testResult &lt; lowerLimit)
          {
              belowLowerLimit = TRUE;
          }
          else /* testResult &gt; upperLimit */
          {
              belowLowerLimit = FALSE;
          }
      }
  
      testResult = LinearMapping(testResult);
      lowerLimit = LinearMapping(lowerLimit);
      upperLimit = LinearMapping(upperLimit);
  
      insideLimitAfter = ((lowerLimit &lt;= testResult) &amp;&amp; (testResult &lt;= upperLimit)) ? TRUE : FALSE;
  
      if ((FALSE == insideLimitBefore) &amp;&amp; (TRUE == insideLimitAfter))
      {
          if (TRUE == belowLowerLimit)
          {
              printf("OUTPUT:\n\tLower limit:\t%d\t\n\tTest result:\t%d\t\n\tUpper limit:\t%d\t\n", lowerLimit+1, testResult, upperLimit);
          }
          else /* belowLowerLimit == FALSE =&gt; testResult &gt; upperLimit */
          {
              printf("OUTPUT:\n\tLower limit:\t%d\t\n\tTest result:\t%d\t\n\tUpper limit:\t%d\t\n", lowerLimit, testResult, upperLimit-1);
          }
      }
      else if ((TRUE == insideLimitBefore) &amp;&amp; (FALSE == insideLimitAfter))
      {
         /* Is this case even possible? */
      }
      else
      {
          /* Do nothing */
      }
  }
  </code></pre>