[英]C++ double value losing precision when multiplied?
我正在嘗試創建一個函數來查找數字的平方根。 出於調試目的,它具有打印當前變量值的指令。 函數squareRoot
接受兩個參數x
和t
。 然后它聲明並初始化n
和s
。 n
是加或減的數量,每次使用時減半。 s
被認為是當前的平方根。 在跑步時,我可以清楚地看到n
正在正確調整。 但是,當前四位數字正確時, s
停止變化。 我在main()
使用此調用:
cout << squareRoot(1000, 10) << "\n";
這應該打印1000的平方根到最近的十分之一,但發生兩件奇怪的事情:
我關於它為什么停止在四位數的理論是這樣的:在乘法中, s
失去了它的一些精度。 這是真的? 如果是這樣,你能告訴我如何糾正它嗎? 如果沒有,導致這種情況的原因是什么?如何糾正?
我試圖通過使用另一個變量s1
來解決它,它將被乘以並檢查。 然后s
將增加n
, s1
與s
同步。 這沒用,所以我回到了原始代碼。
我的代碼如下:
#include <iostream>
using namespace std;
double squareRoot(double x, int t) {
double s = 0;
double n = 0.1;
while ((s*s) <= x) {
s += n;
n *= 2;
cout << n << "\n" << s << "\n";
}
cout << "\n";
s -= n;
// Keep changing until margin of error is reached
while ((((s*s) - x) < (1/t)) || ((x - (s*s) < (1/t)))) {
// If too high, lower s
if ((s*s) <= x) {
s += n;
n /= 2;
cout << "Adding 1/2 of previous n\n";
}
// If too low, raise s
else if ((s*s) >= x) {
s -= n;
n /= 2;
cout << "Subtracting 1/2 of previous n\n";
}
cout << s << "\n" << n << "\n\n";
}
return s;
}
我正在運行Windows 7 64位,MSVC ++ 2008 Express。 提前感謝您的所有答案!
它收斂到正確的平方根,但cout默認只打印六位有效數字:31.xxxx。
另請注意,您的終止檢查不起作用,因為對於t> 1,(1 / t)將始終評估為0。 請改用1./t。
原因循環沒有停止是循環條件不正確。 你有
while ((current - target < precision) || (target - current < precision)) {
...
}
但值current - target
或值target - current
將<= 0
。 並且0 < precision
。 因此,您具有等效的while (true) {...}
循環。
你需要類似的東西
while (abs(current - target) > precision) {
...
}
(不知道在C ++中獲取絕對值的確切函數)
編輯
剛剛注意到, hamster3null在我之前寫了大約1/t
。
不相關,但您的sqrt算法可以通過使用現有算法來加速,例如Newton's Method。
它是這樣的:
double mySqrt(double x, unsigned long accuracy = 10)
{
if(x < 0.0)
return(-1.0);
double retval = 1.0;
for(unsigned long rep = 0; rep < accuracy; rep++)
retval = ((x / retval) + retval) / 2.0;
return(retval);
}
牛頓方法也適用於立方根等。對於十進制指數,查找二項式定理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.