C:计算2个浮点数模12之间的距离

问题描述 投票:0回答:5

我需要一个函数 dist( a, b ) // 0 ≤ a,b < 12 which returns the shortest (absolute ie +ve) distance ala clock arithmetic, using modulo 12.

举个例子,

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

编辑:虽然这可以通过一些黑客操作轻松完成,但我觉得必须有一些直观的解决方案,可能使用 fmod 和 modulo 6

c distance modulo
5个回答
16
投票

首先,最佳解决方案并不简单,需要一点思考。

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


7
投票

如果我没看错的话,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;
}

6
投票

类似的东西

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 );

}

使用数学库。


1
投票

我认为我们无需任何比较或分支就能找到答案。一条单行线。 (我认为这是最优雅的方式)

float dist(float a, float b){
    return abs(5.5-((b-(a-5.5))%12.0))
}

5.5 这里是 0 到 11 数轴的中点。

虽然经过基准测试,它似乎可能比仅通过 MIN 慢一点。


0
投票

绝对差值始终在 [0,12) 范围内。从中减去 6 并取绝对值映射到范围 [0,6]9 但“相反”,因此从 6 中减去所有值即可得到

float dist(float a, float b){
    return 6-abs(abs(a-b)-6)
}

© www.soinside.com 2019 - 2024. All rights reserved.