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)
在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 备忘录模式主要思想是——利用备忘录对象来对保存发起人的内部状态,当发起人需要恢复原 ...
随机推荐
- C#匿名对象序列化
//匿名对象序列化 }; Console.WriteLine(JsonConvert.SerializeObject(obj)); //匿名集合序列化 List<object> list ...
- crond 的注意点
本来在控制台调试的好好的程序,一通过crond运行, 就执行不了. 一般需要注意: 1) 环境变量 当前目录 会变成用户的Home 2) /var/log/messages 可以看出 crond 调 ...
- 流氓 2345.com的新动态及解决方法
安装了[电脑公司]的Win7_SP1之后, IE的主页被绑架. 症状是先转到 IE959.com,然后自动跳转到 www.2345.com 网上当然有很多例子了,可是都没有效果. 1. 更改IE设置没 ...
- 雷林鹏分享:Ruby 方法
Ruby 方法 Ruby 方法与其他编程语言中的函数类似.Ruby 方法用于捆绑一个或多个重复的语句到一个单元中. 方法名应以小写字母开头.如果您以大写字母作为方法名的开头,Ruby 可能会把它当作常 ...
- [Java学习] Java Object类
Object 类位于 java.lang 包中,是所有 Java 类的祖先,Java 中的每个类都由它扩展而来. 定义Java类时如果没有显示的指明父类,那么就默认继承了 Object 类.例如: 1 ...
- Confluence 6 使用 LDAP 授权连接一个内部目录 - 用户 Schema 设置
请注意:这部分仅在拷贝用户登录(Copy User on Login)功能被启用后可见. 其他用户 DN(Additional User DN) 这个值被用在进行用户查找和载入的时候来针对 base ...
- hdu3294 manacher
One day, sailormoon girls are so delighted that they intend to research about palindromic strings. O ...
- java.lang.Exception: Socket bind failed: [730048]
严重: Error initializing endpoint java.lang.Exception: Socket bind failed: [730048] ?????????×???(Э?é/ ...
- ES批量索引写入时的ID自动生成算法
对bulk request的处理流程: 1.遍历所有的request,对其做一些加工,主要包括:获取routing(如果mapping里有的话).指定的timestamp(如果没有带timestamp ...
- Openwrt Udev Configure(3)
1 Scope of Document This document describes how to write udev script, when enum usb device mayb ...