# Round

## Recommended Posts

Good Day,

var

a,b : Double

a:= 66,3333

b:= 1,5

c:= a* b ( Delphi shows  c:= 99,5,   actually c should be 99,49995 )

How can i get exact result ( 99,49995 ) ?

Thank You

How do you display the result? You can control the number of decimals displayed when converting a floating-point value from its internal binary (not decimal!) representation, but the exact syntax depends on the function you use (Write, WriteLn, Format, FormatFloat, FloatToStr, FloatToStrF etc. The run-time library has accumulated quite a number of such conversion functions over time. Oh, and the result of your multiplication is actually not exactly  99,49995 since the computer stores numbers as binary and not as decimal, and since it only has a limited number of bits available many decimal numbers cannot be stored without a small loss of precision. These errors accumulate over calculation steps...

Thank you so much Peter

I dont convert anything

My Code =

a:= MyQuery.FieldByName('TOTAL').asFloat;    (which is 66,3333.-)

b:= MyQuery.FieldByName('RATIO').asFloat;   (Which is 1,50 );

c:= a * b;   // In Debug i see c as 99,50  instead of  99,4999

MyTable.Edit;

MyTableBENF.asFloat := c;   // i was expecting to see in mytable's BENF field  99,49 not 99,50

(BENF field in firebird3 database is as Numeric(15,2)

(In Delphi my table's releated field's Currency proporties = True)

```var
a, b, c: Double;
begin
try
a := 66.3333;
b := 1.5;
c := a * b;
WriteLn(FloatToStrF(c, ffFixed, 16, 5));
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.```

Output: 99,49995

Guys, I think the problem reported above is more related to the Database than to Delphi itself and its adventures!
We must remember that the numbers, as reported above, are stored binary, not decimal!
And, when you define a field of type NUMERIC/DECIMAL 15x2, then, we must remember the range of the smallest and largest value that can be stored in this field! For that, you can check the Database or Delphi documentation.

See the example using Firebird 4.02, I created 6 fields:

Quote

CREATE TABLE MYTABLENUMERIC (
FNUMERIC15X2 NUMERIC(15,2),
FNUMERIC15X3 NUMERIC(15,3),
FDECIMAL15X2 DECIMAL(15,2),
FDECIMAL15X3 DECIMAL(15,3),
FNUMERIC15X5 NUMERIC(15,5),      <-------   try keep the "precision"
FDECIMAL15X5 NUMERIC(15,5)       <-------   maybe not as you see on "precision storing"
);

and using the formula from the first post, see the results:

```implementation

{\$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
FDQuery1.Open;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
a, b, c: double;
begin
a          := 66.3333;
b          := 1.5;
c          := a * b;
Edit1.Text := c.ToString;
//
FDQuery1.Append;
FDQuery1.Fields[0].AsFloat := c;
FDQuery1.Fields[1].AsFloat := c;
FDQuery1.Fields[2].AsFloat := c;
FDQuery1.Fields[3].AsFloat := c;
FDQuery1.Fields[4].AsFloat := c;
FDQuery1.Fields[5].AsFloat := c;
FDQuery1.Post;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
FDConnection1.Close;
end;

end.```

NOTE Now, YOU can use "DisplayFormat" to show your value in another "MASK"  for example:  0.##,  ###,00   etc... but the "real value stored on database" is another of course!

Edited by programmerdelphi2k

Firebird/InterBase® converts the columns as follows:

Definition Data type Created
Decimal(1)-Decimal(4) Small Integer
Decimal(5)-Decimal(9) Integer
Decimal(10)-Decimal(18) Int (64)

Note that if a DECIMAL(5) data type is specified, it is actually possible to store a value as high as a DECIMAL(9) because Firebird/InterBase® uses the smallest available data type to hold the value. For a DECIMAL(5) column, this is an INTEGER, which can hold a value as high as a DECIMAL(9).

## Enhancement in precision of calculations with NUMERIC/DECIMAL (Firebird 4.0)

Supported in IBExpert since version 2017.12.03.

Function

Maximum precision of NUMERIC and DECIMAL data types is increased to 34 digits.

Author Alex Peshkoff <peshkoff@mail.ru>

Syntax rules

```    NUMERIC ( P {, N} )
DECIMAL ( P {, N} )
where P is precision (P <= 34, was limited prior with 18 digits) and N is optional number
of digits after decimal separator (as before).
```

Storage

128-bit, format according to IEEE 754.

Example(s)

```    1. DECLARE VARIABLE VAR1 DECIMAL(25);
2. CREATE TABLE TABLE1 (FIELD1 NUMERIC(34, 17));
```

Note(s)

Numerics with precision less than 19 digits use SMALLINT, INTEGER, BIGINT or DOUBLE PRECISION as base datatype depending upon number of digits and dialect. When precision is between 19 and 34 digits DECFLOAT(34) is used for it. Actual precision is always increased to 34 digits. For complex calculations such digits are casted (internally, in trivial way) to DECFLOAT(34) and the result of various math (log, exp, etc.) and aggregate functions using high precision numeric argument is DECFLOAT(34).

--------

Edited by programmerdelphi2k

5 hours ago, Henry Olive said:

var

a,b : Double

a:= 66,3333

b:= 1,5

c:= a* b

What language is this? It's not Delphi.

Also, your expectation is incorrect. This is what Python says the right answer is:

```>>> 66.3333 * 1.5
99.49994999999998```

I expect that if you showed your actual code, it would be clear what is going on.

21 minutes ago, programmerdelphi2k said:

I think the problem reported above is more related to the Database

Where in the question is a database mentioned?

Edited by programmerdelphi2k

And for those who are "blind" due to constant and innate bad temper...

• FDQUERY ->> accesses a data source in a DATABASE!
3 hours ago, Henry Olive said:

(BENF field in firebird3 database is as Numeric(15,2)

3 hours ago, Henry Olive said:

My Code =

a:= MyQuery.FieldByName('TOTAL').asFloat;    (which is 66,3333.-)

b:= MyQuery.FieldByName('RATIO').asFloat;   (Which is 1,50 );

c:= a * b;   // In Debug i see c as 99,50  instead of  99,4999

MyTable.Edit;

Edited by programmerdelphi2k

Does Python have an RTL and Delphi Object PASCAL forum?

the question remains

to "force" usage +decimals you can try this:

varX * ( varY + 0.00000) should sum decimals places on resulted

14 hours ago, David Heffernan said:

Where﻿ in ﻿the question is a database mentioned﻿?

OK, there seem to be two questions asked by @Henry Olive

The first one doesn't have any mention of a database, but has code that does not compile. The second question has database but we don't know what the values are.

@Henry Olive you can't get a definitive answer unless we have precise details of what the data is.

One thing we can say is that floating point multiplication is correct in Delphi.

Edited by David Heffernan

Thank you SO much David, KodeZwerg, Programmer

I solved the problem.