I have a float array in C# that stores data. However, I need to cast the data to structures like Vector2, Vector3 etc. The structures are holding only floats, so there is no data type conversion in the matter of bytes, only in access.
Eg.:
struct Vector3
{
public float x;
public float y;
public float z;
//plus some methods
}
I can copy the whole float array to the struct one manually by creating a new array, but that is kind of slow for big ones. I have tried to do conversion in unsafe code, but using generic is not working and creating special method for every struct I have is kind of "weird".
In C++ I have something like this:
float * arrayFloat = ....
Vector3 * arrayVector3 = reinterpret_cast<Vector3 *>(arrayFloat);
but that is not an option in C#...
Any ideas how to achieve this, or how to change the design?
you could add a constructor to your struct:
struct Vector3
{
public float x;
public float y;
public float z;
public Vector3(float[] vals)
{
if(vals.Length != 3)
throw new ArgumentException();
x = vals[0]; y = vals[1]; z = vals[2];
}
}
...elsewhere
float[] myFloats = { 0.0f, 1.1f, 2.2f };
var myVec = new Vector3(myFloats);
if you're asking if there is something that lets you do this without any work, the answer is no. Any conversion from an array to a struct of your choosing has to be implemented by you, preferably in your struct.
I believe this can work for your struct, using .NET Core 2.1's MemoryMarshal methods.
My answer here describes how. The essence is:
var vectors = MemoryMarshal.Cast<float, Vector3>(floatArray.AsSpan());
var firstVector = vectors[0];
This is C#'s equivalent of a reinterpret cast.
I'm new to C#, and i was struggling with the same problem, what i found useful is to use an enumerator which lazily converts every element on access:
IEnumerator<Vector3> Positions()
{
for (int i = 0; i < _positions.Length / 3; ++i)
{
yield return new Vector3(_positions[3*i],
_positions[3*i+1],
_positions[3*i+2]);
}
}
With this you don't need to copy the whole array and compiler most likely will not create new object of type Vector3 in memory instead it will use registers.
Related
I have a struct which is for an Arc.
I created a constructor that accepts an Arc struct type and i want to basically copy the contents to the new struct i am creating but it seems to zero everything out - not sure if i am misunderstanding how this works.
This is what i have:
//constructor, take an arc - copy it but with a new radius
public Arc(Arc a, float radius)
{
this = a;
a.Radius = radius;
}
With the usage
Arc arc1 = new Arc(arc0, arc0.Radius + _width/2f);
arc1.Draw(Color.green,2);
Arc arc2 = new Arc(arc0, arc0.Radius - _width/2f);
arc2.Draw(Color.green,2);
For some reason arc1 and arc2 have default values for all its fields including the radius field.
I was expecting arc1 and arc2 to basically be copies of arc0 but with a new radius.
Is the use of this not applicable for non reference types or something? I can't see why else i am having this problem.
public Arc(Arc a, float radius)
{
this = a;
a.Radius = radius; // <-- This line is the problem
}
Your use of a.Radius = radius means you're overwriting the .Radius member of parameter a, not field this.a.
Value-types, including struct values in .NET, do not share identity - whereas reference-types (class instances, Object, etc) can do (and do by default). So, with limited exceptions, you can think of each struct-variable as holding its own distinct copy of the entire structure instance.
Change your code to this:
public Arc(Arc source, float radius)
{
this = source; // Copy `source` into `this`
this.Radius = radius; // Then overwrite `this.Radius`
}
I'm making a game in c# and I'm trying to make my texture move. I need some help and advice to make the texture move. This is what I've used so far.
public float InitialTime { get; set; }
public Vector2 InitialPosition { get; set; }
public Vector2 InitialVelocity { get; set; }
public Vector2 Position(GameTime time)
{
float t = (float)time.TotalGameTime.TotalSeconds = InitialTime;
return InitialPosition + t * InitialVelocity;
}
on the 'float t' line, it comes up with the following error,
Error CS0131 The left-hand side of an assignment must be a variable,
property or indexer
Your problem is because of this:
float t = (float)time.TotalGameTime.TotalSeconds = InitialTime;
Both sides of an assignment operation need to have valid syntax. If you were to isolate the second assignment, it would look like this:
(float)time.TotalGameTime.TotalSeconds = InitialTime;
Which is not only invalid syntax, but it also makes little sense.
I imagine that the reason you are doing the cast is because TotalSeconds and InitialTime are doubles and you need to cast them to a float. There are two ways to accomplish this.
You can either split up the assignment onto two different lines:
time.TotalGameTime.TotalSeconds = InitialTime;
float t = (float)time.TotalGameTime.TotalSeconds;
Or, if you insist on doing this on a single line, use parentheses to group your operations:
float t = (float)(time.TotalGameTime.TotalSeconds = InitialTime);
EDIT:
Then again, I've been assuming that the double assignment was intentional. What you may have meant to do was to subtract InitialTime from your TotalTime to get the current time stamp. In that case, it's just a simple fix of a typo:
float t = (float)(time.TotalGameTime.TotalSeconds - InitialTime);
(Note that if TotalSeconds and InitialTime are doubles, you will need to use parentheses to cast the operation to a float, as I have done.)
There is a well known issue when it comes to using .NET value types in IronPython. This has recently caused me a headache when trying to use Python as an embedded scripting language in C#. The problem can be summed up as follows:
Given a C# struct such as:
struct Vector {
public float x;
public float y;
}
And a C# class such as:
class Object {
public Vector position;
}
The following will happen in IronPython:
obj = Object()
print obj.position.x # prints ‘0’
obj.position.x = 1
print obj.position.x # still prints ‘0’
As the article states, this means that value types are mostly immutable. However, this is a problem as I was planning on using a vector library that is implemented as seen above. Are there any workarounds for working with existing libraries that rely on value types? Modifying the library would be the very last resort, but I'd rather avoid that.
There's no need to modify the library, just use a proxy.
struct Vector {
public float X;
public float Y;
}
class BetterVector {
public float X;
public float Y;
public Vector Optimized { get { return new Vector(X, Y); } }
}
class Object {
public BetterVector Position { get; set; }
}
Now the Python code can set fields as normal and your code can call Optimized when it needs to feed the data to OpenGL or XNA or whatever you're using.
You can even use implicit coercion if calling Optimized seems like too much work:
class BetterVector {
// ...
public static implicit operator Vector(BetterVector v) {
return v.Optimized;
}
}
When you call
obj.position.x = 1
What you get is that the obj object gets you an instance of the position struct, which it essentially makes a copy of, so, setting the X value doesn't get propogated.
What you're saying is that obj.position = Vector(1,0) is what you should be doing. Similar things happen in C#.
Edit - possible work around.
If you don't want to set up the constructor, I believe this will work:
obj = Object()
pos = obj.position; # gets the object
pos.x = 1
pos.y = 2
obj.position = pos # I'm not sure if this line is necessary
The only way I've found to update structs is to make use of the fact that you can specify any public field/property when creating a struct. The syntax looks like named/optional parameters in Python.
namespace StructExample
{
public struct MyStruct
{
public int x;
public int y { get; set; }
}
public class MyClass
{
public MyStruct a;
}
}
We can use the classes in IronPython like this:
>>> foo = MyClass()
>>> print "%d:%d" % (foo.a.x, foo.a.y)
0:0
>>> foo.a.x = 1 # doesn't work!
>>> print "%d:%d" % (foo.a.x, foo.a.y)
0:0
>>> foo.a = MyStruct(x=1,y=2)
>>> print "%d:%d" % (foo.a.x, foo.a.y)
1:2
It would be nice if Python had a syntax like the F# 'with' for creating a new struct, copying the fields from the old one. Unfortunately we have to specify all the fields when cloning a struct.
Rather puzzling that you ended up in such a corner. In python (tried this on IronPython 2.6.1, .Net 4.0) the equivalent code would be about this:
>>> class a:
... x = 0
... y = 0
...
>>> class b:
... Vector = a()
...
>>> c = b()
>>> c.Vector.x = 1
>>> print c.Vector.x
1
Note there is one difference between my pseudo code and yours - static property is assigned an instance of a class, not just left with type definition. As a side effect, an actual instance of a class is initialized as b.Vector when b is instantiated.
(The pseudo-code is still "broken" - the initialization must go into def init(self), but that's a different story)
The moral of the example, instead of leaving "public Vector position" uninitialized, build initialization of "position" into class Object.
Can someone please tell me whether AddB below will result in less CLR allocations than AddA? I've examined disassembly and it looks to be the case but I'd like confirmation from the Experts please. Can someone Exchange this information with me please?
Cheers,
Charlie.
namespace A
{
struct Vec2
{
public float x;
public float y;
public Vec2 AddA(Vec2 other)
{
Vec2 v = new Vec2(); // Reference variable
v.x = x + other.x;
v.y = y + other.y;
return v;
}
public Vec2 AddB(Vec2 other)
{
Vec2 v; // Value variable
v.x = x + other.x;
v.y = y + other.y;
return v;
}
}
}
If Vec2 is a struct in both examples, by using Vec2 v = new Vec2(); you are not creating a reference to your struct, you are simply creating a new struct on your stack. If you don't use the new keyword, your struct is nevertheless created on the stack and you can initialize each field separately.
In that case, using the new keyword for a struct does't make much sense if your constructor doesn't accept some meaningful parameters to initialize the data in a single line.
If the first method uses a class instead of a struct, then it does create an object for GC to collect, unlike the second method. Since v in AddB is allocated on the stack, it is not collected, the stack is simply popped when your method is finished.
There's no guarantee for anything. Value items are not necessarily stored in the heap.
See The Stack Is An Implementation Detail by Eric Lippert, and the following second part.
The code in your AddA method simply does the same as:
public Vec2 AddA(Vec2 other) {
Vec2 v;
v.x = 0;
v.y = 0;
v.x = x + other.x;
v.y = y + other.y;
return v;
}
The parameterless constructor of a struct returns the default value for the struct, which is a value where all the members are zeroed out. The value is just returned by the call to the constructor, it's never allocated on the heap.
Also, a mutable struct is generally a bad idea. I would implement it like:
struct Vec2 {
public float X { get; private set; }
public float Y { get; private set; }
public Vec2(float x, float y) {
X = x;
Y = y;
}
public Vec2 Add(Vec2 other) {
return new Vec2(X + other.X, Y + other.Y);
}
}
Note that AddA and AddB do not differ in their memory behaviour, both will be allocated on the stack. What does make a difference is that AddB does not call the default constructor for the type and thereby leaves the fields of the Vec2 uninitialized, whereas AddA will zero them out first.
Having said that I'd imagine that the performance hit of zeroing the contents is probably not measurable (if the JIT compiler doesn't even remove it altogether anyway).
To add to the other answers:
Firstly, the code can be improved by using an appropriate constructor and thus omitting the tedious assignments. This isn't really optional: it should be done. Additionally, it would be good to implement such a structure as an immutable type, i.e. making the fields readonly so chances to it aren't at all possible: thus, you would implement pure value semantics.
Secondly, concerning the question of stack vs. heap allocation: I wouldn't bother too much here anyway: the kind of GC used in .NET is specialized to handle lots of such small allocations: your code would be the optimal scenario as far as the .NET GC is concerned. Don't try to avoid it.
This question already has answers here:
Convert int bits to float bits
(8 answers)
Closed 2 years ago.
1.
How can I reinterpret cast a float to an int (or a double to a long)?
float f = 2.0f;
int i = (int)f; // causes conversion
I only want to copy the bit-pattern from f to i. How can this be done?
2.
The implicit and explicit operators in C# uses one intermediate object because the operator function is static
public static implicit operator MyClass(double s)
{
return new MyClass(s);
}
..
..
MyClass m = 2.2; // this code uses 'm' and one intermediate object.
This is fine for reference types, but for value-types which are big (say 20-30 bytes), this will cause unnecessary data copy. Is my understanding correct? And If yes, then why doesn't C# have a non-static conversion operator or user-defined assignment operator so that the conversion/assignment takes place on 'this'? If it does, whats the way to do it?
1: BitConverter (as sixlettervariables) is an option; as is unsafe code (which doesn't need an intermediate buffer):
float f = 2.0f;
int i;
// perform unsafe cast (preserving raw binary)
unsafe
{
float* fRef = &f;
i = *((int*)fRef);
}
Console.WriteLine(i);
// prove same answer long-hand
byte[] raw = BitConverter.GetBytes(f);
int j = BitConverter.ToInt32(raw, 0);
Console.WriteLine(j);
2: note that you should limit the size of structs. I can't find a citation fr it, but the number "16 bytes" (max, as a recommendation) seems to stick in my mind. Above this, consider an immutable reference-type (class).
Barring unsafe code - this is the fastest method I know of to perform a reinterpret:
[StructLayout(LayoutKind.Explicit)]
private struct IntFloat
{
[FieldOffset(0)]
public int IntValue;
[FieldOffset(0)]
public float FloatValue;
}
private static float Foo(float x)
{
var intFloat = new IntFloat { FloatValue = x };
var floatAsInt = intFloat.IntValue;
...
Hope this helps someone.
The BitConverter class can retrieve the bytes for any primitive type, which you can then use to create an int. Another option is Buffer.BlockCopy if you have large amounts of converting to do.
float ff = 2.0f;
int ii = BitConverter.ToInt32(BitConverter.GetBytes(ff), 0);
float[] ff = new float[...];
int[] ii = new int[ff.Length];
Buffer.BlockCopy(ff, 0, ii, 0, ff.Length * 4); // byte-wise copy of ff into ii
No there is no other option given in C#, however, I think that while you're correct in the sense that there will be a copy made, any sufficiently simple implementation will have JIT optimizations done, possibly removing the need for a copy.
This approach, while unsafe, works as a generic solution
static unsafe TDest ReinterpretCast<TSource, TDest>(TSource source)
{
var tr = __makeref(source);
TDest w = default(TDest);
var trw = __makeref(w);
*((IntPtr*)&trw) = *((IntPtr*)&tr);
return __refvalue(trw, TDest);
}
This should be the fastest and cleanest way to do it:
public static class ReinterpretCastExtensions {
public static unsafe float AsFloat( this int n ) => *(float*)&n;
public static unsafe int AsInt( this float n ) => *(int*)&n;
}
public static class MainClass {
public static void Main( string[] args ) {
Console.WriteLine( 1.0f.AsInt() );
Console.WriteLine( 1.AsFloat() );
}
}