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 ...
随机推荐
- hdoj1435 Stable Match(稳定婚姻问题)
简单稳定婚姻问题. 题目描述不够全面,当距离相同时容量大的优先选择. 稳定婚姻问题不存在无解情况. #include<iostream> #include<cstring> # ...
- Flask从入门到精通之flask安装
使用虚拟环境 安装Flask最简单的方式是使用虚拟环境,虚拟环境是python解释器的一个私有副本,在这个环境中你可以安装私有包,而且不会影响系统中安装的全局的Python解释器.虚拟环境非常有用,可 ...
- 智能卡操作系统COS概述
随着IC卡从简单的同步卡发展到异步卡,从简单的EPROM卡发展到内带微处理器的智能卡(又称CPU卡),对IC卡的各种要求越来越高.而卡本身所需要的各种管理工作也越来越复杂,因此就迫切地需要有一种工具来 ...
- 腾讯云 利用php + apache + mysql 搭建服务器环境
1.一键安装需要的软件源 yum install -y httpd php php-fpm mysql mysql-server php-mysql 1) httpd 即为 apache 2)php ...
- Observer观察者设计模式
Observer设计模式主要包括以下两种对象: (1)被观察对象:Subject,它往往包含其他对象感兴趣的东西,上面例子中热水器中就是Subject(被监视对象); (2)观察对象:Observer ...
- Ubuntu链接库查找
apt-get install apt-file apt-get update apt-file search
- [转] 用协议分析工具学习TCP/IP
一.前言 目前,网络的速度发展非常快,学习网络的人也越来越多,稍有网络常识的人都知道TCP/IP协议是网络的基础,是Internet的语言,可以说没有TCP/IP协议就没有互联网的今天.目前号称搞网的 ...
- 修改salt-minion的id后报错解决方法
centos7使用命令 /usr/bin/salt-minion start运行报错 Error parsing configuration file: /etc/salt/master - expe ...
- C语言利用异或进行两个值的交换
异或有两个很重要的性质: 1. A^A = 0; 2.A^0 = A; 利用这两个性质,我们就能够利用异或进行两个值的交换. 代码如下: #include <stdio.h> int ma ...
- URL编码分析与乱码解决方案
一.问题的由来 URL就是网址,只要上网,就一定会用到. 一般来说,URL只能使用英文字母.阿拉伯数字和某些标点符号,不能使用其他文字和符号.比如,世界上有英文字母的网址"http://ww ...