Comparing two arrays in C, element by element

后端 未结 5 944
孤城傲影
孤城傲影 2020-12-20 20:30

I have been cracking my head at achieving something very simple in C in order to make my one of the programs (not written by me) in our computational physics project more dy

5条回答
  •  爱一瞬间的悲伤
    2020-12-20 21:11

    Your best bet is to rewrite it as a function that returns true or false (1 or 0):

    int compareArrays(double a[], double b[], int n) {
      int ii;
      for(ii = 1; ii <= n; ii++) {
        if (a[ii] != b[ii]) return 0;
        // better:
        // if(fabs(a[ii]-b[ii]) < 1e-10 * (fabs(a[ii]) + fabs(b[ii]))) {
        // with the appropriate tolerance
      }
      return 1;
    }
    

    Note that it is usually bad practice to compare doubles for equality - you are better off comparing their difference, and making sure the absolute value is less than some tolerance.

    Also note you are comparing elements 1 through n - C arrays start at 0 though.

    You would use the above with

    if (compareArrays(a, a_tmp, N)) {
    

    where the value N is #define'd per your question.

    If you want to be "clever" and avoid a loop, you can write the following - it will stop ("short-circuiting") as soon as you reach the right number of comparisons. It is still a Bad Idea to compare doubles for equality but I will leave that for another time (see comment in code above for a solution).

    if(a[1]==a_temp[1] && (2 > N || (a[2]==a_temp[2] && (3 > N || (a[3]==a_temp[3]))))) {
    

    This makes the "and the rest" true as soon as you have compared the right number of terms - so it will stop evaluating terms (as you need). I am not convinced this is either faster, or better code - but it is "dynamic"... You can obviously make this expression as long as you would like; I just wrote the first three terms so you get the idea. I DO NOT RECOMMEND IT.

    As for the comparison of doubles, you might consider replacing

    if(a == b)
    

    with

    if(closeEnough(a, b))
    

    where you define the macro

    #define closeEnough(a, b) (fabs((a)-(b)) < 1e-10 * (fabs(a) + fabs(b)))? 1 : 0
    

    This will make sure that your doubles don't have to be "exactly equal" - depending on how you arrived at them, they will almost never be, and the relative tolerance of 1 part in 10^10 is usually plenty for most practical comparisons.

提交回复
热议问题