简洁的方式来实现圆(c)中? [英] Concise way to implement round() in C?

查看:108
本文介绍了简洁的方式来实现圆(c)中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是没有一个圆形嵌入式C()函数它,它的数学lib中,这将是用C来实现这个简洁的方式?我想将它打印到一个字符串,寻找小数位,然后找到该期后的第一个字符,那么围捕如果> = 5,别人打倒。等在想,如果有更多的东西巧妙的。

The embedded C I'm using doesn't have a round() function it it's math lib, what would be a concise way to implement this in C? I was thinking of printing it to a string, looking for the decimal place, then finding the first char after the period, then rounding up if >= 5, else down. etc. Was wondering if there's something more clever.

谢谢,
弗雷德

Thanks, Fred

推荐答案

您可以重新发明轮子,因为很多其他的答案建议。或者,你可以用别人的轮子 - 我建议Newlib的,这是BSD许可,并且可在嵌入式系统中使用。它正确处理负数,NaN的,无穷大和案件不会被再次presentable作为整数(由于被过大),以及在使用指数有效的方式这样做和掩蔽,而不是通常-昂贵浮动 - 点操作。此外,它的定期测试,让你知道它没有明显的极端情况虫子在里面。

You could re-invent the wheel, as many other answers suggest. Alternately, you could use someone else's wheel -- I'd suggest Newlib's, which is BSD-licensed and intended for use on embedded systems. It properly handles negative numbers, NaNs, infinities, and cases which are not representable as integers (due to being too large), as well as doing so in an efficient manner that uses exponents and masking rather than generally-costlier floating-point operations. In addition, it's regularly tested, so you know it doesn't have glaring corner-case bugs in it.

该Newlib源可以是一个有点尴尬导航,所以这里有你想要的位:

The Newlib source can be a bit awkward to navigate, so here are the bits you want:

浮动版本:
<一href=\"http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/newlib/libm/common/sf_round.c?rev=1.4&content-type=text/plain&cvsroot=src\">http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/newlib/libm/common/sf_round.c?rev=1.4&content-type=text/plain&cvsroot=src

双版本:
<一href=\"http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/newlib/libm/common/s_round.c?rev=1.2&content-type=text/plain&cvsroot=src\">http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/newlib/libm/common/s_round.c?rev=1.2&content-type=text/plain&cvsroot=src

字提取的宏定义在这里:
<一href=\"http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/newlib/libm/common/fdlibm.h?rev=1.9&content-type=text/plain&cvsroot=src\">http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/newlib/libm/common/fdlibm.h?rev=1.9&content-type=text/plain&cvsroot=src

Word-extraction macros defined here: http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/newlib/libm/common/fdlibm.h?rev=1.9&content-type=text/plain&cvsroot=src

如果你需要从那里的其他文件,父目录是这一个:
<一href=\"http://sourceware.org/cgi-bin/cvsweb.cgi/src/newlib/libm/common/?cvsroot=src\">http://sourceware.org/cgi-bin/cvsweb.cgi/src/newlib/libm/common/?cvsroot=src

If you need other files from there, the parent directory is this one: http://sourceware.org/cgi-bin/cvsweb.cgi/src/newlib/libm/common/?cvsroot=src

有关记录,这里的code浮子版本。正如你所看到的,有处理所有正确的情况下,可能需要一点复杂性。

For the record, here's the code for the float version. As you can see, there's a bit of complexity required to deal with all the possible cases correctly.

float roundf(x)
{
  int signbit;
  __uint32_t w;
  /* Most significant word, least significant word. */
  int exponent_less_127;

  GET_FLOAT_WORD(w, x);

  /* Extract sign bit. */
  signbit = w & 0x80000000;

  /* Extract exponent field. */
  exponent_less_127 = (int)((w & 0x7f800000) >> 23) - 127;

  if (exponent_less_127 < 23)
    {
      if (exponent_less_127 < 0)
        {
          w &= 0x80000000;
          if (exponent_less_127 == -1)
            /* Result is +1.0 or -1.0. */
            w |= ((__uint32_t)127 << 23);
        }
      else
        {
          unsigned int exponent_mask = 0x007fffff >> exponent_less_127;
          if ((w & exponent_mask) == 0)
            /* x has an integral value. */
            return x;

          w += 0x00400000 >> exponent_less_127;
          w &= ~exponent_mask;
        }
    }
  else
    {
      if (exponent_less_127 == 128)
        /* x is NaN or infinite. */
        return x + x;
      else
        return x;
    }
  SET_FLOAT_WORD(x, w);
  return x;
}

这篇关于简洁的方式来实现圆(c)中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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