I have some C99 code where I need to convert an array of 2n double to an array of n double complex. I do this with
static void real_to_complex(const double *r, size_t n, double complex *z)
{
size_t i;
for (i=0 ; i<n ; i++)
z[i] = r[2*i] + r[2*i + 1]*I;
}
This is a performance critical part of the code, and I'd really rather not have to create a new storage area z and have the expense of the copying, instead I'd like to replace these function calls by
z = (double complex*)r;
Is there any way to do this and remain standard conforming? I understand that a double complex is guaranteed to have the same layout as an array of two doubles -- perhaps I could get away with a compiler check as to whether this layout is (real,imaginary) or (imaginary,real)?
You are guaranteed the first element of the complex array corresponds to the real part and the second element corresponds to the imaginary part.
Quote from the publicly available draft of C11 Standard
6.2.5/13 Each complex type has the same representation and alignment requirements as an array type containing exactly two elements of the corresponding real type; the first element is equal to the real part, and the second element to the imaginary part, of the complex
number.
Example program
#include <complex.h>
#include <stdio.h>
int main(void) {
double x[] = {42, 2, 41, 1, 0, 0};
_Complex double *y = (void*)x;
while (creal(*y) > 0) {
printf("%f + %fi\n", creal(*y), cimag(*y));
y++;
}
return 0;
}
Related
Using the complex number type of the C99 standard, how does one assign the real and imaginary parts of a variable individually? I found the GNU extension __real__ and __imag__ will do it, as in the following example program. But this isn't portable or standard. How can one do this portably?
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
int
main()
{
complex double z;
__real__ z = 3.0;
__imag__ z = 2.0;
fprintf(stderr, "z = %f + i %f\n", creal(z), cimag(z));
return 0;
}
C 2018 6.2.5 13 implies we can treat complex number as an array of two elements:
Each complex type has the same representation and alignment requirements as an array type containing exactly two elements of the corresponding real type; the first element is equal to the real part, and the second element to the imaginary part, of the complex number.
This is crude wording, at odds with the explicitly stated aliasing rules in 6.5 7, but the standard is imperfect, and footnotes 41 and 49, about integers and pointers, suggest such statements about representation and alignment are supposed to allow some use of one view of the object for another in spite of the rules in 6.5 7. If so, we can define macros:
#define Re(x) (_Generic((x), \
complex float : ((float *) &(x)), \
complex double : ((double *) &(x)), \
complex long double : ((long double *) &(x)))[0])
#define Im(x) (_Generic((x), \
complex float : ((float *) &(x)), \
complex double : ((double *) &(x)), \
complex long double : ((long double *) &(x)))[1])
after which Re(x) and Im(x), when given a complex object, produce an lvalue for the real or imaginary part. So we can assign them:
Re(x) = 3;
Im(x) = 4;
How can one do this portably?
It's just... addition:
z = 3.0;
z += I * 2.0;
You could first zero the imaginary part, if you want to:
z = creal(z) + I * 2.0;
how does one assign the real and imaginary parts of a variable
individually?
// assign real
z = new_value + I * cimag(z);
// assign imaginary
z = creal(z) + I * new_value;
One could prefer _Imaginary_I or CMPLXF macros over I.
I found another possible solution. The code below assumes that complex double is bit-equivalent to double[2] (which I think is correct but would appreciate a verification!). I think the solution below may be more efficient since it doesn't involve an extra addition operation for each assignment (as does KamilCuk's solution).
If anyone can verify this is will be portable to all platforms, I would appreciate it.
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#define SET_REAL(z, x) ( *((double *) &(z)) = (x) )
#define SET_IMAG(z, x) ( *(((double *) &(z)) + 1) = (x) )
int
main()
{
complex double z;
SET_REAL(z, 3.0);
SET_IMAG(z, 2.0);
fprintf(stderr, "z = %f + i %f\n", creal(z), cimag(z));
return 0;
}
How to compare long doubles with qsort() and with regard to not-a-number?
When sorting an array that might contain not-a-numbers, I would like to put all the those NAN to one end of the sorted array.
qsort() imposes some restriction on the compare function.
The function shall return an integer less than, equal to, or
greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
C11dr §7.22.5.2 3
When the same objects ... are passed more than once to the comparison function, the results shall be consistent with one another. That is, for qsort they shall define a total ordering on the array, ... the same object shall always compare the same way with the key.
§7.22.5 4
a > b is false when a <= b or if a is not-a-number or if b is not-a-number. So a > b is not the same as !(a <= b) as they have opposite results if one of them is NaN.
If the compare function uses return (a > b) - (a < b);, code would return 0 if one or both a or b are NaN. The array would not sort as desired and it loses the total ordering requirement.
The long double aspect of this sort is important when using the classify functions like int isnan(real-floating x); or int isfinite(real-floating x);. I know isfinite( finite_long_double_more_than_DBL_MAX) might return false. So I have concerns about what isnan(some_long_double) might do something unexpected.
I tried the below. It apparently sorts as desired.
Sub-question: Is compare() below sufficient to sort as desired? Any recommended simplifications? If not - how to fix?
(For this task, it is OK for values like 0.0L and -0.0L to sort in any way)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
int compare(const void *a, const void *b) {
const long double *fa = (const long double *) a;
const long double *fb = (const long double *) b;
if (*fa > *fb) return 1;
if (*fa < *fb) return -1;
if (*fa == *fb) {
//return -memcmp(fa, fb, sizeof *fa); if -0.0, 0.0 order important.
return 0;
}
// At least one of *fa or *fb is NaN
// is *fa a non-NaN?
if (!isnan(*fa)) return -1;
if (!isnan(*fb)) return 1;
// both NaN
return 0;
// return -memcmp(fa, fb, tbd size); if NaN order important.
}
int main(void) {
long double x[] = { 0.0L / 0.0, 0.0L / 0.0, 0.0, 1.0L / 0.0, -0.0, LDBL_MIN,
LDBL_MAX, 42.0, -1.0L / 0.0, 867-5309, -0.0 };
x[0] = -x[0];
printf("unsorted: ");
size_t n = sizeof x / sizeof x[0];
for (size_t i = 0; i < n; i++) {
printf("%.3Le,", x[i]);
}
printf("\nsorted: ");
qsort(x, n, sizeof x[0], compare);
for (size_t i = 0; i < n; i++) {
printf("%.3Le,", x[i]);
}
puts("");
}
Output
unsorted: nan,-nan,0.000e+00,inf,-0.000e+00,3.362e-4932,1.190e+4932,4.200e+01,-inf,-4.442e+03,-0.000e+00,
sorted: -inf,-4.442e+03,-0.000e+00,0.000e+00,-0.000e+00,3.362e-4932,4.200e+01,1.190e+4932,inf,nan,-nan,
If I knew the compare function was correct, I'd post on Code Review for improvement ideas. Yet I am not confident enough that code works correctly with those pesky NaNs.
This is just a simple reordering of your tests, but it makes the status of NaN more clear if you will.
int compare(const void *a, const void *b)
{
const long double fa = *(const long double *) a;
const long double fb = *(const long double *) b;
if (isnan(fa))
{
if (isnan(fb))
{
return 0;
}
return 1;
}
if (isnan(fb))
{
return -1;
}
if (fa > fb) return 1;
if (fa < fb) return -1;
/* no more comparisons needed */
return 0;
}
As the tests for NaN are at the top and no NaNs should pass through, the bottom three lines can safely be replaced with your
return (a > b) - (a < b);
Apart from the discussion of the different types of NaN (a bit sounding like how many angels can dance on a CPU core), this ought to be stable enough for your purposes, and I can't see any possible issues with this code.
With Clang, neither -ffast-math nor -fdenormal-fp-math=[ieee|preserve-sign|positive-zero] yields other results. Nor did gcc with -ffast-math,
-funsafe-math-optimizations, and even -ffinite-math-only (the latter most likely because there are no operations other than a straight compare to NaN).
Just to be complete, I tested with both std::numeric_limits<double>::signaling_NaN(); and std::numeric_limits<double>::quiet_NaN(); (from C++ <limits.h>) as well – again, no difference in the sort order.
The NaN test
int isnan(real-floating x);
The isnan macro determines whether its argument value is a NaN. First, an argument represented in a format wider than its semantic type is converted to its semantic type. Then determination is based on the type of the argument.235
235 For the isnan macro, the type for determination does not matter unless the implementation supports NaNs in the evaluation type but not in the semantic type.
isnan(some_long_double) will work as hoped except on a rare platform.
int isunordered(real-floating x, real-floating y) acts like isnan() expect it accounts for both arguments.
On many platforms, code could use (a == a) as a candidate NaN test as that evaluates to 0 when a is NaN and 1 otherwise. Unfortunately, unless an implementation defines __STDC_IEC_559__, that is not certain to work.
The compare
>=, >, <, <= and C11 7.12.14 Comparison macros
Using >=, >, <, <= when at least one operand is a NaN can result in a "invalid" floating-point exception. So prior testing for NaN is prudent as answered by #usr2564301
C offers macros isgreaterequal(), isgreaterequal(), isless(), islessthna() which do the compare and not raise the "invalid" floating-point
exception. This is good alternative for double, yet the macros use a real-floating which may differ from long double. isgreater(long_double_a, long_double_a) may evaluate as double and not provide the desired compare result.
The challenge with classify macros is that the semantic type may be narrower than long double.
The following uses the above ideas and as I read the C spec is well defined and functionally correct for all cases except the rare one: when long double has NaN but not the real-floating (often double) does not.
#include <math.h>
// compare 2 long double. All NaN are greater than numbers.
int compare(const void *a, const void *b) {
const long double *fa = (const long double *) a;
const long double *fb = (const long double *) b;
if (!isunordered(*fa, *fb)) {
return (*fa > *fb) - (*fa < *fb);
}
if (!isnan(*fa)) {
return -1;
}
return isnan(*fb); // return 0 or 1
}
Note: After reading many of the good comments and learning a great deal, I am posting this self-answer as provided in Can I answer my own question? in addition to accepting another answer.
I am trying to understand the different aspects of memory allocation in C. In the example below, I am calculating the mean of an array. I have defined one function in which the return is an int = 4, and the second in which the return is a double = 4.57.
#include <stdio.h>
#include <stdlib.h>
int getMean(int arr[], int size);
double getMean2(int arr[], int size);
int main()
{
int mean1;
double mean2;
int array[7] = {1,3,5,7,5,4,7};
mean1 = getMean(array, sizeof(array)/sizeof(array[0]));
printf(" Mean 1 = %d", mean1);
mean2 = getMean2(array, sizeof(array)/sizeof(array[0]));
printf("\n Mean 2 = %.2f", mean2);
return 0;
}
int getMean(int arr[], int size) {
int i;
printf("\n");
int sum = 0;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
return sum/size;
}
double getMean2(int arr[], int size) {
int i;
printf("\n");
double sum = 0;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
return sum/size;
}
In the case of the mean function returning an int, is the same memory allocation in RAM still used as in the function returning the double? Or is it still able to perform the calculation using less RAM?
When the int function is performing the calculation, does it still have to store the number as a double, before returning the int?
When the int function is performing the calculation, does it still have to store the number as a double, before returning the int?
This question seems to assume that the result of the following line:
return sum/size;
is always a floating point. But this assumption is wrong. See for example
C11 (draft N1570), §6.5.6 p6:
When integers are divided, the result of the / operator is the algebraic quotient with any
fractional part discarded.
So, if both operands have an integer type, you just get an integer division, the result is an integer type, in your example int (with a value that just discards any fractional part).
In your other function, one operand is already a double. Have a look at
C11 (draft N1570) §6.3.1.8 p1:
[...]
Otherwise, if the corresponding real type of either operand is double, the other
operand is converted, without change of type domain, to a type whose
corresponding real type is double.
So in this case, your size is implicitly converted to double and therefore / performs a floating point division, the result is a double.
The answer depends on
1.Size of integer on your platform (Compiler Specific).
2.The way in which your compiler+processor supports floating point arithmetic. Floating point arithmetic could be emulated by your compiler if your processor doesn't have FPU.
Consider Below Points:
Assuming for your platform double needs more bytes than integer:
Stack Usage will be more in getMean2function.
Assuming your processor don't have FPU: Text(Code) Segment will consume more memory in getMean2 function.
return sum/size;
will be a integer division in getMean1 and it will be a floating point division in getMean2
Note:
As you are neither allocating memory dynamically nor you are having global variables your data segment and heap will be unaffected.
I'm implementing my own decrease-and-conquer method for an.
Here's the program:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
double dncpow(int a, int n)
{
double p = 1.0;
if(n != 0)
{
p = dncpow(a, n / 2);
p = p * p;
if(n % 2)
{
p = p * (double)a;
}
}
return p;
}
int main()
{
int a;
int n;
int a_upper = 10;
int n_upper = 50;
int times = 5;
time_t t;
srand(time(&t));
for(int i = 0; i < times; ++i)
{
a = rand() % a_upper;
n = rand() % n_upper;
printf("a = %d, n = %d\n", a, n);
printf("pow = %.0f\ndnc = %.0f\n\n", pow(a, n), dncpow(a, n));
}
return 0;
}
My code works for small values of a and n, but a mismatch in the output of pow() and dncpow() is observed for inputs such as:
a = 7, n = 39
pow = 909543680129861204865300750663680
dnc = 909543680129861348980488826519552
I'm pretty sure that the algorithm is correct, but dncpow() is giving me wrong answers.
Can someone please help me rectify this? Thanks in advance!
Simple as that, these numbers are too large for what your computer can represent exactly in a single variable. With a floating point type, there's an exponent stored separately and therefore it's still possible to represent a number near the real number, dropping the lowest bits of the mantissa.
Regarding this comment:
I'm getting similar outputs upon replacing 'double' with 'long long'. The latter is supposed to be stored exactly, isn't it?
If you call a function taking double, it won't magically operate on long long instead. Your value is simply converted to double and you'll just get the same result.
Even with a function handling long long (which has 64 bits on nowadays' typical platforms), you can't deal with such large numbers. 64 bits aren't enough to store them. With an unsigned integer type, they will just "wrap around" to 0 on overflow. With a signed integer type, the behavior of overflow is undefined (but still somewhat likely a wrap around). So you'll get some number that has absolutely nothing to do with your expected result. That's arguably worse than the result with a floating point type, that's just not precise.
For exact calculations on large numbers, the only way is to store them in an array (typically of unsigned integers like uintmax_t) and implement all the arithmetics yourself. That's a nice exercise, and a lot of work, especially when performance is of interest (the "naive" arithmetic algorithms are typically very inefficient).
For some real-life program, you won't reinvent the wheel here, as there are libraries for handling large numbers. The arguably best known is libgmp. Read the manuals there and use it.
Is the defacto method for comparing arrays (in C) to use memcmp from string.h?
I want to compare arrays of ints and doubles in my unit tests
I am unsure whether to use something like:
double a[] = {1.0, 2.0, 3.0};
double b[] = {1.0, 2.0, 3.0};
size_t n = 3;
if (! memcmp(a, b, n * sizeof(double)))
/* arrays equal */
or to write a bespoke is_array_equal(a, b, n) type function?
memcmp would do an exact comparison, which is seldom a good idea for floats, and would not follow the rule that NaN != NaN. For sorting, that's fine, but for other purposes, you might to do an approximate comparison such as:
bool dbl_array_eq(double const *x, double const *y, size_t n, double eps)
{
for (size_t i=0; i<n; i++)
if (fabs(x[i] - y[i]) > eps)
return false;
return true;
}
Using memcmp is not generally a good idea. Let's start with the more complex and work down from there.
Though you mentioned int and double, I first want to concentrate on memcmp as a general solution, such as to compare arrays of type:
struct {
char c;
// 1
int i;
// 2
}
The main problem there is that implementations are free to add padding to structures at locations 1 and 2, making a bytewise comparison potentially false even though the important bits match perfectly.
Now down to doubles. You might think this was better as there's no padding there. However there are other problems.
The first is the treatment of NaN values. IEEE754 goes out of its way to ensure that NaN is not equal to any other value, including itself. For example, the code:
#include <stdio.h>
#include <string.h>
int main (void) {
double d1 = 0.0 / 0.0, d2 = d1;
if (d1 == d2)
puts ("Okay");
else
puts ("Bad");
if (memcmp (&d1, &d2, sizeof(double)) == 0)
puts ("Okay");
else puts
("Bad");
return 0;
}
will output
Bad
Okay
illustrating the difference.
The second is the treatment of plus and minus zero. These should be considered equal for the purposes of comparison but, as the bit patterns are different, memcmp will say they are different.
Changing the declaration/initialisation of d1 and d2 in the above code to:
double d1 = 0.0, d2 = -d1;
will make this clear.
So, if structures and doubles are problematic, surely integers are okay. After all, they're always two's complement, yes?
No, actually they're not. ISO mandates one of three encoding schemes for signed integers and the other two (ones' complements and sign/magnitude) suffer from a similar problem as doubles, that fact that both plus and minus zero exist.
So, while they should possibly be considered equal, again the bit patterns are different.
Even for unsigned integers, you have a problem (it's also a problem for signed values as well). ISO states that these representations can have value bits and padding bits, and that the values of the padding bits are unspecified.
So, even for what may seem the simplest case, memcmp can be a bad idea.
Replace memset with memcmp in your code, and it works.
In your case (as the size both arrays arrays are identical and known during compilation) you can even do:
memcmp(a, b, sizeof(a));
The function you're looking for is memcmp, not memset. See the answers to this question for why it might not be a good idea to memcmp an array of doubles though.
memcmp compares two blocks of memory for number of size given
memset is used to initialise buffer with a value for size given
buffers can be compared without using memcmp in following way. same can be changed for different datatypes.
int8_t array_1[] = { 1, 2, 3, 4 }
int8_t array_2[] = { 1, 2, 3, 4 }
uint8_t i;
uint8_t compare_result = 1;
for (i = 0; i < (sizeof(array_1)/sizeof(int8_t); i++)
{
if (array_1[i] != array_2[i])
{
compare_result = 0;
break;
}
}