简体   繁体   English

将size_t除以unsigned long并将结果赋值为double

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

I have to divide an unsigned long int for a size_t (returned from a dimension of a array with size() ) like this: 我必须将一个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();

but in this way an integer division takes place (I lose the decimal part. That's no good) 但是这样就会发生整数除法(我丢失小数部分。这不好)

Therefore, I can do: 因此,我可以这样做:

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

But in this way feature_sum.at(index) is automatically converted (Temporary copy) to double and I could lose precision. 但是这样, feature_sum.at(index)会自动转换(临时副本)为double ,我可能会失去精度。 How can I tackle the question? 我该如何解决这个问题? I have to use some library? 我要用一些图书馆?

It could be precision loss when you convert the unsigned long in double (because the unsigned long value could be larger than maximum double) The unsigned long value is the sum of the features (positives values). 将无符号long转换为double时可能会导致精度损失(因为无符号long值可能大于最大double)无符号long值是要素的总和(正值)。 The samples of feature can be 1000000 or more and the sum of values of the features can be enourmus. 特征的样本可以是1000000或更多,并且特征的值的总和可以是nourmus。 The max value of a feature is 2000 thus: 2000*1000000 or more 因此,特征的最大值为2000:2000 * 1000000或更高

(I'm using C++11) (我正在使用C ++ 11)

You could try to use std::div 你可以尝试使用std::div

Along the lines 沿线

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

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

You could use: 你可以使用:

// 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();

you cannot do better (if you want to store the result as a double ), than the simple 你不能做得更好 (如果你想把结果存储为double ),而不是简单

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

because the relative accuracy of the truncated form of the correct result using float128 因为使用float128的截断形式的正确结果的相对准确性

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

is typically the same (for typical input -- there may be rare inputs, where improvement is possible). 通常是相同的(对于典型的输入 - 可能有罕见的输入,可能的改进)。 Both have a relative error dictated by the length of the mantissa for double (53 bits). 两者都有一个相对误差,由double尾(53位)的尾数长度决定。 So the simple answer is: either use a more accurate type than double for your mean or forget about this issue. 所以,简单的答案是:要么使用更精确的类型比double您的均值或忘记了这个问题。


To see the relative accuracy, let us assume that 为了看到相对准确性,我们假设这一点

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

where e , f are of the order 2^-53. 其中ef的顺序为2 ^ -53。

Then the 'correct' quotient is to first order in e and f 然后'正确'的商是ef第一个商

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

Converting this to double incurs another relative error of the order of 2^-53, ie of the same order as the the error of (a/b) , the result of the naive 将此转换为double会导致另一个2 ^ -53的相对误差,即与(a/b)的误差相同的顺序,这是天真的结果

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

Of course, e and f can conspire to cancel, when more accuracy can be gained by the methods suggested in other answers, but typically the accuracy cannot be improved. 当然,当通过其他答案中建议的方法获得更高的准确度时, ef可以合谋取消,但通常不能提高准确度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM