bsantos Posted January 13, 2021 at 10:37 PM Share Posted January 13, 2021 at 10:37 PM Eu tenho serios problemas com meu GCC ao usar funcoes matematicas. Esse codigo eh um exercicios (13 do capitulo 3) do livro do Andre Backes - Linguagem - Completa e Descomplicada. Como no exemplo abaixo: #include <stdio.h> #include <stdlib.h> #include <tgmath.h> int main(void) { double h, a, b; printf("-- Calculo da Hipotenuza do triangulo retangulo --\n"); scanf("%lf%lf",&a,&b); h = sqrt(exp(2.00*log(a) + exp(2.00*log(b)))); printf("O valor da hipotenuza eh: %.4lf\n",h); return EXIT_SUCCESS; } O problema aparece quando vou compilar, seja usando make ou gcc -std=c??. Tambem usando -std=gnu?? make exec13_3 cc exec13_3.c -o exec13_3 /usr/bin/ld: /tmp/ccktALow.o: na função "main": exec13_3.c:(.text+0x36): referência não definida para "log" /usr/bin/ld: exec13_3.c:(.text+0x49): referência não definida para "log" /usr/bin/ld: exec13_3.c:(.text+0x52): referência não definida para "exp" /usr/bin/ld: exec13_3.c:(.text+0x5c): referência não definida para "exp" /usr/bin/ld: exec13_3.c:(.text+0x61): referência não definida para "sqrt" collect2: error: ld returned 1 exit status make: *** [<builtin>: exec13_3] Error 1 Eh nisso que fico perdido. Consultei as headers tgmath.h e math.h, alem de sua indicacao de livro (pdf) "ModernC". Mas nao consigo achar o problema da falta de referencia. PS: sim, a ortografia falha eh por conta do teclado US. Link to comment Share on other sites More sharing options...
bsantos Posted January 14, 2021 at 03:54 AM Author Share Posted January 14, 2021 at 03:54 AM Resolvido pessoal. É com muita vergonha que venho confessar que esquecia de declarar -lm na hora de compilar. Exemplo: gcc exec13_3.c -o exec13_3 -lm #vergonha . Mas está sanado a dúvida. Link to comment Share on other sites More sharing options...
Administrators Fernando Mercês Posted January 14, 2021 at 01:23 PM Administrators Share Posted January 14, 2021 at 01:23 PM hahahaha maravilhoso @bsantos. Acontece. De boa. ? Link to comment Share on other sites More sharing options...
fredericopissarra Posted January 21, 2021 at 02:03 PM Share Posted January 21, 2021 at 02:03 PM Só uma dica com relação ao Teorema de Pitágoras... Ao fazer: Se a e/ou b forem muito grandes, você poderá obter +INFINTE (overflow) como resposta. A mesma coisa acontece com a exponenciação que você usou... Uma aproximação melhor e menos provável de obter overflow é selecionando o maior dos dois valores (suponha: a) e fazer: Desde que a != 0 (neste caso h=|b|). Eis a simplificação: Assim, (b/a)², no máximo, será um valor subnormal (entre 0 e 1) e a podera ser bem mais próximo do máximo valor suportado da precisão do tipo em ponto flutuante. Além de diminuir o esforço ao calcular apenas uma potência simples. A função: #include <math.h> #define swap(a,b) \ { double t; t = (a); (a) = (b); (b) = t; } double hipotenuse(double a, double b) { double tmp; if ( isnan(a) || isnan(b) ) return NAN; if (b > a) swap( a, b ); if (a < 0.0) return NAN; if ( a == 0.0 ) return fabs(b); // Poderíamos usar 'return -b' porque b pode ser igual a 0.0, o que resultaria em -0.0, // que, para todos os efeitos, é a mesma coisa que +0.0. tmp = b / a; return a * sqrt(1.0 + tmp*tmp); } Link to comment Share on other sites More sharing options...
fredericopissarra Posted January 21, 2021 at 02:44 PM Share Posted January 21, 2021 at 02:44 PM Regra geral: TODA equação, ao ser codificada usando ponto flutuante, tem que ser condicionada para evitar condições de overflow e underflow... É bom lembrar que tipos em ponto flutuante têm menor precisão binária que os mesmos tipos, do mesmo tamanho, inteiros e que o domínio da representação desses valores (em ponto flutuante) não são ℝ, mas sim ℚ (domínio dos "racionais" -- o que, se pensar bem, é óbvio). Sobre a alegação de precisão menor... O tipo long long int tem 63 bits de precisão (1 para o sinal), enquanto double tem 53 -- a estrutura de ambos os tipos e de 64 bits. A mesma coisa acontece com int e float (31 e 24, respectivamente). "Precisão" NÃO se refere à quantidade de "algarismos depois da vírgula"... Link to comment Share on other sites More sharing options...
bsantos Posted January 23, 2021 at 05:11 PM Author Share Posted January 23, 2021 at 05:11 PM Em 21/01/2021 em 11:44, fredericopissarra disse: Regra geral: TODA equação, ao ser codificada usando ponto flutuante, tem que ser condicionada para evitar condições de overflow e underflow... É bom lembrar que tipos em ponto flutuante têm menor precisão binária que os mesmos tipos, do mesmo tamanho, inteiros e que o domínio da representação desses valores (em ponto flutuante) não são ℝ, mas sim ℚ (domínio dos "racionais" -- o que, se pensar bem, é óbvio). Sobre a alegação de precisão menor... O tipo long long int tem 63 bits de precisão (1 para o sinal), enquanto double tem 53 -- a estrutura de ambos os tipos e de 64 bits. A mesma coisa acontece com int e float (31 e 24, respectivamente). "Precisão" NÃO se refere à quantidade de "algarismos depois da vírgula"... Obrigado pela dica. Aliás, depois de ler, fui conferir a biblioteca <math.h> e sim, as funções estão definidas com double. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.