• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
vadevaman

Identical math code working differently on C# and C++

17 posts in this topic

So basically I prototyped and developed a math code (for vechicle simulations) in C# and it works perfectly. Now when I port the code to C++

so that I could acces it in a C# environment through a DLL I get some junky behaviour.

 

For example when I run my physics program, the cars driving wheels start accelerating with no reason and it seems like it's mostly caused by rolling resistance, wich by the way works great in C# environment.

This rolling resistance relys on a value that is received from C# environment (from C# float to c++ float)

Another problem is caused by slip ratio and slip angle, the wheels start shaking at low speeds, wich again does not happen in the C# version.

Slip calcs both rely also on values received from C# environment.

 

So might the float conversion from C# to C++ be the case?

 

This stands in my exportFunctions.cpp:

EXPORT_API void Dll_Wheel_SetVelocity(CarWheel* wheel,float lonRoadVelocity,float latRoadVelocity){    wheel->SetVelocity(lonRoadVelocity,latRoadVelocity);}

 

These 2 velocityes are used for the calculations that cause those bug's.  

 

And no I cant share the code, but I can give closer information on how it looks like.

 

Thanks!

 

Edit:

Strange part is that this acceleration issue only occurs in Debug build. If I build the dll as a release, then this issue is vanished, but small friction error still remains. Actually it's only causing the smoke to come out of the tires and tireq squal sound to emmit, but physically it seems to be ok.

But I still suspect that there is some sort of a error somewhere, because debug & release should work identically shouldnt they?

Edited by vadevaman
1

Share this post


Link to post
Share on other sites


I have seen differences between debugger attached and no debugger attached (see here).

 

So after reading this article, as I understand should use double instead in C++ ?

I think float's size is 4 for both C# and C++ and I'm not sure why'd there be a problem when passing a float from C# to C++
but after looking this I got confirmed, that there can be a difference...

 

Anyway thanks for explaining.

0

Share this post


Link to post
Share on other sites

Still fighting with this.
After setting the flotaing point model to /fp:fast in my compiler (msvc2010) it should have now get the exact same float's from the dll but the "flickering" issue still remains, and I suspect its from very small values like 3.21-e8 etc. because when the car is stand still, it still causes minimalistic movements.
Now when I pass them to my DLL something gets messed... So maybe its the way I pass them?

Anyway this is how I pass these speccific values in C# side:
 

namespace Example
[
	public class Wheel
	{		
		public bool loging = true;
		#region Members		
		public IntPtr nativeWheelObject; 
	    #endregion Members

		public Wheel()
		{			
        	this.nativeWheelObject = Sim.Dll_Wheel_Add();
			return;
		}
		
		#region Wrapper methods	
		public void SetVelocity(float lonRoadVelocity,float latRoadVelocity){Sim.Dll_Wheel_SetVelocity(this.nativeWheelObject,lonRoadVelocity,latRoadVelocity);}
		#endregion Wrapper methods
	}
	
	internal class Sim
	{
    	#region PInvokes
		[DllImport(pluginName, CallingConvention=CallingConvention.Cdecl)] public static extern void Dll_Wheel_SetVelocity(IntPtr wheel,float lonRoadVelocity,float latRoadVelocity);
		#endregion PInvokes	
	}		
}

This much code I can show.

0

Share this post


Link to post
Share on other sites

What have you done to debug the issue? Can't you set breakpoints on either side of the .net/native transition to verify the values are the same?

 

Also, what makes you think it's a problem with the interop, rather than with the port of your actual math code?

0

Share this post


Link to post
Share on other sites

I atached the debugger to the program and set the breaking point to where the problem occurs.

c++ lonVel    -0.036019072    float
c# lonVel    -0.029392920    float

As you can see there is a noticable difference. Even after /fp:fast

I also tryed to use the values a double and convert it to float and that didnt work at all. Probably did it wrong anyways.

 

The reason why I think my math port isnt the case, is that the math is rather simple and straight forward and mostly copy/paste from the C# code. And the actual proof that the transfered values are different.
But I guess the math gets a bit messed aswell because I also transfer the TimeStep from C# and use it in the math calcs.

0

Share this post


Link to post
Share on other sites

Specifying /arch:SSE2 might get you a bit closer.

 

However, you shouldn't even expect your C# code to produce identical results on all systems - it will almost certainly differ between x86 and x64 systems for example.

0

Share this post


Link to post
Share on other sites


/arch:SSE2

This didnt help also. Saddly I need these 2 values to be correct, otherwise my math calcs will be broken... This numerical chage doesnt seem huge, but it's really huge for my calcs.

 

Is there any tutorial or a post atleast, on how to pass a small float wit hatleast 90-99% of accuracy from C# environment to c++ environment. And t obe more specific I'm using c# mono.
I dont want to believe that there isnt a way, when there clearly must be a way. Maybe a new custom data type? one that is compatible with C# float's?

 

I'm really worried because this has been a huge setback in my coding for a while. I cant release my products, because of this. My product works ok in C# but I need to port the code to C++ for security reasons, as you know C# can be easily decompiled.

0

Share this post


Link to post
Share on other sites

perhaps you could try to pass it over the boundary as double and cast it back to float on the C side.

 

Just to make sure, you are saying that you have a function:

 

void myCFunction(float value);

 

On the C side.. and if you call it from C# with a value myCFunction(0.2899344f); you receive something different on the C side?

Edited by kunos
0

Share this post


Link to post
Share on other sites

The main problem isn't passing values to and from C#.

 

The way the two different languages transform calculations into assembly is different. Most notably in both cases some of the intermediate calculations may be done at a higher precision than you've specified. There will also be small differences in the results from library functions like sin(). In addition C# depending on which CPU it's run on may generate different assembly when it's JITted, so the C# result almost certainly won't be identical between different PCs.

 

If you want reproducibility integer maths is much easier to do that with.

 

C++ can also be easily disassembled. It's impossible to keep any calculation you do on a computer secret from the owner of that computer. If this is for something like license key validation you should switch to something based on public key cryptography.

1

Share this post


Link to post
Share on other sites

C++ can also be easily disassembled.

 

 

 

yes but no... in C# you can get back to the names of the functions and variables. Surely in C++ you will still read the names of the function but the code inside will be much harder to reverse engineering. I understand where the OP is coming from because I went through exactly the same decisions.

 

I wonder if the OP tested the new .NET native.. that might solve the problem without need to leave C# land.

0

Share this post


Link to post
Share on other sites

perhaps you could try to pass it over the boundary as double and cast it back to float on the C side.

 

Well I tryed it like this:
C#

public void SetVelocity(float lonRoadVelocity,float latRoadVelocity){Sim.Dll_Wheel_SetVelocity(this.nativeWheelObject,lonRoadVelocity,latRoadVelocity);}

  C++

    EXPORT_API void Dll_Wheel_SetVelocity(CarWheel* wheel,double lonRoadVelocity,double latRoadVelocity){    wheel->SetVelocity((float)lonRoadVelocity,(float)latRoadVelocity);}

And the result was, that nothing was transfered... the values stayed 0.

 

And about the question, to be specific I'm not using C, I'm using C++ (the languages should be different)

And currently I'm passing them the way as you described.

 

 

Also after some deeper debuging I found out that strangely the difference happens in my wheel class...

void CarWheel::SetVelocity(float lonVel,float latVel)
{
	lonRoadVelocity = lonVel;
	latRoadVelocity = latVel;
}

"lonRoadVelocity = lonVel" is actually "lonRoadVelocity != lonVel"

So its internal??? C++ float mismatched with C++ float? I'm confused....

 

Edit:

The above "internal" was a false alarm I guess.

Because I removed the "SetVelocity" method and pass the values directly, wheel->lonRoadVelocity = lonRoadVelocity;

and there still is difference, I think I was just confused,

 

Debug Results:

		latRoadVelocity	-0.15862428	float
		lonRoadVelocity	-0.036250707	float
+		wheel	0x1b75e120 {brake={...} tire={...} suspension={...} ...}	CarWheel *
		wheel->latRoadVelocity	-0.15102120	float
		wheel->lonRoadVelocity	-0.036250707	float

After /arch:SSE2 and /fp:fast the difference actually is notably smaller. In this case for some reason it only occurs in "latRoadVelocity".

"lonRoadVelocity" seems to be 1:1 o nevery frame I debuged, so I'm getting closer

Edited by vadevaman
0

Share this post


Link to post
Share on other sites

hm weird.. in C# if the signature of the function requires a double, it shouldn't compile if you pass a float to it... did you change the signature of the DLL_Set_velocity on the C# side?

0

Share this post


Link to post
Share on other sites

I just noticed there is a inacuracy issue with floats in C++, flaots in C# (atleast in mono) stay the same and are pretty good to work with

but in C++ a float of 0.0091 is actually 0.0091000004 ... that 4 in the end can make a math calc result in wrong calculations.

 

While "lonRoadVelocity" seems to pass normally now, I dont understnd why the "latRoadVelocity" has a offset, when I pass it the same way...
 

 

 

 


in C# if the signature of the function requires a double

Sounds right indeed. Maybe it's because I'm using mono?
Anyway when passing a float instead of double, the values stay 0, but when I cast the float to double in C# and pass the double ... well saddly nothing changes.

 

But like I mentioned, the "lonRoadVelocity" seems to now be 1:1, but for some strange reason the "latRoadVelocity" has an offset.

 

Edit:

Here are some debug results in a single frame:

In aplication (C#)

debugcsharp.jpg

and results in msvc2010 debug:

w0
lonRoadVelocity    0.027051473    float
latRoadVelocity    0.13362961    float
wheel->lonRoadVelocity    0.027051473    float
wheel->latRoadVelocity    0.14100081    float
w1
lonRoadVelocity    -0.034490682    float
latRoadVelocity    0.13361663    float
wheel->lonRoadVelocity    -0.034490682    float
wheel->latRoadVelocity    0.14098407    float
w2
lonRoadVelocity    0.026764294    float
latRoadVelocity    0.030822765    float
wheel->lonRoadVelocity    0.026764294    float
wheel->latRoadVelocity    0.043717053    float        
w3
lonRoadVelocity    -0.034203805    float
latRoadVelocity    0.030835744    float
wheel->lonRoadVelocity    -0.034203805    float
wheel->latRoadVelocity    0.043733794    float
Edited by vadevaman
0

Share this post


Link to post
Share on other sites

So the parameters are fine. Now where might that breakpoint be ?

 

Also: 0.0091000004 is within float precision of 0.0091. It's probably also just a difference with the debug view, not the actual value.

1

Share this post


Link to post
Share on other sites

So the parameters are fine.

At w2 lateral speeds:

actual value 0.043717053

"equal" value 0.030822765
0.043717053 - 0.030822765 = 0.012894288
this is 34.59% of difference how come this be fine?

Breakpoint is at my exportFunctions.cpp

 

 

Edit: I just noticed something, the latRoadVelocity seem to be used form the last frame... I'll have a deeper look on my main class

 

Edit2: This is odd, seems like the values are passed quite accurate now, but the calculations are still messed and the wheel's cant find theyr correct slip's...
Is there a possibility that the math function (wich is quite simple) may produce absolutely different results, causing the math to break?

Edited by vadevaman
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0