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 :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

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:

Kód: Vybrat vše

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

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 :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.