Ir para conteúdo
Fórum Script Brasil
  • 0

Arredondamento de float no printf


cjacchus

Pergunta

Olá a todos.

Sou novo no fórum, e indo direto ao ponto, vim em busca de ajuda...

Em um trabalho da linguagem c, tenho a seguinte struct

typedef struct {
   int RA; /* RA do aluno (ex: 101234) */
   char nome[MAX_NOME_ALUNO + 1]; /* nome do aluno (ex: "Marcio Roberto Barreto")*/
   int codCurso; /* codigo do curso no qual o aluno esta matriculado (ex: 11) */
   int anoIngresso; /* ano em que o aluno ingressou na universidade, naquele curso (ex: 2010) */
   float CR; /* coeficiente de rendimento do aluno (ex: 0.7812) */
   float CP; /* coeficiente de progressao do aluno (ex: 0.2091) */
} Aluno;

em um determinado momento, meu campo RA tem valor 0.616250. Eu desejo imprimi-lo com 5 dígitos, sendo 4 casas decimais, portanto, pensei em utilizar

%5.4f

Porém, ao invés de 0.6163, meu programa apresenta o resultado 0.6162 (0.6163 é o resultado que me foi informado como certo pelo professor, e pela minha lógica).

Tentei, ao invés de %5.4f, utilizar %.4f, o que não alterou em nada meu resultado.

Alguém sabe como me ajudar?

Muito obrigado,

Francisco

Link para o comentário
Compartilhar em outros sites

5 respostass a esta questão

Posts Recomendados

  • 0

O resultado não está de acordo com o que o seu professor quer. Mas ele não pode dizer que está errado. O arredondamento foi feito de acordo com um método. Provavelmente é o "arredondamento do banqueiro", que é utilizado em vários compiladores populares (delphi, c++ builder, etc). Aliás, ele deveria ter um mínimo de tolerância a respeito. Afinal de contas, você não está fazendo software para controle de flaps de um avião comercial. Um errinho desses não vai matar ninguém. :)

No método mais conhecido das pessoas, que normalmente aprendemos nos tempos do colégio (ensino básico), o valor seria arredondado para cima. Hoje é até intuitivo para nós. Mas no método do banqueiro, o valor será arredondado para cima quando o valor do dígito vizinho à esquerda for par e para baixo quando for ímpar. Esse método existe como forma de levar justiça aos arredondamentos, pois no método tradicional, alguém sempre ganha e alguém sempre perde de forma constante em todos os valores que terminam em 5. No método do banqueiro isso não ocorre. Explique isso ao seu professor. Aliás, ele deveria saber.

Mas saiba que existe também a norma ABNT NBR 5891, de 12/77, que traz outro método, mais vinculado e (talvez) utilizado em documentos fiscais. Não é o caso, já que o compilador que você utiliza é estrangeiro. Mas deixo a informação como curiosidade. Um dia pode ser útil.

Não sei dizer se será possível mudar o comportamento do compilador quando do arredondamento. Você terá de verificar a documentação dele. Pelo que sei, não é possível mudar o arredondamento pelo printf(). Pesquisando no Google, talvez você encontre algo a respeito.

Link para o comentário
Compartilhar em outros sites

  • 0

Meu pensamento lógico me leva a não acreditar que o truncamento seja o comportamento padrão em qualquer linguagem; C ou C++, mesmo em funções simples, como printf(). Explico: C e C++ são linguagens largamente utilizadas em softwares científicos, e o truncamento poderia causar sérias discrepâncias, a ponto de comprometer os resultados. Por isso, deve haver um método mais aprimorado.

Nas normas das linguagens C++ (ANSI ISO-IEC 14882/98) e C (ANSI ISO-IEC 98/99) não constam que o procedimento padrão a ser tomado seja o truncamento puro e simples. Pelo contrário. Há uma série de switches que orientam o arredondamento. Normalmente há um header no compilador ("limits.h"), onde são encontrados os símbolos que definem isso.

No Delphi (e por conseqüência, C++ Builder) eu sei que é utilizado como padrão o método do banqueiro. Palavras de Nick Hodges, Delphi Development Manager da Embarcadero, quando questionado a respeito num fórum público: "Delphi rounds using "Bankers Rounding"".

O truncamento até pode ser uma característica da função printf() de C (e funções congêneres), mas vai da implementação do compilador. Padrão não é Lei; é apenas uma orientação. Mas veja que em outras funções pode até não ser usado o truncamento. Infelizmente, a notação em ponto flutuante (padrão IEEE754) é muito complicada de lidar. Acho que só por isso já não se pode usar o truncamento como padrão.

Link para o comentário
Compartilhar em outros sites

  • 0

Bem, o problema foi "resolvido".

Alterei a ordem em que as notas eram lidas (O CR era calculado a partir das notas) e magicamente o numero mudou de 0.6162 para 0.6163.

Porém, fiquei com essa questão na cabeça: O padrão do printf() não é o truncamento, podemos testar isso facilmente imprimindo o pi com uma restrição no número de casas decimais.

O que será que aconteceu, e como eu poderia ersolver? Maligno, você sugeriria ler sobre o header limits.h?

Link para o comentário
Compartilhar em outros sites

  • 0

É como dizem: "a ordem dos tratores não altera o viaduto". :)))

Mas trocando os valores de lugar você obteve um resultado diferente. Ponto flutuante é isso aí. Nem zero é zero de verdade. A simples comparação de valores float após um cálculo é uma coisa bizarra. Como saber se o resultado é zero? É necessário verificar se o número é tão pequeno que possa ser considerado zero.

Respondendo à sua pergunta: seu compilador C (você não disse qual é) provavelmente deve permitir alterar o método do arredondamento. No C++ Builder eu tenho a função SetRoundMode(). No seu compilador, imagino, deve ter algo do tipo. Ler o "limits.h" não vai ajudar, infelizmente. Como não trabalho com C, não posso ajudar muito. Mas seu professor deveria ser capaz de indicar o caminho pra resolver essa questão.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...