簡體   English   中英

將size_t除以unsigned long並將結果賦值為double

[英]Divide an unsigned long for a size_t and assign the result to a double

我必須將一個unsigned long int除以size_t(從一個帶有size()的數組維返回),如下所示:

vector<string> mapped_samples;
vector<double> mean;
vector<unsigned long> feature_sum;
/* elaboration here */
mean.at(index) = feature_sum.at(index) /mapped_samples.size();

但是這樣就會發生整數除法(我丟失小數部分。這不好)

因此,我可以這樣做:

 mean.at(index) = feature_sum.at(index) / double(mapped_samples.size());

但是這樣, feature_sum.at(index)會自動轉換(臨時副本)為double ,我可能會失去精度。 我該如何解決這個問題? 我要用一些圖書館?

將無符號long轉換為double時可能會導致精度損失(因為無符號long值可能大於最大double)無符號long值是要素的總和(正值)。 特征的樣本可以是1000000或更多,並且特征的值的總和可以是nourmus。 因此,特征的最大值為2000:2000 * 1000000或更高

(我正在使用C ++ 11)

你可以嘗試使用std::div

沿線

auto dv = std::div(feature_sum.at(index), mapped_samples.size());

double mean = dv.quot + dv.rem / double(mapped_samples.size());

你可以使用:

// Grab the integral part of the division
auto v1 = feature_sum.at(index)/mapped_samples.size();

// Grab the remainder of the division
auto v2 = feature_sum.at(index)%mapped_samples.size();

// Dividing 1.0*v2 is unlikely to lose precision
mean.at(index) = v1 + static_cast<double>(v2)/mapped_samples.size();

你不能做得更好 (如果你想把結果存儲為double ),而不是簡單

std::uint64_t x=some_value, y=some_other_value;
auto mean = double(x)/double(y);

因為使用float128的截斷形式的正確結果的相對准確性

auto improved = double(float128(x)/float128(x))

通常是相同的(對於典型的輸入 - 可能有罕見的輸入,可能的改進)。 兩者都有一個相對誤差,由double尾(53位)的尾數長度決定。 所以,簡單的答案是:要么使用更精確的類型比double您的均值或忘記了這個問題。


為了看到相對准確性,我們假設這一點

x=a*(1+e);   // a=double(x)
y=b*(1+f);   // b=double(y)

其中ef的順序為2 ^ -53。

然后'正確'的商是ef第一個商

(x/y) = (a/b) * (1 + e - f)

將此轉換為double會導致另一個2 ^ -53的相對誤差,即與(a/b)的誤差相同的順序,這是天真的結果

mean = double(x)/double(y).

當然,當通過其他答案中建議的方法獲得更高的准確度時, ef可以合謀取消,但通常不能提高准確度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM