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 ...
随机推荐
- (4)Oracle基础--操作表中数据
· 添加数据 <1> INSERT 语句 ① 向表中所有字段添加值 语法: INSERT INTO table_name (column1,column2...) VALUES(val ...
- ReentrantLock锁的释放
一:代码 reentrantLock.unlock(); 虽然只有一句,但是源码却比较多: public final boolean release(int arg) { if (tryRelease ...
- JSP知识汇总
JSP知识汇总 一.简介 > HTML - HTML擅长显示一个静态的网页,但是不能调用Java程序. > Servlet - Servlet擅长调用Java程序和后台进行交互,但是它不擅 ...
- ionic的基础学习(第一篇)
1.ioinc的头部与底部 1.Header 固定在屏幕的顶端的组件,可包含标题,左右的功能按钮.(提供很多颜色的样式,及调用不同的样式名,亦可自定义) bar-light,bar-stable,ba ...
- 剑指offer四十之数组中只出现一次的数字
一.题目 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 二.思路 建一个hashMap,统计各数字出现的次数,然后遍历hashMap,输出出现一次的数字 ...
- (转)MYSQL线程池总结(一)
MYSQL线程池总结(一) 原文:http://www.cnblogs.com/cchust/p/4510039.html 线程池是Mysql5.6的一个核心功能,对于服务器应用而言,无论是web应 ...
- HTML页面的重绘(repaint)和重流(reflow)
重流(Reflow)是指布局引擎为frame计算图形的过程. frame是一个矩形,拥有宽高和相对父容器的偏移.frame用来显示盒模型(content model), 但一个content mode ...
- CentOS7 配置 Redis Sentinel主从集群配置
Redis Sentinel主从集群 环境.准备 slave配置 sentinel配置 测试 C#连接Redis Sentinel 1.环境.准备 单实例3台CentOS7服务器,IP地址.: 192 ...
- python基础笔记之注释三种方法
---恢复内容开始--- 1,,单行注释 用# 2,多行注释 用 “”” dddd""" 3,较长行虽然分行写但是只是注释,最终显示为一行:用 \ ---恢复内容结束- ...
- Intellij-怎么避免import.*包,以及import包顺序问题
Intellij版本 IntelliJ IDEA 2018.1.2 (Ultimate Edition) Build #IU-181.4668.68, built on April 24, 2018 ...