【问题标题】:Calculating a logarithmic percentage计算对数百分比
【发布时间】:2013-11-14 23:24:37
【问题描述】:

我有一个监控多个数据点的应用程序,我正在根据线性百分比fading between green, yellow and red 执行着色。然而,这并不能准确地将问题可视化,因为数字越高,问题越严重。范围是 0 -> 30000,我怎样才能生成我认为称为对数百分比值而不是线性的值?

【问题讨论】:

    标签: c# c#-4.0 math logarithm


    【解决方案1】:

    我假设您希望通过“对数百分比”以对数方式将数据映射到范围 [0, 100]。你可以试试这样:

    double Scale(int val)
    {
        if (val <= 1)
            return 0; // log is undefined for 0, log(1) = 0
        return 100 * Math.Log(val) / Math.Log(30000);
    }
    

    【讨论】:

    • 如果您想绘制指数增长的值,这是正确的答案。
    【解决方案2】:

    使用以下形式的函数。

    f(x) = s bx / 30000 + t

    我们知道 0 应该映射到 0%,而 30000 应该映射到 100%。

    f(0) = 0
    f(30000) = 100

    这些暗示了以下方程组。

    s + t = 0
    s b + t = 100

    解决方案(关于 b)如下。

    s = 100 / (b - 1)
    t = -100 / (b - 1)

    选择一个特定的 b > 1 值(例如 b = 10)。然后你得到以下解决方案。

    s = 100 / 9
    t = -100 / 9

    即函数f(x)如下。

    f(x) = (100 10x / 30000 - 100) / 9

    你可以在这里看到这个函数的图:Wolfram Alpha

    在 C# 中,这将如下所示。

    double x = ...;
    
    double b = 10.0;
    double s = 100.0 / (b - 1);
    double t = -100.0 / (b - 1);
    
    double f = s * Math.Pow(b, x / 30000.0) + t;
    

    【讨论】:

    • 这个图肯定是指数的而不是对数的。即它缓慢增长然后爆炸。而不是爆炸,然后缓慢增长到顶峰。
    • @IanWarburton 我没抓住重点?我在哪里说它是对数的?这显然是指数级的。 :)
    • @IanWarburton 哦 - 现在我明白了。为什么代码使用Math.Log 而不是Math.Pow?答案开头的f 的定义使用指数。很好的收获。
    【解决方案3】:

    改进 bmm6o 的答案:

    public static double Scale(long value, long maxInputValue, long maxOutputValue)
    {
        if (value <= 1)
            return 0; // log is undefined for 0, log(1) = 0
        return maxOutputValue * Math.Log(value) / Math.Log(maxInputValue);
    }
    

    如果您正在寻找介于线性和对数之间的东西,以下可能会有所帮助:

    public static double Scale(long value, long maxInputValue, long maxOutputValue, double scaleFactor)
    {
        if (value <= 1)
            return 0; // log is undefined for 0, log(1) = 0
        return maxOutputValue * Math.Pow(Math.Log(value), scaleFactor) / Math.Pow(Math.Log(maxInputValue), scaleFactor);
    }
    

    【讨论】:

      【解决方案4】:

      使用Math.Log(double)(或Math.Log(double, double),如果您想使用底数)来获取您的值的对数,然后您可以将其映射到颜色值。

      【讨论】:

        猜你喜欢
        • 2023-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-01
        • 2021-01-10
        • 2013-10-17
        • 1970-01-01
        相关资源
        最近更新 更多