无符号双人

时间:2011-09-05 08:53:03

标签: c# double unsigned

我需要使用 unsigned double 但事实证明C#不提供这样的类型。

有谁知道为什么?

4 个答案:

答案 0 :(得分:17)

浮点数只是IEEE 754规范的实现。据我所知,在那里没有无符号的双子。

http://en.wikipedia.org/wiki/IEEE_754-2008

为什么需要无符号浮点数?

答案 1 :(得分:15)

正如Anders Forsgren所指出的那样,IEEE规范中没有未签名的双打(因此不在C#中)。

你总是可以通过调用Math.Abs()得到正值,你可以在结构中包含一个double并在那里强制执行约束:

public struct PositiveDouble 
{
      private double _value;
      public PositiveDouble() {}
      public PositiveDouble(double val) 
      {
          // or truncate/take Abs value automatically?
          if (val < 0)
              throw new ArgumentException("Value needs to be positive");
          _value = val;
      }

      // This conversion is safe, we can make it implicit
      public static implicit operator double(PositiveDouble d)
      {
          return d._value;
      }
      // This conversion is not always safe, so we make it explicit
      public static explicit operator PositiveDouble(double d)
      {
          // or truncate/take Abs value automatically?
          if (d < 0)
              throw new ArgumentOutOfRangeException("Only positive values allowed");
          return new PositiveDouble(d);
      }
      // add more cast operators if needed
}

答案 2 :(得分:3)

在我听说过的任何语言或系统中都没有无符号双重的东西。

  

我需要能够传递一个可以是分数的变量,并且必须是正数。我想在我的Function签名中使用它来强制执行它。

如果要强制执行参数为正的约束,则需要通过运行时检查来执行此操作。

答案 3 :(得分:2)

我在这里和那里推出了更详细的@Isak Savo的实现。不确定它是否完美,但它是一个很好的起点。

public struct UDouble
{
    /// <summary>
    /// Equivalent to <see cref="double.Epsilon"/>.
    /// </summary>
    public static UDouble Epsilon = double.Epsilon;

    /// <summary>
    /// Represents the smallest possible value of <see cref="UDouble"/> (0).
    /// </summary>
    public static UDouble MinValue = 0d;

    /// <summary>
    /// Represents the largest possible value of <see cref="UDouble"/> (equivalent to <see cref="double.MaxValue"/>).
    /// </summary>
    public static UDouble MaxValue = double.MaxValue;

    /// <summary>
    /// Equivalent to <see cref="double.NaN"/>.
    /// </summary>
    public static UDouble NaN = double.NaN;

    /// <summary>
    /// Equivalent to <see cref="double.PositiveInfinity"/>.
    /// </summary>
    public static UDouble PositiveInfinity = double.PositiveInfinity;

    double value;

    public UDouble(double Value)
    {
        if (double.IsNegativeInfinity(Value))
            throw new NotSupportedException();

        value = Value < 0 ? 0 : Value;
    }

    public static implicit operator double(UDouble d)
    {
        return d.value;
    }

    public static implicit operator UDouble(double d)
    {
        return new UDouble(d);
    }

    public static bool operator <(UDouble a, UDouble b)
    {
        return a.value < b.value;
    }

    public static bool operator >(UDouble a, UDouble b)
    {
        return a.value > b.value;
    }

    public static bool operator ==(UDouble a, UDouble b)
    {
        return a.value == b.value;
    }

    public static bool operator !=(UDouble a, UDouble b)
    {
        return a.value != b.value;
    }

    public static bool operator <=(UDouble a, UDouble b)
    {
        return a.value <= b.value;
    }

    public static bool operator >=(UDouble a, UDouble b)
    {
        return a.value >= b.value;
    }

    public override bool Equals(object a)
    {
        return !(a is UDouble) ? false : this == (UDouble)a;
    }

    public override int GetHashCode()
    {
        return value.GetHashCode();
    }

    public override string ToString()
    {
        return value.ToString();
    }
}

至于为什么需要一个无符号double,考虑到UI元素的宽度和高度尺寸在大多数应用程序中不能为负,因为这是不合逻辑的;那么,为什么在不需要的地方支持负数呢?

PositiveInfinityNaN等某些值可能仍适用;因此,我们提供直观的参考。 doubleUDouble之间的最大区别是UDouble不需要常量NegativeInfinity(或者至少我假设这么多;毕竟我不是数学家)而MinValue常数只是0。此外,Epsilon是肯定的,但我不确定在无符号数字的相同上下文中使用它是否合乎逻辑。

注意,此实现会自动截断负数,如果您尝试设置为NegativeInfinity,则会引发异常。