Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 应用于阵列时使阵列积分的最小正乘数_C++_C_Algorithm_Boost_Eigen - Fatal编程技术网

C++ 应用于阵列时使阵列积分的最小正乘数

C++ 应用于阵列时使阵列积分的最小正乘数,c++,c,algorithm,boost,eigen,C++,C,Algorithm,Boost,Eigen,给定一个由n非负元素组成的数组,C/C++库中是否有一个函数返回最小的正乘数,当应用于数组的每个元素时返回一个整数 例如,如果n=2的数组是1.66667,2.33333,则乘法器将是3。因为当我们用3乘以数组中的每个元素时,我们得到了5,7,两者都是整数 如果数组为8,10,则乘数为0.5。这将给我们提供4,5 (1) 在诸如boost、eigen等著名的库中,是否有有效的函数来实现这一点 (2) 如果库中没有可用的数据,那么计算倍数的有效算法是什么?与您指定的否不同。问题是十进制值1.666

给定一个由
n
非负元素组成的数组,C/C++库中是否有一个函数返回最小的正乘数,当应用于数组的每个元素时返回一个整数

例如,如果
n=2
的数组是
1.66667,2.33333
,则乘法器将是3。因为当我们用3乘以数组中的每个元素时,我们得到了
5,7
,两者都是整数

如果数组为
8,10
,则乘数为0.5。这将给我们提供
4,5

(1) 在诸如
boost
eigen
等著名的库中,是否有有效的函数来实现这一点


(2) 如果库中没有可用的数据,那么计算倍数的有效算法是什么?

与您指定的否不同。问题是十进制值
1.66667
2.33333
没有这样的乘数:您假设的近似值来自,从数学的角度来看,这是一种任意的舍入策略

还有一些浮点属性需要考虑,因此可以使用
double
float
排除任何问题

在这里,您最好使用一个分数类来表示数字。然后,任何普通的乘法器都会因为一些简单的数学运算而退出


请参见

在一般情况下,您的问题没有很好的解决方案,因为值是以浮点格式存储的,该格式具有有限精度,并且只能精确存储分母为2次幂的分数。例如,
0.1*10
在您的平台上可能不是一个完整的值

如果从整数量计算数组中的值,则应将它们表示为具有适当大小整数对的标准化分数,并计算其分母的最小公倍数


如果需要问题的近似解决方案,可以指定epsilon的值,然后手动设计解决方案。我想不出任何库函数可以满足这一需求,但暴力解决方案很容易编写:

unsigned long long ullgcd(unsigned long long a, unsigned long long b) {
     /* compute the greatest common divisor using Euclid's elegant method */
     if (a < b)
         return ullgcd(b, a);
     else
     if (b == 0)
         return a;
     else
         return ullgcd(b, a % b);
}

double least_multiple(double *a, size_t n, double epsilon) {
    for (double mult = 1;; mult += 1) {
        size_t i;
        unsigned long long div = 0;
        for (i = 0; i < n; i++) {
            double d = fabs(a[i] * mult);
            unsigned long long v = round(d);
            if (fabs(v - d) > epsilon)
                break;
            div = ullgcd(v, div);
        }
        if (i == n)
            break;
    }
    /* mult is the smallest non zero integer that fits your goal.
       the smallest multiplier is obtained by dividing it 
       by the greatest common divisor of the resulting integer array.
    */
    return mult / div;
}
无符号长ullgcd(无符号长a,无符号长b){
/*用欧几里德的优雅方法计算最大公约数*/
if(aε)
打破
div=ullgcd(v,div);
}
如果(i==n)
打破
}
/*mult是符合您的目标的最小非零整数。
最小的乘数是除以它得到的
由结果整数数组的最大公约数。
*/
返回mult/div;
}

看一下Rosetta代码,因为我不熟悉C,所以我将C代码转换成Python(尽管我认为Python可能有一些相关的库),并添加了一些可以轻松适应C的函数。如果分数转换中的分母都是
1.0
,我们除以数字列表中的最大公约数。否则,我们返回唯一分母的乘积

导入数学
进口经营者
def f(arr):
ε=4
分数=[arr中i的大鼠_近似值(i,16**epsilon)]
#分数转换中的分母均为1.0
如果总和([denom表示分数中的(num,denom)]==len(分数):
返回1.0/gcd_/u(分数中的[num代表(num,denom)])
其他:
#否则,返回唯一分母的乘积
返回reduce(operator.mul,set([denom for(num,denom)的分数]),1)
def gcd(a、b):
如果a
输出:

f([8,10])
=> 0.5
f([1.66667,2.33333])
=> 3.0

2.33333*3
6.99999
,而不是
7
。不,没有这样的函数。你需要自己写。似乎是个X-Y问题……我认为至少对于浮点型来说,这是不可能的,因为浮点型的对象不能准确地表示实数。也许您可以使用有理数类型,并基于该类型实现此函数。浮点数可以被视为整数*2^指数。因此,如果您的乘法器应该是整数,那么您正在寻找2的幂。很遗憾,有些数组元素将是另一个返回普通浮点数的程序的输出。你知道boost是否能用分数有效地逼近任意的双精度值吗?@Tryer:这样的函数太“基于意见”或“依赖用户”,所以不知道。你必须自己构建那个位,这取决于你准备承受的容忍度。从rational类开始,用一些有趣的方法构建一个适用于y的构造方法