60 * 1000 = 4294961760 ?

Hai, alle miteinander! Kann mir jemand sagen, warum 60 mal 1000 nicht 60000, sondern 4294961760 sind? Unter "Reference - unsigned long" wird gesagt, "... Unsigned long variables are ... making their range from 0 to 4,294,967,295..., Und 60000 liegen doch innerhalb des Bereiches, oder?

Der Code: unsigned long wert; void setup() { Serial.begin(9600); } void loop() { wert = 60 * 1000; Serial.print("wert: "); Serial.print(wert); Serial.println(""); delay(1000); }

Auf dem Monitor wird als Ergebnis "wert: 4294671760" angegeben. FG, Gerhard

weil ein int nicht 60000 sein kann.

Probier mal 60 * 1000L

P.S. willkommen im Club. Da ist JEDER schon mal drauf reingefallen.

Weil standardmäßig alles ein signed int ist.

Mach es so:

 wert = 60 * 1000UL;

Dann ist 1000 ein unsigned long und es wird auch in unsigned long gerechnet.

gerhardmb: Kann mir jemand sagen, warum 60 mal 1000 nicht 60000, sondern 4294961760 sind?

Du machst beim Rechnen und Zuweisen einen Doppelfehler, deshalb.

Der erste Fehler ist, dass Du beim Rechnen int*int auch wieder einen int Wert bekommst, und als int können positive Zahlen nur bis hoch zu 32767 dargestellt werden. Aber 60000 ist größer als 32767, und daher ergibt das per Zahlenüberlauf eine negative Zahl.

Der zweite Fehler ist dann, dass Du einen negativen int Wert an einen vorzeichenlosen "unsigned long" Wert zuweisen möchtest. Dabei entsteht dann ein Zahlenunterlauf, denn negative Zahlen sind ohne Vorzeichen nicht darstellbar.

Du wolltest ein Ergebnis ausrechnen, das nur als "long" Zahlenwert einen Sinn ergibt. Mit "long" Werten rechnest Du, wenn mindestens einer der beiden an der Rechnung beteiligten Werte "long" ist. int * int ergibt int long * long ergibt long long * int ergibt long int * long ergibt long

Was Du wolltest ist also:

  wert = 60 * 1000L;

In dem Fall 1000L sind die 1000 "long" und es kommt bei der Multiplikation ein "long" heraus (und kein int mit Überlauf).

Hai, da bin ich wieder! Man kann alt werden wie eine Kuh und lernt immer noch was dazu... Jetzt beschaeftige ich mich doch schon eine ganze Weile mit dem Arduino, aber da bin ich echt reingefallen. Das mit dem "L" fand ich ja besonders toll und einfach. Also, normalerweise zuerst Variable mit unsigned long definieren und denen dann diese Werte zuweisen. Ich will einen Blumengiesser bauen, der waehrend unserer Abwesenheit alle 24 oder 48 Stunden mittels Relais eine Wasserpumpe eine Minute lang einschaltet. Was ja mit dem Arduino eigentlich ganz einfach ist, waere da nicht das Problem mit den grossen Zahlen gewesen... Danke, dass ihr mir alles so verstaendlich erklaert habt!

Ich vergess das auch immer wieder (muss am Alter liegen ... ;)).

Aber

unsigned long wert;
wert = 60000;

ist doch korrekt, oder? Ich kann das jetzt gerade nicht ausprobieren, daher muss ich euch bemühen, sorry.

Klaus_ww:
Ich vergess das auch immer wieder (muss am Alter liegen … ;)).

Aber

unsigned long wert;

wert = 60000;




ist doch korrekt, oder?
Ich kann das jetzt gerade nicht ausprobieren, daher muss ich euch bemühen, sorry.

Ja, das geht. (gerade probiert)

Super, danke Dir!

Ich bin auch schon auf diese Weise auf die Nase gefallen. Wenn ich z.b in Delphi sowas mache:

procedure TForm1.Button1Click(Sender: TObject);
var test:byte;
begin
 test:=60 * 1000;
 label1.Caption:=inttostr(test);
end;

Hier meckert schon der compiler, weil das Ergebnis nicht ein ein Byte passt. Wenn ich test als longint definiere passt alles. Also scheint der Delphi Compiler alles am Typ der Variable des Ergebnis fest zu machen. Wenn dieser long ist wird auch alles in long gerechnet, auch wenn ein Produkt zum Beispiel ein int ist.

Dieses Verhalten ist für mich logisch, warum wird dies dann in C so gemacht ? Auch wenn der Ergebnistyp float ist, und ein Produkt ein const Integer (z.b 20) muss man hier 20.0 schreiben.

Das ist der Unterschied zwischen "starker Typisierung" und "schwacher Typisierung": http://de.wikipedia.org/wiki/Starke_Typisierung http://en.wikipedia.org/wiki/Strong_and_weak_typing

C ist schwach typisiert und macht sehr viele Typumwandlungen implizit. C++ wird auf diesen Seiten als stärker typisiert beschrieben, aber das trifft nicht auf die primitiven Datentypen zu, deren Verhalten identisch zu C ist, sondern eher auf Klassen.

Auf dem PC sind solche Fehler auch seltener weil da ein int schon 32 Bytes hat und man meistens mit kleineren Zahlen arbeitet die da rein passen.