Problem mit negativer Zahl

Hallo,

ich würde mir gerne das korrekte Ergebnis folgender "Aufgabe" anzeigen lassen. Leider bekomme ich als Ausgabe lediglich eine null, obwohl ich eigentlich einen Wert um die 600 erwarte. Was mache ich falsch?

Gruß Chris

int additionswert = 0;
unsigned long timeindex[12];

void setup()
{
  timeindex[0] = 3000;
  
  Serial.begin(9600);
  delay(6000);
  additionswert = additionswert + (((millis() - timeindex[0]) - 6000) / -5);

  Serial.println(additionswert);  // 0 + ((6000 - 3000) - 6000) / -5) = 600
}

void loop()
{
}

So Gehts:

int additionswert = 0;
unsigned long timeindex[12];

void setup()
{
  timeindex[0] = 3000;
  
  Serial.begin(9600);
  delay(6000);
  int a = (millis()-timeindex[0]-6000/-5);
  additionswert += a;

  Serial.println(additionswert);  // 0 + ((6000 - 3000) - 6000) / -5) = 600
}

void loop()
{
}

Gruß Eberhard

Kommen aber trotzdem keine 600 raus.

Gruß Chris

Chris72622: Was mache ich falsch?

Du gehest davon aus, dass Du mit stets positiven "unsigned long" Zahlen in den negativen Bereich hinein rechnen kannst und dann ein richtiges Ergebnis herausbekommst. Tatsächlich bekommst Du bei einer Subtraktion in den Minusbereich einen Underflow mit Zahlen, die etliche Milliarden darstellen, und das ergibt dann wohl einen Overflow bei der abschließenden Division.

Rechnen mit negativen Zahlen funktioniert nur mit vorzeichenbehafteten Zahlen, z.B.

additionswert = additionswert + ((long)millis() - (long)timeindex[0] - 6000) / -5;

Aber Vorsicht: (long)millis() wird nach ca. 25 Tagen negativ, wenn Dein Programm so lange ohne Reset läuft.

was man machen könnte: einen eigenen Sekunden-Zeit-Zähler deklarieren plus einen Zähler-Overhead (oder wie immer man das nennen will ) und die millis immer div 1000 rechnen. Dann auch den millis overflow nach 25 Tagen im Auge behalten, overhead inkrementieren und manuell dann den Sekunden-overhead dazuaddieren.

Du hattest Recht. Offensichtlich vertragen sich Addition und Division nicht in einer Zeile. Ich habe es schon häufiger gehabt, dass Zwischenergebnisse erzeugt werden müssen.

So gehts aber wirklich:

int additionswert = 0;
unsigned long timeindex[12];

void setup()
{
  timeindex[0] = 3000;
  
  Serial.begin(9600);
  delay(6000);

  additionswert = additionswert + (millis() - timeindex[0]-6000);
  additionswert = additionswert/-5;
  Serial.println(additionswert);  // 0 + ((6000 - 3000) - 6000) / -5) = 600
}

void loop()
{
}

Gruß Eberhard

Edit: Dass das Ergebnis hier passt, ist wohl mehr oder weniger Zufall. Jurs und HaWe haben die einzig richtige Erklärung.

jurs: Aber Vorsicht: (long)millis() wird nach ca. 25 Tagen negativ, wenn Dein Programm so lange ohne Reset läuft.

So lange wird es in keinem Fall laufen müssen.

Vielen Dank- jetzt klappts!

Gruß Chris