Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    [javascript]- somme di parseFloat

    ragazzi succede una cosa strana quando faccio questa somma in javascipt:

    alert((45.08)+(12.77));
    il risultato è: 57.849999999999994

    ma come è possibile?
    se invece faccio:
    alert((45.07)+(12.78));

    ottengo:
    57.85

    non capisco
    grazie per l'aiuto

  2. #2
    Utente di HTML.it L'avatar di pietro09
    Registrato dal
    Jan 2002
    Messaggi
    10,116
    per la stessa ragione di questo codice fatto in Excel

    Option Explicit

    Private Sub prova()
    Dim i, n
    n = 0
    For i = 1 To 10
    n = n + 0.1
    Next
    Debug.Print (n) '==> stampa 1
    Debug.Print (n = 1) '==> stampa false
    End Sub

    la prima istruzione Debug.Print (n) stampa 1

    la seconda istruzione Debug.Print (n = 1) stampa false perchè il risultato non è 1 ma un numero che gli avvicina molto.

    In altre parole, non è possibile rappresentare in maniera esatta i numeri in formato in virgola mobile e i calcoli soffrono di questo. Perciò, il risultato lo devi arrotondare te
    Pietro

  3. #3

  4. #4
    La matematica in JavaScript è "rotta", sin dalla nascita, uno dei fix che verrà fatto in JS 2.0 se mai e/o quando uscirà.

    Per avere precisione basta usare i metodi di Number appositi, tipo toFixed oppure toPrecision, stan li apposta per evitare problemi.


    alert(parseFloat(((45.08)+(12.77)).toFixed(2)));

    57.85



    P.S.
    pietro ... 1 è 1, non un numero vicino ad uno, ora che Microsoft giustifichi le porcate Ok, ma che pure tu ci credi no eh


    Edit P.S.2
    non a caso in C# 1.0 == 1 ... per il semplice fatto che l'altro comportamento è semplicemente errato
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  5. #5
    Utente di HTML.it L'avatar di pietro09
    Registrato dal
    Jan 2002
    Messaggi
    10,116
    Originariamente inviato da Lukem
    che palle però
    grazie
    ma scusa, visto che si usa da sempre questo sistema, non ti sembra che forse sia un buon sistema?
    Pietro

  6. #6
    Utente di HTML.it L'avatar di pietro09
    Registrato dal
    Jan 2002
    Messaggi
    10,116
    P.S.
    pietro ... 1 è 1, non un numero vicino ad uno, ora che Microsoft giustifichi le porcate Ok, ma che pure tu ci credi no eh


    Edit P.S.2
    non a caso in C# 1.0 == 1 ... per il semplice fatto che l'altro comportamento è semplicemente errato
    Gentilissimo Andrea, è proprio vero che anche gli Dei cadono e anche su cose banali :

    Questo codice in c#, che tu conosci bene

    codice:
        protected void Page_Load(object sender, EventArgs e)
        {
            double n = 0;
            for (int i = 1; i <= 10; i++) n += 0.1;
            Response.Write(n.ToString() + "
    "); // stampa 1
            Response.Write((n == 1).ToString() + "
    "); // stampa false
        }
    funziona come funzionano tutti i programmi che usano i numeri in formato in virgola mobile

    La somma di 0.1 per 10 volte viene arrotondata a 1 ma la seconda istruzione mi dice che quella somma non è 1 ma 1 a meno dell'errore del sistema di rappresentazione in virgola mobile. La rappresentazione esatta di numeri decimali in virgola mobile è possibile solo per alcuni (non ricordo la regola, ma credo che uno sia 0.125)

    I calcoli esatti si fanno ma con gli interi, con i decimal


    ps. nozioni che riportano i testi sacri, fin dai tempi dei tempi


    un link a wikipedia non si nega a nessuno

    http://it.wikipedia.org/wiki/Virgola_mobile

    http://bonda.cnuce.cnr.it/Documentat.../parte4_7.html
    Pietro

  7. #7
    non ho testato niente ma so per certo che in C#

    1.0 == 1

    è assolutamente true

    il punto del 3D è che a lui stampa troppe cifre dopo la virgola, che è il motivo per cui tutti hanno detto da sempre che la matematica in JavaScript è rotta e gli stessi sviluppatori hanno previsto di correggerla nella 2.0

    In C# se fai + 0.1 per 10 volte e fai un Console.WriteLine ti da 1, non 0.988898887723 ... fin qui, almeno, spero che siamo d'accordo .. per il resto non ho tempo di testare ma lo farò, soprattutto un confronto di .1 * 10 == 1.0 ... se mi da false, la matematica in C# è rotta, del resto è ECMA pure lui
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  8. #8
    Utente di HTML.it L'avatar di pietro09
    Registrato dal
    Jan 2002
    Messaggi
    10,116
    Originariamente inviato da andr3a
    non ho testato niente ma so per certo che in C#

    1.0 == 1

    è assolutamente true

    il punto del 3D è che a lui stampa troppe cifre dopo la virgola, che è il motivo per cui tutti hanno detto da sempre che la matematica in JavaScript è rotta e gli stessi sviluppatori hanno previsto di correggerla nella 2.0

    In C# se fai + 0.1 per 10 volte e fai un Console.WriteLine ti da 1, non 0.988898887723 ... fin qui, almeno, spero che siamo d'accordo .. per il resto non ho tempo di testare ma lo farò, soprattutto un confronto di .1 * 10 == 1.0 ... se mi da false, la matematica in C# è rotta, del resto è ECMA pure lui
    se sommi 0.1 per 10 volte, viene stampato 1 ma quello è un arrotondamento perchè quella somma non si può fare in maniera precisa con i numeri a virgola mobile
    codice:
            double n = 0;
            for (int i = 1; i <= 10; i++) n += 0.1;
            Response.Write(n.ToString() + "
    "); // stampa 1
            Response.Write((n == 1).ToString() + "
    "); // stampa false
            Response.Write((Math.Abs(n - 1)).ToString() + "
    "); // stampa 1,11022302462516E-16
    infatti la differenza tra 1 e n è circa 1e-16

    ti rimando ai link wikipedia più sopra
    Pietro

  9. #9
    allora, Python 2.5 (che sotto sotto è C) da console (per fare na prova rapida)

    1.0 == 1 #True
    .1 + .1 == .2 #True
    .2 #0.200000000000001

    .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 == 1.0 # False

    ma

    .1 * 10 == 1.0 #True

    e

    .1 + .1 + .1 + .1 + .1 + .1 + .1 == .7 # True

    quindi da una parte pensavo erroneamente che C# facesse correzioni in automatico (più che C# la VM sotto), dall'altra aggiungere un float statico per N volte non ha senso quindi non mi sono mai interessato troppo al comportamento

    il fatto è che i problemi in virgola mobile li conosco ma i problemi in vorgola mobile con linguaggi interpretati non li capisco, partendo da JavaScript, continuando con Python, arrivando a C# che ha una VM sotto ... buono a sapersi, motivo in più per continuare ad usare le funzioni apposite come toFixed e toPrecision
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.