• 取模:

  1. 转载自:http://ceeji.net/blog/mod-in-real/

  1. 背景
  2.  
  3. 最近在一道 Java 习题中,看到这样的一道题:
  4.  
  5. What is the output when this statement executed:
  6. System.out.printf(- % );
  7.  
  8. 正整数的取余运算大家都很熟悉,但是对于负数、实数的取余运算,确实给人很新鲜的感觉。于是我对此进行了一些探索。我发现,这里面还是颇有一点可以探索的东西的。
  9.  
  10. 探究
  11.  
  12. 首先,看看自然数的取模运算(定义1):
  13.  
  14. 如果ad是两个自然数,d非零,可以证明存在两个唯一的整数 q r,满足 a = qd + r 0 r < d。其中,q 被称为商,r 被称为余数。
  15.  
  16. 那么对于负数,是否可以沿用这样的定义呢?我们发现,假如我们按照正数求余的规则求 (-) mod 的结果,就可以表示 - (-)* +。其中,2是余数,-3是商。
  17.  
  18. 那么,各种编程语言和计算器是否是按照这样理解的呢?下面是几种软件中对此的理解。
  19.  
  20. 语言 语句 输出
  21. C++(G++ 编译) cout << (-) % ; -
  22. Java1.6 System.out.println((-) % ); -
  23. Python 2.6 (-) %
  24. 百度计算器 (-) mod
  25. Google 计算器 (-) mod
  26. 可以看到,结果特别有意思。这个问题是百家争鸣的。看来我们不能直接把正数的法则加在负数上。实际上,在整数范围内,自然数的求余法则并不被很多人所接受,大家大多认可的是下面的这个定义2
  27.  
  28. 如果a d 是整数,d 非零,那么余数 r 满足这样的关系:
  29.  
  30. a = qd + r , q 为整数,且0 |r| < |d|。
  31.  
  32. 可以看到,这个定义导致了有负数的求余并不是我们想象的那么简单,比如,- 都是 (-) mod 正确的结果,因为这两个数都符合定义。这种情况下,对于取模运算,可能有两个数都可以符合要求。我们把 - 分别叫做正余数和负余数。通常,当除以d 时,如果正余数为r1,负余数为r2,那么有
  33.  
  34. r1 = r2 + d
  35.  
  36. 对负数余数不明确的定义可能导致严重的计算问题,对于处理关键任务的系统,错误的选择会导致严重的后果。
  37.  
  38. 看完了 (-) mod ,下面我们来看一看 mod (-) 的情况(看清楚,前面是 带负号,现在是 带负号)。根据定义2 = (-) * (-) + 7 = (-) * (-) -,所以余数为 -。
  39.  
  40. 语言 语句 输出
  41. C++(G++ 编译) cout << % (-);
  42. Java1.6 System.out.println( % (-));
  43. Python 2.6 % (-) -
  44. 百度计算器 mod (-) -
  45. Google 计算器 mod (-) -
  46. 从中我们看到几个很有意思的现象:
  47.  
  48. Java 紧随 C++ 的步伐,而 PythonGoogle、百度步调一致。难道真是物以类聚?联想一下,Google 一直支持 PythonPython 也颇有 Web 特色的感觉,而且 Google Application Engine 也用的 Python,国内的搜索引擎也不约而同地按照 Google 的定义进行运算。
  49. 可以推断,C++ Java 通常会尽量让商更大一些。比如在 (-) mod 3中,他们以 - 为商,余数为 -。在 Python Google 计算器中,尽量让商更小,所以以 - 为商。在 mod (-) 中效果相同:C++ 选择了 作为商,Python 选择了 作为商。但是在正整数运算中,所有语言和计算器都遵循了尽量让商小的原则,因此 mod 结果为 不存在争议,不会有人说它的余数是-。
  50. 如果按照第二点的推断,我们测试一下 (-) mod (-),结果应该是前一组语言(C++,Java)返回 ,后一组返回 -。(请注意这只是假设)
  51. 于是我做了实际测试:
  52.  
  53. 语言 语句 输出
  54. C++(G++ 编译) cout << - % (-); -
  55. Java1.6 System.out.println(- % (-)); -
  56. Python 2.6 - % (-) -
  57. 百度计算器 - mod (-) -
  58. Google 计算器 - mod (-) -
  59. 结果让人大跌眼镜,所有语言和计算机返回结果完全一致。
  60.  
  61. 总结
  62.  
  63. 我们由此可以总结出下面两个结论:
  64.  
  65. 对于任何同号的两个整数,其取余结果没有争议,所有语言的运算原则都是使商尽可能小。
  66. 对于异号的两个整数,C++/Java语言的原则是使商尽可能大,很多新型语言和网页计算器的原则是使商尽可能小。
  67. 拓展
  68.  
  69. 最后是拓展时间。对于实数,我们也可以定义取模运算(定义3)。
  70.  
  71. a d 是实数,且d 非零, a 除以 d 会得到另一个实数(商),没有所谓的剩余的数。但如果要求商为一个整数,则余数的概念还是有必要的。可以证明:存在唯一的整数商 q 和唯一的实数 r 使得: a = qd + r, r < |d|. (转自维基百科)
  72.  
  73. 如上在实数范围内扩展余数的定义在数学理论中并不重要,尽管如此,很多程序语言都实现了这个定义。至于哪些程序语言实现了这个定义,就留给大家自己探究吧!

  

  2. 5%7=5   4%9=4

    小数除大数商0余本身

  • while后如果没有花括号"{" "}",则默认紧跟着while的那一句是循环体。
  • TJU 小号:tjuacm2015

C++ 备忘录 (1)的更多相关文章

  1. MementoPattern(备忘录模式)

    /** * 备忘录模式 * @author TMAC-J * 用于存储bean的状态 */ public class MementoPattern { public class Memento{ pr ...

  2. C#设计模式-备忘录模式

    访问者模式的实现是把作用于某种数据结构上的操作封装到访问者中,使得操作和数据结构隔离.而本文要介绍的备忘者模式与命令模式有点相似,不同的是,命令模式保存的是发起人的具体命令(命令对应的是行为),而备忘 ...

  3. Vuex2.0+Vue2.0构建备忘录应用实践

    一.介绍Vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化,适合于构建中大型单页应用. ...

  4. 设计模式03备忘录(java)

    先贴代码有空来写内容. 备忘录1 //简单的备忘录,只可以记录上一次修改前的状态,实现撤回一次的操作. class Student{ private String name; private Stri ...

  5. C#设计模式系列:备忘录模式(Memento)

    1.备忘录模式简介 1.1>.定义 备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可以将该对象恢复到原先保存的状态. 1.2>.使用频率 ...

  6. php实现设计模式之 备忘录模式

    <?php /*备忘录模式:在不破坏封装的前提下,获取对象的内部状态,并且在对象外保存该状态.这样就可以将该对象恢复到保存之前的状态(行为模式) * * 发起人:记录当前时刻的内部状态,负责定义 ...

  7. 十一个行为模式之备忘录模式(Memento Pattern)

    定义: 在不破坏原有封装的情况下,捕获一个对象的内部状态,并在对象之外保存.当对象出错或者无效是,可以根据该备忘录进行恢复. 结构图: Originator:原发类,被记录的对象,包含若干内部状态.一 ...

  8. 自适应备忘录 demo

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  9. java设计模式之备忘录模式

    备忘录模式 备忘录模式是一种软件设计模式:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.一听到备忘录这个字的时候想起了小小时打的游 ...

  10. 备忘录模式(Memento Pattern)

    在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 备忘录模式主要思想是——利用备忘录对象来对保存发起人的内部状态,当发起人需要恢复原 ...

随机推荐

  1. Codeforces 545D - Queue

    545D - Queue 思路:忍耐时间短的排在前面,从小到大排序,贪心模拟,记录当前等待时间,如过等待时间大于当前的这个人得忍耐时间,那么就把这个人扔到最后面,不要管他了(哼╭(╯^╰)╮,谁叫你那 ...

  2. SQL脚本去重分组统计

    需求:首先有一张表记录学生姓名.科目和成绩,然后模拟插入几条数据,脚本如下: create table score ( Name ),--姓名 subject ),--科目 grade int--成绩 ...

  3. js如何创建JSON对象

    js如何创建JSON对象 一.总结 一句话总结:直接创建js数组和js对象即可,然后JSON.stringify就可以获取json字符串,js中的一切都是对象,而且js中的对象都是json对象 js ...

  4. Jersey 2.x 分支 Java SE 兼容性

    直到 Jersey 2.6 版本,Jersey 将会兼容 Java SE 6.这个情况将会在在 Jersey 2.7 的版本有所改变. 直到 Jersey 版本 2.25x, 所有的 Jersey 的 ...

  5. django-celery定时任务以及异步任务and服务器部署并且运行全部过程

    Celery 应用Celery之前,我想大家都已经了解了,什么是Celery,Celery可以做什么,等等一些关于Celery的问题,在这里我就不一一解释了. 应用之前,要确保环境中添加了Celery ...

  6. hdu-4417-主席树+离线

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. nyoj306 二分+DFS

    走迷宫 时间限制:1000 ms  |  内存限制:65535 KB 难度:5   描述 Dr.Kong设计的机器人卡多非常爱玩,它常常偷偷跑出实验室,在某个游乐场玩之不疲.这天卡多又跑出来了,在SJ ...

  8. XML删除节点

    XmlDocument doc = new XmlDocument(); doc.Load("Order.xml"); XmlNode xn = doc.SelectSingleN ...

  9. 高性能mysql-----MySQL_explain关键字分析查询语句(一)

    转载地址:https://www.cnblogs.com/xpp142857/p/7373005.html   MySQL_explain关键字分析查询语句 通过对查询语句的分析,可以了解查询语句的执 ...

  10. 51nod1210

    题解: 二维树状数组,再矩阵推一下 代码: #include<bits/stdc++.h> using namespace std; typedef long long LL; ; int ...