According to the C++ ISO spec, §26.2/2:
The effect of instantiating the template
complex
for any type other thanfloat
,double
orlong double
is unspecified.
Why would the standard authors explicitly add this restriction? This makes it unspecified, for example, what happens if you make complex<int>
or a complex<MyCustomFixedPointType>
and seems like an artificial restriction.
Is there a reason for this limitation? Is there a workaround if you want to instantiate complex
with your own custom type?
I'm primarily asking this question because of this earlier question, in which the OP was confused as to why abs
was giving bizarre outputs for complex<int>
. That said, this still doesn't quite make sense given that we also might want to make complex
numbers out of fixed-points types, higher-precision real numbers, etc.
If high precision is not required and the program only needs a huge array of decimal numbers to be stored, float is a cost-effective way of storing data and saves memory. Double is costlier, occupies more space and is more effective when more precision is required.
A float has 7 decimal digits of precision and occupies 32 bits . A double is a 64-bit IEEE 754 double-precision floating-point number. 1 bit for the sign, 11 bits for the exponent, and 52 bits for the value. A double has 15 decimal digits of precision and occupies a total of 64 bits .
You can't properly implement many of the std::complex
operations on integers. E.g.,
template <class T> T abs(const complex<T> &z);
for a complex<long>
cannot have T = long
return value when complex numbers are represented as (real,imag) pairs, since it returns the value of sqrt(pow(z.real(), 2) + pow(z.imag(), 2))
. Only a few of the operations would make sense.
Even worse, the polar
named constructor cannot be made reliable without breaking the default constructor and vice versa. The standard would have to specify that "complex integers" are Gaussian integers for them to be of any use, and that one of the constructors is severely broken.
Finally, how would you like your "complex integer division" served, and would you like a "complex remainder" with that? :)
Summarizing, I think it would be more sensible to specify a separate gaussian_int<T>
type with just a few operations than graft support for integral T
onto std::complex
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With