Предупреждение о потере данных c ++/c

Я получаю мягкое предупреждение о возможной потере данных

предупреждение C4244: 'аргумент': преобразование из 'интервала константы' для 'плавания', возможная потеря данных

Вопрос

Я помню, как будто плавание имеет большую точность, чем интервал. Таким образом, как данные могут быть потеряны, если я преобразовываю из меньшего типа данных (интервал) к большему типу данных (плавание)?

9
задан Veger 17 April 2010 в 14:53
поделиться

6 ответов

Потому что числа с плавающей запятой неточны. Вы не можете представить каждое возможное значение, которое int может содержать в float , даже если максимальное значение float намного выше.

Например, запустите эту простую программу:

#include <stdio.h>

int main()
{
 for(int i = 0; i < 2147483647; i++)
 {
  float value = i;
  int ivalue = value;
  if(i != ivalue)
   printf("Integer %d is represented as %d in a float\n", i, ivalue);
 }
}

Вы быстро увидите, что существуют тысяч миллиардов целых чисел, которые нельзя представить как float s. Например, все целые числа в диапазоне от 16 777 219 до 16 777 221 представлены как 16 777 220.

ИЗМЕНИТЬ снова Выполнение указанной выше программы указывает на то, что существуют 2,071,986,175 положительных целых чисел, которые не могут быть представлены точно как float s. В результате у вас остается примерно 100 миллионов положительных целых чисел, которые правильно помещаются в float . Это означает, что только одно целое число из 21 является правильным, когда вы помещаете его в число с плавающей запятой.

Я ожидаю, что числа будут одинаковыми для отрицательных целых чисел.

14
ответ дан 4 December 2019 в 08:51
поделиться

На большинстве архитектур int и float имеют одинаковый размер, поскольку они имеют одинаковое количество бит . Однако в float эти биты разделены между экспонентой и мантиссой, что означает, что на самом деле у float меньше битов точности, чем у int. Однако это может быть проблемой только для больших целых чисел.

В системах, где int составляет 32 бита, double обычно 64 бита и поэтому может точно представлять любое int.

6
ответ дан 4 December 2019 в 08:51
поделиться

Мой стандартный ответ на такие вопросы - прочитать это - Что каждый компьютерный ученый Должен знать об арифметике с плавающей точкой .

0
ответ дан 4 December 2019 в 08:51
поделиться

Точность не имеет значения. Точность int равна 1, а точность типичного числа с плавающей запятой (одинарная точность IEEE 754) составляет приблизительно 5,96e-8. Важен набор чисел, которые могут представлять два формата. Если есть числа, которые int может представлять именно то, что float не может, то возможна потеря данных.

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

32-битное int фактически имеет 31 бит, кодирующий абсолютное значение числа. Фактически, число с плавающей запятой IEEE 754 имеет только 24 бита, кодирующих мантиссу (один неявный).

1
ответ дан 4 December 2019 в 08:51
поделиться

float обычно используется в стандарте IEEE single- формат точности. Это означает, что в float всего 24 бита точности, тогда как int , скорее всего, будет 32-битным. Итак, если ваш int содержит число, абсолютное значение которого не может поместиться в 24 бита, вы, вероятно, округлите его до ближайшего представимого числа.

0
ответ дан 4 December 2019 в 08:51
поделиться

Оба типа состоят из 4 байтов (32 бита). Только один из них допускает дробь (число с плавающей запятой).

Возьмем это для примера с плавающей точкой;

34.156

(целое число). (Дробь)

Теперь используйте свою логику; Если один из них должен сохранить информацию о дробях (в конце концов, он должен представляют собой число), то это означает, что у него меньше бит для целой части.

Таким образом, число с плавающей запятой может представлять максимальное целое число, которое меньше, чем возможность типа int.

Чтобы быть более конкретным, «int» использует 32 бита для представления целого числа (максимальное целое число без знака 4 294 967 296). Для этого «float» использует 23 бита (максимальное целое число без знака 8 388 608).

Вот почему при преобразовании из int в float вы можете потерять данные.

Пример: int = 1,158,354,125

Вы не можете сохранить это число в виде «числа с плавающей запятой».

Дополнительная информация:

http://en.wikipedia.org/wiki/Single_precision_floating-point_format

http://en.wikipedia.org/wiki/Integer_%28computer_science%29

3
ответ дан 4 December 2019 в 08:51
поделиться