为什么我的返回值为-1(0xFFFFFFFF)?

时间:2017-12-01 01:54:07

标签: c

我最近开始学习c,这是我的第一种编码语言。我正在尝试解决Project Euler中的问题3,并且我写了这样做。此代码旨在确定最大的素数因子600851475143, 但相反,我得到了一个我不明白的奇怪的回报价值。谁知道为什么?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i = 1, a = 0, prime = 0;
    for(i = 1; i < 600851475143; i += 2) {
        for(a = 0; a <= i / 2; a++) {
            if(i % a == 0) {
                break;
            }
            if(a = i / 2) {
                if(600851475143 % i == 0) {
                    prime = i;
                }
            }
        }
    }
    printf("%d\n", prime );
    return 0;
}

2 个答案:

答案 0 :(得分:3)

除以0(或尝试for(a = 0; a <= i / 2; a++) { // v---- a is zero! if(i % a == 0) { )。这是未定义的行为(UB)并且可以解释-1的返回。使用UB - 任何都可能发生。  在修复之前,其余代码并不重要。

// for(a = 0; a <= i / 2; a++) {
for(a = 2; a <= i / 2; a++) {

代码可能应该从2开始。

i / 2

不是以 v-------------------v Same a <= sqrt(600851475143) without FP or overflow for(a = 2; a <= 600851475143 / a; a++) { 结束,而是以√600851475143结束,而是很多

if(a = i / 2)

其他问题也存在。 int@Tom Karzes

i < 600851475143可能在600851475143范围内,因此warning: comparison is always true due to limited range of data type [-Wtype-limits] 始终为真。常见的编译器警告将发出此警告。务必完全启用警告以节省时间。 @iBug

int main(void) {
  wide_enough_type n = 600851475143;
  wide_enough_type factor = 1;
  try each i starting at 2 and until  i*i <= n
    repeat as long as n divides into i with no remainder
      make n smaller by diving it by i
      save i as factor
  save the larger of (n, factor) as factor
  printf("Greatest factor: %some_type_specifier\n", factor);
}

伪代码解决方案

{{1}}

答案 1 :(得分:1)

您的问题称为溢出。由于可用内存有限,所有数据类型的范围都有限。平均现代计算机上的int通常高达2,147,483,647(警告:我通常说) - 实际上事情有点复杂。无论如何,你的上限超过了这个。

int(或有符号整数数据类型)溢出时,由于某些与表示相关的问题,它会变为负数。有关原因的更多详细信息,请查看两个补码表示

要修复它,请使用范围更广的数据类型。 long long上升到9,223,372,036,854,775,807,这似乎适合您的需要。

请注意,整数文字也需要标记为long long,否则它们也会溢出:

for(i = 1; i < 600851475143LL; i += 2)

如果你需要的整数值大于long long所支持的范围(虽然现在看起来并非如此),你运气不好:你需要找一些聪明的人处理它的方法。

要查找的其他内容是,当我运行代码时,我得到除以0.我不知道这是否与溢出有关。