C: Расчет расстояния между 2 поплавками по модулю 12 - PullRequest
9 голосов
/ 31 мая 2011

Мне требуется функция dist (a, b) // 0 ≤ a, b <12, которая возвращает кратчайшее (абсолютное, то есть + ve) арифметическое значение часов, используя модуль 12. </p>

Так, например,

dist( 1, 2 )
 = dist( 2, 1 )
 = dist( 11, 0 )
 = dist( 0, 11 )
 = dist( 0.5, 11.5 )
 = 1

РЕДАКТИРОВАТЬ: хотя это легко можно сделать, немного взломав, я чувствую, что должно быть какое-то интуитивное решение, возможно, с использованием fmod и modulo 6

Ответы [ 3 ]

13 голосов
/ 01 июня 2011

Во-первых, оптимальное решение нетривиально, нужно немного подумать.

float distMod12(float a,float b)
{
    float diff = fabs( b - a );
    return ( diff < 6 ) ? diff : 12 - diff;
}

РЕДАКТИРОВАТЬ: в качестве альтернативы,

    return MIN( diff, 12 - diff ); // needs a MIN function

Полный список кодов здесь: http://ideone.com/XxRIw

6 голосов
/ 01 июня 2011

Если я правильно прочитал, a и b не являются отрицательными, и они меньше 12.

#include <math.h>
#include <stdio.h>

double min( double a, double b ) {
   return a < b ? a : b;
}

double dist( double a, double b ) {
   return min( 
      fmod( 12+b-a, 12 ),
      fmod( 12+a-b, 12 )
   );
}

int main() {
   printf("%f\n", dist(1, 2));
   printf("%f\n", dist(2, 1));
   printf("%f\n", dist(11, 0));
   printf("%f\n", dist(0, 11));
   printf("%f\n", dist(0.5, 11.5));
   return 0;
}

, что упрощается до

double dist( double a, double b ) {
   double diff = fmod( 12+a-b, 12 );
   return diff <= 6 ? diff : 12-diff;
}
4 голосов
/ 01 июня 2011

Что-то вроде

float dist( float a, float b ){

   float amod, bmod;

   amod = fmod( a, 12 );
   bmod = fmod( b, 12 );

   if( amod < bmod ) return dist( bmod, amod );

   return min( amod-bmod, bmod-amod+12 );

}

Использование математической библиотеки.

...