为了检查两个浮点数之间的差异是否为0.01,我这样做
if ((float1 - float.Parse(someFloatAsStringFromXML).ToString(), System.Globalization.CultureInfo.InvariantCulture)).ToString() == "0,01000977")
这种“做法”是否可以接受?还有更好的方法吗?怎么样?
P.S。我是c#和强类型语言的新手!所以,如果您有简短的解释,我很乐意阅读它!
我忘了提及,数字是“353.58”和“353.59”。我把它们作为带有点“。”的字符串。不是“,”这就是我使用float.Parse
的原因答案 0 :(得分:5)
事实上,你应该总是将数字作为基础类型(浮点数,双数,十进制),而不是字符串。
现在,您可能认为可以这样比较:
float floatFromXml = float.Parse(someFloatAsStringFromXML);
if (Math.Abs(float1 - floatFromXml) == 0.01)
我的示例如下:
首先,计算两个值之间的差异:
float1 - floatFromXml
然后取其绝对值(只删除减号)
Math.Abs(float1 - floatFromXml)
然后查看该值是否等于0.01:
if (Math.Abs(float1 - floatFromXml) == 0.01)
如果您不想忽略该标志,则不会执行Math.Abs()
部分:
if ((float1 - floatFromXml) == 0.01)
但由于舍入错误,这对您的示例无效!
因为你正在使用花车(并且这也适用于双打),你将会得到四舍五入的错误,这使得将差异与0.01进行比较是不可能的。它将更像是0.01000001或其他一些稍微错误的值。
要解决这个问题,你必须将实际差异与目标差异进行比较,如果只是相差很小,你会说“那就行”。
在以下代码中,target
是您要查找的目标差异。在您的情况下,它是0.01
。
然后epsilon
是target
可能出错的最小数量。在此示例中,它是0.00001
。
我们所说的是“如果两个数字之间的差异在0.1001的0.00001之内,那么我们将其视为匹配0.1的差异。”
因此,代码会计算两个数字difference
之间的实际差异,然后它会看到该差异离0.01
有多远,如果它在0.00001
之内则打印出“YAY” ”
using System;
namespace Demo
{
class Program
{
void Run()
{
float f1 = 353.58f;
float f2 = 353.59f;
if (Math.Abs(f1 - f2) == 0.01f)
Console.WriteLine("[A] YAY");
else
Console.WriteLine("[A] Oh dear"); // This gets printed.
float target = 0.01f;
float difference = Math.Abs(f2 - f1);
float epsilon = 0.00001f; // Any difference smaller than this is ok.
float differenceFromTarget = Math.Abs(difference - target);
if (differenceFromTarget < epsilon)
Console.WriteLine("[B] YAY"); // This gets printed.
else
Console.WriteLine("[B] Oh dear");
}
static void Main()
{
new Program().Run();
}
}
}
但是,以下内容可能就是您的答案
或者,您可以使用the decimal
type代替浮点数,然后直接比较将起作用(针对此特定情况):
decimal d1 = 353.58m;
decimal d2 = 353.59m;
if (Math.Abs(d1 - d2) == 0.01m)
Console.WriteLine("YAY"); // This gets printed.
else
Console.WriteLine("Oh dear");
答案 1 :(得分:3)
您举两个数字的例子
353.58 353.59
这些数字无法以二进制浮点格式精确表示。此外,值0.01
无法以二进制浮点格式精确表示。请阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic。
因此,例如,当您尝试将353.58
表示为float
时,没有float
具有该值,并且您获得最接近的浮点值恰好为{{ 3}}
在我看来,您使用错误的数据类型来表示这些值。您需要使用小数格式。这将允许您准确地表示这些值。在C#中,您使用353.579986572265625类型。
然后你可以写:
decimal value1 = 353.58m;
decimal value2 = 353.59m;
Debug.Assert(Math.Abs(value2-value1) == 0.01m);
使用decimal
或decimal.Parse()
将数字的文字表示转换为decimal
值。
答案 2 :(得分:0)
直接回答你的问题,你能做到吗?是。这是一种有效的方法吗?几乎肯定不是。
如果您提供更多上下文,您将获得更详细的答案。
答案 3 :(得分:0)
这不是一个很好的方法。没有必要将它与字符串进行比较,你不会通过这样做获得任何东西。将它与实际的浮点值进行比较。
您的方法立即可见的问题是它不是文化安全的。在英国,我们使用.
代替,
作为小数点 - 因此.ToString()
的结果根本不匹配。但除此之外,没有充分理由这样做是不好的做法。