CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    Weird behavior in ctor

    Hello all,

    Ive got a weird bug somewhere and have run out of clues as to how to track it down. I was adding some math routines to a library and when I started testing them, I got a strange behavior and not sure what it could be for EX:

    Code:
    MiniDec^ Sqr(MiniDec^ _val){
           
           .
           .
           .
         while(_iterations<_runs){
    
                _current=_current+(_val/_current);     <------this is how the alg was originally
                _iterations+=1;
    
           }
    
    
    the alg now looks like this
    
    
          while(_iterations<_runs){
    
                    _temp=gcnew MiniDec(_current);   <-----on the first run through _current=1
                    _temp=_val/_temp;
                    _temp=_temp+_current;
                    _current=_temp;
                    _iterations+=1;
    
           }
    where I point out thats how the alg was originally, when it jumps into the division routine the values of val and current have changed (and it jumps straight from there to the division), so I changed it to see if I could figure out what was causing it.
    As I pointed out above on the first run through _current=1 (this is not how it will run when finished, I just wanted it in a consistent state for debugging). And I know its value is 1 because I checked it in the ide before it went to the MiniDec ctor

    the division routine:

    Code:
    static MiniDec^ operator/(MiniDec^ _val1, MiniDec^ _val2){  <-----values are not what was sent
    
          MiniDec^ _retval=gcnew MiniDec();
    
          .
          .
          .
    
          return _retval;
    
    }
    MiniDec ctor:

    Code:
    MiniDec(MiniDec^ _val):MiniBI(){   <-------at this point _val does not equal one
    
          .
          .
          .
    
    }
    when stepping through the code I get to the part of the alg that creates a new instance of MiniDec and I checked the value in the ide before stepping into the ctor, but somehow, when it gets to creating a new instance the value has changed to some apparantly random number (and I am checking it as soon as it gets to the ctor and again after it executes the very first instruction)

    This is running in a single threaded app for testing, no other apps using the library are running, everything seems to work fine till it gets to this algorithm then I have this problem about half way into the alg. The full listing for it is:

    Code:
    
    MiniDec^ Sqr(MiniDec _value){
    
    	bool neg=false;
    	MiniDec^ power=gcnew MiniDec();
    	MiniDec^ temp=gcnew MiniDec(_value);
    	MiniDec^ half=gcnew MiniDec("1");
    
                    int _iterations=0;
                    int _runs=1000;
    
    	half=half/2;
    
    	if(temp<0){
    
    		temp=temp*-1;
    		neg=true;
    
    	}
    
    	while(temp>1){
    
    		temp=(temp-(temp%2))/2;
    		power=power+1;
    
    	}
    
    	temp=gcnew MiniDec(_value);
    
    	if(power==0){
    
    		power=gcnew MiniDec("1");
    
    	}
    
    	MiniDec^ retval=gcnew MiniDec();
    	MiniDec^ last=gcnew MiniDec();
    	MiniDec^ current=gcnew MiniDec();
    	MiniDec^ _retval=gcnew MiniDec();
    
    	retval=power;
    	current=power;
    	power=gcnew MiniDec();   <------ everything appears to work to this point
    
    	while(_iterations<_runs){
    
                              _current=_current+(_val/_current);    <---but screws up here
                              _iterations+=1;
    
    
    	}
    
    	_retval=current;
    
    	return _retval;
    }
    where I put it screws up there I mean when it goes into the division part, the values that make it to the division routine are not the same as the values that were sent to it.

    everything else tested so far either worked or had a small error which I fixed, but I cant figure out where this error is.

    Thanks in advance

  2. #2
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Weird behavior in ctor

    Could it be you ran into a problem with reference semantics here? Having the following line inside the loop in your first code snippet looks really suspicious to me:

    Code:
                    _temp=gcnew MiniDec(_current);
    You need to be aware that this will create a new and separate MiniDec object each time.

    Could you turn MiniDec into a value class? I think this should be possible as long as it doesn't contain any members that are refernce types themselves.

    It looks like you're working on some decimal math or bignum library here, and both the Decimal and BigInteger of the .NET framework are value types as well.

    If that doesn't help, I'd probably need a compilable and runnable sample that I can examine in the debugger.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  3. #3
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    Re: Weird behavior in ctor

    I just put that snippet in there when trying to debug it to find out what was happening. I actually have it working now, however, I believe something is still wrong. I have the alg pretty much back the way it was originally:

    Code:
    MyMath::MiniDec^ MyMath::Math::Math::Sqr(MiniDec _value){
    
    	bool _neg=false;
    
    	MiniDec^ _power=gcnew MiniDec();
    	MiniDec^ _temp=gcnew MiniDec(_value);
    	MiniDec^ _half=gcnew MiniDec("10");
    	MiniDec^ _retval=gcnew MiniDec();
    	MiniDec^ _current=gcnew MiniDec("10");
    	MiniDec^ _last=gcnew MiniDec();
    	MiniDec^ _ahalf=gcnew MiniDec();
    	MiniDec^ _ret=gcnew MiniDec();
    	MiniDec^ _la=gcnew MiniDec();
    
    	_ahalf=_ahalf+1;
    	_ahalf=_ahalf/2;
    
    	_half=_half/2;
    
    	if(_temp<0){
    
    		_neg=true;
    		_temp=_temp*-1;
    
    	}
    
    	_current=MiniDec::Pow(_current,(((_temp->ToString())->Length-((_temp->ToString())->Length%2))/2));
    
    	while(_power<d_Sqr_Iterations){
    
    		_last=_retval;
    		_retval=_current+(_temp/_current);
    		_retval=_retval*_ahalf;
    		_current=_retval;
    		_power=_power+1;
    
    		if(_last==_retval){
    
    			break;
    
    		}
    
    	}
    
    	return _current;
    
    }
    I am getting correct results from the alg now (I know I have extra variables in there, they are there trying to debug it). but when I am in the alg, right at the beggining when I am creating the variables, about half the variables NEVER show data, and when I try looking at them in the ide it says they are out of scope. for ex:

    Code:
    MyMath::MiniDec^ MyMath::Math::Math::Sqr(MiniDec _value){
    
    	bool _neg=false;
    
    	MiniDec^ _power=gcnew MiniDec();
    	MiniDec^ _temp=gcnew MiniDec(_value);
    	MiniDec^ _half=gcnew MiniDec("10");
    	MiniDec^ _retval=gcnew MiniDec();
    	MiniDec^ _current=gcnew MiniDec("10");   <--when break in right here
    	MiniDec^ _last=gcnew MiniDec();
    	MiniDec^ _ahalf=gcnew MiniDec();
    	MiniDec^ _ret=gcnew MiniDec();
    	MiniDec^ _la=gcnew MiniDec();
    
    	_ahalf=_ahalf+1;
    	_ahalf=_ahalf/2;
         .
         .
         .
    }

    when I break in where I have it marked, I can try looking at the variable _retval (right above it) and the debugger says it is out of scope. same with _half, _last, _ret, and _la. And the debugger says that they are out of scope no matter where in the alg I try to look at them, however, they must be storing the data correctly becuase _last & _retval are integral in the main loop and it is returning correct answers even though the debugger says they are allways out of scope and never have any data.

    I am not sure what got it to working this far though. I commented out the entire library, then uncommented and compiled it one class at a time (some 4 hours of work there).

    Ive played with the .net 4 big number classes (and yes mine is a set of bignumber class I have biginitger, bigdecimal, bigfraction and a good start on the complex versions of the decimal and fraction ones), but I have my collection setup with everything I need plus all my math classes are allready built around my version.

    As far as turning it into a value class, I would love to but I do have a few reference members, the only one of which that I cant do without yet is the java biginteger which is what actually holds the number in the class. The only functionality in the java biginteger I use is the basic math (+-*/) I had to write all my own algorithms for exponentiation, modular reduction and such because after the number approached about 100 decimal digits java seemed to get lost. Unfortunately I havent been able to write my own base class to hold the number that works as fast as the java one.

    I hated messing with it since I had it all working, but it had grown to the point I needed to break the library down into seperate modules again. Each time ive broken it down, ive spent longer and longer getting it working again.

    Anyways, even though it works, I dont trust the fact that I cant pull the info from the variables in the debugger like I should. It just feels unstable, but again, I am kind of lost as to what I should be looking at for a possible problem.

  4. #4
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Weird behavior in ctor

    I, too, have already observed the effect of the debugger showing variables as out of scope that IMO definitely shouldn't be, but I didn't bother much: If I really wanted to know their values I simply printed them out using Debug::WriteLine(). Not really convenient but it works and I don't really need to do it that often. I never found out under which circumstances that happens and have no idea which one of my projects I could use to reproduce it now. Perhaps someone reads the thread who knows what that's about...

    Quote Originally Posted by AKRichard View Post
    As far as turning it into a value class, I would love to but I do have a few reference members, the only one of which that I cant do without yet is the java biginteger which is what actually holds the number in the class. The only functionality in the java biginteger I use is the basic math (+-*/) I had to write all my own algorithms for exponentiation, modular reduction and such because after the number approached about 100 decimal digits java seemed to get lost. Unfortunately I havent been able to write my own base class to hold the number that works as fast as the java one.
    Wow, daring! I never saw anyone do interop with Java from .NET, but then again, it's possible from native C++, so why not from C++/CLI? But as you're already using an external implementation of the basic math functionality anyway, isn't replacing the Java class with .NET's BigInteger an option? As I already mentioned, this is a value type and so would allow you to turn yours into a value type too. Even if the .NET class is a bit slower than the one from Java, that might be compensated by eliminating the interop overhead.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  5. #5
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    Re: Weird behavior in ctor

    Yes it would be an option to switch to the .net 4 version, but as I mentioned, I had started messing with .nets latest, but not enough to convince myself the library would benefit from it yet. It really upsets me that I havent been able to create an implementation myself to compare with java. My basic math operations in c++ are about 1/3 the speed of java, though my implementation of the more advanced math functions outperforms java once the numbers reach about 75 decimal digits or so. I have eeven been trying to build it in assembly, but am having trouble getting that code to interface with the .net code. Guess I shouldve focused on native c++ when I decided to teach myself.

    I, too, have already observed the effect of the debugger showing variables as out of scope that IMO definitely shouldn't be, but I didn't bother much
    So it might not be my code that is the problem? That would be a first lol, I ALLWAYS assume my code is the problem.

  6. #6
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Weird behavior in ctor

    Quote Originally Posted by AKRichard View Post
    I have eeven been trying to build it in assembly, but am having trouble getting that code to interface with the .net code.
    Here's a small thread about interfacing between C++/CLI and assembly: http://www.codeguru.com/forum/showthread.php?t=501723. It might not be quite instructive, but perhaps it can be used as a starting point for initial experiments.

    So it might not be my code that is the problem?
    IMO probably not.

    That would be a first lol, I ALLWAYS assume my code is the problem.
    You certainly know that this is generally recommended, and that for good reasons. In most cases it actually is your (or my) code, yet not in all cases.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  7. #7
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    Re: Weird behavior in ctor

    Well I know this is off subject, but since you seem to know something about it...First I actually wrote the routines in and compiled them in an assembler because I became very frustrated trying to get managed code to accept assembler, but Id rather have it in with the c++ code. Anyways, when I was trying it I was trying the #pragma managed(push,off) inside of the routine instead of right before (probably why I was having such a hard time). My question is, how does that affect the declaration? in managed c++ I would have for EX:

    Code:
    MiniBI^ operator+(MiniBI^ _val1, MiniBI^ _val2){
    
          MiniBI^ _retval=gcnew MiniBI();
          int carry=0;
    
         for(int x=0;x<_val1->thearray->Length;x++){
    
                long temp=_val1->thearray[x]+_val2->thearray[x]+carry;
                _retval->thearray[x]=temp%(max+1);
                temp>>16;
                carry=temp;
    
         }
    
         return _retval;
    
    }
    dont laugh to hard thats not actual code in use just something off the top of my head to give an idea of what Im talking about.

    Now, if I were to change the above to include the #pragma managed(push,off) directive, that effectively makes the compiler expect native c++ code right? So what types of changes would I have to make to the above so I could actually work with the array in the MiniBI^ references from assembly? From everything Ive read, managed arrays are a completely different creature from native arrays, not to mention that native c++ doesnt even understand reference semantics right?

    as Ive said before I chose managed c++ when teaching myself, now I really wish I had started with native c++.

  8. #8
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Weird behavior in ctor

    I have no concrete idea of what's inside your MiniBI class, but while we're talking about arrays, here's a thread with an interop layer that demonstrates passing a vector of strings from managed to native code: http://www.codeguru.com/forum/showthread.php?t=511781. (If you want to skip the preliminaries: The interop code is in post #19.) The method Test21::Song::Play() is the relevant one.

    Note that this is the only half-way notable piece of interop code I've ever written, so there's some chance something in there is suboptimal in some way or plain wrong. At least it behaved as expected...

    The source container on the .NET side in that code is a cliext::vector that I really don't recommend for general use, but as the method processes the items one by one it would work with pretty much any .NET container.

    If you ignore the part of the code that converts the managed strings to native ones, the method decays to something nearby trivial. I don't know much about the memory layout of managed arrays, but if the items in your array are value types with a memory layout matching that of a native type, I suppose there even is a one-line solution. But since I'm not really an interop expert either, I'd need to research that first. (IIRC there's a Marshal class with static methods somewhere.)

    Quote Originally Posted by AKRichard View Post
    [...] native c++ doesnt even understand reference semantics right?
    Well, it does, just not those of .NET. The .NET tracking handles actually have more similarities with native pointers than with native references, yet they don't have an equivalent in the native world. That's why I was concerned about using the term "reference semantics" above at all: If that term really has an "official" meaning in .NET, that meaning is different from its meaning in native C++.

    as Ive said before I chose managed c++ when teaching myself, now I really wish I had started with native c++.
    Though native C++ and C++/CLI have similar names, look similar and in fact have a bunch of commonalities, they're pretty different languages. In particular, native C++ is much more low-level. As it looks like you know how to write assembly language, which usually implies one likes low-level stuff, yes, chances are native C++ would have been preferable. But what's stopping you from learning that now?
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  9. #9
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    Re: Weird behavior in ctor

    Quote Originally Posted by Eri523 View Post
    As it looks like you know how to write assembly language, which usually implies one likes low-level stuff, yes, chances are native C++ would have been preferable. But what's stopping you from learning that now?
    I wouldnt say I know very much about assembly language, I did some (very little) programming in the old 286 days, but till now, I havent done any since. All I can say about assembly is I know enough to be dangerous (to myself that is haha). The only language I can say with any confidence that I am pretty good at would be vb. I do plan teaching myself native c++, noow that Ive built my confidence up in managed c++ Ill probably start, especialy since I allready have most of the assembly routines built I want to use.

    Thanks for the info, Ill see you next time I get stuck

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured