Ho deciso di creare un nuovo argomento poiché l’ultimo problema non riguarda regole di arrotondamento discutibili, ma regole completamente errate. Pertanto, l’argomento deve essere nella categoria Contribute > Bug. Non è un problema grave, ma comunque un po’ imbarazzante.
Abbiamo avuto un sondaggio pubblico in cui erano stati espressi 106 voti. C’erano 69 voti per “no” e 37 per “sì”. Una semplice divisione dà che 69/106 è circa il 65,09 %. Eppure il sistema indica che il 66 % ha votato per “no” e il 34 % per “sì”. Ecco un’immagine:
Il risultato finale è stato di 72 voti per “no” e 38 per “sì” e il sondaggio è ora chiuso. 72/110 è circa il 65,45 %, che il sistema arrotonda anch’esso al 66 %, quindi puoi vedere il bug in azione su Tappara.co.
Ho cercato di guardare il codice per trovare cosa causa il bug, ma non ci sono riuscito. Ho scoperto che viene chiamata una funzione chiamata evenRound, ma quando ho cercato la sua origine, non l’ho trovata. È solo un’ipotesi, ma forse quella funzione arrotonda il numero all’intero par più vicino?
Il risultato è terribile, è proprio questo il problema.
Grazie per il codice. Non sono riuscito a trovarlo, il che dimostra quanto sia bravo a usare GitHub. Il codice è stato preso da Stack Overflow, dove il suo autore scrive:
Non sono sicuro del livello di precisione di cui hai bisogno, ma quello che farei io è semplicemente aggiungere 1 ai primi n numeri, dove n è il valore arrotondato per eccesso della somma totale delle parti decimali. In questo caso è 3, quindi aggiungerei 1 ai primi 3 elementi e arrotonderei per difetto gli altri. Ovviamente non è una soluzione super precisa, alcuni numeri potrebbero essere arrotondati per eccesso o per difetto quando non dovrebbe, ma funziona abbastanza bene e darà sempre come risultato il 100%.
Non è una sorpresa che con un metodo così drastico si ottengano risultati strani. Suggerirei di essere un po’ più elaborati. Questo post nella stessa discussione ha 72 voti positivi, mentre il post da cui proviene il codice ne ha solo 1.
Ci sono molti modi per farlo, purché non ti preoccupi della dipendenza dai dati decimali originali.
Il primo e forse il metodo più popolare è il Metodo della Maggior Residuo
Che consiste fondamentalmente in:
Arrotondare tutto per difetto
Calcolare la differenza tra la somma e 100
Distribuire la differenza aggiungendo 1 agli elementi in ordine decrescente delle loro parti decimali
…
Penso che questo metodo sarebbe la scelta migliore. È ancora molto semplice e dà risultati molto migliori. Il codice attuale ha bisogno di un paio di righe in più per indicare alla funzione quali numeri devono essere arrotondati per eccesso. C’è però un altro problema da considerare. Da questo post nella stessa discussione:
La risposta molto votata di Varun Vohra minimizza la somma degli errori assoluti ed è molto semplice da implementare. Tuttavia, ci sono casi limite che non gestisce: qual è il risultato dell’arrotondamento di 24,25, 23,25, 27,25, 25,25? Uno di questi deve essere arrotondato per eccesso invece che per difetto.
Il post suggerisce vari metodi per scegliere quale arrotondare per eccesso e quale per difetto, ma non si può mai evitare completamente la scelta arbitraria. Se si vuole raggiungere la perfezione, si potrebbe leggere ulteriormente quel post, ma sarei soddisfatto anche di questa soluzione in questi rari casi speciali.
Probabilmente si sceglie arbitrariamente il primo o l’ultimo della lista.
Spero che questo aiuti. Le mie competenze sarebbero probabilmente sufficienti per apportare io stesso i miglioramenti, se studiassi prima una sintassi di base. Non lo farò ora, ma forse in un secondo momento, se qualcuno non ci darà un’occhiata prima.
Modifica. Ho migliorato leggermente il titolo cambiando la parola “rotto” con “impreciso”. Questa discussione dovrebbe anche essere spostata in Contribute > Feature o unita alla discussione precedente.
It was like classic exercises for beginning programmers. Here is a way to do it, but someone who has more experience and isn’t totally new to JavaScript might find some shortcuts.