Záludnosti typování čísel

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
Odpovědět
ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Záludnosti typování čísel

Příspěvek od ondraN » 04 kvě 2020, 16:07

Proč typovat čísla?? Ve většině případů to funguje automaticky, ale neplatí to vždycky :mrgreen:
Tady je jedna fakt záludná chyba, která mě stála něco času :?

Kód: Vybrat vše

const unsigned long MaxGPSWait=6000*10;

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

void loop() {
  Serial.println(MaxGPSWait);
  delay(1000);

}
Výsledek?
4294961760
4294961760
4294961760
4294961760

A správné řešení???

Kód: Vybrat vše

const unsigned long MaxGPSWait=6000L*10L;

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

void loop() {
  Serial.println(MaxGPSWait);
  delay(1000);

}
Tak tohle je už lepší :P
60000
60000
60000
60000

KamilV
Příspěvky: 479
Registrován: 03 dub 2018, 15:27
Reputation: 0
Bydliště: Olomouc

Re: Záludnosti typování čísel

Příspěvek od KamilV » 04 kvě 2020, 16:31

Ano, protože ten signed int "přeteče".
Obdobně se mi docela často stává, že přehlédnu toto:

Kód: Vybrat vše

byte i;
for(i = 5; i >= 0; i--) {
    Serial.println(i);
}
Serial.println("x");
Člověk by čekal:

Kód: Vybrat vše

5
4
3
2
1
0
x
že? :mrgreen:

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: Záludnosti typování čísel

Příspěvek od ondraN » 04 kvě 2020, 16:37

To podtečení byte do max. hodnoty bych chápal, ale tady je zajímavé že vadí ta 10
Výraz

Kód: Vybrat vše

const unsigned long MaxGPSWait=6000*10L;
už má správnou hodnotu.

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: Záludnosti typování čísel

Příspěvek od ondraN » 04 kvě 2020, 16:51

Nejspíše je to protože si obě čísla dá jako signed int, to při vynásobení přeteče, a teprve pak to retypuje na unsigned long.
Správná hodnota vyjde pokud libovolné číslo je typovane jako long.
Žil jsem v domění, že pokud je vlevo vyšší typ, tak automatické přetypování to bere na vědomí. Takže nebere.

mart-in
Příspěvky: 16
Registrován: 27 kvě 2020, 21:43
Reputation: 0

Re: Záludnosti typování čísel

Příspěvek od mart-in » 28 kvě 2020, 12:58

ondraN píše:
04 kvě 2020, 16:37
To podtečení byte do max. hodnoty bych chápal, ale tady je zajímavé že vadí ta 10
Výraz

Kód: Vybrat vše

const unsigned long MaxGPSWait=6000*10L;
už má správnou hodnotu.
To asi záleží na překladači, když si to zkusíš zkompilovat v GCC na PC, tak je průchozí i zápis bez "L".

Kód: Vybrat vše

const unsigned long MaxGPSWait=6000*10;
Výsledek 60 000.

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: Záludnosti typování čísel

Příspěvek od ondraN » 28 kvě 2020, 18:49

Už jsem se poučil, že je to tak, že si kompilátor (nebo alespoň ty, s nimiž pracuji), typují číslo podle jeho hodnoty a ne podle levé strany. U kompilátoru pro 8bitové MCu je int 16bitů a číslo (6000) se vejde do signovaného intu. Pak se ale vynásobí a výsledek se se zase uloží do signovaného intu, takže přeteče na nějaký nesmysl. ten se následně přetypuje na nesignovaný long a hausnumero je tady :mrgreen: U PC je int 32bitový, takže tam to funguje díky tomu. Kdybych dal ale číslo takové, co by po vynásobení přeteklo ten 32 bitový int, byla by to ta samá situace.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 14 hostů