Stránka 1 z 1
Záludnosti typování čísel
Napsal: 04 kvě 2020, 16:07
od ondraN
Proč typovat čísla?? Ve většině případů to funguje automaticky, ale neplatí to vždycky
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ší
60000
60000
60000
60000
Re: Záludnosti typování čísel
Napsal: 04 kvě 2020, 16:31
od KamilV
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:
že?

Re: Záludnosti typování čísel
Napsal: 04 kvě 2020, 16:37
od ondraN
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.
Re: Záludnosti typování čísel
Napsal: 04 kvě 2020, 16:51
od ondraN
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.
Re: Záludnosti typování čísel
Napsal: 28 kvě 2020, 12:58
od mart-in
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.
Re: Záludnosti typování čísel
Napsal: 28 kvě 2020, 18:49
od ondraN
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

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.