C++ 备忘录 (1)
- 取模:
1. 转载自:http://ceeji.net/blog/mod-in-real/
背景 最近在一道 Java 习题中,看到这样的一道题: What is the output when this statement executed:
System.out.printf(- % ); 正整数的取余运算大家都很熟悉,但是对于负数、实数的取余运算,确实给人很新鲜的感觉。于是我对此进行了一些探索。我发现,这里面还是颇有一点可以探索的东西的。 探究 首先,看看自然数的取模运算(定义1): 如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = qd + r 且0 ≤ r < d。其中,q 被称为商,r 被称为余数。 那么对于负数,是否可以沿用这样的定义呢?我们发现,假如我们按照正数求余的规则求 (-) mod 的结果,就可以表示 - 为 (-)* +。其中,2是余数,-3是商。 那么,各种编程语言和计算器是否是按照这样理解的呢?下面是几种软件中对此的理解。 语言 语句 输出
C++(G++ 编译) cout << (-) % ; -
Java(1.6) System.out.println((-) % ); -
Python 2.6 (-) %
百度计算器 (-) mod
Google 计算器 (-) mod
可以看到,结果特别有意思。这个问题是百家争鸣的。看来我们不能直接把正数的法则加在负数上。实际上,在整数范围内,自然数的求余法则并不被很多人所接受,大家大多认可的是下面的这个定义2。 如果a 与d 是整数,d 非零,那么余数 r 满足这样的关系: a = qd + r , q 为整数,且0 ≤ |r| < |d|。 可以看到,这个定义导致了有负数的求余并不是我们想象的那么简单,比如,- 和 都是 (-) mod 正确的结果,因为这两个数都符合定义。这种情况下,对于取模运算,可能有两个数都可以符合要求。我们把 - 和 分别叫做正余数和负余数。通常,当除以d 时,如果正余数为r1,负余数为r2,那么有 r1 = r2 + d 对负数余数不明确的定义可能导致严重的计算问题,对于处理关键任务的系统,错误的选择会导致严重的后果。 看完了 (-) mod ,下面我们来看一看 mod (-) 的情况(看清楚,前面是 带负号,现在是 带负号)。根据定义2, = (-) * (-) + 或7 = (-) * (-) -,所以余数为 或 -。 语言 语句 输出
C++(G++ 编译) cout << % (-);
Java(1.6) System.out.println( % (-));
Python 2.6 % (-) -
百度计算器 mod (-) -
Google 计算器 mod (-) -
从中我们看到几个很有意思的现象: Java 紧随 C++ 的步伐,而 Python、Google、百度步调一致。难道真是物以类聚?联想一下,Google 一直支持 Python,Python 也颇有 Web 特色的感觉,而且 Google Application Engine 也用的 Python,国内的搜索引擎也不约而同地按照 Google 的定义进行运算。
可以推断,C++ 和 Java 通常会尽量让商更大一些。比如在 (-) mod 3中,他们以 - 为商,余数为 -。在 Python 和 Google 计算器中,尽量让商更小,所以以 - 为商。在 mod (-) 中效果相同:C++ 选择了 作为商,Python 选择了 作为商。但是在正整数运算中,所有语言和计算器都遵循了尽量让商小的原则,因此 mod 结果为 不存在争议,不会有人说它的余数是-。
如果按照第二点的推断,我们测试一下 (-) mod (-),结果应该是前一组语言(C++,Java)返回 ,后一组返回 -。(请注意这只是假设)
于是我做了实际测试: 语言 语句 输出
C++(G++ 编译) cout << - % (-); -
Java(1.6) System.out.println(- % (-)); -
Python 2.6 - % (-) -
百度计算器 - mod (-) -
Google 计算器 - mod (-) -
结果让人大跌眼镜,所有语言和计算机返回结果完全一致。 总结 我们由此可以总结出下面两个结论: 对于任何同号的两个整数,其取余结果没有争议,所有语言的运算原则都是使商尽可能小。
对于异号的两个整数,C++/Java语言的原则是使商尽可能大,很多新型语言和网页计算器的原则是使商尽可能小。
拓展 最后是拓展时间。对于实数,我们也可以定义取模运算(定义3)。 当 a 和 d 是实数,且d 非零, a 除以 d 会得到另一个实数(商),没有所谓的剩余的数。但如果要求商为一个整数,则余数的概念还是有必要的。可以证明:存在唯一的整数商 q 和唯一的实数 r 使得: a = qd + r, ≤ r < |d|. (转自维基百科) 如上在实数范围内扩展余数的定义在数学理论中并不重要,尽管如此,很多程序语言都实现了这个定义。至于哪些程序语言实现了这个定义,就留给大家自己探究吧!
2. 5%7=5 4%9=4
小数除大数商0余本身
- while后如果没有花括号"{" "}",则默认紧跟着while的那一句是循环体。
- TJU 小号:tjuacm2015
C++ 备忘录 (1)的更多相关文章
- MementoPattern(备忘录模式)
/** * 备忘录模式 * @author TMAC-J * 用于存储bean的状态 */ public class MementoPattern { public class Memento{ pr ...
- C#设计模式-备忘录模式
访问者模式的实现是把作用于某种数据结构上的操作封装到访问者中,使得操作和数据结构隔离.而本文要介绍的备忘者模式与命令模式有点相似,不同的是,命令模式保存的是发起人的具体命令(命令对应的是行为),而备忘 ...
- Vuex2.0+Vue2.0构建备忘录应用实践
一.介绍Vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化,适合于构建中大型单页应用. ...
- 设计模式03备忘录(java)
先贴代码有空来写内容. 备忘录1 //简单的备忘录,只可以记录上一次修改前的状态,实现撤回一次的操作. class Student{ private String name; private Stri ...
- C#设计模式系列:备忘录模式(Memento)
1.备忘录模式简介 1.1>.定义 备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可以将该对象恢复到原先保存的状态. 1.2>.使用频率 ...
- php实现设计模式之 备忘录模式
<?php /*备忘录模式:在不破坏封装的前提下,获取对象的内部状态,并且在对象外保存该状态.这样就可以将该对象恢复到保存之前的状态(行为模式) * * 发起人:记录当前时刻的内部状态,负责定义 ...
- 十一个行为模式之备忘录模式(Memento Pattern)
定义: 在不破坏原有封装的情况下,捕获一个对象的内部状态,并在对象之外保存.当对象出错或者无效是,可以根据该备忘录进行恢复. 结构图: Originator:原发类,被记录的对象,包含若干内部状态.一 ...
- 自适应备忘录 demo
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- java设计模式之备忘录模式
备忘录模式 备忘录模式是一种软件设计模式:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.一听到备忘录这个字的时候想起了小小时打的游 ...
- 备忘录模式(Memento Pattern)
在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 备忘录模式主要思想是——利用备忘录对象来对保存发起人的内部状态,当发起人需要恢复原 ...
随机推荐
- ASP.NET MVC实现网站验证码功能
网站添加验证码,主要为防止机器人程序批量注册,或对特定的注册用户用特定程序暴力破解方式,以进行不断的登录.灌水等危害网站的操作.验证码被广泛应用在注册.登录.留言等提交信息到服务器端处理的页面中. 在 ...
- 探秘AOP实现原理
可以这么说,AOP是基于动态代理实现的. 那么,这个过程是怎样的? 首先,我们有这样的一个Service类,它是被作为切面的一个类: public class Service implements U ...
- 【Golang】字符串首字母大小写转化
写在前面 在自动化过程中,我们用得最多的可能就是字符串的处理,熟悉Python的都知道在Python中要让一个字符串的首字母大写直接用capitalize就可以了,但是同样的事情在Golang中没有这 ...
- 在每个节点填充向右的指针 Populating Next Right Pointers in Each Node
2018-08-09 16:01:40 一.Populating Next Right Pointers in Each Node 问题描述: 问题求解: 由于是满二叉树,所以很好填充. public ...
- Intellij IDEA 搭建Spring Boot项目(一)
原文出处 第一步选择File –> New –> Project –>Spring Initialer –> 点击Next 第二步自己修改 Group 和 Artifact 字 ...
- Leetcode 79
//这是我写过最难的递归了...//class Solution { public: bool exist(vector<vector<char>>& board, s ...
- POJ 3481 treap
这是利用treap写的二叉排序树,只要理解其中旋转能够改变树的左右子树平衡度,即高度之差,差不多就能掌握treap树的要领了. 相对于其他高级BST,treap树实现应该算最简单了,利用的是随机树产生 ...
- RabbitMQ脑裂问题解决方案调查
现象: RabbitMQ GUI上显示 Network partition detectedMnesia reports that this RabbitMQ cluster has experien ...
- The Architecture of Open Source Applications——阅读笔记part 1
Architects look at thousands of buildings during their training, and study critiques of those buildi ...
- Ybquery项目部署idea
家庭公计网的引用