Re: converting float to double
dcorbit@connx.c om wrote:
Nothing mythical here.
1 US dollar = 1374865.7 Turkish Lira
So don't use 64 bit integers to calculate the world GDP in
Turkish Lira unless your system is tolerant of small errors.
Both char and short are (probably) worse.
Double on the other hand is fine for many uses.
float has many uses, currency calculations is not among them.
As pointed out: Find out what the correct answer is, then design
your system. It may be that no native type is sufficient.
Looks to me like you are using high precision floating point arithmetic
(rather than arbitrary precision integer arithmetic), then rounding to
get your final answer. Nothing wrong with this strategy, but it is
hardly an argument in favour of integer arithmetic.
- William
Hughes
dcorbit@connx.c om wrote:
William Hughes wrote:
>
A 64 bit integer will correctly model currency to 18 digits (with
hundredths units that gives 16 digits for the integer part).
In a mythical currency with 1,000,000 units per dollar,
Dik T. Winter wrote:
Indeed. This is not a fix. This is a kludge that might work with
a broken system.
The suggested kludge does not make the errors any worse
(we expect an error of about 10e-6 times the shareprice)
It just insures that the errors have a consistent sign. The
alternative
of not adding the fudge factor mean that there will still
be some error with unknown sign. The preferred alternatives
of avoiding or rewriting the software do not appear to be
available.
Just remember you may be dealing with the world GDP expressed
in Turkish lira. Or design your system to use floating point and be
tolerant of
small errors In the end you need to find out what the correct answer
is (this is an accounting, not a mathematical or computer question)
and design your system to give the correct answer. What internal
data type or structure you use to do this is of lesser importance.
In article <1166646566.617 718.113730@i12g 2000cwa.googleg roups.com"Willi am Hughes" <wpihughes@hotm ail.comwrites:
Dilip wrote:
...
THis isn't always possible. The market data vendor I connect to
insists that I read the stock prices as float. So when I reach into
the byte-stream I will have to memcpy sizeof(float) number of bytes.
Since everywhere else the system uses double to hold these prices, I
had no choice but to stuff that retreived float value into a double
causing all these problems.
>
A system that uses floating point variables to store prices should
work correctly if a price is just above or just below the
correct price (e.g for a price of 0.010001 dollars or 0.009998
dollars).
The system you use does not have this property. It needs
to be fixed.
>
How do you fix a system that follows the C standard?
>
A possible workaround:
Read the prices as float
Round to the nearest cent or tenth of a cent (*)
Convert to double
Add a fudge factor of 0.00000001
Now your prices will be subtly wrong, but they will be subtly wrong in
the correct direction. This should work as well as the
(double)(f*1000 .0)/1000.0
kludge, and will work for any value.
>
But after subtraction you can be subtly wrong the wrong way.
Dilip wrote:
...
THis isn't always possible. The market data vendor I connect to
insists that I read the stock prices as float. So when I reach into
the byte-stream I will have to memcpy sizeof(float) number of bytes.
Since everywhere else the system uses double to hold these prices, I
had no choice but to stuff that retreived float value into a double
causing all these problems.
>
A system that uses floating point variables to store prices should
work correctly if a price is just above or just below the
correct price (e.g for a price of 0.010001 dollars or 0.009998
dollars).
The system you use does not have this property. It needs
to be fixed.
>
How do you fix a system that follows the C standard?
>
A possible workaround:
Read the prices as float
Round to the nearest cent or tenth of a cent (*)
Convert to double
Add a fudge factor of 0.00000001
Now your prices will be subtly wrong, but they will be subtly wrong in
the correct direction. This should work as well as the
(double)(f*1000 .0)/1000.0
kludge, and will work for any value.
>
But after subtraction you can be subtly wrong the wrong way.
Indeed. This is not a fix. This is a kludge that might work with
a broken system.
The suggested kludge does not make the errors any worse
(we expect an error of about 10e-6 times the shareprice)
It just insures that the errors have a consistent sign. The
alternative
of not adding the fudge factor mean that there will still
be some error with unknown sign. The preferred alternatives
of avoiding or rewriting the software do not appear to be
available.
To avoid
all this is done by internally working with integers, longs, long longs,
or whatever integer size you need.
all this is done by internally working with integers, longs, long longs,
or whatever integer size you need.
in Turkish lira. Or design your system to use floating point and be
tolerant of
small errors In the end you need to find out what the correct answer
is (this is an accounting, not a mathematical or computer question)
and design your system to give the correct answer. What internal
data type or structure you use to do this is of lesser importance.
A 64 bit integer will correctly model currency to 18 digits (with
hundredths units that gives 16 digits for the integer part).
In a mythical currency with 1,000,000 units per dollar,
1 US dollar = 1374865.7 Turkish Lira
that would
leave 10 billion dollar transactions accurate to the penny.
leave 10 billion dollar transactions accurate to the penny.
Turkish Lira unless your system is tolerant of small errors.
>
With 6 digits {typically} of precision, float can barely handle a
decent paycheck. Float is one of the most onerous native C data type
that I can imagine for use with currency.
With 6 digits {typically} of precision, float can barely handle a
decent paycheck. Float is one of the most onerous native C data type
that I can imagine for use with currency.
Double on the other hand is fine for many uses.
float has many uses, currency calculations is not among them.
Our database tools do all
calcuations in 110 digits of precision (so that things like interest
calculations for the national debt over 100 years would still yield
sensible results).
calcuations in 110 digits of precision (so that things like interest
calculations for the national debt over 100 years would still yield
sensible results).
your system. It may be that no native type is sufficient.
>
For instance,
select convert(8624231 011335.27 * pow(1+(.05/4),100*4), varchar(256))
returns:
124088957459618 1.0524862250897 801838715263375 815269734635536 879733900109878 357698345898209 198819494984492 8
For instance,
select convert(8624231 011335.27 * pow(1+(.05/4),100*4), varchar(256))
returns:
124088957459618 1.0524862250897 801838715263375 815269734635536 879733900109878 357698345898209 198819494984492 8
Looks to me like you are using high precision floating point arithmetic
(rather than arbitrary precision integer arithmetic), then rounding to
get your final answer. Nothing wrong with this strategy, but it is
hardly an argument in favour of integer arithmetic.
- William
Hughes
Comment