InvSqrt()函数结果不对,求解

icesongqiang 2016-09-25 05:40:29

#include <iostream>
#include <cmath>
#include <ctime>
#include <windows.h>
void sqrt_inv(double x)
{
cout << "x= " << x << endl;
clock_t start = clock();
const float threehalfs = 1.5F;
double xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating VALUE
cout << "i= " << i << endl;
i = 0x5f375a86 - (i >> 1); // gives initial guess y0
x = *(float*)&i; // convert bits BACK to float
cout << "x= " << x << endl;
x = x*(threehalfs - xhalf*x*x); // Newton step, repeating increases accuracy
x = x*(threehalfs - xhalf*x*x); // Newton step, repeating increases accuracy
x = x*(threehalfs - xhalf*x*x); // Newton step, repeating increases accuracy
double ans = 1.0 / x;
Sleep(1000);
clock_t finish = clock();

cout << "inv:" << "\t" << ans << "\t" << start << "\t" << finish << "\t" << (finish - start) << endl; // (finish - start) / CLOCKS_PER_SEC
}
int main()
{
double x = 2;
//sqrt_sys(x);
sqrt_inv(x);
//sqrt_Newton(x);
system("pause");
return 0;
}



输出:

...全文
753 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
其实迭代一次就可以了,迭代三次精度也没提高多少,性能下降不少。要快的话可以使用rsqrtss指令,速度很好,精度一般,对于VC++、intel C++可以直接使用_mm_rsqrt_ss,不需要内嵌汇编。
icesongqiang 2016-09-27
  • 打赏
  • 举报
回复

void sqrt_inv(float x)     // 参数类型是float
{
	cout << "x= " << x << endl;
	clock_t start = clock();
	const float threehalfs = 1.5F;
	double xhalf = 0.5f*x;
	int i = *(int*)&x;              // get bits for floating VALUE 
	cout << "i= " << i << endl;
	i = 0x5f375a86 - (i >> 1);      // gives initial guess y0
	x = *(float*)&i;                // convert bits BACK to float
	cout << "x= " << x << endl;
	x = x*(threehalfs - xhalf*x*x); // Newton step, repeating increases accuracy
	x = x*(threehalfs - xhalf*x*x); // Newton step, repeating increases accuracy
	x = x*(threehalfs - xhalf*x*x); // Newton step, repeating increases accuracy
	double ans = 1.0 / x;
	Sleep(1000);
	clock_t finish = clock();

	cout << "float_inv:" << "\t" << ans << "\t" << start << "\t" << finish << "\t" << (finish - start) << endl;  // (finish - start) / CLOCKS_PER_SEC
}

void sqrt_inv(double x)     // 类型是double
{
	clock_t start = clock();
	const double threehalfs = 1.5F;
	double xhalf = 0.5f*x;
	long long i = *(long long*)&x;              // get bits for floating VALUE 
	cout << "i= " << i << endl;
	i = 0x5fe6ec85e7de30da - (i >> 1);      // gives initial guess y0
	x = *(double*)&i;                // convert bits BACK to float
	cout << "x= " << x << endl;
	x = x*(threehalfs - xhalf*x*x); // Newton step, repeating increases accuracy
	x = x*(threehalfs - xhalf*x*x); // Newton step, repeating increases accuracy
	x = x*(threehalfs - xhalf*x*x); // Newton step, repeating increases accuracy
	double ans = 1.0 / x;
	Sleep(1000);
	clock_t finish = clock();

	cout << "double_inv:" << "\t" << ans << "\t" << start << "\t" << finish << "\t" << (finish - start) << endl;  // (finish - start) / CLOCKS_PER_SEC
}
  • 打赏
  • 举报
回复
这个carmack的快速开平方根倒数算法只适用于float,如果double参数的话要: double InvSqrt(double x) { double xhalf = 0.5 * x; long long i = *(long long *)&x; i = 0x5fe6ec85e7de30da - (i >> 1); x = *(double *)&i; x = x * (1.5 - xhalf * x * x); return x; }

13,824

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧