【C深度解剖】负数(取余&取模)

一、数学取整

注:这些函数在<math.h>中

1)trunc函数

作用:直接去除数字的小数部分,返回整数部分。

    printf("%.1f\n", trunc(-2.9));  //-2
	printf("%.1f\n", trunc(2.9));   //2

本质是向零取整:
在这里插入图片描述

2)floor函数

作用:本质是向-∞取整

    printf("%.1f\n", floor(-2.9)); //-3 
    printf("%.1f\n", floor(-2.1)); //-3 
    printf("%.1f\n", floor(2.9)); //2 
    printf("%.1f\n", floor(2.1)); //2

在这里插入图片描述

3)ceil函数

作用:本质是向+∞取整

    printf("%.1f\n", ceil(-2.9)); //-2 
    printf("%.1f\n", ceil(-2.1)); //-2 
    printf("%.1f\n", ceil(2.9)); //3 
    printf("%.1f\n", ceil(2.1)); //3

在这里插入图片描述

4)round函数

作用:四舍五入

    printf("%.1f\n", round(2.1)); //2
    printf("%.1f\n", round(-2.1));//-2
    printf("%.1f\n", round(2.9)); //3
    printf("%.1f\n", round(-2.9));//-3

5)总结

	const char* format = "%.1f \t%.1f \t%.1f \t%.1f \t%.1f\n";
	printf("value\tround\tfloor\tceil\ttrunc\n"); 
	printf("-----\t-----\t-----\t----\t-----\n");
	printf(format, 2.3, round(2.3), floor(2.3), ceil(2.3), trunc(2.3));
	printf(format, 3.8, round(3.8), floor(3.8), ceil(3.8), trunc(3.8)); 
	printf(format, 5.5, round(5.5), floor(5.5), ceil(5.5), trunc(5.5)); 
	printf(format, -2.3, round(-2.3), floor(-2.3), ceil(-2.3), trunc(-2.3));
	printf(format, -3.8, round(-3.8), floor(-3.8), ceil(-3.8), trunc(-3.8));
	printf(format, -5.5, round(-5.5), floor(-5.5), ceil(-5.5), trunc(-5.5));

在这里插入图片描述

二、取模与取余

1)初步了解

取模概念:

如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = q*d + r 且0 ≤ r < d。其中,q 被称为商,r 被称为余数。

    int a = 10; 
    int d = 3; 
    printf("%d\n", a%d); //结果是1
    //因为:a=10,d=3,q=3,r=1 0<=r<d(3) 
    //所以:a = q*d+r -> 10=3*3+1

我们对于正数十分熟悉,那么负数呢?
①C语言 vs2019

   int a = -10;
   int d = 3;
   printf("%d\n", a/d); //C语言中是-3,很好理解
   printf("%d\n", a%d);

结果是 -1
②C语言 gcc 4.8.5
结果是 -1
③Python 3.7.3
在这里插入图片描述结果是 2


结论:很显然,上面关于取模的定义,并不能满足语言上的取模运算

因为在C中,现在-10%3出现了负数,根据定义:满足 a = q*d + r 且0 ≤ r < d,C语言中的余数,是不满足定义的, 因为,r<0了。

故,大家对取模有了一个修订版的定义: 如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = q*d + r , q 为整数,且0 ≤ |r| < |d|。其中,q 被称为商,r 被称为余数

有了这个新的定义,那么C中或者Python中的“取模”,就都能解释了。

解释C: -10 = (-3) * 3 + (-1)
解释Python:-10 = (-4)* 3 + 2。
所以,在不同语言,同一个计算表达式,负数“取模”结果是不同的。我们可以称之为分别叫做正余数 和 负余数

2)二者区别

取余和取模一样吗? 这两个并不能严格等价(虽然大部分情况差不多)
取余或者取模,都应该要算出商,然后才能得出余数

本质 1 取整:
取余:尽可能让商,进行向0取整
取模:尽可能让商,向-∞方向取整
故:C中%,本质其实是取余。 Python中%,本质其实是取模。
理解链:
对任何一个大于0的数,对其进行0向取整和-∞取整,取整方向是一致的。故取模等价于取余
对任何一个小于0的数,对其进行0向取整和-∞取整,取整方向是相反的。故取模不等价于取余
同符号数据相除,得到的商,一定是正数(正数vs正整数),即大于0!
故,在对其商进行取整的时候,取模等价于取余。
本质 2 符号:
参与取余的两个数据,如果同符号,取模等价于取余

如果异号呢?
重新看看定义: 如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = q*d + r , q 为整数,且0 ≤ |r| < |d|。其中,q 被称为商,r 被称为余数。

a = qd + r 变换成 r = a - qd 变换成 r = a + (-qd) 对于:x = y + z,这样的表达式,x的符号 与 |y|、|z|中大的数据一致
而r = a + (-q
d)中,|a| 和 |-q*d|的绝对值谁大,取决于商q的取整方式。
c是向0取整的,也就是q本身的绝对值是减小的。

如:
-10/3=-3.333.33 向0取整 -3. a=-10 |10|, -q* d=-(-3)* 3=9 |9|
10/-3=-3.333.33 向0取整 -3. a=10 |10|, -q* d=-(-3)*(-3)=-9 |9|
绝对值都变小了

python是向-∞取整的,也就是q本身的绝对值是增大的。
-10/3=-3.333.33 向-∞取整 -4. a=-10 |10|, -q * d=-(-4)* 3=12 |12|
10/-3=–3.333.33 向-∞取整 -4. a=10 |10|, -q*d=-(-4) * (-3)=-12 |12|
绝对值都变大了

结论:如果参与取余的两个数据符号不同,在C语言中(或者其他采用向0取整的语言如:C++,Java),余数符号,与被除数 相同。

3)结论

1) 浮点数(或者整数相除),是有很多的取整方式的。
2)如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = q*d + r , q 为整数,且0 ≤ |r|< |d|。其中,q 被称为商,r 被称为余数。
3)在不同语言,同一个计算表达式,“取模”结果是不同的。我们可以称之为分别叫做正余数 和 负余数
3)具体余数r的大小,本质是取决于商q的。而商,又取决于除法计算的时候,取整规则。
4)取余vs取模: 取余尽可能让商,进行向0取整。取模尽可能让商,向-∞方向取整。
5)参与取余的两个数据,如果同符号,取模等价于取余
6)如果参与取余的两个数据符号不同,在C语言中(或者其他采用向0取整的语言如:C++,Java),余数符号,与被除数相同。(因为采用的向0取整)

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
&quot;C语言深度解剖&quot;是一本PDF电子书,它在内容上对C语言进行了全面而深入的剖析和解析。该电子书以书签的形式提供,这使得读者可以方便地浏览和导航书中的各个章节。 书中的内容涵盖了C语言的各个方面,包括基本语法、数据类型、运算符、控制语句、函数、指针等。每个章节都提供了详细的解释和示例,以帮助读者更好地理解和掌握C语言的各个概念和特性。 书签功能使得读者可以迅速定位到感兴趣的章节或部分。通过点击书签,读者可以跳转到所选章节的开头或指定的页面,从而节省时间并提高阅读效率。 对于初学者来说,&quot;C语言深度解剖&quot;提供了一个系统而详细的学习资源。读者可以按照自己的学习进度,逐步阅读不同章节,并通过书签功能进行快速导航。这种结构化的学习方式有助于初学者建立起对C语言的整体认识和理解。 对于有一定C语言基础的读者来说,&quot;C语言深度解剖&quot;也是一个很好的参考书籍。书中对于一些较为复杂或深奥的知识点进行了深入分析和讲解,可以帮助读者更深入地理解C语言的工作原理和内部机制。 总之,&quot;C语言深度解剖&quot;是一本内容详尽、结构清晰、带有书签功能的PDF电子书,适合不同层次的读者学习和参考。无论是初学者还是有经验的C语言开发者,都可以从中获到有益的知识和信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zzt.opkk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值