double
é de 64 bits. Isso gera problemas ao salvar e recuperar valores salvos na memória. Observe o exemplo:
#include <bits/stdc++.h> using namespace std; int main() { double br = 0; for (int i = 0; i < 2; i++) { double T, D; cin >> T >> D; double r = D/T; if (r > br) { cout << (i+1) << "\n"; cerr << "saved " << br << " " << (*reinterpret_cast<uint64_t*>(&br)) << "\n"; cerr << "now " << r << " " << (*reinterpret_cast<uint64_t*>(&r)) << "\n"; br = r; } } }Com a entrada:
44 80 22 40Se compilarmos com o flag
-m32
e -O
, obtemos a seguinte resposta:
1 saved 0 0 now 1.81818 4610867182131502359 2 saved 1.81818 4610867182131502359 now 1.81818 4610867182131502359Que é extremamente estranha. Se salvamos o valor
1.81818
na memória, ele não pode ser igual ao que calculamos! Isso é devido à otimização: r
é calculado usando a precisão de 80 bits, o que resulta em um valor um pouco diferente do br
já guardado. Se compilarmos sem o flag -m32
, mas com o flag -O
em uma máquina 64 bits, obtemos a resposta correta:
1 saved 0 0 now 1.81818 4610867182131502359Isto porque desta vez, usamos operações SSE que operam em 64 bits que estão ativadas por padrão quando compilamos em 64 bits.
Isso é importante lembrar porque o Codeforces e muitos judges usam máquinas 32 bits por padrão. Temos algumas opções para arrumar este erro: