免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 74463 | 回复: 12
打印 上一主题 下一主题

[C] C语言如何实现浮点数的四舍五入? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-02-03 13:57 |只看该作者 |倒序浏览
C语言对浮点数的支持总是显得比较奇怪,与0比较的时候已经相当麻烦,没想到连简单的四舍五入也总是得不到应有的结果,向高手请教:C语言中有正确的浮点数四舍五入函数么?如果没有,哪位大侠能提供这么一个函数?别告诉我floor之类的哦,它们都不能得到正确结果。谢谢!

论坛徽章:
0
2 [报告]
发表于 2005-02-03 17:03 |只看该作者

C语言如何实现浮点数的四舍五入?

在csdn有大侠回复如下:
float a = 3.456; //保留到小数点后两位
float b =(int)((a * 100) + 0.5) / 100.0;

//output b = 3.46;

我的答复:
感谢大伙的热心。4楼的方法很巧妙。但在负数时有问题,例如-4.9999,精确到2位小数进行四舍五入,应该是-5.00,使用4楼的方法得到-4.99。因此应当判断输入浮点数是负数还是正数,区别处理,如下:

int myround(double indata,int precision,double outdata)
{
  if ( indata>;0.00 )
    *outdata=(int)((indata*precision*10)+0.5)/100.00;
  else
    *outdata=(int)((indata*precision*10)-0.5)/100.00;
  return 0;
}

但是问题是浮点数与0比较的时候不能这么写,应该写成类似下面的:
int myround(double indata,int precision,double outdata)
{
  if ( indata>;0.005 )
    *outdata=(int)((indata*precision*10)+0.5)/100.00;
  else if ( indata<-0.005 )
    *outdata=(int)((indata*precision*10)-0.5)/100.00;
  else *outdata=0.00;
  return 0;
}
这样写就对精确度提出挑战,怎样才能形成一个比较通用的比较方法呢?请高手赐教!

论坛徽章:
0
3 [报告]
发表于 2005-02-03 17:23 |只看该作者

C语言如何实现浮点数的四舍五入?

不好意思,错了。应该是:

int myround(double indata,int precision,double *outdata)
{
  long pre=1,i;

  for (i=0;i<precision;i++) pre=pre*10;
  if ( cy_FloatCompare(indata,0.00)>;0 )
    *outdata=(int)((indata*pre)+0.5)/100.00;
  else
    *outdata=(int)((indata*pre)-0.5)/100.00;
  return 0;
}

cy_FloatCompare是浮点数与0比较的函数,假设它存在。返回值与strcmp相同。

论坛徽章:
0
4 [报告]
发表于 2010-07-19 20:43 |只看该作者
double
Round( src_val, pos )
double src_val;     /* 原始数 */
int    pos;/*小数点位数*/
{
   charstr_tmp_val[3];
   doubleret_val=0.0;
   doubletmp_val=0.0;

    src_val = src_val + 0.000001;
    tmp_val = src_val * usr_pow( pos );
    if( tmp_val >0.000001 )
        tmp_val = tmp_val +0.5;
    else
        tmp_val = tmp_val -0.5;
    tmp_val = modf( tmp_val, &ret_val );

    ret_val = ret_val / usr_pow( pos );

    return( ret_val );
}
long
usr_pow( int i )
{
    switch( i )
    {
        case 0:
            return( 1 );
        case 1:
            return( 10 );
        case 2:
            return( 100 );
        case 3:
            return( 1000 );
        case 4:
            return( 10000 );
        case 5:
            return( 100000 );
        case 6:
            return( 1000000 );
    }
}

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
5 [报告]
发表于 2010-07-20 11:55 |只看该作者
本帖最后由 yulihua49 于 2010-07-20 11:58 编辑
C语言对浮点数的支持总是显得比较奇怪,与0比较的时候已经相当麻烦,没想到连简单的四舍五入也总是得不到应 ...
play123456 发表于 2005-02-03 13:57
  1. #include <math.h>

  2. double fround(double x,int flg,int dig);

  3. double fround(x,flg,dig)
  4. double x;
  5. int flg,dig;
  6. {
  7. double r,y,z;
  8. int i;
  9.         if(!x) return x;
  10.         z=x;
  11.         if(dig > 0) {
  12.                 for(i=0;i<dig;i++) z *= 10;
  13.         } else if(dig < 0) {
  14.                 for(i=0;i<dig;i++) z /= 10;
  15.         } else ;
  16.         r=modf(z,&y);
  17.         switch(flg) {
  18.         case 1:    /*    to - */
  19.                 if(r<0) y--;
  20.                 break;
  21.         case 2:    /*    to + */
  22.                 if(r>0) y++;
  23.                 break;
  24.         case 3: ;  /*    to 0 */
  25.                 break;
  26.         case 4:    /*    to +- */
  27.                 if(z>=0) {
  28.                         if(r>0) y++;
  29.                 } else {
  30.                         if(r<0) y--;
  31.                 }
  32.                 break;
  33.         case 5:   /*    4s5r */
  34.         default:
  35.                 if(z>=0) {
  36.                         if(r>=0.5) y++;
  37.                 } else {
  38.                         if(r<=-0.5) y--;
  39.                 }
  40.         }
  41.         if(dig > 0) {
  42.                 for(i=0;i<dig;i++) y /= 10;
  43.         } else if(dig < 0) {
  44.                 for(i=0;i<dig;i++) y *= 10;
  45.         } else ;
  46.         return(y);
  47. }

复制代码

论坛徽章:
0
6 [报告]
发表于 2010-07-20 17:17 |只看该作者
IEEE754

论坛徽章:
0
7 [报告]
发表于 2010-07-21 09:06 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:50:28
8 [报告]
发表于 2010-07-21 09:33 |只看该作者
math.h里面有现成的啊。
  1. /* 7.12.9.6 */
  2. /* round away from zero, regardless of fpu control word settings */
  3. extern double __cdecl round (double);
  4. extern float __cdecl roundf (float);
  5. extern long double __cdecl roundl (long double);

  6. /* 7.12.9.7  */
  7. extern long __cdecl lround (double);
  8. extern long __cdecl lroundf (float);
  9. extern long __cdecl lroundl (long double);

  10. extern long long __cdecl llround (double);
  11. extern long long __cdecl llroundf (float);
  12. extern long long __cdecl llroundl (long double);
复制代码

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
9 [报告]
发表于 2010-07-21 09:37 |只看该作者
rint,rintf

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
10 [报告]
发表于 2013-04-27 13:16 |只看该作者
“C语言对浮点数的支持总是显得比较奇怪,与0比较的时候已经相当麻烦”
------ 不就是 f==0.0 和 f!=0.0 嘛,麻烦在哪里?fabs(f)<EPSILON 等等都是闲得蛋疼的半瓶子货,建议这些人不要搞C/C++。

“别告诉我floor之类的哦,它们都不能得到正确结果”
------ 怎么可能呐?是你用的不对,如果不能得到正确结果,难道几十年间都没有人发现这个bug?

“float b =(int)((a * 100) + 0.5) / 100.0;”
------ 写得这么累赘可以去撞墙了。更可喜的是,它还是错的,连float表示的范围比int大都不知道。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP