Преобразование из unsigned long int в подписанное int и наоборот

Я хотел бы передать подписанное int gsl_rng_uniform_int (const gsl_rng * r, unsigned long int n). Знаковое int, которое я передаю, больше или равно нулю. Функция вернет число от 0 до n, поэтому, если я передаю ей положительное подписанное int, она вернет что-то, что находится в диапазоне подписанного int. Затем я хочу сохранить возвращаемое значение в подписанном int. Какой самый чистый способ сделать это с очевидным ожидаемым поведением? Я использую 64-битный компилятор на 64-битной машине Linux.

Обновление. Извините, ребята. Пожалуйста, игнорируйте. Проблема с моим кодом была в другом месте. Я неверно истолковал вывод gdb.


person mshang    schedule 27.07.2011    source источник


Ответы (2)


Начнем с:

int input = something;
int result = gsl_rng_uniform_int(r, input);

Скорее всего, компилятор предупредит о небезопасном сужающем преобразовании, поэтому измените значение на:

// 0 <= return value < input, so conversion is safe
int result = (int) gsl_rng_uniform_int(r, input);

Или в целях безопасности:

if (input <= 0) { panic(); }
unsigned long rawresult = gsl_rng_uniform_int(r, input);
if (rawresult > INT_MAX) { panic(); }
int result = (int) rawresult;

Эти строки можно обернуть вспомогательной функцией:

int gsl_rng_uniform_signed(const gsl_rng *r, int input) {
    if (input <= 0) { panic(); }
    unsigned long rawresult = gsl_rng_uniform_int(r, input);
    if (rawresult > INT_MAX) { panic(); }
    return (int) rawresult;
}

В любом случае тестирование вашего ввода обычно более полезно, чем тестирование вывода функций, на которые вы полагаетесь, и если вы доверяете gsl_rng_uniform_int, тогда достаточно тестирования ввода.

[Edit: вау, Google индексирует ТАК очень агрессивно. Я просто искал, чтобы убедиться, что gsl_rng_uniform_signed еще не является функцией, и нашел себя.]

person Steve Jessop    schedule 27.07.2011

Если функция ожидает unsigned long, вы можете без проблем передать unsigned long, unsigned int, unsigned short и unsigned char, стандарт гарантирует это.

Если вы передадите signed, но отрицательно int, вы не получите правильных результатов, так как функция будет оценивать его как очень большое целое число.

Лучший способ - проверить, является ли подписанное int >= 0 перед его передачей.

Надеюсь, я правильно понял ваш вопрос.

person Vinicius Kamakura    schedule 27.07.2011