Цель C - Как конвертировать двойное в длинное - PullRequest
2 голосов
/ 14 октября 2011

У меня есть двойное значение 1318611498349.3559, я хотел преобразовать его в long, выполнив следующее, но получаю значение -4506682935000170496, что мне кажется неправильным.найти документацию по этому вопросу?

Ответы [ 6 ]

5 голосов
/ 30 апреля 2012

Другие ответы верны в том смысле, что double может содержать значения, значительно превышающие любой целочисленный тип, однако, если значение double находится в пределах диапазона, было бы неплохо иметь возможность преобразовать.

Причина, по которой компиляторне пытается вас обмануть, если вы пытаетесь просто бросить дубль в длинную, потому что вы действительно можете это сделать.Очевидно, что все в компьютере хранится в виде строк из 1 и 0, в основном ваш код говорит: возьмите vIn и интерпретируйте биты как длинное целое значение.Взятие битов значения с плавающей запятой и интерпретация их как целочисленного типа редко полезно, и значение не близко к тому, что представляет двойное число.

Я фактически пытался сделать обратное.Мне нужно было конвертировать long (на самом деле long long) в double.Тогда меня поразило, пусть NSNumber сделает конвертацию.Создайте временный объект NSNumber со значением, которое вы хотите, затем используйте метод, чтобы получить тип значения, которое вы хотите вернуть.

double vIn = 123.4321;
long vOut = [[NSNumber numberWithDouble:vIn] longValue];

Нет гарантий, что это будет делать то, что вы хотите.Я предполагаю, что если значение double больше, чем то, что может хранить long, оно просто вернет максимальное значение.

2 голосов
/ 14 октября 2011

Это неправильно, потому что двойное число представлено на 8 байтах, а длинное на 4 байта, поэтому двойное число слишком велико.

0 голосов
/ 24 октября 2014

Я использую это для хранения секунд, начиная с эпохи. Это требует преобразования, потому что timeIntervalSince1970 возвращает значение типа double. В моем случае переполнение может не произойти (по крайней мере, в ближайшем будущем), но вы можете добавить тест превышения LONG_MAX ...

NSDate * now = [NSDate date] ; NSNumber * seconds_since_epoch = [[NSNumber numberWithDouble:[now timeIntervalSince1970]] longValue];

0 голосов
/ 14 октября 2011

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

В результате диапазон значений намного большечем может обработать long.

Более подробная информация здесь:

http://en.wikipedia.org/wiki/Floating_point

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

Например, не может быть представлено максимальное 4-байтовое число с плавающей точкойв 8-байтовом целочисленном типе.

0 голосов
/ 14 октября 2011
double vIn = 0.0;
long vOut = (long)vIn;

Должен быть способ конвертации.

0 голосов
/ 14 октября 2011

LONG_MAX: 0x7FFFFFFFL или 2147483647.

т.е:.

2147483647

Это намного меньше, чем:

1318611498349.3559

Я удивлен, что компилятор не выдает ошибку преобразования / предупреждение какого-либо рода, потому что, независимо от того, что вы делаете, 64 фунта бит просто не помещаются в мешок весом 32 фунта.

...