#c #sigfpe
#c #sigfpe
Вопрос:
У меня есть следующий фрагмент кода c :
void update(const int step, const int total) const
{
double s = static_cast<double>(step);
double t = static_cast<double>(total);
std::cout << s/t <<"------n";
// etc...
}
Я использую компилятор Intel c с активированным флагом -fp-trap=all . При запуске кода через gdb я получаю следующую ошибку:
Program received signal SIGFPE, Arithmetic exception.
0x000000000040ee07 in NilDa::progressBar::update (this=0x7fffffffbc9c, step=1, total=60000) at /home/d2d/dev/NilDa/sources/utils/progressBar.h:69
69 std::cout << s/t <<"------n";
Я действительно не понимаю, что происходит. Разделение кажется четко определенным.
Комментарии:
1. входные данные: step = 1, total = 60000 (как сообщает gdb), поэтому s = 1.0, t = 60000.0
2. Кроме того, мы понятия не имеем, когда и где вызывается этот код. Как насчет простой
main
программы, которая просто делит 1.0 на 60000.0, чтобы посмотреть, есть ли что-то не так в этом простом случае.3. @cigien Значения видны в выводе gdb 😉 Данте: Какой компилятор вы используете?
4. PS Если вы используете компилятор Intel C , быстрый поиск здесь решит ваш вопрос (
Enables or disables the IEEE trap for invalid operation.
): software.intel.com/content/www/us/en/develop/documentation /…
Ответ №1:
Я предполагаю, что вы используете компилятор Intel C (я не знаю ни одного другого компилятора, имеющего такой флаг). Если это так, вы можете посмотреть здесь: https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/compiler-options/compiler-option-details/floating-point-options/fp-trap-qfp-trap.html#
Как указано в этой документации, аргумент all
наследует ловушку для неточных результатов ( [no]inexact
)
Включает или отключает ловушку IEEE для неточного результата.
Поскольку 1/60000 не может быть представлено числом с плавающей запятой, результат является неточным (1.66667e-05).
Комментарии:
1. @WolvernDEV Как указано в вопросе, я использую компилятор Intel c . Я понимаю точку зрения о приближении 1/6000, но верно ли это и для double? Я использую не число с плавающей запятой, а значение double .
2. Ну, независимо от двойного числа с плавающей точкой или чего-то еще, 1/60000 является периодическим результатом (1/6 * 1e-5). 1/6 не может быть представлено в виде числа с плавающей запятой или числа с фиксированной запятой 😉