Newsgroup: it.comp.lang.javascript
Titolo: Sottrazioni - Stavolta una domanda la faccio io. :)

Come dico sempre, siamo tutti qui per imparare, e non si smette mai di
farlo. :)
Per puro caso, ieri mi sono trovato a sottrarre in Javascript due numeri.
Ed ho avuto un risultato un po', a mio avviso, particolare.. Magari mi
sbaglio, e se cosi' fosse prego chiunque di illuminarmi.
Ho semplicemente sottratto il numero 4 dal numero 4.52.
Indovinate cosa mi aspettavo di ottenere? :)
0.52, ovviamente.
Invece mi sono ritrovato ad avere 0.5199999999999996....
Essendo a casa, la prima cosa che ho pensato e' stata "Vai, stai a vedere
che ho un Athlon con l'FPU bacata..."
Ovviamente non e' molto realistica come cosa. :D Cmq, facendo lo stesso
calcolo in VBScript, il risultato torna esatto.
In ogni caso per correttezza ho provato su piu' macchine (Win98, Win2k) con
piu' browser (IE 5.01, NS 4.x, NS 6.0).
Sempre lo stesso risultato.
Allora ho fatto un po' di sano testing.. Roba da due minuti, intendiamoci,
ma ha dato risultati interessanti.
Scrivendo le seguenti righe di codice, i risultati ottenuti lo sapete quali
sono?
a) document.write(3.5-3);
b) document.write(3.52-3);
c) document.write(4.5-4);
d) document.write(4.52-4);
a) 0.5
b) 0.52
c) 0.5
d) 0.5199999999999996
C'e' qualcuno in questo NG che sa' spiegarmi come mai Javascript (perche' di
Javascript si tratta) ha un comportamento del genere?
Per ricavare da 4.52 il numero 0.52 ci sono un sacco di modi (basta passarlo
in stringa e manipolarla come tale) ma al di la' del fatto che sono piu'
"lunghi" (li si tratta di una sottrazione, nel caso di stringhe invece, o
faccio una substr tramite l'indexOf del punto e trasformo tutto in float,
oppure uso una regExp e trasformo il risultato in float..), non mi spiegano
cmq tale anomalia.
Aspetto interventi da chiunque... ^___^

 cerchero` un'altra donna dentro ai sogni di Tarzan...

 Nota come sia il '57' ad essere arrotondato a '6'.
Notato.
Ma ancora devo spiegarmelo questo comportamento.
Any Idea?

 >
Stò provando in tutte le maniere dal tuo primo post.........
nel modo normale risulta sempre sbagliato , pure moltiplicando etc..etc...
l'unico modo per ottenere quel risultato esatto con javascript ( esempio
preso da manuale che peraltro non enuncia nessun problema relativo)....
spiegazioni???????
<script language="JavaScript"><!--
function round(number,X) {
    X = (!X ? 2 : X);
    return Math.round(number*Math.pow(10,X))/Math.pow(10,X);
}
document.write(round(4.52-4)+'<BR>');
//--></script>
____________________
andreotta fabiano
WebMªster ATI POWER s.n.c.
andr...@atipower.it
http://www.atipower.it
http://www.afdsoftware.freeweb.org
____________________
Collaboratore: 
http://www.jsdir.com
____________________
*¢ L'unica certezza nella vita è che tutto è relativo (per fortuna)¢*

     return Math.round(number*Math.pow(10,X))/Math.pow(10,X);
Come ho detto in precedenza, non e' l'unico modo. Molto piu' semplicemente
posso passare da float a stringa e poi di nuovo a float.
Il post non era incentrato sul fatto che ho problemi a ricavare un 0.52 da
4.52, tutt'altro.
La questione e' su ben altro livello... :/


Avevo capito! :-)), intendevo solo dire che ho spulciato i manuali e lì nin
ce stà nada .........
e finora nnon ho trovato niente neanche su internet........
Ciao!


 ce stà nada .........
Anche perche' e' una cosa ben strana.
Mi sembra strano, pero', che sia una sorta di  "bug non documentato".
Possibile che nessuno, da quando c'e' il Javascript, si sia mai messo a fare
sottrazioni in float?

 sottrazioni in float?
boh!
Conoscevi questa di IE???
x=4.52-4
alert(x.toFixed(2))
alert(x.toPrecision(2))
quel precision. lì.che microsoft se lo sia inventato a caso??
cosa dici??....


 cosa dici??....
Seconda di poi, io voglio fare una semplice sottrazione, non voglio fare una
divisione particolare e settare un determinato livello di precisione.
A me non interessa avere una precisione di 2.. o che..  Non e' una
divisione, e' una banalissima sottrazione! Voglio semplicemente il risultato
corretto, con *tutti* i numeri (2,3,4..quanti sono) dalla virgola in poi
(cosa ottibile con un semplice indexOf, come abbiamo detto ma non e' questo
il punto).
Capito cosa intendo? Anche la funzione che hai postato prima, era una
funzione di relativa alla precisione del risultato.
Io voglio capire con quale criterio Javascript ritiene che 4.52 - 4 sia
uguale a 0.5199999999999996...
(considerando che non e' l'unico caso anomalo,cmq).



il bello è che con....
document.write(4.54-4)
il risultato è corretto...mentre a parte chiaramente lo 0 gli altri numeri
li sbaglia..


 li sbaglia..
E fin qui sono tutte cose note... Io vorrei capire il perche' Javascript si
comporta cosi'.

 4.541-4
Appunto!!! Incredibile!!!!!!!!!
Non riesco a tirar fuori una casistica, ho provato un'infinità di sottrazioni 
(con la console per far prima, tanto l'engine è la stessa) ed ho ottenuto 
un'infinità di fesserie
Gli errori di arrotondamento sono dei più incredibili:
provate questa (scritta tippettando sul tast. numerico):
96846546378456.68712364-96846546378456
Vi aspettate qualcosa come .68712363000001 per dire?
Ebbene no! Ottenete ".6875", che neanche per scherzo può essere sbagliato!
Stesso risultato se, sempre nella console scrivete:
var a = 96846546378456.683342346645153452-96846546378456;alert(a);
E non finisce qui!
Provate nella console, poi togliete a caso alcuni decimali del minuendo: il 
risultato *NON* cambia: resta ".6875".
E' qualcosa come un flag di riporto che non viene azzerato prima di essere 
riutilizzato, ma la cosa è stranissima.
Considerazioni:
Possibile che JavaScript faccia in modo nativo le operazioni fondamentali?
Cioè che incorpori i necessari parser! Si affiderà, come qualsiasi 
applicazione, ad una DLL che a su volta passa la palla al processore e ci pensa 
lui. Sennò che ci sta a fare al FPU?
(Ok, se ho scritto una fesseria ditemelo che mi metto a coltivare cicorielle)
Ma nella calcolatrice il risultato è esatto, ed anche in Excel.
E tanto per farla completa queste cinque righe in Turbo Pascal:
program prova;
uses crt;
begin
write(4.52-4);
end.
danno 5.2000000000E-01 che è 0.52 sotto forma di reale.
Rilancio.
Ciao, Riccardo
------------------------------------------------------------------------
WebMaster: ----> 
http://www.jsdir.com
 <---- (aka 
http://www.jspoint.it
)
------------------------------------------------------------------------
Need a JavaScript password?
http://www.jspoint.it/staffscripts/script021/PazzWordProva/ingresso.html
------------------------------------------------------------------------
"Any sufficientely advanced technology is indistinguishable from magic"
                      Arthur Charles Clarke
------------------------------------------------------------------------

 Rilancio.
Qui non facciamo altro che rilanciare. :)
Io, purtroppo, non ho tantissimo tempo da perdere per passare al setaccio la
rete per trovare documentazione o articoli che facciano riferimento a tale
.. "bug"..(?)
.. Ma da quel poco che ho potuto vedere, non c'e' molto a riguardo.

 .. "bug"..(?)
Ho il brutto presentimento che sia proprio un baco, ma è molto strano che si 
presenti in TUTTI gli engine JavaScript provati. PC e Mac, NS e IE in tutte le 
salse.
Anche dando per scontato che:
- l'errore possa essere ricondotto al "core del core del core" di JavaScript, e 
visto che succede anche in NN3 (domani in ufficio provo sotto IE3Win95 e 
IE4WinNT)
- *supponendo* che JavaScript si occupi in proprio delle funzioni elementari 
senza appoggiarsi al processore (probabilità 0.000000000001)
- si presenta in IE ed NN
====> allora è chiaro che ad essere bacati sono gli algoritmi di base di 
JavaScript, ma.....
.... possibile che sia in Netscape che in Microsoft abbiano fatto lo stesso 
errore??????
Trovano tutti i pretesti possibili ed immaginabili per far casino fra di loro e 
poi si vanno a mettere d'accordo proprio per fare un baco????
Ma daaaaiiiii.... io mando una mail a Guninsky, hai visto mai... :-)
Direi che Fabiano, che ha già nominato il gruppo Mozilla, potrebbe chiedere 
lumi in quell'ambiente.
Onestamente io non saprei neanche da dove cominciare :-)
Ma siamo sicuri che non sbagliamo noi? Che non abbiamo *SEMPRE* sbagliato, 
*TUTTI* e c'è qualcosa da mettere prima di cominciare un qualsiasi pezzo di 
codice JavaScript?
Penso a qualcosa tipo un "uses crt;" del Pascal, o a un "#include <stdio.h> del 
C.


 Onestamente io non saprei neanche da dove cominciare :-)
già fatto!!!!

provato. Per la serie sillogismi :-)))
quello è VBA (è diverso)
comunque il bug c'è, noioso e illogico :(
e a volte salta fuori anche con le moltiplicazioni....

 > Il Wed, 20 Sep 2000 17:59:14 +0200, ZER0 si fece coraggio e scrisse.....
Sicuramente il problema è conosciuto visto che ho trovato questa faq su
http://developer.netscape.com/support/faqs/champions/javascript.html#2-2
2.2: Is JavaScript's math inaccurate (0.119 * 100 = 11.899999)?
It's not an issue of accuracy, but rather of the way that JavaScript does
math internally. Generally, you can avoid any unexpected results by rounding
the result of your calcuations to the precision of the most precise number
in your equation. In the example above, you would get the correct answer if
you rounded the output to three decimal places.
cmq scarsa spiegazione.....
P.S.(apriamo un altro thread? questo si stà allungando un pò!)
Ciao!


 cmq scarsa spiegazione.....
Ma era esattamente quello a cui stavo pervenendo... Tutti i risultati se
rounded ad un numero di cifre decimali uguale alla somma delle cifre
decimali presenti nei due operatori erano corretti (chiaramente parlo
della somma delle posizioni decimali per comprendere anche la
moltiplicazione). Volevo dare un'occhiata in proposito al comportamento
con le divisioni, dove il fermarsi ad un certo numero di decimali e` un
errore procedurale... Volete una previsione da "palla di cristallo"?
Secondo me js con le divisioni si comprota egregiamente fino alla
penultima cifra decimale mostrata (l'ultima potrebbe essere il round di
un valore sbagliato).
Il tutto IMVHO si basa sul trattamento dei numeri float, e questa
divinazione sulla divisione e` frutto dei rimescolamenti in memoria dei
miei pruriti, causati da reminiscienze di informatico, mentre ero in
viaggio sulla metro B (che Vanneschi mi perdoni ;o)))


 viaggio sulla metro B (che Vanneschi mi perdoni ;o)))
ahahhah :-))))))))))))))))))


 C.
MA che c'entra.. quelle sono librerie "di base", ma posso cmq usare il
linguaggio senza di esse.. Io in Pascal la crt l'ho usata solo quando ero in
prima superiore, poi l'ho eliminata definitivamente.
Sono librerie di supporto, non servono certo a far funzionare il
linguaggio... tantomeno a "fixarti" un bug nelle operazioni matematiche.
:D

 già fatto!!!!
Avevo provato anche io, ma ho problemi col newsgroup della community.. :/
A te va tutto bene?

 comunque il bug c'è, noioso e illogico :(
Soprattutto il bug persevera. :)
C'e' in tutte le versioni di JS!

 wrote:
http://www2.hursley.ibm.com/decimal/decifaq.htm
decimale 0.9 / 10 =0.09
binary     0.9/ 10 = 0.89999996



sì infatti l'ho postata direttamente a Martin Honnen.....



forse ero l'unico che lo aveva intuito!! :-))))))))))))))
Ciao!


 moltiplicazione).
Si, ma come abbiamo notato non sempre accade, ci sono dei casi "limite" in
cui effettivamente il risultato e' corretto.
Oppure, sei riuscito a spiegarti come mai su Mac 1.2-1 da' un risultato
corretto mentro su piattaforma Windows no?
Alla fin dei conti cmq il bug c'e', ed e' palese.
Ora io mi domando, vista e letta la faq, possibile che non vi abbiano *MAI*
posto rimedio, da una versione di JS all'altra?

 ha scritto nel messaggio
news:8qci6g$gcg$1...@fe2.cs.interbusiness.it...


Il lato comico è che ci abbiamo fatto pure le calcolatrici in javascript!!
:-)))
e ce ne sono in giro parecchie......!


 sě infatti l'ho postata direttamente a Martin Honnen.....
Attendiamo fiduciosi una sua risposta, allora. :)

 e ce ne sono in giro parecchie......!
Ahahaha.. e' vero!! :DD
Io personalmente non ne ho mai fatte, ma ricordo parecchie Zuper che
simulavano una calcolatrice... ^__^

 Attendiamo fiduciosi una sua risposta, allora. :)
con tutte le e-mail che riceve....
l'ultima volta mi ha risposto dopo una settimana!!
cmq appena riesco la posto anche sul NG di netscape.....


avevo appunto provato con quella (presa dal sito di un "illustre" ) per
vedere se era giusto il risultato......ahaha :-))))))))))
Secondo me tra quelli che hanno codato javascript finora ci hanno pensato
in pochi!!
cmq ho postato la domanda anche su  netscape.devs-javascript (vediamo!!).


 
No, dai, questo è così carino :-))))
-- 


 Javascript.. ;D
Nessuno ha provato con OPERA o qualche altro?


 un valore sbagliato).
Direi che questa affermazione si dovrebbe correggere in:
"l'ultima è precisa +/- 1", ma avrebbe senso solo in conversioni analogico -> 
digitali no?
Comunque è OT. Chiuso il discorso (salvo che si voglia continuare in e-mail :-)


 Nessuno ha provato con OPERA o qualche altro?
Io no.