* * * *

Privacy Policy

Blog italiano

Clicca qui se vuoi andare al blog italiano su Lazarus e il pascal.

Forum ufficiale

Se non siete riusciti a reperire l'informazione che cercavate nei nostri articoli o sul nostro forum vi consiglio di visitare il
Forum ufficiale di Lazarus in lingua inglese.

Lazarus 1.0

Trascinare un file nel programma
DB concetti fondamentali e ZeosLib
Recuperare codice HTML da pagina web
Mandare mail con Lazarus
Stabilire il sistema operativo
Esempio lista in pascal
File INI
Codice di attivazione
Realizzare programmi multilingua
Lavorare con le directory
Utilizzare Unità esterne
TTreeView
TTreeview e Menu
Generare controlli RUN-TIME
LazReport, PDF ed immagini
Intercettare tasti premuti
Ampliare Lazarus
Lazarus e la crittografia
System Tray con Lazarus
UIB: Unified Interbase
Il file: questo sconosciuto
Conferma di chiusura di un applicazione
Liste e puntatori
Overload di funzioni
Funzioni a parametri variabili
Proprietà
Conversione numerica
TImage su Form e Panel
Indy gestiore server FTP lato Client
PopUpMenu sotto Pulsante (TSpeedButton)
Direttiva $macro
Toolbar
Evidenziare voci TreeView
Visualizzare un file Html esterno
StatusBar - aggirare l'errore variabile duplicata
Da DataSource a Excel
Le permutazioni
Brute force
Indy 10 - Invio email con allegati
La gestione degli errori in Lazarus
Pascal Script
Linux + Zeos + Firebird
Dataset virtuale
Overload di operatori
Lavorare con file in formato JSON con Lazarus
Zeos ... dietro le quinte (prima parte)
Disporre le finestre in un blocco unico (come Delphi)
Aspetto retrò (Cmd Line)
Lazarus 1.0
Come interfacciare periferica twain
Ubuntu - aggiornare free pascal e lazarus
fpcup: installazioni parallele di lazarus e fpc
Free Pascal e Lazarus sul Raspberry Pi
Cifratura: breve guida all'uso dell'algoritmo BlowFish con lazarus e free pascal.
Creare un server multithread
guida all'installazione di fpc trunk da subversion in linux gentoo
Indice
DB concetti fondamentali e connessioni standard
Advanced Record Syntax
DB concetti fondamentali e DBGrid
DB concetti fondamentali e TDBEdit, TDBMemo e TDBText
Advanced Record Syntax: un esempio pratico
Superclasse form base per programmi gestionali (e non)
Superclasse form base per programmi gestionali (e non) #2 - log, exception call stack, application toolbox
Superclasse form base per programmi gestionali (e non) #3 - traduzione delle form
Superclasse form base per programmi gestionali (e non) #4 - wait animation
Un dialog per la connessione al database:TfmSimpleDbConnectionDialog
Installare lazarus su mac osx sierra
immagine docker per lavorare con lazarus e free pascal
TDD o Test-Driven Development
Benvenuto! Effettua l'accesso oppure registrati.
Novembre 25, 2024, 06:35:49 pm

Inserisci il nome utente, la password e la durata della sessione.

49 Visitatori, 1 Utente
 

Autore Topic: [RISOLTO]strano risultato di parte frazionale di un numero in stringa  (Letto 1508 volte)

antoniog

  • Scrittore
  • Sr. Member
  • *****
  • Post: 257
  • Karma: +0/-0
    • Informatica Utile
Nella trasformazione  della parte frazionale di un numero in stringa Lazarus opera di fantasia o sbaglio qualcosa?
Provate ad inserire un pulsate in una form e scrivete questo codice:
Codice: [Seleziona]

procedure TForm1.Button7Click(Sender: TObject);
 var
 st : string;
 num : real;
 mNumber : double;
 begin
 mNumber:= 80237,68;
 num:=Frac(mNumber);
 St:= IntToStr(Trunc(Num * 100));
 showmessage(st);
 end; 
il risultato mi da 67 e non 68
Sono stupito ed un po anche inc...
« Ultima modifica: Maggio 06, 2021, 08:28:09 pm da antoniog »
avrai solo la libertà che riuscirai a conquistarti e anche questa sarà incerta.

brunello

  • Jr. Member
  • **
  • Post: 83
  • Karma: +0/-0
Re:strano risultato di parte frazionale di un numero in stringa
« Risposta #1 il: Maggio 06, 2021, 04:54:44 pm »
con questa conversione il risultato è corretto, ciao
Codice: [Seleziona]
 showmessage(FloatToStrF(num * 100,  ffNumber, 10,2));

antoniog

  • Scrittore
  • Sr. Member
  • *****
  • Post: 257
  • Karma: +0/-0
    • Informatica Utile
Re:strano risultato di parte frazionale di un numero in stringa
« Risposta #2 il: Maggio 06, 2021, 08:27:39 pm »
Brunello, ringrazio per la risposta.
funziona ma a me va bene così:
Codice: [Seleziona]
showmessage(FloatToStrF(num * 100,  ffNumber, 10,0));

perchè non voglio decimali di decimali.
Avevo già risolto con:
Codice: [Seleziona]
st:=rightstr(Floattostr(mNumber),2);
showmessage(st);

Posso mettere risolto anche se le soluzioni trovate aggirano il problema.
avrai solo la libertà che riuscirai a conquistarti e anche questa sarà incerta.

SB

  • Scrittore
  • Sr. Member
  • *****
  • Post: 283
  • Karma: +1/-0
Re:[RISOLTO]strano risultato di parte frazionale di un numero in stringa
« Risposta #3 il: Maggio 09, 2021, 08:19:31 am »
...
 num:=Frac(mNumber);
 St:= IntToStr(Trunc(Num * 100));
 showmessage(st);
 end; 
..
il risultato mi da 67 e non 68
Sono stupito ed un po anche inc...

Il problema non è di FP.
Probabilmente ti sfugge che i numeri sono trattati internamente in binario, non in decimale
Non puoi pensare che i numeri reali siano esattamente ciò che scrivi nel programma, specie quando hanno una parte frazionaria
Infatti quando scrivi come double il numero 80237.68 in realtà viene memorizzato internamente
80237.679999999993
Per chi è curioso:
0100000011110011100101101101101011100001010001111010111000010100

L'uso del Trunc() invece del Round() fa il resto
Te ne puoi rendere conto seguendo i passaggi uno ad uno

Codice: [Seleziona]
 mNumber:= 80237.68;
 num:=Frac(mNumber);
 st := format('%.10f',[num]);
 showmessage(st);
 st := format('%.10f',[num*100]);
 showmessage(st);
 St:= IntToStr(Trunc(Num * 100));
 showmessage(st);

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1403
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:[RISOLTO]strano risultato di parte frazionale di un numero in stringa
« Risposta #4 il: Maggio 09, 2021, 12:26:08 pm »
Vorrei aggiungere due note a quanto già detto:


Codice: [Seleziona]

 num : real;
 mNumber : double;

1) Attenzione ai tipi, double e real potrebbero non avere la stessa precisione (15 cifre contro 7 normalmente); real è un tipo che dipende dalla piattaforma in uso. Consiglio di usare sempre tipi omogenei.

2) L'assegnazione tra tipi non omegenei impone o in fase di compilazione o in fase di runtime una conversione ---> quindi con introduzione di errori, sopratutto nei dati in virgola mobile.

Ovviamente bisogna porre attenzione nei confornti tra dati in virgola mobile (ma anche se sono interi derivati da virgola mobile  :P ), ci potrebbero essere sorprese come quelle indicate.

Saluti
« Ultima modifica: Maggio 09, 2021, 12:28:52 pm da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

antoniog

  • Scrittore
  • Sr. Member
  • *****
  • Post: 257
  • Karma: +0/-0
    • Informatica Utile
Re:[RISOLTO]strano risultato di parte frazionale di un numero in stringa
« Risposta #5 il: Maggio 09, 2021, 11:06:04 pm »
Ringrazio SB e DragoRosso per avermi rinfrescato alcune nozioni. Mi occupo da oltre 30 anni di gestionali e fortunatamente ancora oggi non soffro di un galoppante "analfabetismo di ritorno".
È praticamente impossibile un dialogo sereno fra informatici puri ed un semplice ingegnere civile quasi del tutto autodidatta in informatica che cerca le procedure e funzioni di sistema per ottenere i risultati che gli interessano cercando di non complicarsi la vita. Per esperienza la precisione che viene richiesta non va oltre i quatro decimali e quindi se ho 15 o 7 cifre posso dire che ne ho fin troppe e sono costretto ad arrotondare.
Posso andare oltre e superare quanto finora discusso con questo semplice codice:
Codice: [Seleziona]

uses fpexprpars, symbolic, math;


var
  s, st:string;
  mNum, mNumber : real;
begin
   s:='( ( 9.20*6.25 ) +9.20 *( 1.37/2 )  ) *2+ ( 10.00*6.25*2 )+( 1.00*1.35 )';
   mNumber:= RoundTo(quickevaluate(s,[],[]),-2);
   mNum:=Frac(mNumber);
   St:= IntToStr(Trunc(mNum * 100));
   showmessage(st);
   //mi darà la stringa '95' che è quello che volevo
end;
il risultato real di -s- lo posso ottenere  anche con una query:
Codice: [Seleziona]

ZQuery1.SQL.Text := 'SELECT ' + s+'*1.00' +';';
          zQuery1.Active := True;
          s:= StringReplace(zQuery1.Fields[0].Text, '.',',', [rfReplaceAll]);
          mNumber:= RoundTo(StrToFloat(s),-2);
          St:= IntToStr(Trunc(mNum * 100));
          showmessage(st); 
il segreto è RoundTo() in entrambi i casi.
« Ultima modifica: Maggio 09, 2021, 11:34:28 pm da antoniog »
avrai solo la libertà che riuscirai a conquistarti e anche questa sarà incerta.

doc

  • Jr. Member
  • **
  • Post: 96
  • Karma: +2/-0
  • "L'Ingegnere sa quello che fa e fa quello che sa".
    • Spagnotto Ing. Mirko
Re:[RISOLTO]strano risultato di parte frazionale di un numero in stringa
« Risposta #6 il: Maggio 12, 2021, 11:06:10 am »
@antoniog

Caro collega Ing., altro che computer e software....io sono cresciuto col regolo calcolatore e la precisione del metro "a bacchette" da cantiere. Bei tempi.... :'(

SB

  • Scrittore
  • Sr. Member
  • *****
  • Post: 283
  • Karma: +1/-0
Re:[RISOLTO]strano risultato di parte frazionale di un numero in stringa
« Risposta #7 il: Maggio 12, 2021, 05:46:47 pm »
Ringrazio SB e DragoRosso per avermi rinfrescato alcune nozioni. Mi occupo da oltre 30 anni di gestionali e fortunatamente ancora oggi non soffro di un galoppante "analfabetismo di ritorno".
È praticamente impossibile un dialogo sereno fra informatici puri ed un semplice ingegnere civile quasi del tutto autodidatta in informatica che cerca le procedure e funzioni di sistema per ottenere i risultati che gli interessano cercando di non complicarsi la vita. Per esperienza la precisione che viene richiesta non va oltre i quatro decimali e quindi se ho 15 o 7 cifre posso dire che ne ho fin troppe e sono costretto ad arrotondare.
Posso andare oltre e superare quanto finora discusso con questo semplice codice:
Codice: [Seleziona]
   mNumber:= RoundTo(quickevaluate(s,[],[]),-2);
...
   mNum:=Frac(mNumber);
   St:= IntToStr(Trunc(mNum * 100));

Codice: [Seleziona]
          mNumber:= RoundTo(StrToFloat(s),-2);
...
          St:= IntToStr(Trunc(mNum * 100));
il segreto è RoundTo() in entrambi i casi.

Perdonami, ma se i decimali sono così importanti per il tuo lavoro forse è meglio insistere su questo punto per evitarti problemi.
Ribadisco che il punto critico del tuo codice è il trunc(), che sarebbe da evitare
Qualunque cosa esca dal RoundTo() in generale non è un numero decimale esatto a due cifre, ma una rappresentazione binaria di un numero molto vicino
Non escluderei a priori l'esistenza di numeri arrotondati a 2 cifre decimali che moltiplicati per 100 e troncati siano diversi da quello che ti aspetti

Come ti ha fatto notare DragoRosso, è meglio non sottovalutare i problemi di precisione nei numeri
Le 7 o 15 cifre significative sono quelle totali, non quelle dopo la virgola, mentre tu parli di 4 cifre dopo la virgola
Nell'esempio che hai pubblicato, il numero 80237.68 usa 7 cifre significative. Sei al limite per il tipo float.
Se aggiungi 2 cifre sei già fuori precisione e necessiti di un double.

Se ho compreso la tua esigenza, che sembra simile a quella che si ha in campo economico dove si lavora con i centesimi di euro, ti consiglio di prendere in considerazione altri tipi di dati numerici.
Esistono tipi di dati che internamente lavorano direttamente con la rappresentazione decimale del numero ed evitano per quanto possibile problemi di conversione binaria
Vedi ad esempio BCD
Ovviamente hanno un costo computazionale più elevato, ma li hanno inventati proprio per gestire situazioni di questo tipo.





antoniog

  • Scrittore
  • Sr. Member
  • *****
  • Post: 257
  • Karma: +0/-0
    • Informatica Utile
Re:[RISOLTO]strano risultato di parte frazionale di un numero in stringa
« Risposta #8 il: Giugno 12, 2021, 11:40:17 am »
Caro Doc,
anch'io ho usato il regolo calcolatore ed anche le tavole logaritmiche, quando i calcoli si facevano a "spanne" stimando il risultato e spesso usando anche i prontuari Santarella e Torsello. I risultati erano attendibili senza tante scene grafiche e il calcolatore sapeva quello che faceva mentre oggi, spesso, non lo sa, inserisce alcuni dati ed ottiene il risultato, facile e pericoloso. Il computer per me è sempre stato un hobby, una passione portata avanti dalla metà degli anni '80 anche con qualche soddisfazione ma sempre e solo con la finalità di supporto ed automazione delle routine più noiose per chi sa quello che fa.
avrai solo la libertà che riuscirai a conquistarti e anche questa sarà incerta.

antoniog

  • Scrittore
  • Sr. Member
  • *****
  • Post: 257
  • Karma: +0/-0
    • Informatica Utile
Re:[RISOLTO]strano risultato di parte frazionale di un numero in stringa
« Risposta #9 il: Giugno 12, 2021, 11:46:06 am »
SB
grazie del consiglio, lo terrò in debita considerazione.
avrai solo la libertà che riuscirai a conquistarti e anche questa sarà incerta.

doc

  • Jr. Member
  • **
  • Post: 96
  • Karma: +2/-0
  • "L'Ingegnere sa quello che fa e fa quello che sa".
    • Spagnotto Ing. Mirko
Re:[RISOLTO]strano risultato di parte frazionale di un numero in stringa
« Risposta #10 il: Giugno 12, 2021, 09:50:21 pm »
Vedo che il problema sul formato numerico ha suscitato un bell'interesse....un pò come il "casino" che si crea quando si pretende di ottenere la massima precisione numerica nel calcolo, usando perciò il tipo Extended, ma poi ci si scorsa che compilando il tutto per Windows a 64 bit e destinazioni non Intel Extended è un alias per Double (ossia il tipo Extended viene convertito, in automatico, dal compilatore nel formato Double). A volte, nella ricerca della massima precisione nel calcolo numerico (ma non solo lì), si perde quello che è il fulcro del problema: il pc è una macchina, con delle limitazioni, che opera secondo istruzioni precise e con un suo linguaggio determinato; non pensiamo che possa essere un "cervello artificiale" in grado di pensare ed agire come il nostro.....al momento non lo fa ancora, in un futuro...mah!

Quando si scrive un programma di calcolo numerico occorre sempre pensare (almeno io faccio così) ai seguenti punti:
1) quale tipo di dato avrò in input?
2) quale è la precisione del dato di input?
3) come voglio gestire sub-dati intermedi?
4) quale tipo di dato avrò in output?
5) quale è la precisione del dato di output?

Un chiaro esempio lo si può ottenere quando ho la necessità di salvare su di un file temporaneo dei dati numerici. Quale tipo di file uso? Molti commettono l'errore, forse perchè vogliono poter leggere chiaramente cosa contiene quel file, di usare il tipo Text. Non dico che non vada bene, ma per la miseria quante volte vogliamo far fare al nostro programma la conversione numero -> stringa e viceversa? Questa continua conversione non è immune da errori.
Quindi cerchiamo di usare il tipo più adatto alle nostre esigenze ma anche il più conforme alla compilazione che vogliamo ottenere.

@ antoniog
Purtroppo i software di calcolo strutturale, sempre più orientati agli elementi finiti, sono da un lato uno strumento potentissimo (per chi conosce la teoria alla base di tale metodologia di calcolo) mentre dall'altro una fonte infinita di possibili errori di progetto (poi le cose crollano!!!). Facendo un esempio: ho visto neo-ing modellare un setto attraversato da una trave....ma quando mai una trave attraversa un setto in c.a.? Il modello numerico-matematico proposto dal programma ha portato ad una soluzione (il processo convergeva)....peccato che era sbagliata (sottostimava fortemente il momento d'incastro). Per non parlare di chi confonde le proprietà di un elemento finito con l'altro: un plane stress element viene definito da funzioni completamente diverse rispetto ad un plane strain element!!!

 

Recenti

How To

Utenti
  • Utenti in totale: 803
  • Latest: maXim.FI
Stats
  • Post in totale: 19194
  • Topic in totale: 2289
  • Online Today: 66
  • Online Ever: 900
  • (Gennaio 21, 2020, 08:17:49 pm)
Utenti Online
Users: 1
Guests: 49
Total: 50

Disclaimer:

Questo blog non rappresenta una testata giornalistica poiché viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge n. 62/2001.