Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

JSA

Erro ao comparar números float na condição do if

Recommended Posts

Olá a todos.

Observem o seguinte código extremamente simples:

 

#include <stdio.h>

 

int main()

{

float n1 = 9.8;

 

if (n1 == 9.8)

{

printf("ok!\n\n");

}

 

printf("Fim do programa...!\n");

scanf("%*c");

return 0;

}

 

Esse código não gera a frase ok! porque o compilador não enxerga n1 igual 9.8 apesar de, visualmente, a condição ser verdadeira devido a comparação entre números reais idênticos.

Porém, quando eu insiro cast antes do 9.8 na condição do if o código funciona corretamente: if (n1 == (float) 9.8)

Esse problema só existe quando eu uso números reais do tipo float diferentes de 9.0 e 9.5, ou seja, escrevendo dessa forma if (n1 == 9.0) ou desta outra forma if (n1 == 9.5), sem cast, o código funciona perfeitamente.

Para números dos tipos int e double esse problema de comparação na condição do if não ocorre.

Estou usando o codeblocks, com compilador GCC, no windows 7, processador i3, 64bits.

 

Alguém com mais anos de prática na Linguagem C poderia esclarecer por qual razão o tipo floatnecessita de casting na condição do if?

Compartilhar este post


Link para o post
Compartilhar em outros sites
#include <stdio.h>


int main()

{

float n1 = 9.8;


if ( n1 == 9.8f) //Colocando "f" desta forma você declara ao if que sua variável é um float, caso contrário o if reconhece o seu "9.8" como double.

{

printf("ok!\n\n");

}


printf("Fim do programa...!\n");

scanf("%*c");

return 0;

}

Compartilhar este post


Link para o post
Compartilhar em outros sites
Então @x8mhz , agradeço por participar do tópico.
Realmente a solução é está. Eu já tinha enxergado isto ao usar o cast antes do número (float) 9.8.
E sim, a especificação de tipo do literal numérico (inserir o f após o numero real) também é uma forma de definir um tipo para o número. Legal que você tenha visto isso também.
A minha maior curiosidade era saber PORQUE só o tipo float necessita de casting (ou definição literal do tipo do dado) dentro do if .
Depois de passar algum tempo estudando, focado em encontrar uma justificativa eis que a solução foi observada.
O if nesta situação, não tem nada a ver com essa questão do float, a não ser possibilitar a sintaxe para a comparação.

O problema está na declaração de constantes dentro do programa. Isso mesmo, constantes.

Sempre que colocamos um número PONTO FLUTUANTE dentro do código que NÃO tenha sido atrelado a um tipo, o COMPILADOR passa a tratar este número (por padrão) como sendo uma constante do tipo DOUBLE!
Por isso que a condição do if é falsa sempre que estiver desta forma:

 float n1 = 9.8;
 
 if ( n1 == 9.8 )
 {
      //instruções
 }

A variável n1, por declaração, é do tipo float e a constante 9.8 está sendo visto pelo compilador como sendo uma constante double. Para o compilador, um número ponto flutuante com precisão estabelecida pelo tipo float é diferente de um número ponto flutuante com precisão estabelecida pelo tipo double. Ambos possuem precisões distintas.
Ao colocar o cast ou a especificação literal de tipo, ambos os números 9.8 passam a possuir a mesma precisão, imposta pelo tipo float. Consequentemente, a condição do if após a alteração passa a ser verdadeira. :D






Compartilhar este post


Link para o post
Compartilhar em outros sites

 


Para o compilador, um número real float é diferente de um número real do tipo double.
Ao colocar o cast ou a definição literal de tipo igualamos os tipos numéricos e a condição do if passa a ser verdadeira pois ambos os números serão do tipo float e possuem o valor 9.8.



Não é bem assim.
Por padrão, constantes numéricas de ponto flutuante são double.Veja: por padrão -> isso está no ISO C.
Mas o que acontece no if é que a representação de 9.8 possui precisão menor no float que no double.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não é bem assim.

Por padrão, constantes numéricas de ponto flutuante são double.Veja: por padrão -> isso está no ISO C.

Mas o que acontece no if é que a representação de 9.8 possui precisão menor no float que no double.

 

_Isis_ o que você disse é exatamente o que eu falei no poste anterior. Não vejo diferença!

 

Quando eu falo por padrão, estou querendo dizer, levando em consideração as regras oficiais da linguagem, como é o caso das documentadas na ISO C.

 

Como eu falei, por padrão, literais não tipados são considerados constantes para o compilador, por exemplo, o 9.8 que se encontra na condição if.

Quando um literal não tipado é um número ponto flutuante, por padrão o compilador (certamente baseando-se em regras documentadas no ISO C) encara a constante como double.

 

Se o compilador trata 9.8 como double e inicialmente a comparação foi em relação a um 9.8 float (da variável n1), sem dúvida a comparação estava dando falso porque existia uma comparação entre números de tipos distintos, logo com precisões distintas. :)

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

 

Para o compilador, um número ponto flutuante float é diferente de um número ponto flutuante do tipo double.

(...)
Ao colocar o cast ou a especificação literal de tipo igualamos os tipos numéricos (...)

Isso pra mim quer dizer que você está comparando apenas o tipo da variável, não o conteúdo da mesma.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isso pra mim quer dizer que você está comparando apenas o tipo da variável, não o conteúdo da mesma.

Foi questão de semântica.

Não existe comparação direta entre um tipo e outro na linguagem C, por exemplo, if (float == double).

Certamente comparamos o conteúdo que é moldado pelo o tipo da variável que armazena tal conteúdo.

 

Porém, sua observação foi interessante.

Escrevi de outra forma o texto para enfatizar mais ainda a questão da comparação entre os conteúdos numéricos envolvidos e suas respectivas precisões.

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

O C11 passa a permitir esse tipo de coisa:
http://stackoverflow.com/questions/6280055/how-do-i-check-if-a-variable-is-of-a-certain-type-compare-two-types-in-c

A utilidade disso é que fica no ar (ex: programadores Python dizem que se vc está verificando tipo de alguma coisa, então está fazendo tudo errado)

Fora da mão do programador, internamente, há a comparação dos tipos de variáveis p/ fazer as conversões aritméticas e lembro vagamente das "restrições" do if (numa das seções do padrão ISO) listar que os dois operandos devem ser numéricos (entre outras coisas). Mas isso já serve p/ implementação de compiladores.

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por Wilherme
      Boa tarde galera, preciso de uma ajuda,
       
      Tenho um gráfico no meu Power Bi porem apresenta o erro abaixo:
       

       
      já habilitei as funções porém ainda com erro.
       
       
      Obrigado.
    • Por 4Unknow
      Bom dia comunidade Imasters.

      Venho aqui tratar de um problema dúvida que estou tendo com um layout que estou tentando usar o formulário php dele.
      Quando clico em enviar ele me enviar para um arquivo .php  (assets/vendor/simple-forms/sendmail.php)

      Ele não envia o e-mail, acredito que deveria aparecer uma mensagem que o contato foi enviado corretamente.
      Vou deixar os arquivos aqui em anexo quem puder me ajudar nessa, ficaria muito grato.
       
      Link Website (wetransfer.com)
    • Por Algorithm
      Olá a todos
       
      Eu estou codificando um exemplo de uso do GraphQL com Nodejs, mas eu estou recebendo um erro de syntax relacionado a [ : ] [ Dois Pontos ], mas eu comparei meu codigo, com o da documentação oficial e esta tudo certo. Será que alguem, conseguiria achar o erro ?
       
      OBS: Esta incluso neste post [ Exemplo Documentação, Meu Exemplo, Mensagem de Erro, Código Completo ]
       
      Exemplo Documentação
      module.exports = /* GraphQL */ ` type Client { id: ID! name: String age: Int products: [Product] } type Query { clients: [Client] client(id: ID!): Client } type Mutation { addClient(name: String!, age: Int!): Client } `  
      Meu Exemplo
      const typeDefs = ` type Pessoa { _id: ID _codigo: Float _nome: String _idade: Int _email: String } input inputPessoa { _codigo: Float _nome: String _idade: Int _email: String } type Query { resposta: String saudacao(nome: String!): String findPessoaOne(codigo: Float): Pessoa findPessoa(input: inputPessoas): [Pessoa] } type Mutation { insertPessoa(input: inputPessoa): Pessoa updatePessoa(codigo: Float, input: inputPessoa) Pessoa deletePessoa(codigo: Float) [Pessoa] } `;  
      Mensagem de Erro
      C:\Users\Core\node\node_modules\graphql\language\parser.js:1413 throw (0, _syntaxError.syntaxError)( ^ GraphQLError: Syntax Error: Expected ":", found Name "Pessoa". at syntaxError (C:\Users\Core\node\node_modules\graphql\error\syntaxError.js:15:10) at Parser.expectToken (C:\Users\Core\node\node_modules\graphql\language\parser.js:1413:40) at Parser.parseFieldDefinition (C:\Users\Core\node\node_modules\graphql\language\parser.js:847:10) at Parser.optionalMany (C:\Users\Core\node\node_modules\graphql\language\parser.js:1510:28) at Parser.parseFieldsDefinition (C:\Users\Core\node\node_modules\graphql\language\parser.js:831:17) at Parser.parseObjectTypeDefinition (C:\Users\Core\node\node_modules\graphql\language\parser.js:803:25) at Parser.parseDefinition (C:\Users\Core\node\node_modules\node_modules\graphql\language\phql\language\parser.js:171:23) at Parser.many (C:\Users\Core\node\node_modules\graphql\language\parser.js:1529:26) at Parser.parseDocument (C:\Users\Core\node\node_modules\graphql\language\parser.js:121:25) at parse (C:\Users\Core\node\node_modules\graphql\language\parser.js:32:17) { path: undefined, locations: [ { line: 26, column: 57 } ], extensions: [Object: null prototype] {} }  
      Codigo Completo
      // Requires const express = require('express'); const GraphQL_HTTP = require('express-graphql'); const { mergeSchemas } = require('@graphql-tools/schema'); // Run // const connect = MongoClient.connect(''); const app = express(); const getCode = () => { return 10 }; // GraphQL Definitions || Query and Mutation const typeDefs = ` type Pessoa { _id: ID _codigo: Float _nome: String _idade: Int _email: String } input inputPessoa { _codigo: Float _nome: String _idade: Int _email: String } type Query { resposta: String saudacao(nome: String!): String findPessoaOne(codigo: Float): Pessoa findPessoa(input: inputPessoas): [Pessoa] } type Mutation { insertPessoa(input: inputPessoa): Pessoa updatePessoa(codigo: Float, input: inputPessoa) Pessoa deletePessoa(codigo: Float) [Pessoa] } `; // Functions const resolvers = { Query: { resposta: function() { return `GraphQL Conectado com Sucesso...`; }, saudacao: function(_, args) { return `Olá ${args.nome}! Seja Muito Bem Vindo(a) a GraphQL!!!! ` }, findPessoaOne: function(_, args) { return db.collection('GraphQL-Pessoa').findOne({codigo: args.codigo}) .then((result) => { return result; }); }, findPessoa: function(_, args) { return db.collection(`GraphQL-Pessoa`).find(args.input).toArray() .then((result) => { return result; }); }, Mutation: { insertPessoa: function(_, args) { args.input.codigo = getCode(); return db.collection(`GraphQL-Pessoa`).insertOne(args.input) .then((result) => { return result.ops[0]; }); }, updatePessoa: function(_, args) { return db.collection('GraphQL-Pessoa').updateOne({codigo: args.codigo}, {$set: args.input}) .then((result) => { if(result.result.n > 0) return `Registro Alterado com Sucesso!`; else return `Ocorreu um erro ao alterar o registro`; }); }, deletePessoa: function(_, args) { return db.collection(`GraphQL-Pessoa`).deleteOne({codigo: args.codigo}) .then((result) => { if(result.result.n > 0) return `Registro Deletado com Sucesso!`; else return `Ocorreu um erro ao deletar o registro`; }); } } } }; const schema = mergeSchemas({ typeDefs: typeDefs, resolvers: resolvers }) // Listen app.listen(3005, () => { console.log(`Servidor Rodando na Porta 3005`); })  
       
      Obrigado
    • Por Kefatif
      Prezados, bom dia.
       
      Preciso da ajuda dos Srs!
       
      Não estou conseguindo localizar o erro no arquivo abaixo.
       
      Ao clicar no botão ele me envia a mensagem: "Erro ao registrar estoque !"
       
      Poderiam me ajudar?
       
      Agradeço desde já pela ajuda.
       
      <?php include_once 'autenticacao.php'; include_once'../../conexao.php'; include_once '../../funcoes.php'; include_once '../../decodepost.php'; if( !isset($_POST["cont"]) or !isset($_SESSION["cnes"]) ){ ECHO "Erro"; }else{ $cnes = $_SESSION["cnes"]; $idusuario = $_SESSION["idusuario"]; $cont = $_POST["cont"]; $sql = "insert into LESAO_ESTOQUE values(null,curdate(), '".$cnes."',".$idusuario.")"; if(mysqli_query($con, $sql)){ $idestoque = mysqli_insert_id($con); $coberturas = 0; for($i=1 ; $i<=$cont; $i++){ if(isset($_POST[$i])){ if($_POST[$i]<=0){ }else{ $qtd = $_POST[$i]; $sqlqtd = "insert into LESAO_REL_ESTOQUE_COBERTURAS values(".$idestoque.", ".$i.", ".$qtd.", ".$idusuario.")"; if(mysqli_query($con, $sqlqtd)){ $coberturas = $coberturas+1; } } } } $grav = "Registrado estoque de ".$coberturas." coberturas !"; }else{ $grav = "Erro ao registrar estoque !"; } //5- Fechar a conexão mysqli_close($con); ?> <script> alert('<?php echo $grav; ?>'); location.href="estoque-registrar.php"; </script> <?php } ?>  
    • Por Sapinn
      Opa galera, tudo blz? Recentemente comecei a estudar reactjs e para praticar estou fazendo o clone da Netiflix. Mas estou com um erro ao tentar chamar as imagens da API do TMDB o erro é: 
      TypeError: Cannot read properties of undefined (reading 'results')
       
      Já tentei refazer o código varias vezes mas não consegui resolver o problema. Vou postar o resto do código aqui
       
      App.js:
      import React, {useEffect, useState} from 'react'; import Tmdb from './Tmdb'; import MovieRow from './components/MovieRow'; const App = () =>{   const [movieList, setMovieList] = useState([]);   useEffect(()=>{     const loaddAll = async () =>{       let list = await Tmdb.getHomeList();       setMovieList(list)     }     loaddAll();   }, []);   return(       <div className="page">           <section className="lists">               {movieList.map((item, key)=>(                     <MovieRow key={key} title={item.title} items={item.items}/>               ))}                         </section>       </div>   ); } export default App; Consumir a api:
      Tmdb.js:
      const API_KEY = '******************************'; const API_BASE = 'https://api.themoviedb.org/3'; const basicFetch = async (endpoint) =>{     const req = await fetch(`${API_BASE}${endpoint}`)     const json = await req.json();     return json; } export default {     getHomeList: async () =>{         return [             {                 slug: 'originals',                 title: 'Originais da Netflix',                 items: await basicFetch(`/discover/tv?with_networks=213&language=pt-BR&api_key=${API_KEY}`)             },             {                 slug: 'trending',                 title: 'Recomendados para você',                 item: await basicFetch(`/trending/all/week?language=pt-BR&api_key=${API_KEY}`)             },             {                 slug: 'toprated',                 title: 'Em alta',                 item: await basicFetch(`/movie/top_rated?language=pt-BR&api_key=${API_KEY}`)             },             {                 slug: 'action',                 title: 'Ação',                 item: await basicFetch(`/discover/movie?width_genres=28&language-pt-BR&api_key=${API_KEY}`)             },             {                 slug: 'comedy',                 title: 'Comédia',                 item: await basicFetch(`/discover/movie?width_genres=35&language-pt-BR&api_key=${API_KEY}`)             },             {                 slug: 'horror',                 title: 'Terror',                 item: await basicFetch(`/discover/movie?width_genres=27&language-pt-BR&api_key=${API_KEY}`)             },             {                 slug: 'romance',                 title: 'Romance',                 item: await basicFetch(`/discover/movie?width_genres=10749&language-pt-BR&api_key=${API_KEY}`)             },             {                 slug: 'documentary',                 title: 'Documentários',                 item: await basicFetch(`/discover/movie?width_genres=99&language-pt-BR&api_key=${API_KEY}`)             },                     ]     } }  
       
      Componente para mostrar os filmes:
      MovieRow.js:
      import React from "react"; import './MovieRow.css'; export default ({title, items}) =>{         return (         <div>             <h2>{title}</h2>             <div className="moviewRow--listarea">                 {items.results.length > 0 && items.results.map((key, item)=>(                     <img src={`https://image.tmdb.org/t/p/w300${item.poster_path}`} />                 ))}             </div>         </div>     ); }  
      Se alguém pudesse me ajudar eu ficaria muito grato.
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.