Вопрос

У меня возникла странная проблема с C++, когда тип данных long переполняется задолго до того, как это должно произойти.Что я делаю (пока успешно), так это заставляю целые числа вести себя как числа с плавающей запятой, чтобы диапазон [-32767,32767] сопоставлялся с [-1.0,1.0].Где он спотыкается, так это с более крупными аргументами, представляющими числа с плавающей точкой больше 1,0:

inline long times(long a, long b) {
  printf("a=%ld b=%ld ",a,b);
  a *= b;
  printf("a*b=%ld ",a);
  a /= 32767l;
  printf("a*b/32767=%ld\n",a);
  return a;
}

int main(void) {
  printf("%ld\n",times(98301l,32767l));
}

В качестве вывода я получаю:

a=98301 b=32767 a*b=-1073938429 a*b/32767=-32775
-32775

Таким образом, times(98301,32767) аналогично 3,0*1,0.Этот код отлично работает, когда аргументы times меньше 32767 (1.0), но ни один из промежуточных шагов с приведенными выше аргументами не должен переполнять 64 бита long.

Есть идеи?

Это было полезно?

Решение

длина не обязательно равна 64 битам.вместо этого попробуйте «длинный-длинный».

Другие советы

Тип long не обязательно 64 бита.Если вы используете 32-битную архитектуру (по крайней мере, MS Visual C++), long тип 32 бита.Проверьте это с sizeof (long).Существует также long long тип данных, который может помочь.

Вероятно, у вас 32-битные длинные значения.Попробуйте использовать long long вместо.

98301 * 32767 = 3221028867, а 32-битное длинное переполняется по адресу 2147483648.

Стандарт C гарантирует только то, что long будет иметь как минимум 32-битную версию (что на самом деле имеет место на большинстве 32-битных платформ).

Если вам нужна 64-битная версия, используйте long long.Он гарантированно поддерживает не менее 64 бит.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top