Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.misc > #2535 > unrolled thread

BASIC is 50

Started byGordon Henderson <gordon+usenet@drogon.net>
First post2014-04-30 09:34 +0000
Last post2014-05-14 17:40 +0100
Articles 20 on this page of 56 — 22 participants

Back to article view | Back to comp.misc


Contents

  BASIC is 50 Gordon Henderson <gordon+usenet@drogon.net> - 2014-04-30 09:34 +0000
    Re: BASIC is 50 Ant <ant@zimage.comANT> - 2014-04-30 03:42 -0700
      Re: BASIC is 50 Bob Eager <news0002@eager.cx> - 2014-04-30 10:46 +0000
        Re: BASIC is 50 Gordon Henderson <gordon+usenet@drogon.net> - 2014-04-30 12:03 +0000
    Re: BASIC is 50 Rich <rich@example.com> - 2014-04-30 11:12 +0000
      Re: BASIC is 50 scott@alfter.diespammersdie.us (Scott Alfter) - 2014-04-30 15:56 +0000
        Re: BASIC is 50 Rich <rich@example.com> - 2014-04-30 20:41 +0000
          Re: BASIC is 50 Will Honea <whonea@whonea.net> - 2014-04-30 18:38 -0600
            Re: BASIC is 50 Rich <rich@example.com> - 2014-05-01 02:38 +0000
              Re: BASIC is 50 Will Honea <whonea@whonea.net> - 2014-04-30 22:50 -0600
        Re: BASIC is 50 Rich <rich@example.com> - 2014-04-30 20:48 +0000
          Re: BASIC is 50 Richard Kettlewell <rjk@greenend.org.uk> - 2014-05-02 09:27 +0100
            Re: BASIC is 50 Tim Streater <timstreater@greenbee.net> - 2014-05-02 09:50 +0100
          Re: BASIC is 50 "BartC" <bc@freeuk.com> - 2014-05-07 10:48 +0100
            Re: BASIC is 50 Tim Streater <timstreater@greenbee.net> - 2014-05-07 10:57 +0100
            Re: BASIC is 50 Huge <Huge@nowhere.much.invalid> - 2014-05-07 11:20 +0000
              Re: BASIC is 50 "BartC" <bc@freeuk.com> - 2014-05-07 13:14 +0100
                Re: BASIC is 50 Marko Rauhamaa <marko@pacujo.net> - 2014-05-07 16:05 +0300
                  Re: BASIC is 50 Paul Sture <nospam@sture.ch> - 2014-05-08 18:06 +0200
                    Re: BASIC is 50 Marko Rauhamaa <marko@pacujo.net> - 2014-05-08 20:17 +0300
                Re: BASIC is 50 "James Harris" <james.harris.1@gmail.com> - 2014-05-07 16:08 +0100
                  Re: BASIC is 50 "BartC" <bc@freeuk.com> - 2014-05-07 18:38 +0100
                    Re: BASIC is 50 "James Harris" <james.harris.1@gmail.com> - 2014-05-07 19:09 +0100
                      Re: BASIC is 50 Huge <Huge@nowhere.much.invalid> - 2014-05-07 19:08 +0000
                Re: BASIC is 50 greymausg@mail.com - 2014-05-08 10:15 +0000
                  Re: BASIC is 50 "BartC" <bc@freeuk.com> - 2014-05-08 11:38 +0100
                Re: BASIC is 50 Paul Sture <nospam@sture.ch> - 2014-05-08 17:55 +0200
            Re: BASIC is 50 Paul Sture <nospam@sture.ch> - 2014-05-08 17:44 +0200
            Re: BASIC is 50 Rich <rich@example.com> - 2014-05-12 12:39 +0000
              Re: BASIC is 50 Marko Rauhamaa <marko@pacujo.net> - 2014-05-12 16:06 +0300
              Re: BASIC is 50 Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-05-12 22:48 +0100
                Re: BASIC is 50 Rich <rich@example.com> - 2014-05-13 12:03 +0000
                  Re: BASIC is 50 "BartC" <bc@freeuk.com> - 2014-05-13 13:23 +0100
                    Re: BASIC is 50 Rich <rich@example.com> - 2014-05-13 16:22 +0000
                      Re: BASIC is 50 "BartC" <bc@freeuk.com> - 2014-05-13 19:42 +0100
                        Re: BASIC is 50 "BartC" <bc@freeuk.com> - 2014-05-13 19:49 +0100
                          Re: BASIC is 50 Rich <rich@example.com> - 2014-05-14 01:09 +0000
                            Re: BASIC is 50 "BartC" <bc@freeuk.com> - 2014-05-14 09:51 +0100
                        Re: BASIC is 50 bde@besplex.bde.org (Bruce Evans) - 2014-05-14 10:36 +0000
                          Re: BASIC is 50 "BartC" <bc@freeuk.com> - 2014-05-14 12:58 +0100
                            Re: BASIC is 50 bde@besplex.bde.org (Bruce Evans) - 2014-05-14 16:13 +0000
                              Re: BASIC is 50 "BartC" <bc@freeuk.com> - 2014-05-14 19:24 +0100
                  Re: BASIC is 50 Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-05-13 15:50 +0100
      Re: BASIC is 50 Johny B Good <johnny-b-good@invalid.ntlworld.com> - 2014-05-01 02:50 +0100
      Re: BASIC is 50 David Hume <David.Hume@example.com> - 2014-05-01 09:06 +0100
        Re: BASIC is 50 Gordon Henderson <gordon+usenet@drogon.net> - 2014-05-01 09:56 +0000
        Re: BASIC is 50 Rich <rich@example.com> - 2014-05-01 10:25 +0000
          Re: BASIC is 50 Marko Rauhamaa <marko@pacujo.net> - 2014-05-01 16:43 +0300
            Re: BASIC is 50 Gordon Henderson <gordon+usenet@drogon.net> - 2014-05-01 18:03 +0000
            Re: BASIC is 50 Bob Eager <news0002@eager.cx> - 2014-05-01 21:35 +0000
          Re: BASIC is 50 Rob <monst.oorzudo@ntlworld.com> - 2014-05-01 22:41 +0100
            Re: BASIC is 50 David Hume <David.Hume@example.com> - 2014-05-02 09:26 +0100
              Re: BASIC is 50 Hils <hils@saynotospam.net> - 2014-05-02 10:46 +0100
              Re: BASIC is 50 Johny B Good <johnny-b-good@invalid.ntlworld.com> - 2014-05-02 23:11 +0100
    Re: BASIC is 50 Anssi Saari <as@sci.fi> - 2014-04-30 17:51 +0300
    Re: BASIC is 50 Peter Percival <peterxpercival@hotmail.com> - 2014-05-14 17:40 +0100

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#2676

From"James Harris" <james.harris.1@gmail.com>
Date2014-05-07 16:08 +0100
Message-ID<lkdi9g$cpd$1@dont-email.me>
In reply to#2673
"BartC" <bc@freeuk.com> wrote in message 
news:Xtpav.335997$5V5.276603@fx08.am4...
>
>
> "Huge" <Huge@nowhere.much.invalid> wrote in message

...

>> Pretty obvious you've never worked in finance or banking.
>
> I've written software that worked with currency. I used floating point. 
> But
> not for banking. (In that particular application, it needed to work in two
> linked currencies. The conversion rate between them was such that one or 
> the
> other would generally always be a fraction of a cent wrong, rounded to the 
> nearest cent.)
>
> The only issue that might arise (and I can't remember it happening in my
> code), is in rounding a value ending in 0.5 cents or very close, then you
> have to decide to round up or down. The result might however have to match
> the same calculation done elsewhere, where the rounding might be the other
> way because their floating point result is different. (But there are ways 
> of
> getting consistent, portable floating point results too.)
>
> (In any case, typical 64-bit floating point can represent amounts up to
> nearly $100 trillion, expressed in whole cents.)

The big problem with floating point is subtraction. All programmers using 
floats should be aware of it but I don't know if it is generally taught. 
Even with 64-bit floats if you have two intermediate results that are 
similar and you subtract one from the other the result may have lost lots of 
digits of precision.

For example, if you have a precise but very small floating point number X 
such as 3.1415926539e-10 and the code does

  X = X + 1
  X = X - 1

The code looks harmless but X will have lost a lot of its precision. It may 
now be only something like 3.1e-10.

For financial applications decimal numbers or scaled integers are normally 
safer.

James

[toc] | [prev] | [next] | [standalone]


#2677

From"BartC" <bc@freeuk.com>
Date2014-05-07 18:38 +0100
Message-ID<8duav.279147$Tp4.228677@fx11.am4>
In reply to#2676

"James Harris" <james.harris.1@gmail.com> wrote in message
news:lkdi9g$cpd$1@dont-email.me...
> "BartC" <bc@freeuk.com> wrote in message
> news:Xtpav.335997$5V5.276603@fx08.am4...

>> (In any case, typical 64-bit floating point can represent amounts up to
>> nearly $100 trillion, expressed in whole cents.)
>
> The big problem with floating point is subtraction. All programmers using
> floats should be aware of it but I don't know if it is generally taught.
> Even with 64-bit floats if you have two intermediate results that are
> similar and you subtract one from the other the result may have lost lots
> of digits of precision.
>
> For example, if you have a precise but very small floating point number X
> such as 3.1415926539e-10 and the code does
>
>  X = X + 1
>  X = X - 1
>
> The code looks harmless but X will have lost a lot of its precision. It
> may now be only something like 3.1e-10.

I think the precision will be lost as soon as you do X=X+1. Although you're
right in that someone who expects X to be unchanged after those two
assignments may not be aware of the problem. (It's like right-shifting an 
integer by N places followed by left-shifting by N places.)

> For financial applications decimal numbers or scaled integers are normally
> safer.

But it's possible (depending on the number of decimals) they won't be able
to represent 3.14159265359e-10 anyway. Maybe only 3.1e-10 ! Or 0.

-- 
Bartc

 

[toc] | [prev] | [next] | [standalone]


#2678

From"James Harris" <james.harris.1@gmail.com>
Date2014-05-07 19:09 +0100
Message-ID<lkdss3$vi1$1@dont-email.me>
In reply to#2677
"BartC" <bc@freeuk.com> wrote in message 
news:8duav.279147$Tp4.228677@fx11.am4...
>
>
> "James Harris" <james.harris.1@gmail.com> wrote in message
> news:lkdi9g$cpd$1@dont-email.me...
>> "BartC" <bc@freeuk.com> wrote in message
>> news:Xtpav.335997$5V5.276603@fx08.am4...
>
>>> (In any case, typical 64-bit floating point can represent amounts up to
>>> nearly $100 trillion, expressed in whole cents.)
>>
>> The big problem with floating point is subtraction. All programmers using
>> floats should be aware of it but I don't know if it is generally taught.
>> Even with 64-bit floats if you have two intermediate results that are
>> similar and you subtract one from the other the result may have lost lots
>> of digits of precision.
>>
>> For example, if you have a precise but very small floating point number X
>> such as 3.1415926539e-10 and the code does
>>
>>  X = X + 1
>>  X = X - 1
>>
>> The code looks harmless but X will have lost a lot of its precision. It
>> may now be only something like 3.1e-10.
>
> I think the precision will be lost as soon as you do X=X+1.

Yes, although the precision of the floating point value of X is really 
unchanged at that point. Its precision is still the same number of digits 
that it was before. For the sake of choosing some numbers say it has 11 
digits of precision both before and after the addition of 1. If 1 is not 
subsequently subtracted the value of X is still precise to 11 digits and 
fine as a highly precise floating point number. The lost information is now 
around the 20 digits mark which is almost always negligible. Still, on 
subtraction the result loses precision which is significant.

> Although you're
> right in that someone who expects X to be unchanged after those two
> assignments may not be aware of the problem. (It's like right-shifting an 
> integer by N places followed by left-shifting by N places.)
>
>> For financial applications decimal numbers or scaled integers are 
>> normally
>> safer.
>
> But it's possible (depending on the number of decimals) they won't be able
> to represent 3.14159265359e-10 anyway. Maybe only 3.1e-10 ! Or 0.

Yes. I was just trying to illustrate the problem with simple numbers. As you 
know, the issue would arise in the same way if the number of pennies in a 
person's account was 3 million and as a result of an intermediate 
calculation 10e18 was added and then a number close to 10e18 was subtracted. 
Mathematically the subtraction may be correct but the result in a computer 
would differ markedly.

Don't get me wrong, I believe that floats can be used for finances as long 
as the programmer is extremely careful about intermediate values and does 
lots of boundary testing. But even then the code can become very hard to 
maintain safely.

(I was prompted to reply because I saw the comment that 64-bit floats can 
represent up to $100 trillion. That may be true for static storage but they 
would be very difficult to do calculations on due to the danger of losing 
information.)

James

[toc] | [prev] | [next] | [standalone]


#2679

FromHuge <Huge@nowhere.much.invalid>
Date2014-05-07 19:08 +0000
Message-ID<bsvel8Fj03qU1@mid.individual.net>
In reply to#2678
On 2014-05-07, James Harris <james.harris.1@gmail.com> wrote:

> (I was prompted to reply because I saw the comment that 64-bit floats can 
> represent up to $100 trillion. That may be true for static storage but they 
> would be very difficult to do calculations on due to the danger of losing 
> information.)

Especially if you're trying to do the maths in the kinds of timescales required
for high frequency trading...


-- 
Today is Boomtime, the 54th day of Discord in the YOLD 3180
“Stupidity cannot be cured. Stupidity is the only universal capital crime;
 the sentence is death. There is no appeal, and execution is carried out
                 automatically and without pity.”

[toc] | [prev] | [next] | [standalone]


#2689

Fromgreymausg@mail.com
Date2014-05-08 10:15 +0000
Message-ID<slrnlmm4e9.ub.greymausg@gmaus.org>
In reply to#2673
On 2014-05-07, BartC <bc@freeuk.com> wrote:
>
>
> "Huge" <Huge@nowhere.much.invalid> wrote in message
> news:bsuj7gFd631U1@mid.individual.net...
>> On 2014-05-07, BartC <bc@freeuk.com> wrote:
>>> "Rich" <rich@example.com> wrote in message
>>> news:53616180$0$59815$c3e8da3$e074e489@news.astraweb.com...
>>>> Scott Alfter <scott@alfter.diespammersdie.us> wrote:
>>>
>>>> 99.7099999999999999436561815002733055735006928443908691406250000000000000
>>>>
>>>> This is why floating point can be dangerous, and why floating point
>>>> should _NEVER_ ever be used to compute monetary values:
>>>
>>> Why not? Because the result might be off by a quadrillionth of a cent?
>>>
>>> Use rounding properly and it can be made to work (unless you're dealing
>>> with
>>> very large amounts such as the US debt then it's a bit trickier to avoid
>>> errors starting to affect the cents).
>>
>> Pretty obvious you've never worked in finance or banking.
>
> I've written software that worked with currency. I used floating point. But
> not for banking. (In that particular application, it needed to work in two
> linked currencies. The conversion rate between them was such that one or the
> other would generally always be a fraction of a cent wrong, rounded to the 
> nearest cent.)
>
> The only issue that might arise (and I can't remember it happening in my
> code), is in rounding a value ending in 0.5 cents or very close, then you
> have to decide to round up or down. The result might however have to match
> the same calculation done elsewhere, where the rounding might be the other
> way because their floating point result is different. (But there are ways of
> getting consistent, portable floating point results too.)
>
> (In any case, typical 64-bit floating point can represent amounts up to
> nearly $100 trillion, expressed in whole cents.)
>

[why floating point should not be used in finance]
Those tiny amounts, added together, can be diverted, as in the salami
scam. Python has decimal.Decimal for that sort of thing

[toc] | [prev] | [next] | [standalone]


#2691

From"BartC" <bc@freeuk.com>
Date2014-05-08 11:38 +0100
Message-ID<J8Jav.1$z21.0@fx12.am4>
In reply to#2689
<greymausg@mail.com> wrote in message 
news:slrnlmm4e9.ub.greymausg@gmaus.org...
> On 2014-05-07, BartC <bc@freeuk.com> wrote:

>> (In any case, typical 64-bit floating point can represent amounts up to
>> nearly $100 trillion, expressed in whole cents.)
>>
>
> [why floating point should not be used in finance]
> Those tiny amounts, added together, can be diverted, as in the salami
> scam. Python has decimal.Decimal for that sort of thing

That might be an *for* using floating point:

If you calculate 2.7% interest on $1234.56, then floating point will give 
you $33.33312.

You can see the 0.312 cents left over after rounding to $33.33 and can 
choose what to do with it.

What happens to the 0.312 cents with 'decimal.Decimal'?

-- 
Bartc  

[toc] | [prev] | [next] | [standalone]


#2703

FromPaul Sture <nospam@sture.ch>
Date2014-05-08 17:55 +0200
Message-ID<n0ms3b-3562.ln1@news.chingola.ch>
In reply to#2673
On 2014-05-07, BartC <bc@freeuk.com> wrote:
>
> "Huge" <Huge@nowhere.much.invalid> wrote in message
>>
>> Pretty obvious you've never worked in finance or banking.
>
> I've written software that worked with currency. I used floating point. But
> not for banking. (In that particular application, it needed to work in two
> linked currencies. The conversion rate between them was such that one or the
> other would generally always be a fraction of a cent wrong, rounded to the 
> nearest cent.)

Currency is a different beast, because rates change with time.  You need
a separate currency gains/losses account to keep track of these differences
(e.g. the differences between what you invoice and what you receive some
time later).  Round errors simply get absorbed in here.

As an example of how large these sums can be, the first computer I worked
with cost GBP 100,000 and was funded out of what my employer had made out
of currency gains* the previous year on a turnover of GBP 12 million.

* gains because the Pound Sterling took a hammering that year; invoices
in foreign currencies realised more pounds by the time they were paid.

-- 
Paul Sture

The final step of #heartbleed recovery is to call your mother, and advise
her to change her maiden name                                  -- @gojomo

[toc] | [prev] | [next] | [standalone]


#2702

FromPaul Sture <nospam@sture.ch>
Date2014-05-08 17:44 +0200
Message-ID<nbls3b-3562.ln1@news.chingola.ch>
In reply to#2670
On 2014-05-07, BartC <bc@freeuk.com> wrote:
> "Rich" <rich@example.com> wrote in message
> news:53616180$0$59815$c3e8da3$e074e489@news.astraweb.com...
>> Scott Alfter <scott@alfter.diespammersdie.us> wrote:
>
>> 99.7099999999999999436561815002733055735006928443908691406250000000000000
>>
>> This is why floating point can be dangerous, and why floating point
>> should _NEVER_ ever be used to compute monetary values:
>
> Why not? Because the result might be off by a quadrillionth of a cent?

That quadrillionth of a cent will sooner or later make the difference
between rounding up and rounding down, and then your books don't add up.

> Use rounding properly and it can be made to work (unless you're dealing with 
> very large amounts such as the US debt then it's a bit trickier to avoid 
> errors starting to affect the cents).

You can see the effects of floating point inaccuracies within a one page
invoice; let that loose on a full set of company accounts and the auditors
aren't going to sign them.

> You can also work with whole cents or pence for fewer problems, but at some
> point (for tax calculations, compound interest etc) you will need to do more
> complex arithmetic.

In all my accounting and payroll work we used pence and rounding was done
by "half adjusting".

Even doing that you have to be careful.  Our shiny new invoicing system
back in 1978 was making a mistake with the VAT (sales tax) because it
itemised the tax on a line item basis (so the customer could see the net,
tax and gross amounts for each item) but calculated the VAT due on the
invoice total rather than adding up the VAT on the line items.

Easy to fix once we realised what was going on, but there are no doubt
novices out there still making that mistake.

FWIW the pocket calculator I had in 1987 wasn't up to the task of doing a
month's accounts.  I was simply checking that the row totals equalled
the column totals for a set of figures and the damn thing couldn't get
the same answer for both.  I went out the following day and purchased
a proper accounting desk calculator which could get those figures right.

-- 
Paul Sture

The final step of #heartbleed recovery is to call your mother, and advise
her to change her maiden name                                  -- @gojomo

[toc] | [prev] | [next] | [standalone]


#2755

FromRich <rich@example.com>
Date2014-05-12 12:39 +0000
Message-ID<5370c119$0$59769$c3e8da3$e074e489@news.astraweb.com>
In reply to#2670
BartC <bc@freeuk.com> wrote:
> "Rich" <rich@example.com> wrote in message
> news:53616180$0$59815$c3e8da3$e074e489@news.astraweb.com...
> > Scott Alfter <scott@alfter.diespammersdie.us> wrote:

> > 99.7099999999999999436561815002733055735006928443908691406250000000000000
> >
> > This is why floating point can be dangerous, and why floating point
> > should _NEVER_ ever be used to compute monetary values:

> Why not? Because the result might be off by a quadrillionth of a cent?

> Use rounding properly and it can be made to work (unless you're dealing with 
> very large amounts such as the US debt then it's a bit trickier to avoid 
> errors starting to affect the cents).

> You can also work with whole cents or pence for fewer problems, but at some
> point (for tax calculations, compound interest etc) you will need to do more
> complex arithmetic.

An excellent writeup of "why not" is given here:

http://speleotrove.com/decimal/decifaq1.html#inexact

Reading the whole is better, but here is a small quote:

   "For example, using the Java or C double datatype, 0.1 × 8 (a binary
    multiple) gives the result
    0.8000000000000000444089209850062616169452667236328125 but 0.1
    added to itself 8 times gives the different answer
    0.79999999999999993338661852249060757458209991455078125. The two
    results would not compare equal, and further, if these values are
    multiplied by ten and rounded to the nearest integer below (the
    "floor" function), the result will be 8 in one case and 7 in the
    other."

[toc] | [prev] | [next] | [standalone]


#2757

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-05-12 16:06 +0300
Message-ID<877g5rdu3t.fsf@elektro.pacujo.net>
In reply to#2755
Rich <rich@example.com>:

> Reading the whole is better, but here is a small quote:
>
>    "For example, using the Java or C double datatype, 0.1 × 8 (a
>    binary multiple) gives the result
>    0.8000000000000000444089209850062616169452667236328125 but 0.1
>    added to itself 8 times gives the different answer
>    0.79999999999999993338661852249060757458209991455078125. The two
>    results would not compare equal, and further, if these values are
>    multiplied by ten and rounded to the nearest integer below (the
>    "floor" function), the result will be 8 in one case and 7 in the
>    other."

Why would you round like that? The age-old technique is floor(x + 0.5).


Marko

[toc] | [prev] | [next] | [standalone]


#2768

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2014-05-12 22:48 +0100
Message-ID<0.749162ecb023be910298.20140512224801BST.878uq6u0ry.fsf@bsb.me.uk>
In reply to#2755
Rich <rich@example.com> writes:

> BartC <bc@freeuk.com> wrote:
>> "Rich" <rich@example.com> wrote in message
>> news:53616180$0$59815$c3e8da3$e074e489@news.astraweb.com...
>> > Scott Alfter <scott@alfter.diespammersdie.us> wrote:
>
>> > 99.7099999999999999436561815002733055735006928443908691406250000000000000
>> >
>> > This is why floating point can be dangerous, and why floating point
>> > should _NEVER_ ever be used to compute monetary values:
>
>> Why not? Because the result might be off by a quadrillionth of a cent?
>
>> Use rounding properly and it can be made to work (unless you're dealing with 
>> very large amounts such as the US debt then it's a bit trickier to avoid 
>> errors starting to affect the cents).
>
>> You can also work with whole cents or pence for fewer problems, but at some
>> point (for tax calculations, compound interest etc) you will need to do more
>> complex arithmetic.
>
> An excellent writeup of "why not" is given here:
>
> http://speleotrove.com/decimal/decifaq1.html#inexact

I am sure this is an excellent write-up of the perils of doing financial
calculations using binary floating-point arithmetic, but it can't
possible answer the "why not?" as applied to the original question.
First, because the original claim was about using floating point, not
about using binary floating point and, second, because it was far too
broad.  It's a common Usenet problem: someone makes a slightly overly
broad claim, and when questioned, the defence is of a more limited
claim, and then some knob-head like me comes along and points that out.

Are representational and arithmetic errors the reason why you should
_NEVER_ (note: CAPS *and* _underlined_) use floating point for monetary
calculations?  No, I use floating point in financial spreadsheets all
the time for things like my home budget.  What's more, I know a fund
manager (managing millions) who does the same.  They want to know data
about company performance where the cents are of no importance at all.

> Reading the whole is better, but here is a small quote:
>
>    "For example, using the Java or C double datatype, 0.1 × 8 (a binary
>     multiple) gives the result
>     0.8000000000000000444089209850062616169452667236328125 but 0.1
>     added to itself 8 times gives the different answer
>     0.79999999999999993338661852249060757458209991455078125. The two
>     results would not compare equal, and further, if these values are
>     multiplied by ten and rounded to the nearest integer below (the
>     "floor" function), the result will be 8 in one case and 7 in the
>     other."

That calculation comes out fine using decimal floating point.  I also
detect a whiff of polemic here.  Describing floor as "rounding to the
nearest integer below" suggests some similarity with rounding to the
nearest integer which is reasonable, even in some financial contexts,
but while floor has mathematical uses I struggle to think of a
reasonable financial one.

(And there a technical error: C does not specify much about the floating
point implementation.  It might even be decimal floating-point, in which
case the result would be exactly as expected.)

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#2772

FromRich <rich@example.com>
Date2014-05-13 12:03 +0000
Message-ID<537209fc$0$17199$c3e8da3$dd9697d2@news.astraweb.com>
In reply to#2768
Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> I am sure this is an excellent write-up of the perils of doing
> financial calculations using binary floating-point arithmetic, but it
> can't possible answer the "why not?" as applied to the original
> question. First, because the original claim was about using floating
> point, not about using binary floating point and, second, because it
> was far too broad.  It's a common Usenet problem: someone makes a
> slightly overly broad claim, and when questioned, the defence is of a
> more limited claim, and then some knob-head like me comes along and
> points that out.

Fair enough.  You are quite correct.  My original statement was overly
broad.  I meant to say "binary floating point" but wrote "floating
point".  The ubiquity of "binary floating point" has resulted in my
refering to the format as simply "floating point" more often than not,
even though such reference is incorrect.

[toc] | [prev] | [next] | [standalone]


#2773

From"BartC" <bc@freeuk.com>
Date2014-05-13 13:23 +0100
Message-ID<Y8ocv.64639$8%2.40203@fx06.am4>
In reply to#2772

"Rich" <rich@example.com> wrote in message
news:537209fc$0$17199$c3e8da3$dd9697d2@news.astraweb.com...
> Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>> I am sure this is an excellent write-up of the perils of doing
>> financial calculations using binary floating-point arithmetic, but it
>> can't possible answer the "why not?" as applied to the original
>> question. First, because the original claim was about using floating
>> point, not about using binary floating point and, second, because it
>> was far too broad.  It's a common Usenet problem: someone makes a
>> slightly overly broad claim, and when questioned, the defence is of a
>> more limited claim, and then some knob-head like me comes along and
>> points that out.
>
> Fair enough.  You are quite correct.  My original statement was overly
> broad.  I meant to say "binary floating point" but wrote "floating
> point".  The ubiquity of "binary floating point" has resulted in my
> refering to the format as simply "floating point" more often than not,
> even though such reference is incorrect.

I meant binary floating point too. I haven't really thought about a decimal
version (but sounds like an interesting project to complement my decimal
integer library).

> An excellent writeup of "why not" is given here:
>
> http://speleotrove.com/decimal/decifaq1.html#inexact

Most of that article is about not understanding how to use (binary) floating
point effectively.

Given enough precision, I believe that binary floating point can emulate
what can be done in decimal arithmetic.

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#2775

FromRich <rich@example.com>
Date2014-05-13 16:22 +0000
Message-ID<537246b1$0$59749$c3e8da3$e074e489@news.astraweb.com>
In reply to#2773
BartC <bc@freeuk.com> wrote:
> "Rich" <rich@example.com> wrote in message
> news:537209fc$0$17199$c3e8da3$dd9697d2@news.astraweb.com...
> > Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> >> I am sure this is an excellent write-up of the perils of doing
> >> financial calculations using binary floating-point arithmetic, but it
> >> can't possible answer the "why not?" as applied to the original
> >> question. First, because the original claim was about using floating
> >> point, not about using binary floating point and, second, because it
> >> was far too broad.  It's a common Usenet problem: someone makes a
> >> slightly overly broad claim, and when questioned, the defence is of a
> >> more limited claim, and then some knob-head like me comes along and
> >> points that out.
> >
> > Fair enough.  You are quite correct.  My original statement was
> > overly broad.  I meant to say "binary floating point" but wrote
> > "floating point".  The ubiquity of "binary floating point" has
> > resulted in my refering to the format as simply "floating point"
> > more often than not, even though such reference is incorrect.

> I meant binary floating point too. I haven't really thought about a
> decimal version (but sounds like an interesting project to complement
> my decimal integer library).

It (binary) floating point is so ubiquitous that I don't think we are
alone in conflating "floating point" with "binary floating point".

> > An excellent writeup of "why not" is given here:
> >
> > http://speleotrove.com/decimal/decifaq1.html#inexact

> Most of that article is about not understanding how to use (binary)
> floating point effectively.

> Given enough precision, I believe that binary floating point can
> emulate what can be done in decimal arithmetic.

Actually, no.

0.1 in decimal is an infinite repeating sequence in binary floating
point.  So it is impossible to have enough precision to exactly
represent 0.1 (decimal) in binary floating point.

I.e., 0.1 is the same as 1/3 in decimal.  The decimal representation of
1/3 is an infinite repeating sequence.

The problem comes about because humans with math backgrounds understand
where the inexactness exists for decimal (1/3, 2/3, etc.).  With binary
representations there are even more inexact items and so the
opportunity for many more surprising results occurs.

From the page above:

   "Similarly, the Java or C expression (0.1+0.2==0.3) evaluates to
   false."

[toc] | [prev] | [next] | [standalone]


#2780

From"BartC" <bc@freeuk.com>
Date2014-05-13 19:42 +0100
Message-ID<JJtcv.95786$Sp6.12404@fx15.am4>
In reply to#2775
"Rich" <rich@example.com> wrote in message
news:537246b1$0$59749$c3e8da3$e074e489@news.astraweb.com...
> BartC <bc@freeuk.com> wrote:

>> Given enough precision, I believe that binary floating point can
>> emulate what can be done in decimal arithmetic.
>
> Actually, no.
>
> 0.1 in decimal is an infinite repeating sequence in binary floating
> point.  So it is impossible to have enough precision to exactly
> represent 0.1 (decimal) in binary floating point.

>   "Similarly, the Java or C expression (0.1+0.2==0.3) evaluates to
>   false."

No, it's nothing to do with not being able to represent 0.1 exactly. You
*know* it's an approximation, but can work with that provided the precision
is greater than the number of decimal digits you're trying to emulate.

The following is an example of how it can be done (see main()). Actually,
you can replace the definition of 'myfloat' with just 'float' instead of
'double', and it will still work (but up to a smaller magnitude). This code
emulates some decimal arithmetic with two decimal places. (Note that the
normal 0.1+0.2==0.3 can give True with some compilers.)

/* Floating emulation of fixed point decimal arithmetic */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define decimals 2
#define rounding 0.005
#define factor 100.0
//#define myfloat float
#define myfloat double

myfloat round_dec(myfloat x){
if (x>0.0)
 return floor((x+rounding)*factor)/factor;
else
 if (x>-rounding) return 0.0;
 return ceil((x-rounding)*factor)/factor;
}

myfloat add_dec(myfloat x, myfloat y){
return round_dec(x+y);
}

myfloat sub_dec(myfloat x, myfloat y){
return round_dec(x-y);
}

myfloat mul_dec(myfloat x, myfloat y){
return round_dec(x*y);
}

int equal_dec(myfloat x, myfloat y){
return fabs(x-y)<rounding;
}

char* str_dec(myfloat x){
static char str[500];
sprintf(str,"%.2f (%.28f)",round_dec(x),x);
return str;
}

int main(void) {
myfloat x,y,z;
int i;

puts("Normal floating point:");
printf("0.1            = %.28f\n",0.1);
printf("0.2            = %.28f\n",0.2);
printf("0.1+0.3        = %.28f\n",0.3);
printf("0.1+0.2 == 0.3 = %s\n", (0.1+0.2==0.3)?"True":"False");

x=0.1;
y=x*8.0;
z=0.1;
for (i=1; i<=7; ++i)
  z=z+0.1;

printf("0.1*8                           = %.28f\n",y);
printf("0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 = %.28f\n",z);
printf("Difference:                     = %.28f\n",y-z);

puts("\nDecimal emulation using same floating point type:");
printf("0.1            = %s\n",str_dec(0.1));
printf("0.2            = %s\n",str_dec(0.2));
printf("0.1+0.3        = %s\n",str_dec(add_dec(0.1,0.2)));
printf("0.1+0.2 == 0.3 = %s\n", 
equal_dec(add_dec(0.1,0.2),0.3)?"True":"False");

x=0.1;
y=mul_dec(x,8.0);
z=0.1;
for (i=1; i<=7; ++i)
  z=add_dec(z,0.1);

printf("0.1*8                           = %s\n",str_dec(y));
printf("0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 = %s\n",str_dec(z));
printf("Difference:                     = %s\n",str_dec(y-z));

}

-- 
Bartc  

[toc] | [prev] | [next] | [standalone]


#2782

From"BartC" <bc@freeuk.com>
Date2014-05-13 19:49 +0100
Message-ID<XOtcv.72133$Ch2.21998@fx13.am4>
In reply to#2780
"BartC" <bc@freeuk.com> wrote in message 
news:JJtcv.95786$Sp6.12404@fx15.am4...

> The following is an example of how it can be done (see main()). Actually,

A couple of the printfs were messed up.

A fixed, downloadable version is here:

http://pastebin.com/0TRdD52q

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#2790

FromRich <rich@example.com>
Date2014-05-14 01:09 +0000
Message-ID<5372c23d$0$17205$c3e8da3$dd9697d2@news.astraweb.com>
In reply to#2782
BartC <bc@freeuk.com> wrote:
> "BartC" <bc@freeuk.com> wrote in message 
> news:JJtcv.95786$Sp6.12404@fx15.am4...

> > The following is an example of how it can be done (see main()). Actually,

> A couple of the printfs were messed up.

> A fixed, downloadable version is here:

> http://pastebin.com/0TRdD52q

Nice.  An educational read.  Thanks for that one.

[toc] | [prev] | [next] | [standalone]


#2791

From"BartC" <bc@freeuk.com>
Date2014-05-14 09:51 +0100
Message-ID<I9Gcv.91670$vt2.2348@fx36.am4>
In reply to#2790

"Rich" <rich@example.com> wrote in message 
news:5372c23d$0$17205$c3e8da3$dd9697d2@news.astraweb.com...
> BartC <bc@freeuk.com> wrote:
>> "BartC" <bc@freeuk.com> wrote in message
>> news:JJtcv.95786$Sp6.12404@fx15.am4...
>
>> > The following is an example of how it can be done (see main()). 
>> > Actually,
>
>> A couple of the printfs were messed up.
>
>> A fixed, downloadable version is here:
>
>> http://pastebin.com/0TRdD52q
>
> Nice.  An educational read.  Thanks for that one.

Odd how slight changes creep in between testing and posting! (I think 
because one compiler out of seven had trouble with it and I was trying to 
find out why.)

 I couldn't edit the 'guest' version above. But if someone wants to run the 
code, it's best to change the "(%f)" in str_dec() to "(%.28f)", or use this 
version:

http://pastebin.com/uwpzHLH6

which shows the decimal results accompanied by a more precise internal 
representation, to highlight that the underlying values still have the 
inaccuracies, yet do not affect the ability to emulate decimal arithmetic.

There is still the problem that a result ending in more or less exactly 
x.xx5 (using 2 decimal places) can be rounded either up or down depending on 
slight differences in the floating point representation between machines. 
However that would be an issue with true decimal arithmetic too (what is 
half of 0.99 expressed to 2 decimals places?). But I think that whatever 
behaviour is stipulated for such matters, could also be emulated.

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#2799

Frombde@besplex.bde.org (Bruce Evans)
Date2014-05-14 10:36 +0000
Message-ID<lkvgvv$19v$1@dont-email.me>
In reply to#2780
In article <JJtcv.95786$Sp6.12404@fx15.am4>, BartC <bc@freeuk.com> wrote:
>"Rich" <rich@example.com> wrote in message
>news:537246b1$0$59749$c3e8da3$e074e489@news.astraweb.com...
>> BartC <bc@freeuk.com> wrote:
>
>>> Given enough precision, I believe that binary floating point can
>>> emulate what can be done in decimal arithmetic.
>>
>> Actually, no.

Actually, yes.

>> 0.1 in decimal is an infinite repeating sequence in binary floating
>> point.  So it is impossible to have enough precision to exactly
>> represent 0.1 (decimal) in binary floating point.

10.0 (0.1 dollars in cents) is equally exact all reasonable implementations
of floating point.

>>   "Similarly, the Java or C expression (0.1+0.2==0.3) evaluates to
>>   false."

Similarly, the Java or C expression (10.0 + 20.0 == 30.0) evaluates to
true.

>No, it's nothing to do with not being able to represent 0.1 exactly. You
>*know* it's an approximation, but can work with that provided the precision
>is greater than the number of decimal digits you're trying to emulate.

Indeed.

>The following is an example of how it can be done (see main()). Actually,
>you can replace the definition of 'myfloat' with just 'float' instead of
>'double', and it will still work (but up to a smaller magnitude). This code
>emulates some decimal arithmetic with two decimal places. (Note that the
>normal 0.1+0.2==0.3 can give True with some compilers.)

Giving True is probably a compiler bug.  The addition may be evaluated
in extra precision in C, but then its result has even less chance of being
accidentally equal to the double precision 0.3.  It is probably a compiler
bug to evaluate any of the double precision constants in extra precision.
Buggy compilers like to misevaluate such expressions at compile time using
different rounding precisions and rounding modes than apply at runtime.
C's rules for when the compiler is permitted to evaluate at compile time
using defaults for rounding are delicate.

>/* Floating emulation of fixed point decimal arithmetic */

Too complicated.  Just do everything in whole cents (or whatever the
minimal unit in the currency is).  In C, require C99 or later, with
IEEE754 support (otherwise you cannot even depend on 1.0 + 1.0 being
2.0).  Use fenv to initialize the FP environment suitably.  Almost
all calculations need to be exact in cents, possibly after rounding
to cents according to financial rules.  Use fenv to check for inexact
results (except in cases where they the intermediate calculations are
expected to be inexact).

>#include <stdio.h>
>#include <stdlib.h>
>#include <math.h>
>
>#define decimals 2
>#define rounding 0.005
>#define factor 100.0
>//#define myfloat float
>#define myfloat double
>
>myfloat round_dec(myfloat x){
>if (x>0.0)
> return floor((x+rounding)*factor)/factor;
>else
> if (x>-rounding) return 0.0;
> return ceil((x-rounding)*factor)/factor;
>}

This only works when the error in the FP calculations is slightly less
than 0.5 cents.  One URL pointed to in this thread gives an example
where adding 0.5 to round up half-way cases doesn't work as expected,
because some expression like 0.49999... + 0.5 gives 1.0 after rounding.

Interest rate calculations are one source of half-way cases.  The
interest rate is presumably specified as a decimal fraction, say
5%/year.  Suppose the principal is $1.10.  The interest in infinite
precision is 5.5 cents.  This must be rounded according to
financial rules.  I don't know what they are, but presumably they
favour bankers, so it is down to 5 cents.  Suppose you calculated
the principal dollars an have a tiny error, so it is $1.10000...1.
Then the interest calculation gives 5.50000...5 cents.  This is
above the half-way point, so hopefully it is not rounded in the
banker's favour and is rounded up to 6 cents.  However, that would
be illegal since the error is in the calculation.

If the financial rules are actually to always round up or down to
cents, then you get the rounding problem whole cents instead of
half-way, and it is practically impossible to round correctly
since no error bound except 0 is sharp enough.

The above is similar to C99's round().  round() just has factor = 1.
Some implementations of round() look similar, but are a bit more
careful to avoid the rounding error for 0.49999... + 0.5 and to
get a specific rounding for exactly half-way cases.

C90 only has rint().  rint() is a bit harder to use, especially in
C90, since it rounds in the current mode and C90 gives no control
over what that is.  But in C99 with IEEE754 support you can use
fesetround() to set a known suitable rounding mode.  rint() with
rounding to nearest mode is the same as round() (round() is mode-
independent), except for half-way cases, where half-way is half-
way between integers here.  Neither of them is any more likely
than the above to match the financial rules (if any) for half-way
cases:
- for rint(), the rounding is machine-dependent (typically, to
  even, so that +-0.5 is rounded to +-0 and +-1.5 is rounded to +-2).
- for round(), the rounding is always towards (+-infinity) (so
  that +-0.5 is rounded to +-1 and +-1.5 is rounded to +-2).
   
Working in cents doesn't completely eliminate the problems.  Adding up
cents is exact up to $90 trillion in IEEE754 double precision.  If
that is not enough, upgrade to 1980s technology with Intel 8087
extended precision.  This works up to $184467 trillion.  But interest
rate calculations need to first calculate fractional cents, then
round according to financial rules.  This seems too hard to do without
doing the first calculation exactly.  This is easy to do by working
in units of decimal fractions of cents for doing the interest rate
calculations.  E.g., for 5% interest, use hundredths of a cent, and
for 5.68725% interest, use millionths of a cent.

Note that decimal FP only simplifies the interest rate calculations if
there are plenty of decimal digits and the rounding mode matches the
financial rounding rules.  Otherwise, there are the following problems:
- as above with $1.10 at 5% interest giving 5.5 cents.  Decimal FP
  gives 5.5 without the complication of working with cents.  But you
  have to use funancial rules and not necessarily the machines FP rules
  to round this
- the machine's precision (now in decimal digits) must have plenty of
  to spare for multiplying by interest rates with many significant
  digits.  8 more for multiplying by 5.68725% = 0.0568725.  So FP that
  can handle up to $90 trillion for adding up cents can only handle
  up to $900 thousand for this interest calculation.  I guess the
  financial rules disallow even more exotic interest rates like
  5.68725187171771777171000003888 that would challenge everyone's
  software.
Decimal precision is less efficient, so it would cost more for the same
effective range.  E.g., the above calculations show that binary 53 bit
precision is no enough, since it only goes up to $900k for the moderately
exotic interest rate.  Binary 64 bit precision goes up to $120 trillion,
so it can handle the world's GDP again.  Decimal needs 2+12+8 = 21
digits to go up to $100 trillion with the exotic precision.  21 decimal
digits take about 64 binary bits, but only in a binary encoding.  I
think practical implementations in hardware would take a few more
binary and cost more.

Bruce

[toc] | [prev] | [next] | [standalone]


#2803

From"BartC" <bc@freeuk.com>
Date2014-05-14 12:58 +0100
Message-ID<jUIcv.37987$ub6.35971@fx32.am4>
In reply to#2799

"Bruce Evans" <bde@besplex.bde.org> wrote in message
news:lkvgvv$19v$1@dont-email.me...
> In article <JJtcv.95786$Sp6.12404@fx15.am4>, BartC <bc@freeuk.com> wrote:
>>"Rich" <rich@example.com> wrote in message
>>news:537246b1$0$59749$c3e8da3$e074e489@news.astraweb.com...
>>> BartC <bc@freeuk.com> wrote:
>>
>>>> Given enough precision, I believe that binary floating point can
>>>> emulate what can be done in decimal arithmetic.
>>>
>>> Actually, no.
>
> Actually, yes.
>
>>> 0.1 in decimal is an infinite repeating sequence in binary floating
>>> point.  So it is impossible to have enough precision to exactly
>>> represent 0.1 (decimal) in binary floating point.
>
> 10.0 (0.1 dollars in cents) is equally exact all reasonable
> implementations
> of floating point.

So what? You don't use the primitive '=' (or '==' in C) between floating
point values when you know the results are not absolutely precise.

>>The following is an example of how it can be done (see main()). Actually,
>>you can replace the definition of 'myfloat' with just 'float' instead of
>>'double', and it will still work (but up to a smaller magnitude). This
>>code
>>emulates some decimal arithmetic with two decimal places. (Note that the
>>normal 0.1+0.2==0.3 can give True with some compilers.)
>
> Giving True is probably a compiler bug.

Not really. Probably just a coincidence. For example, if any constant 0.1 to
0.9 in the code is constructed as a multiple of 0.1, then it could well be
the case that 0.1+0.2 has exactly the same representation as 0.3.

>>/* Floating emulation of fixed point decimal arithmetic */
>
> Too complicated.  Just do everything in whole cents (or whatever the
> minimal unit in the currency is).

The emulation could have used whole units, sure, with input or output scaled
by the right number of decimal places. But it was tidier in this simple demo
to have the stored floating point value be the same as the emulated decimal 
without scaling. Also you can use floating point constants within the code 
as 0.1 without a scale function needed.

>  In C, require C99 or later, with
> IEEE754 support (otherwise you cannot even depend on 1.0 + 1.0 being
> 2.0).

That sounds like a bad implementation, but shouldn't effect the results of
programs like this.

>>myfloat round_dec(myfloat x){
>>if (x>0.0)
>> return floor((x+rounding)*factor)/factor;
>>else
>> if (x>-rounding) return 0.0;
>> return ceil((x-rounding)*factor)/factor;
>>}
>
> This only works when the error in the FP calculations is slightly less
> than 0.5 cents.

That's the trick. If you are emulating some hardware or software that always
has intermediate results with two decimal places (as in my example), then
you do the same. For simple addition or subtraction, you might have to do
large numbers of successive operations, each without rounding, before the
cumulative error approaches 0.005.

With intermediate rounding at each step, the error will rarely be that
large.

>  One URL pointed to in this thread gives an example
> where adding 0.5 to round up half-way cases doesn't work as expected,
> because some expression like 0.49999... + 0.5 gives 1.0 after rounding.

Yes there are issues with rounding where a result is exactly between two
possible values. I mention that in another post.

> Interest rate calculations are one source of half-way cases.  The
> interest rate is presumably specified as a decimal fraction, say
> 5%/year.  Suppose the principal is $1.10.  The interest in infinite
> precision is 5.5 cents.  This must be rounded according to
> financial rules.  I don't know what they are, but presumably they
> favour bankers, so it is down to 5 cents.  Suppose you calculated
> the principal dollars an have a tiny error, so it is $1.10000...1.
> Then the interest calculation gives 5.50000...5 cents.  This is
> above the half-way point, so hopefully it is not rounded in the
> banker's favour and is rounded up to 6 cents.  However, that would
> be illegal since the error is in the calculation.

Floating point gives you the opportunity to round to either 5.0 or 6.0
cents, it doesn't really matter, and remember the approximate 0.5 cents and
add it to next year's interest. Nobody loses out in the long run. Decimal
fixed point can end up discarding some fractions of a cent completely.
Unless you use decimal floating point, then you have the same rounding
problems.

But to solve the above problem, requires a bit more thought. For example, if
interest rates are quoted to a resolution of 0.1% (ie. 0.001), and principal
amounts to $0.01, then any such calculation can only give results to 5
decimal places (but I'm not a mathematician so cannot say for certain).

In other words, any result must be to the nearest $0.00001. Provided there 
is enough floating point precision in reserve, it can make use of this fact 
to apply the right kind of rounding.

In your example, in one instance I got a result of $0.05500000000000000700,
rounded to 0.05500 (to 1/1000 of a cent). Now I can apply a rounding
function more confidently: any value less than 0.054995 can be rounded down
to 0.05000, and above 0.055005 to 0.06000, assuming rounding rules are to
the nearest cent. But I now have a window within which the interest rate 
calculation is expected to be, and that gives me leaway for any FP 
inaccuracies.

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.misc


csiph-web