求教一个关于C语言数据溢出的检验程序有关问题和setjmp函数,有代码
求教一个关于C语言数据溢出的检验程序问题和setjmp函数,有代码
最近在做毕设,课题是解决编译器对于数据溢出不报错的问题的解决办法,也就是说要设计一个算法或者流程,当在运算中(打比方,两个向量的相加相减和内积的运算)出现数据溢出的时候,程序能检测出来,然后提示并报错。
我根据课内的目标写了一小段代码,用到了C语言的跳转,setjmp()和longjmp(),可是遇到了一些小小的问题,特来请教有经验的前辈。
我用的是short类型,范围是-326767到32767,然后运行实例如下

当两个向量相加时,32767+1结果时-32767,得到的P3点的响应值跟真正的32768不对应,会进入longjmp的跳转部分,但是跳转完之后我那个the result is overflow那个输出就进入无限循环了,也就是不停的输出,想请教是什么原因。 还有就是关于数据溢出的检测,我这么做有没有问题?涉及到向量的内积,也就是两点相乘的时候出现溢出,要如何检测?十分感谢。
------解决方案--------------------
太谢谢你了,例子十分清楚,容我追加一个问题,就是乘法的溢出,代码中我没有处理乘法部分是因为我还没弄明白如何处理他们?你有好的建议吗?尤其是对于带符号的向量,内积中可能会有一部分的乘法结果溢出,但是有负值的话,最后求得的内积的和还是有可能在范围内,导致加减法溢出的检验方法不适用。
===============
一样啊。用一个更大的类型,比如int, 如果计算的结果超出了short的范围,则溢出。代码几乎一模一样,两overflow函数都是重用的。
最近在做毕设,课题是解决编译器对于数据溢出不报错的问题的解决办法,也就是说要设计一个算法或者流程,当在运算中(打比方,两个向量的相加相减和内积的运算)出现数据溢出的时候,程序能检测出来,然后提示并报错。
我根据课内的目标写了一小段代码,用到了C语言的跳转,setjmp()和longjmp(),可是遇到了一些小小的问题,特来请教有经验的前辈。
//
// main.c
// Bachelorarbeit
//
// Created by Nan on 1/1/14.
// Copyright (c) 2014 Nan. All rights reserved.
//
#include <stdio.h>
#include <setjmp.h>
jmp_buf jump_buffer;
typedef struct Vektor{
short int x,y,z;
}Point,*pPoint;
void Input(pPoint p)
{
printf("please enter the value of x :");
scanf("%hd",&(p->x));
printf("please enter the value of y :");
scanf("%hd",&(p->y));
printf("please enter the value of z :");
scanf("%hd",&(p->z));
}
//Skalarprodukt
double Inner(Point p1,Point p2)
{
return p1.x*p2.x+p1.y*p2.y+p1.z*p2.z;
}
//Addition
void Add(Point p1,Point p2,Point *p3)
{
p3->x=p1.x+p2.x;
p3->y=p1.y+p2.y;
p3->z=p1.z+p2.z;
}
//Subtraktion
void Subtra(Point p1,Point p2,Point *p4)
{
p4->x=p1.x-p2.x;
p4->y=p1.y-p2.y;
p4->z=p1.z-p2.z;
}
void show_point(Point p)
{
printf("(%.3d,%.3d,%.3d)", p.x, p.y, p.z);
}
int main()
{
Point p1, p2, p3,p4;
if (setjmp(jump_buffer)==0) {
printf("\n*******input p1*******\n"), Input(&p1);
printf("\n*******input p2*******\n"), Input(&p2);
Add(p1, p2, &p3);
Subtra(p1, p2, &p4);
if(p3.x!=(p1.x+p2.x)){
longjmp(jump_buffer, 1);
}
puts("\n=======result=======");
printf("\ninner: %.3lf", Inner(p1, p2));
printf("\nadd:"), show_point(p3);
printf("\nmin:"), show_point(p4);
}
else{
printf("\n*******the result is overflow,pleas check your input and enter the value again*******\n");
}
while(getchar()!='\n');
puts("\npress enter to exit.\n");
getchar();
return 0;
}
我用的是short类型,范围是-326767到32767,然后运行实例如下
当两个向量相加时,32767+1结果时-32767,得到的P3点的响应值跟真正的32768不对应,会进入longjmp的跳转部分,但是跳转完之后我那个the result is overflow那个输出就进入无限循环了,也就是不停的输出,想请教是什么原因。 还有就是关于数据溢出的检测,我这么做有没有问题?涉及到向量的内积,也就是两点相乘的时候出现溢出,要如何检测?十分感谢。
------解决方案--------------------
太谢谢你了,例子十分清楚,容我追加一个问题,就是乘法的溢出,代码中我没有处理乘法部分是因为我还没弄明白如何处理他们?你有好的建议吗?尤其是对于带符号的向量,内积中可能会有一部分的乘法结果溢出,但是有负值的话,最后求得的内积的和还是有可能在范围内,导致加减法溢出的检验方法不适用。
===============
一样啊。用一个更大的类型,比如int, 如果计算的结果超出了short的范围,则溢出。代码几乎一模一样,两overflow函数都是重用的。
void Multiply(Point p1, Point p2, Point* rslt)
{
int x=(int)p1.x*p2.x;
int y=(int)p1.y*p2.y;
int z=(int)p1.z*p2.z;
if(overflow(x)
------解决方案--------------------
overflow(y)
------解决方案--------------------
overflow(z))
longjmp(jump_buffer, 3); // suppose we decide to differentiate MULTIPLY overflow