Chinaunix

标题: awk算数运算的疑问 [打印本页]

作者: murdercool    时间: 2012-11-26 17:42
标题: awk算数运算的疑问
本帖最后由 murdercool 于 2012-11-27 06:58 编辑
  1. awk 'BEGIN{a=(0.9-0.8)*10;print a;if(a==1){print "yes"}else{print "N"}}'
  2. 1
  3. N

  4. awk 'BEGIN{a=(0.9-0.8)*10;print a;if(a<1){print "yes"}else{print "N"}}'
  5. 1
  6. yes
复制代码
这里a是等于1的啊,为什么判断<1 反倒为真呢。。求解释

作者: 代号:军刀    时间: 2012-11-26 17:49
贴在代码框里
作者: jason680    时间: 2012-11-27 06:31
回复 1# murdercool

http://zh.wikipedia.org/zh-cn/IEEE_754
IEEE二进制浮点数算术标准(IEEE 754)是1980年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。...
作者: murdercool    时间: 2012-11-27 09:12
回复 3# jason680


    怎么解决呢
作者: reyleon    时间: 2012-11-27 09:41
  1. awk 'BEGIN{a=(0.9-0.8)*10;print a;if(a=="1"){print "yes"}else{print "N"}}'
复制代码

作者: jason680    时间: 2012-11-27 10:01
本帖最后由 jason680 于 2012-11-27 17:01 编辑

回复 4# murdercool

1. using awk, but don't using float
Note: change some algorithm

$ awk 'BEGIN{n=(0.9-0.8)*10;print n;if(n==1){print "yes"}else{print "No"}}'
1
No


$ awk 'BEGIN{n=0.9*10-0.8*10;print n;if(n==1){print "yes"}else{print "No"}}'
1
yes

2. using awk with error(误差)
Note: using the same algorithm and using some function to check equal

$ awk 'function eq(n,m,err,diff){diff=(n>m)?n-m:m-n;return diff<=err?1:0}BEGIN{n=(0.9-0.8)*10;printf("%.20f\n",n);if(eq(n,1,0.00000000000001)){print "yes"}else{print "No"}}'
0.99999999999999977796
yes


$ awk 'function eq(n,m,err,diff){diff=(n>m)?n-m:m-n;return diff<=err?1:0}BEGIN{n=(0.9-0.8)*10;printf("%.20f\n",n);if(eq(n,1,0.000000000000000001)){print "yes"}else{print "No"}}'
0.99999999999999977796
No

3. using other language(ex: perl) to support it
Note: using the same algorithm

$ perl -e 'use bignum; $n=(0.9-0.8)*10;printf("%.20f\n",$n);if($n==1){print "yes\n"}else{print "No\n"}'
1.00000000000000000000
yes

$ perl -e '$n=(0.9-0.8)*10;printf("%.20f\n",$n);if($n==1){print "yes\n"}else{print "No\n"}'
0.99999999999999977796
No
   
作者: yestreenstars    时间: 2012-11-27 10:12
本帖最后由 yestreenstars 于 2012-11-27 10:12 编辑

回复 6# jason680


学习了,没想到a=(0.9-0.8)*10用printf("%.20f\n",a)打印出来的效果是这样的!
作者: murdercool    时间: 2012-11-27 10:32
回复 6# jason680
   
     谢谢!! 刚试了下
  1. awk 'BEGIN{a=(0.9-0.8)*10;print a;if(a eq 1){print "yes"}else{print "N"}}'
  2. 1
  3. yes
复制代码
貌似有eq内置函数 ,以前还真没看到过
作者: yestreenstars    时间: 2012-11-27 10:35
回复 8# murdercool


    在awk里没有eq这个内置函数,不信你把1换成2、3、4……结果都是yes。
作者: murdercool    时间: 2012-11-27 10:42
回复 9# yestreenstars


   是的,   我2了  :wink:
作者: 油条回锅肉    时间: 2012-11-27 16:47
这个帖子好,又长见识了




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2