//*******************************

//

//    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算法引发的细节问题的更多相关文章

  1. 【红外DDE算法】数字细节增强算法的缘由与效果(我对FLIR文档详解)

    [红外DDE算法]数字细节增强算法的缘由与效果(我对FLIR文档详解) 1. 为什么红外系统中图像大多是14bit(甚至更高)?一个红外系统的性能经常以其探测的范围来区别,以及其对最小等效温差指标.首 ...

  2. ZeroMQ接口函数之 :zmq_z85_decode – 从一个用Z85算法生成的文本中解析出二进制密码

    ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_z85_decode zmq_z85_decode(3)         ØMQ Manual - ØMQ/4.1 ...

  3. 一个UUID生成算法的C语言实现 --- WIN32版本 .

    一个UUID生成算法的C语言实现——WIN32版本   cheungmine 2007-9-16   根据定义,UUID(Universally Unique IDentifier,也称GUID)在时 ...

  4. 一个简单的算法,定义一个长度为n的数组,随机顺序存储1至n的的全部正整数,不重复。

    前些天看到.net笔试习题集上的一道小题,要求将1至100内的正整数随机填充到一个长度为100的数组,求一个简单的算法. 今天有空写了一下.代码如下,注释比较详细: using System; usi ...

  5. 手动实现一个虚拟DOM算法

    发现一个好文:<深度剖析:如何实现一个 Virtual DOM 算法> 源码 文章写得非常详细,仔细看了一遍代码,加了一些注释.其实还有有一些地方看的不是很懂(毕竟我菜qaq 先码 有时间 ...

  6. 自己实现一个一致性 Hash 算法

    前言 在前文分布式理论(八)-- Consistent Hash(一致性哈希算法)中,我们讨论了一致性 hash 算法的原理,并说了,我们会自己写一个简单的算法.今天就来写一个. 普通 hash 的结 ...

  7. 一个UUID生成算法的C语言实现——WIN32版本

    源: 一个UUID生成算法的C语言实现——WIN32版本

  8. 一个基于RSA算法的Java数字签名例子

    原文地址:一个基于RSA算法的Java数字签名例子 一.前言: 网络数据安全包括数据的本身的安全性.数据的完整性(防止篡改).数据来源的不可否认性等要素.对数据采用加密算法加密可以保证数据本身的安全性 ...

  9. 能够满足这样要求的哈希算法有很多,其中比较著名并且应用广泛的一个哈希算法,那就是MurmurHash 算法。尽管这个哈希算法在 2008 年才被发明出来,但现在它已经广泛应用到 Redis、MemCache、Cassandra、HBase、Lucene 等众多著名的软件中。

    能够满足这样要求的哈希算法有很多,其中比较著名并且应用广泛的一个哈希算法,那就是MurmurHash 算法.尽管这个哈希算法在 2008 年才被发明出来,但现在它已经广泛应用到 Redis.MemCa ...

随机推荐

  1. SLua 中继承 C# 类接口 Slua.Class 的一个 Bug。

    由于目前要把大量的代码移植到 lua 中(真是够虐心的),面向对象肯定少不了,项目的代码都是这么设计的,于是就测试 Slua.Class 接口来扩展 C# 的类,发现有点问题,给作者提交了一个 Iss ...

  2. Web---自己写的一个简单云相册~

    实现的功能是: 用户可以一次上传一个至多个文件. 用户可以下载其他人上传的图片. 用户可以查看其他所有人的图片. 用户只能删除通过自己IP上传的图片. 用到的技术: 文件上传下载.设计模式.Dom4j ...

  3. Android项目开发全程(三)-- 项目的前期搭建、网络请求封装是怎样实现的

    在前两篇博文中已经做了铺垫,下面咱们就可以用前面介绍过的内容开始做一个小项目了(项目中会用到Afinal框架,不会用Afinal的童鞋可以先看一下上一篇博文),正所谓麻雀虽小,五脏俱全,这在里我会尽量 ...

  4. JVM performance profiling (有待整理)

    Agenda memory model 3 parts: heap, permgen (method area) , thread stack(pointer, local var) heap: yo ...

  5. Java内存区域 - 深入Java虚拟机读后总结

    Java虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途,有各自的创建时间和销毁时间,有的区域随着虚拟机进程的启动而存在,有的区域则是依赖用户线程的启动 ...

  6. (7/18)重学Standford_iOS7开发_视图、绘制、手势识别_课程笔记

    第七课: 1.View 一般来说,视图是一个构造块,代表屏幕上一块矩形区域,定义了一个坐标空间,并在其中绘制及添加触控事件等. ①视图的层级关系 一个视图只能有一个父视图,可以有多个子视图 - ( - ...

  7. JMeter Tutorial的安装和具体操作

    1.下载Jmeter 下载地址:http://jmeter.apache.org/download_jmeter.cgi 目前最新版为2.9,其余文件如源代码等也可从如下官网下载: http://jm ...

  8. HTML5到底能给企业带来些什么?

    一.改变企业网络广告的模式与分布 广告是企业网络营销的主要方式之一.十几年来,无论是展示还是互动,基本被Adobe Flash所主宰.然而,HTML5网页的多媒体特性.三维.图形及特效,超炫的浏览体验 ...

  9. android intent 隐式意图和显示意图(activity跳转)

    android中的意图有显示意图和隐式意图两种, 显示意图要求必须知道被激活组件的包和class 隐式意图只需要知道跳转activity的动作和数据,就可以激活对应的组件 A 主activity  B ...

  10. hadoop错误Cannot load libsnappy.so.1 (libsnappy.so.1 cannot open shared object file No such file or directory)!

    报如下错误 解决方法: 1.下载libsnappy.so.1(https://yunpan.cn/cSHRHTBJGVVX6  访问密码 c992) 2.上传到linux系统 3.安装 4.安装完成后 ...