繁体   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