C Traps:运算
位移
如果sizeof(int) = 4,那么下面的代码的结果是什么?
int x=255; printf("%d", x>>34);
实际输出:63
在编译这个代码时,编译器会给出警告
[Warning] right shift count >= width of type [enabled by default]
(这时假设位移运算位移步数只能在[0, type_bit_width)范围内)位移操作会对其位移步数对数值位宽(这里int类型为32位)做一次求余操作即上述代码等同于
x >> (34 % 32)
实际上上述的等同不完全正确,当位移步数是负数时
x >> -1 // 0
这时通过%操作不能把位移步数转化到[0, type_bit_width)范围内(-1 % 32 = -1)
更为正确的我们可以用以下代码来等效(商向负无穷取整的一种取余方式,正数:n % m,负数:n % m + m,详见“取余”一节)
int shift = -1
int q = floor(shift / 32.0);
double r = i - q * 32.0;
x >> (int)(r)
可以写一段代码进行测试
#include <stdio.h>
#include <math.h>
int main() {
for (int i=-1; i>-65; i--) {
int sh = i;
int q = (int)floor(sh / 32.0);
double r = sh - q * 32;
printf("custommod: q = % d, r = % g\n", q, r);
int xn = 255;
printf("%d>>%d = %d\n", xn, sh, xn>>(sh));
}
return 0;
}
输出见:http://codepad.org/RzYr6fkI
取余
取余围绕一下公式进行
q * b + r = a
其中q = [a / b],r为余数。
但当a / b为一个浮点数时,它向那个方向取整决定了余数r的取值
- %:朝0取整(a/b为正时向负方向取整,为负时向正方向取整)
下面给出一个比较代码(c中的%操作和上一节中自定义的取余方式)
for (int i=-; i<; i++) {
if (i == ) continue;
printf("(%2d, %d)\n", i, );
printf("%% : q = % d, r = % d \n", i / , i % );
int q = floor(i / 3.0);
double r = i - q * ;
printf("custommod: q = % d, r = % g\n", q, r);
}
运行结果见:http://codepad.org/jSmd5Jnq
另外c语言math库中另有一些取余函数:
- remainder:商向最接近的整数取整
- remquo:商向最接近的整数取整
- fmod:商直接截断小数部分(即向0取整),与%运算符一致
另外在python中%的行为模式与上文自定义的那个取余方式一致见代码:http://codepad.org/XFangjmO
参考:
http://www.cplusplus.com/reference/cmath/remainder/
C traps & pitfalls
http://blog.csdn.net/huasion/article/details/6855900
C Traps:运算的更多相关文章
- C Traps:优先级常见错误
逻辑与关系运算符 if (flags & FLAG != 0) {...} 这类错误以前也犯过,因为!=的优先级比&要高所以实际上是这样的 if (flags & (FLAG ...
- PHP赋值运算
1. 赋值运算:= ,意思是右边表达式的值赋给左边的运算数. $int1=10; $int1=$int1-6; //$int1=4 echo $int1,"<br>"; ...
- javascript中的浮点数运算
解释一下下面代码的输出 console.log(0.1 + 0.2); //0.30000000000000004 console.log(0.1 + 0.2 == 0.3); //false Jav ...
- Java 位运算2-LeetCode 201 Bitwise AND of Numbers Range
在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= ...
- 妥协与取舍,解构C#中的小数运算
题外话 正文开始之前,我首先要感谢博客园提供的这个优秀的平台.通过在这个优秀的平台上和很多志同道合的朋友交流,互相帮助,我也很荣幸的获得了15年的微软MVP的奖项.也使我更加坚信了代码改变世界.感激! ...
- 简简单单学会C#位运算
一.理解位运算 要学会位运算,首先要清楚什么是位运算?程序中的所有内容在计算机内存中都是以二进制的形式储存的(即:0或1),位运算就是直接对在内存中的二进制数的每位进行运算操作 二.理解数字进制 上面 ...
- pyhton学习笔记(基础五:数据类型、数据运算)
数据类型初识 1. 数字 整数:2是一个整数的例子 长整数 不过是大一些的整数 3.23和52.3E-4是浮点数的例子.E标记表示10的幂.在这里,52.3E-4表示52.3*10-4. (-5+4j ...
- JS-- 浮点数运算处理
一. 问题描述 最近在做一个项目,页面上会存在一些JS浮点数的运算,发现JS浮点数运算存在一些bug.譬如: 0.1+0.2 == 0.30000000000000004 0.1 + 0.7 ...
- [LeetCode] Plus One Linked List 链表加一运算
Given a non-negative number represented as a singly linked list of digits, plus one to the number. T ...
随机推荐
- JavaScript基础流程控制(3)
day51 参考:https://www.cnblogs.com/liwenzhou/p/8004649.html for循环 while循环 三元运算 a>b条件成立,选a,不成立选b
- Java并发编程之happens-before
happens-before是JMM最核心的概念,理解happens-before是理解JMM的关键. 一.JMM的设计 首先,让我们先分析一下JMM的设计意图.从JMM的设计者的角度,在设计JMM的 ...
- [Python]Threading.Thread之Daemon线程
之前对Daemon线程理解有偏差,特记录说明: 一.什么是Daemon A thread can be flagged as a "daemon thread". The sign ...
- Sip协议
会话初始协议.SIP是IETF标准进程的一部分,它是在诸如SMTP(简单邮件传送协议)和HTTP(超文本传送协议)基础之上建立起来的(请求应答的通讯模式).微信采用了自主研发的SYNC协议,他通过“握 ...
- WebDriverAPI(5)
将当前浏览器截屏 测试网址 http://www.baidu.com Java语言版本实例 @Test public void captureScreenInCurrentWindows() { dr ...
- Kali Linux信息收集工具全集
001:0trace.tcptraceroute.traceroute 描述:进行路径枚举时,传统基于ICMP协议的探测工具经常会受到屏蔽,造成探测结果不够全面的问题.与此相对基于TCP协议的探测,则 ...
- c#调用R
R.NET使用文档 介绍 本页面涉及R.NET1.5.13. 1.5.13版本在功能上等同于1.5.12,但可作为一个包在NuGet.org上获得. R.NET使.NET框架与R统计语言在同一进程进行 ...
- 转:android studio 一直卡在Gradle:Build Running的解决办法
在使用AS开发安卓应用程序的时候经常会遇到Gradle build running一直在运行甚至卡死的情况,解决方法如下: 方法1: 1.在C:\User\<用户名>\.gradle 目录 ...
- http编程(一)使用javaAPI实现
Java Http编程中常见的实现方式是使用Java 提供的API,另外就是使用Apache提供的 API 1.通过Java提供的API实现Http编程 类:URL:类 URL 代表一个统一资源定位符 ...
- webpack4重新梳理一下2
上一篇已经实现了webpack的基本打包操作,但是并没有使用配置文件,而是使用 CLI 来实现打包. 配置文件 // webpack.config.js module.exports = { //入口 ...