位移

如果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:运算的更多相关文章

  1. C Traps:优先级常见错误

    逻辑与关系运算符 if (flags & FLAG != 0) {...} 这类错误以前也犯过,因为!=的优先级比&要高所以实际上是这样的 if (flags & (FLAG ...

  2. PHP赋值运算

    1. 赋值运算:= ,意思是右边表达式的值赋给左边的运算数. $int1=10; $int1=$int1-6; //$int1=4 echo $int1,"<br>"; ...

  3. javascript中的浮点数运算

    解释一下下面代码的输出 console.log(0.1 + 0.2); //0.30000000000000004 console.log(0.1 + 0.2 == 0.3); //false Jav ...

  4. Java 位运算2-LeetCode 201 Bitwise AND of Numbers Range

    在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= ...

  5. 妥协与取舍,解构C#中的小数运算

    题外话 正文开始之前,我首先要感谢博客园提供的这个优秀的平台.通过在这个优秀的平台上和很多志同道合的朋友交流,互相帮助,我也很荣幸的获得了15年的微软MVP的奖项.也使我更加坚信了代码改变世界.感激! ...

  6. 简简单单学会C#位运算

    一.理解位运算 要学会位运算,首先要清楚什么是位运算?程序中的所有内容在计算机内存中都是以二进制的形式储存的(即:0或1),位运算就是直接对在内存中的二进制数的每位进行运算操作 二.理解数字进制 上面 ...

  7. pyhton学习笔记(基础五:数据类型、数据运算)

    数据类型初识 1. 数字 整数:2是一个整数的例子 长整数 不过是大一些的整数 3.23和52.3E-4是浮点数的例子.E标记表示10的幂.在这里,52.3E-4表示52.3*10-4. (-5+4j ...

  8. JS-- 浮点数运算处理

        一. 问题描述 最近在做一个项目,页面上会存在一些JS浮点数的运算,发现JS浮点数运算存在一些bug.譬如: 0.1+0.2 == 0.30000000000000004 0.1 + 0.7 ...

  9. [LeetCode] Plus One Linked List 链表加一运算

    Given a non-negative number represented as a singly linked list of digits, plus one to the number. T ...

随机推荐

  1. JavaScript基础流程控制(3)

    day51 参考:https://www.cnblogs.com/liwenzhou/p/8004649.html for循环 while循环 三元运算 a>b条件成立,选a,不成立选b

  2. Java并发编程之happens-before

    happens-before是JMM最核心的概念,理解happens-before是理解JMM的关键. 一.JMM的设计 首先,让我们先分析一下JMM的设计意图.从JMM的设计者的角度,在设计JMM的 ...

  3. [Python]Threading.Thread之Daemon线程

    之前对Daemon线程理解有偏差,特记录说明: 一.什么是Daemon A thread can be flagged as a "daemon thread". The sign ...

  4. Sip协议

    会话初始协议.SIP是IETF标准进程的一部分,它是在诸如SMTP(简单邮件传送协议)和HTTP(超文本传送协议)基础之上建立起来的(请求应答的通讯模式).微信采用了自主研发的SYNC协议,他通过“握 ...

  5. WebDriverAPI(5)

    将当前浏览器截屏 测试网址 http://www.baidu.com Java语言版本实例 @Test public void captureScreenInCurrentWindows() { dr ...

  6. Kali Linux信息收集工具全集

    001:0trace.tcptraceroute.traceroute 描述:进行路径枚举时,传统基于ICMP协议的探测工具经常会受到屏蔽,造成探测结果不够全面的问题.与此相对基于TCP协议的探测,则 ...

  7. c#调用R

    R.NET使用文档 介绍 本页面涉及R.NET1.5.13. 1.5.13版本在功能上等同于1.5.12,但可作为一个包在NuGet.org上获得. R.NET使.NET框架与R统计语言在同一进程进行 ...

  8. 转:android studio 一直卡在Gradle:Build Running的解决办法

    在使用AS开发安卓应用程序的时候经常会遇到Gradle build running一直在运行甚至卡死的情况,解决方法如下: 方法1: 1.在C:\User\<用户名>\.gradle 目录 ...

  9. http编程(一)使用javaAPI实现

    Java Http编程中常见的实现方式是使用Java 提供的API,另外就是使用Apache提供的 API 1.通过Java提供的API实现Http编程 类:URL:类 URL 代表一个统一资源定位符 ...

  10. webpack4重新梳理一下2

    上一篇已经实现了webpack的基本打包操作,但是并没有使用配置文件,而是使用 CLI 来实现打包. 配置文件 // webpack.config.js module.exports = { //入口 ...