Это происходит потому, что вы компилируете в 32-битном режиме, он использует процессор с плавающей запятой x86. Оптимизатор кода удаляет избыточные перемещения из регистров FPU в память и обратно, оставляя промежуточные результаты в стеке FPU. Довольно важная оптимизация.
Проблема в том, что FPU сохраняет удвоения с точностью до 80 бит. Вместо 64 битов точность удваивается. Изначально Intel предположила, что это была особенность, производящая более точные промежуточные вычисления, но это действительно ошибка. Они не совершили ту же ошибку, когда разработали набор инструкций SSE2, используемый 64-битными компиляторами для математики с плавающей запятой. Регистры XMM имеют 64 бита.
Таким образом, в режиме релиза вы получаете несколько иные результаты, поскольку вычисления выполняются с большим количеством битов. Это не должно никогда быть проблемой в программе, которая использует для вычисления значения с плавающей запятой, двойной может хранить только 15 значащих цифр. Отличительными являются цифры шума, которые выходят за первые 15 цифр. Но иногда меньше, если ваш расчет сильно теряет значащие цифры. Как и при расчете 1 - 3 * (1 / 3,0).
Но да, вы можете использовать fp: precision для получения согласованных цифр шума. Это заставляет промежуточные значения записываться в память, чтобы они не могли оставаться в FPU с точностью 80 битов. Это делает ваш код медленным, конечно.