You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于INumber<T>泛型约束的类如何返回NaN?

在INumber泛型中返回NaN的解决方案

首先要明确:不是所有实现INumber<T>的类型都支持NaN值。比如整数类型(int、long、short等)和decimal本身没有NaN的概念——这些类型的所有实例都是有效的数值,不存在“非数字”的状态,因此对于这类类型,你无法返回NaN,只能抛出异常。

对于支持NaN的类型(如float、double、nfloat等符合IEEE 754标准的浮点类型),可以通过INumberBase<T>接口定义的静态属性T.NaN来获取该类型的NaN值,因为INumber<T>继承了INumberBase<T>。

修改后的Divide类实现

public class Divide<T> where T : INumber<T>
{
    public T Evaluate()
    {
        var divisor = Child[1].Evaluate();
        if (divisor.CompareTo(T.Zero) == 0)
        {
            try
            {
                // 尝试返回NaN,不支持的类型会抛出NotSupportedException
                return T.NaN;
            }
            catch (NotSupportedException)
            {
                // 针对不支持NaN的类型,抛出除零异常
                throw new DivideByZeroException("无法对不支持NaN的类型执行除零操作");
            }
        }

        var dividend = Child[0].Evaluate();
        return dividend / divisor;
    }
}

更精准的类型判断(避免异常捕获)

如果你想提前判断类型是否支持NaN,而不是依赖异常捕获,可以通过类型码来区分:

public class Divide<T> where T : INumber<T>
{
    public T Evaluate()
    {
        var divisor = Child[1].Evaluate();
        if (divisor.CompareTo(T.Zero) == 0)
        {
            var typeCode = Type.GetTypeCode(typeof(T));
            return typeCode switch
            {
                TypeCode.Single => (T)(object)float.NaN,
                TypeCode.Double => (T)(object)double.NaN,
                TypeCode.NFloat => (T)(object)nfloat.NaN,
                _ => throw new DivideByZeroException("无法对不支持NaN的类型执行除零操作")
            };
        }

        var dividend = Child[0].Evaluate();
        return dividend / divisor;
    }
}

关于无穷大的补充

和NaN一样,无穷大也只有IEEE 754浮点类型支持,你可以用T.PositiveInfinity或T.NegativeInfinity来获取,同样只适用于支持的类型,不支持的类型会抛出异常或需要提前判断。

内容的提问来源于stack exchange,提问作者Dominick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 19:52:36