整型运算中的类精度丢失问题--以洛谷P1150 Peter 的烟为例

整形运算是c语言基础运算之一,也就是数学中整数可加和数乘概念的编程实现。

在实际使用过程中,c语言编译器的运算模式是以一次计算作为运算的基础单元,每次计算结束后都会取整。由于int 型数据结束本次运算后自动向下取整的特性,常常会导致除数中无法被整除的部分直接丢失,例如计算(7/4)*4,数学运算的结果为7,编程实现的结果为4。

以洛谷P1150为例,来看看重复规律运算中极易被忽略的整形运算类精度丢失问题。

 

题目:

Peter 有 n 根烟,他每吸完一根烟就把烟蒂保存起来,k(k>1)个烟蒂可以换一个新的烟,那么 Peter 最终能吸到多少根烟呢?

与某些脑筋急转弯不同的是,Peter 并不能从异次元借到烟蒂,抽完后再还回去。

输入格式

每组测试数据一行包括两个整数 n,k(1<n,k≤10^8)

输出格式

对于每组测试数据,输出一行包括一个整数表示最终烟的根数。

 

看似简单,实则暗藏杀机。

问题一:烟蒂循环换烟,抽完烟留下烟蒂,当烟蒂大于某个数时,又可以换取烟。

问题二:测试用例的数据下很多代码都可以得到正确答案,但是当k取一个稍微大一点的值时,由于整数运算的自动向下取整特性,导致精度丢失。即每一次n/k都会丢失一个>0&&<k的烟蒂值,假设它为d,当总循环次数的d之和大于k时,就会导致反映在答案中的误差。

难点三:把无法被k整除的一部分烟蒂取出放下下一次的烟蒂兑换中,从而弥补丢失的精度。

程序如下:

#include<stdio.h>
 int main()
 {
     int a,b,c=0;
     int j=0;
     scanf("%d %d",&a,&b);
     c+=a;
    while(a>=b)
    {
        j=a%b;//把无法被b整除的部分存入变量
        a/=b;
        c+=a;
        a+=j;//取出无法被b整除的部分,加入到后续烟蒂兑换中
    }
     printf("%d",c);
     return 0;
 }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值