![](/img/trans.png)
[英]how to std::variant<unsigned long, size_t, unsigned int>
[英]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)
其中e
, f
的順序為2 ^ -53。
然后'正確'的商是e
和f
第一個商
(x/y) = (a/b) * (1 + e - f)
將此轉換為double
會導致另一個2 ^ -53的相對誤差,即與(a/b)
的誤差相同的順序,這是天真的結果
mean = double(x)/double(y).
當然,當通過其他答案中建議的方法獲得更高的准確度時, e
和f
可以合謀取消,但通常不能提高准確度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.