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

13

我需要一个函数 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。


6
为什么会有负评?你们只看了第一个答案,就因为ChrisLegend这样宣称就认为这是琐碎的吗? - P i
3
因为没有问题和明显的尝试,所以这样说。 - pickypg
3
@pickypg 你可能是正确的。尽管如此,我认为任何给出负面评价的人都应该考虑一下……问题是隐含的;任何聪明人都不会错过它。另外,我认为用半吊子的实现来混淆视听是不好的做法。这并不能促进一个干净的问答资源。对于几周后浏览问题的人来说,这种表述将清楚地阐明主题,而不会在避免冒犯人们的潜意识文化敏感性时闪烁其词。 - P i
1
考虑一下提示工具对于踩的箭头所说的话:“这个问题没有展示任何研究努力...”。那么你的问题是什么?“我需要一个函数...[以及一些不同的例子]”你清楚地尝试过自己找到解决方案了吗?显然你没有展示出来。实际上,你所做的是一个plzsendtehcodez问题。这可能不是你的本意,但你没有很清楚地表达你的情况。 - Jeff Mercado
1
我认为这个网站是一个教学环境,而教学的重要规则之一就是不要立刻给出完整的答案(也就是所谓的“give teh codez”),因为学生必须努力寻找答案,否则他们将学不到任何东西。 - trutheality
显示剩余6条评论
4个回答

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


哦,你假设a和b已经>=0且<12。那么你可以在我的解决方案中摆脱amod和bmod,最终得到基本相同的结果。 - trutheality
@trutheality,我在我的问题中指定了那个标准。 - P i
使用PHP实现的24小时计算函数:function distMod24($a,$b){ $diff = abs($b-$a); return ($diff<12) ? $diff : 24 - $diff; } - Bryce Chamberlain

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

}

使用数学库。

感谢您发布代码,直觉告诉我一定有更优雅的解决方案(这也是我首次发布的原因)。但如果有的话,我看不到它,也看不清这是否是最简洁的解决方案。 - P i
3
你总是需要比较两个距离(顺时针和逆时针)。 - trutheality

1

我认为我们可以找到一个不需要比较或分支的答案。一行代码搞定。(在我看来,这是最优雅的方式)

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

5.5是从0到11的数线中点。

经过基准测试,似乎比仅通过MIN执行稍微慢一些。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接