"WK" wrote in message <ksrj3v$ilr$1@newscl01ah.mathworks.com>...
> "WK" wrote in message <ksptpo$fos$1@newscl01ah.mathworks.com>...
> > "WK" wrote in message <ksptao$eoq$1@newscl01ah.mathworks.com>...
> > > "James Tursa" wrote in message <ksg3lr$1kp$1@newscl01ah.mathworks.com>...
> > > > "WK" wrote in message <ksfnfv$68s$1@newscl01ah.mathworks.com>...
> > > > > Hi all,
> > > > > I am porting a matlab code to c++ but I find out that there is minor different between the floating number precision in matlab and c++. My matlab code is running in 64bit windows8 as follow
> > > > >
> > > > > data = 3:0.2:3;
> > > > > sprintf('%.30f\n', bin_series)
> > > > >
> > > > > which shows
> > > > >
> > > > > 
> > > > > 3.000000000000000000000000000000
> > > > > 2.799999999999999800000000000000
> > > > > 2.600000000000000100000000000000
> > > > > 2.399999999999999900000000000000
> > > > > 2.200000000000000200000000000000
> > > > > 2.000000000000000000000000000000
> > > > > 1.799999999999999800000000000000
> > > > > 1.599999999999999900000000000000
> > > > > 1.399999999999999900000000000000
> > > > > 1.200000000000000000000000000000
> > > > > 1.000000000000000000000000000000
> > > > > 0.799999999999999820000000000000
> > > > > 0.599999999999999640000000000000
> > > > > 0.399999999999999910000000000000
> > > > > 0.199999999999999730000000000000
> > > > > 0.000000000000000000000000000000
> > > > > 0.199999999999999730000000000000
> > > > > 0.399999999999999910000000000000
> > > > > 0.599999999999999640000000000000
> > > > > 0.799999999999999820000000000000
> > > > > 1.000000000000000000000000000000
> > > > > 1.200000000000000000000000000000
> > > > > 1.399999999999999900000000000000
> > > > > 1.599999999999999900000000000000
> > > > > 1.799999999999999800000000000000
> > > > > 2.000000000000000000000000000000
> > > > > 2.200000000000000200000000000000
> > > > > 2.399999999999999900000000000000
> > > > > 2.600000000000000100000000000000
> > > > > 2.799999999999999800000000000000
> > > > > 3.000000000000000000000000000000
> > > > > 
> > > > > and in C++ (64bit, linux) with compile intel icpc
> > > > >
> > > > > double max=3, min=3, s=0.2;
> > > > > unsigned int num = floor((maxmin)/s)+1;
> > > > > double data[num];
> > > > > for (unsigned int n=0; n<num; n++)
> > > > > {
> > > > > data[n] = min + (double)n*s;
> > > > > cout << setprecision(30) << data[n] << endl;
> > > > > }
> > > > >
> > > > > which shows
> > > > > 
> > > > > 3
> > > > > 2.79999999999999982236431605997
> > > > > 2.60000000000000008881784197001
> > > > > 2.39999999999999991118215802999
> > > > > 2.20000000000000017763568394003
> > > > > 2
> > > > > 1.79999999999999982236431605997
> > > > > 1.59999999999999986677323704498
> > > > > 1.39999999999999991118215802999
> > > > > 1.19999999999999995559107901499
> > > > > 1
> > > > > 0.799999999999999822364316059975
> > > > > 0.59999999999999964472863211995
> > > > > 0.399999999999999911182158029987
> > > > > 0.199999999999999733546474089962
> > > > > 0
> > > > > 0.200000000000000177635683940025
> > > > > 0.40000000000000035527136788005
> > > > > 0.600000000000000088817841970013
> > > > > 0.800000000000000266453525910038
> > > > > 1
> > > > > 1.20000000000000017763568394003
> > > > > 1.40000000000000035527136788005
> > > > > 1.60000000000000053290705182008
> > > > > 1.8000000000000007105427357601
> > > > > 2
> > > > > 2.20000000000000017763568394003
> > > > > 2.40000000000000035527136788005
> > > > > 2.60000000000000053290705182008
> > > > > 2.8000000000000007105427357601
> > > > > 3
> > > > > 
> > > > > It seems that they are the same; however, in my algorithm, I need to use that array to search some boundary. For example, I need to find out all number greater than or eqal to 2.8. But in the c++ code, it returns the correct numbers, but in matlab some number will be miss. In my algorithm, I need to use the return numbers for some calculating a need seed and put it back to the program and iterate the same process for 10 millions time. I find that initially, the results given by matlab and c++ are almost the same, but after long time running, the difference accumulated to a big number. I am not asking the method to improve the precision of the algorithm. I just want to know why the number generated in two language looks that different?
> > > >
> > > > The sprintf function in Windows does not print all of the trailing digits beyond the eps of the number, hence all the zeros at the end. To see how different the results really are you can pass the C++ results back to MATLAB (or viceversa) and then compare them. You can also use this utility on the MATLAB side to print all the digits:
> > > >
> > > > http://www.mathworks.com/matlabcentral/fileexchange/22239num2strexactexactversionofnum2str
> > > >
> > > > James Tursa
> > >
> > > Thank James. I think instead of talking how to render the number. Let's consider the a concrete example due to the floating number representation. I am searching some elements from a matrix under some condition
> > >
> > > bi = 0.2;
> > > range = 4:bi :4;
> > > NUM= length(range);
> > > jn = 1:0.1:1;
> > > sol = 4:4;
> > > [a, b] = meshgrid(jn, sol);
> > > data = a+b;
> > > for k = 1:NUM
> > > lb = (range(k)  0.5*bi);
> > > up = (range(k) + 0.5*bi);
> > > found{k} = find( (data>=lb) & (data<up) );
> > > end
> > >
> > > I write a simple C++ code to create the data matrix (I check that those two data are exact the same), also bi and range are identical in the C++ code to the matlab one. But for searching, I did
> > >
> > > // c++ array with index start at 0
> > > // here I am not showing the full code but just the kernal part
> > > std::vector<int> found[NUM];
> > > for (int k=0; k<NUM; k++)
> > > {
> > > lb = (range[k]  0.5*bi);
> > > up = (range[k] + 0.5*bi);
> > > for (int col=0; col<MAX_COL_NUM; col++)
> > > {
> > > for (int row=0; row<MAX_ROW_NUM; row++)
> > > {
> > > if ((data[row][col]>=lb) && (data[row][col]<up))
> > > {
> > > found[k].push_back(col*9 + row + 1);
> > > }
> > > }
> > > }
> > > }
> > >
> > > By comparing the found, you will see some of the numbers are not matching. I compare the data carefully and see that because when it calculate the bounds (lb and up), matlab and c++ give a very slight different numbers (e.g. for C++ some numbers is supposed to be 1.500000000000002 but matlab will give 1.499999999999999999999) so it won't return the same number as expected. I just wonder why is that? Both c++ and matlab use double precision and why it gives that difference? Is it anything to do with 64bit or not? The matlab I am using is 64bit but the compiler (g++) is running in the server and I don't know if it is 32 bit or 64bit (I think it should be 64bit too).
> > >
> >
> > The matlab code I shown here is to retrieve the indices of the desired elements based on some condition. I will use those elements as input for a nonlinear iterative equation. If it return different elements, since it is nonlinear, very soon the results will diverse. So it is important to get the same number. I just don't know why they will give the different number if the precision is the same.
>
> I download the num2exact package and use it to show all digits of the results generated by matlab. I shows all numbers in range and jn vectors and use loop to create that in c++. It shows the following number
>
> 1) range
> MATLAB:
> 4
> 3.79999999999999982236431605997495353221893310546875
> 3.600000000000000088817841970012523233890533447265625
> 3.399999999999999911182158029987476766109466552734375
> 3.20000000000000017763568394002504646778106689453125
> 3
> 2.79999999999999982236431605997495353221893310546875
> 2.5999999999999996447286321199499070644378662109375
> 2.399999999999999911182158029987476766109466552734375
> 2.20000000000000017763568394002504646778106689453125
> 2
> 1.79999999999999982236431605997495353221893310546875
> 1.5999999999999996447286321199499070644378662109375
> 1.399999999999999911182158029987476766109466552734375
> 1.199999999999999733546474089962430298328399658203125
> 1
> 0.79999999999999982236431605997495353221893310546875
> 0.5999999999999996447286321199499070644378662109375
> 0.399999999999999911182158029987476766109466552734375
> 0.199999999999999733546474089962430298328399658203125
> 0
> 0.199999999999999733546474089962430298328399658203125
> 0.399999999999999911182158029987476766109466552734375
> 0.5999999999999996447286321199499070644378662109375
> 0.79999999999999982236431605997495353221893310546875
> 1
> 1.199999999999999733546474089962430298328399658203125
> 1.399999999999999911182158029987476766109466552734375
> 1.5999999999999996447286321199499070644378662109375
> 1.79999999999999982236431605997495353221893310546875
> 2
> 2.20000000000000017763568394002504646778106689453125
> 2.399999999999999911182158029987476766109466552734375
> 2.5999999999999996447286321199499070644378662109375
> 2.79999999999999982236431605997495353221893310546875
> 3
> 3.20000000000000017763568394002504646778106689453125
> 3.399999999999999911182158029987476766109466552734375
> 3.600000000000000088817841970012523233890533447265625
> 3.79999999999999982236431605997495353221893310546875
> 4
>
> CPP:
> 4
> 3.79999999999999982236431605997495353221893310546875
> 3.600000000000000088817841970012523233890533447265625
> 3.399999999999999911182158029987476766109466552734375
> 3.20000000000000017763568394002504646778106689453125
> 3
> 2.79999999999999982236431605997495353221893310546875
> 2.5999999999999996447286321199499070644378662109375
> 2.399999999999999911182158029987476766109466552734375
> 2.20000000000000017763568394002504646778106689453125
> 2
> 1.79999999999999982236431605997495353221893310546875
> 1.5999999999999996447286321199499070644378662109375
> 1.399999999999999911182158029987476766109466552734375
> 1.199999999999999733546474089962430298328399658203125
> 1
> 0.79999999999999982236431605997495353221893310546875
> 0.5999999999999996447286321199499070644378662109375
> 0.399999999999999911182158029987476766109466552734375
> 0.199999999999999733546474089962430298328399658203125
> 0
> 0.20000000000000017763568394002504646778106689453125
> 0.4000000000000003552713678800500929355621337890625
> 0.60000000000000053290705182007513940334320068359375
> 0.800000000000000710542735760100185871124267578125
> 1
> 1.20000000000000017763568394002504646778106689453125
> 1.4000000000000003552713678800500929355621337890625
> 1.60000000000000053290705182007513940334320068359375
> 1.800000000000000710542735760100185871124267578125
> 2
> 2.20000000000000017763568394002504646778106689453125
> 2.4000000000000003552713678800500929355621337890625
> 2.60000000000000053290705182007513940334320068359375
> 2.800000000000000710542735760100185871124267578125
> 3
> 3.20000000000000017763568394002504646778106689453125
> 3.4000000000000003552713678800500929355621337890625
> 3.60000000000000053290705182007513940334320068359375
> 3.800000000000000710542735760100185871124267578125
> 4
>
> 2) and for jn vector:
> MATLAB:
> 1
> 0.90000000000000002220446049250313080847263336181640625
> 0.8000000000000000444089209850062616169452667236328125
> 0.6999999999999999555910790149937383830547332763671875
> 0.59999999999999997779553950749686919152736663818359375
> 0.5
> 0.399999999999999911182158029987476766109466552734375
> 0.29999999999999993338661852249060757458209991455078125
> 0.1999999999999999555910790149937383830547332763671875
> 9.999999999999997779553950749686919152736663818359375e2
> 0
> 9.999999999999997779553950749686919152736663818359375e2
> 0.1999999999999999555910790149937383830547332763671875
> 0.29999999999999993338661852249060757458209991455078125
> 0.399999999999999911182158029987476766109466552734375
> 0.5
> 0.59999999999999997779553950749686919152736663818359375
> 0.6999999999999999555910790149937383830547332763671875
> 0.8000000000000000444089209850062616169452667236328125
> 0.90000000000000002220446049250313080847263336181640625
> 1
>
> CPP:
> 1
> 0.90000000000000002220446049250313080847263336181640625
> 0.8000000000000000444089209850062616169452667236328125
> 0.6999999999999999555910790149937383830547332763671875
> 0.59999999999999997779553950749686919152736663818359375
> 0.5
> 0.399999999999999911182158029987476766109466552734375
> 0.29999999999999993338661852249060757458209991455078125
> 0.1999999999999999555910790149937383830547332763671875
> 0.09999999999999997779553950749686919152736663818359375
> 0
> 0.100000000000000088817841970012523233890533447265625
> 0.20000000000000017763568394002504646778106689453125
> 0.3000000000000000444089209850062616169452667236328125
> 0.4000000000000001332267629550187848508358001708984375
> 0.5
> 0.600000000000000088817841970012523233890533447265625
> 0.70000000000000017763568394002504646778106689453125
> 0.8000000000000000444089209850062616169452667236328125
> 0.9000000000000001332267629550187848508358001708984375
> 1
>
>
> Interestingly, all negative numbers matching pretty well but the positive number not that good. I check that both matlab and my intel c++ compile use ANSI/IEEE 754 standard for floating point and both use 64bits for double precision, just don't understand why they will render such different numbers.
Um ... since the negative numbers match up, I modify my c++ code to generate the vector in this way
for (int k=0; k<NUM; k++)
{
range[k] = 4 + (double)k*bi;
if (k>=round(NUM/2)) range[k] = range[2*(int)round(NUM/2)  k];
}
With this trick, the results match up well. But still don't know why I have to do this way.
