Jump to content

Recommended Posts

Posted (edited)

Olá pessoal, bom dia!

Me ajudem para descobrir qual estrutura usar

Preciso fazer o seguinte; dados uma faixa de numeros reais, por exemplo, 2,5 a 10,2. Como faço para, dado tambem uma quantidade de numeros reais, cria-los nesta faixa?

Tentei assim:

 quantidade:=10;
 valor_ini:=2.5; (digitado pelo usuario);
 valor_fim:=10.2; (digitado pelo usuario);


 assign(arquivo, nome);  //atrelando variavel ao arquivo:
 rewrite(arquivo);  //criando o arquivo (que não existe):
 reset(arquivo);   // colocando o ponteiro no inicio do arquivo;

 for i:1 to quantidade do
begin
	write(arquivo,random(10));
end;
close(arquivo);

Mas não deu certo.

Edited by carcleo
Posted

carcleo,

Antes de te lançares a escrevê-los num ficheiro, porque não tentas primeiro mostrá-los no ecrã?

Ficaram algumas coisas por esclarecer: os números deverão ser gerados aleatoriamente? Ou deverão ser números sucessivos equidistantes no intervalo dado?

Posted (edited)

carcleo,

Então vou apenas dar a pista de que a função random (sem parâmetros) devolve um extended (número real) aleatório entre entre 0 e 1. Agora é só encontrar maneira de transformar um número entre 0 e 1 num número entre A e B (fornecidos pelo utilizador) e fazer isso N vezes (definido também pelo utilizador). É só matemática agora.

Importante: no início do programa deve ser chamada a Randomize.

Página de referência que poderás consultar: http://www.freepascal.org/docs-html/rtl/system/random.html

Edited by pwseo
Posted

Tentei fazer

 for i:=1 to quantidade do
begin
	   write(arquivo,random(trunc(valor_fim-valor_ini)).random());
end;

Mas não deu certo

Segue arquivo até aqui:

{
Suponha a declaração:
Type
 ArqFlutuante = File of real;
Faça um programa em Pascal que peça ao usuário:
O nome de um arquivo, a quantidade de números e a faixa (valor mínimo e valor máximo) de variação dos números aleatórios a serem gerados, e:
(1) Crie um arquivo do tipo ArqFlutuante com o nome, a quantidade lida e com os valores aleatórios na faixa escolhida.
(2) Mostre o arquivo gerado na tela;
(3) Ordene o arquivo, em ordem crescente (sem utilizar nenhuma outra variável estruturada);
(4) Mostre o arquivo após a ordenação;
(5) Calcule e mostre a média dos elementos no arquivo;
(6) Caso exista, escreva o terceiro maior elemento do arquivo. Caso contrário, escreva mensagem informando que ele não existe.
}
program Questao2;
uses
 crt, sysutils;
Type
 ArqFlutuante = File of real;
var
 arquivo: ArqFlutuante;
 quantidade, i: integer;
 valor_ini, valor_fim, linha: real;
 nome: string;
BEGIN
 randomize; // Optimiza random para que não haja repetição.
 // Pedindo dados ao usuario:
 writeLn('Atencao:');
 writeLn('Serao pedidos em sequencia: Um nome para criarmos um arquivo, uma quantidade de numeros para inserirmos nesse arquivo e a faixa (valor inicial, valor final) dos numeros a serem inseridos nesse arquivo.');
 writeLn;
 writeLn('Entao:');
 writeLn;
 writeLn('Digite um nome para o nosso arquivo:');
 read(nome);
 nome:= nome+'.tmp';
 writeLn('Digite agora uma quantidade de numeros para inserirmos nesse arquivo:');
 read(quantidade);
 writeLn('Digite agora a faixa (valor inicial e valor final) dos numeros a serem inseridos nesse arquivo.');
 writeLn('Exemplo: 1.34 e 9.59');
 readLn(valor_ini, valor_fim);
 writeLn;
 assign(arquivo, nome);  //atrelando variavel ao arquivo:
 rewrite(arquivo);  //criando o arquivo (que não existe):
 reset(arquivo);   // colocando o ponteiro no inicio do arquivo;
 for i:=1 to quantidade do
   begin
	  write(arquivo,random(trunc(valor_fim-valor_ini)).random());
   end;
 while not eof(arquivo) do
   begin
  read(arquivo, linha);
  writeLn(linha);
   end;
 close(arquivo);
 readkey;
END.
Posted (edited)

Tentei fazer

 for i:=1 to quantidade do
   begin
          write(arquivo,random(trunc(valor_fim-valor_ini)).random());
   end;

Mas não deu certo

Retirando os argumentos, tens isto:

random().random()

Isto não faz sentido.

O que o @pwseo te disse foi para fazeres um simples random, que te dará um número real entre 0 e 1, e transformá-lo no respectivo número que fique no intervalo [A, B]. Uma pista:

- Se random te der 0, então o valor calculado deverá dar A.

- Caso retorne 1, o valor calculado é B (o mesmo que A + (B - A)).

Edited by thoga31

Knowledge is free!

Posted
O que o @pwseo te disse foi para fazeres um simples random, que te dará um número real entre 0 e 1, e transformá-lo no respectivo número que fique no intervalo [A, B]. Uma pista:

- Se random te der 0, então o valor calculado deverá dar A.

- Caso retorne 1, o valor calculado é B (o mesmo que A + (B - A)).

Exactamente. Existe apenas uma pequena nuance: a função random devolve números no intervalo [0..1[.

Posted

Exactamente. Existe apenas uma pequena nuance: a função random devolve números no intervalo [0..1[.

Aqui pode-se introduzir uma pequena estratégia cuja taxa de viciação é desprezável:

r := random(1.0 + 1E-5);
if r >= 1.0 then numero := B;

Não sei até quão pequeno poderá ser o incremento adicional para poder funcionar devidamente, mas este nunca dará uma taxa de viciação não desprezável.

Knowledge is free!

Posted

Penso que não é necessário fazer isso. Aliás, tecnicamente nem podes, visto que a random só aceita parâmetros inteiros (e devolve inteiros).

Para obter números reais, deve ser chamada sem parâmetros.

De qualquer modo, mesmo que desse, não seria necessário. A própria random é capaz de gerar valores até 0.(99) (com um grau de precisão que desconheço), que certamente arredondarão para 1 nalgumas situações (depende da precisão que o carcleo quer), mesmo que o valor original não seja 1

Posted

Acho que ainda não compreendi.

fiz assim:

 contador:=0;
 valor:=0.0;
 for i:=1 to quantidade do
   begin
  while (valor>=valor_ini) and (valor<=valor_fim) do
    begin
	  if(contador mod 2=0) then valor:= valor_ini+random
	  else valor:= valor_fim-random;
	  inc(contador);
    end;
   write(arquivo, valor);
   end;
Posted

Penso que não é necessário fazer isso. Aliás, tecnicamente nem podes, visto que a random só aceita parâmetros inteiros (e devolve inteiros).

Para obter números reais, deve ser chamada sem parâmetros.

De qualquer modo, mesmo que desse, não seria necessário. A própria random é capaz de gerar valores até 0.(99) (com um grau de precisão que desconheço), que certamente arredondarão para 1 nalgumas situações (depende da precisão que o carcleo quer), mesmo que o valor original não seja 1

Pois, já não me lembrava, falha minha. Não trabalho com aleatoriedade em Pascal há uma temporada valente xD

Acho que ainda não compreendi.

fiz assim:

 contador:=0;
 valor:=0.0;
 for i:=1 to quantidade do
   begin
     while (valor>=valor_ini) and (valor<=valor_fim) do
       begin
         if(contador mod 2=0) then valor:= valor_ini+random
         else valor:= valor_fim-random;
         inc(contador);
       end;
      write(arquivo, valor);
   end;

Exactamente o que não compreendeste?

E não entendi por completo o objectivo desse trecho de código, explica.

Knowledge is free!

Posted (edited)

Pois na verdade, se o tipo fosse inteiro(mas não é), era só fazer um for entre os valores, inicial e finak pronto.

Porem, é real o tipo. Então, terão infinitos numeros entre um e outro,

Então, como se há de encontrar numeros reais entrre um e outro?

Pensei: for variando do menor ao maior e dentro do for eu faria tipo uma 'gambiarra' assim: pegasse um contador e, se ele for par, pego o valor_ini e soma o random e, se ele for impar, pego o maior e subtraio o random. Dessa forma, sempre ficará entre o menor ew o maior.

O que pensão vocês?

contador:=0; //inteiro
 valor:=0.0;  // real
 for i:=1 to quantidade do
begin
	  if(contador mod 2=0) then valor:= valor_ini+random
	  else valor:= valor_fim-random;
	  inc(contador);
	  write(arquivo, valor);
end;

Compila, grava, mas não tem como verificar o que esta gravado.

Acho que erro na hora de lista

 while not eof(arquivo) do
   begin
  read(arquivo, linha);
  writeLn(linha);
   end;
Edited by carcleo
Posted

É um método interessante, mas não sei até que ponto será o melhor.

O método que mantém a taxa de aleatoriedade na conversão de um valor do intervalo [0, 1[ para o intervalo [A, B[ é outro:

- Imagina que o random te dá 0,5 (simplificando). O teu intervalo final é, na realidade, [2, 10[. O teu 0,5 terá de ser convertido a 6.

Isto garante a repercussão da aleatoriedade do intervalo padrão para o intervalo final sem perdas.

Knowledge is free!

Posted (edited)

Mas, o probema agora, não sei porque, é que não sai nada na listagem do arquivo:

while not eof(arquivo) do
begin
read(arquivo, linha);
writeLn(linha);
end;

arquvo é file of real;

linha é real

Porque será/?

Edited by carcleo
Posted

Foi necessário (nao entendi porque), fechar o arquvo e abri-lo se novo.

Mas agora surge outra dificuldade, arredondar os valores gravador para 2 casas dedimais e eles estoa com um monte

contador:=0;
 valor:=0.0;
 for i:=1 to quantidade do
begin
	  if(contador mod 2=0) then valor:= round((valor_ini+random),2)
	  else valor:= round(valor_fim-random,2);
	  inc(contador);
	  write(arquivo, valor);
end;
 close(arquivo);
 reset(arquivo);
 while not eof(arquivo) do
begin
  read(arquivo, linha);
  writeLn(linha);
end;
 close(arquivo);

Saida

http://www.irajovemmuriae.com.br/aa.jpg

Posted (edited)

Foi necessário (nao entendi porque), fechar o arquvo e abri-lo se novo.

Quando abres o ficheiros defines um modo de o abordar: leitura (reset) ou escrita (rewrite). Para mudares de escrita para leitura tens de o fechar e depois reabri-lo. Não podes mudar o modo "dos pés para as mãos".

Mas agora surge outra dificuldade, arredondar os valores gravador para 2 casas dedimais e eles estoa com um monte

Este é o formato por defeito do Pascal para números reais. Quando fazes o output deles manda arredondar:

(* numero_real : espaco_minimo_a_ocupar : casas_decimais *)
writeln(numero:20:5);  // exemplo
Edited by thoga31

Knowledge is free!

Posted (edited)

carcleo,

A escrita de números formatados só existe quando estamos a falar da representação textual dos números. Como disseste acima, arquivo = file of real, o que significa que não estamos a falar de texto, e não podes escrever em arquivo texto nenhum.

No ficheiro, ficam armazenados os bytes que representam os números gerados. Já experimentaste abrir esse ficheiro? aposto que não parece nada do que aparece no programa.

Adenda: tudo isto tem a ver com a diferença entre um número e a sua representação textual.

Edited by pwseo

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.