Überlegungshilfe benötigt



  • Hi Zusammen

    Ich habe eine Funktion für mein Programm zu schreiben, bei der überprüft werden muss, ob ein erhaltener Wert zwischen einem minWert und einem maxWertliegt.

    Das Problem ist nur, dass kein eindeutiger Wert sondern vielmehr ein Wertbereich erhalten wird.

    Ich bekomme von einem Gerät eine Delay Angabe (ns). Die Besteht aus einer Zahl oder einem Buchstaben. Jede Zahl und jeder Buchstabe definiert einen Wertbereich:

    0 = 0 - 488 (ns)
    1 = 489 - 976 (ns)
    2 = 977 - 1464 (ns)
    3 = 1465 - 1952 (ns)
    4 = 1953 - 2440 (ns)
    5 = 2441 - 2928 (ns)
    6 = 2929 - 3416 (ns)
    7 = 3417 - 3904 (ns)
    8 = 3905 - 4394 (ns)
    9 = 4395 - 4882 (ns)
    A = 4883 - 5371 (ns)
    B = 5372 - 5859 (ns)
    C = 5860 - 6347 (ns)
    D = 6348 - 6836 (ns)
    E = 6834 - 7324 (ns)
    F = 7325 - byte Missed (unendlich)

    Mein Problem ist nun, dass ich nicht darauf komme, wie ich überprüfe ob 0-9 und a-f zwischen dem minWert und dem MaxWert liegt.

    Ich hoffe ihr könnt mir ein paar Denkhilfen geben.

    Vielen Dank 🙂



  • 😕

    Warum mappst du nicht einfach dein Minima und Maxima auf den entsprechenden Wert?

    min = 1000 --> 977  < 1000 < 1464 --> 2
    max = 3000 --> 2929 < 1000 < 3416 --> 6
    

    Du musst jetzt nur noch schauen, ob dein Wert im Bereich 2 bis 6 liegt. Genauer wirst du das so nicht hinbekommen.



  • Du brauchst doch nur mit dem jeweiligen kleinsten und größten Wert des Wertbereiches vergleichen.

    Also bei 0 -> 0 und 488. Was dazwischen liegt ist doch egal.



  • Also ich hab mich für eine Variante entschieden:

    Ich werde ein 2dimensionales Array erstellen, mit 2 Spalten (für upperBound und lowerBound des Werbereichs) und 16 Zeilen für die 16 möglichen Werbereiche.

    nun habe ich leider keine Ahnung wie man so einem 2D-Array Werte zuweist.

    const unsigned int lookUpTable [2][16] = {
    						0,    488;
    						489,    976;
    						977,   1464;
    						1465,   1952;
    						1953,   2440;
    						2441,   2928;	   
    						2929,   3416;
    						3417,   3904;
    						3905,   4394;
    						4395,   4882;
    						4883,   5371;
    						5372,   5859;
    						5860,   6347;
    						6348,   6836;
    						6834,   7324;
    						7325,  60000;
    						};
    

    Danach werde ich überprüfen

    Die Chars 0-9 und A-F, die ich vom gerät bekomme wandle ich in einen unsigned int counter(0-15) um.
    Danach will ich die lowerBound und upperBound aus dem Array generieren.

    lowerBound = lookUpTable[0][counter];
    upperBound = lookUpTable[1][counter];
    

    Dann müsste ich doch nur noch überprüfen ob mein minWert und maxWert in den Werbereich der lookUpTable passt.

    if (
          (lowerBound > minArg)
          &&			
          (upperBound < maxArg)
       )
    {
       return true;
    };
    
    else
    {
       return false;
    };
    

    Ist jetzt alles nur pseudoCode. Aber meint ihr mein vorhaben könnte klappen?
    Und wie erstelle ich das 2D-Array lookUpTable? Die MSDN sagt mir nichts dazu, was ich verstehen würde-.- .

    Ich hoffe ihr könnt mir nocheinmal etwas weiter helfen. Das Projekt sollte bis morgen grösstenteils laufen.

    Danke!



  • So kann man das mit dem Array machen:

    int Array[2][3] = { {1, 2, 3}, {4, 5, 6} };
    oder
    int Array[][] = { {1, 2, 3}, {4, 5, 6} };



  • Hast du die Wertebereiche denn schon bei programmstart?



  • muli schrieb:

    So kann man das mit dem Array machen:

    int Array[2][3] = { {1, 2, 3}, {4, 5, 6} };
    oder
    int Array[][] = { {1, 2, 3}, {4, 5, 6} };

    Danke!

    muli schrieb:

    Hast du die Wertebereiche denn schon bei programmstart?

    Ja, die Wertbereiche, die im Array stehen habe ich von Programmstart an.



  • Danke für die Hilfe. Habs geschafft:

    bool CTransitObserver::IsDelayErrorDetected(int *minDelay, int *maxDelay, char *counterValue)
    		{
    			const unsigned int lookUpTable [2][16] =
    								{
    									{0, 489, 977, 1465, 1953, 2441, 2929, 3417, 3905, 4395, 4883, 5372, 5860, 6348, 6834, 7325},
    									{488 ,976 ,1464 ,1952 ,2440 ,2928 , 3416 ,3904 ,4394 ,4882 ,5371 ,5859 ,6347 ,6836 ,7324 ,60000}
    								};
    
    			unsigned int counter;			
    /*
    			for (unsigned int i = 0; i < 2; i++)
    			{
    				for (unsigned int j = 0; j < 16; j++)
    				{
    					printf("lookUpTable[%d][%d] = %d\n", i, j, lookUpTable[i][j]);
    				}
    			}
    */
    			if( *counterValue == 'A')
    			{
    				counter = 10;
    			}
    
    			else if( *counterValue == 'B')
    			{
    				counter = 11;
    			}
    
    			else if( *counterValue == 'C')
    			{
    				counter = 12;
    			}
    
    			else if( *counterValue == 'D')
    			{
    				counter = 13;
    			}
    
    			else if( *counterValue == 'E')
    			{
    				counter = 14;
    			}
    
    			else if( *counterValue == 'F')
    			{
    				counter = 15;
    			}
    
    			else
    			{
    				counter = atoi(counterValue);
    			};
    
              int lowerBound = lookUpTable[0][counter];
    		  int upperBound = lookUpTable[1][counter];
    
    		   if ( (lowerBound >= *minDelay) && (upperBound <= *maxDelay) )        
    
    		   {
    		     return false;
    		   }
    
    		   else
    		   {
    			   return true;
    		   };
    
    		}
    


  • int hexCharToInt(char c)
    {
    	stringstream str;
    	str << hex << c;
    	int i;
    	str >> i;
    	return i;
    
    	// kürzer, schneller, aber verlässt sich auf ASCII
    	// return c >= 'A' ? c + 10 - 'A' : c - '0';
    }
    
    bool CTransitObserver::IsDelayErrorDetected(int minDelay, int maxDelay, char counterValue)	// Warum Zeiger?
    {
    	assert(minDelay <= maxDelay);
    
    	const int lookupTable [2][16] = {
    		{  0, 489,  977, 1465, 1953, 2441, 2929, 3417, 3905, 4395, 4883, 5372, 5860, 6348, 6834,  7325},
    		{488, 976, 1464, 1952, 2440, 2928, 3416, 3904, 4394, 4882, 5371, 5859, 6347, 6836, 7324, 60000}
        };
    
    	int pos = hexCharToInt(counterValue);
    	return maxDelay > lookupTable[1][pos] || lookupTable[0][pos] > minDelay;	// dein if am Ende ist ziemlich redundant
    }
    

    Edit: Bedingung umgekehrt.



  • switch kennst du aber?

    Auch kann man die Umwandlung wesentlich kürzer lösen:

    int GetCounterValue(char counterValue)
    {
        if (counterValue >= '0' && counterValue <= '9')
            return counterValue - '0';
        counterValue |= 0x20; // toLower
        if (counterValue >= 'a' && counterValue <= 'f')
            return counterValue - 'a' + 10;
        throw ("unsupported counter value");
        return -1;
    }
    


  • Schade das deine Werte nicht regelmässiger liegen:

    min		newMin		max		newMax
    		   -oldMin				 -oldMax
       0				    488		
     489		[b]489[/b]		 976		488
     977		488		1464		488
    1465		488		1952		488
    1953		488		2440		488
    2441		488		2928		488
    2929		488		3416		488
    3417		488		3904		488
    3905		488		4394		[b]490[/b]
    4395		[b]490[/b]		4882		488
    4883		488		5371		[b]489[/b]
    5372		[b]489[/b]		5859		488
    5860		488		6347		488
    6348		488		6836		[b]489[/b]
    6834		[b]486[/b]		7324		488
    7325		[b]491[/b]
    
    bool CTransitObserver::IsDelayErrorDetected(int *minDelay, int *maxDelay, char *counterValue)  //  wofür alles als pointer? Ein pointer ist meist genauso groß (evtl größer) 
                                                                                                   //  wie ein int, sicher größer wie ein char - du sparst also nix. 
                                                                                                   //  Da du nix änderst kannste auch über const nachdenken...
            {
                const unsigned int lookUpTable [2][16] =
                                    {
                                        {0, 489, 977, 1465, 1953, 2441, 2929, 3417, 3905, 4395, 4883, 5372, 5860, 6348, 6834, 7325},
                                        {488 ,976 ,1464 ,1952 ,2440 ,2928 , 3416 ,3904 ,4394 ,4882 ,5371 ,5859 ,6347 ,6836 ,7324 ,60000}
                                    };
    
                unsigned int counter;           
    
                if(0) {} // zu einrückungszwecken :D
                else if( *counterValue == 'A')            {                counter = 10;            }
                else if( *counterValue == 'B')            {                counter = 11;            }
                else if( *counterValue == 'C')            {                counter = 12;            }
                else if( *counterValue == 'D')            {                counter = 13;            }
                else if( *counterValue == 'E')            {                counter = 14;            }
                else if( *counterValue == 'F')            {                counter = 15;            }
                else                                      {                counter = atoi(counterValue);            }; // unnötig, s.u. // atoi s.u. 
    
                // warum nicht:
                switch (*counterValue) 
                {
                  case 'a': // statt toUpper, wenn immer ein Großbuchstabe kommt, egal
                  case 'A': counter=10; break;
                  case 'b':
                  case 'B': counter=11; break;
                  case 'c':
                  case 'C': counter=12; break;
                  case 'd':
                  case 'D': counter=13; break;
                  case 'e':
                  case 'E': counter=14; break;
                  case 'f':
                  case 'F': counter=15; break;
                  default : counter= *countervalue - '0'; // ziehe ASCII Wert von '0' von deinem char ab -> zufällig genau der Zahlenwert den du suchst
                }
    
                int lowerBound = lookUpTable[0][counter];
                int upperBound = lookUpTable[1][counter];
    /*         
               if ( (lowerBound >= *minDelay) && (upperBound <= *maxDelay) )                    
               {
                 return false;
               }
               else
               {
                   return true;
               }; // das hier ist unnötig, da es eine (wegoptimierte) leere Anweisung bedeutet, die ganze else ist so unnötig, mE geschickter wäre s.u.
    */
               if ( (lowerBound < *minDelay) && (upperBound > *maxDelay) )                    
               {
                 return true;
               }
    
               return false; // so hat die Methode IMMER einen Rückkehrwert 'shudder' und das ist evtl eine Warnung weniger.
            }
    

    statt atoi: kann exceptions werfen, guck mal FAQ C++ Einmal Zahl nach String und zurück


Log in to reply