La divisione con risultato intero deve essere effettuata tramite la funzione DIV:
var
a, b, c: cardinal;
a := b div c;
La problematica di gestione dei numeri è costante ed è stata già affronta più volte nel forum.
Uno dei trucchi è quello di avere i numeri "moltiplicati per il fattore di precisione":
var a_cen, b, c: cardinal;
a_cen := (b*100) div c; //il risultato è in "centesimi" ....
Questa tecnica viene usata normalmente quando si ha a che fare con i sistemi di automazione industriale.
Di altro c'è la fantasia oltre che la normalità già spiegata dai precedenti post.
N.B.: ATTENZIONE ..... 2.0 / 2.0 potrebbe non fare sempre 1 :o
P.S.: non usare definizioni come real, float, o simili. Usa o "single" per la precisione singola o "double" per la precisione doppia che è anche quella più usata per la numerazione in virgola mobile.
Tre risposte molto utili: non ricordavo FloatToString(!!)e avevo dimenticato il trucchetto di moltiplicare per 100 / 1000 per poi dividere nuovamente per 100 / 1000. Unica differenza: assegnare la variabile come Real (Cardinal genera errore).
Nello screenshot il mix dei consigli che hanno risolto il problema:
procedure TForm1.Button1Click(Sender: TObject);
Var Sinistra: Integer;
Var Sin_decimale: Real; // NO Cardinal;
begin
Sinistra:= Button1.Left; // Valore Intero (proprietà .Left)
Sin_decimale:= ((Sinistra*1000) div 3) / 1000; // Variabile Real
ShowMessage('Risultato finale: ' + FloatToStr(Sin_decimale));
end;
potrebbe dipendere dalla formattazione che hai usato per convertire in stringa
(floattostr sceglie il formato più conveniente in modo automatico)
con questo codice, il risultato lo vedi nell'allegato
forzando le cifre decimali a 16, il double è più preciso
procedure TForm1.Button1Click(Sender: TObject);
var s: single;
d: double;
sapp: string;
begin
s := 92 / 3;
d := 92 / 3;
sApp := Format('Risultati:' + LineEnding +
'single = %20.16f' + LineEnding +
'double = %20.16f', [s, d]);
ShowMessage(sapp);
end;
Edit:
un altro controllo che puoi fare è quello di guardare il contenuto delle variabili a runtime con il debugger
ma ricorda che si tratta sempre di una conversione in stringa :)
Create una nuova applicazione, metteteci due pulsanti e fate doppio click sui due pulsanti, poi sovrascrivete tutto col codice qui sotto (basta anche solo la parte implementation):
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
type
TConverterRec = packed record
case Boolean of
false: (ByteArray: array[0..7] of Byte);
true: (FloatValue: Double);
end;
var
Pippo: TConverterRec;
procedure TForm1.Button1Click(Sender: TObject);
var d: double;
begin
d := 0.43; // $85EB51B81E85DB3F Valore 0,43 in double float
//Pippo.FloatValue := d;
Pippo.ByteArray[0] := $85;
Pippo.ByteArray[1] := $EB;
Pippo.ByteArray[2] := $51;
Pippo.ByteArray[3] := $B8;
Pippo.ByteArray[4] := $1E;
Pippo.ByteArray[5] := $85;
Pippo.ByteArray[6] := $DB;
Pippo.ByteArray[7] := $3F;
ShowMessage('Valore 0,43 = '+floattostr(Pippo.FloatValue));
//Sommiamo 9 al primo byte byte (per verificare le cifre significative e la rappresentatività)
inc(Pippo.ByteArray[0], 9);
ShowMessage('Incremento ultima cifra di 9 del Valore 0,43 = '+floattostr(Pippo.FloatValue));
//Non cambia .... dobbiamo sommare almeno 10 (9 di prima più 1) al primo byte byte (per verificare le cifre significative e la rappresentatività)
inc(Pippo.ByteArray[0], 1);
ShowMessage('Incremento ultima cifra di 10 del Valore 0,43 = '+floattostr(Pippo.FloatValue));
//però ora facciamo i cattivi: proviamo a sommare il valore precedente (quello che anche se aveva 9 in più veniva visto come 0,43) a se stesso
dec(Pippo.ByteArray[0], 1);
ShowMessage('(Incremento ultima cifra di 9 del Valore 0,43) * 2 = '+floattostr(Pippo.FloatValue+Pippo.FloatValue));
//OHH inciminciano i primi "disturbi ... ma il numero originale avrà anche lui questi problemi ?
Pippo.FloatValue := d;
ShowMessage('Valore 0,43 * 2 = '+floattostr(Pippo.FloatValue+Pippo.FloatValue));
//No, non li ha
end;
procedure TForm1.Button2Click(Sender: TObject);
var d: double;
begin
d := 100.43; // $EC51B81E851B5940 Valore 100,43 in double float
//Pippo.FloatValue := d;
Pippo.ByteArray[0] := $EC;
Pippo.ByteArray[1] := $51;
Pippo.ByteArray[2] := $B8;
Pippo.ByteArray[3] := $1E;
Pippo.ByteArray[4] := $85;
Pippo.ByteArray[5] := $1B;
Pippo.ByteArray[6] := $59;
Pippo.ByteArray[7] := $40;
ShowMessage('Valore 100,43 = '+floattostr(Pippo.FloatValue));
//Sommiamo 9 al primo byte byte (per verificare le cifre significative e la rappresentatività)
inc(Pippo.ByteArray[0], 9);
ShowMessage('Incremento ultima cifra di 9 del Valore 100,43 = '+floattostr(Pippo.FloatValue));
//Non cambia .... dobbiamo sommare 10 (1 di prima più 9) al primo byte byte (per verificare le cifre significative e la rappresentatività)
inc(Pippo.ByteArray[0], 1);
ShowMessage('Incremento di 10 nell''ultima cifra del Valore 100,43 = '+floattostr(Pippo.FloatValue));
//Non cambia ancora.... dobbiamo sommare ulteriormente (non solo al primo byte ma dobbiamo combinare sia il primo che il secondo)
//Quindi, riassumendo è cambiata la rappresentività del numero, con una piccola variazione (10) ora il valore non sembra cambiare, con il 0,43 si ......
end;
end.
Eseguite e leggete i commenti, vedrete come si comportano apparentemente i numeri ..... o meglio come cambia di significato la rappresentazione: pensate pure se svolgete la semplice addizione mostrata 1000 o 100000 volte nel corso del programma ....
Ciao