Community
cancel
Showing results for 
Search instead for 
Did you mean: 
www_q_
Beginner
79 Views

Possible bugs?

case 1: 

if (!((a>b&&c>d)||(a<b&&c<d)))


case 2: 

if ((a>b&&c<d)||(a<b&&c>d)||(a==b)||(c==d))

Where, a, b, c, d are some non-NaN random double variables (between -1 and 1 in my case, I also test them with random variables generated by ippsGaussRand_Direct_64f() functions and the results for case 1 are also incorrect).

Anyone can see the above 2 experssions are of the same thing, but the complier (ICC 13.0, x86-64, highest level of optimization, Windows-64 OS) only return correct results for the second experssion, is this a bug here?

0 Kudos
6 Replies
jimdempseyatthecove
Black Belt
79 Views

These are not equivilent expressions. Build a truth table [cpp] (!((a > b && c > d)||(a < b && c < d))) a b c d ! 1 1 1 1 !((F...)||(F...)) T 1 2 1 1 !((F...)||(F...)) T 2 1 1 1 !((T&&F)||(F...)) T 1 1 1 2 !((F...)||(F...)) T 1 2 1 2 !((F...)||(T&&T)) F 2 1 1 2 !((T&&F)||(F...)) T 1 1 2 1 !((F...)||(F...)) T 1 2 2 1 !((F...)||(T&&F)) T 2 1 2 1 !((T&&T)||(...)) F ((a > b&&c < d)||(a < b&&c > d)||(a==b)||(c==d)) a b c d 1 1 1 1 (F...)||(F...)||(T)||(.) T 1 2 1 1 (F...)||(T&&F)||(T)||(.) T 2 1 1 1 (T&&F)||(F...)||(T)||(.) T 1 1 1 2 (F...)||(F...)||(T)||(.) T 1 2 1 2 (F...)||(T&&F)||(F)||(F) F 2 1 1 2 (T&&F)||(F...)||(F)||(F) F 1 1 2 1 (F...)||(F...)||(T)||(.) T 1 2 2 1 (F...)||(T&&T)||(.)||(.) T 2 1 2 1 (T&&F)||(F...)||(F)||(F) F [/cpp] Jim Dempsey
jimdempseyatthecove
Black Belt
79 Views

I may need to retract the above hand written truth table. Subsiquent to the post I wrote a simple program to illustrate, the program produces the same results for the two expressions. I suspect the hand written table is incorrect.... Yes, the 2 1 1 2 was incorrect for the second table. [cpp] int _tmain(int argc, _TCHAR* argv[]) { int ia,ib,ic,id; double a,b,c,d; for(ia = 1; ia <= 2; ++ia) { a = ia; for(ib = 1; ib <= 2; ++ib) { b = ib; for(ic = 1; ic <= 2; ++ic) { c = ic; for(id = 1; id <= 2; ++id) { d = id; printf("%lf %lf %lf %lf %d %d\n", a, b, c, d, (!((a > b && c>d)||(a < b && c < d))), ((a > b&&c < d)||(a < b&&c > d)||(a==b)||(c==d))); } } } } return 0; } [/cpp] Perhaps at issue is an IPO thing (Inter-Procedural Optimization). Can you make a reproducer? Jim Dempsey
mecej4
Black Belt
79 Views

Jim, There is just a simple error in line-36 of your truth table. (T&&F) should have been (T&&T) because c (=1) is less than d (=2).
SergeyKostrov
Valued Contributor II
79 Views

>>...Where, a, b, c, d are some non-NaN random double variables (between -1 and 1 in my case... I agree that a complete test-case that uses IPP ippsGaussRand_Direct_64f to generate a, b, c and d values would help. >>...highest level of optimization... Could you post the C++ compiler command line options?
www_q_
Beginner
79 Views

The settings are: /GS /Qopenmp /Qrestrict /W1 /QxAVX /Zi /O3 /fp:precise /Quse-intel-optimized-headers
mecej4
Black Belt
79 Views

From a logical/mathematical perspective, running a test (by hand or using a short program, as Jim showed), but with one set (or many sets) of values for the real variables a,b,c,d, is sufficient to prove non-equivalence. Such a test is not sufficient to prove equivalence, given the possibility that both candidate logical expressions may yield different values for different combinations of a, b, c, d. By applying Boolean Algebra rules, I come to the same conclusion as the OP, that is, the two expressions are equivalent. The next question is: Does the Intel C compiler show a bug in this regard? I ran the following test program, which makes the four real variables cover the range (-5,+5), taking steps that are slightly larger than 0.1. [cpp] #include <stdio.h> main(){ float a,b,c,d; int r1,r2; for(a=-5.0; a<=5.0; a+=0.111) for(b=-5.0; b<=5.0; b+=0.112) for(c=-5.0; c<=5.0; c+=0.113) for(d=-5.0; d<=5.0; d+=0.114){ r1 = !((a > b && c > d)||(a < b && c < d)); r2 = (a > b && c < d) || (a < b && c > d) || (a==b) || (c==d); if(r1-r2)printf("%7.1e %7.1e %7.1e %7.1e %e %e\\n",a,b,c,d,r1,r2); } } [/cpp] Running this program showed no error after compiling with the 13.0.1.119 X64 compiler with (i) options /O3 /QxAVX and (ii) the options shown above by the OP. Here is another test program, which calls IPP to generate one million sets of normally distributed values of a, b, c, d , with mean = 0 and standard-deviation = 1. [cpp] #include <stdio.h> #include <ipp.h> #define NSAMP 1000000 #define LEN 4*NSAMP Ipp32f samp[LEN]; main(){ float a,b,c,d; int r1,r2,i,len=LEN; IppsRandGaussState_32f *pRandGaussState; ippsRandGaussInitAlloc_32f(&pRandGaussState, 0.0, 1.0, 162903); ippsRandGauss_32f(samp, len, pRandGaussState); for(i=0; i<NSAMP; i++){ a=samp[4*i]; b=samp[4*i+1]; c=samp[4*i+2]; d=samp[4*i+3]; r2 = !((a > b && c > d)||(a < b && c < d)); r1 = (a > b && c < d) || (a < b && c > d) || (a==b) || (c==d); if(r1-r2)printf("%7.1e %7.1e %7.1e %7.1e %e %e\\n",a,b,c,d,r1,r2); if((i+1)%10000==0)printf("%8d",(i+1)/10000); } } [/cpp] As I stated earlier, my test programs are inconclusive: no error was found for the several sets of values of a, b, c, d   tried in them. We need the OP to present values of a,b,c,d   for which an error is encountered.
Reply