NO

Author Topic: Assignment and Ternary Operator  (Read 18903 times)

eheredia2511

  • Guest
Assignment and Ternary Operator
« on: September 14, 2010, 11:38:23 PM »
Hi for all!

I have a problem with the ternary operator and assignment, as shown below (see the coments):

Code: [Select]
#include <stdio.h>
#include <stdlib.h>

#define MIN(x,y) ( (x<y) ? (x) : (y) )
#define MAX(x,y) ( (x>y) ? (x) : (y) )

#define NELEMS 50

double vetor[NELEMS];

int main(void)
{
double min=0.0, max=0.0, minx=0.0, maxx=0.0;

for(int i=0;i<NELEMS;i++)
vetor[i]=(double) (rand())/RAND_MAX*100;

min=vetor[0];
max=vetor[0];

double x = 0.0;

for(int i=1;i<NELEMS;i++) {

x = vetor[i];

// CASE 1: this code doesn´t work *********************
// min=MIN(min, x);
// max=MAX(max, x);

// Case 2: neither this *******************************
            min = (min > x ? x : min);
            max = (max < x ? x : max);

// Case 3: but this works *****************************
// if( min > x ) min = x;
// if( max < x ) max = x;

}

printf("\n\n");
printf("MIN =%8.4f MAX =%8.4f\n",min,max);
             printf("\n\n");

return EXIT_SUCCESS;
}

Cases 1 and 2 don´t work. Case 3 always works!

Why?

Thanks in advance...






« Last Edit: September 15, 2010, 12:03:07 AM by eheredia2511 »

CommonTater

  • Guest
Re: Assignment and Ternary Operator
« Reply #1 on: September 15, 2010, 03:01:31 AM »
It's in the construction of your  ? conditional:

Where the goal is to return the lesser of two numbers try it as:

min = (x < y) ?  x : y;

If the condition  (x < y) is true ... you get the first value after the ?  If it is false you get the second.

« Last Edit: September 15, 2010, 03:05:36 AM by CommonTater »

eheredia2511

  • Guest
Re: Assignment and Ternary Operator
« Reply #2 on: September 15, 2010, 03:28:14 AM »
Thanks,

but the problem persists. See my code (case 1).

[]s


CommonTater

  • Guest
Re: Assignment and Ternary Operator
« Reply #3 on: September 15, 2010, 04:28:46 AM »
Ok, maybe I'm not getting what the problem is. 

I corrected the bracketing in your "case 2" example and it ran perfectly, giving a string of random numbers showing low and high values...  I uncommented each case in turn and ran the program again and they all work. Mind you they were not terribly random... but it did work.

What is the expected output?


Offline Robert

  • Member
  • *
  • Posts: 245
Re: Assignment and Ternary Operator
« Reply #4 on: September 15, 2010, 04:44:00 AM »
Ok, maybe I'm not getting what the problem is. 

I corrected the bracketing in your "case 2" example and it ran perfectly, giving a string of random numbers showing low and high values...  I uncommented each case in turn and ran the program again and they all work. Mind you they were not terribly random... but it did work.

What is the expected output?



For examples 1, 2 and 3 the Microsoft C/C++ compiled snippet prints

MIN =  0.1251 MAX = 98.8525

For examples 1 and 2 the Pelle's  C compiled snippet prints

MIN = 12.5836 MAX = 30.7502

For example 3 the Pelle's  C compiled snippet prints

MIN =  0.1805 MAX = 97.7357

None of the Pelle's C compiled values match the Microsoft compiled outputs.

Robert Wishlaw
 

CommonTater

  • Guest
Re: Assignment and Ternary Operator
« Reply #5 on: September 15, 2010, 04:48:32 AM »
You are, afterall, working with random numbers.  If you preload a set sequence of numbers into your array and scan it, I'm pretty sure the outputs would be identical.

Offline Robert

  • Member
  • *
  • Posts: 245
Re: Assignment and Ternary Operator
« Reply #6 on: September 15, 2010, 05:14:07 AM »
You are, afterall, working with random numbers.  If you preload a set sequence of numbers into your array and scan it, I'm pretty sure the outputs would be identical.


For both, the Microsoft C/C++ and MinGW g++ compilers, examples 1, 2, and 3 print

MIN =  0.1251 MAX = 98.8525

Robert Wishlaw

Offline Robert

  • Member
  • *
  • Posts: 245
Re: Assignment and Ternary Operator
« Reply #7 on: September 15, 2010, 05:25:30 AM »
You are, afterall, working with random numbers.  If you preload a set sequence of numbers into your array and scan it, I'm pretty sure the outputs would be identical.


For both, the Microsoft C/C++ and MinGW g++ compilers, examples 1, 2, and 3 print

MIN =  0.1251 MAX = 98.8525

Robert Wishlaw

For the Pelle's C 5.01 compiled snippet the output for examples 1, 2, and 3 is

MIN =  0.1805 MAX = 97.7357

Robert Wishlaw


CommonTater

  • Guest
Re: Assignment and Ternary Operator
« Reply #8 on: September 15, 2010, 06:15:20 AM »
Now ... instead of preloading the array with random numbers, put in a known sequence of pre-set numbers so that you are certain you have the same starting sequence on all compilers... with the same input you should get the same output.

What you are probably seeing is a difference between random number generators... and yes it does happen.  There is no standard method of creating random numbers.  Each compiler has it's own way of doing things.  In fact, if you add a call to srand(time); before your first call to rand() you'll get a different sequence every time, even from the same compiler.

Don't trip over that... it's normal and expected behavior. Random numbers are a deliberate unknown.


« Last Edit: September 15, 2010, 06:16:52 AM by CommonTater »

Offline Robert

  • Member
  • *
  • Posts: 245
Re: Assignment and Ternary Operator
« Reply #9 on: September 15, 2010, 07:00:17 AM »
Now ... instead of preloading the array with random numbers, put in a known sequence of pre-set numbers so that you are certain you have the same starting sequence on all compilers... with the same input you should get the same output.

What you are probably seeing is a difference between random number generators... and yes it does happen.  There is no standard method of creating random numbers.  Each compiler has it's own way of doing things.  In fact, if you add a call to srand(time); before your first call to rand() you'll get a different sequence every time, even from the same compiler.

Don't trip over that... it's normal and expected behavior. Random numbers are a deliberate unknown.

Yes, that is a good comment to make but the problem that eheredia2511 started this thread with regarding Pelle's 6.0 erratic output still remains. The Microsoft, MinGW and Pelle's C 5.0.1 compilers produce a consistent output, Pelle's C version 6.0 does not. The output from the three cases should be the same although, as you have commented, it may vary between compilers.

Robert Wishlaw
« Last Edit: September 15, 2010, 07:02:59 AM by Robert »

CommonTater

  • Guest
Re: Assignment and Ternary Operator
« Reply #10 on: September 15, 2010, 09:13:23 AM »
Hi Robert... It still looks to me like the difference is bound to happen because he is testing with random numbers.  Again the same sequence of seed values applied every time in all three compilers should bring the same result and I don't see why it wouldn't.

If he were to replace:
Code: [Select]
for(int i=0;i<NELEMS;i++)
vetor[i]=(double) (rand())/RAND_MAX*100;
with something like...
Code: [Select]
for int (i = 0; i < NELEMS; i++)
vetor[i] = (double) i * 3.55;
He would now have a known initializer and the answers from all three compilers would (should) be exactly the same...

 What I'msaying is that the differences he's seeing are most likely due to the use of random number sequences and not due to different processing of his MIN and MAX macros (etc).


« Last Edit: September 15, 2010, 09:27:08 AM by CommonTater »

JohnF

  • Guest
Re: Assignment and Ternary Operator
« Reply #11 on: September 15, 2010, 10:06:40 AM »
It seems to work ok in version 5 of PellesC but not in version 6.

This should be a bug report.

John

CommonTater

  • Guest
Re: Assignment and Ternary Operator
« Reply #12 on: September 15, 2010, 10:22:57 AM »
Hi John...
I'm using 6.0 here and it worked for me...

the macros ran first try.
the second option worked once I fixed the brackets
the third option worked first try.


« Last Edit: September 15, 2010, 10:25:19 AM by CommonTater »

JohnF

  • Guest
Re: Assignment and Ternary Operator
« Reply #13 on: September 15, 2010, 10:49:44 AM »
Using your alteration filling in the vector I get

min = 0.0000 max = 3.5500

John



Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Assignment and Ternary Operator
« Reply #14 on: September 15, 2010, 03:33:30 PM »
I modified the test program as below and made checks using as standard C runtime library the Pelles POCRT.lib and MSVCRT.lib from M$.
If you have coincident values using MingW maybe you are linking with M$ runtime library, so de facto you are using the same routine.
The compiler used is PellesC V6.00 RC#3.
Code: [Select]
#include <stdio.h>
#include <stdlib.h>

#define MIN(x,y) ( (x<y) ? (x) : (y) )
#define MAX(x,y) ( (x>y) ? (x) : (y) )

#define NELEMS 50

double vector[NELEMS];

int main(void)
{
double min1,min2,min3, max1,max2,max3, minx=0.0, maxx=0.0;

for(int i=0;i<NELEMS;i++)
vector[i]=(double) (rand())/RAND_MAX*100;
//vector[i] = (double) i * 3.55;


min1=min2=min3=vector[0];
max1=max2=max3=vector[0];

double x = 0.0;

for(int i=1;i<NELEMS;i++) {

x = vector[i];

// CASE 1: this code doesn´t work *********************
min1=MIN(min1, x);
max1=MAX(max1, x);

// Case 2: neither this *******************************
    min2 = (min2 > x ? x : min2);
    max2 = (max2 < x ? x : max2);

// Case 3: but this works *****************************
if( min3 > x ) min3 = x;
if( max3 < x ) max3 = x;

}

printf("\n\n");
printf("Case 1 -> MIN =%8.4f MAX =%8.4f\n",min1,max1);
printf("Case 2 -> MIN =%8.4f MAX =%8.4f\n",min2,max2);
printf("Case 3 -> MIN =%8.4f MAX =%8.4f\n",min3,max3);
             printf("\n\n");

return EXIT_SUCCESS;
}
But I haven't seen any bug.

The values changes depending on the pseudodistribution of the random function, which of course have not the same implementation for all libraries.
You can see it enlarging the array, i.e NELEMS=5000. The larger you make it, higher is the probability that you will cover the whole range of pseudorandom values.
If you use the linear filling proposed by CommonTater you will get the correct answer:
MIN=0.00 (i=0)*3.55
MAX=173.95 (i=49)*3.55
The bracketing have no influence because the expression is solved based on operators priorities.
John I don't understand why you get that strange result. Please try my code.
Eheredia2511 what you exactly mean for cases 1 & 2 not working? compilation error, zero values or simply not coincident with M$? In last case I already explained the reason.
« Last Edit: September 15, 2010, 04:08:50 PM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide