Я работаю над процедурой оптимизации функций (вариант алгоритма Нелдера-Мида), которая не может сходиться в очень специфических условиях.
Я определил, что переменная float
, давайте назовемему a
присваивается среднее значение между a
и другой переменной b
, которая отличается от нее только битом.
Точнее, значения каждой переменной следующие:
float a = 25.9735966f; // 41CFC9ED
float b = 25.9735947f; // 41CFC9EC
И теперь я пытаюсь присвоить a
среднее значение от a
до b
:
a = 0.5 * (a+b);
Когда я пишу этот код в тестовой программе, я получаюрезультат, который я хочу, а именно 25.9735947
.Но в отладчике моего исходного библиотечного кода я вижу, что значение остается 25.9735966
.Я почти уверен, что у меня одинаковые флаги компилятора в обеих программах. Есть ли какая-то причина, по которой это вычисление с одинарной точностью даст разные результаты?
ОБНОВЛЕНИЕ
Как и запрашивал @PascalCuoq, вот что я думаюэто сборка для рассматриваемой линии.Строка делает еще несколько вещей, и я не уверен, где происходит умножение.
.loc 1 53 0 discriminator 2
movl -60(%rbp), %eax
cltq
salq $3, %rax
addq -88(%rbp), %rax
movq (%rax), %rax
movl -44(%rbp), %edx
movslq %edx, %rdx
salq $2, %rdx
leaq (%rax,%rdx), %rcx
movl -44(%rbp), %eax
cltq
salq $2, %rax
addq -72(%rbp), %rax
movl -60(%rbp), %edx
movslq %edx, %rdx
salq $3, %rdx
addq -88(%rbp), %rdx
movq (%rdx), %rdx
movl -44(%rbp), %esi
movslq %esi, %rsi
salq $2, %rsi
addq %rsi, %rdx
movss (%rdx), %xmm1
movl -52(%rbp), %edx
movslq %edx, %rdx
salq $3, %rdx
addq -88(%rbp), %rdx
movq (%rdx), %rdx
movl -44(%rbp), %esi
movslq %esi, %rsi
salq $2, %rsi
addq %rsi, %rdx
movss (%rdx), %xmm0
addss %xmm1, %xmm0
movss .LC6(%rip), %xmm1
mulss %xmm1, %xmm0
movss %xmm0, (%rax)
movl (%rax), %eax
movl %eax, (%rcx)
УТОЧНЕНИЕ
Мой код - ripoff вариант кода Нелдера-Мида из Числовых Рецептов.Вот эта строка:
p[i][j]=psum[j]=0.5*(p[i][j]+p[ilo][j]);
В этой строке p[i][j] == 25.9735966f
и p[ilo][j] == 25.9735947f
.Результирующее значение в p[i][j]
равно 25.9735966f
.