Подтвердить что ты не робот

Преобразование двойного плавания без бесконечности

Я конвертирую double в float, используя старые float myFloat = (float)myDouble.

Однако это иногда приводит к "бесконечности", что плохо для дальнейшей обработки, которую я делаю. Я в порядке с потерей, пока он указывает на общее направление, поскольку исходное число (относительное число "сила" для всех чисел, которые я конвертирую, должно поддерживаться).

Как преобразовать float в double и избежать бесконечности?

Справочная информация:
Я читаю байтовый поток из wav/mic, преобразовывая его в float, преобразовывая его в double, запуская его с помощью вычисления FFT (это то, что требует double), и теперь я хочу, чтобы он вернулся к float (сохранение данных в 32-битном контейнере изображений).

4b9b3361

Ответ 1

Итак, если значение больше, чем float.MaxValue, вы довольны тем, что это просто float.MaxValue? Это эффективно "закрепит" значения. Если это хорошо, это достаточно просто:

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

Ответ 2

Вы можете использовать метод .NET Convert.ToSingle(). Например:

float newValue = Convert.ToSingle(value);

В соответствии с Документация MSDN:

Преобразует указанное значение в число с плавающей запятой с одной точностью.

Update: После дальнейшего рассмотрения Convert.ToSingle(Double.MaxValue) приводит к бесконечности, поэтому вам все равно придется проверять бесконечность, как это сделано в ответе Джона Скита.

Ответ 3

Если результат вычисления вычисления превышает диапазон типа, в котором вы его храните, необходимо сделать одну из трех вещей:

  • Выбросить исключение
  • Возвращает значение "дозорного", которое указывает на наличие проблемы и которое предпочтительно будет признано как эффективное аннулирование любых вычислений там, где оно появляется
  • Привести результат к определенному значению (к которому он будет привязан даже если он не превышает диапазон вашего числового типа). Например, может быть узел датчика с двумя усредненными по времени входами X и Y, чье "значение" равно (X * X)/(Y * Y) - (Y * Y)/(X * X). Если входные сигналы являются шумными, низкое значение на одном входе может считаться исключительно низким значением. Если измерение будет использоваться для управления контуром обратной связи, и если "фактическое" значение не будет превышать +/- 1000000,0, может быть лучше привязать значение к этому диапазону, чем позволить контуру управления видеть полностью дикую вычисленную (X или Y - наименьшее возможное ненулевое значение).

Существует много приложений, в которых третий подход будет правильным. В таких ситуациях, однако, если было бы целесообразно привязать показания к значению миллиона, то не имеет значения, приводит ли вычисление значение 1000,001 или 1E + 39 (с плавающей запятой + INF). В обоих случаях нужно привязать к миллиону.

Ответ 4

Используйте эту функцию

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