Pergunta

long long int A = 3289168178315264;
long long int B = 1470960727228416;
double D = sqrt(5);

long long int out = A + B*D;

printf("%lld",out);

Isto dá resultado: -2147483648

Eu não sou capaz de descobrir por que (ele deve ser um resultado positivo). Alguém pode ajudar?

Foi útil?

Solução

Meu palpite é que as necessidades do compilador para arredondar o resultado de "A + B * D" para um número inteiro em primeiro lugar, porque você está armazenando o resultado dentro de um campo int. Então, basicamente, você está tendo um conflito de tipo de dados.

Ambos A e B ainda são números válidos para um int long long, que é de 8 bytes. Você poderia até multiplicá-los por 1.000 e ainda ter valores long long int válidos. Em algumas outras línguas também é conhecido como o int64.

Um duplo, no entanto, é também de 64-bits, mas parte daqueles são utilizados como expoente. Quando você multiplicar um casal com uma int64, o resultado seria outro duplo. Adicionando outra int64 a ele ainda mantém um duplo. Então você está atribuindo o resultado a um int64 novamente sem o uso de um método específico de arredondamento. Não me surpreenderia se o compilador iria usar uma função de arredondamento de 4 bits para isso. Estou ainda espantado que o compilador não vomitar e quebrar nessa declaração!

De qualquer forma, quando se utiliza grandes números como estes, você tem que ser extremamente cuidadoso ao misturar tipos diferentes.

Outras dicas

talvez você tem que especificar essas constantes como literais "long long"? por exemplo. 3289168178315264LL

O compilador / sistema operacional você está usando? Corri seu código usando o Visual C ++ 2008 Express Edition no Windows XP e FUNCIONA - resposta:. 6578336356630528 (este é um número 53-bit, por isso só se encaixa dentro de um double)

Eu também tentei duas variações para ver se a ordem das operações importava:

long long int out = A; a = + B * D;

longa longo int fora = B * D; out + = A;

Estes dois trabalhos bem!

Curious.

A sua resposta (tem que verificar) calcuates com sucesso, no entanto, faz com que um estouro no bit de sinal, o que torna o negativo resposta. Solução:. Fazer todas as suas variáveis ??não assinados

Por:

Os números são armazenados como uma série de bits em você memória do computador. O primeiro bit em séries um, quando definido significa que você número é negativo. Assim, os trabalhos de cálculo, mas transborda para o bit de sinal.

Recomendação:

Se você está trabalhando com números tão grande, eu recomendo que você obtenha uma biblioteca aritmética multiprecision. 'T você vai economizar um monte de tempo e problemas.

O parâmetro para sqrt deve ser duplo .

#include <math.h>
double sqrt( double num );

E também devemos explict converter o resultado de B * D ao longo de comprimento.

    long long int A = 3289168178315264;
    long long int B = 1470960727228416;
    double D = sqrt(5.0);
    printf("%f\n",D);
    long long int out = A + (long long) (B * D);
    printf("%lld",out);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top