Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
Solved

# Rounding numbers

Posted on 2004-08-12
Medium Priority
549 Views
Hi.

There is a form with 2 buttons.

Button1 OnClick event looks like this:

procedure TForm1.Button1Click(Sender: TObject);

function RoundedAmount(R: double; D: Longint): Double;

function SymbolOf(Nbr: Double): Double;
begin
if Nbr < 0 then
Result := -1
else
Result := 1;
end;

function NbrExponentOf(Nbr: Double; Exponent: Integer): Double;
begin
Result := 1;

while Exponent < 0 do
begin
Result := Result / Nbr;
Exponent := Exponent + 1;
end;

while Exponent > 0 do
begin
Result := Result * Nbr;
Exponent := Exponent - 1;

end;
end;

var
P: double;
X: double;
dNbrExp: double;

begin
P := SymbolOf(R) * 0.5;
dNbrExp := NbrExponentOf(10, D);
X := R * dNbrExp + P;
Result := int(X) / dNbrExp;
end;

begin
showmessage(FloatToStr(RoundedAmount(0.105, 2)));
end;

And here is Button2.OnClick event:

procedure TForm1.Button2Click(Sender: TObject);

function RoundedAmount(R: double; D: Longint): Double;

function SymbolOf(Nbr: Double): Double;
begin
if Nbr < 0 then
Result := -1
else
Result := 1;
end;

function NbrExponentOf(Nbr: Double; Exponent: Integer): Double;
begin
Result := 1;

while Exponent < 0 do
begin
Result := Result / Nbr;
Exponent := Exponent + 1;
end;

while Exponent > 0 do
begin
Result := Result * Nbr;
Exponent := Exponent - 1;

end;
end;

var
P: double;

begin
P := SymbolOf(R) * 0.5;
Result := Int(R * NbrExponentOf(10, D) + P) / NbrExponentOf(10, D);
end;

begin
showmessage(FloatToStr(RoundedAmount(0.105, 2)));
end;

The only difference is the inline "RoundedAmount" which is slightly different between Button1 and Button2.  "RoundedAmount" is supposed to round an amount of money  (No I CANNOT use any Delphi's Math functions like RoundTo.  The point isn't there anyways).  Here are the only differences between the 2 functions:

With Button2, I calculate RESULT on a single line:

P := SymbolOf(R) * 0.5;
Result := Int(R * NbrExponentOf(10, D) + P) / NbrExponentOf(10, D);

With Button1, I calculate RESULT using multiple variables so it can stand on multiple lines:

P := SymbolOf(R) * 0.5;
dNbrExp := NbrExponentOf(10, D);
X := R * dNbrExp + P;
Result := int(X) / dNbrExp;

At first look, both functions should give the same result, right ?.  And that is my problem: IT DOES NOT!!
When I hit Button1 I get 0.11 and with Button2 I get 0.1.

My question is simple: why is that ?  How can I fix this ?
0
Question by:qas
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 10
• 7

LVL 7

Expert Comment

ID: 11786936
I cant see the problem, however if you want to check out some of the delphi functions, to see if they do what they should, then I have found this site to be very useful

http://www.delphibasics.co.uk

David
0

LVL 7

Expert Comment

ID: 11786984
Double, http://www.delphibasics.co.uk/RTL.asp?Name=Double
Extended http://www.delphibasics.co.uk/RTL.asp?Name=Extended
LongInt http://www.delphibasics.co.uk/RTL.asp?Name=LongInt
Int http://www.delphibasics.co.uk/RTL.asp?Name=Int

is it anything to do with when you are adding 'P' ? try sticking brackets into it...
Result := Int(R * (NbrExponentOf(10, D) + P)) / NbrExponentOf(10, D);

0

Author Comment

ID: 11787204
Thanks David

When you say that you dont see the problem, do you mean that you tried the code and everything worked fine or that it doesn't and you can't say why ?
0

LVL 7

Expert Comment

ID: 11787240
sorry, looking over the code I couldnt see any thing except where you add P, I'll try the code in a moment, im trying to solve a problem of my own in delphi ;)

DAvid
0

Author Comment

ID: 11787290
I placed the brackets in both functions and it didn't changed anything.

A problem in Delphi ?  Sorry, never happenned to me ;)
0

LVL 7

Expert Comment

ID: 11787328
looking @ it now, cant see anything, but if you place brackets around the line
X := R * dNbrExp + P;
in the first button like this
X := R *( dNbrExp + P);

it will return .1  ? but change the line on button 2

Result := Int( (R * NbrExponentOf(10, D)) + P) / NbrExponentOf(10, D);

but it still returns 0.1 ?

DAvid
0

LVL 7

Expert Comment

ID: 11787401
its something to do with the int function

P := SymbolOf(R) * 0.5;
B:=  NbrExponentOf(10, D);
Result :=  Int((R *B) + P) ;
Result := (result) / B

will give 0.1

P := SymbolOf(R) * 0.5;
B:=  NbrExponentOf(10, D);
Result :=  ((R *B) + P) ;
Result := Int(result) / B

give 0.11

it must be something to do with delphi.... is there anything on the borland website... *looking*

David
0

Author Comment

ID: 11787427
Yes it's true.  I also tried it with trunk() with same result.
0

LVL 7

Expert Comment

ID: 11787452
not sure if this helps but  according to http://www.efg2.com/Lab/Library/Delphi/MathFunctions/General.htm

int will round DOWN to 0 which would explain it... it must be working out the int function (with 10.5) without adding the value of P (0.5)

which result did you get? what code?

David
0

Author Comment

ID: 11787667

>which result did you get? what code?
I just replaced the int function with the trunc function (which should work the same way) and it gave me the same erroneous results (0.1 and 0.11).

It is normal that the int rounds down to 0.  That is actually why it is used in the function, to get rid of the remaining digits.

The thing I can't understand is that if...

((R *B) + P) = 11

...and...

Int(11) = 11

...why would...

Int((R *B) + P) = 10 ??

Does ((R *B) + P) actually gives someting like 10.99999999... or what ?
0

LVL 7

Accepted Solution

DavidBirch2dotCom earned 1000 total points
ID: 11787748
I think that the int function only works on the (R *B) for some unkown reason... Borland dont know thier BODMAS ;)  (BODMAS = Brackets Over Division Multiplaction Addition Subtraction)
0

Author Comment

ID: 11788001
That is just great.

How the hell am I supposed to get back to people telling me that Delphi sucks and VB rocks now ?  If that is the problem, Delphi DOES suck.  We're talking about basics here damnit !

Thanls a lot David for your help :)

0

LVL 7

Expert Comment

ID: 11788035
thats the first time i have seen it do that , in every other time and function it works normaly, just a querk with that one function, its the first delphi bug ive come accross in 2-3 years.. of delphi.

personaly, from dabbles into VB from outlook and excel VB sucks ;) but i never really go into it so...

David
0

LVL 7

Expert Comment

ID: 11788044
many thanks for the points :)
0

Author Comment

ID: 11788115
My pleasure :)

Just a last question if you have a second.  Lets say I have:

P := 12;
P := 25;
showmessage(inttostr(P));

Delphi wont compile the first line since the assigned value aint used.  Can I force Delphi to compile it anyway ?  Maybe our problem is around such optimization...
0

LVL 7

Expert Comment

ID: 11788151
erm, how would you tell if it did or didnt compile it ?

didnt know delphi didnt compile it?

DAvid
0

Author Comment

ID: 11788310
Yes, Delphi kind of optimizes the code so that useless lines arent compiled at all.

For example, make a function and never call it.  When you compile it, no little blue dots are drawn on the left margin.  The function wont be compiled.

Another example is to try the sample code:

P := 12;
P := 25;
showmessage(inttostr(P));

Try putting a Break Point on the 1st line, it wont stop on it.

If Delphi decides that some brackets are useless and removes them, there could be our problem.

But if you dont know how to remove the optimization, that is ok.  You helped me alot already :)

Thanks again!

0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have toâ€¦
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usuaâ€¦
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a qâ€¦
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for â€¦
###### Suggested Courses
Course of the Month9 days, 2 hours left to enroll