C++ 为什么“while(base*10<;=2147447412)”溢出

C++ 为什么“while(base*10<;=2147447412)”溢出,c++,C++,数值限制::max()=>2147483647 int x = 2147447412; int base = 1; while (base * 10 <= x) base *= 10; // this loop will run forever. while ((long long)(base * 10) <= (long long)(x)) base *= 10; // this loop still will run forever while (x -

数值限制::max()=>2147483647

int x = 2147447412;
int base = 1;
while (base * 10 <= x) 
    base *= 10; // this loop will run forever.

while ((long long)(base * 10) <= (long long)(x)) 
    base *= 10; // this loop still will run forever

while (x - base * 10 >= 0 ) 
    base *= 10; // this loop will stop.
intx=2147447412;
int base=1;

虽然(base*10为什么while循环永远运行?溢出?

是的,溢出。一旦
base
达到1e9,
base*10
溢出。因此您有未定义的行为。

base
100000000
base*=10;
完成后,它会显示未定义的行为。在您的情况下,它似乎溢出了变为负值。

在某一点上,
base
的值将是
100000000
,它小于
x
,但乘以
10
溢出,因此
while
循环中的条件永远不会满足。

修复了在进行乘法之前检测溢出内容的代码:

int const kBase = 10;
int const kMax  = numeric_limits<decltype(kBase)>::max() / kBase;

int b = 1;
do {
  b *= kBase;
} while (b <= kMax);
int const kBase=10;
int const kMax=数值限制::max()/kBase;
int b=1;
做{
b*=kBase;

}而(b
base
是一个
int
10
是一个
int
。将它们相乘的结果是一个
int
。为了使循环不会永远运行,您应该检查溢出情况以及条件。(或者)将x设为尽可能长的值type@Rahul,
long
通常仍然是32位。@chris,LOL,我实际上用的是C#(长64位).
通常仍然是32位
无法确定。它应该是固定大小的。对吗?@Rahul,它是编译器制作的任何东西,只要它至少是32位。请注意,这直接来自C。不过,你可以指望每个编译器都会对它进行适当的记录。也许编译器足够聪明,可以用
w替换它希尔(真)
。呃,我检查了Clang和GCC。Clang也没有真正简化,但GCC实际上在这方面做了很多工作:有趣的是,GCC是如何优化代码的。这段代码与原来的代码有不同的含义。@q0987你是对的,上次错过了iteration@AlanStokes是的,之前也意识到了截断,但忽略了修复它我认为t点遗漏的是,在while语句的条件检查中,当
base
=1e9时,
base*10
溢出。@q这正是我写的。对不起,我的意思是我遗漏了要点:)在这种情况下,对不起,我遗漏了你的要点。;-)请看一下我更新的帖子。第三种方法很好用,它表明只有当整个表达式溢出而不是部分溢出时,代码才会溢出。换句话说,
10*base
最终会溢出,但
x-base*10
不会溢出。