“无符号长长”太小,无法表示数字
`unsigned long long` too small to represent number?
我一直在试图得到欧拉项目问题 3 的答案,我需要找到600851475143的最大素因数,但我的程序挂在这个数字上,而不是更小的数字(有时是更大的数字)。我删除了该程序寻找素数分解的更一般的目的,希望它能减少计算时间,也许会给我一个答案,但它没有。以前,当程序从 1 而不是输入开始时,它给了我最低的素数 17,但仅此而已。现在它什么也没给我。
对于其他人来说,似乎有效的是增加数据类型的大小并将"ULL"附加到变量的末尾。这对我不起作用。其他人建议创建一个大数字类,但我的知识还不足以做到这一点,或者根本不使用类,真的。这是程序。
#include <iostream>
using namespace std;
bool is_prime(unsigned long long int input);
void factor_number(unsigned long long int input);
int main()
{
unsigned long long int input = 600851475143ULL;
cout << "Hello World!nn";
if (is_prime(input) == false)
factor_number(input);
else
cout << input << 1;
cin.get();
return 0;
}
bool is_prime(unsigned long long int input)
{
for (int i = 1; i <= input; i++)
{
if (i != 1 && i != input)
{
if (input % i == 0)
{
return false;
}
}
else if (i == input)
return true;
}
}
void factor_number(unsigned long long int input)
{
unsigned long long int i = input;
while (input % i != 0 || is_prime(i) == false)
{
i--;
}
cout << i << endl;
}
bool is_prime(unsigned long long int input)
{
for (int i = 1; i <= input; i++)
unsigned long long int
input
可以存储值 [0,2^64)。
int
i
可以存储一个介于 [-(2^31),2^31) 之间的值。
当i
2,147,483,647
并且您递增它时,它变为负数,因此当input
为>= 2^31 时,循环条件i <= input
永远不会为假。如果i
是一个unsigned int
,则值>= 2^32时会出现问题。
#include <iostream>
#include <cstdint>
#include <limits>
int main() {
int i = std::numeric_limits<int>::max();
std::cout << i << "n";
++i;
std::cout << i << "n";
}
现场演示:http://ideone.com/kmeXti
很有可能,当您比较i
和input
时,您的编译器会给您一个警告,但您选择忽略它。
您可以通过以下方式修复代码:
#include <cstdint>
bool is_prime(uint64_t input)
{
for (uint64t_t i = 1; i <= input; ++i) {
---编辑---
您的素数函数也这样做:
for (int i = 1; i <= input; i++)
{
if (i != 1 && i != input)
{
循环内的测试条件可能很昂贵(在本例中,您为循环的每次迭代进行测试)。如果您担心代码的性能,您应该做的第一件事就是尝试消除这些测试。
循环包含i != input
测试 - 因此让我们将其提升到循环条件中:
for (uint64_t i = 1; i < input; i++)
{
...
}
return true;
现在我们不需要测试循环内的i != input
,但我们仍然需要测试讨厌的 1。我们可以在开始时添加一些显式测试:
if (input < 4) {
return (input > 1); // 2 and 3 are prime, 0 and 1 are not
}
但更重要的是,我们可以快速消除所有偶数。如果数字的最低位是"0",则数字为偶数:
if ((input & 1) == 0) // even number
return false;
但是现在我们知道数字不可能是偶数,我们也可以少做除法测试。把所有的东西放在一起:
#include <iostream>
bool is_prime(uint64_t input)
{
if (input < 4)
{
// eliminate 1, 2 and 3.
return (input > 1);
}
// Eliminate even numbers
if ((input & 1) == 0)
return false;
// we've eliminated even numbers, so the smallest
// possible divisor is 3, start from there, but
// we can also skip all even divisors!
for (uint64_t div = 3; div <= input / 3; div += 2)
{
if ((input % div) == 0)
return false;
}
return true;
}
int main()
{
for (uint64_t i = 0; i < 64; ++i)
{
std::cout << i << ": " << (is_prime(i) ? "yes" : "no") << 'n';
}
}
http://ideone.com/aJqApL
- 如何知道n!是否可以表示为三个连续数字的乘法?
- 将数字表示为两个三角形数字的总和
- 如何将uint8_t的二进制表示形式读取为数字
- 算法设计:用边界数字表示 2D 网格的最佳方式,以C++?
- C++显示两个区间之间的数字的程序检查一个数字是否可以表示为两个素数的总和
- 递归地将给定字符串转换为它所表示的数字
- 将两位数字转换为低内存表示的最快方法
- 使用单个数字表示多个变量
- 如何解析小数分离器为结肠的数字的字符串表示:
- 获取所有方式以两个整数的产品表示数字
- 乘以两个表示为链接列表的大数字
- 如何将一个数字(大于8个字节)从字符阵列转换为其ASCII表示
- 如何使用C 将二进制数字的字符串转换为其签名的十进制表示
- 编译C 程序时具有逻辑错误,该程序应将任意大的数字表示为字符串
- 如何在没有循环的二进制数字表示中只计算1位
- C 的数字拟合的错误表示
- 如何使用大值表示C++中未定义的数字
- 用O(1)表示法求一系列数字的平均值——常数时间
- 如何以 2³² 为基数表示数字?
- “无符号长长”太小,无法表示数字