"Union" struct type

Y

Yair

Hi,
I need to shift the bits of a float type.
In order to do so, I declared the following struct:

[StructLayout(LayoutKind.Explicit, Size=4)]
private struct unionIntFloatType
{
[FieldOffset(0)]
public float m_asFloat;

[FieldOffset(0)]
public int m_asInt;
}

Problem is: If I initialize the struct via 'm_asFloat',
and then extract the data using 'm_asInt', I get
CS0170: "Use of possibly unassigned field..." (Since
actually m_asInt was not initialized directly).
Writing a dummy 'm_asInt=0' at the begining of the call is
quite costly, since I'm within a loop.

Will appreciate any help with this...
 
J

Jon Skeet

Yair said:
Thanks for your reply.
The reason I'm avoiding 'BitConverter' is that it is
relatively slow (about x4 times than the union thing).

Interesting. (I presume you know for sure that you absolutely need the
performance?)

I wonder why BitConverter does what it does instead of using the union
idea internally... if there's a good reason, it might be worth knowing
to see whether it's relevant for your code as well.

One thing you could do for your struct is to give it a constructor or
two, which do the "dummy" assignment for you. For instance, you could
code it as:

using System;
using System.Runtime.InteropServices;

public class Test
{
static void Main()
{
IntFloatConverter x = new IntFloatConverter(4);
Console.WriteLine (x.FloatValue);
Console.WriteLine ((float)x);

IntFloatConverter y = (IntFloatConverter) 3.5d;
Console.WriteLine (y.IntValue);
Console.WriteLine ((int)y);
}
}

[StructLayout(LayoutKind.Explicit, Size=4)]
public struct IntFloatConverter
{
[FieldOffset(0)]
int intValue;

public int IntValue
{
get { return intValue; }
set { intValue = value; }
}

[FieldOffset(0)]
float floatValue;

public float FloatValue
{
get { return floatValue; }
set { floatValue = value; }
}


public IntFloatConverter (int i)
{
floatValue=0;
intValue = i;
}

public IntFloatConverter (float f)
{
intValue=0;
floatValue = f;
}


public static explicit operator int (IntFloatConverter x)
{
return x.intValue;
}

public static explicit operator float (IntFloatConverter x)
{
return x.floatValue;
}

public static explicit operator IntFloatConverter (int i)
{
return new IntFloatConverter(i);
}

public static explicit operator IntFloatConverter (float f)
{
return new IntFloatConverter(f);
}
}

The code above gives both casting and property access to let you easily
convert from one form to the other.
 
J

Jon Skeet

Jon Skeet said:
IntFloatConverter y = (IntFloatConverter) 3.5d;

This line should, of course, have 3.5f, not 3.5d. Not that the compiler
complained, interestingly.
 
J

Jeff Lindholm

[StructLayout(LayoutKind.Explicit, Size=4)]
private struct unionIntFloatType
{
[FieldOffset(0)]
public float m_asFloat;

[FieldOffset(0)]
public int m_asInt;
}

Problem is: If I initialize the struct via 'm_asFloat',
and then extract the data using 'm_asInt', I get
CS0170: "Use of possibly unassigned field..." (Since
actually m_asInt was not initialized directly).

unionIntFloatType i = new unionIntFloatType();

i.m_asFloat = 1.0f;

int foo = i.m_asInt;



Works fine for me. I get no error etc. I am using 1.1 of the framework.
 
V

Val Savvateev

You could add a "getter" property for asInt field and use it to get the
integer value instead of accessing the asInt directly.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top