Newsgroup: it.comp.java
Titolo: equazioni di secondo grado

Ciao a tutti, sto scrivendo un programma per risolvere le equazioni di 
secondo grado. A parte l'algoritmo che posso senz'altro migliorare ho questo 
problema: alle righe 31, 32 e 39 ricevo l'errore
"possible loss of precision". Ho provato ad effettuare il casting, a 
dichiarare tutto float o tutto intero, ma niente da fare. Potete aiutarmi? 
Un'altro problema e che voglio evitare che come coefficiente della A venga 
inserito 0 e se B vale zero contemporaneamente non può valere 0 anche C, ma 
non so come far ripetere la richiesta di inserimento del solo coefficiente 
"incriminato". Potrei usare un do while evitando di aggiungere un if? Però 
in questo caso come posso visualizzare anche il messaggio di errore? Grazie 
mille in anticipo a tutti, ecco il codice:
public class equazione_secondo_grado
{
 public static void main(String[] args)
 {
  int a,b,c,x1,x2,delta;
  System.out.println("\n\nquesto programma risolve un'equazione di secondo 
grado");
  System.out.println("\n\nnella forma ax2 +bx +c");
  //acquisizione dati
  a=Console.readInt("inserisci coefficiente di a: ");
  if(a!=0)
  {
   b=Console.readInt("inserisci coefficiente di b: ");
   if(b!=0)
   {
    if(c!=0) //equazione completa
    {
     delta=(int)Math.pow(b,2)-4*(a*c);
     if(delta>0)
     {
      x1=(float)-b+Math.sqrt(delta)/(2*a);
      x2=(float)-b-Math.sqrt(delta)/(2*a);
      System.out.println("\n\nle radici dell'equazione sono:");
      System.out.println("\n\nX1: "+x1);
      System.out.println("\n\nX2: "+x2);
     }
     else if(delta==0)
     {
      x1=(float)-b+Math.sqrt(delta)/(2*a);
      x2=x1;
      System.out.println("\n\nle radici dell'equazione coincidono:");
      System.out.println("\n\nX1: "+x1);
      System.out.println("\n\nX2: "+x2);
     }
     else if(delta<0) System.out.println("\n\nl'equazione non ha soluzioni 
reali e distinte");
    }
    else //equazione spuria: manca termine noto
    {
     System.out.println("\n\nle radici dell'equazione sono:");
     System.out.println("\n\nX1: 0");
     x2=-b/a;
     System.out.println("\n\nX2: "+x2);
    }
   }
   else if(c!=0) //falso di b diverso da 0
   {
    //equazione pura
    x1=(int)Math.sqrt(-c/a);
    System.out.println("\n\nle radici dell'equazione sono:");
    System.out.println("\n\nX1: "+x1);
    System.out.println("\n\nX2: -"+x1);
   }
   else
   {
    //se b=0 c deve essere divero da 0
    System.out.println("se b=0 c non puo' essere 0");
   }
  } //chiusura primo if
  else System.out.println("il valore di a non puo' essere 0");
 } //chiusura main
} //chiusura classe

 messaggio di errore? Grazie mille in anticipo a tutti, ecco il codice:
Scrivere tutto il codice nel metodo main ? Non va bene, scusa la franchezza: 
comincia
con il riorganizzare il codice suddividendo l'acquisizione dell'input, la 
validazione dell'input,
e l'esecuzione del calcolo. Poi pensa a come potresti risolvere il tuo 
problema (reimmissione
dei dati).... vedrai che, se ti sforzi, ci arrivi da solo.
Buono studio,
Scorpio. 

 dei dati).... vedrai che, se ti sforzi, ci arrivi da solo.
Grazie, ho risolto il problema del casting: non mi ero accorto di usare la 
readInt al posto di readFloat. Perň č stato necessario farne due: 
x1=(float)-b+(float)Math.sqrt(delta)/(2*a);
Anch'io avevo pensato di dividere l'acquisizione dei dati, il controllo e il 
calcolo, cosě come farei con il linguaggio C. Il problema č che in java non 
so come si fa: ho appena cominciato a studiarlo a scuola. Potresti farmi 
vedere un piccolo esempio? Bisogna dichiarare un prototipo come in C? Grazie 
ancora. 

 vedere un piccolo esempio? Bisogna dichiarare un prototipo come in C? 
Eccoti un esempio (migliorabile):
class Parameters {
    double a = 0.0;
    double b = 0.0;
    double c = 0.0;
    boolean allZeros() {
       return !((a == 0.0) && (b==0.0) && (c==0.0));
    }
    boolean areOk() {
       return (!(a == 0.0)) && !allZeros();
    }
}
class Solution {
    double x1;
    double x2;
}
public class Solver {
    static Parameters readParameters() {
        do {
            Parameters result = new Parameter();
            result.a = Console.readDoube("Inserisci a: ");
            result.b = Console.readDoube("Inserisci b: ");
            result.c = Console.readDoube("Inserisci c: ");
        } while(result.areOk());
        return result;
    }
    static Solution solve(Parameters param) {
        ...
    }
    static printSolution(Solution solution){
        ...
    }
    public static void main(String[] notUsed) {
        Parameters params = readParameters();
        Solution solution = solve(params);
        printSolution(solution);
    }
}
-- 
Andrea Francia
http://andreafrancia.blogspot.com/2008/07/colinux-linux-dentro-windows.html

 C? Grazie ancora.
Ciao, ti posto solo lo scheletro di una soluzione assolutamente da 
raffinare. Posso aggiungere una cosa ? Se stai studiando a scuola Java, ti 
consiglio di aspettare a lanciarti ed imparare  prima i fondamenti: C non è 
ad oggetti, Java sì, e occorre un po' di tempo per fare il passaggio 
mentale.
// Equazione nella forma ax^2+bx+c  = 0;
public class Equazione {
   float a, b,c;
   float x1,x2;
   // Codifica qui la lettura dei coefficienti
   // Il metodo restituirà true se i coefficienti
   // soddisfano le condizioni di ammissibilità,
   // false in caso contrario
   public boolean caricaCoefficienti() {
     //...
   }
   public void computa() {
    // calcola x1 e x2.
   }
   public static void main(String args) {
    do{
      //// cicla fintantoche l'input non è corretto
    }while(!caricaCoefficienti())
    computa();
    // Scrive i risultati.
   }
}

 


       statico.
Vero, devi prima creare un'istanza della classe.
Pardon, la fretta - e il sonno - non aiutano.... ;-)
Scorpio. 

            result.a = Console.readDoube("Inserisci a: ");
Hai modellato una classe Solver. Bene, falle svolgere il suo compito e
basta: niente input all'utente. L'input deve arrivare da fuori e il
metodo main() non deve stare qui dentro. La classe solvere dovrebbe
solo accettare i suoi 3 coefficienti in ingresso.

 solo accettare i suoi 3 coefficienti in ingresso.
Ci sono due motivi per cui ho deciso di fare così:
  - l'OP è partito da un programma interattivo.
  - mi sembrava che l'OP avesse chiesto un programma interattivo
    (parlava di "ripetere l'inserimento", e di voler usare il "while").
  - dato che l'OP ha detto di essere agli inizi ho pensato che potrebbe
    non conoscere gli input da linea di comando. Dato che lo scopo era
    didattico ho pensato che non fosse il caso di sovraccaricare l'OP con
    un nuovo concetto.


    non conoscere gli input da linea di comando.
Non hai capito che cosa sto dicendo: la classe deve avere una sua
responsabilità ed esistere a prescindere dal fatto che i suoi
coefficienti arrivino dall'input utente o meno. Bisogna separare
questi comportamenti. In generale, non bisogna MAI scrivere codice
interattivo in una classe del dominio, perché potrebbe benissimo, in
linea di principio, essere usata in contesti non interattivi.

 [...]
Alcuni dei tuoi discorsi mi sembrano sensati ma sono poco pratici.
Se hai del codice migliore postalo e spiegaci perché lo č.


Alcuni dei tuoi discorsi mi sembrano sensati ma sono poco pratici.
Non sono abituato a fare discorsi accademici, quindi credo che la tua
impressione sia sbagliata. Oltretutto, non vedo in che cosa ciò che
dico risulterebbe "poco pratico" visto che tende a smontare, invece,
la tua costruzione architetturale troppo azigogolata e molto poco
pratica.


La mia soluzione è più complessa (o arzigogolata) di quella di Scorpio 
anche perché ha una qualità in piu': L'integrità dei dati non dipende 
dalla sequenza con cui invochi i metodi.
Con il programma di Scorpio puoi avere un oggetto equazione con questo 
stato
    a=3000, b = 9, c = 9;
    x1=0.0; x2 = 0.0; // questa non è la soluzione di 3000x^2+9x+9=0
Ad esempio quando hai chiamato caricaCoefficienti() ma non ancora computa().
Questo non può succedere con l'architettura individuata nel mio post 
perché fintantoché non hai chiamato solve() l'oggetto Solution non 
esiste neanche.
Comunque non mi sembra *molto* più complessa di quella di Scorpio.
La soluzione di Scorpio sembra la soluzione procedurale del problema, e 
ti dirò di più: secondo me Scorpio ha fatto bene a farla così.
Dato che:
  - l'OP sembra essere a digiuno di OOP (venendo dal C)
  - il problema può essere risolto banalmente con la programmazione
    strutturata
  - l'OP aveva solo bisogno di imparare a spezzare il codice in piu'
    metodi
credo che la soluzione di Scorpio sia più istruttiva della mia.


Comunque non mi sembra *molto* più complessa di quella di Scorpio.
Francia, sei pesante e allunghi il brodo delle discussioni in maniera
estenuante. Non accetti il contraddittorio e tendi a difendere a spada
tratta le tue soluzioni. Non è un atteggiamento costruttivo. La tua
soluzione *è* più arzigogolata ed inutilmente complessa.

 mappano "al plurale":
Non l'ho mai sentita questa, e comunque ci sono concetti plurali. Non
credo proprio che tu non abbia mai scritto una classe con nomi alla
"Users" o "ItemList".

 mappano "al plurale":
Non l'ho mai sentita questa, e comunque ci sono concetti plurali. Non


 mappano "al plurale":
Non l'ho mai sentita questa, e comunque esistono anche concetti
plurali.
Nutro grossi dubbi sul fatto che tu non abbia mai scritto una classe


 soluzione *è* più arzigogolata ed inutilmente complessa.
Questa e la tua opinione, se usassi "IMHO" ti troverei meno sgarbato.
-- 
Andrea Francia
http://www.andreafrancia.it/


Questa soluzione contiene delle cose che non mi piacciono:
  - Non risolve il problema dell'OP di fattorizzare la lettura dei
    parametri dell'equazione.
  - Non considera il fatto che un equazione possa avere come soluzione i 
seguenti casi particolari:
    - un solo valore di x
    - nessun valore di x
    - tutti i valori di x
    Ma gestisce solo i casi:
     - due valori diversi di x
     - due valori coincidenti di x
    Questo è possibile se incapsuli la Soluzione in una classe apposita
    capace di gestire tutti i casi particolari.
  - L'equazione e la soluzione sono lo stesso oggetto. Questo vuol dire
    che per esempio non puoi fare un toString() per l'equazione ed uno
    per la soluzione, oppure per scrivere un metodo equals che confronti
    le soluzioni di due equazioni diverse sono uguali.
  - la classe è mutabile. Di solito si cerca di evitare le classi
    mutabili (vedi item 15 di Effective Java second edition). Se i valori
    di a, b, c non devono cambiare andrebbero contrassegnati come final.
-- 
Andrea Francia
FtpServerStub ease your FTP Client unit-testing:
http://andreafrancia.it/ftpserverstub/