tonux Posted December 15, 2016 at 06:39 PM Report Share #601266 Posted December 15, 2016 at 06:39 PM Olá Ao fazer cálculos mais rigorosos em C++, apercebi-me de certas particularidades: pow(a,(1/3) não é igual a pow(a,0.333333). Isto é significativo quando são exigidos cálculos matemáticos nesta área. Assim, num programa C++ onde figurem raízes cúbicas, por exemplo, é conveniente adicionar a linha na área do cabeçalho #define ir3 0.333333. Para futuros cálculos utilizaremos pow(a,ir3) . Em BASIC é indiferente (ver mais abaixo) Nota: isto em relação ao compilador usado por mim( GNU); não utilizei outros (ainda) #include <iostream> #include <cmath> using namespace std; #define ir3 0.333333 int main() { for (float i=1;i<50;i=i+5) { cout<<"valor com 1/3= "<<pow(i,(1/3))<<endl; cout<<"valor com 0.333333= "<<pow(i,ir3)<<endl; } return 0; } Resultados: valor com 1/3= 1 valor com 0.333333= 1.81712 valor com 1/3= 1 valor com 0.333333= 2.22398 valor com 1/3= 1 valor com 0.333333= 2.51984 valor com 1/3= 1 valor com 0.333333= 2.75892 valor com 1/3= 1 valor com 0.333333= 2.96249 valor com 1/3= 1 valor com 0.333333= 3.14138 valor com 1/3= 1 valor com 0.333333= 3.30192 valor com 1/3= 1 valor com 0.333333= 3.44821 valor com 1/3= 1 valor com 0.333333= 3.58304 dim i as single const ir3=0.333333 for i=1 to 50 step 5 print print "com 1/3= ";(i^(1/3)) print print "com 0.333333= ";(i^ir3) print next end resultados: com 1/3= 1 com 0.333333= 1 com 1/3= 1.81712059283214 com 0.333333= 1.817119507551454 com 1/3= 2.223980090569315 com 0.333333= 2.223978312946244 com 1/3= 2.519842099789746 com 0.333333= 2.519839770962227 com 1/3= 2.75892417638112 com 0.333333= 2.758921376513688 com 1/3= 2.96249606840737 com 0.333333= 2.962492851043056 com 1/3= 3.141380652391393 com 0.333333= 3.141377056573129 com 1/3= 3.301927248894626 com 0.333333= 3.301923304724039 com 1/3= 3.44821724038273 com 0.333333= 3.448212971984297 com 1/3= 3.583047871015946 com 0.333333= 3.583043298283729 Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted December 15, 2016 at 10:10 PM Report Share #601271 Posted December 15, 2016 at 10:10 PM isso não é problema do compilador ... é problema do programador ... - inteiro / inteiro = inteiro - inteiro / float = float - float / inteiro = float - float / float = float isto é algo que um programador de C se apercebe rapidamente, chamasse elevação do tipo de dados para o tipo de maior representação. isto porque o primeiro exemplo chamasse divisão inteira. isto faz parte da linguagem e não do compilador isto simplesmente quer dizer que : se queres fazer contas com valores de virgual flutuante, não uses inteiros IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
Knitter Posted December 15, 2016 at 10:52 PM Report Share #601273 Posted December 15, 2016 at 10:52 PM E a tua questão é? 4 horas atrás, tonux disse: pow(a,(1/3) não é igual a pow(a,0.333333). Isto é significativo quando são exigidos cálculos matemáticos nesta área. Claro que não é igual, era suposto ser? 1/3 nem é igual a 0.333333. Como o HappyHippyHippo disse, não é um problema do compilador... nada no teu exemplo é um problema da linguagem, do compilador, ou do que seja, nem dá bem para perceber a ideia de mencionar BASIC... ou a ideia geral do tópico. Link to comment Share on other sites More sharing options...
tonux Posted December 16, 2016 at 03:14 AM Author Report Share #601277 Posted December 16, 2016 at 03:14 AM (edited) 4 horas atrás, Knitter disse: E a tua questão é? Claro que não é igual, era suposto ser? 1/3 nem é igual a 0.333333. Como o HappyHippyHippo disse, não é um problema do compilador... nada no teu exemplo é um problema da linguagem, do compilador, ou do que seja, nem dá bem para perceber a ideia de mencionar BASIC... ou a ideia geral do tópico. Acho que era suposto ser. 1:3 (1/3) tem como quociente uma dizima infinita: 0.333333 ...33333.... basta fazer a conta à mão. Também acho que para a mesma operação deveria haver consonância entre as várias linguagens de programação quanto a resultados, embora os estilos de programação sejam diferentes. Ou então pode-se optar(?) por uma divisão inteira e temos o resultado 0. Para a resolução de uma raiz cubica não é muito conveniente. A não ser que se faça o seguinte: na igualdade v=1/3, declarar v como float. Vou experimentar. Obrigado pelas respostas🙂 Edited December 16, 2016 at 03:23 AM by tonux Link to comment Share on other sites More sharing options...
tonux Posted December 16, 2016 at 03:40 AM Author Report Share #601278 Posted December 16, 2016 at 03:40 AM (edited) #include <iostream> #include <cmath> using namespace std; int main () { float v; cout<<1/3.0<<endl; v=1/3.0; cout<<v<<endl; return 0; } // resultado para os dois casos: 0.33333 Erro de palmatória. O número 3 (ou no 1 ou os dois) devem ser dados a conhecer como não inteiros, isto é, como 1.0 e/ou 3.0. Senão temos 0 para as duas saídas no programa, se pelo menos um deles não for considerado 'float'. O compilador tem razão em C++, respeitando as suas regras. Ok. Obrigado pela ajuda. Edited February 5, 2017 at 10:50 AM by pwseo Syntax highlight. Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted December 16, 2016 at 08:56 AM Report Share #601283 Posted December 16, 2016 at 08:56 AM 5 hours ago, tonux said: Acho que era suposto ser. 1:3 (1/3) tem como quociente uma dizima infinita: 0.333333 ...33333.... basta fazer a conta à mão. Também acho que para a mesma operação deveria haver consonância entre as várias linguagens de programação quanto a resultados, embora os estilos de programação sejam diferentes. Ou então pode-se optar(?) por uma divisão inteira e temos o resultado 0. Para a resolução de uma raiz cubica não é muito conveniente. A não ser que se faça o seguinte: na igualdade v=1/3, declarar v como float. Vou experimentar. Obrigado pelas respostas🙂 5 hours ago, tonux said: Erro de palmatória. O número 3 (ou no 1 ou os dois) devem ser dados a conhecer como não inteiros, isto é, como 1.0 e/ou 3.0. Senão temos 0 para as duas saídas no programa, se pelo menos um deles não for considerado 'float'. O compilador tem razão em C++, respeitando as suas regras. Ok. Obrigado pela ajuda. afinal leste o meu post ? está lá explicado como é que isso funciona !!! o problema está na tua cabeça, lá porque teres uma ideia fixa de como pensas que a coisas funcionam, não quer dizer que sejam assim. a meu ver, o problema é mais do BASIC do que do C, no meu prisma é o BASIC que te está a abstrair da conversão, porque a divisão inteira é útil e tem a sua razão. tem haver como as coisas funcionam em termos de memória. a tua afirmação parece indicar que ainda não estás elucidado nessa matéria se quiseres a divisão seja feita com virgula flutuante, basta fazer uma cast de qualquer parâmetro da operação IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 16, 2016 at 12:30 PM Report Share #601291 Posted December 16, 2016 at 12:30 PM Só para reforçar o que já foi ditto. 1/3 é diferente de 0.33 e diferente de 0.3333 e diferente de 0.333333333333. Logo aqui vai haver uma diferença de resultado que pode ser significativa consoante a magnitude dos dados que estamos a usar! Ao dizer que 1/3 é igual a 0.33333333333333, por exemplo, estamos a cometer um erro porque na verdade 1/3 = 0.33(3) onde o 3 entre parêntesis é a tal dízima infinita e se é infinita não se pode dizer que é 0.333 ou 0.33333333 ou 0.333333333333.... Mas só estou a reforça ro que já foi ditto!! Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
tonux Posted December 16, 2016 at 03:28 PM Author Report Share #601294 Posted December 16, 2016 at 03:28 PM 6 horas atrás, HappyHippyHippo disse: afinal leste o meu post ? está lá explicado como é que isso funciona !!! o problema está na tua cabeça, lá porque teres uma ideia fixa de como pensas que a coisas funcionam, não quer dizer que sejam assim. a meu ver, o problema é mais do BASIC do que do C, no meu prisma é o BASIC que te está a abstrair da conversão, porque a divisão inteira é útil e tem a sua razão. tem haver como as coisas funcionam em termos de memória. a tua afirmação parece indicar que ainda não estás elucidado nessa matéria se quiseres a divisão seja feita com virgula flutuante, basta fazer uma cast de qualquer parâmetro da operação #include <iostream> using namespace std; int main() { cout<<(1/3); return 0; } Resultado 0 ------------------------------------------- 'Programa em BASIC print 1/3 end Resultado 0.33333 Basta correr estes dois exemplos simples para ser ver a diferença de tratamento que cada compilador dá. Por defeito, o BASIC considera a operação fraccionária; o C++ considera, por princípio uma operação inteira, caso não seja nada especificado. De facto, acho mais correcta a "posição" do C++: é necessário especificar com rigor o que pretendemos.🙂 Nota: Decidi iniciar-me mais a fundo no C++, agora. Já tinha abordado esta linguagem há uns bons anos atrás (mais de dez), com o C e C++. Contudo, tenho sempre feito alguns programas sempre em BASIC. São (maus) hábitos que se criam. Link to comment Share on other sites More sharing options...
tonux Posted December 16, 2016 at 03:34 PM Author Report Share #601295 Posted December 16, 2016 at 03:34 PM (edited) 3 horas atrás, PsySc0rpi0n disse: Só para reforçar o que já foi ditto. 1/3 é diferente de 0.33 e diferente de 0.3333 e diferente de 0.333333333333. Logo aqui vai haver uma diferença de resultado que pode ser significativa consoante a magnitude dos dados que estamos a usar! Ao dizer que 1/3 é igual a 0.33333333333333, por exemplo, estamos a cometer um erro porque na verdade 1/3 = 0.33(3) onde o 3 entre parêntesis é a tal dízima infinita e se é infinita não se pode dizer que é 0.333 ou 0.33333333 ou 0.333333333333.... Mas só estou a reforça ro que já foi ditto!! Sim, o número de casas decimais/algarismos significativos depende do rigor que pretendemos. Isto é importante, por exemplo, para o cálculo de raízes cúbicas, e não só, num determinado processo e objectivo. Edited December 16, 2016 at 03:35 PM by tonux Link to comment Share on other sites More sharing options...
PsySc0rpi0n Posted December 16, 2016 at 03:44 PM Report Share #601297 Posted December 16, 2016 at 03:44 PM 8 minutes ago, tonux said: Sim, o número de casas decimais/algarismos significativos depende do rigor que pretendemos. Isto é importante, por exemplo, para o cálculo de raízes cúbicas, e não só, num determinado processo e objectivo. Pronto, para além deste facto e do que o @HappyHippyHippo disse, os resultados estavam a ser diferentes entre Pascal e C/C++... A precedência de operadores faz toda a diferença! E o tipo de dados usados em algumas operações também! Kurt Cobain - Grunge misses you Nissan GT-R - beast killer Link to comment Share on other sites More sharing options...
tonux Posted December 16, 2016 at 04:18 PM Author Report Share #601300 Posted December 16, 2016 at 04:18 PM (edited) 42 minutos atrás, PsySc0rpi0n disse: Pronto, para além deste facto e do que o @HappyHippyHippo disse, os resultados estavam a ser diferentes entre Pascal e C/C++... A precedência de operadores faz toda a diferença! E o tipo de dados usados em algumas operações também! program est implicit none print*, '1/3= ',(1/3) print*, '1/3.0= ',(1/3.0) end program resultado: 1/3= 0 1/3.0= 0.333333343 Já agora, e por curiosidade, apresento o mesmo cálculo em Fortran 95. Só que está ali um 4 que... não devia lá estar! Aqui, o compilador não andou muito bem. Em relação ao C++, o FORTRAN considera as mesmas diferenças de cálculo; os resultados são "idênticos", só que com mais casas decimais para o FORTRAN, fora o tal 4! Edited December 16, 2016 at 04:27 PM by tonux Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted December 16, 2016 at 04:35 PM Report Share #601301 Posted December 16, 2016 at 04:35 PM 15 minutes ago, tonux said: program est implicit none print*, '1/3= ',(1/3) print*, '1/3.0= ',(1/3.0) end program resultado: 1/3= 0 1/3.0= 0.333333343 Já agora, e por curiosidade, apresento o mesmo cálculo em Fortran 95. Só que está ali um 4 que... não devia lá estar! Aqui, o compilador não andou muito bem. Em relação ao C++, o FORTRAN considera as mesmas diferenças de cálculo; os resultados são "idênticos", só que com mais casas decimais para o FORTRAN, fora o tal 4! isso é problema de representação de um valor de virgula flutuante ao nível do IEEE 754 . em algum lado a coisa tem que parar e ter um erro ... IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now