默认头像
捉鬼专家
捉鬼专家
  • 注册日期2004-08-13
  • 发帖数552
  • QQ
  • 铜币2462枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:2146回复:0

判断分数和小数之间是否近似相等

楼主#
更多 发布于:2008-01-19 23:57

说明:在看C# CookBook,英文版的,一方面是想自己边看边能够更好的理解,另一方面是想借翻译,也提高下自己的英语水平。  以后想基本上每两天翻译一篇。
至于,适不适合放在首页,我也不是很清楚,如果不合适,还请见谅。  dudu留情:我只是想先测试下,这个系列应不应该在首页出现。

问题:

你需要比较一个分数和一个double或float类型的值,去决定它们是否近似相等。以1/6和0.16666667比较的结果为例。除了0.16666667只精确到小数点后8位,而1/6在小数点后精确到该类型小数最大可能的长度之外,它们看上去是相等的。

解决方法:

要在分数和小数之间比较它们是否近似相等,需要确定它们之间的差是否在允许的范围内:


using System;
      // 用System.Double.Epsilon的值重载函数

       public static bool IsApproximatelyEqualTo(double numerator,
                                                 double denominator,
                                                 double dblValue)
       {
           return IsApproximatelyEqualTo(numerator,
                denominator, dblValue, double.Epsilon);
       }
       // 重载函数,使得可以自己确定一个误差值,而不是用
         // System.Double.Epsilon
       public static bool IsApproximatelyEqualTo(double numerator,
                                                 double denominator,
                                                 double dblValue,
                                                 double epsilon)
       {
           double difference = (numerator/denominator) - dblValue;
           if (Math.Abs(difference) < epsilon)
           {
               // 近似相等
               return true;
           }
           else
           {
               // 不是近似相等
               return false;
           }
       }

通过float替代double类型,允许你可以在分数和float之间比较它们是否近似相等。

讨论:

分数可以被表示为分子除以分母;但是,把它们保存为小数还是有必要的。把分数作为小数保存,引入了舍入错误,使得他比较难以实现比较。用分数来表示一个值(比如1/6)能够使得它最大程度的精确。用小数来表示一个值(比如0.16666667)能够限制一个值的精度。在这里,这个精度依赖于开发者决定使用的小数点右边数字的个数。

你也许需要一种方法去确定两个值之间是否近似相等的。这个比较是通过定义一个值(epsilon)——代表两数之间的差值的最小的正数——来确定的。换句话说,通过确定两数(numberator/denominator和dblValue)之差的绝对值,并把它和已经确定、并作为参数传递给epsilon的值比较,你可以去定这个小数是否是这个分数的一个合适的近似值。

考虑1/7和0.14285714285714285之间的比较。下面的调用IsApproximatelyEqualTo方法指出该小数没有足够的小数点后的位数去成为一个合适的近似值(他有六位,但是七位是必需的):


bool Approximate = Class1.IsApproximatelyEqualTo(1, 7, .142857, .0000001);
       // Approximate == false

为第三个参数增加一个小数位后,这个函数反映出这个更精确的值就是你需要的1/7的合适的近似值:


bool Approximate = Class1.IsApproximatelyEqualTo(1, 7, .1428571, .0000001);
        // Approximate == true

其他参考:

查看MSDN文档中关于Double.Epsilon Field和Single.Epsilon Field主题的相关内容。

喜欢0 评分0
A friend is never known till a man has need. ...CL
默认头像

返回顶部