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


Groups > comp.lang.c > #164058 > unrolled thread

Can this program be improved?

Started byManu Raju <MR@invalid.invalid>
First post2021-12-25 01:00 +0000
Last post2021-12-29 15:21 +0000
Articles 20 on this page of 113 — 19 participants

Back to article view | Back to comp.lang.c


Contents

  Can this program be improved? Manu Raju <MR@invalid.invalid> - 2021-12-25 01:00 +0000
    Re: Can this program be improved? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-12-24 21:44 -0800
      Re: Can this program be improved? David Brown <david.brown@hesbynett.no> - 2021-12-25 12:56 +0100
      Re: Can this program be improved? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-12-25 11:13 -0800
      Re: Can this program be improved? Manfred <noname@add.invalid> - 2021-12-25 23:50 +0100
      Re: Can this program be improved? Manu Raju <MR@invalid.invalid> - 2021-12-26 18:52 +0000
        Re: Can this program be improved? Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2021-12-26 19:22 +0000
          Re: Can this program be improved? Manu Raju <MR@invalid.invalid> - 2021-12-26 21:30 +0000
            Re: Can this program be improved? Bart <bc@freeuk.com> - 2021-12-26 22:02 +0000
            Re: Can this program be improved? Richard Damon <Richard@Damon-Family.org> - 2021-12-26 18:24 -0500
            Re: Can this program be improved? Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2021-12-27 00:47 +0000
      Re: Can this program be improved? Guillaume <message@bottle.org> - 2021-12-29 17:52 +0100
        Re: Can this program be improved? Bart <bc@freeuk.com> - 2021-12-29 17:49 +0000
          Re: Can this program be improved? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-12-29 11:33 -0800
            Re: Can this program be improved? James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-12-29 22:45 -0500
              Re: Can this program be improved? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-12-30 00:35 -0800
                Re: Can this program be improved? David Brown <david.brown@hesbynett.no> - 2021-12-30 10:19 +0100
            Re: Can this program be improved? Bart <bc@freeuk.com> - 2022-01-01 18:19 +0000
              Re: Can this program be improved? Bart <bc@freeuk.com> - 2022-01-01 19:33 +0000
          Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-12-29 14:37 -0800
            Re: Can this program be improved? Bart <bc@freeuk.com> - 2021-12-29 23:09 +0000
              Re: Can this program be improved? scott@slp53.sl.home (Scott Lurndal) - 2021-12-29 23:54 +0000
                Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-12-29 16:11 -0800
                Re: Can this program be improved? Kaz Kylheku <480-992-1380@kylheku.com> - 2021-12-30 00:34 +0000
                  Re: Can this program be improved? Bart <bc@freeuk.com> - 2021-12-30 12:49 +0000
                    Re: Can this program be improved? Kaz Kylheku <480-992-1380@kylheku.com> - 2021-12-30 21:04 +0000
                      Re: Can this program be improved? Bart <bc@freeuk.com> - 2021-12-31 02:13 +0000
              Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-12-29 16:09 -0800
                Re: Can this program be improved? Kaz Kylheku <480-992-1380@kylheku.com> - 2021-12-30 00:59 +0000
                  Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-12-29 17:48 -0800
                    Re: Can this program be improved? Kaz Kylheku <480-992-1380@kylheku.com> - 2021-12-30 20:47 +0000
                Re: Can this program be improved? Bart <bc@freeuk.com> - 2021-12-30 01:06 +0000
                  Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-12-30 04:48 -0800
                  Re: Can this program be improved? Manfred <noname@add.invalid> - 2021-12-30 18:16 +0100
                    Re: Can this program be improved? Bart <bc@freeuk.com> - 2021-12-31 02:20 +0000
                      Re: Can this program be improved? Manfred <noname@add.invalid> - 2021-12-31 18:25 +0100
                      Re: Can this program be improved? James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-12-31 18:13 -0500
                        Re: Can this program be improved? Bart <bc@freeuk.com> - 2021-12-31 23:59 +0000
                          Re: Can this program be improved? "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2021-12-31 16:20 -0800
                          Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-12-31 16:35 -0800
                            Re: Can this program be improved? Bart <bc@freeuk.com> - 2022-01-01 00:53 +0000
                              Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-12-31 20:22 -0800
                                Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-12-31 22:04 -0800
                                  Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-01 14:59 -0800
                                    Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-02 17:22 -0800
                                      Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-02 20:49 -0800
                                        Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-03 03:09 -0800
                                          Re: Can this program be improved? scott@slp53.sl.home (Scott Lurndal) - 2022-01-03 16:22 +0000
                                          Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-03 14:42 -0800
                                            Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-03 14:52 -0800
                                              Re: Can this program be improved? gazelle@shell.xmission.com (Kenny McCormack) - 2022-01-03 22:58 +0000
                                                Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-04 04:27 -0800
                                                  Re: Can this program be improved? gazelle@shell.xmission.com (Kenny McCormack) - 2022-01-04 13:39 +0000
                                              Re: Can this program be improved? David Brown <david.brown@hesbynett.no> - 2022-01-04 00:18 +0100
                                              Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-03 15:24 -0800
                                                Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-03 15:43 -0800
                                                  Re: Can this program be improved? Öö Tiib <ootiib@hot.ee> - 2022-01-03 21:19 -0800
                                                  Re: Can this program be improved? Mateusz Viste <mateusz@xyz.invalid> - 2022-01-04 09:23 +0100
                                                    Re: Can this program be improved? Guillaume <message@bottle.org> - 2022-01-04 18:18 +0100
                                                      Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-04 10:35 -0800
                                                        Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-04 14:07 -0800
                                                          Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-04 15:11 -0800
                                                            Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-04 15:47 -0800
                                                              Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-04 18:30 -0800
                                                          Re: Can this program be improved? scott@slp53.sl.home (Scott Lurndal) - 2022-01-04 23:46 +0000
                                                      Re: Can this program be improved? Bart <bc@freeuk.com> - 2022-01-04 18:41 +0000
                                                        Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-04 10:52 -0800
                                                          Re: Can this program be improved? scott@slp53.sl.home (Scott Lurndal) - 2022-01-04 19:00 +0000
                                                            Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-04 11:15 -0800
                                                              Re: Can this program be improved? Guillaume <message@bottle.org> - 2022-01-04 21:57 +0100
                                                          Re: Can this program be improved? Bart <bc@freeuk.com> - 2022-01-04 21:02 +0000
                                                            Re: Can this program be improved? scott@slp53.sl.home (Scott Lurndal) - 2022-01-04 21:38 +0000
                                                            Re: Can this program be improved? Manfred <noname@add.invalid> - 2022-01-04 23:01 +0100
                                                  Re: Can this program be improved? David Brown <david.brown@hesbynett.no> - 2022-01-04 09:31 +0100
                                                    Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-04 01:30 -0800
                                                      Re: Can this program be improved? David Brown <david.brown@hesbynett.no> - 2022-01-04 14:55 +0100
                                                        Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-04 06:21 -0800
                                                          Re: Can this program be improved? David Brown <david.brown@hesbynett.no> - 2022-01-04 16:49 +0100
                                                            Re: Can this program be improved? gazelle@shell.xmission.com (Kenny McCormack) - 2022-01-04 15:56 +0000
                                                      Re: Can this program be improved? gazelle@shell.xmission.com (Kenny McCormack) - 2022-01-04 15:03 +0000
                                            Re: Can this program be improved? gazelle@shell.xmission.com (Kenny McCormack) - 2022-01-03 22:54 +0000
                                      Re: Can this program be improved? Mateusz Viste <mateusz@xyz.invalid> - 2022-01-03 09:22 +0100
                                        Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-03 03:30 -0800
                                          Re: Can this program be improved? David Brown <david.brown@hesbynett.no> - 2022-01-03 17:22 +0100
                                            Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-03 08:48 -0800
                                              Re: Can this program be improved? Mateusz Viste <mateusz@xyz.invalid> - 2022-01-03 18:42 +0100
                                                Re: Can this program be improved? Bart <bc@freeuk.com> - 2022-01-03 17:59 +0000
                                                Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-03 11:09 -0800
                                                  Re: Can this program be improved? Mateusz Viste <mateusz@xyz.invalid> - 2022-01-03 20:32 +0100
                                                    Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-03 11:58 -0800
                                              Re: Can this program be improved? scott@slp53.sl.home (Scott Lurndal) - 2022-01-03 18:13 +0000
                                                Re: Can this program be improved? gazelle@shell.xmission.com (Kenny McCormack) - 2022-01-03 20:05 +0000
                                Re: Can this program be improved? Bart <bc@freeuk.com> - 2022-01-01 16:53 +0000
            Re: Can this program be improved? Kaz Kylheku <480-992-1380@kylheku.com> - 2021-12-30 00:29 +0000
    Re: Can this program be improved? Bart <bc@freeuk.com> - 2021-12-25 12:47 +0000
      Re: Can this program be improved? Manu Raju <MR@invalid.invalid> - 2021-12-26 18:56 +0000
    Re: Can this program be improved? Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2021-12-25 17:38 +0000
      Re: Can this program be improved? Öö Tiib <ootiib@hot.ee> - 2021-12-25 10:58 -0800
        Re: Can this program be improved? Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2021-12-25 19:16 +0000
          Re: Can this program be improved? Öö Tiib <ootiib@hot.ee> - 2021-12-25 11:25 -0800
        Re: Can this program be improved? "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-12-25 15:01 -0800
          Re: Can this program be improved? Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2021-12-25 23:09 +0000
            Re: Can this program be improved? "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-12-25 20:56 -0800
      Re: Can this program be improved? scott@slp53.sl.home (Scott Lurndal) - 2021-12-25 19:30 +0000
        Re: Can this program be improved? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-12-25 15:50 -0800
          Re: Can this program be improved? Manu Raju <MR@invalid.invalid> - 2021-12-26 19:02 +0000
      Re: Can this program be improved? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-12-25 11:53 -0800
      Re: Can this program be improved? Manu Raju <MR@invalid.invalid> - 2021-12-26 19:00 +0000
    Re: Can this program be improved? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-12-25 11:22 -0800
      Re: Can this program be improved? Manu Raju <MR@invalid.invalid> - 2021-12-26 19:01 +0000
    Re: Can this program be improved? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-12-25 13:27 -0800
      Re: Can this program be improved? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-12-25 16:06 -0800
    Re: Can this program be improved? Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2021-12-29 15:21 +0000

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


#164104

FromBart <bc@freeuk.com>
Date2021-12-29 23:09 +0000
Message-ID<sqiprq$1kk$1@dont-email.me>
In reply to#164103
On 29/12/2021 22:37, Keith Thompson wrote:
> Bart <bc@freeuk.com> writes:
> [...]
>> 3) Double is perfectly suitable for representing monetary amounts,
>> especially in a toy program or for personal use. (I've used it for
>> accounts within a small business.)
> 
> In a toy program, sure -- and I'd say *only* in a toy program.
> 
> Using floating-point for money risks, at best, rare off-by-one errors,
> such as a computation yielding a result one cent off from the correct
> value.  I believe that would be considered unacceptable in any
> real-world financial application.

Real-world doesn't need to mean dealing with trillions of dollars to the 
exact cent.

Most businesses work with amounts far smaller. Then I believe the 
precision of float64 is enough to emulate the needed rounding methods.

(But I didn't even bother with that. My app anyway had to work with 
multliple parallel currencies so if an amount was correct to the nearest 
cent on one, it couldn't also be correct in another. But the environment 
was also fairly informal.)

>> But what exactly would be a practical alternative here? To import a
>> decimal float library, or somehow work with int64 whole cents? (Good
>> luck with interest calculations with that.)
> 
> If you only need to do calculations that yield whole numbers of cents,
> then yes, you can use a wide integer (long long or uint64_t, for
> example, or define your own type "in64" if you insist for some reason)
> with a scaling factor of 100.  If you need to do interest calculations
> in the real world (not in a toy program), you need to find out the exact
> rules for those calculations and implement them.

I wouldn't know where to start to apply an interest rate specified to 
multiple decimals, to an integer amount, to yield an integer result.

> [...]
> 
>> 5) I can't see an issue in using pow() to do pow(float,int); the
>> result will not be exact anyway. What is the alternate, to invent a
>> local powint(float,int) routine? Which will probably contain a
>> loop. Or change the logic for an accumulative product. pow() is
>> simpler!
> 
> Integer exponentiation can be done exactly (assuming no overflow).
> pow() can suffer floating-point errors.  Whether pow() is acceptable
> depends on the application and the financial rules governing it.

This is integer exponentation of floating point values. The choice is 
between repeated multiplications, or calling pow().

The latter is likely done with logs and exp() which can introduce 
errors, but if I calculate 3% compound interest monthly over about 80 
years, then the results of:

    1.03 * 1.03 * ...           // 1000 times

and:

    pow(1.03, 1000)

differ only in the 16th significant digit.

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


#164105

Fromscott@slp53.sl.home (Scott Lurndal)
Date2021-12-29 23:54 +0000
Message-ID<Cy6zJ.242630$IW4.143221@fx48.iad>
In reply to#164104
Bart <bc@freeuk.com> writes:
>On 29/12/2021 22:37, Keith Thompson wrote:
>> Bart <bc@freeuk.com> writes:
>> [...]
>>> 3) Double is perfectly suitable for representing monetary amounts,
>>> especially in a toy program or for personal use. (I've used it for
>>> accounts within a small business.)
>> 
>> In a toy program, sure -- and I'd say *only* in a toy program.
>> 
>> Using floating-point for money risks, at best, rare off-by-one errors,
>> such as a computation yielding a result one cent off from the correct
>> value.  I believe that would be considered unacceptable in any
>> real-world financial application.
>
>Real-world doesn't need to mean dealing with trillions of dollars to the 
>exact cent.

Real-world still uses COBOL for these type of applications.

>
>Most businesses work with amounts far smaller. Then I believe the 
>precision of float64 is enough to emulate the needed rounding methods.

Why bother with the error-prone "needed rounding methods".  Use uint64_t
and denominate in mills.

If your domain requires larger numbers, widen it to 128 bits.

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


#164107

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2021-12-29 16:11 -0800
Message-ID<87k0fn2bp9.fsf@nosuchdomain.example.com>
In reply to#164105
scott@slp53.sl.home (Scott Lurndal) writes:
> Bart <bc@freeuk.com> writes:
>>On 29/12/2021 22:37, Keith Thompson wrote:
>>> Bart <bc@freeuk.com> writes:
>>> [...]
>>>> 3) Double is perfectly suitable for representing monetary amounts,
>>>> especially in a toy program or for personal use. (I've used it for
>>>> accounts within a small business.)
>>> 
>>> In a toy program, sure -- and I'd say *only* in a toy program.
>>> 
>>> Using floating-point for money risks, at best, rare off-by-one errors,
>>> such as a computation yielding a result one cent off from the correct
>>> value.  I believe that would be considered unacceptable in any
>>> real-world financial application.
>>
>>Real-world doesn't need to mean dealing with trillions of dollars to the 
>>exact cent.
>
> Real-world still uses COBOL for these type of applications.
>
>>Most businesses work with amounts far smaller. Then I believe the 
>>precision of float64 is enough to emulate the needed rounding methods.
>
> Why bother with the error-prone "needed rounding methods".  Use uint64_t
> and denominate in mills.
>
> If your domain requires larger numbers, widen it to 128 bits.

Compound interest calculations can give intermediate results that are
not a whole number of cents or even mills, and those results must be
rounded to the nearest cent at some specified point using specified
rules.  (And no, I don't know what those rules are.)

Using large integers representing cents or mills is find if all
you're doing is adding and subtracting.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

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


#164109

FromKaz Kylheku <480-992-1380@kylheku.com>
Date2021-12-30 00:34 +0000
Message-ID<20211229162959.990@kylheku.com>
In reply to#164105
On 2021-12-29, Scott Lurndal <scott@slp53.sl.home> wrote:
> Bart <bc@freeuk.com> writes:
>>On 29/12/2021 22:37, Keith Thompson wrote:
>>> Bart <bc@freeuk.com> writes:
>>> [...]
>>>> 3) Double is perfectly suitable for representing monetary amounts,
>>>> especially in a toy program or for personal use. (I've used it for
>>>> accounts within a small business.)
>>> 
>>> In a toy program, sure -- and I'd say *only* in a toy program.
>>> 
>>> Using floating-point for money risks, at best, rare off-by-one errors,
>>> such as a computation yielding a result one cent off from the correct
>>> value.  I believe that would be considered unacceptable in any
>>> real-world financial application.
>>
>>Real-world doesn't need to mean dealing with trillions of dollars to the 
>>exact cent.
>
> Real-world still uses COBOL for these type of applications.
>
>>
>>Most businesses work with amounts far smaller. Then I believe the 
>>precision of float64 is enough to emulate the needed rounding methods.
>
> Why bother with the error-prone "needed rounding methods".  Use uint64_t
> and denominate in mills.

This common intution is incorrect. Financial systems sometimews need to
calculate fractional amounts, like a 15.03% tax or whatever.

And in those situations, you may be required to implement the required
rounding rules: what to do when some fractional result lands halfway
between two pennies: which one does it go to.

You cannot get away from rounding issues just because you used an
integer representation for mills or penies.

-- 
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

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


#164120

FromBart <bc@freeuk.com>
Date2021-12-30 12:49 +0000
Message-ID<sqk9tn$q5h$1@dont-email.me>
In reply to#164109
On 30/12/2021 00:34, Kaz Kylheku wrote:
> On 2021-12-29, Scott Lurndal <scott@slp53.sl.home> wrote:
>> Bart <bc@freeuk.com> writes:
>>> On 29/12/2021 22:37, Keith Thompson wrote:
>>>> Bart <bc@freeuk.com> writes:
>>>> [...]
>>>>> 3) Double is perfectly suitable for representing monetary amounts,
>>>>> especially in a toy program or for personal use. (I've used it for
>>>>> accounts within a small business.)
>>>>
>>>> In a toy program, sure -- and I'd say *only* in a toy program.
>>>>
>>>> Using floating-point for money risks, at best, rare off-by-one errors,
>>>> such as a computation yielding a result one cent off from the correct
>>>> value.  I believe that would be considered unacceptable in any
>>>> real-world financial application.
>>>
>>> Real-world doesn't need to mean dealing with trillions of dollars to the
>>> exact cent.
>>
>> Real-world still uses COBOL for these type of applications.
>>
>>>
>>> Most businesses work with amounts far smaller. Then I believe the
>>> precision of float64 is enough to emulate the needed rounding methods.
>>
>> Why bother with the error-prone "needed rounding methods".  Use uint64_t
>> and denominate in mills.
> 
> This common intution is incorrect. Financial systems sometimews need to
> calculate fractional amounts, like a 15.03% tax or whatever.
> 
> And in those situations, you may be required to implement the required
> rounding rules: what to do when some fractional result lands halfway
> between two pennies: which one does it go to.
> 
> You cannot get away from rounding issues just because you used an
> integer representation for mills or penies.

The problem isn't the recommended rounding method, it's repeatability.

With floating point, an intermediate result might end in .4999999993 or 
in .5000000007. If the rule is that up to exactly 0.5 rounds down, and 
anything beyond rounds up, then it can go either way.

With integer divide, the results should be much more consistent: a 
remainder will either be 4999999993 or 5000000007 or whatever, always.

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


#164132

FromKaz Kylheku <480-992-1380@kylheku.com>
Date2021-12-30 21:04 +0000
Message-ID<20211230124827.649@kylheku.com>
In reply to#164120
On 2021-12-30, Bart <bc@freeuk.com> wrote:
> On 30/12/2021 00:34, Kaz Kylheku wrote:
>> On 2021-12-29, Scott Lurndal <scott@slp53.sl.home> wrote:
>>> Bart <bc@freeuk.com> writes:
>>>> On 29/12/2021 22:37, Keith Thompson wrote:
>>>>> Bart <bc@freeuk.com> writes:
>>>>> [...]
>>>>>> 3) Double is perfectly suitable for representing monetary amounts,
>>>>>> especially in a toy program or for personal use. (I've used it for
>>>>>> accounts within a small business.)
>>>>>
>>>>> In a toy program, sure -- and I'd say *only* in a toy program.
>>>>>
>>>>> Using floating-point for money risks, at best, rare off-by-one errors,
>>>>> such as a computation yielding a result one cent off from the correct
>>>>> value.  I believe that would be considered unacceptable in any
>>>>> real-world financial application.
>>>>
>>>> Real-world doesn't need to mean dealing with trillions of dollars to the
>>>> exact cent.
>>>
>>> Real-world still uses COBOL for these type of applications.
>>>
>>>>
>>>> Most businesses work with amounts far smaller. Then I believe the
>>>> precision of float64 is enough to emulate the needed rounding methods.
>>>
>>> Why bother with the error-prone "needed rounding methods".  Use uint64_t
>>> and denominate in mills.
>> 
>> This common intution is incorrect. Financial systems sometimews need to
>> calculate fractional amounts, like a 15.03% tax or whatever.
>> 
>> And in those situations, you may be required to implement the required
>> rounding rules: what to do when some fractional result lands halfway
>> between two pennies: which one does it go to.
>> 
>> You cannot get away from rounding issues just because you used an
>> integer representation for mills or penies.
>
> The problem isn't the recommended rounding method, it's repeatability.
>
> With floating point, an intermediate result might end in .4999999993 or 
> in .5000000007. If the rule is that up to exactly 0.5 rounds down, and 
> anything beyond rounds up, then it can go either way.

This is fairly straightforward, actually. Suppose we are workign with
dollars and cents, and have a $0.0049999993 or $0.005000000007 result.

We do not just look at the 4 or 5 digit we look at (at least) one more
digit, and round that off first:

  $0.0049...  ->  $0.0050 -> $0.005

  $0.0050...  ->  $0.0050 -> $0.005

Now that we have our mill (tenth of a cent) denomination rounded off
using conventional arithmetic rounding, we then look at the tenth of a
cent digit and round to the cent.

Here we can use a specific rounding rule like Banker's for instance, if
we are so inclined:

  $0.005 -> $0.00  // digit before 5 is 0, which is even, so down

This could be done with character processing: format the floating point
number to a certain number of fixed digits after the decimal point, just
letting sprintf (or whatever function) doing its built-in rounding.
Then, using the resulting decimal, implement the exact pencil-and-paper
rounding method.

Or it can all be done with just floating-point calculations.

The key point is that both of the original numbers $0.0049999993 and
$0.005000000007 are understood to be floating-point approximations
representing precisely half a cent, and with a little care we can get
the rounding to work accordingly: we can get that half a cent value
first, and then implement the required rounding to the cent.

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


#164137

FromBart <bc@freeuk.com>
Date2021-12-31 02:13 +0000
Message-ID<sqlp05$5uc$1@dont-email.me>
In reply to#164132
On 30/12/2021 21:04, Kaz Kylheku wrote:
> On 2021-12-30, Bart <bc@freeuk.com> wrote:
>> On 30/12/2021 00:34, Kaz Kylheku wrote:
>>> On 2021-12-29, Scott Lurndal <scott@slp53.sl.home> wrote:
>>>> Bart <bc@freeuk.com> writes:
>>>>> On 29/12/2021 22:37, Keith Thompson wrote:
>>>>>> Bart <bc@freeuk.com> writes:
>>>>>> [...]
>>>>>>> 3) Double is perfectly suitable for representing monetary amounts,
>>>>>>> especially in a toy program or for personal use. (I've used it for
>>>>>>> accounts within a small business.)
>>>>>>
>>>>>> In a toy program, sure -- and I'd say *only* in a toy program.
>>>>>>
>>>>>> Using floating-point for money risks, at best, rare off-by-one errors,
>>>>>> such as a computation yielding a result one cent off from the correct
>>>>>> value.  I believe that would be considered unacceptable in any
>>>>>> real-world financial application.
>>>>>
>>>>> Real-world doesn't need to mean dealing with trillions of dollars to the
>>>>> exact cent.
>>>>
>>>> Real-world still uses COBOL for these type of applications.
>>>>
>>>>>
>>>>> Most businesses work with amounts far smaller. Then I believe the
>>>>> precision of float64 is enough to emulate the needed rounding methods.
>>>>
>>>> Why bother with the error-prone "needed rounding methods".  Use uint64_t
>>>> and denominate in mills.
>>>
>>> This common intution is incorrect. Financial systems sometimews need to
>>> calculate fractional amounts, like a 15.03% tax or whatever.
>>>
>>> And in those situations, you may be required to implement the required
>>> rounding rules: what to do when some fractional result lands halfway
>>> between two pennies: which one does it go to.
>>>
>>> You cannot get away from rounding issues just because you used an
>>> integer representation for mills or penies.
>>
>> The problem isn't the recommended rounding method, it's repeatability.
>>
>> With floating point, an intermediate result might end in .4999999993 or
>> in .5000000007. If the rule is that up to exactly 0.5 rounds down, and
>> anything beyond rounds up, then it can go either way.
> 
> This is fairly straightforward, actually. Suppose we are workign with
> dollars and cents, and have a $0.0049999993 or $0.005000000007 result.
> 
> We do not just look at the 4 or 5 digit we look at (at least) one more
> digit, and round that off first:
> 
>    $0.0049...  ->  $0.0050 -> $0.005
> 
>    $0.0050...  ->  $0.0050 -> $0.005
> 
> Now that we have our mill (tenth of a cent) denomination rounded off
> using conventional arithmetic rounding, we then look at the tenth of a
> cent digit and round to the cent.


I think I thought of some similar idea at one time, but I never tested 
it for real, and now I'm not so sure.

For example, if instead of 4999993 and 5000007, you have 4499993 and 4500007

Now it's not so clear whether that first digit ends up as 4 or 5.

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


#164106

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2021-12-29 16:09 -0800
Message-ID<87o84z2bsi.fsf@nosuchdomain.example.com>
In reply to#164104
Bart <bc@freeuk.com> writes:
> On 29/12/2021 22:37, Keith Thompson wrote:
>> Bart <bc@freeuk.com> writes:
>> [...]
>>> 3) Double is perfectly suitable for representing monetary amounts,
>>> especially in a toy program or for personal use. (I've used it for
>>> accounts within a small business.)
>> In a toy program, sure -- and I'd say *only* in a toy program.
>> Using floating-point for money risks, at best, rare off-by-one
>> errors,
>> such as a computation yielding a result one cent off from the correct
>> value.  I believe that would be considered unacceptable in any
>> real-world financial application.
>
> Real-world doesn't need to mean dealing with trillions of dollars to
> the exact cent.

But it can mean dealing with thousands of dollars to the exact cent --
and if you get a result of $1234.565001 and round it to $1234.57, when
the rules call for a result of $1234.56, that could be a serious problem.

> Most businesses work with amounts far smaller. Then I believe the
> precision of float64 is enough to emulate the needed rounding methods.

Working with smaller amounts just means that errors like this are rarer,
not that they don't happen.

> (But I didn't even bother with that. My app anyway had to work with
> multliple parallel currencies so if an amount was correct to the
> nearest cent on one, it couldn't also be correct in another. But the
> environment was also fairly informal.)

If "fairly informal" means you don't need results accurate to the cent,
then floating-point might be good enough.  But financial institutions
can't afford that.

>>> But what exactly would be a practical alternative here? To import a
>>> decimal float library, or somehow work with int64 whole cents? (Good
>>> luck with interest calculations with that.)
>> If you only need to do calculations that yield whole numbers of
>> cents,
>> then yes, you can use a wide integer (long long or uint64_t, for
>> example, or define your own type "in64" if you insist for some reason)
>> with a scaling factor of 100.  If you need to do interest calculations
>> in the real world (not in a toy program), you need to find out the exact
>> rules for those calculations and implement them.
>
> I wouldn't know where to start to apply an interest rate specified to
> multiple decimals, to an integer amount, to yield an integer result.

Neither would I.  My understanding is that there are precisely stated
rules that tell you exactly what results a given computation must
produce, for example when computing compound interest.  If you're going
to be writing real-world software, where satisfying those rules is a
requirement, you *must* learn those rules first.  (I haven't done so and
probably won't.)

>> [...]
>> 
>>> 5) I can't see an issue in using pow() to do pow(float,int); the
>>> result will not be exact anyway. What is the alternate, to invent a
>>> local powint(float,int) routine? Which will probably contain a
>>> loop. Or change the logic for an accumulative product. pow() is
>>> simpler!
>> Integer exponentiation can be done exactly (assuming no overflow).
>> pow() can suffer floating-point errors.  Whether pow() is acceptable
>> depends on the application and the financial rules governing it.
>
> This is integer exponentation of floating point values. The choice is
> between repeated multiplications, or calling pow().
>
> The latter is likely done with logs and exp() which can introduce
> errors, but if I calculate 3% compound interest monthly over about 80 
> years, then the results of:
>
>    1.03 * 1.03 * ...           // 1000 times
>
> and:
>
>    pow(1.03, 1000)
>
> differ only in the 16th significant digit.

And if that difference in the 16th significant digit happens to
give you a result that's off by one cent after rounding, that's
a problem -- unless your environment is "fairly informal" and you
don't mind sometimes being off by a cent.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

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


#164110

FromKaz Kylheku <480-992-1380@kylheku.com>
Date2021-12-30 00:59 +0000
Message-ID<20211229163503.145@kylheku.com>
In reply to#164106
On 2021-12-30, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
> Bart <bc@freeuk.com> writes:
>> On 29/12/2021 22:37, Keith Thompson wrote:
>>> Bart <bc@freeuk.com> writes:
>>> [...]
>>>> 3) Double is perfectly suitable for representing monetary amounts,
>>>> especially in a toy program or for personal use. (I've used it for
>>>> accounts within a small business.)
>>> In a toy program, sure -- and I'd say *only* in a toy program.
>>> Using floating-point for money risks, at best, rare off-by-one
>>> errors,
>>> such as a computation yielding a result one cent off from the correct
>>> value.  I believe that would be considered unacceptable in any
>>> real-world financial application.
>>
>> Real-world doesn't need to mean dealing with trillions of dollars to
>> the exact cent.
>
> But it can mean dealing with thousands of dollars to the exact cent --
> and if you get a result of $1234.565001 and round it to $1234.57, when

You cannot get a result of $1234.565... by only additive and subtractive
transactions, such as recording expenses in a ledger whose
denomination is pennies!

(Not unless you neglected to take care of cumulative truncation error
and let that error freely accumulate for a vast number of transactions.
But let's say everything was done right up to the point this $1234.565001
showed up.)

The way you got that half penny in there: 0.56 + 0.005001 is that
you performed a fractional calculation, like calculating a percentage
due to tax or interest or dividend or whatever.

If you calculate a fractional quantity, you must deal with the rounding,
right there and then, based on the applicable requirements.
(Whether or not you're recording monetary amounts using integers!)

For instance, let's suppose that 1234.565001 is the calculation of the
new account balance due to interest earned. The previous balance was
1232.19.  Being recorded in the ledger, that fiture is exact. (Or, if we
use doubles, it is a vastly accurate approximation of 1232.19).

We calculated some interest and came up with 1234.565001. But we cannot
record that; the account is to the penny. So what do we do? We apply
some rounding rule, like Banker's Rounding.

If the result were exactly 1234.565, then according ot Banker's
Rounding, we would round down to 1234.56, because 6 is an even digit.
A 5 following an odd digit would go up.

This kind of thing you must handle even if the inputs amounts (other
than the percentage rate) are integers, and so are the outputs.

In the accounting system I wrote for my self-employment activities,
I used integers representing pennies, but fractionals are calculated
with the help of floating-point. I'm not required to deal with precise,d
decimal-based rounding rules, so what I did is this: the fractional
result (measuring pennies) is calculated in double-precision floating
point. Then this cents amount is subject to the C library round()
function to get it to the closest integer (i.e. cent), and then that is
converted to the integer-based monetary type.

I'm confident I could replace that integer-based monetary type with
floating-point and get all the same results (that would be fairly easily
checked, because the system calculates everything from scratch
from the recrded transaction log, every time it is run; my real data
could be converted to a giant regression test case.)

-- 
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

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


#164112

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2021-12-29 17:48 -0800
Message-ID<87fsqa3lsi.fsf@nosuchdomain.example.com>
In reply to#164110
Kaz Kylheku <480-992-1380@kylheku.com> writes:
> On 2021-12-30, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
[...]
>> But it can mean dealing with thousands of dollars to the exact cent --
>> and if you get a result of $1234.565001 and round it to $1234.57, when
>
> You cannot get a result of $1234.565... by only additive and subtractive
> transactions, such as recording expenses in a ledger whose
> denomination is pennies!

I didn't say otherwise.

[...]

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

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


#164131

FromKaz Kylheku <480-992-1380@kylheku.com>
Date2021-12-30 20:47 +0000
Message-ID<20211230124646.382@kylheku.com>
In reply to#164112
On 2021-12-30, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
> Kaz Kylheku <480-992-1380@kylheku.com> writes:
>> On 2021-12-30, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
> [...]
>>> But it can mean dealing with thousands of dollars to the exact cent --
>>> and if you get a result of $1234.565001 and round it to $1234.57, when
>>
>> You cannot get a result of $1234.565... by only additive and subtractive
>> transactions, such as recording expenses in a ledger whose
>> denomination is pennies!
>
> I didn't say otherwise.

No, you didn't; but so then that doesn't really speak to the issue of
should the base amounts be integers or floating-point.

An integer-based system can have fractional values come up and
has to deal with them.

-- 
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

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


#164111

FromBart <bc@freeuk.com>
Date2021-12-30 01:06 +0000
Message-ID<sqj0mf$532$1@dont-email.me>
In reply to#164106
On 30/12/2021 00:09, Keith Thompson wrote:
> Bart <bc@freeuk.com> writes:

>> Real-world doesn't need to mean dealing with trillions of dollars to
>> the exact cent.
> 
> But it can mean dealing with thousands of dollars to the exact cent --
> and if you get a result of $1234.565001 and round it to $1234.57, when
> the rules call for a result of $1234.56, that could be a serious problem.

With floating point, that result could as easily be just under 1234.565 
as just over. If the requirements really are that binary floating point 
must have exactly identical results, down to the least significant bit, 
even for intermediates so that rounding will always give the same 
results too, then that's what you have to do.

But I don't believe the OP's program is in that class. (This is one of a 
category of exercises, like hashes, prngs, and reading a line of input 
of arbitrary length, where apparently nothing less that a perfect, 
industrial-strength professional solution will do.)


>> Most businesses work with amounts far smaller. Then I believe the
>> precision of float64 is enough to emulate the needed rounding methods.
> 
> Working with smaller amounts just means that errors like this are rarer,
> not that they don't happen.
> 
>> (But I didn't even bother with that. My app anyway had to work with
>> multliple parallel currencies so if an amount was correct to the
>> nearest cent on one, it couldn't also be correct in another. But the
>> environment was also fairly informal.)
> 
> If "fairly informal" means you don't need results accurate to the cent,
> then floating-point might be good enough.  But financial institutions
> can't afford that.

You can easily get results to the nearest cent. The problem can be when 
rounding errors or rounding methods result in discrepancies between 
different approaches, or between different programs and languages.

I just don't think this is a programming issue, more one of requirements 
and specification.


>> I wouldn't know where to start to apply an interest rate specified to
>> multiple decimals, to an integer amount, to yield an integer result.
> 
> Neither would I.  My understanding is that there are precisely stated
> rules that tell you exactly what results a given computation must
> produce, for example when computing compound interest.  If you're going
> to be writing real-world software, where satisfying those rules is a
> requirement, you *must* learn those rules first.  (I haven't done so and
> probably won't.)

Again with real-world. Is this a corner shop or is it Lloyds Bank? Or 
someone working out figures for their tax return? Or doing a personal 
budget?

(In my country, tax returns only need figures in whole pounds, and don't 
need to be that exact. So long as you are not deliberately 
misrepresenting by significant amounts, it doesn't matter if they are a 
pound either way.)

So, what do you think the OP should do?

Remember this is floating point which is generally not exact: 1.00625 
(the factor needed for 7.5% annual interest applied monthly) can't be 
represented precisely IEEE754. Using long integers for this isn't a 
magic bullet, since you still have to multiply by 1.00625.

As it turns out, I do have a clue how it's done: you multiply by 100625 
and divide by 100000.

However, int64 or even int128 don't have enough range to multiply by 
100625 N times before dividing by 100000 N times. You have to do the 
divide at each step. Which means deciding what to do about the remainder 
at each step (especially if negative numbers are involved).

It's back to specifications.

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


#164119

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2021-12-30 04:48 -0800
Message-ID<164e3d93-e3f3-48b9-9399-b0352f02ff3dn@googlegroups.com>
In reply to#164111
On Thursday, 30 December 2021 at 01:06:35 UTC, Bart wrote:
> 
> (In my country, tax returns only need figures in whole pounds, and don't 
> need to be that exact. So long as you are not deliberately 
> misrepresenting by significant amounts, it doesn't matter if they are a 
> pound either way.) 
> 
In the UK, the Inland Revenue doesn't care about small amounts of money.

But, if you write a cheque to Inland Revenue, the amount the bank calculates
you have in your account needs to match the amount the program calculates
you have in your account to the exact penny. Not because accountants care
about one penny, but because any discrepancy, however small, could indicate
some more serious mis-accounting.

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


#164124

FromManfred <noname@add.invalid>
Date2021-12-30 18:16 +0100
Message-ID<sqkphm$p3g$1@gioia.aioe.org>
In reply to#164111
On 12/30/2021 2:06 AM, Bart wrote:
> On 30/12/2021 00:09, Keith Thompson wrote:
>> Bart <bc@freeuk.com> writes:
> 
>>> Real-world doesn't need to mean dealing with trillions of dollars to
>>> the exact cent.
>>
>> But it can mean dealing with thousands of dollars to the exact cent --
>> and if you get a result of $1234.565001 and round it to $1234.57, when
>> the rules call for a result of $1234.56, that could be a serious problem.
> 
> With floating point, that result could as easily be just under 1234.565 
> as just over. If the requirements really are that binary floating point 
> must have exactly identical results, down to the least significant bit, 
> even for intermediates so that rounding will always give the same 
> results too, then that's what you have to do.

Yes, and that's why standard floating point is not suitable for accurate 
accounting.

IEEE 754 floating point types are designed for applications where its is 
OK to assume that all values are approximated, e.g. measurements of 
physical quantities. In this kind of environment the goal is to have 
lots of decimal digits and huge scale of representation, some 
predictable estimate of the propagation of rounding errors, and 
calculation efficiency.
The price of not being able to represent exactly the value 1% (i.e. 
0.01) is acceptable, even if this value is so common, as long as the 
goals above are achieved.

The financial world has different requirements: they want exact results 
whenever possible, and rounding errors, when impossible to avoid, are 
thoroughly regulated.
This is because balancing the books down to the exact cent is important 
to those guys.
In order to achieve this, they are willing to pay some price in terms of 
representable numbers: the whole world uses monetary amounts quantified 
down to the cent (2 decimal digits). In a similar fashion, conversion 
ratios like currency exchange rates are conventionally expressed in a 
fixed amount of significant digits (I think it's 6 or 7 digits), and the 
same is likely to hold for interest rates as well. There's some upper 
limit to the largest monetary amount to handle (e.g. the global wealth), 
and so on.
Finally, calculations need not be super fast: a monetary transaction 
involves much less computation than, say, modeling a magnetic field.

All in all, it's no surprise that the financial world uses different 
data types than floating point, like e.g. the Decimal type.

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


#164138

FromBart <bc@freeuk.com>
Date2021-12-31 02:20 +0000
Message-ID<sqlpcn$3fa$1@dont-email.me>
In reply to#164124
On 30/12/2021 17:16, Manfred wrote:
> On 12/30/2021 2:06 AM, Bart wrote:
>> On 30/12/2021 00:09, Keith Thompson wrote:
>>> Bart <bc@freeuk.com> writes:
>>
>>>> Real-world doesn't need to mean dealing with trillions of dollars to
>>>> the exact cent.
>>>
>>> But it can mean dealing with thousands of dollars to the exact cent --
>>> and if you get a result of $1234.565001 and round it to $1234.57, when
>>> the rules call for a result of $1234.56, that could be a serious 
>>> problem.
>>
>> With floating point, that result could as easily be just under 
>> 1234.565 as just over. If the requirements really are that binary 
>> floating point must have exactly identical results, down to the least 
>> significant bit, even for intermediates so that rounding will always 
>> give the same results too, then that's what you have to do.
> 
> Yes, and that's why standard floating point is not suitable for accurate 
> accounting.
> 
> IEEE 754 floating point types are designed for applications where its is 
> OK to assume that all values are approximated, e.g. measurements of 
> physical quantities. In this kind of environment the goal is to have 
> lots of decimal digits and huge scale of representation, some 
> predictable estimate of the propagation of rounding errors, and 
> calculation efficiency.
> The price of not being able to represent exactly the value 1% (i.e. 
> 0.01) is acceptable, even if this value is so common, as long as the 
> goals above are achieved.
> 
> The financial world has different requirements: they want exact results 
> whenever possible, and rounding errors, when impossible to avoid, are 
> thoroughly regulated.
> This is because balancing the books down to the exact cent is important 
> to those guys.
> In order to achieve this, they are willing to pay some price in terms of 
> representable numbers: the whole world uses monetary amounts quantified 
> down to the cent (2 decimal digits). In a similar fashion, conversion 
> ratios like currency exchange rates are conventionally expressed in a 
> fixed amount of significant digits (I think it's 6 or 7 digits), and the 
> same is likely to hold for interest rates as well. There's some upper 
> limit to the largest monetary amount to handle (e.g. the global wealth), 
> and so on.
> Finally, calculations need not be super fast: a monetary transaction 
> involves much less computation than, say, modeling a magnetic field.
> 
> All in all, it's no surprise that the financial world uses different 
> data types than floating point, like e.g. the Decimal type.

Well, I have my own unlimited precision decimal floating point library. 
But I would still think it a vast overkill for the mortgage calculation 
exercise of the OP's.

It also doesn't magically solve all issues. You'd have problems with 
exactly representing 1/3 of 1% for example, or 1/3 of £1 (approx 33.33p 
or exactly 6/8d in old money), or doing any similar kind of division.

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


#164166

FromManfred <noname@add.invalid>
Date2021-12-31 18:25 +0100
Message-ID<sqnedh$19cf$1@gioia.aioe.org>
In reply to#164138
On 12/31/2021 3:20 AM, Bart wrote:
> On 30/12/2021 17:16, Manfred wrote:
>> On 12/30/2021 2:06 AM, Bart wrote:
>>> On 30/12/2021 00:09, Keith Thompson wrote:
>>>> Bart <bc@freeuk.com> writes:
>>>
>>>>> Real-world doesn't need to mean dealing with trillions of dollars to
>>>>> the exact cent.
>>>>
>>>> But it can mean dealing with thousands of dollars to the exact cent --
>>>> and if you get a result of $1234.565001 and round it to $1234.57, when
>>>> the rules call for a result of $1234.56, that could be a serious 
>>>> problem.
>>>
>>> With floating point, that result could as easily be just under 
>>> 1234.565 as just over. If the requirements really are that binary 
>>> floating point must have exactly identical results, down to the least 
>>> significant bit, even for intermediates so that rounding will always 
>>> give the same results too, then that's what you have to do.
>>
>> Yes, and that's why standard floating point is not suitable for 
>> accurate accounting.
>>
>> IEEE 754 floating point types are designed for applications where its 
>> is OK to assume that all values are approximated, e.g. measurements of 
>> physical quantities. In this kind of environment the goal is to have 
>> lots of decimal digits and huge scale of representation, some 
>> predictable estimate of the propagation of rounding errors, and 
>> calculation efficiency.
>> The price of not being able to represent exactly the value 1% (i.e. 
>> 0.01) is acceptable, even if this value is so common, as long as the 
>> goals above are achieved.
>>
>> The financial world has different requirements: they want exact 
>> results whenever possible, and rounding errors, when impossible to 
>> avoid, are thoroughly regulated.
>> This is because balancing the books down to the exact cent is 
>> important to those guys.
>> In order to achieve this, they are willing to pay some price in terms 
>> of representable numbers: the whole world uses monetary amounts 
>> quantified down to the cent (2 decimal digits). In a similar fashion, 
>> conversion ratios like currency exchange rates are conventionally 
>> expressed in a fixed amount of significant digits (I think it's 6 or 7 
>> digits), and the same is likely to hold for interest rates as well. 
>> There's some upper limit to the largest monetary amount to handle 
>> (e.g. the global wealth), and so on.
>> Finally, calculations need not be super fast: a monetary transaction 
>> involves much less computation than, say, modeling a magnetic field.
>>
>> All in all, it's no surprise that the financial world uses different 
>> data types than floating point, like e.g. the Decimal type.
> 
> Well, I have my own unlimited precision decimal floating point library. 
> But I would still think it a vast overkill for the mortgage calculation 
> exercise of the OP's.

It's not really a matter of unlimited precision, see my remark above 
about the amount of significant digits.

> 
> It also doesn't magically solve all issues. You'd have problems with 
> exactly representing 1/3 of 1% for example, or 1/3 of £1 (approx 33.33p 
> or exactly 6/8d in old money), or doing any similar kind of division.

No finite arithmetic can solve these issues - whatever the base, you 
will always have some divisor that yields an unrepresentable result.

But, as I said, the financial world has addressed this by limiting the 
number of significant digits - decimal digits - in conversion factors. I 
had this information, for international currency exchange rates, from 
someone who used to make up his living writing financial software, and I 
wouldn't be surprised at all if the same applied to other factors as 
well, like interest rates.

I can understand that the difference between an interest rate of 1.03% 
and 1.030000001% is negligible (the business manager may be perfectly 
happy with a discrete choice between say 1.03% and 1.03001%), but 
inexact books balancing is not, even (maybe especially) if it's about a 
cent for a business worth billions.

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


#164178

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2021-12-31 18:13 -0500
Message-ID<sqo2re$fdi$1@dont-email.me>
In reply to#164138
On 12/31/2021 3:20 AM, Bart wrote:
...
> It also doesn't magically solve all issues. You'd have problems with 
> exactly representing 1/3 of 1% for example, or 1/3 of £1 (approx 33.33p 
> or exactly 6/8d in old money), or doing any similar kind of division.

The issue is not about accurately representing the results of all
possible divisions. It's about getting the legally mandated results.
Whenever money is involved, there's people trying to use every possible
trick to get more of it than they're actually entitled to. As a result,
regulatory agencies have gotten heavily involved in such issues,
specifying precisely how financial calculations should be performed.
I've heard from second-hand sources what kinds of requirements those
agencies have imposed, but I have not been able to locate any first-hand
sources. It hardly matters, because the detailed requirements vary from
one country to another, and even between different industries. However,
they all are based upon the same idea:

Every quantity you need to calculate must, in effect, be stored as an
integer with a scaling factor that is an integer power of 10, usually
negative. All calculations are performed as if using ordinary integer
arithmetic, with the appropriate scaling factor for the result. I say
"in effect", because on some platforms you can achieve the same result
by relying upon hardware support for decimal floating point.

The point is, if you don't use either scaled integers or decimal
floating point or something similar, you won't always round the results
of your calculation the same way as is required by the relevant
regulations.  Even if it only happens rarely and only involves a tiny
amount of money, if the regulators find out they will come after you
because the fact that you calculated it incorrectly is taken as evidence
hinting that you were at least sloppy with your calculations, and at
worst, may have been trying to do something fraudulent.

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


#164182

FromBart <bc@freeuk.com>
Date2021-12-31 23:59 +0000
Message-ID<sqo5gl$tbl$1@dont-email.me>
In reply to#164178
On 31/12/2021 23:13, James Kuyper wrote:
> On 12/31/2021 3:20 AM, Bart wrote:
> ...
>> It also doesn't magically solve all issues. You'd have problems with
>> exactly representing 1/3 of 1% for example, or 1/3 of £1 (approx 33.33p
>> or exactly 6/8d in old money), or doing any similar kind of division.
> 
> The issue is not about accurately representing the results of all
> possible divisions. It's about getting the legally mandated results.
> Whenever money is involved, there's people trying to use every possible
> trick to get more of it than they're actually entitled to. As a result,
> regulatory agencies have gotten heavily involved in such issues,
> specifying precisely how financial calculations should be performed.
> I've heard from second-hand sources what kinds of requirements those
> agencies have imposed, but I have not been able to locate any first-hand
> sources. It hardly matters, because the detailed requirements vary from
> one country to another, and even between different industries. However,
> they all are based upon the same idea:
> 
> Every quantity you need to calculate must, in effect, be stored as an
> integer with a scaling factor that is an integer power of 10, usually
> negative. All calculations are performed as if using ordinary integer
> arithmetic, with the appropriate scaling factor for the result. I say
> "in effect", because on some platforms you can achieve the same result
> by relying upon hardware support for decimal floating point.
> 
> The point is, if you don't use either scaled integers or decimal
> floating point or something similar, you won't always round the results
> of your calculation the same way as is required by the relevant
> regulations.  Even if it only happens rarely and only involves a tiny
> amount of money, if the regulators find out they will come after you
> because the fact that you calculated it incorrectly is taken as evidence
> hinting that you were at least sloppy with your calculations, and at
> worst, may have been trying to do something fraudulent.

Then the regulators should themselves provide a library that performs 
arithmetic or other calculations according to their standards.

That's if someone is working on software where this is an actual necessity.

I'm just fed up with people always bringing this up on forums when some 
quantity might involve money. Those advanced requirements are heavily 
dependent on application areas, and little to do with basic programming, 
especially when a language doesn't provide the special types (scaled 
integers etc) that might be needed.

		

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


#164184

From"james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu>
Date2021-12-31 16:20 -0800
Message-ID<b6ea4f7c-dd72-4b9a-95f1-f0cead4610c2n@googlegroups.com>
In reply to#164182
On Friday, December 31, 2021 at 6:59:28 PM UTC-5, Bart wrote:
> On 31/12/2021 23:13, James Kuyper wrote: 
...
> > The point is, if you don't use either scaled integers or decimal 
> > floating point or something similar, you won't always round the results 
> > of your calculation the same way as is required by the relevant 
> > regulations. Even if it only happens rarely and only involves a tiny 
> > amount of money, if the regulators find out they will come after you 
> > because the fact that you calculated it incorrectly is taken as evidence 
> > hinting that you were at least sloppy with your calculations, and at 
> > worst, may have been trying to do something fraudulent.
> Then the regulators should themselves provide a library that performs 
> arithmetic or other calculations according to their standards.

That's not their responsibility. And there's a large body of existing
software that does exactly what's needed. It's mostly specialized accounting
software. If you're using commercial accounting software, it probably
conforms to the relevant requirements.

> That's if someone is working on software where this is an actual necessity. 

Correct. Different financial calculations are subject to different regulations,
and in many cases the relevant regulations are lenient enough to allow
people to ignore these issues. However, that's generally not the case with
mortgages.

> I'm just fed up with people always bringing this up on forums when some 
> quantity might involve money. Those advanced requirements are heavily 
> dependent on application areas, and little to do with basic programming, 
> especially when a language doesn't provide the special types (scaled 
> integers etc) that might be needed.

If you feel that way, then you should be pleased to know that _decimal32,
_decimal64, and _decimal128 are being considered for inclusion in the next
version of the C standard. There were added precisely because of these
issues.

Mortgages are heavily regulated (at least in the US, and I presume also in
most first-world countries where mortgages are even permitted). Any
calculations like the ones the OP was performing should be disclaimed as
only estimates, unless they handle the rounding of the results in the manner
required by law.

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


#164186

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2021-12-31 16:35 -0800
Message-ID<87v8z41efe.fsf@nosuchdomain.example.com>
In reply to#164182
Bart <bc@freeuk.com> writes:
> On 31/12/2021 23:13, James Kuyper wrote:
>> On 12/31/2021 3:20 AM, Bart wrote:
>> ...
>>> It also doesn't magically solve all issues. You'd have problems with
>>> exactly representing 1/3 of 1% for example, or 1/3 of £1 (approx 33.33p
>>> or exactly 6/8d in old money), or doing any similar kind of division.
>> The issue is not about accurately representing the results of all
>> possible divisions. It's about getting the legally mandated results.
>> Whenever money is involved, there's people trying to use every possible
>> trick to get more of it than they're actually entitled to. As a result,
>> regulatory agencies have gotten heavily involved in such issues,
>> specifying precisely how financial calculations should be performed.
>> I've heard from second-hand sources what kinds of requirements those
>> agencies have imposed, but I have not been able to locate any first-hand
>> sources. It hardly matters, because the detailed requirements vary from
>> one country to another, and even between different industries. However,
>> they all are based upon the same idea:
>> Every quantity you need to calculate must, in effect, be stored as
>> an
>> integer with a scaling factor that is an integer power of 10, usually
>> negative. All calculations are performed as if using ordinary integer
>> arithmetic, with the appropriate scaling factor for the result. I say
>> "in effect", because on some platforms you can achieve the same result
>> by relying upon hardware support for decimal floating point.
>> The point is, if you don't use either scaled integers or decimal
>> floating point or something similar, you won't always round the results
>> of your calculation the same way as is required by the relevant
>> regulations.  Even if it only happens rarely and only involves a tiny
>> amount of money, if the regulators find out they will come after you
>> because the fact that you calculated it incorrectly is taken as evidence
>> hinting that you were at least sloppy with your calculations, and at
>> worst, may have been trying to do something fraudulent.
>
> Then the regulators should themselves provide a library that performs
> arithmetic or other calculations according to their standards.

Are you sure they don't?  I'm not.

And if they don't -- is the ISO C committee obligated to provide a
conforming C implementation?

It's not my field and I don't know the details.  Unlike you, I admit that.

> That's if someone is working on software where this is an actual necessity.
>
> I'm just fed up with people always bringing this up on forums when
> some quantity might involve money. Those advanced requirements are
> heavily dependent on application areas, and little to do with basic
> programming, especially when a language doesn't provide the special
> types (scaled integers etc) that might be needed.

As several of us have acknowledged, using floating-point for money is
probably fine for toy or introductory programs.  It's not ok for any
application that interacts with financial regulations.  And I'm fed up
with you whining when anyone points that out.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

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


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

Back to top | Article view | comp.lang.c


csiph-web