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

.NET 7+中INumber<T>转float?整数与float互转插值问题

整数转浮点计算后转回整数的线性插值实现方案

当前的LinearBetween泛型方法存在核心问题:当T为整数类型(如int)时,所有运算会执行整数除法,直接截断小数部分,导致斜率m计算错误,最终插值结果完全偏离预期。比如示例中(3-5)/(10-0)会得到0而非-0.2,返回结果为3,但正确的浮点计算结果应为1.6,四舍五入后是2。

以下是两种可行的解决方案:

方案1:泛型方法内统一转浮点计算,再转回原类型

修改泛型方法,将所有参数转换为float执行浮点运算,最后根据原类型决定是直接转换还是四舍五入:

void Main()
{
    Interpolation.LinearBetween((0, 5), (10, 3), 7).DumpIt(); // 输出2
    Interpolation.LinearBetween((0.0f, 5f), (10f, 3f), 7f).DumpIt(); // 输出1.6
}

public static class Interpolation
{
    public static T LinearBetween<T>((T x1, T y1) a, (T x2, T y2) b, T x) where T : INumber<T>
    {
        // 将所有参数转换为float执行浮点运算
        float x1Float = float.CreateTruncating(a.x1);
        float y1Float = float.CreateTruncating(a.y1);
        float x2Float = float.CreateTruncating(b.x2);
        float y2Float = float.CreateTruncating(b.y2);
        float xFloat = float.CreateTruncating(x);

        float m = (y2Float - y1Float) / (x2Float - x1Float);
        float n = y2Float - m * x2Float;
        float resultFloat = xFloat * m + n;

        // 根据类型转换回T:整数类型四舍五入,浮点类型直接转换
        if (typeof(T).IsInteger())
        {
            return T.CreateRoundingToEven(resultFloat);
        }
        else
        {
            return T.CreateTruncating(resultFloat);
        }
    }

    public static int RoundToInt(this float value)
    {
        return (int)Math.Round(value);
    }

    public static void DumpIt(this object toDump)
    {
        Console.WriteLine(toDump);
    }
}

方案2:重载方法分别处理整数和浮点类型

通过重载方法,为整数类型单独实现转浮点计算的逻辑,浮点类型直接使用原有逻辑:

void Main()
{
    Interpolation.LinearBetween((0, 5), (10, 3), 7).DumpIt(); // 输出2
    Interpolation.LinearBetween((0.0f, 5f), (10f, 3f), 7f).DumpIt(); // 输出1.6
}

public static class Interpolation
{
    // 整数专用版本:内部转浮点计算后返回四舍五入结果
    public static int LinearBetween((int x1, int y1) a, (int x2, int y2) b, int x)
    {
        float x1f = a.x1;
        float y1f = a.y1;
        float x2f = b.x2;
        float y2f = b.y2;
        float xf = x;

        float m = (y2f - y1f) / (x2f - x1f);
        float n = y2f - m * x2f;
        return (int)Math.Round(xf * m + n);
    }

    // 浮点类型通用版本
    public static T LinearBetween<T>((T x1, T y1) a, (T x2, T y2) b, T x) where T : IFloatingPoint<T>
    {
        var m = (b.y2 - a.y1) / (b.x2 - a.x1);
        var n = b.y2 - m * b.x2;
        return x * m + n;
    }

    public static int RoundToInt(this float value)
    {
        return (int)Math.Round(value);
    }

    public static void DumpIt(this object toDump)
    {
        Console.WriteLine(toDump);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 18:05:59