我需要一个函数 dist(a, b),其中 0 ≤ a,b < 12,该函数返回使用模 12 的时钟算术来计算的最短(绝对值即 +ve)距离。
例如:
dist( 1, 2 )
= dist( 2, 1 )
= dist( 11, 0 )
= dist( 0, 11 )
= dist( 0.5, 11.5 )
= 1
编辑:虽然可以通过一些技巧很容易地实现这个目标,但我觉得一定有一些直观的解决方案,也许是使用 fmod 和模 6。
首先,最优解并不简单,需要一些思考。
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
#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;
}
类似于这样的东西
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 );
}
我认为我们可以找到一个不需要比较或分支的答案。一行代码搞定。(在我看来,这是最优雅的方式)
float dist(float a, float b){
return abs(5.5-((b-(a-5.5))%12.0))
}
5.5是从0到11的数线中点。
经过基准测试,似乎比仅通过MIN执行稍微慢一些。
plzsendtehcodez
问题。这可能不是你的本意,但你没有很清楚地表达你的情况。 - Jeff Mercado