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 1 of 6  [1] 2 3 4 5 6  Next page →


#164058 — Can this program be improved?

FromManu Raju <MR@invalid.invalid>
Date2021-12-25 01:00 +0000
SubjectCan this program be improved?
Message-ID<sq63mi$gom$1@dont-email.me>
>
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <math.h>
>
> int main()
> {
>   float P = 100000; // Loan Amount
>   float r = 7.5; // Advertised Interest Rate
>   int n = 12; // Loan Period
>   float payBack = (P * r / 1200 * pow(1 + r / 1200, n)) / (pow((1 + 
> r / 1200), n) - 1);
>   float Opening = P; // Opening Balance
>   float closing = 0;  // Closing Balance
>   float interest = 0;
>   float Total = 0;
>   float repaid = 0;
>
>   printf("\nMonthly payment is: %.2f\n", payBack);
>
>     printf("%10s %14s %13s %10s %14s %12s\n", "Month", "Beginning", 
> "Interest", "Total", "Repayment", "Balance");
>
>     for (int i = 1; i <= n; i++)
>     {
>         for (int j = 0; j <= n; j++)
>         {
>             interest = Opening * r / 1200;
>             Total = Opening + interest;
>             repaid = payBack;
>             closing = Total - payBack;
>         }
>         printf("%10d %14.0f %13.0f %10.0f %14.0f %12.0f\n", i, 
> Opening, interest, Total, repaid, closing);
>         Opening = closing;
>     }
>     return 0;
> }
>
> /*
> * Output should be:
> Monthly payment is: 8675.71
>      Month      Beginning      Interest      Total Repayment Balance
>          1         100000           625     100625 8676 91949
>          2          91949           575      92524 8676 83848
>          3          83848           524      84372 8676 75697
>          4          75697           473      76170 8676 67494
>          5          67494           422      67916 8676 59240
>          6          59240           370      59610 8676 50935
>          7          50935           318      51253 8676 42577
>          8          42577           266      42843 8676 34168
>          9          34168           214      34381 8676 25706
>         10          25706           161      25866 8676 17190
>         11          17190           107      17298 8676 8622
>         12           8622            54       8676 8676 0
>
> */
>
>
>
>
>

[toc] | [next] | [standalone]


#164059

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2021-12-24 21:44 -0800
Message-ID<sq6b3t$ce5$1@dont-email.me>
In reply to#164058
On 12/24/2021 5:00 PM, Manu Raju wrote:
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <math.h>
>>
>> int main()
>> {
>>    float P = 100000; // Loan Amount
>>    float r = 7.5; // Advertised Interest Rate
>>    int n = 12; // Loan Period
>>    float payBack = (P * r / 1200 * pow(1 + r / 1200, n)) / (pow((1 +
>> r / 1200), n) - 1);
>>    float Opening = P; // Opening Balance
>>    float closing = 0;  // Closing Balance
>>    float interest = 0;
>>    float Total = 0;
>>    float repaid = 0;
>>
>>    printf("\nMonthly payment is: %.2f\n", payBack);
>>
>>      printf("%10s %14s %13s %10s %14s %12s\n", "Month", "Beginning",
>> "Interest", "Total", "Repayment", "Balance");
>>
>>      for (int i = 1; i <= n; i++)
>>      {
>>          for (int j = 0; j <= n; j++)
>>          {
>>              interest = Opening * r / 1200;
>>              Total = Opening + interest;
>>              repaid = payBack;
>>              closing = Total - payBack;
>>          }
>>          printf("%10d %14.0f %13.0f %10.0f %14.0f %12.0f\n", i,
>> Opening, interest, Total, repaid, closing);
>>          Opening = closing;
>>      }
>>      return 0;
>> }

Certainly.

1. int main(void)

2. Stop using `float` for local variables. "Default" floating-point type 
in C is `double`. Everything else is used only if you have a good reason 
to do that. In this case you don't.

3. Stop using "regular" floating point types for representing monetary 
quantities. They are not good for that purpose.

4. It appears that you are actually trying to use `float` to represent 
_integer_ quantities (judging by your `printf`). Why?

5. Stop using `pow` for calculating integer powers. You don't really 
need `<math.h>` here.

6. Stop piling up all variable declarations at the beginning of the 
function. Declare variables as locally as possible.

7. Stop using dummy initializers for your variables. It is better to 
leave them uninitialized than initialize them to dummy zeros. This point 
is actually connected to the previous one: once you start declaring 
variables as locally as possible, you'll normally have a meaningful 
initializers for them at the point of declaration.

8. What's going on with capitalization in your variables names? 
`Opening`, `closing`, `interest`, `Total`? Is this a convention of some 
sort?

9. "Magical constants"? What on Earth is `1200`?

10. Repetitive subexpressions, like `1 + r / 1200` (some explicit, some 
slightly obfuscated) are probably a matter of style.... But anyway: DRY 
- do not repeat yourself.

-- 
Best regards,
Andrey Tarasevich

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


#164060

FromDavid Brown <david.brown@hesbynett.no>
Date2021-12-25 12:56 +0100
Message-ID<sq70ss$hlh$1@dont-email.me>
In reply to#164059
On 25/12/2021 06:44, Andrey Tarasevich wrote:

> 
> Certainly.
> 
> 1. int main(void)
> 
> 2. Stop using `float` for local variables. "Default" floating-point type
> in C is `double`. Everything else is used only if you have a good reason
> to do that. In this case you don't.
> 
> 3. Stop using "regular" floating point types for representing monetary
> quantities. They are not good for that purpose.
> 
> 4. It appears that you are actually trying to use `float` to represent
> _integer_ quantities (judging by your `printf`). Why?
> 
> 5. Stop using `pow` for calculating integer powers. You don't really
> need `<math.h>` here.
> 
> 6. Stop piling up all variable declarations at the beginning of the
> function. Declare variables as locally as possible.
> 
> 7. Stop using dummy initializers for your variables. It is better to
> leave them uninitialized than initialize them to dummy zeros. This point
> is actually connected to the previous one: once you start declaring
> variables as locally as possible, you'll normally have a meaningful
> initializers for them at the point of declaration.
> 
> 8. What's going on with capitalization in your variables names?
> `Opening`, `closing`, `interest`, `Total`? Is this a convention of some
> sort?
> 
> 9. "Magical constants"? What on Earth is `1200`?
> 
> 10. Repetitive subexpressions, like `1 + r / 1200` (some explicit, some
> slightly obfuscated) are probably a matter of style.... But anyway: DRY
> - do not repeat yourself.
> 

That's a good list.  Let me add:

11. Be very suspicious of short variable names with a comment attached.
 It /might/ be the best choice, because of the way the variable is used
or how it matches some external information (like a mathematical
formula).  But often it is better to give the variable a more complete
name.  (As a rule of thumb, the smaller the scope, the shorter the
variable name you can get away with.)

12. Be clear in your units - perhaps also including them in names or
even type information (though that is not common in C).  Make it clear
which variables are money, percentages, monthly rates, annual rates, etc.

13. Any variables that are fixed at initialisation and not changed
should be declared with "const".  It makes code clearer and lets the
compiler catch some kinds of mistakes.

14. It looks like you are mixing up 12 years loan period and 12 months
per year, using the same rather anonymous variable "n" for the purpose.


(Don't take this long list as a sign that your code is terrible.  It's
not bad, and I'm sure we've all seen far worse.  But these are all tips
for ways to improve it and get in good coding habits early.)

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


#164065

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2021-12-25 11:13 -0800
Message-ID<868rw81or6.fsf@linuxsc.com>
In reply to#164059
Andrey Tarasevich <andreytarasevich@hotmail.com> writes:

> On 12/24/2021 5:00 PM, Manu Raju wrote:
>
>> [revised to repair white space]
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <math.h>
>>
>> int main()
>> {
>>     float P = 100000; // Loan Amount
>>     float r = 7.5; // Advertised Interest Rate
>>     int n = 12; // Loan Period
>>     float payBack = (P * r / 1200 * pow(1 + r / 1200, n))
>>         / (pow((1 + r / 1200), n) - 1);
>>     float Opening = P; // Opening Balance
>>     float closing = 0; // Closing Balance
>>     float interest = 0;
>>     float Total = 0;
>>     float repaid = 0;
>>     
>>     printf("\nMonthly payment is: %.2f\n", payBack);
>>
>>     printf("%10s %14s %13s %10s %14s %12s\n", "Month", "Beginning",
>>         "Interest", "Total", "Repayment", "Balance");
>>
>>     for (int i = 1; i <= n; i++)
>>     {
>>         for (int j = 0; j <= n; j++)
>>         {
>>             interest = Opening * r / 1200;
>>             Total = Opening + interest;
>>             repaid = payBack;
>>             closing = Total - payBack;
>>         }
>>         printf("%10d %14.0f %13.0f %10.0f %14.0f %12.0f\n", i,
>>             Opening, interest, Total, repaid, closing);
>>         Opening = closing;
>>     }
>>     return 0;
>> }
>
> Certainly.
>
> 1. int main(void)

Check.

> 2. Stop using `float` for local variables.  "Default" floating-point
> type in C is `double`. Everything else is used only if you have a
> good reason to do that.  In this case you don't.

Check.

> 3. Stop using "regular" floating point types for representing
> monetary quantities.  They are not good for that purpose.

For this level of programming I think floating point is okay.  A
problem that is important is the program makes no effort to round
(to the nearest cent, for example), so the calculation gives
funny results typical of calculations done with floating point.
But that problem can be addressed without throwing out floating
point altogether.

> 4. It appears that you are actually trying to use `float` to
> represent _integer_ quantities (judging by your `printf`).  Why?

To me that just looks like what the print formats are, not what
the kinds of quantities are.

> 5. Stop using `pow` for calculating integer powers.  You don't
> really need `<math.h>` here.

I have to vote against this comment.  Using pow() makes it
obvious what is being done, the exponent being integral
notwithstanding.

> 6. Stop piling up all variable declarations at the beginning of
> the function.  Declare variables as locally as possible.

Good advice here I would say, but this rule is a point of style
with differing viewpoints.

> 7. Stop using dummy initializers for your variables.  It is better
> to leave them uninitialized than initialize them to dummy zeros.
> This point is actually connected to the previous one:  once you
> start declaring variables as locally as possible, you'll normally
> have a meaningful initializers for them at the point of declaration.

Check.

> 8. What's going on with capitalization in your variables names?
> Opening`, `closing`, `interest`, `Total`?  Is this a convention of
> some sort?

Check.

> 9.  "Magical constants"?  What on Earth is `1200`?

Check.  However I think it should be added that the "magicness"
of the constant(s) can be addressed by rephrasing the expressions
where they are used, without necessarily taking the constants
out of those expressions.

> 10.  Repetitive subexpressions, like `1 + r / 1200` (some explicit,
> some slightly obfuscated) are probably a matter of style.... But
> anyway:  DRY - do not repeat yourself.

More significant here, I think, is that defining a variable with
the value of this expression offers an opportunity to give some
sort of descriptive name to the quantity.


Two additional points:

The #include <stdlib.h> can be removed.

The inner loop (with 'j' as the index variable) does the same
calculation over and over again.  There is no reason to make
that a loop - just write the body.

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


#164072

FromManfred <noname@add.invalid>
Date2021-12-25 23:50 +0100
Message-ID<sq877f$dof$1@gioia.aioe.org>
In reply to#164059
On 12/25/2021 6:44 AM, Andrey Tarasevich wrote:
> 6. Stop piling up all variable declarations at the beginning of the 
> function. Declare variables as locally as possible.

Put this way, this is questionable advice, IMO.
Experienced programmers may have your same opinion, but some others, 
equally experienced, may label that same programming style as sloppy - 
I've seen some myself.

In order to turn this opinion into good advice, I think there is more to 
add to it:

1) Functions should perform simple, well defined tasks, which implies 
that complex tasks should be split into multiple functions. After you do 
this, then it becomes natural that you don't have "piles" of local 
variables, and you may well have the variables you need at the beginning 
of the function and still be "local".

2) Make good use of language constructs to keep counters, indexes etc. 
local: for example, instead of declaring a generic counter "n" at the 
beginning of the function and reuse it multiple times, prefer the following:

for (int n = 0; n < COUNT; ++n)
{
   /* ... */
}

and thus have multiple "for" (and friends) constructs each with its own 
counter.

3) If in the function body you have a code section that performs some 
specific operation that needs its local variables, you may use a local 
scope for it, and declare its variables inside it (check point 1 above 
as well):

int myfunction(void)
{
   /* ... */

   {
     int myvar = 42;
     /* ... */
   }

   /* ... */
}

Obviously, the body of language constructs like "if", "for", "while", 
"do" make natural local scopes that are good candidates for this purpose.

4) For algorithmic parameters that may affect the entire task, (e.g. 
number of months in a year), you may well have a "const" variable at the 
beginning of the function. "static const" at the beginning of the source 
file is also an option, as well as many others.

> 
> 7. Stop using dummy initializers for your variables. It is better to 
> leave them uninitialized than initialize them to dummy zeros. This point 
> is actually connected to the previous one: once you start declaring 
> variables as locally as possible, you'll normally have a meaningful 
> initializers for them at the point of declaration.

This is tricky. One of the worst bugs I have ever encountered was 
"strlen" being called on an uninitialized string buffer.

I believe the best option is to initialize variables with meaningful 
values, which leads to locality, as you say, but with my notes above.
However, as a last resort, it is probably better to leave them 
uninitialized, rather than dummy zeros, *if* you have a decent compiler 
that will spot its use before assignment.

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


#164082

FromManu Raju <MR@invalid.invalid>
Date2021-12-26 18:52 +0000
Message-ID<sqae28$g83$1@dont-email.me>
In reply to#164059
On 25/12/2021 05:44, Andrey Tarasevich wrote:
> On 12/24/2021 5:00 PM, Manu Raju wrote:
>>>
>>> #include <stdio.h>
>>> #include <stdlib.h>
>>> #include <math.h>
>>>
>>> int main()
>>> {
>>>    float P = 100000; // Loan Amount
>>>    float r = 7.5; // Advertised Interest Rate
>>>    int n = 12; // Loan Period
>>>    float payBack = (P * r / 1200 * pow(1 + r / 1200, n)) / (pow((1 +
>>> r / 1200), n) - 1);
>>>    float Opening = P; // Opening Balance
>>>    float closing = 0;  // Closing Balance
>>>    float interest = 0;
>>>    float Total = 0;
>>>    float repaid = 0;
>>>
>>>    printf("\nMonthly payment is: %.2f\n", payBack);
>>>
>>>      printf("%10s %14s %13s %10s %14s %12s\n", "Month", "Beginning",
>>> "Interest", "Total", "Repayment", "Balance");
>>>
>>>      for (int i = 1; i <= n; i++)
>>>      {
>>>          for (int j = 0; j <= n; j++)
>>>          {
>>>              interest = Opening * r / 1200;
>>>              Total = Opening + interest;
>>>              repaid = payBack;
>>>              closing = Total - payBack;
>>>          }
>>>          printf("%10d %14.0f %13.0f %10.0f %14.0f %12.0f\n", i,
>>> Opening, interest, Total, repaid, closing);
>>>          Opening = closing;
>>>      }
>>>      return 0;
>>> }
>
>
> 9. "Magical constants"? What on Earth is `1200`?


It is just a figure 12 * 100. You first need to convert percentage into 
decimals by dividing by 100; Then you need to divide the number again by 
12 to give monthly rate. Interest rate is normally annual rate. Hope 
this explains the magic number.





X-Mozilla-Status: 0811
X-Mozilla-Status2: 00000000
X-Mozilla-Keys:                           

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


#164087

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2021-12-26 19:22 +0000
Message-ID<sqafdf$qtd$1@dont-email.me>
In reply to#164082
On Sun, 26 Dec 2021 18:52:14 +0000, Manu Raju wrote:

> On 25/12/2021 05:44, Andrey Tarasevich wrote:
>> On 12/24/2021 5:00 PM, Manu Raju wrote:
>>>>
>>>> #include <stdio.h>
>>>> #include <stdlib.h>
>>>> #include <math.h>
>>>>
>>>> int main()
>>>> {
>>>>    float P = 100000; // Loan Amount
>>>>    float r = 7.5; // Advertised Interest Rate
>>>>    int n = 12; // Loan Period
>>>>    float payBack = (P * r / 1200 * pow(1 + r / 1200, n)) / (pow((1 +
>>>> r / 1200), n) - 1);
>>>>    float Opening = P; // Opening Balance
>>>>    float closing = 0;  // Closing Balance
>>>>    float interest = 0;
>>>>    float Total = 0;
>>>>    float repaid = 0;
>>>>
>>>>    printf("\nMonthly payment is: %.2f\n", payBack);
>>>>
>>>>      printf("%10s %14s %13s %10s %14s %12s\n", "Month", "Beginning",
>>>> "Interest", "Total", "Repayment", "Balance");
>>>>
>>>>      for (int i = 1; i <= n; i++)
>>>>      {
>>>>          for (int j = 0; j <= n; j++)
>>>>          {
>>>>              interest = Opening * r / 1200;
>>>>              Total = Opening + interest;
>>>>              repaid = payBack;
>>>>              closing = Total - payBack;
>>>>          }
>>>>          printf("%10d %14.0f %13.0f %10.0f %14.0f %12.0f\n", i,
>>>> Opening, interest, Total, repaid, closing);
>>>>          Opening = closing;
>>>>      }
>>>>      return 0;
>>>> }
>>
>>
>> 9. "Magical constants"? What on Earth is `1200`?
> 
> 
> It is just a figure 12 * 100. You first need to convert percentage into 
> decimals by dividing by 100; Then you need to divide the number again by 
> 12 to give monthly rate. Interest rate is normally annual rate. Hope 
> this explains the magic number.

Well, you've explained it to us, but not to whomever will read your program next.

A good part of the art of programming is writing readable code; readable to you,
readable to you in 5 years from now, readable to the programmer that has to make
the next change to it, readable to the programmer who has to fix the bug in it.

Your use of 1200 is confusing, unless you already know that it facilitates the
conversion of a yearly interest rate expressed as a percent into a monthly
interest rate expressed as a decimal. It is worth noting that, should you
change the loan period expressed in P, you would /also/ have to change this
1200 "magic number" appropriately (or is P a "loan period in years"? if so,
then I believe that your interest calculations are wrong.)


-- 
Lew Pitcher
"In Skills, We Trust"

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


#164090

FromManu Raju <MR@invalid.invalid>
Date2021-12-26 21:30 +0000
Message-ID<sqanf8$9gs$1@dont-email.me>
In reply to#164087
On 26/12/2021 19:22, Lew Pitcher wrote:
>
>
> Your use of 1200 is confusing, unless you already know that it facilitates the
> conversion of a yearly interest rate expressed as a percent into a monthly
> interest rate expressed as a decimal. It is worth noting that, should you
> change the loan period expressed in P, you would /also/ have to change this
> 1200 "magic number" appropriately (or is P a "loan period in years"? if so,
> then I believe that your interest calculations are wrong.)
>
>

The figure of 1200 will NEVER change. There will always be 12 months in 
a year and we will always have to divide by 100 to express percentage as 
decimals.

The interest rate can change and period (I used n) can also change. I used (n = 12) in my program to fit the table for people to see but 
you can have 360 (30 years * 12). The program will still work.

Tim did a very good job to write a function. Did you see it? It is here.


<===========================================================================================>

void show_payment_table(double amount, double yearly_percentage_rate, 
int months)
{
     double const monthly_rate = yearly_percentage_rate / 100 / 12;
     double const compounded = pow(1 + monthly_rate, months);
     double const adjustment = compounded / (compounded - 1);
     double const payment = amount * monthly_rate * adjustment;

     double balance = amount;

     printf("\nMonthly payment is: %.2f\n", payment);

     printf("%10s %14s %13s %10s %14s %12s\n",
            "Month", "Beginning", "Interest", "Total", "Repayment", 
"Balance");

     for (int i = 1; i <= months; i++)
     {
         double const interest = balance * monthly_rate;
         double const owing = balance + interest;
         double const remaining = owing - payment;

         printf("%10d %14.2f %13.2f %10.2f %14.2f %12.2f\n",
                i, balance, interest, owing, payment, remaining);
         balance = remaining;
     }

<===========================================================================================>

Now in the main function you just need to use it like so:

<===========================================================================================>

show_payment_table(250000, 5.0, 360);

<===========================================================================================>

This program is part of a big project where users will insert their 
figures to calculate their repayments. all they need to enter will be 
the Loan Amount, Interest Rate, and the Duration of the Loan. the 
program will give them the schedule they can base their decision on. The 
Windows Form/WPF will be used for these entries and "ASP.Net/MVC" for 
the web site.

Best regards and have a very Happy New Year.


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


#164094

FromBart <bc@freeuk.com>
Date2021-12-26 22:02 +0000
Message-ID<sqaoqb$hd5$1@dont-email.me>
In reply to#164090
On 26/12/2021 21:30, Manu Raju wrote:
> On 26/12/2021 19:22, Lew Pitcher wrote:
>>
>>
>> Your use of 1200 is confusing, unless you already know that it facilitates the
>> conversion of a yearly interest rate expressed as a percent into a monthly
>> interest rate expressed as a decimal. It is worth noting that, should you
>> change the loan period expressed in P, you would /also/ have to change this
>> 1200 "magic number" appropriately (or is P a "loan period in years"? if so,
>> then I believe that your interest calculations are wrong.)
>>
>>
> 
> The figure of 1200 will NEVER change. There will always be 12 months in
> a year and we will always have to divide by 100 to express percentage as
> decimals.

Imagine this is part of a bigger program, and the constant 1200 also 
occurs elsewhere with a different meaning.

/That/ 1200 might need to change, but now you don't know which 1200s are 
relevant.

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


#164095

FromRichard Damon <Richard@Damon-Family.org>
Date2021-12-26 18:24 -0500
Message-ID<uQ6yJ.190873$3q9.17755@fx47.iad>
In reply to#164090
On 12/26/21 4:30 PM, Manu Raju wrote:
> The figure of 1200 will NEVER change. There will always be 12 months in
> a year and we will always have to divide by 100 to express percentage as
> decimals.

Actually that is a BIG assumption, that assumes that the ONLY payment 
schedule is monthly.

Some people take out loans with Semi-Monthly (or B-Weekly) payment 
schedules to pay things off a bit faster it that is how they get paid.

You might even choose weekly, or some are paid annually or things in 
between.

All these change the 1200 to something else, to something like 100 * 
payments_per_year.

Also, due to how common other operations on interest rates are, it may 
make more sense on a program scale to do the rate/100 early in the 
program and internally store these rates as the actual rate in per unit, 
instead of the artificail percent (that would also allow parts of the 
code to use permill if that was desired (per mill is per 1000 instead of 
percent which is per 100).

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


#164097

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2021-12-27 00:47 +0000
Message-ID<sqb2f3$qtd$2@dont-email.me>
In reply to#164090
On Sun, 26 Dec 2021 21:30:00 +0000, Manu Raju wrote:

> On 26/12/2021 19:22, Lew Pitcher wrote:
>>
>>
>> Your use of 1200 is confusing, unless you already know that it facilitates the
>> conversion of a yearly interest rate expressed as a percent into a monthly
>> interest rate expressed as a decimal. It is worth noting that, should you
>> change the loan period expressed in P, you would /also/ have to change this
>> 1200 "magic number" appropriately (or is P a "loan period in years"? if so,
>> then I believe that your interest calculations are wrong.)
>>
>>
> 
> The figure of 1200 will NEVER change. There will always be 12 months in 
> a year and we will always have to divide by 100 to express percentage as 
> decimals.

30 years ago, when I bought my house, I took out a mortgage. The bank offered
me options to pay in monthly installments, or bi-weekly installments. The bi-weekly
installment option offered a lower individual payment, but at a higher frequency.

So, /yes/, the number of installments per cycle /may/ change.

As for 1200 being an appropriate figure, I disagree. Your 1200 represents /two/
distinct conversion factors. Speaking from a purely "design" point of view, you
never want constants to represent more than one thing.

In this case, your 1200 represents
a) the conversion factor that alters values expressed as a percent into values
   expressed as a decimal, and
b) the conversion factor that alters values expressed as a year into values
   expressed as a number of months.

While it may be convenient for /you/ to consolidate those two conversion factors
into one constant, that consolidation /is not/ obvious, and /can/ lead to issues
if one or the other of those two conversions change.

Remember, you are writing code to be /readable/. The computer doesn't care; it
doesn't know C from COBOL or Brainfuck: it only knows the ones and zeros that
represent it's internal language. What you write must be readable and comprehensible
to other programmers.

[snip]


-- 
Lew Pitcher
"In Skills, We Trust"

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


#164099

FromGuillaume <message@bottle.org>
Date2021-12-29 17:52 +0100
Message-ID<sqi3p9$1bia$1@gioia.aioe.org>
In reply to#164059
Le 25/12/2021 à 06:44, Andrey Tarasevich a écrit :
> On 12/24/2021 5:00 PM, Manu Raju wrote:
>>>
>>> #include <stdio.h>
>>> #include <stdlib.h>
>>> #include <math.h>
>>>
>>> int main()
>>> {
>>>    float P = 100000; // Loan Amount
>>>    float r = 7.5; // Advertised Interest Rate
>>>    int n = 12; // Loan Period
>>>    float payBack = (P * r / 1200 * pow(1 + r / 1200, n)) / (pow((1 +
>>> r / 1200), n) - 1);
>>>    float Opening = P; // Opening Balance
>>>    float closing = 0;  // Closing Balance
>>>    float interest = 0;
>>>    float Total = 0;
>>>    float repaid = 0;
>>>
>>>    printf("\nMonthly payment is: %.2f\n", payBack);
>>>
>>>      printf("%10s %14s %13s %10s %14s %12s\n", "Month", "Beginning",
>>> "Interest", "Total", "Repayment", "Balance");
>>>
>>>      for (int i = 1; i <= n; i++)
>>>      {
>>>          for (int j = 0; j <= n; j++)
>>>          {
>>>              interest = Opening * r / 1200;
>>>              Total = Opening + interest;
>>>              repaid = payBack;
>>>              closing = Total - payBack;
>>>          }
>>>          printf("%10d %14.0f %13.0f %10.0f %14.0f %12.0f\n", i,
>>> Opening, interest, Total, repaid, closing);
>>>          Opening = closing;
>>>      }
>>>      return 0;
>>> }
> 
> Certainly.
> 
> 1. int main(void)
> 
> 2. Stop using `float` for local variables. "Default" floating-point type 
> in C is `double`. Everything else is used only if you have a good reason 
> to do that. In this case you don't.
> 
> 3. Stop using "regular" floating point types for representing monetary 
> quantities. They are not good for that purpose.
> 
> 4. It appears that you are actually trying to use `float` to represent 
> _integer_ quantities (judging by your `printf`). Why?
> 
> 5. Stop using `pow` for calculating integer powers. You don't really 
> need `<math.h>` here.
> 
> 6. Stop piling up all variable declarations at the beginning of the 
> function. Declare variables as locally as possible.
> 
> 7. Stop using dummy initializers for your variables. It is better to 
> leave them uninitialized than initialize them to dummy zeros. This point 
> is actually connected to the previous one: once you start declaring 
> variables as locally as possible, you'll normally have a meaningful 
> initializers for them at the point of declaration.
> 
> 8. What's going on with capitalization in your variables names? 
> `Opening`, `closing`, `interest`, `Total`? Is this a convention of some 
> sort?
> 
> 9. "Magical constants"? What on Earth is `1200`?
> 
> 10. Repetitive subexpressions, like `1 + r / 1200` (some explicit, some 
> slightly obfuscated) are probably a matter of style.... But anyway: DRY 
> - do not repeat yourself.

All good points!

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


#164100

FromBart <bc@freeuk.com>
Date2021-12-29 17:49 +0000
Message-ID<sqi72e$q7e$1@dont-email.me>
In reply to#164099
On 29/12/2021 16:52, Guillaume wrote:
> Le 25/12/2021 à 06:44, Andrey Tarasevich a écrit :


>> 1. int main(void)
>>
>> 2. Stop using `float` for local variables. "Default" floating-point 
>> type in C is `double`. Everything else is used only if you have a good 
>> reason to do that. In this case you don't.
>>
>> 3. Stop using "regular" floating point types for representing monetary 
>> quantities. They are not good for that purpose.
>>
>> 4. It appears that you are actually trying to use `float` to represent 
>> _integer_ quantities (judging by your `printf`). Why?
>>
>> 5. Stop using `pow` for calculating integer powers. You don't really 
>> need `<math.h>` here.
>>
>> 6. Stop piling up all variable declarations at the beginning of the 
>> function. Declare variables as locally as possible.
>>
>> 7. Stop using dummy initializers for your variables. It is better to 
>> leave them uninitialized than initialize them to dummy zeros. This 
>> point is actually connected to the previous one: once you start 
>> declaring variables as locally as possible, you'll normally have a 
>> meaningful initializers for them at the point of declaration.
>>
>> 8. What's going on with capitalization in your variables names? 
>> `Opening`, `closing`, `interest`, `Total`? Is this a convention of 
>> some sort?
>>
>> 9. "Magical constants"? What on Earth is `1200`?
>>
>> 10. Repetitive subexpressions, like `1 + r / 1200` (some explicit, 
>> some slightly obfuscated) are probably a matter of style.... But 
>> anyway: DRY - do not repeat yourself.
> 
> All good points!
> 

All?

2) Nothing wrong with using 'float' when it's appropropriate. Many 
libraries eg. OpenGL make extensive use of float.

It's not obvious that C's /default/ float type is 'double', nor that 
'float' is not the default float type, despite the name!

However, for this application, float is not quite accurate enough.

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.)

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.)

4) Doesn't make sense. The quantities have to be floating point, but are 
simply being printed with zero decimal places, as whole dollars or whatever.

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!

6) I just don't agree with this at all. I like all the cluttery 
declarations out of the way of the logic, and in one place for quick 
reference. Then you also know there are no multiple, incompatible 
instances of any local identifier.

7) I think initialisers are a good idea. Some languages will ensure such 
locals are set to a known starting value, like 0 or 0.0 for static 
types; presumably they think that is a benefit.

Ones like (1) I agree with, but I also think it's a waste of time 
pointing it out, as the practice is so widespread.

Because compilers [not mine!] have long routinely accepted () parameter 
lists without any warnings that args passed to those functions are 
completely unchecked for number or types, most seem to assume that they 
mean /no/ parameters.

In this example program, it means that the code could call main(10, 
20.0, "three") without comment. But then it could still call it legally 
as main() if the (void) was added.

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


#164101

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2021-12-29 11:33 -0800
Message-ID<sqid71$bnf$1@dont-email.me>
In reply to#164100
On 12/29/2021 9:49 AM, Bart wrote:
> On 29/12/2021 16:52, Guillaume wrote:
>> Le 25/12/2021 à 06:44, Andrey Tarasevich a écrit :
> 
> 
>>> 1. int main(void)
>>>
>>> 2. Stop using `float` for local variables. "Default" floating-point 
>>> type in C is `double`. Everything else is used only if you have a 
>>> good reason to do that. In this case you don't.
>>>
>>> 3. Stop using "regular" floating point types for representing 
>>> monetary quantities. They are not good for that purpose.
>>>
>>> 4. It appears that you are actually trying to use `float` to 
>>> represent _integer_ quantities (judging by your `printf`). Why?
>>>
>>> 5. Stop using `pow` for calculating integer powers. You don't really 
>>> need `<math.h>` here.
>>>
>>> 6. Stop piling up all variable declarations at the beginning of the 
>>> function. Declare variables as locally as possible.
>>>
>>> 7. Stop using dummy initializers for your variables. It is better to 
>>> leave them uninitialized than initialize them to dummy zeros. This 
>>> point is actually connected to the previous one: once you start 
>>> declaring variables as locally as possible, you'll normally have a 
>>> meaningful initializers for them at the point of declaration.
>>>
>>> 8. What's going on with capitalization in your variables names? 
>>> `Opening`, `closing`, `interest`, `Total`? Is this a convention of 
>>> some sort?
>>>
>>> 9. "Magical constants"? What on Earth is `1200`?
>>>
>>> 10. Repetitive subexpressions, like `1 + r / 1200` (some explicit, 
>>> some slightly obfuscated) are probably a matter of style.... But 
>>> anyway: DRY - do not repeat yourself.
>>
>> All good points!
>>
> 
> 2) Nothing wrong with using 'float' when it's appropropriate. Many 
> libraries eg. OpenGL make extensive use of float.

That's just emphasizes my the point. The main purpose of "small" types, 
like `float`, `short`, char as plain integer, bit-fields etc. is to save 
memory in quantitatively massive data structures.

That's exactly what OpenGL is intended to work with: massive amounts of 
geometric data. That's why it opts for `float` Everything else is just a 
consequence of that.

> It's not obvious that C's /default/ float type is 'double', nor that 
> 'float' is not the default float type, despite the name!

It doesn't have to be obvious. That's why I state it explicitly.

> 6) I just don't agree with this at all. I like all the cluttery 
> declarations out of the way of the logic, 

Declarations are never cluttery, unless you make a deliberate effort to 
make them that.

> and in one place for quick reference. 

Piling up all variable declarations in one place makes for much slower 
reference: first, one has has to find the pile, then one has to sift 
through the pile.

Local declarations are always instantly visible, making for much quicker 
reference. Basically, with local declarations the matter of "reference" 
is virtually non-existent: the required knowledge is almost always 
naturally and intuitively present within the field of view.

The popular counter-argument stating that "functions have to be small 
with small number of variables" is nothing else that a fake advice whose 
only purpose is to serve as an emergency brace for the cracking and 
crumbling bad practice of piling up variable declarations.

> Then you also know there are no multiple, incompatible 
> instances of any local identifier.

This is a classic "solution looking for a problem": a solution for a 
problem that does not really exist in the first place.

> 7) I think initialisers are a good idea. Some languages will ensure such 
> locals are set to a known starting value, like 0 or 0.0 for static 
> types; presumably they think that is a benefit.

It definitely has a benefit: it works as a bootstrapping point for 
static/dynamic initialization. I.e. gives you a reliable anchoring 
point: something that is guaranteed to be there "even before the 
programs starts", without you having to worry about the initialization 
and associated ordering issues. No other reason.

And this, of course, does not apply outside of static initialization 
contexts. The only thing you achieve by using dummy initializers is 
defeat checks performed by static/dynamic analysis tools.

-- 
Best regards,
Andrey Tarasevich

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


#164113

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2021-12-29 22:45 -0500
Message-ID<sqja15$ea4$1@dont-email.me>
In reply to#164101
On 12/29/21 2:33 PM, Andrey Tarasevich wrote:
> On 12/29/2021 9:49 AM, Bart wrote:
...
>> It's not obvious that C's /default/ float type is 'double', nor that 
>> 'float' is not the default float type, despite the name!
> 
> It doesn't have to be obvious. That's why I state it explicitly.

Stating it explicitly is not as good as providing relevant citations.

That was certainly true in K&R C, where the usual arithmetic conversions
always caused float operands to be converted to double, and the default
argument promotions caused float arguments to be promoted to double.
However, in C90 the usual arithmetic conversions were changed so that
floating-point operands were never converted to a higher precision
unless the other operand had a higher precision.
In C90, none of the standard library functions took a float or long
double argument, but that changed in C99 - all of the math.h functions
now come in three different forms: one suffixed with 'f' that takes
float arguments and/or returns float values, one with no suffix for
double, and on suffixed with 'l' for long double.
C90 also introduced function prototypes. When calling a function with a
prototype declaration in scope (which is now the normal case), the
default argument promotions occur only for the variable parts of
variadic functions. That's the only sense in which "double is the
default" survived past C99.

I'd say that, since C99, it's far from obvious that double is the
default precision, and I'd say that the reason it's not obvious is
because it's no longer true.

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


#164115

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2021-12-30 00:35 -0800
Message-ID<sqjr1g$jd5$1@dont-email.me>
In reply to#164113
On 12/29/2021 7:45 PM, James Kuyper wrote:
> 
> I'd say that, since C99, it's far from obvious that double is the
> default precision, and I'd say that the reason it's not obvious is
> because it's no longer true.

A rather obvious fact that an unsuffixed `0.0` is a `double` still 
grants a significant degree of defaultness (sic) to `double`.

-- 
Best regards,
Andrey Tarasevich

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


#164116

FromDavid Brown <david.brown@hesbynett.no>
Date2021-12-30 10:19 +0100
Message-ID<sqjtip$1km$1@dont-email.me>
In reply to#164115
On 30/12/2021 09:35, Andrey Tarasevich wrote:
> On 12/29/2021 7:45 PM, James Kuyper wrote:
>>
>> I'd say that, since C99, it's far from obvious that double is the
>> default precision, and I'd say that the reason it's not obvious is
>> because it's no longer true.
> 
> A rather obvious fact that an unsuffixed `0.0` is a `double` still
> grants a significant degree of defaultness (sic) to `double`.
> 

If you call a function for which there is no prototype (I think it is
insane that non-prototype declarations are still allowed in C, even C18,
but that's a side point) then any arguments of type "float" are promoted
to "double".  The same applies to arguments to a function with a
variable number of arguments (in the ellipsis part).

That adds to the "double is default" argument (though I agree with James
that it is much less the default in C99 than it was in C90).


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


#164201

FromBart <bc@freeuk.com>
Date2022-01-01 18:19 +0000
Message-ID<sqq5um$udk$1@dont-email.me>
In reply to#164101
On 29/12/2021 19:33, Andrey Tarasevich wrote:
> On 12/29/2021 9:49 AM, Bart wrote:

>> 2) Nothing wrong with using 'float' when it's appropropriate. Many 
>> libraries eg. OpenGL make extensive use of float.
> 
> That's just emphasizes my the point. The main purpose of "small" types, 
> like `float`, `short`, char as plain integer, bit-fields etc. is to save 
> memory in quantitatively massive data structures.
> 
> That's exactly what OpenGL is intended to work with: massive amounts of 
> geometric data. That's why it opts for `float` Everything else is just a 
> consequence of that.

It has to give acceptable results. Presumably float's accuracy is 
sufficient for that. Using less memory, and being somewhat faster, are 
bonuses.

>> and in one place for quick reference. 
> 
> Piling up all variable declarations in one place makes for much slower 
> reference: first, one has has to find the pile, then one has to sift 
> through the pile.
> 
> Local declarations are always instantly visible,

That's the problem! If trying to appreciate the algorithm, the types and 
attributes of the variables are secondary.

Also, the type is only applied to the first occurence. You see 
'interest' being used on a subsequent; what type is it? You glance at 
the top of the function - it's not there! You have to scan backwards 
from where you are until you encounter a matching declaration.

But then, if 'interest' /was/ declared at the top, now you are wasting 
type doing that scan.

(This is a simple program. Have a look at something like the amalgmated 
source file of sqlite3.c, where they really take your style on board.

You also have to contend with names with appear identical but have 
subtle differences, or the same name declared more than once in the same 
function. If you miss the first declaration on that backwards scan, you 
may end up at the wrong one.

Look at the two declarations of pKeyInfo in this extract:

   if( pPart || pOrderBy ){
     int nPart = (pPart ? pPart->nExpr : 0);
     int addrGoto = 0;
     int addrJump = 0;
     int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);

     if( pPart ){
       int regNewPart = reg + pMWin->nBufferCol;
       KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
       addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, 
pMWin->regPart,nPart);
       sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
       addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
       VdbeCoverageEqNe(v);
       windowAggFinal(pParse, pMWin, 1);
       if( pOrderBy ){
         addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
       }
     }

     if( pOrderBy ){
       int regNewPeer = reg + pMWin->nBufferCol + nPart;
       int regPeer = pMWin->regPart + nPart;

       if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
       if( pMWin->eType==TK_RANGE ){
         KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, 
pOrderBy, 0, 0);
         addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, 
nPeer);
         sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
         addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
         VdbeCoverage(v);
       }else{
         addrJump = 0;
       }
       windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT);
       if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
     }

Note that I've helped you by isolating the lines with both declarations, 
but some functions are considerably longer, such as one of 750 lines 
with 3 versions of "pPk".

Yet another delight is a 7000-line function, which uses names such as 
"pcx" and "pCx" (with different types), or "pVtab" (of type sqlite_vtab) 
and "pVTab" (of type VTABLE!).

All the 300+ locals in this function are listed below. Not all identical 
names have the same type (eg. 'len' exists as 'long' and also 'int').

If all were listed at the top, there would necessarily be fewer as you 
couldn't have duplicates (some will be labels), but if sorted like this 
must surely be easier to find than scanning 7000 lines of dense code.


----------------------------------------------

(Sorry the types are not in proper C syntax. Names with void types are 
labels.)

abort_due_to_error             void
abort_due_to_interrupt         void
aEQb                           [6]const uchar
affinity                       schar
aFlag                          [2]const ushort
aGTb                           [6]const uchar
alreadyExists                  int
aLTb                           [6]const uchar
aMem                           ref struct sqlite3_value
and_logic                      [9]const uchar
aOffset                        ref uint
aOp                            ref struct VdbeOp
apArg                          ref ref struct sqlite3_value
apArg                          ref ref struct sqlite3_value
aPermute                       ref int
aRes                           [3]int
arithmetic_result_is_null      void
aRoot                          ref int
aZero                          [16]uchar
azType                         [4]const ref const schar
bIntint                        schar
bRev                           int
c                              int
c                              int
check_for_interrupt            void
cnt                            int
cnt                            int
compare_op                     void
Compiling                      sqlite3.c to sqlite3.exe
db                             ref struct sqlite3
desiredAutoCommit              int
encoding                       uchar
eNew                           int
eOld                           int
eqOnly                         int
exists                         int
file_format                    int
flags                          ushort
flags1                         ushort
flags3                         ushort
fp_math                        void
i                              int
i                              int
i                              int
i                              int
i                              int
i                              int
i                              int
i                              int
i                              int
i                              int
iA                             llong
iA                             llong
iAddr                          uint
iB                             llong
iB                             llong
iCompare                       int
iCookie                        int
iDb                            int
iDb                            int
iDb                            int
iDb                            int
idx                            int
ii                             int
ii                             int
iKey                           llong
iKey                           ullong
iMeta                          int
iMeta                          int
iMoved                         int
initData                       struct (ref struct sqlite3 db,ref ref 
schar pzErrMsg,int iDb,int rc,uint mInitFlags)
iPrior                         uint
iQuery                         int
iRollback                      int
iSavepoint                     int
iSet                           int
isLegacy                       int
isNotInt                       int
isSchemaChange                 int
isTransaction                  int
isWriteLock                    uchar
j                              int
jump_to_p2                     void
jump_to_p2_and_check_for_interrupt void
len                            int
len                            uint
n                              int
n                              int
n                              int
n                              int
n                              int
n                              uint
nArg                           int
nArg                           int
nByte                          int
nByte                          llong
nByte                          llong
nChange                        int
nData                          ullong
nEntry                         llong
nErr                           int
newMax                         uint
next_tail                      void
nField                         int
nField                         int
nField                         int
nHdr                           int
nKeyCol                        int
nMem                           int
nName                          int
no_mem                         void
nProgressLimit                 uint
nRoot                          int
nullFlag                       ushort
nVarint                        int
nVmStep                        uint
nZero                          llong
oc                             int
offset64                       ullong
On                             line: 140
op                             uchar
op_column_corrupt              void
op_column_out                  void
op_column_read_header          void
open_cursor_set_hints          void
opflags                        int
or_logic                       [9]const uchar
origFlags                      ushort
p                              ref struct Vdbe
p1                             int
p1                             int
p1                             int
p1                             int
p2                             int
p2                             int
p2                             int
p2                             int
pArgc                          ref struct sqlite3_value
pBt                            ref struct Btree
pBt                            ref struct Btree
pBt                            ref struct Btree
pBt                            ref struct Btree
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pC                             ref struct VdbeCursor
pCaller                        ref struct VdbeOp
pcDest                         int
pColl                          ref struct CollSeq
pCrsr                          ref struct BtCursor
pCrsr                          ref struct BtCursor
pCrsr                          ref struct BtCursor
pCrsr                          ref struct BtCursor
pCrsr                          ref struct BtCursor
pCrsr                          ref struct BtCursor
pCrsr                          ref struct BtCursor
pCrsr                          ref struct BtCursor
pCtx                           ref struct sqlite3_context
pCtx                           ref struct sqlite3_context
pCtx                           ref struct sqlite3_context
pCtx                           ref struct sqlite3_context
pCur                           ref struct VdbeCursor
pCur                           ref struct VdbeCursor
pCur                           ref struct VdbeCursor
pCur                           ref struct VdbeCursor
pCur                           ref struct VdbeCursor
pcx                            int
pCx                            ref struct VdbeCursor
pCx                            ref struct VdbeCursor
pCx                            ref struct VdbeCursor
pCx                            ref struct VdbeCursor
pData                          ref struct sqlite3_value
pData0                         ref struct sqlite3_value
pDb                            ref struct Db
pDb                            ref struct Db
pDb                            ref struct Db
pDest                          ref struct sqlite3_value
pDest                          ref struct sqlite3_value
pEnd                           ref struct sqlite3_value
pFrame                         ref struct VdbeFrame
pFrame                         ref struct VdbeFrame
pFrame                         ref struct VdbeFrame
pFrame                         ref struct VdbeFrame
pFrame                         ref struct VdbeFrame
pFree                          ref struct UnpackedRecord
pgno                           int
pgno                           int
pIdxKey                        ref struct UnpackedRecord
pIn                            ref struct sqlite3_value
pIn1                           ref struct sqlite3_value
pIn2                           ref struct sqlite3_value
pIn3                           ref struct sqlite3_value
pKey                           ref struct sqlite3_value
pKeyInfo                       ref struct KeyInfo
pKeyInfo                       ref struct KeyInfo
pKeyInfo                       ref struct KeyInfo
pLast                          ref struct sqlite3_value
pMem                           ref struct sqlite3_value
pMem                           ref struct sqlite3_value
pMem                           ref struct sqlite3_value
pMem                           ref struct sqlite3_value
pMem                           ref struct sqlite3_value
pMem                           ref struct sqlite3_value
pModule                        ref struct sqlite3_module
pModule                        ref struct sqlite3_module
pModule                        ref struct sqlite3_module
pModule                        ref struct sqlite3_module
pModule                        ref struct sqlite3_module
pModule                        ref struct sqlite3_module
pName                          ref struct sqlite3_value
pnErr                          ref struct sqlite3_value
pNew                           ref struct Savepoint
pOp                            ref struct VdbeOp
pOrig                          ref struct VdbeCursor
pOut                           ref struct sqlite3_value
pPager                         ref struct Pager
pProgram                       ref struct SubProgram
pQuery                         ref struct sqlite3_value
pRec                           ref struct sqlite3_value
pReg                           ref struct sqlite3_value
pRt                            ref struct sqlite3_value
pSavepoint                     ref struct Savepoint
pTab                           ref struct Table
pTab                           ref struct Table
pTabCur                        ref struct VdbeCursor
pTmp                           ref struct Savepoint
pVar                           ref struct sqlite3_value
pVCur                          ref struct sqlite3_vtab_cursor
pVCur                          ref struct sqlite3_vtab_cursor
pVtab                          ref struct sqlite3_vtab
pVtab                          ref struct sqlite3_vtab
pVtab                          ref struct sqlite3_vtab
pVtab                          ref struct sqlite3_vtab
pVtab                          ref struct sqlite3_vtab
pVtab                          ref struct sqlite3_vtab
pVtab                          ref struct sqlite3_vtab
pVTab                          ref struct VTable
pX                             ref struct Btree
pX                             ref struct sqlite3_value
r                              struct (ref struct KeyInfo pKeyInfo,ref 
struct sqlite3_value aMem,ushort nField,schar default_rc,uchar 
errCode,schar r1,schar r2,uchar eqSeen)
r                              struct (ref struct KeyInfo pKeyInfo,ref 
struct sqlite3_value aMem,ushort nField,schar default_rc,uchar 
errCode,schar r1,schar r2,uchar eqSeen)
r                              struct (ref struct KeyInfo pKeyInfo,ref 
struct sqlite3_value aMem,ushort nField,schar default_rc,uchar 
errCode,schar r1,schar r2,uchar eqSeen)
r                              struct (ref struct KeyInfo pKeyInfo,ref 
struct sqlite3_value aMem,ushort nField,schar default_rc,uchar 
errCode,schar r1,schar r2,uchar eqSeen)
rA                             double
rB                             double
rc                             int
res                            int
res                            int
res                            int
res                            int
res                            int
res                            int
res                            int
res                            int
res                            int
res                            int
res                            int
res                            int
res                            int
res2                           int
resetSchemaOnFault             uchar
rowid                          llong
rowid                          llong
sContext                       struct (ref struct sqlite3_value pOut,ref 
struct FuncDef pFunc,ref struct sqlite3_value pMem,ref struct Vdbe 
pVdbe,int iOp,int isError,uchar skipFlag,uchar argc,[1]ref struct 
sqlite3_value argv)
seek_not_found                 void
seekResult                     int
serial_type                    uint
sMem                           struct (union MemValue u,ushort 
flags,uchar enc,uchar eSubtype,int n,ref schar z,ref schar zMalloc,int 
szMalloc,uint uTemp,ref struct sqlite3 db,ref proc(ref void)void xDel)
sMem                           struct (union MemValue u,ushort 
flags,uchar enc,uchar eSubtype,int n,ref schar z,ref schar zMalloc,int 
szMalloc,uint uTemp,ref struct sqlite3 db,ref proc(ref void)void xDel)
sz                             llong
t                              ref void
t                              uint
takeJump                       int
too_big                        void
type1                          ushort
type2                          ushort
uA                             ullong
v                              llong
v                              llong
v1                             int
v2                             int
val                            llong
vdbe_return                    void
vfsFlags                       const int
vtabOnConflict                 uchar
wrFlag                         int
x                              llong
x                              ref proc(ref void,ref const schar)void
x                              struct (ref const void pKey,llong 
nKey,ref const void pData,ref struct sqlite3_value aMem,ushort nMem,int 
nData,int nZero)
x                              struct (ref const void pKey,llong 
nKey,ref const void pData,ref struct sqlite3_value aMem,ushort nMem,int 
nData,int nZero)
z                              ref const schar
z                              ref schar
z                              ref schar
z                              ref schar
zAffinity                      ref const schar
zAffinity                      ref schar
zData                          ref const uchar
zDb                            ref const schar
zDb                            ref const schar
zEndHdr                        ref const uchar
zFilename                      ref const schar
zHdr                           ref const uchar
zMaster                        ref const schar
zName                          ref schar
zNewRecord                     ref uchar
zSql                           ref schar
zTab                           ref const schar
zTrace                         ref schar

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


#164205

FromBart <bc@freeuk.com>
Date2022-01-01 19:33 +0000
Message-ID<sqqab7$sbi$1@dont-email.me>
In reply to#164201
On 01/01/2022 18:19, Bart wrote:
> On 29/12/2021 19:33, Andrey Tarasevich wrote:

>> Local declarations are always instantly visible,

[Summary of local variables from a giant sqlite3.c function]

> nByte                          int
> nByte                          llong
> nByte                          llong

Don't get caught out!

> nField                         int
> nField                         int
> nField                         int

> p1                             int
> p1                             int
> p1                             int
> p1                             int

> pBt                            ref struct Btree
> pBt                            ref struct Btree
> pBt                            ref struct Btree
> pBt                            ref struct Btree

> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor
> pC                             ref struct VdbeCursor


> pCrsr                          ref struct BtCursor
> pCrsr                          ref struct BtCursor
> pCrsr                          ref struct BtCursor
> pCrsr                          ref struct BtCursor
> pCrsr                          ref struct BtCursor
> pCrsr                          ref struct BtCursor
> pCrsr                          ref struct BtCursor
> pCrsr                          ref struct BtCursor

> pFrame                         ref struct VdbeFrame
> pFrame                         ref struct VdbeFrame
> pFrame                         ref struct VdbeFrame
> pFrame                         ref struct VdbeFrame
> pFrame                         ref struct VdbeFrame

> res                            int
> res                            int
> res                            int
> res                            int
> res                            int
> res                            int
> res                            int
> res                            int
> res                            int
> res                            int
> res                            int
> res                            int
> res                            int
> res2                           int

The above sets of identical names highlight other problems with local 
declarations. Take the 24 versions of 'pC', with struct VdbeFrame*; 
suppose the type needed to change; now you have to change 24 versions of it.

But, you won't know there are 24 versions; you will need to hunt them 
down. Maybe some of the 24 are unrelated in use, and need to stay the 
same type. But the function has mixed them all up in the same way that 
all instances of a literal '1200' can be mixed up in a program.


> x                              llong
> x                              ref proc(ref void,ref const schar)void
> x                              struct (ref const void pKey,llong 

I haven't analysed how these names relate to each within the block 
structure. But suppose the x's are in nested blocks, and one declaration 
is missed out. That one may be shadowing an outer 'x' - of the wrong 
type. With luck, its used will cause a type error, but if not...


> nKey,ref const void pData,ref struct sqlite3_value aMem,ushort nMem,int 
> nData,int nZero)
> x                              struct (ref const void pKey,llong 
> nKey,ref const void pData,ref struct sqlite3_value aMem,ushort nMem,int 
> nData,int nZero)

> z                              ref const schar
> z                              ref schar
> z                              ref schar
> z                              ref schar

... or it ends up with a version that has a missing 'const'. Even when 
they're all the same type, you could end writing or reading into the 
wrong variable.

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


#164103

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2021-12-29 14:37 -0800
Message-ID<87sfub2g2t.fsf@nosuchdomain.example.com>
In reply to#164100
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.

> 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.

[...]

> 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.

[...]

-- 
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 1 of 6  [1] 2 3 4 5 6  Next page →

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


csiph-web