C# 有无符号双精度数吗?

发布于 2024-12-03 05:48:53 字数 63 浏览 0 评论 0原文

我需要使用无符号双精度,但事实证明 C# 不提供这样的类型。

有谁知道为什么?

I need to use an unsigned double but it turns out C# does not provide such a type.

Does anyone know why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

感性不性感 2024-12-10 05:48:53

正如 Anders Forsgren 所指出的,IEEE 规范中没有无符号双精度数(因此 C# 中也没有)。

您始终可以通过调用 Math.Abs​​() 获得正值,并且您可以将双精度数包装在结构中并在那里强制执行约束:

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
}

As pointed out by Anders Forsgren, there is no unsigned doubles in the IEEE spec (and therefore not in C#).

You can always get the positive value by calling Math.Abs() and you could wrap a double in a struct and enforce the constraint there:

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
}
梦晓ヶ微光ヅ倾城 2024-12-10 05:48:53

浮点数只是 IEEE 754 规范的实现。据我所知,不存在无符号双精度之类的东西。

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

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

Floating point numbers are simply the implementation of the IEEE 754 spec. There is no such thing as an unsigned double there as far as i know.

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

Why do you need an unsigned floating point number?

嗳卜坏 2024-12-10 05:48:53

我推出了 @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();
    }
}

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

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

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

I rolled out a more detailed implementation of @Isak Savo's with tweaks here and there. Not sure if its perfect, but it's a great place to start.

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();
    }
}

As to why one would need an unsigned double, consider that width and height dimensions of UI elements cannot be negative in most applications as that would be illogical; why, then, support negative numbers where they're not needed?

Some values like PositiveInfinity and NaN may still be applicable; therefore, we provide intuitive references to them. The big difference between double and UDouble is UDouble wouldn't need the constant NegativeInfinity (or at least I assume this much; I am not a mathematician, after all) and MinValue constant is simply 0. Also, Epsilon is positive, though, I am uncertain whether or not it is logical to use in the same context as unsigned numbers.

Note, this implementation automatically truncates negative numbers and an exception is thrown if you attempt to set to NegativeInfinity.

爱,才寂寞 2024-12-10 05:48:53

在我听说过的任何语言或系统中都不存在“无符号双精度”这样的东西。

我需要提供传递可以是分数且必须为正的变量的能力。我想在我的函数签名中使用它来强制执行它。

如果您想强制执行参数为正的约束,则需要通过运行时检查来实现。

There is no such thing as an unsigned double in any language or system that I have ever heard of.

I need to give the ability to pass a variable that can be a fraction and must be positive. I wanted to use it in my Function signature to enforce it.

If you want to enforce a constraint that the parameter is positive, then you need to do that with a runtime check.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文