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

    [JAVA] Comportamento anomalo in esecuzione codice traccia d'esame

    Salve, credo che per questo problema ci voglia una persona con più conoscenza in campo. Allora, se vi scrivo è perchè ho trovato una stranezza usando Eclipse per compilare ed eseguire un codice che fa parte di una traccia d'esame, infatti fra poco avrò l'esame all'università e vorrei togliermi gli ultimi dubbi su quanto riguarda i fondamenti di Java.
    Il programma è questo:


    public class PariDisp{
    public static void main(String [] args){
    double [] [] mat = new double[][]{{1.0,2.0,2.1,1.1},
    {1.0,1.5,1.5,1.0},
    {1.1,3.3,3.2,1.0},
    {1.1,2.0,2.0,1.1}};
    if(metodo2(mat))
    System.out.println("OK");
    else
    System.out.println("NON OK");
    }
    public static double metodo1(double[] v, int i){
    double s=0;
    for(int k=i;k<v.length;k+=2)
    s+=v[k];
    return s;
    }
    public static boolean metodo2(double [] [] m){
    boolean verificato=true;
    for(int k=0;k<m.length && verificato;k++)
    if(metodo1(m[k],0)!=metodo1(m[k],1))
    verificato=false;
    return verificato;
    }
    }

    In pratica il programma restituisce "OK" se la somma degli elementi in posizione pari è uguale alla somma degli elementi in posizione dispari di ogni riga della matrice "m[][]"...il risultato è stato stranamente "NON OK" perchè mi dice che nella terza riga le somme degli elementi dispari e pari non sono uguali.
    Allora per capire il problema ho fatto una prova di collaudo, cioè ho riscritto il codice con il "System.out.print" nella zona interessata per vedere qual'era l'errore:


    public class PariDisp {
    public static void main(String [] args){
    double[][]mat=new double[][]{{1.0,2.0,2.1,1.1},
    {1.0,1.5,1.5,1.0},
    {1.1,3.3,3.2,1.0},
    {1.1,2.0,2.0,1.1}};

    if(metodo2(mat))
    System.out.println("OK");
    else
    System.out.println("NON OK");
    }

    public static double metodo1(double[] v,int i){
    double s=0;
    for(int k=i;k<v.length;k+=2){
    s+=v[k];
    System.out.println(v[k]);
    }
    System.out.println("La somma è uguale a "+s);
    return s;
    }

    public static boolean metodo2(double [][]m){
    boolean verificato=true;
    for(int k=0;k<m.length && verificato;k++)
    if(metodo1(m[k],0)!=metodo1(m[k],1))
    verificato=false;
    return verificato;
    }
    }

    Ed ecco il risultato in Eclipse:

    1.0
    2.1
    La somma è uguale a 3.1
    2.0
    1.1
    La somma è uguale a 3.1
    1.0
    1.5
    La somma è uguale a 2.5
    1.5
    1.0
    La somma è uguale a 2.5
    1.1
    3.2
    La somma è uguale a 4.300000000000001
    3.3
    1.0
    La somma è uguale a 4.3
    NON OK

    Come viene fuori quel "4.300000000000001" ??

  2. #2
    Scusatemi non ho visto la sottosezione di Java, se qualche mod può spostare gentilmente o riapro io

  3. #3
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    C'è sempre un errore di macchina nelle operazioni di somma tra floating point.
    Più i numeri sono vicini (come grandezza), più l' errore è piccolo.
    Dipende anche dai dati, un numero può non avere la sua rappresentazione esatta, ma arrotondata.
    Puoi sempre risolvere usando la printf di System.out per stampare una cifra sola:

    codice:
    System.out.printf("%1$.1f", s);
    Oppure usare DecimalFormat.

  4. #4
    1.1 non ha una rappresentazione esatta in binario, per cui viene usato un valore approssimato. Per questo e altri motivi non si confrontano mai dei numeri in virgola mobile per uguaglianza, ma si verifica che la loro differenza sia inferiore ad un certo epsilon.
    Per ulteriori informazioni sulla questione puoi leggere questo famoso articolo.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Originariamente inviato da MItaly
    1.1 non ha una rappresentazione esatta in binario, per cui viene usato un valore approssimato. Per questo e altri motivi non si confrontano mai dei numeri in virgola mobile per uguaglianza, ma si verifica che la loro differenza sia inferiore ad un certo epsilon.
    Per ulteriori informazioni sulla questione puoi leggere questo famoso articolo.

  6. #6
    Originariamente inviato da Pierfrank
    ah ecco...capito il problema, è proprio la virgola, quindi qualsiasi decimale, che non esiste in numero binario

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.