Ответ 1
Потому что с "-O3" компилятор предварительно вычисляет sin(2*pi)
во время компиляции с одним алгоритмом. Без "-O3" это вычисляется во время выполнения с другим алгоритмом.
Это может быть связано с тем, что сам компилятор был построен с некоторой математической библиотекой, которая отличается от вашей математической библиотеки.
Обновление
Единственный объект, дающий результат "-0.00000000000000024492127076447545" - это 32-разрядная версия libstdС++. 64-битная версия той же библиотеки, а также gcc сама производит "-0.00000000000000024492935982947064".
Поэтому обновление до более новой версии не поможет. Кроме того, я пробовал различные варианты, предлагаемые здесь: ни -ffloat-store, ни -fno-builtin не имеют никакого значения, а также длинный double и sinl.
32-разрядный libstdС++ использует 387 инструкций с плавающей запятой, а gcc явно использует инструкции SSE. Вот в чем разница. Вероятно, единственный способ сделать их последовательными - перестроить gcc из источников, направляя его на использование только 387 инструкций внутри.