UInt64 fica duvidoso ao fazer grandes contas?
Pergunta
Tenho um resultado estranho vindo de uma grande matemática e não tenho ideia de por que estou recebendo uma resposta diferente de vb.net vs python.
Aqui estão os trechos rápidos e resultados:
VB.NET
Dim MSB As UInt32 = 3067297518
Dim LSB As UInt32 = 1439785590
Dim sqln As UInt64 = MSB * (2 ^ 32) + LSB
Python:
sqln = msb * (2 ** 32) + lsb
Python Result: 13173942528351756918
VB RESULT: 13173942528351756288
Observação:Eu também tento declarar o SQLN como um Ulong e uma dupla (mesma resposta) que o MSB e o LSB são uma correspondência nos dois depuradores - !!??
Alguma ideia?=+ Meus agradecimentos
Excelente Jon - muito eloqüente e funciona!Com um pequeno acompanhamento, você poderia sugerir uma correção para a peça final?Acredito que o mesmo tipo de coisa esteja acontecendo, embora você tenha corrigido meu sqln :)
python says: = bdntyxtax2smq
vb.net says: = bfpuzytbx3s00
VB.NET
Dim sqlid As String = ""
Dim alphabet As String = "0123456789abcdfghjkmnpqrstuvwxyz"
For iCount = 0 To 12
sqlid = alphabet((sqln / (32 ^ iCount)) Mod 32) + sqlid
Next
Python:
for i in range(0, 13):
sqlid = alphabet[(sqln / (32 ** i)) % 32] + sqlid
Solução
Descompilei seu código VB como C# e ficou assim:
uint MSB = 0xb6d33eee;
uint LSB = 0x55d16276;
ulong sqln = (ulong) Math.Round((double) ((num2 * 4294967296) + num));
Isso ocorre porque o operador de energia em VB sempre retorna um Double
:
O resultado é um número elevado à potência do expoente, sempre como um valor Double.
Eu sugeriria usar o operador shift e fazer com que todas as suas variáveis UInt64
, para que a mudança seja feita para um número inteiro de 64 bits:
Dim MSB As UInt64 = 3067297518
Dim LSB As UInt64 = 1439785590
Dim sqln As UInt64 = (MSB << 32) + LSB
Isso dá a resposta certa.(Você realmente não precisa LSB
ser um UInt64
, mas você também pode fazer tudo com números inteiros de 64 bits.)