Icon View Thread

The following is the text of the current message along with any replies.
Messages 11 to 20 of 20 total
Thread Problems with rounding figures (floats)
Thu, Jun 28 2007 8:55 AMPermanent Link

Chris Holland

SEC Solutions Ltd.

Avatar

Team Elevate Team Elevate

The link works for me

Chris Holland


Adam H. wrote:
> Hi Walter,
>
>> http://cc.codegear.com/Author/358
>
> Thanks for the link, but I'm getting an "Server application Unavailable"
> error. Is anyone else able to access this?
>
> Thanks
>
> Adam.
>
>
Thu, Jun 28 2007 7:10 PMPermanent Link

"Adam H."
Hi,

The link seems to be working for me now to - thanks for that.

However, I'm still very confused about the issue. The link provides some
source code on how to deal with rounding, but I'm still unsure as to when to
apply this, or what is the industry standard in dealing with decimal values.

ie:

Do I apply this before saving any numeric values to a dataset, or are
databases incapable of storing true values, making this pointless - so
instead should I be creating a float variable everytime I want to use a
numeric value, and when collecting the values from the dataset, should I be
putting it through one of these rounding routines?

Should I be doing this procedure every single time I want to work with
decimal values (ie, adding and  subtracting) or is it only needed if I'm
dividing or multiplying?

How should I then work with dbGrids? (ie, How do we get DBGrids to show
1.295 and not 1.29499~999?)

In my instance, I have a BCD set to round to 4 decimal places, but will
almost always have only 2 decimal places showing. Therefore, on the
TFloadfield, I set the display value to 0.00##. However, on the odd
occasion, the value reported is still something like 16.2501 when the value
should be 16.25. If the value is *truely* 16.2501 I want the grid to be able
to display this, but I would also like to be able to store a true value of
16.25 and difereenciate between the two.

In my experience, Grids almost always show the correct value, but it's only
on the odd occasion that they show the wrong value? Is this most likely
because datasets are capable of storing the correct value, but it's the
calculations prior to saving the data to the dataset that is causing the
rounding issue?

Matters that even confuse me more include the fact that when previously
using my own rounding function, one computer would round correctly, and yet
another computer would go out to 4 decimal places, with the same value in
the same dataset.

In the provided link, it says that the rounding procedures are for D2 to D7.
Does this mean that D2007 doesn't have these rounding issues (ie, fixed
automatically by the compiler), and by upgrading to D2007 it will fix my
problem without having to recode everywhere in my application that deals
with decimals?

From what I've able to guess so far, it appears as though the issue isn't
with the actual stored values, but moreso when passing them through
variables in the memory, but the more I read on the subject, the more I'm
questioning whether this is the case.

How do you guys deal with decimals? Do you round variables every time you
make a calculation, or  round before saving variables to a dataset, or round
variables after retrieving the information from a dataset?

Thanks for all your help (and patience!) From the provided posts I know I
should be understanding this, but I'm simply not 'getting it' at the moment.

Cheers

Adam.

Fri, Jun 29 2007 5:13 AMPermanent Link

"Malcolm"
Adam

As you will know, many decimal fractions cannot be exactly represented
in binary.

In my case I just accept that the stored values may not be exact and if
there are any computations between such values it gets even more likely
that the values are not exact.

So for display (the easy part) I simply display to the precision
required.

For comparisons or selections I allow a little lattitude and do things
like:

 if ((floatingpointvalue < 26.2301) and (floatingpointvalue >
26.2299)) then it is equal to 26.23.  Naturally I use a suitable
precision for the comparison given the data I expect.

Not sure if this helps...

Malcolm
Fri, Jun 29 2007 7:29 AMPermanent Link

"Robert"

"Adam H." <ahairsub4@rREMOVEMEspamSTOPPER.jvxp.com> wrote in message
news:BAC9A003-74EF-46A3-9D3E-1F3E405A7FEA@news.elevatesoft.com...
>
> Should I be doing this procedure every single time I want to work with
> decimal values (ie, adding and  subtracting) or is it only needed if I'm
> dividing or multiplying?
>

You need to do it AFTER multiplying or dividing. The key, as I said before,
is doing the rounding using currency. Then you get for sure rid of those
pesky small decimals. I'm talking about Delphi currency type, not any
database's.

Robert


Fri, Jun 29 2007 7:48 AMPermanent Link

"Robert"

"Malcolm" <malcolm@spam.will.bounce> wrote in message
news:F5EFA9BA-091B-48C4-9C1A-D7962461B71A@news.elevatesoft.com...
>
> In my case I just accept that the stored values may not be exact and if
> there are any computations between such values it gets even more likely
> that the values are not exact.
>
> So for display (the easy part) I simply display to the precision
> required.
>

That brings its own set of problems.

Say you have 10 items with a value of 2.4445. They all get displayed and
totalled in a report or a grid, using 2 decimals.

Each item will display as 2.45. The total will be 24.445, displayed as
24.45. But anybody can eyeball that report and see that the total "should
be" 10 times 2.45, or 24.50. See the problem?

> For comparisons or selections I allow a little lattitude and do things
> like:
>
>  if ((floatingpointvalue < 26.2301) and (floatingpointvalue >
> 26.2299)) then it is equal to 26.23.  Naturally I use a suitable
> precision for the comparison given the data I expect.
>

Comparisons are the killer, and why you need to round after every divide or
multiply. You put a filter "current_balance <> 0" and an item with a balance
of 0.001 gets displayed. So you change your filter to "current balance <
0.01" and then the negatives don't get displayed. And on and on.

Robert


Fri, Jun 29 2007 9:23 AMPermanent Link

"Adam H."
Hi Robert,

I think the penny's just dropped!

> You need to do it AFTER multiplying or dividing. The key, as I said
> before, is doing the rounding using currency. Then you get for sure rid of
> those pesky small decimals. I'm talking about Delphi currency type, not
> any database's.

Whenever I've searched on this topic, (and reading your previous posts),
I've seen people say to use Currency or BCD's instead of float's to fix this
issue. I was using BCD's, but I was thinking in terms of *data* fields - not
variant types. (I wasn't even aware that a "Currency" type existed for
variables, and mistook this to mean a currency data field!)

You just clarified it by mentioning the "Delphi currency type" and not any
databases!

I've just had a bit of a play with the currency variable, and see that it's
limited to 4 decimal places. Perfect for what I'm after!

Thanks all for your help!

Best Regards

Adam.

Fri, Jun 29 2007 9:25 AMPermanent Link

"Adam H."
Hi Malcolm,

Thanks for your reply. It would appear as though the solution I'm after is
to use Currency variables instead of double variables. (Not talking
datafields here, but Delphi/Pascal variable types).

For what I need, I can't see that I'll be using doubles again for a long
time - pretty tempted to just to a bulk search and replace in my application
to change any double 'variables' to currency type. I think that would do
exactily what I need!

Cheers

Adam.

Fri, Jun 29 2007 10:08 AMPermanent Link

"Robert"

"Adam H." <ahairsub4@rREMOVEMEspamSTOPPER.jvxp.com> wrote in message
news:28DF98B1-F407-482C-97C9-A761DF8EF097@news.elevatesoft.com...
> Hi Malcolm,
>
> Thanks for your reply. It would appear as though the solution I'm after is
> to use Currency variables instead of double variables. (Not talking
> datafields here, but Delphi/Pascal variable types).
>
> For what I need, I can't see that I'll be using doubles again for a long
> time - pretty tempted to just to a bulk search and replace in my
> application to change any double 'variables' to currency type. I think
> that would do exactily what I need!
>

Hold your horses SmileyYou still need to round (using Delphi currency type)
when you multiply and divide, and otherwise it does not matter, so why
change it?

Robert


Fri, Jun 29 2007 7:01 PMPermanent Link

"Adam H."
Hi Robert,

>> For what I need, I can't see that I'll be using doubles again for a long
>> time - pretty tempted to just to a bulk search and replace in my
>> application to change any double 'variables' to currency type. I think
>> that would do exactily what I need!
>>
>
> Hold your horses SmileyYou still need to round (using Delphi currency type)
> when you multiply and divide, and otherwise it does not matter, so why
> change it?

Ok - now I'm confused again. Smiley

Let's say I had the figure 2.5, and I decided to divide by 2.

In double's, it's possible that it would store the answer as 1.2499999999~9

But with currency types, being only available to 4 decimal places, wouldn't
it store that figure as 1.25?

I understand the need to round if the answer would have many decimal places,
but for basics as per the above do we still have the same problem with
currency types too?

If that's not the case - what is the benefit of using Delphi Currency type
variables?

(I'm also assuming to now, that databases have no problems whatsoever in
storing a decimal value like 1.25 in a float field, but it's the variable
that's originally passed to it that is what's causing the problem)

Thanks & Regards

Adam.

Tue, Jul 3 2007 12:58 PMPermanent Link

Chris Erdal
"Adam H." <ahairsub4@rREMOVEMEspamSTOPPER.jvxp.com> wrote in
news:2AF4B5CE-C1F1-494C-A287-A03E8DF48665@news.elevatesoft.com:

> Hi Robert,
>
> I think the penny's just dropped!
>
>> You need to do it AFTER multiplying or dividing. The key, as I said
>> before, is doing the rounding using currency. Then you get for sure
>> rid of those pesky small decimals. I'm talking about Delphi currency
>> type, not any database's.
>
> Whenever I've searched on this topic, (and reading your previous
> posts), I've seen people say to use Currency or BCD's instead of
> float's to fix this issue. I was using BCD's, but I was thinking in
> terms of *data* fields - not variant types. (I wasn't even aware that
> a "Currency" type existed for variables, and mistook this to mean a
> currency data field!)
>
> You just clarified it by mentioning the "Delphi currency type" and not
> any databases!
>
> I've just had a bit of a play with the currency variable, and see that
> it's limited to 4 decimal places. Perfect for what I'm after!
>

Adam,

 You should store any Delphi currency values in DBISAM's BCD type, as
DBISAM's Currency type is a float.

I tripped up on that coming from Paradox where (IIRC) the Currency field
was an exact number type same as the Delphi Currency type, and my
converted application started losing euro-centimes after years of
stability...

--
Chris
(XP-Pro + Delphi 7 Architect + DBISAM 4.25 build 4 + EDB 1.04 build 3)

« Previous PagePage 2 of 2
Jump to Page:  1 2
Image