1

When passing 1113355579999 as an argument, the value changes inside the function to 959050335.

Call(main.c):

printf("%d\n", FindCommonDigit(1113355579999, 123457));

Function(ex4.c):

int FindCommonDigit(long int n1, long int n2) { printf("%d\n", n1); }

What's the problem? worth mentioning that the value changes before getting to the printf.

3 Answers3

6

The decimal number 1113355579999 is too large to be accommodated by a 32-bit integer, which is a common size for type long int, and in fact is the size of long long int in your MSVC environment. On a C implementation that provides 32-bit long ints, that constant has type long long int.

You can pass a long long int to a parameter of type long int, but if the value is too large for long int then the resulting behavior is implementation-defined. Possibly the least-significant 32 bits are retained, which, in the case of your particular number, would result in the number 959050335 (look familiar?). To pass the argument into the function without loss of fidelity, the function parameter must have a type that can accommodate the argument. On a conforming C implementation, long long int will suffice.

Having received the argument correctly, the function must also present it correctly to printf(), else the behavior is undefined. The formatting directive for a long long int expressed in decimal is %lld.

Putting that together, you appear to want this:

int FindCommonDigit(long long int n1, long long int n2) {
    printf("%lld\n", n1);

    return /* ... something ... */;
}

You do need the function to return an int, else the behavior is again undefined.

Additionally, as @pmg observed in comments, a prototype for that function must be in scope at the point where it is called. That would be this ...

int FindCommonDigit(long long int n1, long long int n2);

... near the top of the source file in which the function is used (i.e. main.c). You can put that directly into the file if you like, but you should consider instead putting the prototype into a header file and #includeing that. The latter is particularly useful if the function will be used in multiple source files.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
2

Note that only long long int is guaranteed to be large enough to store the result of that calculation (or, indeed, the input values you're using).

You will also need to ensure that you use your compiler in a C99-compatible mode (for example, using the -std=gnu99 option to gcc). This is because the long long int type was not introduced until C99

  • I'm using Visual Studio, how can I ensure that my C99 compiler is in fact performing? – Ariel Gliksberg Nov 26 '17 at 20:14
  • 1
    Unfortunately, older Visual C is mostly a C89 compiler, with a few C99 features added, and a few non-standard features as well; it looks like this has improved since MSVC2015, though: https://msdn.microsoft.com/en-us/library/hh567368.aspx?f=255&MSPPError=-2147217396 – lockcmpxchg8b Nov 26 '17 at 20:15
  • So essentially the problem is in my compiler? C99 is needed? – Ariel Gliksberg Nov 26 '17 at 20:18
  • Well, the problem is the mismatch between the assumptions and the implementation. If you need 64-bit integers, check whether you have (Visual Studio 2010 and later have it). In that header are defined uint64_t and various other guaranteed-size types. Note that there are special macros for printing the types from `stdint.h`, though. Google how to use "PRIx64" or see https://stackoverflow.com/questions/32112497/how-to-printf-a-64-bit-integer-as-hex for examples. – lockcmpxchg8b Nov 26 '17 at 20:20
  • @ArielGliksberg, although MSVC2015 does not provide a fully-conforming C99 (nor even C89) compiler, I'm pretty sure it does have large enough `long long int`. I'm not a big fan of Visual Studio's C compiler, but I don't think it's the cause of your particular problem. – John Bollinger Nov 26 '17 at 20:24
  • Indeed. In fact, the lack of compiler warnings makes me suspect that `long int` is actually 64-bit for his compiler, and the entire issue stems from using the `"%d"` format specifier, rather than `"%ld"`. To make the code portable, though, `` is the way to go. – lockcmpxchg8b Nov 26 '17 at 20:29
  • On the contrary, @lockcmpxchg8b, [`long int` is 32 bits on MSVC](https://msdn.microsoft.com/en-us/library/s3f49ktz.aspx). The nature of the OP's problem (only the 32 least-significant bits are conveyed to the function via a `long int` parameter) strongly suggests this, too. I attribute the lack of a warning to (1) MSVC's `int` and `long int` having the same size and representation, and (2, speculative) use of the default warning level. – John Bollinger Nov 26 '17 at 20:38
  • It would be useful to include that info in your answer above. In particular "32-bits being a common size" could give that link and indicate that it is in fact true for the OP. – lockcmpxchg8b Nov 26 '17 at 20:43
-1

1113355579999 is too large to fit in your platform's long ints.

Thomas Padron-McCarthy
  • 27,232
  • 8
  • 51
  • 75