Pages: [1]   Go Down
Author Topic: Double Modulo  (Read 997 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo erstmals

und zwar ich bekomme jedesmal diese Fehlermeldung :

error: invalid operands of types 'double' and 'int' to binary 'operator%'

wenn ich versuche mit einer Double Zahl Modulo berechne.


Hier ist ein Beispielcode:


Code:
double x = 100000;
int y = 3;
int s = 0;

void setup(){
  Serial.begin(9600);
 
}


void loop(){
 
 s = x % y;
 Serial.println(s);
 
 
 
}

x muss eine Double Zahl bleiben
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5150
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Modulo ist der Rest einer Ganzzahlen-Division. Die Operation ist auf Gleitkommazahlen nicht definiert, weil dort eine Division immer durchgeführt werden kann (Ausnahme: 0) und keinen Rest übrig lässt. Wenn Du mit Ganzzahlen rechnen willst, solltest Du auch Ganzzahlen als Typ verwenden, also Integer (in welcher Ausprägung auch immer).

Was willst Du genau erreichen? Wieso muss x ein double sein?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Da x sonst eine Variable ist und zum Teil die Zahl größer ist als Integer zulässt
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 146
Posts: 3039
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

x muss eine Double Zahl bleiben

Und die Modulo-Operation ist nur für Ganzzahlenwerte definiert.

Z.B.:
 s = round(x) % y;

Da x sonst eine Variable ist und zum Teil die Zahl größer ist als Integer zulässt

Ganzzahl-Datentypen größer als int existieren.

Die Typen "long" http://arduino.cc/en/Reference/Long
und "unsigned long" http://arduino.cc/en/Reference/UnsignedLong
stehen sogar in der Arduino-Dokumentation drin.

Tatsächlich kannst Du sogar 64-Bit Integers vom Typ "long long" verwenden, damit sind sogar Zahlen bis hoch zu 9.223.372.036.854.775.807, also mit 19 signifikanten Dezimalstellen, bis auf die letzte Stelle genau darstellbar.
« Last Edit: November 27, 2012, 05:55:34 am by jurs » Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5150
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Da x sonst eine Variable ist und zum Teil die Zahl größer ist als Integer zulässt

Wenn die Zahl grösser als 24bit wird (ca. 16Mio), wird sie in einem double (ist auf dem Arduino gleich float und somit 32bit) nicht mehr genau dargestellt, sondern nur angenähert und somit ist das Resultat einer Modulo-Operation sowieso nicht sicher korrekt. Und Zahlen bis 32bit kannst Du mit einem unsigned long noch als Integer darstellen, wie Dimivo bereits ausführte.
Logged

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 266
Posts: 21655
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tatsächlich kannst Du sogar 64-Bit Integers vom Typ "long long" verwenden, damit sind sogar Zahlen bis hoch zu 9.223.372.036.854.775.807, also mit 19 signifikanten Dezimalstellen, bis auf die letzte Stelle genau darstellbar.
Dieses Dateiformat gibt es aber in der Arduino Programmierumgebung nicht.
Grüße Uwe
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 146
Posts: 3039
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dieses Dateiformat gibt es aber in der Arduino Programmierumgebung nicht.

Welche Uralt-Version der Arduino Programmierumgebung meinst Du?

Aktuelle Versionen haben selbstverständlich den Datentyp "long long" drin und können damit umgehen.

Das einzige was bei Arduiono fehlt, aber das ist bei anderen AVR-GCC Programmierumgebungen genau dasselbe, ist eine Möglichkeit, um LongLong-Variablen in einen String umzuwandeln. Z.B. wenn man die Zahl in voller Länge ausgeben möchte. Also um einen "long long" 64-bit Integerwert in einen String umzuwandeln, da ist man auf sich selbst gestellt.

Schwierig ist das allerdings auch nicht. Einen Sketch mit einer selbst implementierten "longlong2char" (funktioniert in der Form aber nur für positive Zahlen) Funktion hänge ich mal dran.

Code:
void setup(){
  Serial.begin(9600);
}


void longlong2char(char *buf,byte buflen,long long number)
{
 byte count=0;
 memset (buf,0,buflen);
 while (number>10)
 {
   buf[count]=(number % 10) +'0';
   number= number / 10;
   count++;
 }
 buf[count]=number+'0';
 strrev(buf);
}

long long x = 9223372000000000000LL;
char longstrbuf[20];

void loop()
{
 x++;
 longlong2char(longstrbuf,sizeof(longstrbuf),x);
 Serial.println(longstrbuf);
 delay(1000);
}

Es würde mich wirklich wundern, wenn jemand noch eine Uralt-Arduino Umgebung hat, die "long long" 64-Bit Ganzzahlen nicht kompiliert.

« Last Edit: November 27, 2012, 08:27:27 am by jurs » Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm, stimmt.
Code:
void setup() {
 long long x=0LL;
 Serial.begin(9600);
 Serial.println(sizeof(x));
 
}

void loop() {}
Das liefert den WErt "8", also 64bit. Wusste ich aber bisher auch nicht. Leider wird der Datentyp in der Referenz nicht erwähnt und ich vermute, das wird intern per Software abgebildet, wir float auch. Aber gut zu wissen.
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 146
Posts: 3039
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Das liefert den WErt "8", also 64bit. Wusste ich aber bisher auch nicht. Leider wird der Datentyp in der Referenz nicht erwähnt und ich vermute, das wird intern per Software abgebildet, wir float auch. Aber gut zu wissen.

Ja natürlich in Software.
So wie bei allen Nicht-8-Bit-Datentypen auf einem 8-Bit-Controller.

Und die Programme werden ganz schön groß, wenn man diese 64-Bit Datentypen in seinem Programm verwendet und damit rechnet, da kommt ein ganz ordentlicher Fußabdruck an Datencode zusammen.

Übrigens ist in meiner oben geposteten Konvertierungsroutine von "long long" in "char array" noch ein herber Fehler drin, die Abbruchbedingung in der while-Schleife stimmt nicht.

Statt (fehlerhaft):
while (number>10)
Setze (korrigiert):
while (number>=10)

Wer auch eine Routine zum Formatieren von "langen negativen Zahlen" benötigt und Probleme beim Coden des Minuszeichens hat, ggf. einfach fragen, dann poste ich noch was dazu.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 78
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Streng genommen hat die Standard-C-Mathematikbibliothek eine Modulo-Funktion für floating point Zahlen, aber nicht über den %-Operator, sondern mit der fmod(double,double)-Funktion. Wie gut sie von avr-libc und Arduino implementiert ist weiß ich jedoch nicht. Aber selbst wenn, bleibt das bereits von anderen erwähnte Problem der Präzision von floating point.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

danke mit long funktioniert es.
Logged

Pages: [1]   Go Up
Jump to: