long long int 变量没有输出
No output for long long int variables
这是一个代码片段:
unsigned int m,n,a;
long long int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
while(m>0){
m-=a;
p++;
}
while(n>0){
n-=a;
q++;
}
c=p*q;
printf("%lld",c);
以上代码不适用于任何输入。也就是说,它似乎已经崩溃了,尽管我不明白我错在哪里。我猜 printf 中带有 %lld 的部分有问题。但我不知道如何修复它。我正在使用代码块。
相应输入的一些预期输出如下:
Input: 6 6 4
输出:4
Input: 1000000000 1000000000 1
输出:1000000000000000000(10^18)。
追加:
所以,我给出下面主要问题的link。我的代码逻辑对我来说似乎是正确的。
while(m>0){
m-=a;
p++;
}
将 运行 直到 m
等于 0,因为它不能为负数,因为它是无符号的。所以如果 m
是 4 并且 a
是 6,那么 m
将下溢并得到 m
可以容纳负 2 的最大值。您应该将输入变量更改为有符号.
4386427 显示了如何使用数学来完全删除循环,但对于更一般的情况,您可以这样做:
while(m > a) {
m-=a;
p++;
}
// The above loop will run one iteration less
m-=a;
p++;
当然,你需要为第二个循环做同样的事情。
另一件事,检查 scanf
的 return 值:
if(scanf("%u%u%u",&m,&n,&a) != 3) {
/* Handle error */
}
正如在 comments/answers 中指出的那样,问题是 m
和 n
是无符号的,所以只有在 m
和 [=14= 时你的循环才能停止] 是 a
.
的倍数
如果您查看输入 6 6 4
(即 m=6 和 a=4),您可以看到 m
首先会像 m = 6 - 4
一样变化,从而导致 m
为 2。因此在下一个循环中,m
将像 m = 2 - 4
一样改变,它应该是 -2 但由于 m
是无符号的,它将换行到一个非常高的正数(即 UINT_MAX-1) 并且循环将继续。这不是你想要的。
要修复它,我建议您放弃 while
循环并简单地执行以下操作:
unsigned int m,n,a;
long long unsigned int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
p = (m + a - 1)/a; // Replaces first while
q = (n + a - 1)/a; // Replaces second while
c=p*q;
printf("%lld",c);
此解决方案的一个问题是总和 (m + a - 1)
可能会溢出(即大于 UINT_MAX),因此会给出错误的结果。您可以通过在求和之前添加溢出检查来解决此问题。
另一种防止溢出的方法可能是:
p = 1; // Start with p=1 to handle m <= a
if (m > a)
{
m -= a; // Compensate for the p = 1 and at the same time
// ensure that overflow won't happen in the next line
p += (m + a - 1)/a;
}
此代码可以简化为:
p = 1;
if (m > a)
{
p += (m - 1)/a;
}
使用 unsigned
类型并不总是表示正值的最佳选择,特别是当不需要其模块化行为时(并且可能被遗忘,这会导致 "unexpected" 错误)。 OP 的用例需要一个能够存储最大 109 值的整数类型,该值在 32 位有符号整数的范围内(肯定是 long int
) .
正如 4386427 的回答所示,OP 代码中的 while
循环无论如何都可以(并且应该)避免,除非以某种方式需要 "brute force" 解决方案(这不太可能鉴于问题的来源)。
不过我会使用一个函数:
#include <stdio.h>
// Given 1 <= x, a <= 10^9
long long int min_n_of_tiles_to_pave_an_edge(long int x, long int a)
{
if ( x > a ) {
// Note that the calculation is performed with 'long' values and only after
// the result is casted to 'long long', when it is returned
return 1L + (x - 1L) / a;
}
else {
return 1LL;
}
}
int main(void)
{
// Given a maximum value of 10^9, a 32-bit int would be enough.
// A 'long int' (or 'long') is guaranteed to be capable of containing at
// least the [−2,147,483,647, +2,147,483,647] range.
long int m, n, a;
while ( scanf("%ld%ld%ld", &m, &n, &a) == 3 )
{
// The product of two long ints may be too big to fit inside a long.
// To be sure, performe the multiplication using a 'long long' type.
// Note that the factors are stored in the bigger type, not only the
// result.
long long int c = min_n_of_tiles_to_pave_an_edge(m, a)
* min_n_of_tiles_to_pave_an_edge(n, a);
printf("%lld\n",c);
}
}
这是一个代码片段:
unsigned int m,n,a;
long long int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
while(m>0){
m-=a;
p++;
}
while(n>0){
n-=a;
q++;
}
c=p*q;
printf("%lld",c);
以上代码不适用于任何输入。也就是说,它似乎已经崩溃了,尽管我不明白我错在哪里。我猜 printf 中带有 %lld 的部分有问题。但我不知道如何修复它。我正在使用代码块。
相应输入的一些预期输出如下:
Input: 6 6 4
输出:4
Input: 1000000000 1000000000 1
输出:1000000000000000000(10^18)。
追加:
所以,我给出下面主要问题的link。我的代码逻辑对我来说似乎是正确的。
while(m>0){
m-=a;
p++;
}
将 运行 直到 m
等于 0,因为它不能为负数,因为它是无符号的。所以如果 m
是 4 并且 a
是 6,那么 m
将下溢并得到 m
可以容纳负 2 的最大值。您应该将输入变量更改为有符号.
4386427 显示了如何使用数学来完全删除循环,但对于更一般的情况,您可以这样做:
while(m > a) {
m-=a;
p++;
}
// The above loop will run one iteration less
m-=a;
p++;
当然,你需要为第二个循环做同样的事情。
另一件事,检查 scanf
的 return 值:
if(scanf("%u%u%u",&m,&n,&a) != 3) {
/* Handle error */
}
正如在 comments/answers 中指出的那样,问题是 m
和 n
是无符号的,所以只有在 m
和 [=14= 时你的循环才能停止] 是 a
.
如果您查看输入 6 6 4
(即 m=6 和 a=4),您可以看到 m
首先会像 m = 6 - 4
一样变化,从而导致 m
为 2。因此在下一个循环中,m
将像 m = 2 - 4
一样改变,它应该是 -2 但由于 m
是无符号的,它将换行到一个非常高的正数(即 UINT_MAX-1) 并且循环将继续。这不是你想要的。
要修复它,我建议您放弃 while
循环并简单地执行以下操作:
unsigned int m,n,a;
long long unsigned int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
p = (m + a - 1)/a; // Replaces first while
q = (n + a - 1)/a; // Replaces second while
c=p*q;
printf("%lld",c);
此解决方案的一个问题是总和 (m + a - 1)
可能会溢出(即大于 UINT_MAX),因此会给出错误的结果。您可以通过在求和之前添加溢出检查来解决此问题。
另一种防止溢出的方法可能是:
p = 1; // Start with p=1 to handle m <= a
if (m > a)
{
m -= a; // Compensate for the p = 1 and at the same time
// ensure that overflow won't happen in the next line
p += (m + a - 1)/a;
}
此代码可以简化为:
p = 1;
if (m > a)
{
p += (m - 1)/a;
}
使用 unsigned
类型并不总是表示正值的最佳选择,特别是当不需要其模块化行为时(并且可能被遗忘,这会导致 "unexpected" 错误)。 OP 的用例需要一个能够存储最大 109 值的整数类型,该值在 32 位有符号整数的范围内(肯定是 long int
) .
正如 4386427 的回答所示,OP 代码中的 while
循环无论如何都可以(并且应该)避免,除非以某种方式需要 "brute force" 解决方案(这不太可能鉴于问题的来源)。
不过我会使用一个函数:
#include <stdio.h>
// Given 1 <= x, a <= 10^9
long long int min_n_of_tiles_to_pave_an_edge(long int x, long int a)
{
if ( x > a ) {
// Note that the calculation is performed with 'long' values and only after
// the result is casted to 'long long', when it is returned
return 1L + (x - 1L) / a;
}
else {
return 1LL;
}
}
int main(void)
{
// Given a maximum value of 10^9, a 32-bit int would be enough.
// A 'long int' (or 'long') is guaranteed to be capable of containing at
// least the [−2,147,483,647, +2,147,483,647] range.
long int m, n, a;
while ( scanf("%ld%ld%ld", &m, &n, &a) == 3 )
{
// The product of two long ints may be too big to fit inside a long.
// To be sure, performe the multiplication using a 'long long' type.
// Note that the factors are stored in the bigger type, not only the
// result.
long long int c = min_n_of_tiles_to_pave_an_edge(m, a)
* min_n_of_tiles_to_pave_an_edge(n, a);
printf("%lld\n",c);
}
}