前言
前天在写IDL程序的时候遇到了NAN,虽然实际问题没能解决,但是大概已经有点眉目了。顺便记下遇到NAN,INF这些可能的操作。
NAN是not a number的缩写,在和浮点数比较的时候,它会出现警告,当时做的时候觉得反而是警告更好,NAN处理起来挺麻烦的。
MATLAB处理这些异常值时候挺熟练的,IDL度娘了半天没找到,只能自己读文档了,好在找到了文档。
inf就是无穷,也可以进行处理。
创建这四种变量
a = !VALUES.F_NAN ;NAN
IDL> b = -!VALUES.F_NAN ;-NAN
IDL> c = !VALUES.F_INFINITY ;INF
IDL> d = -!VALUES.F_INFINITY ;-INF
带感叹号的一般都是IDL系统的变量,所以其实这个只要知道应该就够了。比如你想把某个值去掉,那就改成这个值就行了,比如我想去除我VFC原来是背景的部分,那我就赋值。
还是比较清晰的,当然还有创建的方法,就是需要提前创建一个矩阵,比如,
a = [1.0,'inf','nan','-nan','-inf']
b = 1
b = a[1]
b
c = 2
c = a[2]
c
a = ['inf','nan','-nan','-inf']
a
需要注意的是,在创建这四种数的时候一定要和浮点数创建在一个矩阵里面,那么会生成这四种数,然后单独抽出一种数就行,如果不抽出来就只能用之前的方法,而且必须要和浮点数在一个矩阵里,否则会被识别成文字矩阵。看下面:
浮点数造成的问题
如果你不去除NAN或者INF与浮点数进行比较会出现2个问题
- 第一是会出现警告,即Program caused arithmetic error: Floating illegal operand
- 第二,它照样会运行下去,并且会给出比较的结果,比如返回0.
例如
c为NAN,与为1的d比较会出现报错,并且返回值为0,那么在我比如我想去除背景的话很可能会将背景和等于0的部分混在一起,那么我只能到ENVI里用ROI裁剪掩膜赋值了。我觉得这个问题可能是IDL为了严谨,但实际上可能还是成了人们写IDL的一大阻力了。
如何判断是否是NAN或者INF
利用finite函数,句法的话
Result = FINITE( X [, /INFINITY] [, /NAN] [, SIGN=value])
判断某个数字是否是inf或者NAN,后面是可选参数。
a = [1.0,'inf','-inf','nan','-nan']
a
finite(a)
finite(a,/nan,sign=0)
finite(a,/inf,sign=1)
finite(a,/-inf,sign=1) ;错误语法
可以看到,finite是有限的意思,如果true的话返回值是1,如果是false的话返回值是0,即如果一个数是有限的数的话那么返回的是1,不是的话就返回0。这个可以成为找下标的依据。
而如果加入了可选去找NAN的话,并且加入sign的话true返回1,false返回0,同理inf的可选参数。
从nan到数值的赋值或者返回nan
一旦你有临时的变量nan就不需要再用系统变量!VALUES.F_NAN这种形式了,你可以直接用’inf’来赋值,例如下面
a = [1.0,'inf','-inf','nan','-nan']
a
a[1] = 2
a[1] = 'inf'
a
d = 'inf'
d
可以看到其实已经是可以了,即如果在浮点的环境里你可以抽出一个变量,当成一种存储 NAN,INF 的变量,而如果单纯输入 ‘INF’ 的话出来的是一个字符串不会识别成 NAN 或者 INF,所以如果愿意的话可以一开始就存储一个这4个非数的变量,然后单独赋值就可以了。