C++不正确的算术结果

C++ incorrect arithmetic results

本文关键字:结果 不正确 C++      更新时间:2023-10-16

我正在使用Visual Studios Express for Desktop编写一个程序。 程序给我带来麻烦的部分是取一个十六进制值,它是 2^32 的分数并将其转换为整数值,并使用以下编程对其执行一些简单的数学运算(乘法和除法(。

    if (ch == 'z')
    {
        std::string r, d;
        unsigned int ra;
        unsigned int dec, n = 1;
        r = readline;
        while (n < 9)
        {
            r = r + buffer[0];
            n++;
            ReadFile(file, buffer, sizeof(buffer), &read, NULL);
        }
        ReadFile(file, buffer, sizeof(buffer), &read, NULL);
        n++;
        while (n > 9 && buffer[0] != '#')
        {
            d = d + buffer[0];
            n++;
            ReadFile(file, buffer, sizeof(buffer), &read, NULL);
        }
        std::cout << "n hex RA=" << r << " Hex Dec=" << d << "n";

        std::stringstream ss,dd;
        ss << std::hex << r;
        ss >> ra;
        dd << std::hex << d;
        dd >> dec;
        std::cout << "n ra=" << ra << " dec=" << dec << "n";
        double RA = (ra * 86400);
        double DEC = (dec * 1296000);
        std::cout << "n RA=" << RA << " DEC=" << DEC << "n";
        double rRA = (RA / pow(2,32));
        double dDEC = (DEC / pow(2,32));
        std::cout << "n RA=" << rRA << " DEC=" << dDEC << "n";
    }

我得到以下输出:

 hex RA=1180C1E00 Hex Dec=0EA8A900
 ra=3435973836 dec=245934336
 RA=4294898176 DEC=1376419840
 RA2=0.999984 DEC2=0.320473
正确的值

应该是:(*在不正确的值旁边(

 hex RA=1180c1e00  HEX Dec=0ea8a900
 *ra=4698414592    dec=245934336
 *RA=40594302074880   *DEC=318730899456000
 *RA2=94515.9748...   *DEC2=74210.3204727...

我认为使用 long int 可能会解决问题,但它给出了相同的结果。 我还尝试对给出同样奇怪的结果的值使用双精度类型。 如果您还可以解释为什么一个十六进制转换有效而另一个无效,我将不胜感激。 我是C++新手,并意识到在浏览C++的许多教程时,我可能会错过一些东西。 (注意dec表示赤纬,而不是十进制,与代码无关(。

显然,您正在一个unsigned int 32 位大的平台上工作。 0x1180C1E00不适合 32 位。 ss >> ra尝试分析此字符串时遇到溢出,并失败。 ra仍未初始化;对其执行的任何进一步操作都表现出未定义的行为。

另外,更改

double DEC = (dec * 1296000);

double DEC = (dec * 1296000.0);

如前所述,您对两个整数执行算术运算,然后将结果转换为双精度。但是结果不适合unsigned int,并且在转换之前被包裹在模2^32周围。我建议的更改将dec转换为双精度,然后在浮点中执行乘法。


使用 MSVC,unsigned longunsigned int 一样大 32 位。到处使用unsigned long long应该会有所帮助 - 它有 64 位大。

 hex RA=1180C1E00 Hex Dec=0EA8A900

如果您可以将该值作为字符串,则下面的程序可以根据需要工作。

 unsigned long long int ra,dec;
stringstream ss,dd;
ss << hex << "1180C1E00";
ss >> ra;
dd << hex << "0EA8A900";
dd >> dec;
cout << "n ra=" << ra << " dec=" << dec << "n";
unsigned long long int RA = (ra * 86400);
unsigned long long int DEC = (dec * 1296000);
cout << "n RA=" << RA << " DEC=" << DEC << "n";
double rRA = RA/(pow(2.0,32));
double dDEC = DEC/(pow(2.0,32));
cout << "n RA2=" << rRA << " DEC2=" << dDEC << "n";
return 0;

我希望这能有所帮助。