Convert double to float without Infinity
Asked Answered
R

4

29

I'm converting double to float using ye old float myFloat = (float)myDouble.

This does however sometimes result in "Infinity", which is not good for the further processing I'm doing. I'm okay with loss as long as it is pointing in the general direction as the original number (the relative number 'strength' on all numbers I'm converting must be maintained).

How can I convert float to double and avoid Infinity?

Background:
I'm reading a bytestream from wav/mic, converting it to float, converting it to double, running it through FFT calculation (this is what requires double), and now I want it back to float (storing the data in 32-bit image container).

Ray answered 10/7, 2011 at 11:18 Comment(0)
W
36

So if the value is greater than float.MaxValue, are you happy for it to just be float.MaxValue? That will effectively "clip" the values. If that's okay, it's reasonably easy:

float result = (float) input;
if (float.IsPositiveInfinity(result))
{
    result = float.MaxValue;
} else if (float.IsNegativeInfinity(result))
{
    result = float.MinValue;
}
Weltanschauung answered 10/7, 2011 at 11:23 Comment(3)
No, the relative distance (%) between each number I'm converting must be preserved. Not sure if something like (float)((float.MaxValue / double.MaxValue) * myDouble) could work. But as I understand the decimal precision is dynamic, so that wouldn't work... right?Ray
@Tedd: I suspect you'd lose an awful lot of information due to the way that floating point values are represented, yes. Can you find out the range of actual values before starting to do the processing?Weltanschauung
Thanks. Rewrote the memory handling to use 64-bit storage so I could use Double throughout the app.Ray
V
17

You can use the .NET method Convert.ToSingle(). For example:

float newValue = Convert.ToSingle(value);

According to the MSDN Documentation:

Converts a specified value to a single-precision floating-point number.

Update: Upon further review, Convert.ToSingle(Double.MaxValue) results in Infinity so you still have to check for infinity as done in Jon Skeet's answer.

Virtuous answered 2/12, 2013 at 15:6 Comment(0)
L
1

If a calculation result of a calculation exceeds the range of the type you're storing it in, it will be necessary to do one of three things:

  1. Throw an exception
  2. Return a "sentinel" value which indicates that there was a problem, and which will preferably be recognized as effectively invalidating any calculations where it appears
  3. Peg the result to some particular value (to which it would be pegged even it if it didn't exceed the range of your numeric type). For example, one may have a sensor assembly with two time-averaged inputs X and Y, whose "value" is (X*X)/(Y*Y)-(Y*Y)/(X*X). If the inputs are noisy, a low value on one input may be read as an exceptionally low value. If the measurement will be used to control a feedback loop, and if the "actual" value won't exceed +/- 1000000.0, it may be better to peg the value to that range than to let the control loop see a totally wild computed reading (X or Y being the smallest possible non-zero value).

There are many applications where the third approach would be the right one. In such situations, however, if it would make sense to peg the reading at a value of a million, then it shouldn't matter whether the computation results in a value of 1,000,001 or 1E+39 (floating-point +INF). One should peg to a million in either case.

Logsdon answered 31/5, 2012 at 15:19 Comment(2)
I like you answer; it would be nice to have an example of 2 and 3.Brey
@ScottFoster1000: Conversion of out-of-range numbers to float generally results in behavior #2 (with the pegged values being called "positive infinity" and "negative infinity"), but conflicting operations on infinities (e.g. adding a positive and negative infinity to each other) may result in a sentinel value called NaN ("not a number").Logsdon
D
0

Use this Function

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);
    }
Disappointed answered 13/3, 2017 at 8:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.