Fórum Essa é difícil (números super grandes) #222246
25/03/2004
0
Neoramza
Curtir tópico
+ 0Posts
25/03/2004
Aroldo Zanela
Com inteiro não vai ser possível, veja:
TypeRangeFormat Shortint–128..127signed 8-bit Smallint–32768..32767signed 16-bit Longint–2147483648..2147483647signed 32-bit Int64–2^63..2^63–1signed 64-bit Byte0..255unsigned 8-bit Word0..65535unsigned 16-bit Longword0..4294967295unsigned 32-bit
Que tipo de trabalho precisa fazer exatamente?
Gostei + 0
26/03/2004
Neoramza
Eu presciso de números muito maiores. Númedos de 600 bits mais ou menos que em decimal daria uns 180 caracteres. Um doule (64bits) nao chega nem perto.
Tem que ser números tipo esse:
518454657624648932618215834416921409264096042961492164930919309268083218396759326516...
...0191293475610942375192651645149057612390561093456019465123645015613275601293456145...
...609679609182364501723619240561039456139913745698761951345178657
Gostei + 0
26/03/2004
Beppe
Gostei + 0
26/03/2004
Rodriguesap
Pois bem, o princípio que parti foi, do mesmo princípio que aprendemos nos primeiros anos de escola. Então montei as funções para fazer os cálculos como faziamos no papel.
Esta foi a única alternativa que consegui. Espero que ajude.
Gostei + 0
26/03/2004
Marco Salles
Eu Acredito Que Seje Por Aí...
Gostei + 0
26/03/2004
Cebikyn
type Hugeint: packed array [0..3] of LongWord;
Vê-se que, no caso do artigo, o número é composto por 3 partes. O artigo completo pode ser obtido nos link a baixo:
Inline Assembler in Delphi (VII) - 128-bit integer arithmetic
http://www.delphi3000.com/articles/article_3772.asp
ou a tradução p/ português:
http://www.latiumsoftware.com/br/pascal/0045.php5
Nunca vi nenhum exemplo com mais de 128bits, mas o artigo pode dar uma idéia do que pode ser feito e como pode ser feito.
Gostei + 0
27/03/2004
Neoramza
Se for possível me mostra esse códi go pois é exatamente o que eu estou procurando. Eu preciso somente das 4 operacoes basicas (adicao, subtracao, multiplicacao e divisao) e raiz quadrada.
Valeu galera.
Gostei + 0
27/03/2004
Anderson_blumenau
Gostei + 0
27/03/2004
Beppe
Na maioria, programas com fins científicos...
Gostei + 0
27/03/2004
Neoramza
http://www.rsasecurity.com/rsalabs/challenges/factoring/numbers.html
Gostei + 0
27/03/2004
Beppe
Todas as operações podem ser implementadas como no método papel-e-caneta, mas algumas exigem uma eficiência que só algoritmos melhor projetados podem resolver.
// Big Numbers by Beppe 27/03/2004 const DigitPrecision = 300; // deve ser ao menos 11 type BigNumber = array[1..DigitPrecision] of Byte; var Zero, One: BigNumber; function BigNumberToStr(const N: BigNumber): String; var I: Integer; begin I := Low(BigNumber); while (I <= High(BigNumber)) and (N[I] = 0) do Inc(I); SetString(Result, PChar(@N[I]), High(N) - I + 1); for I := 1 to Length(Result) do Inc(Result[I], Ord(´0´)); end; function BigNumberToInt(const N: BigNumber): Integer; begin Result := StrToInt(BigNumberToStr(N)); end; function NewBigNumber(Value: Integer): BigNumber; var I: Integer; begin FillChar(Result, Length(Result), 0); I := High(BigNumber); repeat Result[I] := Value mod 10; Dec(I); Value := Value div 10; until Value = 0; end; function Equals(const Left, Right: BigNumber): Boolean; begin Result := CompareMem(@Left, @Right, SizeOf(BigNumber)); end; function Add(const Left, Right: BigNumber): BigNumber; var I, Carry, Sum: Integer; begin Result := NewBigNumber(0); Carry := 0; for I := High(BigNumber) downto Low(BigNumber) do begin Sum := Left[I] + Right[I] + Carry; Carry := Sum div 10; Result[I] := Sum mod 10; end; end; function DivideByTwo(const N: BigNumber): BigNumber; var I, Carry, Quo: Integer; begin Result := NewBigNumber(0); Carry := 0; for I := Low(BigNumber) to High(BigNumber) do begin Quo := Carry * 10 + N[I]; Carry := Quo mod 2; Result[I] := Quo div 2; end; end; function IsOdd(const N: BigNumber): Boolean; begin Result := Odd(N[DigitPrecision]); end; function Multiply(const Left, Right: BigNumber): BigNumber; begin if Equals(Left, Zero) or Equals(Right, Zero) then Result := One else if Equals(Left, One) then Result := Right else if Equals(Right, One) then Result := Left else begin Result := Multiply(Left, DivideByTwo(Right)); Result := Add(Result, Result); if IsOdd(Right) then Result := Add(Result, Left); end; end; function GreaterThan(const Left, Right: BigNumber): Boolean; var I: Integer; begin Result := False; for I := High(BigNumber) downto Low(BigNumber) do begin if Left[I] < Right[I] then Exit else if Left[I] > Right[I] then begin Result := True; Exit; end; end; end; function Power(const Left: BigNumber; Right: Cardinal): BigNumber; begin case Right of 0: Result := One; 1: Result := Left; else Result := Power(Left, Right div 2); Result := Multiply(Result, Result); if Odd(Right) then Result := Multiply(Result, Left); end; end; function Mul(A, B: Cardinal): Cardinal; begin case B of 0: Result := 1; 1: Result := A; else Result := Mul(A, B div 2); Result := Result + Result; if Odd(B) then Result := Result + A; end; end; function Pow(A, B: Cardinal): Cardinal; begin case B of 0: Result := 1; 1: Result := A; else Result := Pow(A, B div 2); Result := Result * Result; if Odd(B) then Result := Result * A; end; end; procedure TForm1.Button1Click(Sender: TObject); var A, B: BigNumber; begin A := NewBigNumber(1220232); B := NewBigNumber(5012321); // cheque no calc.exe: 6116194478472 Edit1.Text := BigNumberToStr(Multiply(A, B)); // cheque no calc.exe: 2705278928837504201024262930432 Edit2.Text := BigNumberToStr(Power(A, 5)); end; initialization Zero := NewBigNumber(0); One := NewBigNumber(1);
a partir dessas pucas operações que escrevi, vc pode ir adiante. Subtração é ´straighforward´, divisão por números de um único dígito é simples, complica um pouco mais para outros só.
Eu usei divide-and-conquer para multiplicação e potência, pois tendem a ser mais eficientes. Para multiplicação existe um d-a-c melhor, mas é mais trabalhoso, e para números realmente grandes(milhares de casas), Fast Fourier Transform torna-se interessante.
Tem a questão de representação, também. Aqui usei array of Byte, onde cada byte fica de 0 a 9, de forma decimal. Mais eficiente seria trabalhar bináriamente, ie, array of Cardinal, usando complemento-de-2, para permitir números com sinais sem nenhum ajuste. Com representações decimais, o sinal precisa estar explícito, para facilidade no uso.
Gostei + 0
30/03/2004
Rodriguesap
Desculpa mas devido a Ética, não poderei mostrar o código que usei. Este código tem proprietário. Ele foi usado para criar um algorítmo de Criptografia. É algo que nem eu que conheço o algoritmo seria capaz de quebrar a criptografia. Caso alguém coloca-se um computador dedicado para testar todas as possibilidades, ele levaria séculos para testar todas as possibilidades, e pode ser um computador parrudo. Mas eu posso enviar uma mini calculadora, que fiz para testar os cálculos. Nos testes para multiplicar um número ao quadrado (x^2) com mais de um milhão de dígitos, levou alguns minutos. Se tiver interesse, poste uma mensagem pessoal aqui no fórum.
Gostei + 0
30/01/2006
Apontador
desenvolvi em pascal um tipo de dado que permite:
- entradas e saídas de números infinitos (desde que caibam na memória do pc);
- permite ponto (casas decimais infinitas (desde que caibam na memória do pc));
- permite sinal (positivo, negatido);
- permite cálculo de adição, subtração, multiplicação e divisão com esses números resultando em um número infinito.
veja se se interessa.
[color=red:1c0f63450e][/color:1c0f63450e][size=7:1c0f63450e][/size:1c0f63450e]
Gostei + 0
30/01/2006
Apontador
o código que desenvolvi nao trabalha em momento nenhum com inteiros, somente com ponteiros (apontadores), ou seja, um dígito é endereçado pelo pointer que o seu anterior (ou posterior, como queira) guardado na memória, fazendo com que o número seja ilimitado enquanto haja memória livre no pc...
favor retornar, pelo menos p/ dizer que nao está interessado.
Gostei + 0
31/01/2006
Thomaz_prg
Se puder mandar por email... thomazs@pop.com.br
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)