以下是问题的链接。 http://www.spoj.com/problems/TRIGALGE/
问题很简单,我们只需解决给定的等式。我决定尝试使用Newton-Raphson方法(https://en.wikipedia.org/wiki/Newton%27s_method)。
以下是我提交的代码的链接但得到的答案错误 - > http://ideone.com/dYev3P
我无法理解精确度背后的逻辑。 对于,
a=1 b=1 c=20
x should be , x=19.441787
但我正在
x=19.441786
我打印了整个系列100次迭代,但我没有得到确切的值。请告诉我正确的方法以及如何在处理浮点整数时获得正确的精度。
答案 0 :(得分:1)
Newton-Raphson的基本思想是连续近似。在某些范围内,您希望每个近似值都比前一个更好(尽管这并不完全保证,无论如何)。
就您的代码而言,您使用的是float
s,它们仅适用于大约7位有效数字的精度。这让你17.44179
成为你应该真正希望的最好的东西(事实上,在四舍五入到7位数之后,这正是你得到的)。
如果您确实需要8 th 数字的精度,则应使用double
代替float
作为数据类型。这不会改变您处理连续近似值的事实,但它确实意味着您可以预期大约15位精度而不是7位。
我可能还应该注意到,计算机浮点几乎总是近似的问题。使用正确的库,您可以接近数百甚至数万亿的数字,但是当您处理浮点数时,您通常不会期望某个特定答案是正确的,而其他答案是错误的,即使它们是& #39;几乎等于"权利"一。恰恰相反,你应该期待微小的变化(使用"次要"是一个相对的术语 - 即,可接受的错误与所涉及的数字的大小有关。
答案 1 :(得分:1)
除了Jerry的回答之外,不要忘记在每个.f
之后移除1.0
,以便将它们视为浮点数。这个并将你所有的花车改为双倍绝对可以解决问题。
答案 2 :(得分:1)
如果您只是将float
更改为double
,那么在迭代7之后您确实已经19.441786710
了。
#include <cmath>
#include <iostream>
void solve(int a,int b,int c){
double x = 0.2 ;
for(int i=0;i<15;i++){
x = x*1.0 - ( ( (a*x*1.0 + ( b*sin(x)*1.0 ) )*1.0 - c*1.0 )/
(a*1.0 + b*(cos(x))*1.0 ) ) ;
std::cout << i << " " << x-19.441787 << std::endl;
}
}
int main(){
solve(1,1,20) ;
}