У меня есть причудливая проблема с C++, где долгий тип данных переполняется задолго до того, как это должно. То, что я делаю (с успехом до сих пор) должно иметь целые числа, ведут себя как плавания, так, чтобы диапазон [-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
Так времена (98301,32767) походит 3.0*1.0. Этот код работает отлично, когда аргументы временам - меньше чем 32 767 (1.0), но ни один из промежуточных шагов с аргументами выше не должен переполнять 64 битов долго.
Какие-либо идеи?
long не обязательно 64 бита. попробуйте вместо этого «долго долго».
Стандарт C гарантирует только то, что long
будет как минимум 32-битным (что, собственно, и происходит на большинстве 32-битных платформ).
Если вам нужно 64 бита, используйте long long
. Он гарантированно будет содержать по крайней мере 64 бита.
Вероятно, у вас 32-битные длинные числа. Попробуйте вместо этого использовать long long
.
98301 * 32767 = 3221028867, в то время как 32-битное длинное переполнение на 2147483648
Тип long
не обязательно 64-битный. Если вы используете 32-битную архитектуру (по крайней мере, в MS Visual c ++), тип long
будет 32-битным. Проверьте это с помощью sizeof (long)
. Также может помочь тип данных long long
.