将double转换为float,不带Infinity

本文关键字:不带 Infinity float double 转换 | 更新日期: 2023-09-27 18:01:36

我正在使用旧的float myFloat = (float)myDouble将double转换为float。

然而,这有时会导致"无限",这对我正在做的进一步处理不利。我可以接受损失,只要它指向原始数字的大致方向(我转换的所有数字的相对数字"强度"必须保持)。

如何将float转换为double并避免Infinity?

背景:
我正在从wav/mic读取字节流,将其转换为float,将其转换为double,通过FFT计算运行它(这是需要double的),现在我想让它回到float(将数据存储在32位图像容器中)。

将double转换为float,不带Infinity

因此,如果值大于float.MaxValue,您是否乐意为它只是float.MaxValue ?这将有效地"剪辑"这些值。如果可以的话,这相当简单:

float result = (float) input;
if (float.IsPositiveInfinity(result))
{
    result = float.MaxValue;
} else if (float.IsNegativeInfinity(result))
{
    result = float.MinValue;
}

您可以使用。net方法Convert.ToSingle()。例如:

float newValue = Convert.ToSingle(value);

根据MSDN文档:

将指定的值转换为单精度浮点数。

更新:经过进一步审查,Convert.ToSingle(Double.MaxValue)的结果是无穷大,所以你仍然需要像Jon Skeet的答案一样检查无穷大。

如果计算的计算结果超出了存储它的类型的范围,则需要做以下三件事之一:

    抛出异常
  1. 返回一个"哨兵"值,该值表明存在问题,并且最好将其识别为有效地使出现问题的任何计算无效
  2. 将结果与某个特定值挂钩(即使它没有超出数值类型的范围,它也会与该值挂钩)。例如,一个传感器组件可能具有两个时间平均输入X和Y,其"值"为(X*X)/(Y*Y)-(Y*Y)/(X*X)。如果输入有噪声,则一个输入上的低值可能被读取为异常低值。如果测量值将用于控制反馈回路,并且如果"实际"值不会超过+/- 1000000.0,则将值固定在该范围内可能比让控制回路看到完全疯狂的计算读数(X或Y是可能的最小非零值)更好。

在许多应用中,第三种方法是正确的。然而,在这种情况下,如果将读数固定为一百万是有意义的,那么计算结果是1,000,001还是1E+39(浮点数+INF)就无关紧要了。无论哪种情况,一个人都应该与百万挂钩。

使用此函数

public static float DoubleToFloat(double dValue)
    {
        if (float.IsPositiveInfinity(Convert.ToSingle(dValue)))
        {
            return float.MaxValue;
        }
        if (float.IsNegativeInfinity(Convert.ToSingle(dValue)))
        {
            return float.MinValue;
        }
        return Convert.ToSingle(dValue);
    }