Я столкнулся с очень странным фактом об округлении float
и преобразовании в int
.math.h default rounding mode not clear
Как указано здесь: http://www.gnu.org/software/libc/manual/html_node/Rounding.html
Округление до ближайшего представимому значения по умолчанию режим округления. Но, похоже, это не так.
Так что я создал эту простую программу:
#include <fenv.h>
#include <stdio.h>
int a;
double b;
main() {
b=1.3; a=b; printf("%f %d\n",b,a);
b=1.8; a=b; printf("%f %d\n",b,a);
b=-1.3; a=b; printf("%f %d\n",b,a);
b=-1.8; a=b; printf("%f %d\n",b,a);
printf("%d %d %d\n",fegetround(),FE_TONEAREST,FE_TOWARDZERO);
}
Программа была составлена с GCC-4.7 (Debian), Cygwin GCC и Visual Studio. Результат был таким же, изменилось только определение FE_TOWARDZERO
.
Выход программы:
1.300000 1
1.800000 1
-1.300000 -1
-1.800000 -1
0 0 3072
Таким образом, мы можем ясно видеть, что режим округления устанавливается на FE_TONEAREST
(по умолчанию) во всех протестированных компиляторов, но все они округление к нулю.
Почему?
PS: Да, я могу использовать Math.round()
, но мне интересно, почему это происходит.
Я не понимаю. Я могу использовать Math.round(), ceil() или floor(), когда хочу округлить с плавающей запятой. Или я вижу это неправильно? – Mihalko
@Mihalko Вы не понимаете, что 'int a = (int) aFloat;' и 'int a = round (aFloat);' не совпадают. –
, но режим округления в сопроцессоре FP используется при литье float в int. В любом случае, я нашел ответ здесь: http://software.intel.com/en-us/articles/fast-floating-point-to-integer-conversions в главе «Более внимательный взгляд на конверсии Float-to-Int « – Mihalko