J'ai un compteur sur un champ de 16 bits incrémenté / décrémenté au fil du temps par un périphérique matériel.
J'empone périodiquement sa valeur pour résumer la différence dans un champ de 32bits.
Mon problème est de détecter le débordement / sous-fluide du champ de 16 bits lors de l'informatique de la différence. P>
Prenons l'exemple:
À l'échantillon N-1, la valeur de comptoir VN-1 est 65530.
En tant qu'échantillon N, la valeur de comptoir vn est 4.
Le compteur a été incrémenté par 10. Mais la différence (vn-vn-1), sera quelque chose comme 65529 (pas sûr de la valeur exacte). P>
Le seul moyen que j'ai trouvé pour détecter ce débordement est Pour comparer la valeur de différence à une valeur fixe supérieure à l'incrément maximal (je choisis 10000).
Connaissez-vous une solution pour gérer ce débordement sans comparer à cette valeur subjective? P>
Voici un exemple de code: P>
static sint32 overallCount = 0; sint32 diff; static sint16 previousValue = 0; sint16 currentValue; currentValue = sampleValue(); diff = ((sint32) currentValue) - previousValue; if(diff > 10000) { diff -= 65536; } else if ((-diff) > 10000) { diff += 65536; } overallCount += diff;
4 Réponses :
Voici quelques idées pour vous: P>
À propos de votre premier point, l'addition est déjà effectuée sur un champ 32 bits. J'ai besoin de garder un compteur mondial qui ne déborde pas. Je vais considérer vos 2 autres idées.
Je pensais que vous avez dit que votre valeur actuelle débordait-elle? Je suggère que quelque chose comme int32 temp = courcentvalue & 0xFFFF; TEMP + = NewValue; Si (TEMP> 65535) Overflow! sinon CurrentValue = (int16) TEMP; code>
Vous pouvez essayer d'utiliser un Filtre Kalman pour détecter le débordement. P>
Je cherche une solution simple qui ne nécessite pas beaucoup de frais généraux car je cours avec des ressources de traitement limitées. Mais merci pour cette idée!
Ma réponse précédente Vous avez eu des erreurs donc je me suis réécrit, mais l'idée est la même, utilisez les types non signés correctement.
rendre courantvalue et précédentValuer les entiers non signés de la taille choisie (E.G. uint16_T). Puis simplement soustrayez-les. Étant donné que la différence sera implicitement promue à int code> si
int code> est un type plus grand que
uint16_t code>, vous devez lancer ou convertir implicitement le résultat. Retour à
uint16_t code>. Donc: P>
static uint16_t previousValue;
uint16_t currentValue = sampleValue();
uint16_t diff = currentValue - previousValue;
Pourriez-vous expliquer votre déclaration? Faire le calcul dans SIGNÉ ou non signé ne transférera que le débordement du 0/65535 au -32768/32768.
Désolé, j'espère que c'est mieux maintenant.
Je n'ai jamais vu cette conversion de type implicite de non signée en signée! CurrentValue - PrécédentValue sera toujours fait comme non signé et en cas de débordement de courant actuel, le diff n'est pas la différence effective
Dans C, Tout arithmétique est promu au moins à int code> b>. C'est pourquoi vous voyez des résultats erronés si vous ne moulez pas ou que vous vous attachez à un
uint16_t code>.
OK compris! Vous avez raison :) La seule chose que je dois faire est de lancer la diffusée dans Sint16 pour la somme dans le champ 32 bits pour gérer les sous-flux.
Une autre option consiste à garder une trace du nombre de débordements. Utilisation UINT16_T pour les valeurs,
if (currentValue < previousValue) overflows++;
Cela ne fonctionne pas car le comptoir va dans les deux sens (incrément et décrément). Donc, l'actualisation peut être moins la valeur précédente sans déborder.