C++的 sqrt 问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++的 sqrt 问题相关的知识,希望对你有一定的参考价值。
下面是代码:
#include <iostream>
using namespace std;
#include <math.h>
void main()
double a,R;
cout<<"输入正五边形的边长"<<'\n';
cin>>a;
R=a*(sqrt((10+2*sqrt(5))/5))/2;
cout<<"该五边形外接圆的半径R="<<R<<'\n';
这段代码我在VC6.0中运行就可以,但是我在VS2005中运行就会出错。错误是:
e:\c++\lx\01\01\01.cpp(12) : error C2668: 'sqrt' : ambiguous call to overloaded function
d:\program files\microsoft visual studio 8\vc\include\math.h(581): could be 'long double sqrt(long double)'
d:\program files\microsoft visual studio 8\vc\include\math.h(533): or 'float sqrt(float)'
d:\program files\microsoft visual studio 8\vc\include\math.h(128): or 'double sqrt(double)'
while trying to match the argument list '(int)'
为什么咧?怎么办?
讲得详细些好吗?
因为C++支持重载函数,如果参数不匹配那么就认为找不到该函数。
而C不支持重载,所以会自动将你的5转换成浮点数再运算,就不报错了。
正确的做法,将aqrt(5)改为sqrt(5.0) 参考技术A sqrt(5.0) 参考技术B 意思就是调用sqrt()出现了二义性,因为sqrt()函数有几个重载函数,sqrt( (double)n )以及sqrt( (float)n ),你调用的时候强制转换一下,你程序中都是用double,就牵制转换为double了,这样改就行了:
R=a*((double)sqrt((10+2*sqrt((double)5))/5))/2; 参考技术C 你用#include<cmath>试试,好像在C++里面,都要用C++里面的头文件
另外,你也可做个强制转换
(int)sqrt(5);
C++ sqrt 函数的全平方精度
【中文标题】C++ sqrt 函数的全平方精度【英文标题】:C++ sqrt function precision for full squares 【发布时间】:2013-11-22 04:37:16 【问题描述】:设,x
是一个整数,y = x * x
。
那么保证sqrt(y) == x
?
例如,我能否确定sqrt(25)
或sqrt(25.0)
将返回5.0
,而不是5.0000000003
或4.999999998
?
【问题讨论】:
如果5不能准确表示,怎么可能呢?您可以期望的最好结果是它会截断为 5。 既然5是整数,不应该精确表示吗?我在某处读到 double 可以准确地将值存储在整数范围内。 @RafiKamal:一个 IEEE-754 64 位双精度浮点数可以准确地表示整个 32 位有符号和无符号整数范围而不会丢失。在那种情况下,这只控制类型转换。它不控制计算sqrt(x)
的浮点库的精度。
相关问题:Floating point inaccuracy examples
@JoeZ 谢谢,我明白了
【参考方案1】:
符合 IEEE-754 标准的关于基本操作允许错误的实现(sqrt
是一个示例)要求对值进行正确舍入。
这意味着误差将小于 1/2 ULP(最后一个单位)或基本上尽可能接近实际答案。
要回答您的问题,如果实际答案完全可以用 double
表示,那么您将得到准确的答案。
注意:C++ 标准并不能保证这一点,而是 IEEE-754 标准,这对大多数人来说可能不是问题。
最终,一个简单的测试应该足以满足您的目的:
for(int i = 0; i < (int)std::sqrt(std::numeric_limits<int>::max()); i++)
assert((int)(double)i == i);//Ensure exactly representable, because why not
assert(std::sqrt((double)i*i) == i);
如果这一切都过去了,我认为没有任何理由担心。
【讨论】:
【参考方案2】:不,您不能得到保证。对于适合浮点类型尾数动态范围的整数及其平方(对于典型的 C/C++ double
,为 2^53),您可能没问题,但不一定能保证。
您应该避免在浮点值和精确值之间进行相等比较,尤其是精确整数值。浮点舍入模式和其他类似的东西真的会妨碍你。
您要么想使用“比较范围”来接受“近似相等”的结果,要么根据整数重新调整算法。有多个 *** 问题涉及浮点相等比较。我建议你搜索它们并阅读。
对于某一类问题,我在这里写了一个替代解决方案: Find n-th root of all numbers within an interval
该解决方案采用了不同于依赖复杂浮点运算的方法。
【讨论】:
【参考方案3】:您应该能够很容易地暴力搜索高达 2^26 的所有值,但我相信答案是肯定的。在那个数字之后,没有。
平方根的逐位数教科书算法以余数 == 0 结束,给出了准确的结果。再说一次,如果浮点库声称符合 ieee-754,它也会通过任何其他方式给出这个值。
【讨论】:
以上是关于C++的 sqrt 问题的主要内容,如果未能解决你的问题,请参考以下文章