当前位置:网站首页>实数范围内的求模(求余)运算:负数求余究竟怎么求
实数范围内的求模(求余)运算:负数求余究竟怎么求
2022-07-26 22:36:00 【叁弟】
背景
最近在一道 Java 习题中,看到这样的一道题:
What is the output when this statement executed:
System.out.printf(-7 % 3);
正整数的取余运算大家都很熟悉,但是对于负数、实数的取余运算,确实给人很新鲜的感觉。于是我对此进行了一些探索。我发现,这里面还是颇有一点可以探索的东西的。
探究
首先,看看自然数的取模运算(定义1):
如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = qd + r 且0 ≤ r < d。其中,q 被称为商,r 被称为余数。
那么对于负数,是否可以沿用这样的定义呢?我们发现,假如我们按照正数求余的规则求 (-7) mod 3 的结果,就可以表示 -7 为 (-3)* 3 +2。其中,2是余数,-3是商。
那么,各种编程语言和计算器是否是按照这样理解的呢?下面是几种软件中对此的理解。
| 语言 | 语句 | 输出 |
|---|---|---|
| C++(G++ 编译) | cout << (-7) % 3; | -1 |
| Java(1.6) | System.out.println((-7) % 3); | -1 |
| Python 2.6 | (-7) % 3 | 2 |
| 百度计算器 | (-7) mod 3 | 2 |
| Google 计算器 | (-7) mod 3 | 2 |
可以看到,结果特别有意思。这个问题是百家争鸣的。看来我们不能直接把正数的法则加在负数上。实际上,在整数范围内,自然数的求余法则并不被很多人所接受,大家大多认可的是下面的这个定义2。
如果a 与d 是整数,d 非零,那么余数 r 满足这样的关系:
a = qd + r , q 为整数,且0 ≤ |r| < |d|。
可以看到,这个定义导致了有负数的求余并不是我们想象的那么简单,比如,-1 和 2 都是 (-7) mod 3 正确的结果,因为这两个数都符合定义。这种情况下,对于取模运算,可能有两个数都可以符合要求。我们把 -1 和 2 分别叫做正余数和负余数。通常,当除以d 时,如果正余数为r1,负余数为r2,那么有
r1 = r2 + d
对负数余数不明确的定义可能导致严重的计算问题,对于处理关键任务的系统,错误的选择会导致严重的后果。
看完了 (-7) mod 3,下面我们来看一看 7 mod (-3) 的情况(看清楚,前面是 7 带负号,现在是 3 带负号)。根据定义2,7 = (-3) * (-2) + 1 或7 = (-3) * (-3) -2,所以余数为 1 或 -2。
| 语言 | 语句 | 输出 |
|---|---|---|
| C++(G++ 编译) | cout << 7 % (-3); | 1 |
| Java(1.6) | System.out.println(7 % (-3)); | 1 |
| Python 2.6 | 7 % (-3) | -2 |
| 百度计算器 | 7 mod (-3) | -2 |
| Google 计算器 | 7 mod (-3) | -2 |
从中我们看到几个很有意思的现象:
- Java 紧随 C++ 的步伐,而 Python、Google、百度步调一致。难道真是物以类聚?联想一下,Google 一直支持 Python,Python 也颇有 Web 特色的感觉,而且 Google Application Engine 也用的 Python,国内的搜索引擎也不约而同地按照 Google 的定义进行运算。
- 可以推断,C++ 和 Java 通常会尽量让商更大一些。比如在 (-7) mod 3中,他们以 -2 为商,余数为 -1。在 Python 和 Google 计算器中,尽量让商更小,所以以 -3 为商。在 7 mod (-3) 中效果相同:C++ 选择了 3 作为商,Python 选择了 2 作为商。但是在正整数运算中,所有语言和计算器都遵循了尽量让商小的原则,因此 7 mod 3 结果为 1 不存在争议,不会有人说它的余数是-2。
- 如果按照第二点的推断,我们测试一下 (-7) mod (-3),结果应该是前一组语言(C++,Java)返回 2,后一组返回 -1。(请注意这只是假设)。
于是我做了实际测试:
| 语言 | 语句 | 输出 |
|---|---|---|
| C++(G++ 编译) | cout << -7 % (-3); | -1 |
| Java(1.6) | System.out.println(-7 % (-3)); | -1 |
| Python 2.6 | -7 % (-3) | -1 |
| 百度计算器 | -7 mod (-3) | -1 |
| Google 计算器 | -7 mod (-3) | -1 |
结果让人大跌眼镜,所有语言和计算机返回结果完全一致。
总结
我们由此可以总结出下面两个结论:
- 对于任何同号的两个整数,其取余结果没有争议,所有语言的运算原则都是使商尽可能小。
- 对于异号的两个整数,C++/Java语言的原则是使商尽可能大,很多新型语言和网页计算器的原则是使商尽可能小。
拓展
最后是拓展时间。对于实数,我们也可以定义取模运算(定义3)。
当 a 和 d 是实数,且d 非零, a 除以 d 会得到另一个实数(商),没有所谓的剩余的数。但如果要求商为一个整数,则余数的概念还是有必要的。可以证明:存在唯一的整数商 q 和唯一的实数 r 使得: a = qd + r, 0 ≤ r < |d|. (转自维基百科)
如上在实数范围内扩展余数的定义在数学理论中并不重要,尽管如此,很多程序语言都实现了这个定义。至于哪些程序语言实现了这个定义,就留给大家自己探究吧!
边栏推荐
- Hcia-r & s self use notes (19) VLAN configuration and experiment, routing between VLANs
- Several inventory terms often used in communication
- Practical project: boost search engine
- 上千Tile的倾斜模型浏览提速,告别一块一块往外蹦的尴尬
- 30、 Modern storage system (management database and distributed storage system)
- Three effective strategies for the transformation of data supply chain to be coordinated and successful
- 第二部分—C语言提高篇_9. 链表
- ES6新特性
- 2022年物联网行业有哪些用例?
- 力扣155题,最小栈
猜你喜欢

04-传统的Synchronized锁

NFT展示指南:如何展示你的NFT藏品

力扣141题:环形链表

Silicon Valley class lesson 5 - Tencent cloud object storage and course classification management

【C语言】经典的递归问题

Vit:vision transformer super detailed with code

会议OA之我的会议

How to use data pipeline to realize test modernization

Azure synapse analytics Performance Optimization Guide (3) -- optimize performance using materialized views (Part 2)

Practical project: boost search engine
随机推荐
[2016] [paper notes] differential frequency tunable THz technology——
【面试:并发篇26:多线程:两阶段终止模式】volatile版本
My SQL is OK. Why is it still so slow? MySQL locking rules
Galaxy securities online account opening commission, is online account opening safe for customer managers
第二部分—C语言提高篇_11. 预处理
Silicon Valley class lesson 6 - Tencent cloud on demand management module (I)
18、打开、保存文件对话框使用小记
Pyqt5 how to set pushbutton click event to obtain file address
Part II - C language improvement_ 9. Linked list
Write golang simple C2 remote control based on grpc
Application of workflow engine in vivo marketing automation | engine 03
[shaders realize distorted outline effect _shader effect Chapter 2]
Typescript notes
About statefulwidget, you have to know the principle and main points!
会议OA项目排座功能以及送审功能
What is the reason for oom during redis shake synchronization in shake database?
Disk expansion process and problems encountered in the virtual machine created by VMWare
Hcia-r & s self use notes (21) STP technical background, STP foundation and data package structure, STP election rules and cases
大疆智图、CC生产了多份数据,如何合并为一份在图新地球进行加载
【2016】【论文笔记】差频可调谐THz技术——