【C#食谱】【风味小吃】菜单1: 判断分数和小数之间是否近似相等

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



问题:

你需要比较一个分数和一个doublefloat类型的值,去决定它们是否近似相等。以1/60.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/denominatordblValue)之差的绝对值,并把它和已经确定、并作为参数传递给epsilon的值比较,你可以去定这个小数是否是这个分数的一个合适的近似值。

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


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

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


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

其他参考:

查看MSDN文档中关于Double.Epsilon FieldSingle.Epsilon Field主题的相关内容。
posted @ 2008-01-12 21:27  随风逝去(叶进)  阅读(1910)  评论(3编辑  收藏  举报
Free Web Counter
Free Web Counter