c语言判断溢出
㈠ 在c语言中怎样判断一个程序运算结果是否溢出,举个例子,你用C语言编写程序求n!,判断n为几时n!溢出
#include<stdio.h>
unsignedf(unsigned*n){
unsignedi=2,res=1,lres=1;
while(1){
lres*=i;
if(lres<res){
*n=i-1;
returnres;//溢出后,阶乘的结果会变小。
}
res=lres;
i++;
}
returni;//本行是不会执行的,这是为了函数需要返回值而设的。
}
intmain(){
unsignedn;
printf("%u!=%u ",n,f(&n));
return0;
}
㈡ C语言中怎么样判断溢出
判断边界:void outstr(int a[10])
{ for(i=0;a[i]!=0&&i<10;i++) {
printf("%d\n",a[i]);
}}当i=10时,判断i<10同时需要判断a[i]!=0,此时a[10]已经访问到非法区域,可能引起缓冲区溢出问题。防止方法:将判断条件分成几条语句例:if(i<10){ if(a[i]!=0) {
... }}
</SPAN>
㈢ C语言溢出问题。
以C中同一类型运算,结果仍然是这个类型,由于a与1都是int,所以A+1结果仍然是int,此时就发生了溢出,赋值到B中也是溢出后的值。而当一个int与一个long运算时,结果的类型是long,1L后面的L就是long类型的意思,所以a+1L是int与long运算,得到的也是long,然后赋值到b,所以是正确结果
㈣ C语言中怎么处理溢出
C
中调用积运算符之后做溢出检测已经太晚,但调用和运算符之后做检测则一点也不迟,
所以你可以通过对和运算结果的检测实现能检测溢出的积运算,因为
a
*
b
既是
a
个
b
的和:
-5000000
*
1374389539
等于
-(5000000
*
1374389539)。括号里是
5000000
个
1374389539
的和。
我把能检测溢出的和运算包在
add(
)
里,然后在
multiply(
)
里重复调用
add(
)。
add(
)
怎么检测溢出?
和运算的结果若溢出将导致数值的环绕。上溢导致往下环绕,下溢导致往上环绕。
边界状况:
(1)最轻微的上溢是
INT_MAX
+
1
:结果是
INT_MIN。
(2)最严重的上溢是
INT_MAX
+
INT_MAX
:结果是
-2。
(3)最轻微的下溢是
INT_MIN
-
1
:结果是
INT_MAX。
(4)最严重的下溢是
INT_MIN
-
INT_MIN
:结果是
0。
结论:
(1)所有上溢结果都小于任何一个操作数。
(2)所有下溢结果都大于任何一个操作数。
所以
add(
)
可以用结果和任意选定的一个参数判断溢出,并以落选的参数判断溢出的方向。
add(
)
无法以返回值举报溢出,所以采用
strtol(
)
的举报方法。
不同于
strtol(
)
的是,若没有溢出,add(
)
会把
0
赋值给
errno。
multiply(
)
在这方面跟
add(
)
一样。
#include<stdio.h>
#include<errno.h>
/*
errno,
ERANGE
*/
/*
*
Returns
the
sum
of
a
and
b,
with
overflow
and
underflow
check.
*
If
overflow
or
underflow
occurred,
sets
errno
to
ERANGE,
else
to
0.
*/
int
add(
int
a,
int
b
)
{
int
result
=
a
+
b;
if(
b
>
0
&&
result
>
a
||
b
<=
0
&&
result
<=
a
)
errno
=
0;
else
errno
=
ERANGE;
return
result;
}
/*
*
Returns
the
proct
of
a
and
b
obtained
through
repeated
call
of
add(
).
*
Affects
errno
exactly
as
add(
)
does.
*/
int
multiply(
int
a,
int
b
)
{
int
sign_of_a
=
1,
result
=
0,
i
=
0;
/*
Keep
the
sign
of
multiplier
off
the
loop
sentinel.
*/
if(
a
<
0
)
{
sign_of_a
=
-1;
a
*=
-1;
}
/*
Have
to
reset
errno
here
because
it
won't
be
updated
if
a
is
0.
*/
errno
=
0;
while(
i++
<
a
)
{
result
=
add(
result,
b
);
if(
errno
==
ERANGE
)
break;
}
return
result
*
sign_of_a;
}
int
main(
)
{
int
result;
/*
Operands
too
huge:
sure
overflow.
*/
result
=
multiply(
-5000000,
1374389539
);
if(
errno
==
ERANGE
)
perror(
"Uh
oh"
);
else
printf(
"%d\n",
result
);
/*
Small
operands:
safe.
*/
result
=
multiply(
49,
-972
);
if(
errno
==
ERANGE
)
perror(
"Uh
oh"
);
else
printf(
"%d\n",
result
);
}
当然,应付溢出的最佳方法还是防范:充分了解数据的范围,选择恰当的变量类型。
也许你正考虑改用不需要你担心整数类型溢出的语言。考虑过
Python
吗?
㈤ C语言溢出判断问题
#include<inttypes.h>
#include<stdio.h>
int main()
{
int t;
uint64_t a, b;
scanf("%d", &t);
for(int i=0; i<t; i++)
{
scanf("%" SCNu64 "%" SCNu64, &a, &b);
printf("%d\n", a+b<a);
}
return 0;
}
㈥ C语言数据溢出问题
在C语言中,数据的存储就像一个圆圈,正数溢出数据就会从最小负数开始,负数溢出数据同理,打个比方(简略写一下):
int
a=32768,b=-32769;
printf("a=%d,b=%d",&a,&b);
则会输出a=-32768,b=32767;
这样则50000输出就是(50000-32767)+(-32768)+(-1)=-15536
㈦ c语言溢出判断
#include<stdio.h>
intmain()
{unsignedinta=0,c,n,c1,i;
scanf("%u",&n);
c=1;
for(i=1;i<=n;i++)
{c*=i;
if(c<c1)
{printf("unsignedint最大可以计算%u以内的阶乘。
%u!=%u
s(%u)=%u",i-1,i-1,c1,i-1,a);
break;
}
a+=i;
c1=c;
}
return0;
}
㈧ c语言 判断两数相乘是否溢出
当要发生类型转换时,如果是像更高精度的类型转换,编译器会进行隐式的转换,也就是说,你用64位的X去和32位的Y相乘,编译器就会隐式的把Y转换成64位的,因为精度更高,并不会发生数据丢失,所以不会有任何错误报告
㈨ C语言中如何判断数据类型溢出
一般在工作中会根据实际情况考虑使用合适的数据类型。比如你要存储一个省的人数,你就不能去选择char型,而应该选择int或者能存储更大数据的类型。
所以通常是通过选择合适数据类型来避免溢出。
如果非得判断数据是否溢出,我给你一个方法。通过将其扩大到一个大的数据类型然后进行数据溢出判断。
eg:
char a = X; //X是随机数据
int b = a * Y; //Y是随机数据
if( b < -128 || b > 127) 对于a这种char类型来说则溢出。
㈩ C语言溢出判断
这个是用VC6写的控制台程序中从2147483644开始累加的数列,可以看出溢出的时候没有任何错误提示:
2147483644
2147483645
2147483646
2147483647
-2147483648
-2147483647
-2147483646
-2147483645
-2147483644
-2147483643
-2147483642
这个是我写的可以判断溢出的加法函数:
#include <stdio.h>
int uoadd (int a,int b,int *overflow);
int overflow;
int main ()
{
int a=2147483647-9,b=10,c=0;
c=uoadd(a,b,&overflow);
if (overflow == 1)
printf ("溢出!\n");
else
printf ("%d\n",c);
return (0);
}
int uoadd (int a,int b,int *overflow)
{
*overflow=0;
if (a>0 && b>0 && a+b<0) *overflow=1;
if (a<0 && b<0 && a+b>0) *overflow=1;
return (a+b);
}
VC6编译,新建工程的时候选控制台程序
其实其他的应用程序可能会内置判断溢出的东西,比如VB就会判断,如果数据溢出了就会弹出一个对话框,其他的就不知道了
其实这个东西用汇编解决相当容易了,但考虑到可读性还是用C比较好