|
Tipos Complexos em D e std::complex em C++Como fazer números complexos em D se compararem com a classe std::complex em C++?Estéticas SintáticasEm C++, os tipos complexos são:complex<float>C++ não tem um tipo imaginário distinto. D tem 3 tipos complexos e 3 tipos imaginários: cfloatUm número complexo em C++ pode interagir com um literal aritmético, mas já que não há tipo imaginário, números imaginários podem ser criados somente com a sintaxe de contrutor: complex<long double> a = 5; // a = 5 + 0iEm D, um literal numérico imaginário tem o sufixo 'i'. O código correspondente seria o mais natural: creal a = 5; // a = 5 + 0iPara expressões mais envolvidas envolvendo constantes: c = (6 + 2i - 1 + 3i) / 3i;Em C++, isso seria: c = (complex<double>(6,2) + complex<double>(-1,3)) / complex<double>(0,3);ou se uma classe imaginária fosse acrescentada à C++ poderia ser: c = (6 + imaginary<double>(2) - 1 + imaginary<double>(3)) / imaginary<double>(3);Em outras palavras, um número imaginário nn pode ser representado com apenas nni ao invés de escrever uma chamada à construtor complex<long double>(0,nn). EficiênciaA falta de um tipo imaginário em C++ significa que operações em números imaginários ventam com várias cumputações extras feitas na parte real 0. Por exemplo, somar dois números imaginários em D é uma adição:ireal a, b, c;Em C++, são duas adições, como a parte real é somada também: c.re = a.re + b.re;Multiplicar é pior, como 4 multiplicações e duas adições são feitas ao invés de uma multiplicação: c.re = a.re * b.re - a.im * b.im;Dividir é o pior - D tem uma divisão, considerando que C++ implementa divisão de complexos com tipicamente uma comparação, 3 divisões, 3 multiplicações e 3 somas: if (fabs(b.re) < fabs(b.im))Para evitar essas preocupações com eficiência em C++, alguém poderia simular um número imaginário usando um double. Por exemplo, dado em D: cdouble c;isso poderia ser escrito em C++ como: complex<double> c;mas as vantagens de complexos serem um tipo de biblioteca integrada com os operadores aritméticos seria perdida. SemânticaPior de tudo, a falta de um tipo imaginário pode causar a resposta errada a ser inadivertidamente produzida. Para citar Prof. Kahan:"Um fluxo vai desencaminhado quando as funções complexas SQRT e LOG são implementadas, como é necessário em Fortran e em bibliotecas atualmente distribuídas em compiladores C/C++, de forma que desconsideram o sinal de 0.0 em aritmética IEEE 754 e conseqüêntemente violam identidades como SQRT( CONJ( Z ) ) = CONJ( SQRT( Z ) ) e LOG( CONJ( Z ) ) = CONJ( LOG( Z ) ) sempre que a variável COMPLEXA Z tem valores reais negativos. Tais anomalias são inevitáveis se Aritmética de Complexos opera em pares (x, y) ao invés de somas nocionais x + i*y de variáveis imaginárias e reais. A linguagem de pares é incorreta para Aritmética Complexa; ela precisa de em Tipo Imaginário."Os problemas de semântica são:
ReferênciasHow Java's Floating-Point Hurts Everyone Everywhere Prof. W. Kahan and Joseph D. DarcyThe Numerical Analyst as Computer Science Curmudgeon by Prof. W. Kahan "Branch Cuts for Complex Elementary Functions, or Much
Ado About Nothing's Sign Bit" by W. Kahan, ch. |