2014-06-30 65 views
0

我正在学习从“用C#计算机程序设计基础”用C#Svetlin Nakov等(可免费在这里:http://www.introprogramming.info/english-intro-csharp-book/如何获得Float的长度? (C#)

每章后,作者想问超越的问题本章的范围。第135页,问题3要求我编写一个程序,可以正确比较两个实数,精度为0.000001(7位有效数字)。

所以我使用浮点数来比较数字,我决定添加一些代码来检查输入的数字是否比浮点数可以处理的7位有效数字更长。所以我需要检查有效位数。谷歌告诉我,我应该使用sizeof(float)来做到这一点,但我一直在sizeof检查的行上发现CS0246错误(无法找到类型或名称空间)。

该程序的工作原理是,包括检查数字长度的代码。我找不到C#的答案。

有什么问题?

编辑:感谢所有的答案。让我澄清我的问题:我明白解析为字符串自动浮动检查有效性。不过,我昨天尝试了我的程序,花车将失去超过7位有效数字。所以如果我比较0.123457和0.12345678,程序会声明这两个数字是相同的,因为第二个数字是四舍五入的。这就是为什么我试图捕捉超过7位数字的花车。我用这种方式解释这个问题,因为它发生在我身上,这两个非常相似但不相同的数字在这些裂缝中滑过。

using System; 

// Compare two real numbers with up to 0.000001 (7) significant digits 
class Compare_Numbers 
{ 
static void Main(string[] args) 
{ 
    // Processing the first number 
    String firstNumString = null; 
    Console.WriteLine("This program compares 2 numbers with upto 7 significant digits.\nEnter the FIRST number with up to 7 significant digits"); 
    firstNumString = Console.ReadLine(); 
    float firstNum = Single.Parse(firstNumString); 

    if (sizeof(firstNum) > 7) 
    { 
     Console.WriteLine("That number is too long!\nEnter a number with a MAX of 7 significant digits!"); 
    } 

    // Processing the second number 
    String secondNumString = null; 
    Console.WriteLine("Enter the SECOND number with up to 7 significant digits"); 
    secondNumString = Console.ReadLine(); 
    float secondNum = Single.Parse(secondNumString); 

    if (sizeof(secondNum) > 7) 
    { 
     Console.WriteLine("That number is too long!\nEnter a number with a MAX of 7 significant digits!"); 
    } 

    if (firstNum == secondNum) 
    { 
     Console.WriteLine("The two numbers are the SAME!"); 
    } 
    else 
    { 
     Console.WriteLine("The two numbers are DIFFERENT!"); 
    } 
} 

}

+0

'sizeof'不符合你的想法。请参阅:http://msdn.microsoft.com/en-us/library/eahchzkf.aspx –

+3

'sizeof(float)'会给你一个'float'存储的字节数,而不是有效数字的数目。在解析和计数数字之前,您只需要查看字符串即可。 – Enigmativity

回答

2

“?如何获得一个浮动的长度”

总之,假设7显著位数:

firstNum.ToString("G7").Length // 7 significant digits 

例。

float pi = 3.14159265f; 
    string g5 = a.ToString("G5"); 
    string g7 = a.ToString("G7"); 

但是,您的标题要求简单一些,但您的问题的主体指示了其他内容。所以看起来你认为找到一个浮点的长度正在走向一个更大的解决方案。我不确定,所以我只想指出几个问题。

首先,您正在误用sizeof;在C#中的sizeof()需要一个类型,而不是一个变量。 (所以sizeof(float)将起作用,但不是sizeof(num))。

在任何情况下,sizeof它不会给你有效位数。它会给你存储非托管类型的字节数,它将是不变的(4,8等)。相反,对于一个给定的字符串,请使用string.length减

不过,你不能能做的就是尽力数字解析为float,然后尝试通过检查,检查出的数值范围浮点变量。根据定义,如果你可以成功解析为一个浮点数,那么它是有效的。如果它无效,它不会解析。你的例子中使用Single.Parse()的部分,然后继续尝试使用float变量进行验证是没有意义的。您需要验证字符串值,或者验证解析是否成功,或者更改您的方法。

我认为最简单的解决方案是使用Single.TryParse()并检查布尔返回值。如果它返回false,则该字符串值无效,或超出Single.MinValue和Single.MaxValue的范围。所以你可能会重新考虑你的方法(因为它不是作者最初的挑战)。我个人会使用C#中的大类型我的计算器,但演习的目的可能是要学习这些切线问题,所以:

  1. 如果你已经有一个单精度(浮点数),那么你可以通过使用Single.ToString()或string.Format()转换为字符串并使用string.Length来获得长度,尽管它将包含小数点,所以请考虑这一点。

    参见toString()和格式说明在:

    http://msdn.microsoft.com/en-us/library/fzeeb5cd(v=vs.110).aspx

    http://msdn.microsoft.com/en-us/library/0c899ak8(v=vs.110).aspx

    的问题,这是你使用的ToString()的时候,你已经有了一个有效的float和由时间检查是没有意义的。您需要检查原始值。请参阅(2)

  2. 如果从字符串开始(在此示例中,您正在从控制台读取字符串,然后使用Single.Parse()进行解析,那么您将获得有效值或异常你需要使用与Single.Parse()一个try-catch块,否则切换到Single.TryParse(),并检查布尔返回值。

最后,如果你想确保你既可以解析值以及验证数字的更高精度或范围,您也可以添加一个Double.TryParse()以及。

if(!Single.TryParse(str, ref snum)) { 
    if(Double.TryParse(str, ref dnum)) 
     // valid number is out of range for Single 
    else 
     // valid number is out of range for Double, or invalid 
} 

或者你可以使用Single.Parse和catch(OverflowException异常)

try { 
    snum = Single.Parse(str); 
} 
catch(OverflowException e) { 
} 

所有这一切被说关于您的实际问题,但问题的实质是如何比较2个有效号码,在我看来。在这种情况下,使用的TryParse()来有效的他们,然后就直接对它们进行比较,或使用办法在@ DRF的回答https://stackoverflow.com/a/24482343/257090

+0

我不确定解决方案是否如此简单。难道这不会让大量数据丢失吗? –

+0

@AndrewBarber - 当我读到这个问题时,他想检查有效数字大于7,但不一定使用它进行比较,所以我认为字符串版本足以进行检查。不过,不一定要进行比较。我调整了我的措辞。让我知道如果你仍然认为我错过了什么。我可能没有完全想到它。 – codenheim

+0

我认为'有效数字'的东西在这里被不恰当地强调。他想要的是精确度在+/- 0.0000001之内。 –

1
static private int GetNumDigitsInFloat(float n) 
    { 
    string s = n.ToString(); 
    return s.Length - 1; 
    } 
+0

非常好,简单的解决方案。 – Enigmativity

0

给出如果目的是为了确保两个浮点数字是大致相等的内1E-7,根本不需要转换为字符串。事实上,使用字符串转换可能不是一个可靠的方法:

  • 书面问题需要七个显著数字小数点后,不是七个显著数字总。字符串的长度将包括两个。
  • Single.ToString默认情况下只打印7位精度,但内部最多可存储9个数字。浮点数20.000001和20.000003在默认情况下都会转换为“20”,但在1e-7之内不会相等。 (这是字符串转换的功能,不是对此数据类型的精确限制。)
  • 花车可以解析并以指数表示法输出。如果用户在提示下输入1e+20会发生什么,这是一个长度为5的完全有效的浮动吗?

鉴于两个数字f1f2,和一个接受错误的10^-7 ε,它遵循在数学上这f1f2应该被认为等于(可接受的公差内),当且仅当:

|f1 - f2| ≤ ε 

或者在C#中,我们可以写出相当的功能:

// preconditions: e is non-negativeps, f1 and f2 are not NaN, Inf, or -Inf. 
bool AreApproximatelyEqual(float f1, float f2, float eps) 
{ 
    return Math.Abs(f1 - f2) <= eps; 
} 

鉴于花车firstNum和012近似相等如下获得:

bool equal = AreApproximatelyEqual(firstNum, secondNum, 1e-7f);