Double v.s. Float

Double v.s. Float
最近在做自己的玩具项目Physics2D的时候,对Vector2D是应该使用float还是double类型纠结了很久,通常来说(特别是在学校教学当中),大家都会直观的认为float精度输给double,但是速度会远胜于double,毕竟double比float位数长那么一大截,可实际上真的是这样么?昨天阅读了老赵的博客文章,正巧看到了一个不错的CodeTimer实现,空想没用,干脆用实际测试到的数据说话。 下表为微软给出的两个类型的表示范围以及精度,作为一个参考先放在这里: Type Approximate range Precision float ±1.5e−45 to ±3.4e38 7 digits double ±5.0e−324 to ±1.7e308 15-16 digits   我编写了5组测试用例,分别对应加、减、乘、除以及混合的运算,代码如下所示: [crayon-5a0ee44f4a3bc7482936

使用OpenMP让程序可并行化

使用OpenMP让程序可并行化
在《并行计算》这门课程中我了解到了很多使程序并行化的方法,OpenMP就是其中一种,在实际的使用之后,感觉OpenMP是一种很方便的并行计算工具,它能够提供线程级别的并行化,所以OpenMP一般用于共享内存的单机系统。本文将以K-Means算法作为样例来进行讲解。在介绍算法之前,先做一下热身运动,OpenMP库已经在Visual Studio 2013中集成(前几个版本似乎也有),所以你可以很轻松的为你的Visual Studio项目添加OpenMP支持,在项目属性中,如图所示的地方开启OpenMP支持即可: 热身完毕后进入正题。 K-Means算法是一种聚类算法,顾名思义,它进行划分的方法是依赖于计算均值,算法的整体流程非常简单,假如要把样本分为M个类别:        在样本集N中随机选取M个个体,作为初始类心;        遍历样本中的所有个体,每个个体都与当前的M个类心分别求距离,并将自己和距离最小的那个类心归为一类;        通过平均值的方法计算每一类点...

C# 在PictureBox 中绘图防止闪烁的办法

C# 在PictureBox 中绘图防止闪烁的办法
很久没发技术文章了啊……被人说装文艺了啊……我在乱说些啥吗………… 最近学校开了数据结构的课设设计,说是允许使用C++,Java和C#来进行开发。Java上上个学期学的,说实话,感觉真的不是很爽……或许是我电脑的缘故,也或许是心理作用,我总觉的NetBeans一开就卡得不行!无论怎样都得不到在VS中开发和调试的那种爽快感,于是一度打算投奔C++的阵营,还为此买了Qt的书来学习,不过由于一直以来被诸多事情所扰(懒?),Qt的学习就停留在了……编译完毕。好吧,我输了……C#,就决定是你了! 那么进入正题吧。 在课程设计的过程中,我需要在窗体上进行图片的绘制,但是在实际的测试中发现了问题,那就是重绘的时候会发生闪烁,这个问题其实在大一的C语言课设的时候就出现过了,在程序绘制动画的高频率刷新的时候,也会产生闪烁,而那时候的解决办法,是对动画进行双缓冲(Double Buffering)处理。 在被双缓冲这个名词吓到之前,我们先来探讨下为什么重绘的时候会发生闪烁: 说道动画的原理大家都懂,就是利用了人眼的视

队列与BFS搜索

队列(queue)是一种简单的数据结构,它所遵循的规则是先进先出(First in First out, FIFO),对比LIFO的数据结构“栈”,你可以阅读[这篇文章]。这里所说的队列和我们现实中的队列是一样的,就比如说公交车排队,早到的,排在靠前位置的人自然可以优先上车(假设大家都很文明),利用这种特性,人们可以用来管理各种各样需要按照先后循序的事物,比如银行,因为银行的服务窗口有限,不能同时给所有人提供服务,所以利用计算机提供一个队列系统,给客户一个排队号码,计算机系统可以根据这个排队号码的大小来决定为谁优先提供服务。 按照和栈类似的介绍方法,为了使代码的表意更加明确,我使用C++标准库提供的队列适配器queue来构造队列这种数据结构。 使用queue需要引用头文件: [crayon-5a0ee44f4af6f304652580/] 初始化一个空的队列: [crayon-5a0ee44f4af73268683974/] 令一个元素进入队尾: [crayon-5a0ee44f4af7541

[STL]排列函数next_permutation()

我们自然知道C++的STL提供了丰富的基本数据结构以及算法支持,但事实上在使用中,我们常常容易忽略它,因为学习STL本身也需要一定的时间成本。STL基于泛型编程(Generic Programming, GP),很多人看到这个术语就打了退堂鼓,之内诸如迭代器之流,也更是云里雾里,不知所云也不想探究之,所以明明很好的工具就在手边,但是却弃之不用,着实可惜。 认识这个函数纯属偶然,今天在POJ上做题,看到了一道题[1]的Discuss中提示使用这个函数会使大大简化题目的难度,那么这个函数究竟就以用来做什么呢? 从标题我们就可以知道,可以这个函数用来获取一组元素的全排列,根据其定义,当你输入一组元素后,函数会将这组元素进行排列,排列结果为这组元素按字典序的下一个排列。这里先解释两个名词:一个是字典序,一个是全排列。 所谓字典序,顾名思义,就是像字典上那样的规则对元素进行排列: 我这里从身旁随手的一本字典翻开一页,单词如下: career careerist carefree careful ca

解析算术表达式[2]计算求值

不知道有没有人看了上一篇文章后会有疑问,为什么转换后的表达式要存入表达式栈中呢?虽然在调试器中可以清楚的看到表达式被成功转换了,但如果想要输出的话,岂不是就是倒序了?其实我是在这部分埋下了一个小小的伏笔,我们转换为后缀表达式,是为了计算机能够计算我们输入的“字符串”形式的中缀表达式,而通过后缀法计算,也是要利用栈的,这次,我们还是用图来说话,以计算 1, 2, 3, 4, +, 5, *, +, 6, +, * 这个已经转化好的后缀表达式为例: 1.读入数字入栈 2.然后读入了一个运算符+,这时候就弹出栈中的两个数字,进行加法运算,然后再压回 3.还是继续读入数字 4.此时读入了运算符*,弹出两个数字,进行乘法运算,然后压回 5.再次读入一个加法运算符,弹出两个数字,进行加法运算,然后压回 6.读入数字 7.读入运算符加法,弹出两个数字,进行加法运算,然后压回 8.最后读入乘法运算符,将栈内最后两个数字弹出,进行乘法运算,压回。至此...

解析算术表达式[1]后缀式(逆波兰式)

解析算术表达式[1]后缀式(逆波兰式)
后缀(postfix, 也成逆波兰 reverse Polish)表达式在我们的生活中并不常见,在我们日常中见到的,通常都是中缀(infix)式,例如: 3.14 + 15 * (9.2 – 6.5) 这是便于人类理解的表达式,之所以便于人类理解,是因为人从小便接受识别此类表达式的教育,而且这种记号方式将运算符和数字明确的分开,不会产生数字堆叠在一起的混乱情况。 但是对于计算机而言,这样的表达式并不好理解,计算机是一种线性读入信息,线性输出信息的工具,人类所通识的中缀式,对于这种规规矩矩按照顺序计算的工具而言,是不容易理解的。你可能一眼就看出来要先算小括号里的表达式,然后算乘法,最后算加法。而计算机直接读入的话,可能会先算3.14 + 15,这自然是荒谬的,而后缀法就为计算机计算表达式提供了一种非常有效的解决方案。这篇文章主要的内容是介绍如何将中缀表达式转换为后缀表达式。 说了这么半天,后缀表达式又是什么样子呢?它又有什么样的优势呢? 我们现在来看一组对比: 后缀表达式为什么会有优势呢?因为...

高精度整数运算(7)模运算&总结

取模(Mod)运算应当是我们这个高精度运算类的最后一种运算了^ ^,长达一周的高精度整数运算的介绍的尾声也即将到来~后面部分我将重点介绍模运算,并对高精度整数运算类的最终成品做一点总结。 那么模运算究竟是什么呢?按照大家通俗的理解就是除法运算中剩下的尾巴——余数。其实却实可以这样理解,首先,我们来明确一下除法的表达: A / B = [A / B] + R / B []运算代表向下取整,比如[1.6] = 1。那么[A / B]实际上就是我们做除法运算后所得到的“商”(其实如果商为负数的话,这样说是不合适的,我会在下文中具体解释),而R / B则是除法运算后面的浮点数部分(假如以后有机会做高精度浮点数的运算的话,用这个式子来求是很方便的哦~)。R则是我们这次的主角——模值。 经过整理,我们就可以得到取模运算在数学上的定义: R = A – [A / B] * B 上面这个公式中所有的运算我们之前都已经完成过了,哈哈,看来代码也就是一行的事呀,可是,一次除法运算、一次乘法运算、一次减法运算……这三