一个由IsPrime算法引发的细节问题
//*******************************
//
// 2014年9月18日星期四,于宿舍撰写
// 作者:夏华林
//
//********************************
好久没有没有更新博客了,最近确实烦心事儿挺多,已经大三了,真的静下心来好好看看书了。
今天要说的,就是一个由IsPrime算法引发的细节问题,我这里说的细节,是我所认为的,若有不妥,望指正!
一个简单的IsPrime算法的实现如下:
bool IsPrime(int n)
{
int i; if(n % == )return false;
for(i = ; i <= sqrt(n); i += )
{
if(n%i == )return false;
}
return true;
}
这段代码中有一些严重的错误,很明显的就是,当参数为1和2的时候,函数就会返回一个错误的答案,要解决这个问题,最简单的方法就是单独检查1和2,可以在函数的开头简单的加入:
if(n <= )return false;
if(n == )return true;
还有一个性能上的问题,IsPrime算法的本意是为了提高效率,但实际情况下,有时候却会比老的算法花的时间更长。
这种问题存在于for循环的控制行中:
for(i = ; i <= sqrt(n); i += )
尽管现代计算机能在相当短的时间内计算平方根,但,计算平方根还是会比执行简单的算术运算要花的时间要长。程序中,每执行一次循环,都要计算一下sqrt(n),而n在整个循环中都是不变的量,那么我们每次循环都计算一下sqrt(n)就显得不那么划算,为了避免一次次的调用sqrt()函数,可以在循环前先计算出sqrt(n),把它存入一个变量,例如:
double limit = sqrt(n);
for(i = ; i <= limit; i += )
这个简单的改变,将明显的改善了IsPrime算法的实现效率。
这个IsPrime算法还有一个很难查出的问题,发现这个逻辑错误是很难的,因为它可能在你成千上万的测试例子中都不会出现,而对于一些特殊的测试例子,这个实现可能会在一些机器上能得出正确结果,而在另一个机器上得出不正确的答案。
为了理解这个问题,我觉得自己还是有必要再补写一篇关于计算机浮点数相关的文章,但限于篇幅,这里就不详细叙述其原理了
对浮点数判断严格的相等,是一个危险的行为。假设n是49,它是7的平方,当计算机对49调用sqrt()函数时,会返回什么?在严格的数学领域,这个平方根是7,但计算机并不是在这个领域内运作的,它返回的仅仅是一个接近7的浮点数,而这个数可能是6.9999999999999999999,尽管这个数很接近7,但这个差别足以影响i<=limit的结果。如果i是7,而limit是6.999999999,则循环的最后一个周期将不会得到执行,程序永远不会检查到是否可以整除7,而7又是49唯一的质因子,这样程序会错误的将49分类素数。另一方面,如果sqrt(49)返回的是7.0或者7.0000000001,那么IsPrime算法将会得到正确的答案。因而,这个实现的正确性居然要取决于硬件是如何执行浮点数运算的,而让一个算法的正确性依赖于运行它的计算机的特性是一个严重的错误。这个问题很容易解决,如果n的平方根小于某一个界限,为了保险起见,我们总倾向于多检查一个可能的约数,多测试一个约数并不会有什么害处,仅仅是付出一个非常小的代价,就能确保算法能在不同硬件上得到正确性的执行,这样的取舍对于我们来说是相当合算的
只要简单的修改:
double limit = sqrt(n) + ;
IsPrime算法本身是一个非常简单的,但其中的细节却值得我们引起足够的重视。
一个由IsPrime算法引发的细节问题的更多相关文章
- 【红外DDE算法】数字细节增强算法的缘由与效果(我对FLIR文档详解)
[红外DDE算法]数字细节增强算法的缘由与效果(我对FLIR文档详解) 1. 为什么红外系统中图像大多是14bit(甚至更高)?一个红外系统的性能经常以其探测的范围来区别,以及其对最小等效温差指标.首 ...
- ZeroMQ接口函数之 :zmq_z85_decode – 从一个用Z85算法生成的文本中解析出二进制密码
ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_z85_decode zmq_z85_decode(3) ØMQ Manual - ØMQ/4.1 ...
- 一个UUID生成算法的C语言实现 --- WIN32版本 .
一个UUID生成算法的C语言实现——WIN32版本 cheungmine 2007-9-16 根据定义,UUID(Universally Unique IDentifier,也称GUID)在时 ...
- 一个简单的算法,定义一个长度为n的数组,随机顺序存储1至n的的全部正整数,不重复。
前些天看到.net笔试习题集上的一道小题,要求将1至100内的正整数随机填充到一个长度为100的数组,求一个简单的算法. 今天有空写了一下.代码如下,注释比较详细: using System; usi ...
- 手动实现一个虚拟DOM算法
发现一个好文:<深度剖析:如何实现一个 Virtual DOM 算法> 源码 文章写得非常详细,仔细看了一遍代码,加了一些注释.其实还有有一些地方看的不是很懂(毕竟我菜qaq 先码 有时间 ...
- 自己实现一个一致性 Hash 算法
前言 在前文分布式理论(八)-- Consistent Hash(一致性哈希算法)中,我们讨论了一致性 hash 算法的原理,并说了,我们会自己写一个简单的算法.今天就来写一个. 普通 hash 的结 ...
- 一个UUID生成算法的C语言实现——WIN32版本
源: 一个UUID生成算法的C语言实现——WIN32版本
- 一个基于RSA算法的Java数字签名例子
原文地址:一个基于RSA算法的Java数字签名例子 一.前言: 网络数据安全包括数据的本身的安全性.数据的完整性(防止篡改).数据来源的不可否认性等要素.对数据采用加密算法加密可以保证数据本身的安全性 ...
- 能够满足这样要求的哈希算法有很多,其中比较著名并且应用广泛的一个哈希算法,那就是MurmurHash 算法。尽管这个哈希算法在 2008 年才被发明出来,但现在它已经广泛应用到 Redis、MemCache、Cassandra、HBase、Lucene 等众多著名的软件中。
能够满足这样要求的哈希算法有很多,其中比较著名并且应用广泛的一个哈希算法,那就是MurmurHash 算法.尽管这个哈希算法在 2008 年才被发明出来,但现在它已经广泛应用到 Redis.MemCa ...
随机推荐
- Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 5020 Solved: 1872[Submit][Status ...
- [Yii][RBAC]Yii中应用RBAC完全指南
开端筹办 Yii供给了强大的设备机制和很多现成的类库.在Yii中应用RBAC是很简单的,完全不须要再写RBAC代码.所以筹办工作就是,打开编辑器,跟我来. 设置参数.建树数据库 在设备数组中,增长以下 ...
- 佛山Uber优步司机奖励政策(2月1日~2月7日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- indexOf()不区分大小写用法
str.toLowerCase().indexOf(str.toLowerCase())>=0; 对字符串进行统一小写转换. indexOf()查找到返回索引值大于=0; 未找到,返回-1; i ...
- Notepad++强大的代码补全和代码提示功能的方法
最近写项目,经常要打开一些文件去修改一些代码段.那么我的项目都是使用ied大型编辑器去写的,每次修改文件,哪怕是一个标点都要用一分钟时间去打开软件.当然,后来我也考虑到使用记事本,但总感觉不是很爽. ...
- 【设计模式 - 23】之模版方法模式(Template)
1 模式简介 模版方法模式的定义: 模版方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. 模版方法模 ...
- uva-10487 - Closest Sums
暴力枚举后去重最后二分加推断找答案 #include<iostream> #include<map> #include<string> #include<cs ...
- Android M(6.0) 权限爬坑之旅
坑一:用Android5.0编译的apk,在Android6.0上运行完全没有问题. 在Android6.0以上才需要在运行时请求权限,在旧Android版本上保留原有逻辑,安装时授予权限. 用旧版本 ...
- 比較具体的handle机制
Android的消息机制,用Android线程间通信的Message机制,Android中Handler的用法--在子线程中更新界面,handler机制 Android的消息机制(一) android ...
- NETBSD-DTARCE
http://www.openbsd.org/papers/ https://2015.asiabsdcon.org/timetable.html.en#T3A http://teachbsd.org ...