Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    156

    [Matematica del calcolatore] Divisioni e numeri reali, come funziona.

    Stavo creando un'applicazione in Delphi quando ho notato uno strano fenomeno:

    Funzione realtostr, che trasforma numeri reali in stringhe:


    codice:
    function realstr(x:real):string;
    var tempx, i:integer;
    begin
    realstr:='';
    tempx:=trunc(x);
    realstr:=realstr+inttostr(tempx)+',';
    x:=x-tempx;
    repeat
    tempx:=trunc(x*10);
    x:=(x*10)-tempx;
    realstr:=realstr+intstrnew(tempx);
    until (x=0) and (tempx=0);
    end;
    il problema e che se in input viene dato per esempio 3.4 l'output in stringa è:

    3,3999999999999911182158 etc....

    Ho escluso un difetto nel codice, optando invece per un qualche errore (c'entra niente l'overflow?) relativo al processore e di come questo rappresenta i numeri reali.
    Ma qual'è il vero motivo? E come potrei fare per eluderlo mantenendo però la corrispondenza perfetta tra input e output?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Leggi a partire da

    Representable numbers, conversion and rounding

    in

    http://en.wikipedia.org/wiki/Floating_point
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    156
    vediamo se sbaglio:

    3.4 in binario è rappresentato come

    11.(0110)

    quindi con notazione esponenziale

    0.110110 x2^2

    rappresentato dal calcolatore come

    1000 0010 (esponente) 0(segno)101100110 etc...

    giusto?

    vediamo se ora applicando quello che c'è scritto su wiki riesco a trarre qualche conclusione.
    Grazie per il link

  4. #4
    Utente di HTML.it
    Registrato dal
    Dec 2004
    Messaggi
    286
    vediamo se ora applicando quello che c'è scritto su wiki riesco a trarre qualche conclusione.
    La conclusione a livello pratico è che per evitare di avere 3.3 (se si tronca la parte frazionaria) anziché 3.4 si opera un arrotondamento per cui 3.3(9999xxx) diviene 3.4 come ci si aspetta.

    Il problema è abbastanza comune, ci sono molti documenti in rete che si riferiscono alla Floating Point Question, e per quanto ne so la soluzione più ricorrente a questo problema è il rounding.

  5. #5
    Se invece errori di questo genere non sono tollerabili (ad esempio se si stanno gestendo valori monetari) si usano i vari tipi decimal, che esistono sia in virgola mobile che in fixed point.
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    156
    [QUOTE]Originariamente inviato da MItaly
    si usano i vari tipi decimal, che esistono sia in virgola mobile che in fixed point.
    GRANDE!!
    ecco cosa ho trovato
    http://delphi.about.com/library/rtl/...loatFormat.htm

    è proprio quello che mi serviva! Applico e vi faccio sapere

  7. #7
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    156
    ok, risolto con la funzione floattostrf(x,ffgeneral,8,4);

  8. #8
    Originariamente inviato da Rising1
    ok, risolto con la funzione floattostrf(x,ffgeneral,8,4);
    Vabbé, ma così stai barando, ti limiti ad arrotondare...
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    156
    Originariamente inviato da MItaly
    Vabbé, ma così stai barando, ti limiti ad arrotondare...

    scusa, la funzione era floattostrf(x,ffgeneral,8,8); con ffgeneral comunque, oltre ad evitare i problemi di arrotondamento della mia funzione evito pure che ci siano inutili "0".

    123.4300 ad esempio lo fa diventare semplicemente 123.43. è Proprio quello che cercavo di fare con la mia funzione.

    quello che credevo era però che, togliendo ad ogni moltiplicazione per 10 la parte intera del numero, "dessi più spazio alla parte decimale" per avere una migliore precisione, ma mi sbagliavo. Avevo provato altri metodi ma il difetto di arrotondamento era comunque presente.

    Non la conoscevo proprio questa funzione, SysUtils mi stupisce sempre di più

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.