C 如何实现两个双浮点数组的集合并集,但允许误差为1微秒

C 如何实现两个双浮点数组的集合并集,但允许误差为1微秒,c,C,我试图计算包含双浮点值的两个数组的并集(它们是以毫秒为单位的时间戳),但我需要允许+/-1微秒的公差 例如: 考虑下面两个不同列表(或数组)的两个值: 在上述两个0.001微秒的数字之间有一个小的增量。因此,当我创建新的联合列表时,它们不应该都显示为唯一的,而应该被计算为一个项目,并且应该只包含第一个列表中的项目(在本例中,参考1,以059.841结尾) 以上类型的更多示例: [ref 21 : 1114974794.562] [dut 18 : 1114974794.560] [ref

我试图计算包含双浮点值的两个数组的并集(它们是以毫秒为单位的时间戳),但我需要允许+/-1微秒的公差

例如: 考虑下面两个不同列表(或数组)的两个值:

在上述两个0.001微秒的数字之间有一个小的增量。因此,当我创建新的联合列表时,它们不应该都显示为唯一的,而应该被计算为一个项目,并且应该只包含第一个列表中的项目(在本例中,参考1,以059.841结尾)

以上类型的更多示例:

[ref  21 : 1114974794.562] [dut  18 : 1114974794.560]
[ref  22 : 1114974827.840] [dut  19 : 1114974827.840]
[ref  23 : 1114974861.121] [dut  20 : 1114974861.120]
应将上述所有内容视为一个,因此联合列表应仅包含第一个列表中的一项:联合列表将包含
ref
数组中的所有三项,而
dut
数组中没有任何一项

现在考虑例子:

[ref   8 : 1114974328.641] [dut   8 : 1114974361.921]
在这里,上面列表中两个值之间的增量对于微秒来说非常重要,它小于.01微秒,因此应被视为新联合列表中的两个唯一项

下面是另一个类似于上述示例的示例:

[ref  13 : 1114974495.041] [dut  12 : 1114974528.321]
[ref  26 : 1114974960.960] [dut  23 : 1114975027.520]
[ref  27 : 1114974994.240] [dut  23 : 1114975027.780]
在新的工会名单中,他们都应该被认为是独一无二的

你能帮我吗

我制作了一个子程序,允许我检测如下公差:

unsigned int AlmostEqualRelative(double A, double B, double maxRelDiff){
    double diff = fabs(A - B);      // Calculate the difference.
    // 
    if (diff < maxRelDiff) {
        //printf("\n page hit    [ref: %10.3f] [dut: %10.3f]",A,B);
        return 1;
    }
        //printf("\n page miss   [ref: %10.3f] [dut: %10.3f]",A,B);
    return 0;

}
unsigned int-AlmostEqualRelative(双A、双B、双maxRelDiff){
double diff=fabs(A-B);//计算差值。
// 
if(diff

我将maxRelDiff设为.02。

假设两个列表的大小相同:

unsigned int // size of output array
union_list(const double *list1, // first list
           const double *list2, // second list
           double* ulist,       // output list
           unsigned int size)   // size of input list
{
    unsigned int i = 0u, j = 0u ;
    for(; i < size; ++i, ++j)
    {
        result = is_near(list1[i], list[2]);
        if (result == 1)
        {
            ulist[j] = list1[i] ;
        }
        else
        { 
            ulist[j] = list1[i] ;
            j += 1 ;
            ulist[j] = list2[i];
        }
    }
    return j ;
}

您可以这样做:

unsigned int AlmostEqualRelative(double A, double B, double maxRelDiff){
    double diff = fabs(A - B);      // Calculate the difference.
    // 
    if (diff < maxRelDiff) {
        //printf("\n page hit    [ref: %10.3f] [dut: %10.3f]",A,B);
        return 1;
    }
        //printf("\n page miss   [ref: %10.3f] [dut: %10.3f]",A,B);
    return 0;

}
首先,复制
ref
数组的
foo
foo
必须足够大,以存储
ref
dut
数组的元素,因为它们可能相互排斥

len=0;    
for(i=0;i<length_ref;i++)
        foo[len++]=ref[i];

一种方法是将
AlmostEqualRelative
函数重写为符合原型
int(*compar)(const void*,const void*)
(即根据参数的相对顺序返回负、零或正)。这使得它适合传递给
qsort
(3)函数

这样,您就可以将两个起始数组连接起来,
qsort

这需要一点簿记和一点额外的空间,但它使用现有的代码(即,
qsort
),并且除非您的数组太大以至于额外的空间成为一个问题,否则这可能是找到解决方案的最直接途径


也就是说,这在道德上等同于通过执行
catf1 f2 | sort | uniq
获得两个文件的集合并集,但是在
uniq
比较中有一些模糊性。

Ok,
union
是C语言中的一种特殊数据结构,令人困惑。你的问题是指两个集合的并集,对吗?我想你应该澄清一下。我不太清楚你在处理什么数组。您是否有两个双精度阵列,带有计数器以指示它们的满度?或者你在使用某种链表?不过,使用
AlmostEqualRelative(…)
函数,您肯定走在了正确的轨道上。尽管您可以将其设置为
bool
,而不是无符号int,这只是为了提高效率和符合约定
unsigned int
s也可以。如果您知道如何使用相等运算符编写常规的“union”运算,您可以使用
AlmostEqual
运算符以同样的方式重写它。@Dan:是的,我有两个双精度数组。一个名为ref的数组和一个名为dut的数组,其中包含数量不等的双浮点数。不幸的是,我的两个列表的大小不一样:(Hmmm)通过为
qsort()重新定义
=
,这会导致
A==B
B==C
,但可能
A!=C
。我认为这可能会愚弄
qsort()
太多,导致“排序”数组未完全排序。“然后处理结果数组”在查找“单个示例”时变得模糊嗯,非常正确。事实上,我认为这个问题根本上是不适定的,或者至少是一个比最初出现的更复杂的问题。考虑一个数字序列(0,0.1,0.2,0.3,…,10)。这些都是完全排序的,并且每个这些都等于它的继承者,即0.15的容忍度。(OP想要的“相等”的定义,更接近于数学的概念”,但是显然0和10不应该被看作是等价的。这个问题并没有一个简单的答案。
len=0;    
for(i=0;i<length_ref;i++)
        foo[len++]=ref[i];
for(i=0;i<length_dut;i++)
{
    flag=1;
    for(j=0;j<length_ref;j++)
        if(AlmostEqualRelative(dut[i],ref[j],MAXRELDIFF))
        {
            flag=0;
            break;
        }
    if(flag)
        foo[len++]=dut[i];
}