iOS Nan or +inf
2018-11-30 本文已影响139人
coderPoo
崩溃日志
Invalid number value (NaN) in JSON write-[NSDictionary(JSON)GZ_ toJsonString]
对NaN进行了json转换导致崩溃
什么是NaN 和 +inf
nan: not a number 不是数字
inf: infinity 无穷
inf一般是因为得到的数值,超出浮点数的表示范围(溢出,即阶码部分超过其能表示的最大值);而nan一般是因为对浮点数进行了未定义的操作,如对-1开方
导致项目中崩溃的代码
CMTime time = CMTimeMake(10, 0);
CGFloat videoLength = round(time.value*1.0/time.timescale);
10和0是后台传回数据,导致算出的videoLength = NaN
OC 什么时候会产生这两种情况
- num/0 分母是零
- 对负数开平方
- 数学函数不正确运算
1/0可能出现的值
int i1 = 1/0;
NSInteger n1 = 1/0;
CGFloat cf1 = 1/0;
double d1 = 1/0;
float f1 = 1/0;
结果全部是0
各种类型 变量/0 或者变量/0.0
int ia = 1;
NSInteger na = 1;
CGFloat cfa = 1.0;
double da = 1.0;
float fa = 1.0;
int ria = ia/0; //-374309760
NSInteger rna = na/0; //0
CGFloat rcfa = cfa/0; //+inf
double rda = da/0; //+inf
float rfa = fa/0; //+inf
rcfa = cfa/0.0; //+inf
rda = da/0.0; //+inf
rfa = fa/0.0; //+inf
int ria1 = ia/0; //0
int rna1 = na/0; //32671
int rcfa1 = cfa/0; //-2147483648
int rda1 = da/0; //-2147483648
int rfa1 = fa/0; //-2147483648
变量/变量 第二个变量是0或者0.0
int ia = 1;
NSInteger na = 1;
CGFloat cfa = 1.0;
double da = 1.0;
float fa = 1.0;
int zi = 0;
double zd = 0.0;
int ria2 = ia/zi; //crash: Thread 1: EXC_ARITHMETIC (code=EXC_I386_DIV, subcode=0x0)
NSInteger rna2 = na/zi; //crash: Thread 1: EXC_ARITHMETIC (code=EXC_I386_DIV, subcode=0x0)
CGFloat rcfa2 = cfa/zi; //+inf
double rda2 = da/zi; //+inf
float rfa2 = fa/zi; //+inf
int ria3 = ia/zd; //-2147483648
NSInteger rna3 = na/zd; //-9223372036854775808
CGFloat rcfa3= cfa/zd; //+inf
double rda3 = da/zd; //+inf
float rfa3 = fa/zd; //+inf
// NSData *json1 = [NSJSONSerialization dataWithJSONObject:@{@"key":@(inf)} options:NSJSONWritingPrettyPrinted error:nil];
产生 NaN的情况
CMTime time = CMTimeMake(10, 0);
CGFloat videoLength = round(time.value*1.0/time.timescale);
结论
浮点数类型除以0 产生 +inf ,对这个值@{@“key”:@(+inf)} 进行json处理也会导致崩溃。
变量 /变量(0)会崩溃 crash: Thread 1: EXC_ARITHMETIC (code=EXC_I386_DIV, subcode=0x0)
变量 /变量(0.0)不崩溃,会产生随机数。
NaN或者+inf并不会直接导致崩溃,但是在后期运算中可能导致崩溃
解决办法
-
数学计算时,对分母进行判断 是否为0
-
判断数据
if (isnan(a)) {
NSLog(@"NaN");
}
if (isinf(b)) {
NSLog(@"+inf");
}