voi*_*ter 49 c# floating-point comparison
我来自C++的背景,我知道你无法准确地比较浮点数是否相等.对于C#,我只是假设相同的策略适用于十进制值或一般的任何浮点值.
基本上,我有两个十进制值,如果它们彼此不相等,我需要执行一些操作.例如:
decimal value1, value2;
// Assume value1 and value2 are set somewhere to valid values.
if( value1 != value2 )
{
// Do something
}
Run Code Online (Sandbox Code Playgroud)
如果这不能按预期工作,我愿意接受一个与误差范围进行相等比较的解决方案,比如.00001或类似的东西.这个问题的推荐解决方案是什么?
fre*_*tje 32
您的代码将按预期工作.C#decimal
被优化为非常准确地表示基数为10的数字,所以如果你正在比较(钱,...),一切都应该没问题.
以下是Jon Skeet关于小数精度的非常明确的解释:
我正在研究类似的东西,但精确而不是误差,最后为Float写了一些扩展.这可以很容易地适用于任何类型.我有一系列复杂的比较,这使它变得美观和可读.
/// <summary>
/// A set of extensions to allow the convenient comparison of float values based on a given precision.
/// </summary>
public static class FloatingPointExtensions
{
/// <summary>
/// Determines if the float value is less than or equal to the float parameter according to the defined precision.
/// </summary>
/// <param name="float1">The float1.</param>
/// <param name="float2">The float2.</param>
/// <param name="precision">The precision. The number of digits after the decimal that will be considered when comparing.</param>
/// <returns></returns>
public static bool LessThan(this float float1, float float2, int precision)
{
return (System.Math.Round(float1 - float2, precision) < 0);
}
/// <summary>
/// Determines if the float value is less than or equal to the float parameter according to the defined precision.
/// </summary>
/// <param name="float1">The float1.</param>
/// <param name="float2">The float2.</param>
/// <param name="precision">The precision. The number of digits after the decimal that will be considered when comparing.</param>
/// <returns></returns>
public static bool LessThanOrEqualTo(this float float1, float float2, int precision)
{
return (System.Math.Round(float1 - float2, precision) <= 0);
}
/// <summary>
/// Determines if the float value is greater than (>) the float parameter according to the defined precision.
/// </summary>
/// <param name="float1">The float1.</param>
/// <param name="float2">The float2.</param>
/// <param name="precision">The precision. The number of digits after the decimal that will be considered when comparing.</param>
/// <returns></returns>
public static bool GreaterThan(this float float1, float float2, int precision)
{
return (System.Math.Round(float1 - float2, precision) > 0);
}
/// <summary>
/// Determines if the float value is greater than or equal to (>=) the float parameter according to the defined precision.
/// </summary>
/// <param name="float1">The float1.</param>
/// <param name="float2">The float2.</param>
/// <param name="precision">The precision. The number of digits after the decimal that will be considered when comparing.</param>
/// <returns></returns>
public static bool GreaterThanOrEqualTo(this float float1, float float2, int precision)
{
return (System.Math.Round(float1 - float2, precision) >= 0);
}
/// <summary>
/// Determines if the float value is equal to (==) the float parameter according to the defined precision.
/// </summary>
/// <param name="float1">The float1.</param>
/// <param name="float2">The float2.</param>
/// <param name="precision">The precision. The number of digits after the decimal that will be considered when comparing.</param>
/// <returns></returns>
public static bool AlmostEquals(this float float1, float float2, int precision)
{
return (System.Math.Round(float1 - float2, precision) == 0);
}
}
Run Code Online (Sandbox Code Playgroud)
我同意其他答案,但我遇到了一个问题,将一个“真实的”服务器端小数与来自 JSON/浏览器的小数进行比较(并且在某些时候一定是浮点数)。
我最终用这段代码四舍五入到小数点后的2 位数字,这在我的情况下足够精确:
if (Decimal.Round(serverTotalPrice, 2) != Decimal.Round(request.TotalPrice, 2)) {
throw new ArgumentException("The submitted Total Price is not valid");
}
Run Code Online (Sandbox Code Playgroud)