R和C ++中的相同计算会返回不同的结果吗?

时间:2011-10-28 19:02:55

标签: c++ r

所以,我有一些R代码,我转向C ++。它读取文件,解析字符,计算吨数和吨数的均值和标准差,并返回它们,以及每个字符发生次数的计数。

现在,R产生的结果和C ++的结果的十进制值略有不同。在计数矩阵中,因为它们是整数,所以数字完全相同。然而,在均值矩阵中,这些值在百分之一的位置是相同的,并且它们之间的差别不同。使用标准偏差矩阵,数值差异更大 - 到十分之一。

造成这种情况的原因是什么?我假设R和C ++处理带小数的数字的方式存在某种精确差异。我知道计算机在开始时代表浮点数并不是最好的,但我怎么知道哪个输出更好?

...我尝试过的一件事是在Windows 7中的R,C ++和Calculator中执行计算sqrt(41111.5 / 4522)。它们都产生相同的结果。那么,为什么在运行时遇到这种完全相同的计算时,它们会有所不同吗?在运行时输出中,C ++与Calculator一致,R是奇数。我还注意到,在执行这些大量计算时,后来的输出比早期输出稍微变化一点。在进行如此多的计算并开始陷入困境时,R是否会感到疲倦?这是什么交易?

以下是均值的输出:

C ++:

38.6068 39.0122 38.633 38.5914 0
38.6159 38.7874 38.5053 38.7195 0
38.5205 38.7352 38.3694 38.5388 0
38.6331 38.7408 38.4588 38.5283 0
38.7503 38.6933 38.4173 38.6808 0
38.7637 38.7978 38.4967 38.603 0
38.7616 38.7384 38.4728 38.6946 0
38.6227 38.7689 38.4016 38.5352 0
38.5993 38.7334 38.3206 38.5514 0
38.6395 38.6598 38.43 38.4887 0
38.6414 38.746 38.4353 38.4908 0
38.4353 38.6767 38.3158 38.4694 0
38.35 38.5801 38.1486 38.3528 0
38.4122 38.6267 38.1731 38.3447 0
38.3751 38.5353 38.1782 38.2229 0
38.3373 38.6117 37.8952 38.2017 4.12443
38.332 38.4991 38.027 38.1984 0
38.2005 38.4417 38.0192 38.0446 4.12443
38.1719 38.4435 37.9727 38.0385 0
38.1346 38.3878 37.8634 37.9746 0
37.8505 38.2289 37.6202 37.6986 0
38.0932 38.142 37.7865 37.815 4.12443
37.9176 38.1381 37.5577 37.7273 0
37.7346 38.0934 37.4874 37.6546 0
37.6961 37.897 37.3342 37.4844 0
37.5534 37.9234 37.3341 37.3369 0
37.4914 37.7409 37.094 37.3211 0
37.2179 37.6653 36.9031 37.2592 0
37.0682 37.5625 36.6972 37.0218 4.12443
36.9713 37.4819 36.5387 36.8767 4.12443
36.8284 37.2411 36.223 36.6869 4.12443
36.7396 36.9682 36.0171 36.4556 4.12443
36.7874 36.9482 36.1641 36.5667 4.12443
36.695 36.9307 36.1856 36.3638 0
36.7224 36.9455 36.2212 36.695 4.12443
36.8983 37.1286 36.2652 36.8055 0
36.7835 36.8905 35.9562 36.4745 0
36.5364 36.9037 36.0927 36.4888 0
36.3959 36.6637 35.7378 36.323 0
35.9372 36.2034 35.452 35.6974 0

R:

            A        C        G        T N
[1,] 38.60573 39.01141 38.63195 38.59036 0
[2,] 38.61464 38.78523 38.50391 38.71826 0
[3,] 38.51908 38.73228 38.36774 38.53731 0
[4,] 38.63182 38.73834 38.45730 38.52657 0
[5,] 38.74903 38.69083 38.41585 38.67933 0
[6,] 38.76250 38.79534 38.49556 38.60156 0
[7,] 38.76039 38.73632 38.47145 38.69319 0
[8,] 38.62123 38.76703 38.40030 38.53354 0
[9,] 38.59810 38.73163 38.31917 38.55015 0
[10,] 38.63819 38.65792 38.42873 38.48740 0
[11,] 38.64002 38.74333 38.43387 38.48920 0
[12,] 38.43359 38.67401 38.31414 38.46783 0
[13,] 38.34827 38.57804 38.14686 38.35125 0
[14,] 38.41038 38.62463 38.17138 38.34302 0
[15,] 38.37329 38.53267 38.17653 38.22097 0
[16,] 38.33555 38.60949 37.89278 38.19956 4
[17,] 38.33024 38.49720 38.02496 38.19627 0
[18,] 38.19842 38.43880 38.01730 38.04205 4
[19,] 38.16998 38.44113 37.97058 38.03598 0
[20,] 38.13242 38.38488 37.86108 37.97245 0
[21,] 37.84771 38.22579 37.61745 37.69546 0
[22,] 38.09113 38.13806 37.78409 37.81250 4
[23,] 37.91487 38.13428 37.55473 37.72422 0
[24,] 37.73137 38.09007 37.48473 37.65181 0
[25,] 37.69295 37.89276 37.33098 37.48131 0
[26,] 37.54974 37.91984 37.33063 37.33263 0
[27,] 37.48773 37.73676 37.09027 37.31701 0
[28,] 37.21365 37.66051 36.89896 37.25519 0
[29,] 37.06418 37.55768 36.69254 37.01714 4
[30,] 36.96674 37.47745 36.53390 36.87150 4
[31,] 36.82324 37.23622 36.21721 36.68085 4
[32,] 36.73433 36.96207 36.01076 36.44930 4
[33,] 36.78201 36.94274 36.15842 36.56135 4
[34,] 36.68991 36.92524 36.17984 36.35769 0
[35,] 36.71720 36.94031 36.21548 36.68985 4
[36,] 36.89332 37.12322 36.25921 36.80057 0
[37,] 36.77870 36.88471 35.94958 36.46900 0
[38,] 36.53080 36.89801 36.08650 36.48348 0
[39,] 36.38996 36.65730 35.73058 36.31767 0
[40,] 35.93152 36.19707 35.44496 35.69141 0

3 个答案:

答案 0 :(得分:3)

你无疑知道,任何事情都可能发生。因此,我只能提出一个充满异国情调的可能原因。

一种可能性是R以最小化浮点错误的方式执行计算;你不一定要用C ++或手工计算,除非你知道的更好。特别是,在计算总和之前,应按递增的指数顺序对值进行排序(这应该是任何准确平均过程的第一步)。原因是浮点运算不是关联的(除非你使用的是仲裁精度库,我认为不是这种情况)。由于四舍五入,如果a>>,则(a + b)+ c可以等于c。 b,c而a +(b + c)将给出大于a的结果(假设a,b,c> 0)。如果R例如,这尤其可能。并行化其工作,在这种情况下,你可以合理地期望每个时间得到一个稍微不同的结果!

其他不那么奇特的可能性包括:R和C ++代码以某种微妙但有意义的方式不同(可能在错过第72个元素的错误中,或者使用n-1计算STDEV并使用n在另一个,等等); R和C ++之间的运行时间存在差异,这从根本上导致了这种差异(不同的精度 - 双精度与浮点数相比,长双精度数等,不同的库实现等)。

我无法判断这是否适用于您的问题,但如果没有其他人可能会发现这有用,如果他们无法理解为什么浮点运算没有给出一致的结果。

答案 1 :(得分:2)

我会检查一些事情:

  • 使用floatdouble甚至long double可能有所不同。如果您使用的是double,则可能是R使用float。如果它很容易在两者之间切换,请尝试使用float
  • 检查编译器中设置的浮点精度模式(例如VC2010)并尝试不同的设置。
  • 确保C ++中的所有计算都正确地转换为double / float。例如,此代码:

     double Test = 1.0 + 3/2;
    

    导致2而不是2.5。 R可能会以不同方式投射此类表达式,从而导致您的结果出现差异。

  • 仔细检查R和C ++中的函数是否相同。例如,R中的cos()可能需要度数,而C ++中则是弧度。如果有疑问,请在两者中进行快速测试,以确认。
  • 如果所有其他方法都失败,请在R和C ++应用程序中为其执行一次特定计算并记录/输出详细诊断。在某些时候,你应该开始看到差异,并追溯到它的起源。尝试使用较小的样本,看看是否可以用6/60样本而不是6000样本复制行为。

我刚注意到的一件事是,在最后一列结果中,C ++给出了4.12443而R给出了4.除非这只是一个显示问题,否则看看为什么会这样。可能是R中的某些内容被舍入/强制转换为整数但不是C ++。

答案 2 :(得分:-1)

好吧,我只是想使用C ++值,这主要归功于uesp对最后一列的见解-R可能在某个中间步骤中转换为整数并且失去一些精度。我在C ++的每一步都使用双打,所以我更信任它(...更不用说我开始时自然而然地不信任解释语言了,哈哈)

相关问题