【问题标题】:C++ give me strange resultC++ 给了我奇怪的结果
【发布时间】:2021-07-14 10:43:19
【问题描述】:

我在运行以下 C++ 代码时得到了一个非常奇怪的结果:

#include <iostream>

using namespace std;

int main()
{
    int c[]={49,46,48,46,51};
    int p=0;
    for(int i=0;i<5;i++)
         p =p*100+c[i];

    cout << "Hello World! p=" <<p<< endl;
    return 0;
}

世界你好! p=651517355

但是,预期的结果是 4946484651。

即使我将数据类型更改为长整数,也会给出同样的错误结果。

我的环境是,

windows 10, Qt Creator 4.14.1 (Qt 5.15.2 MSVC2019 64bit)
cl -c -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -EHsc /Fddebug\aa.vc.pdb -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DQT_QML_DEBUG -I..\aa -I. -I..\..\..\Qt\5.14.0\msvc2017\mkspecs\win32-msvc -Fodebug\ @C:\Users\guest\AppData\Local\Temp\main.obj.20080.15.jom
main.cpp

【问题讨论】:

  • 4296596394 对于典型的 32 位整数来说太多了,你会得到一个整数溢出。 long long p 可能会做你想做的事(它的范围大约是 10^18)
  • 不确定时可以通过std::numeric_limits&lt;T&gt;::max()查看范围。

标签: c++ windows-10 integer visual-studio-2019


【解决方案1】:

在许多平台(包括你的平台)上,intlong int 都是 32 位整数,不能保存值 4946484651。 (标准只要求long int 不短于 int 并且至少 32 位宽。)

您需要将long long int 用于p,或者最好使用显式的int64_t 类型:

#include <iostream>
#include <cstdint>

int main()
{
    int c[] = { 49,46,48,46,51 };
    int64_t p = 0;
    for (int i = 0; i < 5; i++)
        p = p * 100 + c[i];

    std::cout << "Hello World! p=" << p << std::endl;
    return 0;
}

输出:

Hello World! p=4946484651

【讨论】:

  • 实现支持int64_t不是强制性的。从 C++11 开始,必须支持 long long。 (在 C++11 之前,两者都不是必需的,尽管一些实现支持其中一种或另一种作为非标准扩展)。
  • @Peter 我不确定是哪个(如果有)标准引入了它,但long long int 现在强制至少是 64 位吗?我正在浏览各种草稿……貌似是 C++11。
  • 所以,也许使用long long intint64_t 更“安全”。不过,这似乎违反直觉。奇怪的是,this cppreference page 暗示 int64_t可选的,但 int_least64_t 不是!
  • 反直觉与否,long long int 是必需的,int64_t 是可选的(包括int64_t 在内的几种固定宽度类型仅在实现直接支持该类型时才需要 - 该措辞留给实现)。 long long 类型和固定宽度类型都是在 C++11 中引入的。
  • 为了正确起见,我认为最好明确#include &lt;cstdint&gt;(而不是依赖std::int64_t可能通过间接拉入的事实)。
【解决方案2】:
#include <iostream>

using namespace std;

int main()
{
    int c[] = { 49,46,48,46,51 };
    int64_t p = 0;
    for (int i = 0; i < 5; i++)
        p = p * 100 + c[i];

    cout << "Hello World! p=" << p << endl;
    return 0;
}

因为您在 p 中保留相同的大(大于 2^32)数字,所以它会溢出。

【讨论】:

    猜你喜欢
    • 2020-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 2013-05-29
    • 2016-12-13
    • 2018-03-13
    相关资源
    最近更新 更多