tonux Posted December 15, 2016 at 06:39 PM Report #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
HappyHippyHippo Posted December 15, 2016 at 10:10 PM Report #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
Knitter Posted December 15, 2016 at 10:52 PM Report #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.
tonux Posted December 16, 2016 at 03:14 AM Author Report #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
tonux Posted December 16, 2016 at 03:40 AM Author Report #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.
HappyHippyHippo Posted December 16, 2016 at 08:56 AM Report #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
PsySc0rpi0n Posted December 16, 2016 at 12:30 PM Report #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
tonux Posted December 16, 2016 at 03:28 PM Author Report #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.
tonux Posted December 16, 2016 at 03:34 PM Author Report #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
PsySc0rpi0n Posted December 16, 2016 at 03:44 PM Report #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
tonux Posted December 16, 2016 at 04:18 PM Author Report #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
HappyHippyHippo Posted December 16, 2016 at 04:35 PM Report #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
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