Ich verstehe nicht, was bei folgendem Programm passiert. Da wo
random(10)-5 negativ wird, werden grosse positive Werte ausgegeben. Bei
allen auskommentierten Versionen ist das nicht der Fall. Für mich sind
die grossen positiven Werte nicht erklärbar, zumal es bei anderen
Schreibweisen keine Probleme gibt. Das ganze läuft auf nem teensy 36.
Hier das Programm zusammen mit der Ausgabe (weiter unten). 1 | long RANDOM(int d){
| 2 | return random(d) ;
| 3 | }
| 4 |
| 5 | void setup() {
| 6 | Serial.begin(115200);
| 7 | delay(2000) ;
| 8 | Serial.print("Hello World 1\n");
| 9 | randomSeed(1);
| 10 |
| 11 | for(int k=0 ; k<20 ; k++){
| 12 |
| 13 | double x=random(10)-5 ;
| 14 |
| 15 | //double x=RANDOM(10)-5 ;
| 16 | //double x=(int)random(10)-5 ;
| 17 | //int i=random(10)-5 ; double x=(double)i ;
| 18 | //long i=random(10)-5 ; double x=(double)i ;
| 19 | //double x=(long)random(10)-5 ;
| 20 | Serial.printf("%5d %15.5f \n",k,x) ;
| 21 | }
| 22 | }
| 23 |
| 24 | void loop(){
| 25 | }
| 26 |
| 27 | /*
| 28 | Hello World 1
| 29 | 0 2.00000
| 30 | 1 4.00000
| 31 | 2 4294967294.00000
| 32 | 3 3.00000
| 33 | 4 4294967291.00000
| 34 | 5 4294967293.00000
| 35 | 6 4294967295.00000
| 36 | 7 3.00000
| 37 | 8 4294967294.00000
| 38 | */
|
Was liefert random() für ein Wert zurück: double, (long) (unsigned) int?
Und was passiert bei 1 | double x = random(10) - 5.0lf;
|
double x=random(10)-5.0f ;
liefert die richtigen (negativen) Werte. 5.0lf ist als Typ nicht
bekannt.
random liefert laut Dokumentation einen long Wert.
Der Doku nach ist der Returntyp von random() ein long.
Damit sollte das Ergebnis von random(10)-5 (long - int) auch ein long
sein, und damit auch negative Werte darstellen können, die dann nach
float umgewandelt werden.
Oliver
Mangels Arduino und mangels Serial.printf lässt sich dein Code bei mir
nicht ausprobieren. Ein Test in Tinkercad mit folgendem Code 1 | ...
| 2 | double x=random(10)-5 ;
| 3 |
| 4 | Serial.print(k);
| 5 | Serial.print(", ");
| 6 | Serial.print(x) ;
| 7 | Serial.print('\n');
| 8 | ...
|
liefert aber das gewünschte Ergebnis:
1 | Hello World 1
| 2 | 0, 2.00
| 3 | 1, 4.00
| 4 | 2, -2.00
| 5 | 3, 3.00
| 6 | 4, -5.00
| 7 | 5, -3.00
| 8 | 6, -1.00
| 9 | 7, 3.00
| 10 | 8, -2.00
| 11 | 9, 4.00
| 12 | 10, -5.00
| 13 | 11, 0.00
| 14 | 12, -3.00
| 15 | 13, -3.00
| 16 | 14, 2.00
| 17 | 15, -2.00
| 18 | 16, 2.00
| 19 | 17, 4.00
| 20 | 18, -5.00
| 21 | 19, -3.00
|
Woher kommt denn deine printf-Funktion?
Oliver
Martin O. schrieb:
> double x=random(10)-5.0f ;
>
> liefert die richtigen (negativen) Werte. 5.0lf ist als Typ nicht
> bekannt.
lf wäre 'long float', also double, aber wenn's mit f funktioniert...
> random liefert laut Dokumentation einen long Wert.
Dann sieht's danach aus, dass die Konvertierung von long nach double
nicht funktioniert für negative Zahlen.
1 | long test = -1;
| 2 | printf("%f", (double) test);
|
müsste dann auch das falsche Ergebnis geben.
Martin O. schrieb:
> random liefert laut Dokumentation einen long Wert.
Das kann sein. In den Quellen (teensy3/WProgram.h) steht aber (mehrfach
überladen) was anderes:
1 | int32_t random(void);
| 2 | uint32_t random(uint32_t howbig);
| 3 | int32_t random(int32_t howsmall, int32_t howbig);
|
Unser Kandidat geht also mit einem uint32_t um.
... übrigens ist das zwar Arduino-mäßig nicht verkehrt, aber
Kinetis-mäßig Murks: der Kinetis hat nämlich einen (ziemlich guten)
Hardware-RNG:
https://forum.pjrc.com/threads/48745-Teensy-3-6-Random-Number-Generator
@Oliver S.: Ja, so sollte es meinem Verständnis nach auch sein. Ist es
aber nicht. Auf einem Arduino Uno tritt der Effekt nicht auf.
Markus F. schrieb:
> In den Quellen (teensy3/WProgram.h) steht aber (mehrfach
> überladen) was anderes:
> int32_t random(void);
> uint32_t random(uint32_t howbig);
> int32_t random(int32_t howsmall, int32_t howbig);
>
> Unser Kandidat geht also mit einem uint32_t um.
Tja, und da wundert sich einige, warum das Zeugs keiner ernst nimmt.
Oliver
Mit dem uint32_t wirds verständlich. Dass random einen long liefert habe
ich der Arduino Doku entnommen, denn angeblich ist Teensy zum Arduino
kompatibel. Stimmt wohl nicht so ganz.
Besten Dank!
Martin O. schrieb:
> Dass random einen long liefert ...
Martin O. schrieb:
> Stimmt wohl nicht so ganz.
Stimmt wohl. Aber nur, wenn man's ohne (oder mit zwei) Parameter(n)
aufruft.
Dann kommt ein int32_t zurück und das ist beim Kinetis identisch zu
long.
Eric B. schrieb:
> Martin O. schrieb:
>> double x=random(10)-5.0f ;
>>
>> liefert die richtigen (negativen) Werte. 5.0lf ist als Typ nicht
>> bekannt.
>
> lf wäre 'long float', also double, aber wenn's mit f funktioniert...
Man braucht ja nun auch nicht unbedingt einen double, um einen
ganzzahligen Wert im Bereich -5 bis 5 darzustellen.
Rolf M. schrieb:
> Man braucht ja nun auch nicht unbedingt einen double, um einen
> ganzzahligen Wert im Bereich -5 bis 5 darzustellen.
Stimmt, aber der TO wollte das so. Er schrieb ja:
> double x=random(10)-5 ;
Das ist schon klar. Ich bezog mich auf den Satz:
Eric B. schrieb:
> lf wäre 'long float', also double, aber wenn's mit f funktioniert...
5.0f funktioniert bei diesem Wertebereich natürlich. Das lf bringt da
keinen Vorteil.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|