最近在做自己的玩具项目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-5ad74260a3c467246081
在《并行计算》这门课程中我了解到了很多使程序并行化的方法,OpenMP就是其中一种,在实际的使用之后,感觉OpenMP是一种很方便的并行计算工具,它能够提供线程级别的并行化,所以OpenMP一般用于共享内存的单机系统。本文将以K-Means算法作为样例来进行讲解。在介绍算法之前,先做一下热身运动,OpenMP库已经在Visual Studio 2013中集成(前几个版本似乎也有),所以你可以很轻松的为你的Visual Studio项目添加OpenMP支持,在项目属性中,如图所示的地方开启OpenMP支持即可:
热身完毕后进入正题。
K-Means算法是一种聚类算法,顾名思义,它进行划分的方法是依赖于计算均值,算法的整体流程非常简单,假如要把样本分为M个类别:
在样本集N中随机选取M个个体,作为初始类心;
遍历样本中的所有个体,每个个体都与当前的M个类心分别求距离,并将自己和距离最小的那个类心归为一类;
通过平均值的方法计算每一类点...
很久没发技术文章了啊……被人说装文艺了啊……我在乱说些啥吗…………
最近学校开了数据结构的课设设计,说是允许使用C++,Java和C#来进行开发。Java上上个学期学的,说实话,感觉真的不是很爽……或许是我电脑的缘故,也或许是心理作用,我总觉的NetBeans一开就卡得不行!无论怎样都得不到在VS中开发和调试的那种爽快感,于是一度打算投奔C++的阵营,还为此买了Qt的书来学习,不过由于一直以来被诸多事情所扰(懒?),Qt的学习就停留在了……编译完毕。好吧,我输了……C#,就决定是你了!
那么进入正题吧。
在课程设计的过程中,我需要在窗体上进行图片的绘制,但是在实际的测试中发现了问题,那就是重绘的时候会发生闪烁,这个问题其实在大一的C语言课设的时候就出现过了,在程序绘制动画的高频率刷新的时候,也会产生闪烁,而那时候的解决办法,是对动画进行双缓冲(Double Buffering)处理。
在被双缓冲这个名词吓到之前,我们先来探讨下为什么重绘的时候会发生闪烁:
说道动画的原理大家都懂,就是利用了人眼的视
队列(queue)是一种简单的数据结构,它所遵循的规则是先进先出(First in First out, FIFO),对比LIFO的数据结构“栈”,你可以阅读[这篇文章]。这里所说的队列和我们现实中的队列是一样的,就比如说公交车排队,早到的,排在靠前位置的人自然可以优先上车(假设大家都很文明),利用这种特性,人们可以用来管理各种各样需要按照先后循序的事物,比如银行,因为银行的服务窗口有限,不能同时给所有人提供服务,所以利用计算机提供一个队列系统,给客户一个排队号码,计算机系统可以根据这个排队号码的大小来决定为谁优先提供服务。
按照和栈类似的介绍方法,为了使代码的表意更加明确,我使用C++标准库提供的队列适配器queue来构造队列这种数据结构。
使用queue需要引用头文件:
[crayon-5ad74260a5057132576689/]
初始化一个空的队列:
[crayon-5ad74260a5060913130061/]
令一个元素进入队尾:
[crayon-5ad74260a506426
我们自然知道C++的STL提供了丰富的基本数据结构以及算法支持,但事实上在使用中,我们常常容易忽略它,因为学习STL本身也需要一定的时间成本。STL基于泛型编程(Generic Programming, GP),很多人看到这个术语就打了退堂鼓,之内诸如迭代器之流,也更是云里雾里,不知所云也不想探究之,所以明明很好的工具就在手边,但是却弃之不用,着实可惜。
认识这个函数纯属偶然,今天在POJ上做题,看到了一道题[1]的Discuss中提示使用这个函数会使大大简化题目的难度,那么这个函数究竟就以用来做什么呢?
从标题我们就可以知道,可以这个函数用来获取一组元素的全排列,根据其定义,当你输入一组元素后,函数会将这组元素进行排列,排列结果为这组元素按字典序的下一个排列。这里先解释两个名词:一个是字典序,一个是全排列。
所谓字典序,顾名思义,就是像字典上那样的规则对元素进行排列:
我这里从身旁随手的一本字典翻开一页,单词如下:
career
careerist
carefree
careful
ca
不知道有没有人看了上一篇文章后会有疑问,为什么转换后的表达式要存入表达式栈中呢?虽然在调试器中可以清楚的看到表达式被成功转换了,但如果想要输出的话,岂不是就是倒序了?其实我是在这部分埋下了一个小小的伏笔,我们转换为后缀表达式,是为了计算机能够计算我们输入的“字符串”形式的中缀表达式,而通过后缀法计算,也是要利用栈的,这次,我们还是用图来说话,以计算
1, 2, 3, 4, +, 5, *, +, 6, +, *
这个已经转化好的后缀表达式为例:
1.读入数字入栈
2.然后读入了一个运算符+,这时候就弹出栈中的两个数字,进行加法运算,然后再压回
3.还是继续读入数字
4.此时读入了运算符*,弹出两个数字,进行乘法运算,然后压回
5.再次读入一个加法运算符,弹出两个数字,进行加法运算,然后压回
6.读入数字
7.读入运算符加法,弹出两个数字,进行加法运算,然后压回
8.最后读入乘法运算符,将栈内最后两个数字弹出,进行乘法运算,压回。至此...
后缀(postfix, 也成逆波兰 reverse Polish)表达式在我们的生活中并不常见,在我们日常中见到的,通常都是中缀(infix)式,例如:
3.14 + 15 * (9.2 – 6.5)
这是便于人类理解的表达式,之所以便于人类理解,是因为人从小便接受识别此类表达式的教育,而且这种记号方式将运算符和数字明确的分开,不会产生数字堆叠在一起的混乱情况。
但是对于计算机而言,这样的表达式并不好理解,计算机是一种线性读入信息,线性输出信息的工具,人类所通识的中缀式,对于这种规规矩矩按照顺序计算的工具而言,是不容易理解的。你可能一眼就看出来要先算小括号里的表达式,然后算乘法,最后算加法。而计算机直接读入的话,可能会先算3.14 + 15,这自然是荒谬的,而后缀法就为计算机计算表达式提供了一种非常有效的解决方案。这篇文章主要的内容是介绍如何将中缀表达式转换为后缀表达式。
说了这么半天,后缀表达式又是什么样子呢?它又有什么样的优势呢?
我们现在来看一组对比:
后缀表达式为什么会有优势呢?因为...
取模(Mod)运算应当是我们这个高精度运算类的最后一种运算了^ ^,长达一周的高精度整数运算的介绍的尾声也即将到来~后面部分我将重点介绍模运算,并对高精度整数运算类的最终成品做一点总结。
那么模运算究竟是什么呢?按照大家通俗的理解就是除法运算中剩下的尾巴——余数。其实却实可以这样理解,首先,我们来明确一下除法的表达:
A / B = [A / B] + R / B
[]运算代表向下取整,比如[1.6] = 1。那么[A / B]实际上就是我们做除法运算后所得到的“商”(其实如果商为负数的话,这样说是不合适的,我会在下文中具体解释),而R / B则是除法运算后面的浮点数部分(假如以后有机会做高精度浮点数的运算的话,用这个式子来求是很方便的哦~)。R则是我们这次的主角——模值。
经过整理,我们就可以得到取模运算在数学上的定义:
R = A – [A / B] * B
上面这个公式中所有的运算我们之前都已经完成过了,哈哈,看来代码也就是一行的事呀,可是,一次除法运算、一次乘法运算、一次减法运算……这三
文章导航