C++ долго переполняется преждевременно
-
22-09-2019 - |
Вопрос
У меня возникла странная проблема с 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 бит.