使用floor(+0.5)做圆有什么不妥? [英] what wronge with using floor(+0.5) as round?

查看:70
本文介绍了使用floor(+0.5)做圆有什么不妥?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须舍入值并将其存储,因为C ++没有舍入函数,因此我使用以下函数:

I have to round value and store it, because the c++ does not has round function I use this:

floor(x+0.5)



但是当我在代码中使用它时,它不起作用:



but when I use it in my code it does not work:

void algo(float xx1, float yy1, float xx2, float yy2, float xx[], float yy[])
{
   double mm, m1, m2;
   m1 = yy2 - yy1;
   m2 = xx2 - xx1;
   mm = m1 / m2;
   yy[0] = yy1;
   xx[0] = xx1;

   if((mm>=-1)&&(mm<=1))
   {
      for(int i=0; i<=xx2; i++)
      {
         yy[i + 1] = floor(yy[i] + mm + 0.5);
         xx[i + 1] = xx[i] + 1;
      }
   }
   else
   {
      for(int i=0; i<=xx2; i++)
      {
         xx[i + 1] = floor(xx[i] + (1/mm) + 0.5);
         yy[i + 1] = yy[i] + 1;
      }
   }
}

推荐答案

您会在这里找到一个很好的答案:
http://www.cplusplus.com/forum/articles/3638/ [
You''ll find a pretty good answer here:
http://www.cplusplus.com/forum/articles/3638/[^]

Best regards
Espen Harlinn


如果将其放在调试器中,这是调试程序时要做的第一件事,您会发现floor()正常工作.

线

If you put this in the debugger which is the FIRST thing to do when debugging a program you will find floor() is working properly.

The line

yy[i+1]=floor(yy[i]+mm+0.5);




使用floor()时会做完全不同的事情,因为yy [i + 1]取决于yy [i].

您正在完全生成另一个系列.

您的算法不正确,需要工作.




does completely different things when you use floor() because yy[i+1] is dependent on yy[i].

You are generating a different series altogether.

Your algorithm is incorrect and needs work.


Espen已经提供了有关四舍五入的良好链接.感谢Espen,我得到了5.

我发布此解决方案的原因是让您意识到,您可能没有意识到有更好的线条绘制算法.它是由杰克·E·布雷森纳姆(Jack E. Bresenham)发明的,并以他的名字命名.

维基百科中的布雷森纳姆算法

该算法的优点在于,它完全可以使用整数运算来运行.这极大地提高了它的速度.浮点格式和整数之间的每次转换始终是一个相对较慢的操作.或者,在您的情况下,您需要对floor进行浮点加(+0.5)函数调用,并且可能在稍后涉及到实际绘图时将其转换为int.因此,对于认真的图形工作,我建议您看一下Bresenham的算法.将Wiki页面上给出的伪代码转换为C代码并不难.

回到四舍五入的主题:我发现C运行时系统从double到int的隐式转换有时很慢. VC ++ V6就是这样.不知道在新版本中是否仍然如此.作为一个好的解决方法,我在CodeProject上的某个地方找到了以下代码(对不起,我不能相信作者;以下文章可能是这样的:
Espen has already contributed a good link regarding the rounding. Thanks Espen, that got my 5.

The reason I post this solution is to make you aware that there is better algorithm for line drawing that you might not be aware of. It was invented by Jack E. Bresenham and is named after him.

Bresenham''s Algorithm in Wikipedia

The nice thing about this algorithm is that it runs completely with integer operations. And that adds tremendously to its speed. Every conversion between floating-point format and integer is always a relatively slow operation. Or in your case you need a floating-point add (+0.5) a function call to floor, and probably later on when it comes to the real drawing a conversion to int. So for serious graphics work I would suggest you take a look at Bresenham''s algorithm. It''s not hard to convert the pseudo-code given on the Wiki page into C code.

Back to the subject of rounding: I have found the implicit conversion from double to int by the C runtime system sometimes a very slow operation. That was true VC++ V6; don''t know if that is still so in newer versions. As a good work-around I found somewhere on CodeProject the following code (sorry that I cannot give credit to the author; might have been the following article: Floating-Point utilities):

inline long RoundInt (double a)
{
    long retval;
    __asm fld a
    __asm fistp retval
    return retval;
}



这个小小的内联函数只能转换为两条机器指令,并且根据我的测量,它比floor(x + 0.5)和以下隐式转换为int更快.

希望对您有帮助.



This little inline function translates into only two machine instructions and is according to my measurements way faster than floor (x + 0.5) and the following implicit conversion to int.

Hope that helped you a little further along the way.


这篇关于使用floor(+0.5)做圆有什么不妥?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆