Come mi fa girare i polsi C#...

...quando mi restituisce un Int32 dalla divisione fra due Int32!

Public Shared Function TestDiv() As Double
     Dim a As Int32 = 12
     Dim b As Int32 = 10
     Return a / b
End Function

restituisce (giustamente IMHO) un Double = 1,2

public static Double TestDiv()
{
     Int32 a = 12;
     Int32 b = 10;
     return a / b;
}

restituisce comunque un Double ma uguale a 1, che nella crapa di un informatico potrebbe anche avere un suo perchè, ma nel mondo reale è un'eresia!

Print | posted @ venerdì 11 maggio 2007 11.26

Comments on this entry:

Gravatar # re: Come mi fa girare i polsi C#...
by Lorenzo Barbieri at 11/05/2007 11.36

Beh... lui prende il tipo del primo argomento se la memoria non inganna... e quindi... un bel casl in testa su a dovrebbe bastare...
  
Gravatar # re: Come mi fa girare i polsi C#...
by Mario Duzioni at 11/05/2007 11.46

Si si, ma è proprio il concetto che mi fa incavolare!
  
Gravatar # re: Come mi fa girare i polsi C#...
by Gian Maria at 11/05/2007 12.13

Ammetto che quando iniziai ad utilizzare C/C++ rimasi anche io stupito da questo comportamento, che però è il più logico. Il processore infatti possiede istruzioni diverse per divisione intera e floating point, anche in termini di performance molto differenti. Il VB restituisce un double dalla divisione intera, questo significa che usa sempre la divisione FloatingPoint, mentre in C# più correttamente se dividi due interi utilizzi la divisione intera, e con un cast gli puoi dire di utilizzare quella floating point, quindi è più flessibile perchè puoi scegliere quella che preferisci.

Dopo un po ci si fa l'abitudine.

Alk.
  
Gravatar # re: Come mi fa girare i polsi C#...
by Mario Duzioni at 11/05/2007 15.30

Si ma quella che è l'implementazione interna non può essere una "giustificazione" per un "calcolo errato" restituito al chiamante (perchè alla fin fine di questo si tratta)!

Potrei essere un pelo più clemente se ti restituisse quantomeno un int (almeno, per quanto comunque sbagliato, ti fa capire che prende solo la parte intera), ma ti restituisce addirittura il risultato in formato double che è "cannato"!

Tradotto significa: "Ah, mi fai dividere due interi? Ma guarda che il risultato è potenzialmente un double; allora ti istanzio e restituisco un double."
Si, però col risultato cannato! :-) E allora cosa mi restituisce a fare un double???

Ahh, 'ste "macchinette"...
  
Gravatar # re: Come mi fa girare i polsi C#...
by Nicolò Carandini at 11/05/2007 21.59

Io quoto Gian Maria, e non capisto il tuo commento:
dato che, giusto o sbagliato che sia (intendo come scelta filosofica di chi ha definito il comportamento di c#), la divisione ti restituisce un intero, il fatto che te la restituisca come Double dipende solo dal fatto che hai TU definito Double la TestDiv, quindi (poiche un intero è a pieno titolo un Double, se vuoi usare una gabbia da pachidermi per tenerci un topolino, beh, non è certo c# che te lo impedisce, mentre il contrario si!
Prova a definire come Int32 una funzione che restituisce un valore double e guarda che ti fa.

Esempio:
--------------------------------------------
static Int32 TryThis(Double x, Double y)
{
return x / y;
}

Messaggio di errore del compilatore:
----------------------------------------------
Impossibile convertire in modo implicito il tipo 'double' in 'int'. È presente una conversione esplicita. Probabile cast mancante.
  
Gravatar # re: Come mi fa girare i polsi C#...
by Simone Busoli at 11/05/2007 22.41

Credo sia una delle prime frasi che io abbia mai sentito dire sul C, "la divisione fra due interi è un intero". Niente di strano.
  
Gravatar # re: Come mi fa girare i polsi C#...
by Simone Busoli at 12/05/2007 1.03

Rileggo il post e mi chiedo se non ti manchi qualche concetto di base... però mi stupisce un po' la risposta di Lorenzo... Non è che prende il tipo del primo argomento (operando, magari?), se sono due interi il risultato è un intero, altrimenti è un numero con la virgola.

Poi non capisco cosa ci sia di strano nel fatto che ti ritorni un valore double che contiene 1. Il risultato dell'operazione restituisce un intero, che viene implicitamente convertito a double quando viene ritornato al chiamante poichè al tipo System.Int32 è consentita la conversione implicita in System.Double senza perdita di dati.

http://msdn2.microsoft.com/en-us/library/y5b434w4.aspx
  
Gravatar # re: Come mi fa girare i polsi C#...
by Gian MAria at 12/05/2007 9.27

La divisione ritorna appunto un intero, chiaramente tu hai definito il valore di ritorno come double, per cui lui educatamente te lo riconverte in double.
Capisco per chi proviene da linguaggio come il basic o il pascal sia strano, ma a mio avviso è la cosa più normale. Io al contrario odio il VB che ha due operatori di divisione
/ Divisione floating point
\ divisione intera
prova infatti a fare
Console.WriteLine(10 / 3)
Console.WriteLine(10 \ 3)
e ti accorgi che la seconda versione ti torna 3, ovvero chiama la divisione intera.
Il VB è un linguaggio nato per permettere a tutti di sviluppare per cui per default ti fa la divisione float, che sicuramente è il risultato piu "intuitivo" a scapito delle performance e della correttezza semantica, poi crea l'operatore \ per la divisione intera, a mio avviso un po una porcata :D
Il C#, C++ e anche il java (mi pare xche java non lo conosco bene) invece fanno la cosa più corretta, decidono l'operatore da utilizzare in base al tipo di dato.

ahhhh...la type safety :D

Alk.
  
Gravatar # re: Come mi fa girare i polsi C#...
by Mario Duzioni at 14/05/2007 11.23

X Simone (1)

Niente di strano su "la divisione fra due interi è un intero"???? :-D
Intenderai che non è strano per un informatico che sta scrivendo codice C... Se vai al supermercato e compri 2 etti di prosciutto a 23 Euro al chilo lo paghi 4 Euro o 4, 60? :-)

Te la vedi la faccia del salumiere? "Scusi signor salumiere ma devo contraddirla: la divisione fra due interi è un intero!"

E' proprio Gian Maria stesso nell'ultimo post che mi aiuta ad esprimere il concetto: VB ti fa by "default" (diciamo così) la divisione "naturale". Se tu vuoi la divisione "elettronica" (più che informatica, visto che si basa su considerazioni riguardanti le capacità del processore) lui ti chiede di ESPLICITARLO con la \.

Voi ragionate CPU-oriented, io ragiono RealWorld-oriented. :-)

X Simone (2)

Ti tolgo ogni dubbio: a me mancheranno sicuramente svariati concetti di base e non :-), ma in questo caso non credo centri un gran che...
Io sto facendo un commento personale su un implementazione che reputo "troppo implicita".

X Nicolò, Simone e GianMaria

Premesso che probabilmente mi sono spiegato veramente MALE nel commento a Gian Maria...
La frase "Tradotto significa: "Ah, mi fai dividere due interi? Ma guarda che il risultato è potenzialmente un double; allora ti istanzio e restituisco un double.""
non è l'implementazione reale di C# ma è quello che ti "arriva", quello che ti sembra che faccia se conosci l'implementazione reale.

Vero, nell'esempio sono io a fargli fare una conversione implicita, ma il concetto era di far vedere che lo faccio "senza che ci sia un evidenza di questa cosa".
Il discorso si riconduce a quello di base ed infatti nella controparte VB non ci sono topolini o pachidermi (attenzione a "mettere" un topolino in un pachiderma, potrebbe reagire DOPPIAMENTE male :-D) ed anzi di contro c'è un risultato IMHO "inequivocabile". :-)

Cmq se non dovessi essere riuscito ancora a far capire cosa intendevo mi scuso e mi arrendo! :-D

Scherzi e battute a parte, grazie a tutti per il feedback. :-)
  
Gravatar # re: Come mi fa girare i polsi C#...
by Mario Duzioni at 14/05/2007 11.26

Uff...

Errata corrige: "quello che ti sembra che faccia se conosci l'implementazione reale."

doveva essere "quello che ti sembra che faccia se NON conosci l'implementazione reale."

Ho bisogno di una vacanza... :-)
  
Comments have been closed on this topic.