2

I apologize for any misunderstanding here with data types or the way C operates (I am relatively new to learning still). Can someone explain to me why I am unable to get the desired output (see below)?

#include<stdio.h>
#include<math.h>

#define size         10

typedef unsigned int      Uint16;

typedef long double        float64;


Uint16 i;


float64 normalization = 0;

void main() {

  for (i=0;i<size;i++)
  {
     normalization = normalization + i;    // same as "normalization += i;"

     printf("\n --------");
     printf("\n normalization %f", normalization);

  }

  return;
}

The console output is the following:

 --------
 normalization 0.000000
 --------
 normalization -0.000000
 --------
 normalization -2.000000
 --------
 normalization -2.000000
 --------
 normalization -0.000000
 --------
 normalization -3105036184601417900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
 --------
 normalization -0.000000
 --------
 normalization -26815615859885194000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
 --------
 normalization -0.000000
 --------
 normalization -0.000000

I am expecting the output to be:

normalization = 0
normalization = 1
normalization = 3
normalization = 6
normalization = 10
normalization = 15
// and so forth...
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Tony Pendleton
  • 358
  • 1
  • 11
  • 1
    On many systems, `unsigned int` is not a 16-bit type but a 32-bit type. On some (most 64-bit) systems, `long double` is a 128-bit type. Your code — or at least the numbers assigned to your typedefs — is not portable. – Jonathan Leffler Feb 19 '20 at 15:15
  • 3
    Note that `void main()` is a non-standard return type for `main()`. See [What should `main()` return in C and C++?](https://stackoverflow.com/q/204476/15168) for exhaustive details. Also, the variable `i` should not be global; it should be local to `main()`, or even to the `for` loop: `for (int i = 0; i < size; i++)`. Similarly for `normalization`; that should be a variable local to `main()`. – Jonathan Leffler Feb 19 '20 at 15:19
  • Since the `%f` format (with appropriate type size modifiers) prints 6 decimal places, you won't get what you expect using it as simply as that. You can request 0 decimal places with `%.0f` (with appropriate type size modifiers). – Jonathan Leffler Feb 19 '20 at 15:25

2 Answers2

6

The problem here is mismatching format specifier and argument type, leading to undefined behavior.

The format %f (as well as %lf) is for plain double, not long double.

For long double you need to use the printf prefix L for the format, as in %Lf:

printf("normalization %Lf\n", normalization);

On an unrelated note, please make it a habit to have trailing newlines in your output. Because output to stdout (which is where printf writes) by default is line buffered, leading newline could lead to unexpected "missing" output.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
5

A long double cannot be printed with %f. Instead use double, which will work with the printf format specifier %f.

Alternatively, if you really want to use long double, you can use %Lf (case sensitive) to print it.

If you specifically want the output you specified without trailing zeros, you'll have to use %g (for double) or %Lg (for long double; case-sensitive).

Also note that long double is not always 64 bits wide, and unsigned int is not always 16 bits wide. A much better idea than using your float64 and Uint16 would be to simply use the types without typedefs, as you should not assume the widths of the types.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
  • I appreciate the help! However, I am still receiving the same issue because changing `%f` to `%Lf` or `%lf` or `%g` or `%Lg` does not work. Can someone try to replicate the example I provided? It will help me understand if the issue is elsewhere in my project. Thank you all so much for the help! :) – Tony Pendleton Feb 19 '20 at 15:15
  • @TonyPendleton It's `%Lf`. Note the lowercase `f` and the uppercase `L`. – S.S. Anne Feb 19 '20 at 15:18
  • 1
    @TonyPendleton How does it not work? If you have changed `long double` to `double` then you need to use `%f` or `%g`. – S.S. Anne Feb 19 '20 at 15:23
  • That's on me! Thank you. I forgot to change that. All I had to do was change `typedef long double float64;` to `typedef double float64;` – Tony Pendleton Feb 19 '20 at 15:28
  • @TonyPendleton But, as noted in the answer, you really shouldn't be using these `typedef`s. They make assumptions about the variable sizes and make it unclear what types you're dealing with (which you apparently have noticed). – S.S. Anne Feb 19 '20 at 15:29