Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何正确比较C#中的十进制值? 我来自C++背景,我知道不能准确地比较浮点以获得相等。对于C#,我只是假设相同的策略适用于十进制值,或者任何浮点值_C#_Comparison_Floating Point - Fatal编程技术网

如何正确比较C#中的十进制值? 我来自C++背景,我知道不能准确地比较浮点以获得相等。对于C#,我只是假设相同的策略适用于十进制值,或者任何浮点值

如何正确比较C#中的十进制值? 我来自C++背景,我知道不能准确地比较浮点以获得相等。对于C#,我只是假设相同的策略适用于十进制值,或者任何浮点值,c#,comparison,floating-point,C#,Comparison,Floating Point,基本上,我有两个十进制值,如果它们彼此不相等,我需要执行一些操作。e、 g: decimal value1, value2; // Assume value1 and value2 are set somewhere to valid values. if( value1 != value2 ) { // Do something } 如果这不能像预期的那样起作用,我愿意接受一个解决方案,这个解决方案会进行一个误差范围的等式比较,比如说.00001之类的。这个问题的推荐解决方案是什么?

基本上,我有两个十进制值,如果它们彼此不相等,我需要执行一些操作。e、 g:

decimal value1, value2;
// Assume value1 and value2 are set somewhere to valid values.
if( value1 != value2 )
{
    // Do something
}
如果这不能像预期的那样起作用,我愿意接受一个解决方案,这个解决方案会进行一个误差范围的等式比较,比如说.00001之类的。这个问题的推荐解决方案是什么?

我想可以解决你的问题

基本上有一个decimal.compare方法

编辑:这可能是更好的方法:


编辑2:如果你能像上面建议的那样直接比较,那可能会更有效率。我将保留此内容,因为它可能会引起兴趣。

您的代码将按预期工作。C#
decimal
s经过优化,能够非常准确地表示以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);
    } 
}
//
///一组扩展,允许基于给定精度方便地比较浮点值。
/// 
公共静态类FloatingPointExtensions
{
/// 
///根据定义的精度确定浮点值是否小于或等于浮点参数。
/// 
///花车1。
///花车2。
///精度。比较时将考虑的小数点后的位数。
/// 
公共静态bool LessThan(此浮点float float1、float float2、int精度)
{
返回值(系统数学四舍五入(float1-float2,精度)<0);
}
/// 
///根据定义的精度确定浮点值是否小于或等于浮点参数。
/// 
///花车1。
///花车2。
///精度。比较时将考虑的小数点后的位数。
/// 
公共静态bool LessThanOrEqualTo(此浮点float1,浮点float2,整数精度)
{
根据定义的精度返回(System.Math.Round(float1-float2,precision))浮点参数。
/// 
///花车1。
///花车2。
///精度。比较时将考虑的小数点后的位数。
/// 
公共静态布尔值大于(此浮点值浮点1、浮点值浮点2、整数精度)
{
返回值(System.Math.Round(float1-float2,精度)>0);
}
/// 
///根据定义的精度确定浮点值是否大于或等于(>=)浮点参数。
/// 
///花车1。
///花车2。
///精度。比较时将考虑的小数点后的位数。
/// 
公共静态布尔值大于或等于整数(此浮点值浮点1、浮点值浮点2、整数精度)
{
返回值(System.Math.Round(float1-float2,精度)>=0);
}
/// 
///根据定义的精度确定浮点值是否等于(=)浮点参数。
/// 
///花车1。
///花车2。
///精度。比较时将考虑的小数点后的位数。
/// 
公共静态布尔值AlmostEquals(此浮点值float1、float float2、int精度)
{
返回值(System.Math.Round(float1-float2,精度)=0);
} 
}

我同意其他答案,但我遇到了一个问题,一个“真实”的服务器端十进制数与一个来自JSON/浏览器的十进制数进行比较(在某个点上一定是一个浮点数)

最后,我将代码四舍五入到小数点后的两位数,这在我的例子中足够精确:

if (Decimal.Round(serverTotalPrice, 2) != Decimal.Round(request.TotalPrice, 2)) {
    throw new ArgumentException("The submitted Total Price is not valid");
}

它与double而不是decimal的关系并不完全相同,但请看一下@Mark:Good point.decimal。你发布的代码是比较两个小数的正确方法。如果你想比较两个小数的误差幅度,你只需在你说“decimal”时执行
If(Math.Abs(value2-value1)<0.00001){…}
,您是在谈论还是在使用“decimal”作为各种浮点格式的总称,包括,
decimal
(如上链接)?我想澄清一下我在原始帖子中对“decimal”的用法。基本上,我指的是实际类型的“decimal”(实际关键字).我不太明白十进制类型的底层数据是什么样子的,我只是假设它们是浮点值,而对于分数类型,它们永远不会完全相同(就像C++中的浮点和双精度)。你可能是对的。里面也有一个decimal.equals。我记得我没有用过它们,但它似乎是合适的。如果有人知道不同的情况,我也会感到好奇。这与
x==y
,其中x是一种浮点类型的问题相同。(小数具有固定精度这一事实在某种程度上只是相关的,因为这是一个有问题的数学问题。)所有提供的答案都是有用的。我之所以把这一个标记为我的答案,主要是因为我意识到我没有完全理解C#中的小数是什么。小数看起来不像我想象的那样是浮点数。另外,解释差异的文章的链接对我非常有帮助。@Robert:小数是浮点数,因为p小数点的位置是“浮动的”。小数点不是“固定点”数字,比如说,小数点前15位,后10位。小数点和双精度的区别在于小数点是固定的