Board index » delphi » Re: Avoiding floating points

Re: Avoiding floating points


2007-04-27 02:58:03 AM
delphi115
John Herbster writes:
Quote
"Jonathan Neve[Microtec]" <XXXX@XXXXX.COM>wrote
>... the compiler produces different code from the same
>source depending on its mood does seem to me to be
>a compiler bug. ...

It is not the compiler's mood; it is the date-time of
compilation. I don't know about the later compilers
in this regard, but Delphi 7 and earlier compiler encoded
the date in two or three dozen places within the EXE.

And yes, I think that it is a bug, too.

Perhaps so, but I think that is a different topic.
I think he is saying that for a particular line
of code, he can look at the CPU view and it will
have different code at different times for the same
source.
HTH,
Brad.
 
 

Re: Avoiding floating points

Jonathan Neve[Microtec] schrieb:
Quote
John Herbster writes:

>>>5 = 5.000000000 no matter how you slice it.
>
>"Jonathan Neve[Microtec]" <XXXX@XXXXX.COM>wrote
>>Not if you ask the FPU.
>>More likely, 5 = 4.99999999999999999999999999.
>Not so!

Ok, well, perhaps not for 5. But your own examples below illustrate my
point, which was simply that the user can not reliably get back exactly
the value they put in.
This is basic education stuff: you simply can not express numbers like 1/7
as exact decimal numbers. Same applies to the binary system. You can't
even represent all decimal numbers in a binary system. If this is an
issue for you, and you do only sub., add., mul. and div. simply write
your own math library calculating only using fractions.
Quote

>Using my IEEE Number Analyzer, for which the Delphi
>source code is available from
>cc.codegear.com/Item/23631,
>you can type in a decimal number and get the exact
>floating point value.

Thanks, that sounds useful.
 

Re: Avoiding floating points

"Brad White" <"remove spaces from b white at i nebraska com">wrote
Quote
... I think he is saying that for a particular line of code,
he can look at the CPU view and it will have different
code at different times for the same source.
With the same compiler and the same compiler option
settings, I'd be surprised if this is true, except for
the obvious dates scattered about and the version info.
Having those worthless date-times scattered about
the EXEs makes detecting other changes more of a
problem that it need be. About a year ago, I posted
a QC report on the problem. Judging from the lack of
interest in the QC report, I don't think that there are
very many application programmers interested in the
quality control of their software.
--JohnH
IDE produces different EXEs from same source
qc.borland.com/qc/wc/qcmain.aspx
 

Re: Avoiding floating points

Hi,
Quote

I hate floating points with a passion. Does anyone know of a simple way
to get rid of them and somehow be able to do elemetary calculations
without random imprecisions and unpredicitble and meaningless error
messages popping up out of no-where?
Do you required "much precision"? Have you considered using int64 to represent your
decimals numbers? You could represent 345.001 as the integer 345001.
Clément
 

Re: Avoiding floating points

Just wondering if there was a
Loren Pechtel writes:
Quote
On 26 Apr 2007 05:54:42 -0700, "AlexB" <XXXX@XXXXX.COM>writes:
Next semester the teacher asks me about it. I utterly astounded the
whole department with the following:

10 X = 3000000
20 X = X + 1
30 If X < X + 1 then goto 10
40 Print "X = X + 1"
Just wondering if line 30 has a typo, in that it should be going to
line 20, not line 10?
Cheers,
Nick
--
 

Re: Avoiding floating points

Quote
>10 X = 3000000
>20 X = X + 1
>30 If X < X + 1 then goto 10
>40 Print "X = X + 1"
"Nicholas Ring" <XXXX@XXXXX.COM>wrote
Just wondering if line 30 has a typo, in that
it should be going to line 20, not line 10?
Nicholas, I think that you are right. I looked at it,
noted the concept that Loren was intending, and
overlooked that error.
Will this ever finish?
var x: int64;
begin
x := 0;
While (x < high(x)) do inc(x);
ShowMessage('Finished with x='+IntToStr(x));
end;
Rgds, JohnH
 

Re: Avoiding floating points

Jonathan Neve[Microtec] writes:
Quote
Loren Pechtel writes:

>Agreed--money needs to be in something fixed. You need longints,
>though if you're going to do any percentages. Otherwise the initial
>multiplication will give overflow problems.

Nah, why use longints? Sure, you can store everything as cents... until
the day your customer tells you they now need to handle a third digit
on their prices (but not on the total amount of course)... No, messing
with multiplying and dividing by a power of 10 everywhere in your
application, is both error prone and tedious.

I suppose a BCD would be a more reasonable choice for such
circumstances...? I'd use them if, as I already mentioned, my
database supported it.
Hi Jonathon,
Perhaps look at this another way, if you were storing sentences in your
database and chopping off the last character because that is all that
would fit, would you expect to be able to retrieve the sentence exactly
as it was? Further if you wanted to concatenate those sentences into
paragraphs, then bits start to go missing in the middle, the problem
would be easy to see.
Well by using floats this is what you're doing to the numbers, it is just
that the effects of the truncation are less obvious at first, but they
are there.
What you can do is place a compatability layer in your app. Internally
in your app and database store the money as an int or BCD, only when its
displayed convert it to human readable form. All the operations
internally will be on your internal representation, not on floats. I'm
not quite sure what you meant by a third digit - fractions of a cent?
As I mentioned, if your database doesn't support BCD's you can store
them in a string (I've used varchars for Oracle in the past). Personally
I'd use ints, because then you have>and < support nativeley in the
database, unless there was a good reason not to.
For your current app that is using floats everywhere, I would start on
upgrading the problem areas to your new representation, then as time
goes by gradually move to your new representation as your modules are
rewritten as part of maintenance.
hth,
Dave
 

Re: Avoiding floating points

Jonathan Neve[Microtec] writes:
Quote
Hi all,

I hate floating points with a passion. Does anyone know of a simple way
to get rid of them and somehow be able to do elemetary calculations
without random imprecisions and unpredicitble and meaningless error
messages popping up out of no-where?

Thanks!
I've posted this before, but given the
ongoing discussion, I thought it was
relevant, and I would post it again.
"New IEEE 754r standard defines a single data type for integer, fixed-,
and floating-point decimal arithmetic that will be of interest for the
FPGA-based acceleration of financial calculations."
www.ddj.com/dept/architect/199100438
HTH,
Brad.
 

Re: Avoiding floating points

Jonathan Neve[Microtec] writes:
Quote
I hate floating points with a passion. Does anyone know of a simple way
to get rid of them and somehow be able to do elemetary calculations
without random imprecisions and unpredicitble and meaningless error
messages popping up out of no-where?
write better, less buggy code with appropriate error handling ?
Do recognize that floating point numbers are a BINARY (power of two)
representation of a REAL number, and as such are approximate. So there is no
such SINGLE value as 3.0 - but there is 2.9999979 or some such.
If you are after speed, then you could implement your own "fixed point" scheme
appropriate to your problem. A google search:
www.google.com.au/search
will give you all the info you need.
 

Re: Avoiding floating points

Florian Klaempfl writes:
Quote
Jonathan Neve[Microtec] schrieb:
>John Herbster writes:
>
>>>>5 = 5.000000000 no matter how you slice it.
>>
>>"Jonathan Neve[Microtec]" <XXXX@XXXXX.COM>wrote
>>>Not if you ask the FPU.
>>>More likely, 5 = 4.99999999999999999999999999.
>>Not so!
>Ok, well, perhaps not for 5. But your own examples below illustrate my
>point, which was simply that the user can not reliably get back exactly
>the value they put in.

This is basic education stuff: you simply can not express numbers like 1/7
as exact decimal numbers. Same applies to the binary system. You can't
even represent all decimal numbers in a binary system. If this is an
issue for you, and you do only sub., add., mul. and div. simply write
your own math library calculating only using fractions.

>>Using my IEEE Number Analyzer, for which the Delphi
>>source code is available from
>>cc.codegear.com/Item/23631,
>>you can type in a decimal number and get the exact
>>floating point value.
>Thanks, that sounds useful.
The problem isn't with irrational numbers.
No one really expects a computer to get those
exact because humans can not either (in decimal).
But humans can do 0.1 + 0.9 and get 1.0 and
so they expect computers to get it right, but
they can not *if* they are using floating point
numbers to do the calculations.
You can, of course, use BCD, but that has its
own set of problems. Namely that no one uses
them, so they are not debugged very thoroughly.
(Unfortunately, my project looks like it is
heading down that path and so we'll be entering
QCs on those issues.)
But if you have inherited a project where someone
wasn't paying attention and used floating point
numbers for financial calculations, then you
are SOL.
Brad.
 

Re: Avoiding floating points

"Mat Ballard" <XXXX@XXXXX.COM>wrote
Quote
... Do recognize that floating point numbers are a
BINARY (power of two) representation of a REAL
number, and as such are approximate. So there is no
Quote
such SINGLE value as 3.0 - but there is 2.9999979
or some such.
Well actually --- "3.0" as well as all small whole numbers
can be exactly represented as a type SINGLE values, which
has the little endian 4-byte value of $00,$00,$40,$40.
Using my IEEE Number Analyzer, for which the Delphi
source code is available from
cc.codegear.com/Item/23631,
you can type in a decimal number and see the *exact*
floating point value.
Rgds, JohnH
 

Re: Avoiding floating points

Brad White writes:
Quote
No matter how you store 0.1 in the database, you will
get something else back out.
Or did I miss your point?

Brad.
Depending on your database, You might have to process on both sides
(both in and out of the database). We have been writing accounting
applications for years and have not had any serious problems processing
floats.. Well we did with Delphi 1, until we got it right.. we could
off by a penny. We use currency types for most things.. and have a
good library developed over the years for processing.
--
David Farrell-Garcia
Whidbey Island Software, LLC
 

Re: Avoiding floating points

Jonathan Neve[Microtec] writes:
Quote
Hi all,

I hate floating points with a passion. Does anyone know of a simple way
to get rid of them and somehow be able to do elemetary calculations
without random imprecisions and unpredicitble and meaningless error
messages popping up out of no-where?
Use COBOL :-)
I really miss them PIC S9(x)V9(y) COMP SYNC types.
BTW I use currency type in Delphi.
--
Best regards
Stig Johansen
 

Re: Avoiding floating points

John Herbster writes:
Quote
Will this ever finish?
var x: int64;
begin
x := 0;
While (x < high(x)) do inc(x);
ShowMessage('Finished with x='+IntToStr(x));
end;
I would say yes. The correct answer would be?
Cheers,
Nick
--
 

Re: Avoiding floating points

Brad White writes:
Quote
David Farrell-Garcia writes:
>Jonathan Neve[Microtec] writes:
>
>If your application processes everything to integers or
>rounds to a fixed number of decimal places why do you care how the
>database stores it? 5 = 5.000000000 no matter how you slice it.
But that only applies to a few numbers.
For example, on the face of it, you would expect it
to apply to 0.1, but it does not.

Instead of 0.1 = 0.100000000
you get 0.1 = 0.100,000,000,000,000,000,001,355,252,715,606,880,
542,509,316,001,087,427,139,282,226,562,5

No matter how you store 0.1 in the database, you will
get something else back out.
Or did I miss your point?

Brad.
Exactly, and for most business applications, that is simply unacceptable.
Anyway, the point of this thread was, I admit, primarily a rant -- I'm
sick of floating point imprecisions, on the one hand, and their weird
errors (perhaps compiler-related) on the other. In none (or hardly any)
of my applications can I conceive a need for decimal points that float
around, I *always* want to get back the *exact* decimal representation
that I put into my database.
So I am not really trying to change the face of computer programming,
I'm just frustrated with floats, and I need to make an effort to
replace them with something more suitable for my needs. I suppose BCDs
or simply Currency fields would be good, and I will make sure I never
make another application with floats... :)
--
Best regards,
Jonathan Neve
_______________
CopyCat - advanced Delphi components for database replication,
supporting CodeGear Interbase, FirebirdSQL and MS SQL Server!
_______________
CopyTiger - the ultimate database replication solution for CodeGear
Interbase, FirebirdSQL and MS SQL Server!
_______________
More information : www.microtec.fr/copycat