0

I am reading from a JSON file using jannson library. The key I am reading for has a value that is of type unsigned int. Jannson cannot recognize unsigned int. So, I am reading the value as a long long. How do I convert this long long value safely to an unsigned int?

user304255
  • 121
  • 1
  • 7
  • 4
    You may not be able to since a `long long` may hold negative numbers and numbers to large for an `unsigned int`. Are you using C or C++? Pick one. – Ted Lyngmo Jun 04 '19 at 00:46
  • 1
    How do you define "safely"? If the value is certainly within the range of `unsigned int`, then just converting it will be safe. – Nicol Bolas Jun 04 '19 at 00:46
  • @TedLyngmo: "*Are you using C or C++?*" In this case, it doesn't really matter, since they both share the same wording with regard to converting integer values. – Nicol Bolas Jun 04 '19 at 00:47
  • `unsigned int result = static_cast(long_long_value);` – Ted Lyngmo Jun 04 '19 at 00:47
  • 3
    @NicolBolas C++ does have other casting options like `static_cast` that C does not have. – tadman Jun 04 '19 at 00:51
  • @tadman: But they don't actually *change anything* in this case. If `static_cast` is well-defined, then a C-style cast will be well-defined too. And vice-versa. – Nicol Bolas Jun 04 '19 at 00:59
  • 1
    @NicolBolas I'm not arguing about the well-defined angle, you're right there, but that C++ prefers things like `static_cast` so that bad conversions can be flagged by the compiler. Normally C doesn't care, it just does what's told, where all sorts of ugly truncation errors can and will occur. `(int) floatX` is totally valid even if it produces undefined behaviour for a wide range of values. – tadman Jun 04 '19 at 01:00
  • 1
    @NicolBolas C++ has other options like `gsl::narrow` and `gsl::narrow_cast` that would be recommended in this case whereas in `C` would be done differently. Reference: https://stackoverflow.com/questions/52863643/understanding-gslnarrow-implementation – Galik Jun 04 '19 at 03:04

3 Answers3

4

How to convert long long to unsigned int in C/C++?

Test if the value is in range.
C solution:

#include <stdbool.h>
#include <limits.h>

// return error status 
bool ll_to_u(unsigned *y, long long x) {
  if (x < 0) {
    return true;
  }
  #if LLONG_MAX > UINT_MAX
  if (x > UINT_MAX) {
    return true;
  }
  #endif
  *y = (unsigned) x;
  return false;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

To avoid narrowing conversion errors it's safer to use - numeric_cast

numeric_cast is easy to add to project because used boost code is header only - no need to build boost. This way you can catch exception in case of lost of precision in run-time.

If safety is not the main priority (or you are confident that unsigned int is always sufficient to contain the long long value) than use:

static_cast<unsigned int>(llval)
Vlad
  • 1,977
  • 19
  • 44
1

How do I convert this long long value safely to an unsigned int?

Like this:

long long input = ...
if (input < 0)
    throw std::runtime_error("unrepresentable value");
if (sizeof(unsigned) < sizeof(long long)
&& input > static_cast<long long>(std::numeric_limits<unsigned>::max()))
    throw std::runtime_error("unrepresentable value");
return static_cast<unsigned>(input);

You can use any other error handling method of your choice if you don't like exceptions.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • 1
    sizeof(unsigned) < sizeof(long long) is known in compile time. It's amazing how checks and optimizations may expand library code. Sometimes errors were found in well-known library functions after many years ) –  Jun 04 '19 at 02:28
  • from the other side it's useful to know K&R strlen implementation for educational purposes. –  Jun 04 '19 at 02:35