简体   繁体   English

C ++加法无效

[英]C++ Addition Not Working

I wrote up a solution for a Google Code Jam problem as demonstrated: 我写了一个解决Google Code Jam问题的解决方案,如下所示:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <cmath>

using namespace std;

int main(int argc, char** argv) {
        ifstream in;
        in.open(argv[1]);
        int t, c = 0;
        in >> t;
        while(c++<t) {
                string msg;
                in >> msg;
                map<char,int> m;
                int base = 0;
                for(char& ch : msg) {
                        if(!m[ch]) {
                                base++;
                                m[ch] = base == 1 ? base : (base == 2 ? -1 : base - 1);
                        }
                }
                if(base < 2)
                        base = 2;
                double total = 0;
                double p = pow(base, msg.size()-1);
                for(char& ch : msg) {
                        if(m[ch] != -1) {
                                if(c == 37) cout << "total=" << total << "+" << (m[ch] * p) << "=" << total + (m[ch] * p) << endl;
                                total = total + (m[ch] * p);
                        }
                        p /= base;
                }
                cout.precision(0);
                cout << fixed << "Case #" << c << ": " << total << endl;
        }
        in.close();
        return 0;
}

As you can see I have some debug statements being printed out for case 37 because some weird stuff happen there: 如您所见,我在案例37中打印了一些调试语句,因为那里发生了一些奇怪的事情:

Case #36: 1000000000000000000
total=0+450283905890997376=450283905890997376
total=450283905890997376+100063090197999424=550346996088996800
total=550346996088996800+16677181699666570=567024177788663360
total=567024177788663360+5559060566555523=572583238355218880
total=572583238355218880+1853020188851841=574436258544070720
total=574436258544070720+1235346792567894=575671605336638592
total=575671605336638592+205891132094649=575877496468733248
total=575877496468733248+68630377364883=575946126846098112
total=575946126846098112+22876792454961=575969003638553088
total=575969003638553088+15251194969974=575984254833523072
total=575984254833523072+847288609443=575985102122132544
total=575985102122132544+564859072962=575985666981205504
total=575985666981205504+62762119218=575985729743324736
total=575985729743324736+20920706406=575985750664031168
total=575985750664031168+6973568802=575985757637600000
total=575985757637600000+129140163=575985757766740160
total=575985757766740160+28697814=575985757795437952
total=575985757795437952+1594323=575985757797032256
total=575985757797032256+177147=575985757797209408
total=575985757797209408+59049=575985757797268480
total=575985757797268480+6561=575985757797275072
total=575985757797275072+4374=575985757797279424
total=575985757797279424+729=575985757797280128
total=575985757797280128+81=575985757797280192
total=575985757797280192+2=575985757797280192
Case #37: 575985757797280192

As you can see, at some point the addition just works incorrectly (eg 575985757797279424+729 = 575985757797280153 not 575985757797280128) 如您所见,在某些时候加法不能正常工作(例如575985757797279424 + 729 = 575985757797280153而不是575985757797280128)

I'm incredibly dumbfounded by this behavior and would greatly appreciate any possible explanation. 我对这种行为感到非常震惊,非常感谢任何可能的解释。

You've reached the limits of precision for your chosen floating-point type. 您已达到所选浮点类型的精度极限。

If you insist on avoiding integers (ie fixed point), you'll need an arbitrary-precision numerical library to best it. 如果您坚持要避免使用整数(即定点数),则需要使用任意精度的数值库来达到最佳效果。 You should also read The Floating-Point Guide before continuing to use these features. 在继续使用这些功能之前,您还应该阅读《浮点指南》

However, the figures you have here would all fit into a 64-bit integer. 但是,这里的数字都可以放入一个64位整数中。 Why not just use that and save yourself some trouble? 为什么不只使用它并为自己省些麻烦呢?

Double has 3 components sign,exponent,fraction. Double具有3个成分:符号,指数,分数。 For example 1.2345 is represented as 12345*10power-4 例如1.2345表示为12345 * 10power-4

Even though Double has size as long long it has some bits dedicated for exponent part so the precision is less than that of long long which gives float an accuracy of 7 decimal digits and double an accuracy of 16 decimal digits.Since floating point arithmetic are not precise after specified number of digits 尽管Double的大小很长,但它有一些位用于指数部分,因此精度小于long long的精度,这会使float的精度为7个十进制数字,而double的精度为16个十进制数字。在指定位数后精确

Also read 也看了
1. https://chortle.ccsu.edu/java5/Notes/chap11/ch11_2.html 1. https://chortle.ccsu.edu/java5/Notes/chap11/ch11_2.html
2. http://codeforces.com/blog/entry/1521?#comment-28329 (about pow in c++) 2. http://codeforces.com/blog/entry/1521?#comment-28329 (关于C ++中的战俘)

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

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