你以为你真的会计算进度吗?

12 篇文章 0 订阅

现有一需求,计算拷贝文件的进度。假设已知文件总大小t字节,已拷贝了n字节。

对于如此简单的需求,大多数人会第一时间这样实现

 
 
  1. int progress(int t, int n) 
  2.     //已完成除以总大小 
  3.     return n/t*100
  4. }

很抱歉,这样实现你将发现它会只有两个值——0和100。原因是,当一个整数除以另一整数,如果小于0,则 向下取整为0,0*100自然也是等于0。

有人于是用以下实现

 
 
  1. int progress(int t, int n) 
  2.     return 100*n/t; 
  3. }

这种方式在多数情况下工作比较理想,直到某一天,你遇到一个大于2G的文件,你发现传统的32位整数表示不了了。 于是采用64位

 
 
  1. int progress(off_t t, off_t n) 
  2.     return 100*n/t; 
  3. }

off_t是个不错的写法,它在不同系统上有不同的定义。可是,你又发现有人给你传了一个大于文件总大小的值,计算的值超过100了!再改改

 
 
  1. int progress(int t, int n) 
  2.    return min(100*n/t, 100); 
  3. }

不过既然有特殊情况,万一传过来是负的怎么办?再判断一下咯

 
 
  1. int progress(int t, int n) 
  2.    if (t < 0 || n < 0
  3.        return 0
  4.    return min(100*n/t, 100); 
  5. }

应该没问题了吧。但是,你可能没料到,一个足够大的文件,即使64位下,100*n也可能溢出!TMD,真的要逼我祭出绝杀武器吗

 
 
  1. int progress(int t, int n) 
  2.    if (t < 0 || n < 0
  3.        return 0
  4.    double p = double(n); 
  5.    p /= t; 
  6.    p *= 100
  7.    return min(int(p), 100); 
  8. }

应该行了吧,老子都用到双精度了。

呃……最后一句int(p)是个隐患,尼玛能保证p不超过64位整形?

 
 
  1. int progress(int t, int n) 
  2.    if (t < 0 || n < 0
  3.        return 0
  4.    double p = double(n); 
  5.    p /= t; 
  6.    p *= 100
  7.    if (p > 99.0
  8.        return 100
  9.    else 
  10.       return int(p); 
  11. }

相安无事了很长时间,直到一天,一个脑残的家伙给了一个大小为0的文件


程序员真的是一件很危险的职业……


作者:annidy
版权所有,转载请注明出处 blog.csdn.net/ani_di


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值