Quake-III代码里神奇的浮点开方函数
开源3D游戏引擎irrlicht(鬼火)Example讲解——Quake3Map
开源3D游戏引擎Irrlicht(鬼火)Example讲解——Quake3Map赵刚Irrlicht引擎自带的第2个Example叫做Quake3Map,她演示了利用irrlicht引擎载入Quake3场景文件(.pk3)的过程,程序运行起来如下图:运行02.Quake3Map.exe的时候会先出来一个控制台窗口,按a,再按回车即可,表示选择OpenGL作为渲染API。
进入bin目录下的examples目录可以看到02.Quake3Map目录,双击Quake3Map_vc9.vcproj文件打开工程文件,工程文件中只有一个main.cpp文件。
内容如下(去除了英文注释):#include<irrlicht.h>#include<iostream>using namespace irr;#ifdef _MSC_VER#pragma comment(lib, "Irrlicht.lib")#endifint main(){video::E_DRIVER_TYPE driverType;printf("Please select the driver you want for this example:\n"\ " (a) OpenGL 1.5\n (b) Direct3D 9.0c\n (c) Direct3D 8.1\n"\" (d) Burning's Software Renderer\n (e) Software Renderer\n"\" (f) NullDevice\n (otherKey) exit\n\n");char i;std::cin >> i;switch(i){case'a': driverType = video::EDT_OPENGL; break;case'b': driverType = video::EDT_DIRECT3D9;break;case'c': driverType = video::EDT_DIRECT3D8;break;case'd': driverType = video::EDT_BURNINGSVIDEO;break;case'e': driverType = video::EDT_SOFTWARE; break;case'f': driverType = video::EDT_NULL; break;default: return 1;}IrrlichtDevice *device =createDevice(driverType, core::dimension2d<u32>(640, 480));if (device == 0)return 1;video::IVideoDriver* driver = device->getVideoDriver();scene::ISceneManager* smgr = device->getSceneManager();device->getFileSystem()->addZipFileArchive("../../media/map-20kdm 2.pk3");scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");scene::ISceneNode* node = 0;if (mesh)node = smgr->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);if (node)node->setPosition(core::vector3df(-1300,-144,-1249));smgr->addCameraSceneNodeFPS();device->getCursorControl()->setVisible(false);int lastFPS = -1;while(device->run()){if (device->isWindowActive()){driver->beginScene(true, true,video::SColor(255,200,200,200));smgr->drawAll();driver->endScene();int fps = driver->getFPS();if (lastFPS != fps){core::stringw str = L"Irrlicht Engine - Quake 3 Map example [";str += driver->getName();str += "] FPS:";str += fps;device->setWindowCaption(str.c_str());lastFPS = fps;}}elsedevice->yield();}device->drop();return 0;}程序很简洁,条理也很清晰,下面讲解一下代码。
c开三次方函数
c开三次方函数C语言是一种广泛使用的计算机编程语言,具有高效、灵活、跨平台等优势,因此在科学计算、游戏开发、操作系统、嵌入式系统等领域得到广泛的应用。
在C语言中,三次方函数是一种常见的数学函数,具有将一个数的立方根作为输出的功能。
下面我们详细介绍如何在C语言中实现三次方函数。
一、三次方函数的定义三次方函数的定义为:y=x^3,其中y是输出值,x是输入值。
因此,三次方函数的作用就是将一个实数x的立方根作为输出。
举例来说,当x=2时,y=2^3=8,因此三次方函数的输出就是8。
二、使用pow()函数实现三次方函数在C语言中,可以使用pow()函数来实现三次方函数。
pow()函数的原型如下:double pow(double x, double y);其中x是底数,y是幂。
pow()函数的返回值是一个double类型的浮点数,表示x的y 次幂。
将y设置为3即可得到三次方函数的结果。
在程序中,可以使用以下代码实现三次方函数:#include <stdio.h>#include <math.h>在这个程序中,用户需要输入一个实数x,程序会根据用户输入的x计算出x的三次方,并将结果输出到屏幕上。
需要注意的是,由于pow()函数的返回值是一个浮点数,所以需要使用double类型来存储结果。
double cube(double x){return x * x * x;}在这个程序中,我们定义了一个名为cube()的函数,它接受一个double类型的实参x,并返回x的三次方。
在主函数中,我们先从用户那里得到一个实数x,然后调用cube()函数进行计算,最后输出结果。
通过自定义函数实现三次方函数的方法可以使程序更加模块化和可读性更强,也便于管理和维护。
在C语言中,使用位运算可以实现快速的幂运算,因此也可以用位运算实现三次方函数。
具体思路是将3表示为二进制数100,然后再将x左移6位,得到x的64倍,再将结果除以64即可得到x的三次方。
开根号算法
因为工作的需要,要在单片机上实现开根号的操作。
目前开平方的方法大部分是用牛顿迭代法。
我在查了一些资料以后找到了一个比牛顿迭代法更加快速的方法。
不敢独享,介绍给大家,希望会有些帮助。
1.原理因为排版的原因,用pow(X,Y)表示X的Y次幂,用B[0],B[1],...,B[m-1]表示一个序列,其中[x]为下标。
假设:B[x],b[x]都是二进制序列,取值0或1。
M = B[m-1]*pow(2,m-1) + B[m-2]*pow(2,m-2) + ... + B[1]*pow(2,1) + B[0]*pow(2,0)N = b[n-1]*pow(2,n-1) + b[n-2]*pow(2,n-2) + ... + b[1]*pow(2,1) + n[0]*pow(2,0)pow(N,2) = M(1) N的最高位b[n-1]可以根据M的最高位B[m-1]直接求得。
设 m 已知,因为 pow(2, m-1) <= M <= pow(2, m),所以 pow(2, (m-1)/2) <= N <=pow(2, m/2)如果 m 是奇数,设m=2*k+1,那么 pow(2,k) <= N < pow(2, 1/2+k) < pow(2, k+1),n-1=k, n=k+1=(m+1)/2如果 m 是偶数,设m=2k,那么 pow(2,k) > N >= pow(2, k-1/2) > pow(2, k-1),n-1=k-1,n=k=m/2所以b[n-1]完全由B[m-1]决定。
余数 M[1] = M - b[n-1]*pow(2, 2*n-2)(2) N的次高位b[n-2]可以采用试探法来确定。
因为b[n-1]=1,假设b[n-2]=1,则 pow(b[n-1]*pow(2,n-1) + b[n-1]*pow(2,n-2),2) = b[n-1]*pow(2,2*n-2) + (b[n-1]*pow(2,2*n-2) + b[n-2]*pow(2,2*n-4)),然后比较余数M[1]是否大于等于 (pow(2,2)*b[n-1] + b[n-2]) * pow(2,2*n-4)。
c语言开方函数
c语言开方函数
c语言的开方函数是:
sqrt()函数。
1、功能:计算一个非负实数的平方根。
2、函数原型:在VC6.0中的math。
h头文件的函数原型为double sqrt(double)。
3、说明:sqrt系。
C语言中平方根的函数是怎么样的?
1、C语言中平方根的函数是:double sqrt(double);参数介绍:()中是double,返回值可能是double 也可能是int;
2、该函数头文件:math。
h;
3、该函数功能:计算一个非。
在c中类似开方,取绝对值
sqrt()
include int main() { double x,y; printf("请输入x:");scanf("%f",&x); if (0
#include#include int main() { double x,y; printf("请输入x:"); scanf("%f",&x); if (0
若开平方,可以使用函数sqrt()完成,若开其他次方,可以
借助函数pow()完成。
开平方示例:#include//sqrt函数使用到
的头文件#include int main(。
牛顿迭代求根法,自己去查一下公式,这里我给出C语言代码,可自行修改一下。
double sqrt_db(double the Input) { double si=1;uint16_t times=0; if (the Input==0) { return 0; } 。
用函数SQRT(A)即可。
高性能浮点除法和开方的设计与实现
、 , 0 1 . 3 9
・计算Fra bibliotek机工
程
2 0 1 3年 1 2月
De c e mb e r 201 3
No . 1 2
Co mp u t e r En g i ne e r i n g
开发研究与工程应用 ・
文章编号{ 1 0 0 0 — l 3 4 2 8 ( 2 0 l 3 ) 1 2 — _ o 2 6 4 —0 5
HONG Qi ’ ZHAO Z h i - we i , HE Mi n
( S c h o o l o f E l e c t r o n i c s a n d I n f o r ma t i o n E n g i n e e r i n g , An h u i Un i v e r s i t y , He f e i 2 3 0 6 0 1 , C h i n a )
基数 S R T浮点 除法 和开 方算法 , 设计基 于 V i r t e x — I I p r o F P G A 的可变位 宽浮 点 除法和 开 方的 3种实现 方 案 , 包括 小 面积 的迭代 实现 、 低延 时 的阵列 实现和 高吞 吐量 的流水 实现 。实验 结果表 明,对 于浮 点除 法和 开方 算法 的流水 实现 , 在 综合 面积 符合 要 求的基 础上 ,
of lo f a t — po i n t di v i s i o n a n d s q ua r e r o ot o p e r a t i o ns w i t h v a r i a b l e wi d t h b a s e d o n Vi ne x- I I pr o FPGA .On e i s a l o w c os t i t e r a t i v e
[转贴]《雷神之锤III》里求平方根倒数的函数(快速平方根(倒数)算法)
[转贴]《雷神之锤III》⾥求平⽅根倒数的函数(快速平⽅根(倒数)算法)[转贴]《雷神之锤III》⾥求平⽅根倒数的函数(快速平⽅根(倒数)算法)在3D图形编程中,经常要求平⽅根或平⽅根的倒数,例如:求向量的长度或将向量归⼀化。
C数学函数库中的sqrt具有理想的精度,但对于3D游戏程式来说速度太慢。
我们希望能够在保证⾜够的精度的同时,进⼀步提⾼速度。
Carmack在QUAKE3中使⽤了下⾯的算法,它第⼀次在公众场合出现的时候,⼏乎震住了所有的⼈。
据说该算法其实并不是Carmack发明的,它真正的作者是Nvidia的Gary Tarolli(未经证实)。
//// 计算参数x的平⽅根的倒数//float InvSqrt (float x){float xhalf = 0.5f*x;int i = *(int*)&x;i = 0x5f3759df - (i >> 1); // 计算第⼀个近似根x = *(float*)&i;x = x*(1.5f - xhalf*x*x); // ⽜顿迭代法return x;}该算法的本质其实就是⽜顿迭代法(Newton-Raphson Method,简称NR),⽽NR的基础则是泰勒级数(Taylor Series)。
NR是⼀种求⽅程的近似根的⽅法。
⾸先要估计⼀个与⽅程的根⽐较靠近的数值,然后根据公式推算下⼀个更加近似的数值,不断重复直到可以获得满意的精度。
其公式如下:函数:y=f(x)其⼀阶导数为:y'=f'(x)则⽅程:f(x)=0 的第n+1个近似根为x[n+1] = x[n] - f(x[n]) / f'(x[n])NR最关键的地⽅在于估计第⼀个近似根。
如果该近似根与真根⾜够靠近的话,那么只需要少数⼏次迭代,就可以得到满意的解。
现在回过头来看看如何利⽤⽜顿法来解决我们的问题。
求平⽅根的倒数,实际就是求⽅程1/(x^2)-a=0的解。
最牛开方代码算法
最牛开方代码算法开方是数学中的一种基本运算,在计算机编程中也有着广泛的应用。
本文将介绍一种最牛的开方代码算法,该算法具有高效、稳定、易于实现等特点,适用于各种编程语言。
一、传统开方算法的局限性传统开方算法主要有二分法和牛顿法两种。
二分法适用于数值较小的情况,但当数值较大时,需要多次迭代才能得到精确结果;而牛顿法虽然精度较高,但需要事先知道函数的导数值,而且容易陷入局部最优解。
二、最牛开方算法原理最牛开方算法是一种基于黄金分割的优化算法,通过将问题拆分成多个小问题,逐个解决,最终得到精确结果。
该算法的核心思想是将待求的平方根问题看作一个整体,通过黄金分割点将整体拆分成两个部分,分别求解两个部分的最优解,最后取两个最优解的平均值作为最终结果。
三、最牛开方算法实现下面是一个基于最牛开方算法的开方代码实现,以Python语言为例:```pythondef golden_square_root(num, max_iter=100):"""使用黄金分割法求平方根:param num: 待求平方根的数:param max_iter: 最大迭代次数:return: 平方根结果"""# 初始化两个黄金分割点x1 = 0.5 * num**(1/2)x2 = 0.8 * num**(1/2)# 初始化误差阈值和当前误差error = abs(num**(1/2) - x1)prev_error = error# 开始迭代for i in range(max_iter):# 分别求两个黄金分割点处函数值的倒数fx1 = 1 / (x1**2 - num)fx2 = 1 / (x2**2 - num)# 取两个函数值倒数的小者与x1的乘积作为新的黄金分割点x = min(fx1, fx2) * x1# 判断是否收敛if error == 0 or abs(x - x1) < 0.0001:break# 更新误差和当前误差prev_error = errorerror = abs(x - num**(1/2))# 将新的黄金分割点加入候选解集合中x1 = xreturn x```四、算法性能分析最牛开方算法通过黄金分割点将问题拆分成多个小问题,逐个解决,具有高效、稳定、易于实现等特点。
C语言编程技巧整数开方算法
C语言编程技巧整数开方算法整数开方算法是计算一个整数的平方根的算法,即求解方程x^2=a的解x。
在计算机编程中,有多种方法可以实现整数开方算法,包括牛顿迭代法、二分法和位运算法等。
下面将介绍几种常用的整数开方算法及其优化技巧。
1.牛顿迭代法牛顿迭代法是一种不断逼近平方根的方法。
它基于以下的迭代公式:x=(x+a/x)/2具体实现时,我们可以选择一个适当的初始值x0,然后不断迭代,直到找到满足精度要求的解。
例如,我们可以选择初始值x0=a/2、然后迭代若干次,直到解的变化非常小,即可认为找到了平方根。
牛顿迭代法的优点是收敛速度快,但需要使用浮点数运算,适用于计算精度较高的场合。
2.二分法二分法是一种更加简单的算法,它通过不断二分待求解的区间来逼近平方根。
具体实现时,我们从区间[1,a]开始,然后不断二分,找到满足条件的解。
例如,我们可以选择初始区间的中点作为猜测的平方根,然后根据和a的关系来判断解在左半区间还是右半区间,继续二分直到找到解。
二分法的优点是实现简单,并且只需要使用整数运算,适用于计算精度要求不高的场合。
3.位运算法位运算法是一种基于位运算的快速整数开方算法。
它利用二进制表示中1的位置与平方根的关系,通过位运算来求解。
具体实现时,我们可以从最高位开始,逐位计算解的每一位。
假设我们要计算a的平方根,这里只考虑正整数的情况。
首先,我们可以确定解的最高位,它是使得b*b<=a的最大整数b。
然后,我们可以依次计算解的其它位,如果当前位是1,那么解的该位可以取0或1,如果当前位是0,那么解的该位只能取0。
位运算法的优点是计算速度快,但需要对二进制表示进行运算,并且在计算负数的平方根时较复杂。
在实际编程中,我们可以根据具体的需求选择合适的整数开方算法。
如果需要高精度的计算,可以选择牛顿迭代法;如果需要快速计算,可以选择位运算法;如果对精度要求不高,可以选择二分法。
另外,还可以结合不同的算法,根据具体情况进行优化。
高效率嵌入式系统开平方根
开平方根目录1. 开平方根 (2)2. 开平方根说明 (8)1. 开平方根我们平时经常会有一些数据运算的操作,需要调用sqrt,exp,abs等函数,那么时候你有没有想过:这个些函数系统是如何实现的?就拿最常用的sqrt函数来说吧,系统怎么来实现这个经常调用的函数呢?虽然有可能你平时没有想过这个问题,不过正所谓是“临阵磨枪,不快也光”,你“眉头一皱,计上心来”,这个不是太简单了嘛,用二分的方法,在一个区间中,每次拿中间数的平方来试验,如果大了,就再试左区间的中间数;如果小了,就再拿右区间的中间数来试。
比如求sqrt(16)的结果,你先试(0+16)/2=8,8*8=64,64比16大,然后就向左移,试(0+8)/2=4,4*4=16刚好,你得到了正确的结果sqrt(16)=4。
然后你三下五除二就把程序写出来了:然后看看和系统函数性能和精度的差别(其中时间单位不是秒也不是毫秒,而是CPU Tick,不管单位是什么,统一了就有可比性)。
二分法和系统的方法结果上完全相同,但是性能上整整差了几百倍。
为什么会有这么大的区别呢?难道系统有什么更好的办法?难道。
哦,对了,回忆下我们曾经的高数课,曾经老师教过我们“牛顿迭代法快速寻找平方根”,或者这种方法可以帮助我们,具体步骤如下。
求出根号a的近似值:首先随便猜一个近似值x,然后不断令x等于x和a/x的平均数,迭代个六七次后x的值就已经相当精确了。
例如,我想求根号2等于多少。
假如我猜测的结果为4,虽然错的离谱,但你可以看到使用牛顿迭代法后这个值很快就趋近于根号2了:这种算法的原理很简单,我们仅仅是不断用(x,f(x))的切线来逼近方程x^2-a=0的根。
根号a实际上就是x^2-a=0的一个正实根,这个函数的导数是2x。
也就是说,函数上任一点(x,f(x))处的切线斜率是2x。
那么,x-f(x)/(2x)就是一个比x更接近的近似值。
代入f(x)=x^2-a得到x-(x^2-a)/(2x),也就是(x+a/x)/2。
世界上最快的浮点开方算法
任何一个3D引擎都是通过其内部的数学模型和实现工具来展现它的力量与速度的,Quake III中使用了一个非常有意思的技巧来计算平方根倒数(inverse square root)Carmack's 不寻常平方根倒数卡马克算法第一个跳出来的便是对函数Q_rsqrt中对0x5f3759df的使用,这个数计算了一个浮点数的inverse square root,但是为什么这个函数有这样的功能呢?观察q_math.c原本的函数:[c-sharp]view plaincopyprint?1.float Q_rsqrt( float number )2.{3.long i;4.float x2, y;5.const float threehalfs = 1.5F;6. x2 = number * 0.5F;7. y = number;8. i = * ( long * ) &y; // evil floating point bit level hacking9. i = 0x5f3759df - ( i >> 1 );10. y = * ( float * ) &i;11. y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration12. y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed13. y = y * ( threehalfs - ( x2 * y * y ) );//增加精度值14.return y; //返回倒数15.}它不仅有效,甚至在某些CPU上,Carmack的Q_rsqrt 比(float)(1.0/sqrt(x)的计算快4倍,尽管sqrt()通常使用的是FSQRT的汇编指令!在另一个文件code/common/cm_trace.c 中,我们发现了更简洁的对同样HACK的实现。
单片机中用C语言精确开平方及附加正弦函数表(全面版)资料
单片机中用C语言精确开平方及附加正弦函数表(全面版)资料在单片机中,通常我们需要算一个数的开方,但如果直接用<MATH.H>中的SQR开方,对单片机是很残酷的,所以自编了一个程序,对任意正整数开方,且可精确到六位小数!////////////输入整数///////////////////////输出浮点型//////////////////////////精确到8位小数///////////#include<stdio.h>#define uint unsigned intfloat sqre(int a);main(){int i;while(1){printf("please input number:");scanf("%d",&i); /*输入要开方的数*/printf("i=%d\n",i);printf("squr=%f\n",sqre(i)); /*被开方数大等于0时输出实数*/}}float sqre(int a){int i;float b,c;for(i=0;;i++){if((a>i* i)&&(a<=(1+i)*(1+i))){b=(float)(i+(1+i))/2;break;}}for(i=0;i<3;i++){c=b+(a/b-b)/2;b=c;}return b;}/*////////自己编写的,一起学习/////////*/0.0{0.0000} 0.1{0.0017} 0.2{0.0035} 0.3{0.0052} 0.4{0.0070} 0.5{0.0087}0.6{0.0105} 0.7{0.0122} 0.8{0.0140} 0.9{0.0157} 1.0{0.0175} 1.1{0.0192}1.2{0.0209} 1.3{0.0227} 1.4{0.0244} 1.5{0.0262} 1.6{0.0279} 1.7{0.0297}1.8{0.0314} 1.9{0.0332}2.0{0.0349} 2.1{0.0366} 2.2{0.0384} 2.3{0.0401}2.4{0.0419} 2.5{0.0436} 2.6{0.0454} 2.7{0.0471} 2.8{0.0488} 2.9{0.0506}3.0{0.0523} 3.1{0.0541} 3.2{0.0558} 3.3{0.0576} 3.4{0.0593} 3.5{0.0610}3.6{0.0628} 3.7{0.0645} 3.8{0.0663} 3.9{0.0680}4.0{0.0698} 4.1{0.0715} 4.2{0.0732} 4.3{0.0750} 4.4{0.0767} 4.5{0.0785}4.6{0.0802} 4.7{0.0819} 4.8{0.0837} 4.9{0.0854}5.0{0.0872} 5.1{0.0889}5.2{0.0906} 5.3{0.0924} 5.4{0.0941} 5.5{0.0958} 5.6{0.0976} 5.7{0.0993}5.8{0.1011} 5.9{0.1028}6.0{0.1045} 6.1{0.1063} 6.2{0.1080} 6.3{0.1097}6.4{0.1115} 6.5{0.1132} 6.6{0.1149} 6.7{0.1167} 6.8{0.1184} 6.9{0.1201}7.0{0.1219} 7.1{0.1236} 7.2{0.1253} 7.3{0.1271} 7.4{0.1288} 7.5{0.1305}7.6{0.1323} 7.7{0.1340} 7.8{0.1357} 7.9{0.1374} 8.0{0.1392} 8.1{0.1409}8.2{0.1426} 8.3{0.1444} 8.4{0.1461} 8.5{0.1478} 8.6{0.1495} 8.7{0.1513}8.8{0.1530} 8.9{0.1547} 9.0{0.1564} 9.1{0.1582} 9.2{0.1599} 9.3{0.1616}9.4{0.1633} 9.5{0.1650} 9.6{0.1668} 9.7{0.1685} 9.8{0.1702} 9.9{0.1719}10.0{0.1736} 10.1{0.1754} 10.2{0.1771} 10.3{0.1788} 10.4{0.1805} 10.5{0.1822}10.6{0.1840} 10.7{0.1857} 10.8{0.1874} 10.9{0.1891} 11.0{0.1908} 11.1{0.1925}11.2{0.1942} 11.3{0.1959} 11.4{0.1977} 11.5{0.1994} 11.6{0.2021} 11.7{0.2028}11.8{0.2045} 11.9{0.2062} 12.0{0.2079} 12.1{0.2096} 12.2{0.2113} 12.3{0.2130}12.4{0.2147} 12.5{0.2164} 12.6{0.2181} 12.7{0.2198} 12.8{0.2215} 12.9{0.2233}13.0{0.2250} 13.1{0.2267} 13.2{0.2284} 13.3{0.2300} 13.4{0.2317} 13.5{0.2334}13.6{0.2351} 13.7{0.2368} 13.8{0.2385} 13.9{0.2402} 14.0{0.2419} 14.1{0.2436}14.2{0.2453} 14.3{0.2470} 14.4{0.2487} 14.5{0.2504} 14.6{0.2521} 14.7{0.2538}14.8{0.2554} 14.9{0.2571} 15.0{0.2588} 15.1{0.2605} 15.2{0.2622} 15.3{0.2639}15.4{0.2656} 15.5{0.2672} 15.6{0.2689} 15.7{0.2706} 15.8{0.2723} 15.9{0.2740}16.0{0.2756} 16.1{0.2773} 16.2{0.2790} 16.3{0.2807} 16.4{0.2823} 16.5{0.2840}16.6{0.2857} 16.7{0.2874} 16.8{0.2890} 16.9{0.2907} 17.0{0.2924} 17.1{0.2940}17.2{0.2957} 17.3{0.2974} 17.4{0.2990} 17.5{0.3007} 17.6{0.3024} 17.7{0.3040}17.8{0.3057} 17.9{0.3074} 18.0{0.3090} 18.1{0.3107} 18.2{0.3123} 18.3{0.3140}18.4{0.3156} 18.5{0.3173} 18.6{0.3190} 18.7{0.3206} 18.8{0.3223} 18.9{0.3239}19.0{0.3256} 19.1{0.3272} 19.2{0.3289} 19.3{0.3305} 19.4{0.3322} 19.5{0.3338}19.6{0.3355} 19.7{0.3371} 19.8{0.3387} 19.9{0.3404}20.0{0.3420} 20.1{0.3437} 20.2{0.3453} 20.3{0.3469} 20.4{0.3486} 20.5{0.3502}20.6{0.3518} 20.7{0.3535} 20.8{0.3551} 20.9{0.3567} 21.0{0.3584} 21.1{0.3600}21.2{0.3616} 21.3{0.3633} 21.4{0.3649} 21.5{0.3665} 21.6{0.3681} 21.7{0.3697}21.8{0.3714} 21.9{0.3730} 22.0{0.3746} 22.1{0.3762} 22.2{0.3778} 22.3{0.3795}22.4{0.3811} 22.5{0.3827} 22.6{0.3843} 22.7{0.3859} 22.8{0.3875} 22.9{0.3891}23.0{0.3907} 23.1{0.3923} 23.2{0.3939} 23.3{0.3955} 23.4{0.3971} 23.5{0.3987}23.6{0.4003} 23.7{0.4019} 23.8{0.4035} 23.9{0.4051} 24.0{0.4067} 24.1{0.4083}24.2{0.4099} 24.3{0.4115} 24.4{0.4131} 24.5{0.4147} 24.6{0.4163} 24.7{0.4179}24.8{0.4195} 24.9{0.4210} 25.0{0.4226} 25.1{0.4242} 25.2{0.4258} 25.3{0.4274}25.4{0.4289} 25.5{0.4305} 25.6{0.4321} 25.7{0.4337} 25.8{0.4352} 25.9{0.4368}26.0{0.4384} 26.1{0.4399} 26.2{0.4415} 26.3{0.4431} 26.4{0.4446} 26.5{0.4462}26.6{0.4478} 26.7{0.4493} 26.8{0.4509} 26.9{0.4524} 27.0{0.4540} 27.1{0.4555}27.2{0.4571} 27.3{0.4586} 27.4{0.4602} 27.5{0.4617} 27.6{0.4633} 27.7{0.4648}27.8{0.4664} 27.9{0.4679} 28.0{0.4695} 28.1{0.4710} 28.2{0.4726} 28.3{0.4741}28.4{0.4756} 28.5{0.4772} 28.6{0.4787} 28.7{0.4802} 28.8{0.4818} 28.9{0.4833}29.0{0.4848} 29.1{0.4863} 29.2{0.4879} 29.3{0.4894} 29.4{0.4909} 29.5{0.4924}29.6{0.4939} 29.7{0.4955} 29.8{0.4970} 29.9{0.4985} 30.0{0.5000} 30.1{0.5015}30.2{0.5030} 30.3{0.5045} 30.4{0.5060} 30.5{0.5075} 30.6{0.5090} 30.7{0.5105}30.8{0.5120} 30.9{0.5135} 31.0{0.5150} 31.1{0.5165} 31.2{0.5180} 31.3{0.5195}31.4{0.5210} 31.5{0.5225} 31.6{0.5240} 31.7{0.5255} 31.8{0.5270} 31.9{0.5284}32.0{0.5299} 32.1{0.5314} 32.2{0.5329} 32.3{0.5344} 32.4{0.5358} 32.5{0.5373}32.6{0.5388} 32.7{0.5402} 32.8{0.5417} 32.9{0.5432} 33.0{0.5446} 33.1{0.5461}33.2{0.5476} 33.3{0.5490} 33.4{0.5505} 33.5{0.5519} 33.6{0.5534} 33.7{0.5548}33.8{0.5563} 33.9{0.5577} 34.0{0.5592} 34.1{0.5606} 34.2{0.5621} 34.3{0.5635}34.4{0.5650} 34.5{0.5664} 34.6{0.5678} 34.7{0.5693} 34.8{0.5707} 34.9{0.5721}35.0{0.5736} 35.1{0.5750} 35.2{0.5764} 35.3{0.5779} 35.4{0.5793} 35.5{0.5807}35.6{0.5821} 35.7{0.5835} 35.8{0.5850} 35.9{0.5864} 36.0{0.5878} 36.1{0.5892}36.2{0.5906} 36.3{0.5920} 36.4{0.5934} 36.5{0.5948} 36.6{0.5962} 36.7{0.5976}36.8{0.5990} 36.9{0.6004} 37.0{0.6018} 37.1{0.6032} 37.2{0.6046} 37.3{0.6060}37.4{0.6074} 37.5{0.6088} 37.6{0.6101} 37.7{0.6115} 37.8{0.6129} 37.9{0.6143}38.0{0.6157} 38.1{0.6170} 38.2{0.6184} 38.3{0.6198} 38.4{0.6211} 38.5{0.6225}38.6{0.6239} 38.7{0.6252} 38.8{0.6266} 38.9{0.6280} 39.0{0.6293} 39.1{0.6307}39.2{0.6320} 39.3{0.6334} 39.4{0.6347} 39.5{0.6361} 39.6{0.6374} 39.7{0.6388} 39.8{0.6401} 39.9{0.6414} 40.0{0.6428} 40.1{0.6441} 40.2{0.6455} 40.3{0.6468}40.4{0.6481} 40.5{0.6494} 40.6{0.6508} 40.7{0.6521} 40.8{0.6534} 40.9{0.6547}41.0{0.6561} 41.1{0.6574} 41.2{0.6587} 41.3{0.6600} 41.4{0.6613} 41.5{0.6626}41.6{0.6639} 41.7{0.6652} 41.8{0.6665} 41.9{0.6678}42.0{0.6691} 42.1{0.6704} 42.2{0.6717} 42.3{0.6730} 42.4{0.6743} 42.5{0.6756}42.6{0.6769} 42.7{0.6782} 42.8{0.6794} 42.9{0.6807} 43.0{0.6820} 43.1{0.6833}43.2{0.6845} 43.3{0.6858} 43.4{0.6871} 43.5{0.6884} 43.6{0.6896} 43.7{0.6909}43.8{0.6921} 43.9{0.6934} 44.0{0.6947} 44.1{0.6959} 44.2{0.6972} 44.3{0.6984}44.4{0.6997} 44.5{0.7009} 44.6{0.7022} 44.7{0.7034} 44.8{0.7046} 44.9{0.7059}45.0{0.7071} 45.1{0.7083} 45.2{0.7096} 45.3{0.7108} 45.4{0.7120} 45.5{0.7133}45.6{0.7145} 45.7{0.7157} 45.8{0.7169} 45.9{0.7181} 46.0{0.7193} 46.1{0.7206}46.2{0.7218} 46.3{0.7230} 46.4{0.7242} 46.5{0.7254} 46.6{0.7266} 46.7{0.7278}46.8{0.7290} 46.9{0.7302} 47.0{0.7314} 47.1{0.7325} 47.2{0.7337} 47.3{0.7349}47.4{0.7361} 47.5{0.7373} 47.6{0.7385} 47.7{0.7396} 47.8{0.7408} 47.9{0.7420}48.0{0.7431} 48.1{0.7443} 48.2{0.7455} 48.3{0.7466} 48.4{0.7478} 48.5{0.7490}48.6{0.7501} 48.7{0.7513} 48.8{0.7524} 48.9{0.7536} 49.0{0.7547} 49.1{0.7559}49.2{0.7570} 49.3{0.7581} 49.4{0.7593} 49.5{0.7604} 49.6{0.7615} 49.7{0.7627}49.8{0.7638} 49.9{0.7649} 50.0{0.7660} 50.1{0.7672} 50.2{0.7683} 50.3{0.7694}50.4{0.7705} 50.5{0.7716} 50.6{0.7727} 50.7{0.7738} 50.8{0.7749} 50.9{0.7760}51.0{0.7771} 51.1{0.7782} 51.2{0.7793} 51.3{0.7804} 51.4{0.7815} 51.5{0.7826}51.6{0.7837} 51.7{0.7848} 51.8{0.7859} 51.9{0.7869} 52.0{0.7880} 52.1{0.7891}52.2{0.7902} 52.3{0.7912} 52.4{0.7923} 52.5{0.7934} 52.6{0.7944} 52.7{0.7955}52.8{0.7965} 52.9{0.7976} 53.0{0.7986} 53.1{0.7997} 53.2{0.8007} 53.3{0.8018}53.4{0.8028} 53.5{0.8039} 53.6{0.8049} 53.7{0.8059} 53.8{0.8070} 53.9{0.8080}54.0{0.8090} 54.1{0.8100} 54.2{0.8111} 54.3{0.8121} 54.4{0.8131} 54.5{0.8141}54.6{0.8151} 54.7{0.8161} 54.8{0.8171} 54.9{0.8181} 55.0{0.8192} 55.1{0.8202}55.2{0.8211} 55.3{0.8221} 55.4{0.8231} 55.5{0.8241} 55.6{0.8251} 55.7{0.8261}55.8{0.8271} 55.9{0.8281} 56.0{0.8290} 56.1{0.8300} 56.2{0.8310} 56.3{0.8320}56.4{0.8329} 56.5{0.8339} 56.6{0.8348} 56.7{0.8358} 56.8{0.8368} 56.9{0.8377}57.0{0.8387} 57.1{0.8396} 57.2{0.8406} 57.3{0.8415} 57.4{0.8425} 57.5{0.8434}57.6{0.8443} 57.7{0.8453} 57.8{0.8462} 57.9{0.8471} 58.0{0.8480} 58.1{0.8490}58.2{0.8499} 58.3{0.8508} 58.4{0.8517} 58.5{0.8526} 58.6{0.8536} 58.7{0.8545}58.8{0.8554} 58.9{0.8563} 59.0{0.8572} 59.1{0.8581} 59.2{0.8590} 59.3{0.8599}59.4{0.8607} 59.5{0.8616} 59.6{0.8625} 59.7{0.8634} 59.8{0.8643} 59.9{0.8652}60.0{0.8660} 60.1{0.8669} 60.2{0.8678} 60.3{0.8686} 60.4{0.8695} 60.5{0.8704}60.6{0.8712} 60.7{0.8721} 60.8{0.8729} 60.9{0.8738} 61.0{0.8746} 61.1{0.8755}61.2{0.8763} 61.3{0.8771} 61.4{0.8780} 61.5{0.8788} 61.6{0.8796} 61.7{0.8805}61.8{0.8813} 61.9{0.8821} 62.0{0.8829} 62.1{0.8838} 62.2{0.8846} 62.3{0.8854}62.4{0.8862} 62.5{0.8870} 62.6{0.8878} 62.7{0.8886} 62.8{0.8894} 62.9{0.8902}63.0{0.8910} 63.1{0.8918} 63.2{0.8926} 63.3{0.8934} 63.4{0.8942} 63.5{0.8949}63.6{0.8957} 63.7{0.8965} 63.8{0.8973} 63.9{0.8980}64.0{0.8988} 64.1{0.8996} 64.2{0.9003} 64.3{0.9011} 64.4{0.9018} 64.5{0.9026}64.6{0.9033} 64.7{0.9041} 64.8{0.9048} 64.9{0.9056} 65.0{0.9063} 65.1{0.9070}65.2{0.9078} 65.3{0.9085} 65.4{0.9092} 65.5{0.9100} 65.6{0.9107} 65.7{0.9114}65.8{0.9121} 65.9{0.9128} 66.0{0.9135} 66.1{0.9143} 66.2{0.9150} 66.3{0.9157}66.4{0.9164} 66.5{0.9171} 66.6{0.9178} 66.7{0.9184} 66.8{0.9191} 66.9{0.9198}67.0{0.9205} 67.1{0.9212} 67.2{0.9219} 67.3{0.9225} 67.4{0.9232} 67.5{0.9239}67.6{0.9245} 67.7{0.9252} 67.8{0.9259} 67.9{0.9265} 68.0{0.9272} 68.1{0.9278}68.2{0.9285} 68.3{0.9291} 68.4{0.9298} 68.5{0.9304} 68.6{0.9311} 68.7{0.9317}68.8{0.9323} 68.9{0.9330} 69.0{0.9336} 69.1{0.9342} 69.2{0.9348} 69.3{0.9354}69.4{0.9361} 69.5{0.9367} 69.6{0.9373} 69.7{0.9379} 69.8{0.9385} 69.9{0.9391}70.0{0.9397} 70.1{0.9403} 70.2{0.9409} 70.3{0.9415} 70.4{0.9421} 70.5{0.9426}70.6{0.9432} 70.7{0.9438} 70.8{0.9444} 70.9{0.9449} 71.0{0.9455} 71.1{0.9461}71.2{0.9466} 71.3{0.9472} 71.4{0.9478} 71.5{0.9483} 71.6{0.9489} 71.7{0.9494}71.8{0.9500} 71.9{0.9505} 72.0{0.9511} 72.1{0.9516} 72.2{0.9521} 72.3{0.9527}72.4{0.9532} 72.5{0.9537} 72.6{0.9542} 72.7{0.9548} 72.8{0.9553} 72.9{0.9558}73.0{0.9563} 73.1{0.9568} 73.2{0.9573} 73.3{0.9578} 73.4{0.9583} 73.5{0.9588}73.6{0.9593} 73.7{0.9598} 73.8{0.9603} 73.9{0.9608} 74.0{0.9613} 74.1{0.9617}74.2{0.9622} 74.3{0.9627} 74.4{0.9632} 74.5{0.9636} 74.6{0.9641} 74.7{0.9646}74.8{0.9650} 74.9{0.9655} 75.0{0.9659} 75.1{0.9664} 75.2{0.9668} 75.3{0.9673}75.4{0.9677} 75.5{0.9681} 75.6{0.9686} 75.7{0.9690} 75.8{0.9694} 75.9{0.9699}76.0{0.9703} 76.1{0.9707} 76.2{0.9711} 76.3{0.9715} 76.4{0.9720} 76.5{0.9724}76.6{0.9728} 76.7{0.9732} 76.8{0.9736} 76.9{0.9740} 77.0{0.9744} 77.1{0.9748}77.2{0.9751} 77.3{0.9755} 77.4{0.9759} 77.5{0.9763} 77.6{0.9767} 77.7{0.9770}77.8{0.9774} 77.9{0.9778} 78.0{0.9781} 78.1{0.9785} 78.2{0.9789} 78.3{0.9792}78.4{0.9796} 78.5{0.9799} 78.6{0.9803} 78.7{0.9806} 78.8{0.9810} 78.9{0.9813}79.0{0.9816} 79.1{0.9820} 79.2{0.9823} 79.3{0.9826} 79.4{0.9829} 79.5{0.9833}79.6{0.9836} 79.7{0.9839} 79.8{0.9842} 79.9{0.9845} 80.0{0.9848} 80.1{0.9851}80.2{0.9854} 80.3{0.9857} 80.4{0.9860} 80.5{0.9863} 80.6{0.9866} 80.7{0.9869}80.8{0.9871} 80.9{0.9874} 81.0{0.9877} 81.1{0.9880} 81.2{0.9882} 81.3{0.9885}81.4{0.9888} 81.5{0.9890} 81.6{0.9893} 81.7{0.9895} 81.8{0.9898} 81.9{0.9900}82.0{0.9903} 82.1{0.9905} 82.2{0.9907} 82.3{0.9910} 82.4{0.9912} 82.5{0.9914} 82.6{0.9917} 82.7{0.9919} 82.8{0.9921} 82.9{0.9923} 83.0{0.9925} 83.1{0.9928}83.2{0.9930} 83.3{0.9932} 83.4{0.9934} 83.5{0.9936} 83.6{0.9938} 83.7{0.9940}83.8{0.9942} 83.9{0.9943} 84.0{0.9945} 84.1{0.9947} 84.2{0.9949} 84.3{0.9951}84.4{0.9952} 84.5{0.9954} 84.6{0.9956} 84.7{0.9957} 84.8{0.9959} 84.9{0.9960}85.0{0.9962} 85.1{0.9963} 85.2{0.9965} 85.3{0.9966} 85.4{0.9968} 85.5{0.9969}85.6{0.9971} 85.7{0.9972} 85.8{0.9973} 85.9{0.9974}86.0{0.9976} 86.1{0.9977} 86.2{0.9978} 86.3{0.9979} 86.4{0.9980} 86.5{0.9981}86.6{0.9982} 86.7{0.9983} 86.8{0.9984} 86.9{0.9985} 87.0{0.9986} 87.1{0.9987}87.2{0.9988} 87.3{0.9989} 87.4{0.9990} 87.5{0.9990} 87.6{0.9991} 87.7{0.9992}87.8{0.9993} 87.9{0.9993} 88.0{0.9994} 88.1{0.9995} 88.2{0.9995} 88.3{0.9996}88.4{0.9996} 88.5{0.9997} 88.6{0.9997} 88.7{0.9997} 89.6{1.0000} 88.8{0.9998}89.7{1.0000} 88.9{0.9998} 89.8{1.0000} 89.0{0.9998} 89.9{1.0000} 89.1{0.9999}90.0{1.0000} 89.2{0.9999} 89.3{0.9999} 89.4{0.9999} 89.5{1.0000}计算机应用单片机在双电机同步控制系统中的应用电力公司苏州热工研究所(苏州215004仲华明摘要文章介绍了利用单片机开发的一种能取代用常规电动仪表组成的双电机同步控制装置,介绍了该装置的组成及软硬件的设计思想。
fortran dsqrt函数
fortran dsqrt函数DSQRT函数是Fortran语言提供的双精度平方根函数。
Fortran是一种高级程序语言,用于科学计算和工程计算。
这种语言主要是为数值计算设计的,因此,它提供了一系列的常见数学函数。
DSQRT函数就是其中的一种,它用于计算双精度浮点数的平方根。
DSQRT函数的语法:double precision function dsqrt(x)real*8 x其中,x是一个双精度实数,它的平方根将被计算。
DSQRT函数返回一个双精度浮点数,它是参数x的平方根。
DSQRT函数可以在程序中任何地方使用,只需要在需要计算平方根的地方调用它即可。
例如,要计算一个双精度实数y的平方根,可以这样写程序:在上面的程序中,双精度实数y的值为16.0,DSQRT函数被调用来计算y的平方根,并将计算结果存储在另一个双精度变量y_sqrt中。
最后,程序使用WRITE语句将y和y_sqrt打印到标准输出设备上。
尽管DSQRT函数可以计算双精度实数的平方根,但是,它也有一些局限性。
首先,DSQRT函数只能处理正数。
如果传递给它的参数是负数,它将返回一个NaN值。
其次,DSQRT函数的计算精度有限,因此,在处理一些非常小或非常大的双精度实数时,它的计算结果可能会出现误差。
总之,DSQRT函数是Fortran语言提供的一个非常有用的数学函数。
它可以计算双精度实数的平方根,并在科学计算和工程计算中得到广泛应用。
然而,用户在使用DSQRT函数时,需要注意它的局限性,并且尽可能地选择算法和数据类型来避免误差。
Quake-III代码里神奇的浮点开方函数
Quake-III Arena (雷神之锤3)是90年代的经典游戏之一。
该系列的游戏不但画面和内容不错,而且即使计算机配置低,也能极其流畅地运行。
这要归功于它3 D引擎的开发者约翰-卡马克(John Carmack)。
事实上早在90年代初DOS时代,只要能在PC上搞个小动画都能让人惊叹一番的时候,John Carmack就推出了石破天惊的Castle Wolfstein, 然后再接再励,doom, doomII, Quake...每次都把3-D技术推到极致。
他的3D引擎代码资极度高效,几乎是在压榨PC机的每条运算指令。
当初MS的Direct3D也得听取他的意见,修改了不少API。
最近,QUAKE的开发商ID SOFTWARE遵守GPL协议,公开了QUAKE-III 的原代码,让世人有幸目睹Carmack传奇的3D引擎的原码。
这是QUAKE-III原代码的下载地址:/file.x?fid=7547(下面是官方的下载网址,搜索“quake3-1.32b-source.zip” 可以找到一大堆中文网页的ftp:///idstuff/source/quake3-1.32b-source.zip)我们知道,越底层的函数,调用越频繁。
3D引擎归根到底还是数学运算。
那么找到最底层的数学运算函数(在game/code/q_math.c),必然是精心编写的。
里面有很多有趣的函数,很多都令人惊奇,估计我们几年时间都学不完。
在game/code/q_math.c里发现了这样一段代码。
它的作用是将一个数开平方并取倒,经测试这段代码比(float)(1.0/sqrt(x))快4倍:float Q_rsqrt( float number ){long i;float x2, y;const float threehalfs = 1.5F;x2 = number * 0.5F;y = number;i = * ( long * ) &y; // evil floating point bit level hackingi = 0x5f3759df - ( i >> 1 ); // what the fuck?y = * ( float * ) &i;y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be re moved#ifndef Q3_VM#ifdef __linux__assert( !isnan(y) ); // bk010122 - FPE?#endif#endifreturn y;}函数返回1/sqrt(x),这个函数在图像处理中比sqrt(x)更有用。
浅谈各种浮点数运算函数
浅谈各种浮点数运算函数浅谈各种浮点数运算函数
本篇随笔简单介绍⼀下C++中各种浮点数处理函数的功能。
⼀、浮点数的处理
有些时候运算的时候是浮点数,但是输出的时候要输出整数。
这时要根据题意对浮点数进⾏处理。
⼆、向上/下取整
向上取整的函数为ceil()
不⽤管是不是四舍五⼊,直接往⼤了去就⾏。
⽐如:
ceil(2.3)=3
ceil(-2.8)=-2
向下取整的函数为floor()
往⼩了去就⾏:
floor(2.8)=2
floor(-3.2)=-4
三、四舍五⼊
四舍五⼊函数为round(),即(⼤约)的意思。
⽐如:
round(2.4)=2
round(2.6)=3
四、截断
截断函数是trunc()。
所谓截断的意思是直接暴⼒砍掉⼩数部分,不进⾏任何取整或舍、⼊的操作。
⽐如:
trunc(2.8)=2
reunc(-2.6)=-2。
磁场定向算法c语言浮点运算仿真
磁场定向算法c语言浮点运算仿真
磁场定向算法(FOC, Field Oriented Control)在C语言中进行浮点运算仿真,主要是为了模拟永磁同步电机(PMSM)或交流感应电机(ACIM)的磁场定向控制过程。
该算法首先通过霍尔传感器或编码器获取电机的实际转子位置信息,接着利用Clark变换和Park变换将三相交流信号转换至直轴(d轴)和交轴(q轴)坐标系下,然后在d-q坐标系中进行矢量控制,计算出理想的d轴和q轴电流,并通过PI控制器调节逆变器输出,实现电机的精确控制。
在C语言中进行仿真时,浮点运算用于保证算法计算的精度,尤其是在角度计算、坐标变换和控制律计算等环节。
借鉴并改进的单片机c语言 含浮点数 快速开方程序
#include "stdio.h"unsigned short sqrt(unsigned long a); unsigned int sqrt_16(unsigned long M) ; void main (void){ float n=3.3,m=33,x,y;while(1){scanf("%f",&m);m=m*10000;n=m+10000;system("cls");printf("sqrt %g =",m/10000);x=sqrt(m);printf("%g\n",x/100);printf("%g\n",x*x/10000);printf("sqrt %g =",n/10000);y=sqrt_16(n);printf("%g\n",y/100);printf("%g\n",y*y/10000);printf("\n");}}unsigned short sqrt(unsigned long a) { char i;unsigned long rem = 0;unsigned long root = 0;unsigned long divisor = 0;for(i=0; i<16; i++){root <<= 1;rem = ((rem << 2) + (a >> 30));a <<= 2;divisor = (root<<1) + 1;if(divisor <= rem){rem -= divisor;root++;}}return (float)(root);}unsigned int sqrt_16(unsigned long M){unsigned int N, i;unsigned long tmp, ttp; // 结果、循环计数if (M == 0) // 被开方数,开方结果也为0return 0;N = 0;tmp = (M >> 30); // 获取最高位:B[m-1]M <<= 2;if (tmp > 1) // 最高位为1{N ++; // 结果当前位为1,否则为默认的0tmp -= N;}for (i=15; i>0; i--) // 求剩余的15位{N <<= 1; // 左移一位tmp <<= 2;tmp += (M >> 30); // 假设ttp = N;ttp = (ttp<<1)+1;M <<= 2;if (tmp >= ttp) // 假设成立0.01~429496{tmp -= ttp;N ++;}}return (float)(N);}。
c语言中sqrt用法
c语言中sqrt用法一、概述sqrt是C语言中的一个数学函数,用于计算一个数的平方根。
它是math.h头文件中定义的函数,需要在使用前进行头文件的包含。
二、函数原型double sqrt(double x);其中,x为要计算平方根的数字,返回值为x的平方根。
三、使用方法1. 计算整数的平方根对于整数类型,可以直接传入参数计算平方根。
例如:```#include <stdio.h>#include <math.h>int main() {int x = 16;double result = sqrt(x);printf("%lf", result);return 0;}```输出结果为:4.0000002. 计算浮点数的平方根对于浮点数类型,同样可以直接传入参数计算平方根。
例如:```#include <stdio.h>#include <math.h>int main() {double x = 2.0;double result = sqrt(x);printf("%lf", result);return 0;}```输出结果为:1.4142143. 错误处理当传入负数时,sqrt函数会返回NaN(Not a Number)表示无法计算。
例如:```#include <stdio.h>#include <math.h>int main() {double x = -1.0;double result = sqrt(x);printf("%lf", result);return 0;}```输出结果为:nan四、注意事项1. 头文件包含在使用sqrt函数前需要进行头文件的包含,即:```#include <math.h>```2. 参数类型sqrt函数的参数可以是整数类型、浮点数类型等,但不能是字符类型。
卡马克的求平方根的倒数的程序(快速平方根倒数算法)
卡马克的求平方根的倒数的程序(快速平方根倒数算法)2009-09-18 10:45:01| 分类:离奇的code |字号大中小订阅这个程序,大概在2006年看到的,当时进行了分析,主要分析了位运算那部分:如何利用浮点数的位表示法快速计算一个近似值。
而对于整个迭代计算原理并没有仔细看,今天再重新分析一下,并把当时那部分分析写的更明了些。
原贴如下:----------------------------------------------------------------------------------------------------------发信人: interma ( 4PZP | 抓紧时间| OFG P ), 信区: C_Cpp标题: [zz] 源自Quake3的快速求InvSqrt()函数发信站: 兵马俑BBS (Mon Dec 4 13:11:36 2006), 本站(202.117.1.8)/article.pl?sid=06/12/04/0210205&from=rss"人们很早就在Quake3源代码中发现了如下的C代码,它可以快速的求1/sqrt(x),在3D图形向量计算方面应用很广。
float InvSqrt(float x){float xhalf=0.5f*x;long i=*(long*)&x;i=0x5f3759df - (i>>1);x=*(float *)&i;x=x*(1.5f-xhalf*x*x);return x;}的Ryszard Sommefeldt一直在想到底是哪个家伙写了这些神奇的代码?2003年Chris Lomont还写了一篇文章(PDF)对这些代码进行了分析。
毫无疑问写出这些代码的人绝对是天才。
"是John Carmack?Michael Abrash?John Carmack在邮件回复中明确表示不是他,也不是Michael,可能是Terje Matheson。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Quake-III Arena (雷神之锤3)是90年代的经典游戏之一。
该系列的游戏不但画面和内容不错,而且即使计算机配置低,也能极其流畅地运行。
这要归功于它3 D引擎的开发者约翰-卡马克(John Carmack)。
事实上早在90年代初DOS时代,只要能在PC上搞个小动画都能让人惊叹一番的时候,John Carmack就推出了石破天惊的Castle Wolfstein, 然后再接再励,doom, doomII, Quake...每次都把3-D技术推到极致。
他的3D引擎代码资极度高效,几乎是在压榨PC机的每条运算指令。
当初MS的Direct3D也得听取他的意见,修改了不少API。
最近,QUAKE的开发商ID SOFTWARE遵守GPL协议,公开了QUAKE-III 的原代码,让世人有幸目睹Carmack传奇的3D引擎的原码。
这是QUAKE-III原代码的下载地址:
/file.x?fid=7547
(下面是官方的下载网址,搜索“quake3-1.32b-source.zip” 可以找到一大堆中文网页的
ftp:///idstuff/source/quake3-1.32b-source.zip)
我们知道,越底层的函数,调用越频繁。
3D引擎归根到底还是数学运算。
那么找到最底层的数学运算函数(在game/code/q_math.c),必然是精心编写的。
里面有很多有趣的函数,很多都令人惊奇,估计我们几年时间都学不完。
在game/code/q_math.c里发现了这样一段代码。
它的作用是将一个数开平方并取倒,经测试这段代码比(float)(1.0/sqrt(x))快4倍:
float Q_rsqrt( float number )
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be re moved
#ifndef Q3_VM
#ifdef __linux__
assert( !isnan(y) ); // bk010122 - FPE?
#endif
#endif
return y;
}
函数返回1/sqrt(x),这个函数在图像处理中比sqrt(x)更有用。
注意到这个函数只用了一次叠代!(其实就是根本没用叠代,直接运算)。
编译,实验,这个函数不仅工作的很好,而且比标准的sqrt()函数快4倍!要知道,编译器自带的函数,可是经过严格仔细的汇编优化的啊!
这个简洁的函数,最核心,也是最让人费解的,就是标注了“what the fuck?”的一句
i = 0x5f3759df - ( i >> 1 );
再加上y = y * ( threehalfs - ( x2 * y * y ) );
两句话就完成了开方运算!而且注意到,核心那句是定点移位运算,速度极快!特别在很多没有乘法指令的RISC结构CPU上,这样做是极其高效的。
算法的原理其实不复杂,就是牛顿迭代法,用x-f(x)/f'(x)来不断的逼近f(x)=a的根。
简单来说比如求平方根,f(x)=x^2=a ,f'(x)= 2*x,f(x)/f'(x)=x/2,把f(x)代入
x-f(x)/f'(x)后有(x+a/x)/2,现在我们选a=5,选一个猜测值比如2,
那么我们可以这么算5/2 = 2.5; (2.5+2)/2 = 2.25; 5/2.25 = xxx; (2.25+xx x)/2 = xxxx ... 这样反复迭代下去,结果必定收敛于sqrt(5),没错,一般的求平方根都是这么算的但是卡马克(quake3作者)真正牛B的地方是他选择了一个神秘的常数0x5f3759df 来计算那个猜测值就是我们加注释的那一行,那一行算出的值非常接近1/sqrt(n),这样我们只需要2次牛顿迭代就可以达到我们所需要的精度.
好吧如果这个还不算NB,接着看:
普渡大学的数学家Chris Lomont看了以后觉得有趣,决定要研究一下卡马克弄出来的这个猜测值有什么奥秘。
Lomont也是个牛人,在精心研究之后从理论上也推导出一个最佳猜测值,和卡马克的数字非常接近, 0x5f37642f。
卡马克真牛,他是外星人吗?
传奇并没有在这里结束。
Lomont计算出结果以后非常满意,于是拿自己计算出的起始值和卡马克的神秘数字做比赛,看看谁的数字能够更快更精确的求得平方根。
结果是卡马克赢了... 谁也不知道卡马克是怎么找到这个数字的。
最后Lomont怒了,采用暴力方法一个数字一个数字试过来,终于找到一个比卡马克数字要好上那么一丁点的数字,虽然实际上这两个数字所产生的结果非常近似,这个暴力得出的数字是0x5f375a86。
Lomont为此写下一篇论文,"Fast Inverse Square Root"。
论文下载地址:
/~clomont/Math/Papers/2003/InvSqrt.pdf /data/InvSqrt.pdf
参考:<IEEE Standard 754 for Binary Floating-Point Arithmetic><FAST INV ERSE SQUARE ROOT>
最后,给出最精简的1/sqrt()函数:
float InvSqrt(float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating VALUE
i = 0x5f375a86- (i>>1); // gives initial guess y0
x = *(float*)&i; // convert bits BACK to float
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy return x;
}
大家可以尝试在PC机、51、AVR、430、ARM、上面编译并实验,惊讶一下它的工作效率。
前兩天有一則新聞,大意是說Ryszard Sommefeldt 很久以前看到這麼樣的一段code (可能出自Quake III的source code):
float InvSqrt (float x) {
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f3759df - (i>>1);
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
return x;
}
他一看之下驚為天人,想要拜見這位前輩高人,但是一路追尋下去卻一直找不到人;同時間也有其他人在找,雖然也沒找到出處,但是Chris Lomont寫了一篇論文(in PDF)解析這段code 的演算法(用的是Newton’s Method,牛頓法;比較重要的是後半段講到怎麼找出神奇的0x5f3759df的)。
PS. 這個function 之所以重要,是因為求開根號倒數這個動作在3D 運算(向量運算的部份) 裡面常常會用到,如果你用最原始的sqrt()然後再倒數的話,速度比上面的這個版本大概慢了四倍吧… XD
PS2. 在他們追尋的過程中,有人提到一份叫做MIT HACKMEM的文件,這是1970 年代的MIT強者們做的一些筆記(hack memo),大部份是algorithm,有些code 是PDP-10 asm 寫的,另外有少數是 C code (有人整理了一份列表)。
附:牛顿迭代法快速寻找平方根
下面这种方法可以很有效地求出根号a的近似值:首先随便猜一个近似值x,然后不断令x等于x和a/x的平均数,迭代个六七次后x的值就已经相当精确了。
例如,我想求根号2等于多少。
假如我猜测的结果为4,虽然错的离谱,但你可以看到使用牛顿迭代法后这个值很快就趋近于根号2了:
( 4 + 2/ 4 ) / 2 = 2.25
( 2.25 + 2/ 2.25 ) / 2 = 1.56944..
( 1.56944..+ 2/1.56944..) / 2 = 1.42189..
( 1.42189..+ 2/1.42189..) / 2 = 1.41423..
....
这种算法的原理很简单,我们仅仅是不断用(x,f(x))的切线来逼近方程x^2 -a=0的根。
根号a实际上就是x^2-a=0的一个正实根,这个函数的导数是2x。
也就是说,函数上任一点(x,f(x))处的切线斜率是2x。
那么,x-f(x)/(2x)就是一个比x更接近的近似值。
代入f(x)=x^2-a得到x-(x^2-a)/(2x),也就是(x+a/x)/2。