Mi esprimo con un esempio.
Se facciamo 17 diviso 10 viene 1, col resto di 7 che è più della metà di 10.
Il 2 come quoziente non ci entrerebbe, ma per poco.
In linguaggio C facendo questa divisione fra variabili dichiarate come int, verrebbe 1 come risultato (sbaglio?).
Se facciamo -17 diviso 10 viene -1, col resto di -7.
In linguaggio C facendo questa divisione fra variabili dichiarate come int, verrebbe -1 come risultato (sbaglio? Non è che in questo caso verrebbe -2?).
Se prendessimo l'abitudine, tutte le volte che facciamo una divisione fra interi, di ritoccare il dividendo, se positivo aggiungendogli la metà del divisore, se negativo sottraendogli la stessa metà del divisore, non è che i calcoli verrebbero meglio arrotondati (mi riferisco in particolare al buon funzionamento dei filtri digitali)?
P.S. Nel caso del primo esempio sopra riportato, ritocchiamo il dividendo 17 aggiungendogli la metà del divisore cioè 5, quindi otteniamo 22 che diviso per 2 fornisce un quoziente pari a 2, approssimato per eccesso ma più vicino al risultato reale di quanto non sia il precedente quoziente pari ad 1.
Divisione fra interi
Moderatori:
PietroBaima,
Ianero
8 messaggi
• Pagina 1 di 1
3
voti
EcoTan ha scritto:Se facciamo -17 diviso 10 viene -1, col resto di -7.
In linguaggio C facendo questa divisione fra variabili dichiarate come int, verrebbe -1 come risultato (sbaglio? Non è che in questo caso verrebbe -2?).
Fa' attenzione: la divisione tra numeri interi in C può dare un risultato diverso dalla divisione intera in altri linguaggi
Contrariamente a quanto sarebbe più prevedibile e matematicamente comodo da utilizzare, i risultati vengono troncati verso lo zero, non arrotondati all'intero inferiore. Quindi certi risultati pari a 0 o negativi possono aver bisogno di essere diminuiti di 1 prima di essere utilizzati in calcoli successivi.
Big fan of ⋮ƎlectroYou! Ausili per disabili e anziani su ⋮ƎlectroYou
Caratteri utili: À È É Ì Ò Ó Ù α β γ δ ε η θ λ μ π ρ σ τ φ ω Ω º ª ² ³ √ ∛ ∜ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ∃ ∄ ∆ ∈ ∉ ± ∓ ∾ ≃ ≈ ≠ ≤ ≥
Caratteri utili: À È É Ì Ò Ó Ù α β γ δ ε η θ λ μ π ρ σ τ φ ω Ω º ª ² ³ √ ∛ ∜ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ∃ ∄ ∆ ∈ ∉ ± ∓ ∾ ≃ ≈ ≠ ≤ ≥
4
voti
Il C utilizza direttamente l'istruzione in linguaggio macchina della CPU selezionata per divide 2 interi (se disponibile) la quale non fa nessun arrotondamento, tronca sempre.
Se serve avere il valore del quoziente e resto la libreria C offre la funzione di libreria "div":
https://linux.die.net/man/3/div
in base al segno del quoziente e al valore del resto è possibile arrotondare all'intero più vicino.
Esiste un metodo veloce per eseguire una divisione tra tipi segnati con arrotondamento all'intero più vicino nei casi con numeratore e denominatore positivi e/o negativi. Nei sorgenti del kernel di Linux nel file "include/linux/kernel.h" esiste la seguente macro (funziona col GCC, ignoro se funziona col altri compilatori):
Se serve avere il valore del quoziente e resto la libreria C offre la funzione di libreria "div":
https://linux.die.net/man/3/div
in base al segno del quoziente e al valore del resto è possibile arrotondare all'intero più vicino.
Esiste un metodo veloce per eseguire una divisione tra tipi segnati con arrotondamento all'intero più vicino nei casi con numeratore e denominatore positivi e/o negativi. Nei sorgenti del kernel di Linux nel file "include/linux/kernel.h" esiste la seguente macro (funziona col GCC, ignoro se funziona col altri compilatori):
- Codice: Seleziona tutto
...
/*
* Divide positive or negative dividend by positive or negative divisor
* and round to closest integer. Result is undefined for negative
* divisors if he dividend variable type is unsigned and for negative
* dividends if the divisor variable type is unsigned.
*/
#define DIV_ROUND_CLOSEST(x, divisor)( \
{ \
typeof(x) __x = x; \
typeof(divisor) __d = divisor; \
(((typeof(x))-1) > 0 || \
((typeof(divisor))-1) > 0 || \
(((__x) > 0) == ((__d) > 0))) ? \
(((__x) + ((__d) / 2)) / (__d)) : \
(((__x) - ((__d) / 2)) / (__d)); \
} \
)
...
0
voti
Infatti quello era un esempio fatto allo scopo di esprimermi.
Nel caso pratico ho un accumulatore long int in cui sommo le letture di un segnale a 10 bit, e dopo ogni 2 letture tolgo dall'accumulatore 1/64 del suo valore (tutto ciò equivale ad amplificare il segnale 127 volte e filtrarlo con una costante di tempo pari a 128 volte l'intervallo fra le letture).
L'intenzione è quella di usare ambedue le tecniche, cioè il dividendo è già abbastanza grande e inoltre arrotondare la divisione per 64 all'intero più vicino.
e qui cade un altro problema: ho l'impressione che non basta dichiarare una variabile long int, poi bisogna specificare (long int) tutte le volte.
Nel caso pratico ho un accumulatore long int in cui sommo le letture di un segnale a 10 bit, e dopo ogni 2 letture tolgo dall'accumulatore 1/64 del suo valore (tutto ciò equivale ad amplificare il segnale 127 volte e filtrarlo con una costante di tempo pari a 128 volte l'intervallo fra le letture).
L'intenzione è quella di usare ambedue le tecniche, cioè il dividendo è già abbastanza grande e inoltre arrotondare la divisione per 64 all'intero più vicino.
e qui cade un altro problema: ho l'impressione che non basta dichiarare una variabile long int, poi bisogna specificare (long int) tutte le volte.
0
voti
EcoTan ha scritto:L'intenzione è quella di usare ambedue le tecniche, cioè il dividendo è già abbastanza grande e inoltre arrotondare la divisione per 64 all'intero più vicino.
Se dividi con potenze di 2 poi non chiamare la divisione ma spostare i bit a destra con operatore ">>", per arrotondare puoi sommare prima dello right shift la meta' del divisore. Molti compilatori, se abilitate le ottimizzazioni, quando si divide per un numero costante potenza di 2 esegue questa ottimizzazione.
Quando si divide bisogna stare molto attenti tra i tipi con e senza segno e evitare di mischiare i tipi, se obbligati fare sempre prima un cast col tipo giusto.
8 messaggi
• Pagina 1 di 1
Chi c’è in linea
Visitano il forum: Nessuno e 8 ospiti

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)





