Go Down

Topic: [risolto] errore calcolo matematico (cast) (Read 186 times) previous topic - next topic

frankz

May 05, 2019, 07:27 pm Last Edit: May 07, 2019, 06:48 am by frankz
Con ide di arduino il seguente codice, il valore di delta0 e delta3 sono sbagliat visualizzanoli con serial monitor, dov'è l'errore?
Code: [Select]
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {
  int y1=148;
  int y2=332;
 int delta3=-(184*320);
int  delta0= (184*320); //
int  delta1=((320-0)*(148-240))-((240-240)*(0-0));
int  ka=(float) delta1/delta0;
int  x0= 0+ka*(320-0);
int  y0=  y1+ka*(y2-y1);

   Serial.println("*****************");
 
      Serial.print("delta0: ");
   Serial.println(delta0);
    Serial.print("delta3: ");
   Serial.println(delta3);
    Serial.print("ka: ");
   Serial.println(ka);
    Serial.print("x0: ");
   Serial.println(x0);
    Serial.print("y0: ");
   Serial.println(y0);
   Serial.println("*****************");


}

gpb01

Hai idea di quale sia il range di valori che un "int" può contenere? ... prova a guardare nel reference e capirai da solo il tuo errore. :)

Guglielmo
Search is Your friend ... or I am Your enemy !

frankz

Dal seguente esempio più generico ho capito devo fare dei cast, ma non so come.
ho provato ma non funzionano.
Code: [Select]
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {
  int y1=148;
  int y2=332;
  int y3=240;
  int y4=240;
  int x1=0;
  int x2=320;
  int x3=0;
  int x4=320;
long  delta0=(y4-y3)*(x2-x1)-(x4-x3)*(y2-y1);
long  delta1=(x4-x3)*(y1-y3)-(y4-y3)*(x1-x3);
float  ka= delta1 / delta0;
int  x0= x1+ka*(x2-x1);
int  y0=  y1+ka*(y2-y1);

   Serial.println("*****************");
 
      Serial.print("delta0: ");
      Serial.println(delta0);
      Serial.print("delta1: ");
      Serial.println(delta1);
      Serial.print("ka: ");
      Serial.println(ka);
      Serial.print("x0: ");
      Serial.println(x0);
      Serial.print("y0: ");
      Serial.println(y0);
   Serial.println("*****************");


}


i risultati calcolati "a mano" sono:
delta0=-58880
delta1=-29440
ka=0.5
x0=160 deve essere intero corrisponde al valore della posizione di un pixel
y0=240 deve essere intero corrisponde al valore della posizione di un pixel

gpb01

#3
May 06, 2019, 06:59 am Last Edit: May 06, 2019, 07:03 am by gpb01
Devi coniderare varie cose ...

1. per semplicità, dato che i tuoi calcoli con "int" producono in realtà risultati di tipo "long", onde evitare troncamenti, usa ovunque il tipo "long".

2. quando calcoli "ka", se non gli dici che deve fare le operazioni in "float", il compilatore fa la divisione tra i due "long" (divisione che, nel tuo caso, da ZERO) e poi converte in float, per cui devi fare un "cast" dei due "long" così che tutte le operazioni vengano fatte in "float" (ottenendo un risultato corretto).

3. ricorda comunque, in generale e per il futuro, che i "float", su Arduino, sono a 32bit e quindi non hanno più di 6/7 cifre significative in tutto ... ovvero, sono soggetti ad arrotondamenti.

In pratica:

Code: [Select]
void setup() {
   // put your setup code here, to run once:
   Serial.begin(115200);

   long y1 = 148;
   long y2 = 332;
   long y3 = 240;
   long y4 = 240;
   long x1 = 0;
   long x2 = 320;
   long x3 = 0;
   long x4 = 320;
   long  delta0 = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
   long  delta1 = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
   float  ka = (float)delta1 / (float)delta0;
   long  x0 = x1 + ka * (x2 - x1);
   long  y0 =  y1 + ka * (y2 - y1);

   Serial.println("*****************");

   Serial.print("delta0: ");
   Serial.println(delta0);
   Serial.print("delta1: ");
   Serial.println(delta1);
   Serial.print("ka: ");
   Serial.println(ka);
   Serial.print("x0: ");
   Serial.println(x0);
   Serial.print("y0: ");
   Serial.println(y0);
   Serial.println("*****************");
}

void loop() {
   // put your main code here, to run repeatedly:
}

Guglielmo
Search is Your friend ... or I am Your enemy !

frankz

Grazie.
Venendo dalla programmazione PHP e HTML che non sembravano cosi rigidi come limiti.
Dovrò leggere un buon semplice libro sul C o C++, se puoi darmi un consiglio... Ti ringrazio.

gpb01

#5
May 06, 2019, 10:42 am Last Edit: May 06, 2019, 10:42 am by gpb01
La "Bibbia" del 'C' è sicuramnete il "Kernighan e Ritchie", ma NON è molto didattico, è più un manuale di "riferimento" ... certamente da AVERE in biblioteca :)

Comunque, una attenta lettura del "reference" di Arduino, già ti da una buona idea delle varie cose ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

maubarzi

Venendo dalla programmazione PHP e HTML che non sembravano cosi rigidi come limiti.
Per HTML intendi javascript suppongo.
Sono linguaggi non tipizzati (cioè puoi sommare tranquillamente pere con mele e ottenere, si spera, quello che ti serve) in cui tutte le conversioni sono fatte implicitamente secondo logiche prestabilite dal linguaggio.
Devi approfondire un po' la tipizzazione forte e le varie conversioni.
I tipi devono essere giusti a monte per non perdere informazioni e non a valle, cioè non devi castare il risultato, ma gli operatori iniziali.
Nel tuo caso, se moltiplichi 2 int il risultato resta un int con overflow se il prodotto è troppo grande, fatto il prodotto ormai è troppo tardi per rimediare.
Questo in linea di principio mooolto generale.
Per il resto ti serve un po' di studio e approfondimento, non è complicao una vola entrati nel meccanismo.
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

frankz


Go Up