Formattazione matematica "complessa"

6

Nota: per matematica "complessa" intendo un'equazione con molti passaggi coinvolti e un ampio mix di operatori.

Un programmatore dovrebbe conoscere l'ordine in cui gli operatori vengono valutati in un'equazione. Tuttavia può essere un dolore reale guardare un'equazione come:

result = value_1 + value_2 * value_1 + value_3 / value_4 % value_5; 

Un'opzione è di scrivere l'equazione in più passaggi come:

part1 = value_2 * value_1;
part1 += value_1;

part2 = value_4 % value_5;
part2 = value_3 / part2;

result = part1 + part2;

Un'altra opzione è quella di formattare l'equazione originale con una parentesi come:

result = (value_1 + (value_2 * value_1)) + (value_3 / (value_4 % value_5)); 

Quando si tratta di matematica complessa nel codice, come si formatta in genere per massimizzare la leggibilità?

    
posta Glenn Nelson 27.08.2011 - 18:40
fonte

6 risposte

9

Hai ragione - ogni programmatore dovrebbe effettivamente conoscere l'ordine delle operazioni. Se trovi un codice simile al tuo esempio:

result = value_1 + value_2 * value_1 + value_3 / value_4 % value_5;

e non sei sicuro che % abbia la precedenza su / , quindi dovresti assolutamente verificarlo. Ogni programmatore intelligente mantiene almeno un manuale di riferimento affidabile per il linguaggio a scelta a portata di mano. Apprendere (o riapprendere) dettagli come questo è il modo in cui acquisisci esperienza. Se prendi queste opportunità ogni volta che si presentano, scoprirai presto che non devi mai cercare nulla perché lo sai freddo.

Il problema più profondo dell'esempio sopra riportato è che non trasmette l'intento del programmatore. Dovresti essere in grado di leggere quella riga e sapere esattamente cosa fa, ma non c'è modo di sapere se fa ciò che l'autore ha inteso. Anche se tu l'hai scritto, probabilmente non ricorderai esattamente cosa stavi pensando in quel momento. Le variabili ben denominate, lo spazio bianco, le parentesi e le funzioni sono tutti strumenti che è possibile utilizzare per comunicare ciò che si aspetta che il codice faccia e perché. Non ha senso scegliere una di queste opzioni; usa la combinazione che sembra chiara. Invece di:

float w = (m1 + m2 + m3) * a * d;

scrittura:

float totalMass = mass1 + mass2 + mass3;
float force = totalMass * acceleration;
float work = force * displacement;
    
risposta data 27.08.2011 - 19:59
fonte
4

Generalmente, scrivi prima per programmatore, per secondo computer. I compilatori sono un ottimizzatore aggressivo in questi giorni (che fa schifo se si sta tentando di implementare la sommatoria di Kahan), quindi prendetevi la libertà di introdurre variabili temporali che hanno senso. Mescolare più di due [ * , / e % e ** (exp)] in una riga è una cattiva idea, IMO - troppe opportunità per bug e rallenta chi sta cercando di leggere questo codice Se puoi usare FP, hai molti strumenti per controllare la complessità. Vorrei passare attraverso il libro SICP e i video che puoi scaricare tramite torrent.

Proprio come con il normale codice, cerca di evitare la 'formattazione', piuttosto dividi le cose in piccole funzioni e / o variabili temporali che hanno senso. Il libro SICP fa cose complesse, eppure il codice non è mai lungo. Se devi lasciare una lunga fila in occasione, fai solo ciò che ha senso. Ancora una volta, una buona lezione da LISP sarebbe quella di provare ad allineare la parentesi da una linea a quella successiva.

In altre lingue vedi questi esempi:

link

link

La matematica è piuttosto complessa, eppure il codice non lo è. Si tratta di controllare la complessità. Speriamo che questi due esempi possano indirizzarti nella giusta direzione.

    
risposta data 27.08.2011 - 18:50
fonte
2

Uso un mix:

  • Uso intensamente le variabili temporali in particolare per i risultati che vengono utilizzati più volte (questo è un po 'un'ottimizzazione, ma mi tranquillizza)

  • e quando non è ancora chiaro uso la parentesi e gioco con la spaziatura di esso in modo che le priorità siano chiare a colpo d'occhio e roba simile si allinea bene anche quando non tutte le variabili hanno la stessa lunghezza:

    result = (val_1   + value_2*val_1   ) + 
             (value_3 -   val_4%value_5 ); 
    
risposta data 27.08.2011 - 18:54
fonte
1

La tua domanda riguarda la massimizzazione della leggibilità di un'equazione. Suggerisco quanto segue:

A. Inserisci un commento o nella tua documentazione con l'equazione chiaramente indicata nella sua forma matematica originale. I calcoli complessi dovrebbero avere un riferimento al di fuori del codice per consentire alle persone di costruire casi di test e capire da dove vengono le equazioni.

B. La divisione dell'equazione migliora il debug di parti dell'equazione. Consente inoltre di rilevare overflow e problemi simili che potrebbero verificarsi. Ad esempio:

x = ((b * b) + Sqrt (b * b- (4 * a * c))) / -1 * 2 * a può portare a un errore se b * b- (4 * a * c ) è negativo o se a è zero. puoi dividere questa espressione per segnalare ogni caso separatamente con un messaggio di errore diverso.

Se hai diverse espressioni, potrebbe esserci un'espressione secondaria che si ripete in diverse equazioni. Sarebbe più efficiente calcolare quell'espressione separatamente per migliorare le prestazioni.

C. Se dividi un'espressione, assicurati che le espressioni intermedie siano assegnate al tipo di variabile corretto. Ad esempio,

int j = Sqrt (b * b- (4 * a * c)) non è buono.

D. La scrittura di lunghe equazioni non suddivise potrebbe non essere leggibile e rendere le parentesi di rilevamento difficoltl

Quindi ti suggerisco di dividerlo con cura.

    
risposta data 27.08.2011 - 23:52
fonte
0

Penso che la leggibilità non sia un problema così grande in questi casi. L'utilizzo di parentesi è un'opzione. Un'altra cosa che si può fare è usare le istruzioni multi-linea come quella usata da cricchetto. Inoltre, usi l'uso di commenti in tutto il linguaggio di programmazione.

Pertanto, concentrati di più sull'algoritmo e sulle equazioni di calcolo. Il riposo è una cosa di poco conto di cui preoccuparsi

    
risposta data 27.08.2011 - 20:34
fonte
0

In linguaggi simili ad Algol, lo farei in questo modo:

result := value_1 +
          value_2 * value_1 +
          (value_3 / value_4) % value_5;

Nota che presumo una regola di precedenza arbitraria per / su % . Vorrei usare parentesi esplicite in qualsiasi lingua per questo.

Lisp ha linee guida di formattazione standard per tali cose ed è completamente esplicito, ad esempio:

(let ((result (+ value-1
                 (* value-2 value-1)
                 (mod (/ value-3 value-4)
                      value-5))))
  (do-something-with result))
    
risposta data 27.08.2011 - 23:50
fonte

Leggi altre domande sui tag