Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.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++_Algorithm_Rounding_Date Range - Fatal编程技术网

C++ 如何检查一个范围内的值是否是另一个范围内值的倍数?

C++ 如何检查一个范围内的值是否是另一个范围内值的倍数?,c++,algorithm,rounding,date-range,C++,Algorithm,Rounding,Date Range,假设我有一个系统,将8820个值分配到96个值中,使用银行家圆(称它们为pulse)进行四舍五入。公式是: pulse = BankerRound(8820 * i/96), with i[0,96[ 因此,这是脉冲列表: 0 92 184 276 368 459 551 643 735 827 919 1011 1102 1194 1286 1378 1470 1562 1654 1746 1838 1929 2021 2113 2205 2297 2389 2481 2572 2664 2

假设我有一个系统,将8820个值分配到96个值中,使用银行家圆(称它们为
pulse
)进行四舍五入。公式是:

pulse = BankerRound(8820 * i/96), with i[0,96[
因此,这是脉冲列表:

0
92
184
276
368
459
551
643
735
827
919
1011
1102
1194
1286
1378
1470
1562
1654
1746
1838
1929
2021
2113
2205
2297
2389
2481
2572
2664
2756
2848
2940
3032
3124
3216
3308
3399
3491
3583
3675
3767
3859
3951
4042
4134
4226
4318
4410
4502
4594
4686
4778
4869
4961
5053
5145
5237
5329
5421
5512
5604
5696
5788
5880
5972
6064
6156
6248
6339
6431
6523
6615
6707
6799
6891
6982
7074
7166
7258
7350
7442
7534
7626
7718
7809
7901
7993
8085
8177
8269
8361
8452
8544
8636
8728
现在,假设系统没有直接向我发送这些脉冲。相反,它在8820发送这些脉冲(称它们为
滴答声
):

我得到的记号列表将变为:

0
0.010430839
0.020861678
0.031292517
0.041723356
0.052040816
0.062471655
0.072902494
0.083333333
0.093764172
0.104195011
0.11462585
0.124943311
0.13537415
0.145804989
0.156235828
0.166666667
0.177097506
0.187528345
0.197959184
0.208390023
0.218707483
0.229138322
0.239569161
0.25
0.260430839
0.270861678
0.281292517
0.291609977
0.302040816
0.312471655
0.322902494
0.333333333
0.343764172
0.354195011
0.36462585
0.375056689
0.38537415
0.395804989
0.406235828
0.416666667
0.427097506
0.437528345
0.447959184
0.458276644
0.468707483
0.479138322
0.489569161
0.5
0.510430839
0.520861678
0.531292517
0.541723356
0.552040816
0.562471655
0.572902494
0.583333333
0.593764172
0.604195011
0.61462585
0.624943311
0.63537415
0.645804989
0.656235828
0.666666667
0.677097506
0.687528345
0.697959184
0.708390023
0.718707483
0.729138322
0.739569161
0.75
0.760430839
0.770861678
0.781292517
0.791609977
0.802040816
0.812471655
0.822902494
0.833333333
0.843764172
0.854195011
0.86462585
0.875056689
0.88537415
0.895804989
0.906235828
0.916666667
0.927097506
0.937528345
0.947959184
0.958276644
0.968707483
0.979138322
0.989569161
不幸的是,在这些节拍之间,它也向我发送了
假节拍
,它们不是原始
脉冲的倍数。例如
0029024943
,它是不在脉冲列表中的
256
的倍数

如何从该列表中找到哪些记号是有效的,哪些是假的? 在这个过程中,我没有要比较的脉冲列表,因为
8820
在这个过程中会发生变化,所以我没有要逐步比较的列表。我需要从每次迭代的滴答声中推断出来

最好的数学方法是什么?也许只在滴答声中推理,而不是脉搏

我想找出最接近的整数脉冲和上/下一个刻度之间的误差。在C++中:

但是,例如,勾号
0.0417234
(脉冲
368
)失败,因为上一个勾号错误似乎比它更接近:
prevpulseABS
错误(
0.00543795
)比
pulseABS
错误(
0.0054464
)小


这是因为我猜这个比较并不关心舍入。

我假设你在一个for循环中初始化你的脉冲,使用
inti
作为循环变量;那么问题是这一行:

bankeround(8820*i/96);
8820*i/96
是一个全整数运算,结果又是整数,去掉了余数(因此,实际上,总是向零舍入),Bankeround实际上不再需要舍入。请尝试以下方法:

bankeround(8820*i/96.0);
如果您试图计算上一个脉冲和下一个脉冲,那么同样的问题也会出现,因为您实际上减去并添加了0(同样,
1/8820
都是整数,结果是0)

编辑:

从我从文件中读到的内容来看,“系统”是不可修改的——正如我之前所假设的那样。实际上,它以 n / 96.0, n &#x220a [0, 96) in ℕ 然后,最大偏差将略大于0.00544(见下文了解更精确的值),阈值大小为0.006、0.0055、0.00545。。。也许是个选择


舍入可能是传感器值内部使用的位数问题(如果我们有13位可用,则实际可能会将滴答数计算为
floor(8192*i/96.0)/8192.0
,8192是
1使用Excel,我想您希望将其乘以(应该是什么)整数,而不是寻找最近的脉冲

Tick                Pulse                   i   Error                           OK
                Tick*8820       Pulse*96/8820   ABS( i - INT( i+0.05 ) )    Error < 0.01
------------    ------------    -------------   ------------------------    ------------
0.029024943     255.9999973     2.786394528     0.786394528                 FALSE
0.0417234       368.000388      4.0054464       0.0054464                   TRUE
0                 0             0               0                           TRUE
0.010430839      91.99999998    1.001360544     0.001360544                 TRUE
0.020861678     184             2.002721088     0.002721088                 TRUE
0.031292517     275.9999999     3.004081632     0.004081632                 TRUE
0.041723356     367.9999999     4.005442176     0.005442176                 TRUE
0.052040816     458.9999971     4.995918336     0.004081664                 TRUE
0.062471655     550.9999971     5.99727888      0.00272112                  TRUE
0.072902494     642.9999971     6.998639424     0.001360576                 TRUE
0.083333333     734.9999971     7.999999968     3.2E-08                     TRUE

新帖子:

好的,根据我现在的理解,这是我修改后的答案

您拥有构建良好价值列表所需的信息。每次切换到新曲目时:

vector<double> good_list;
good_list.reserve(96);
for(int i = 0; i < 96; i++)
    good_list.push_back(BankerRound(8820.0 * i / 96.0) / 8820.0);
矢量良好_列表;
良好清单。储备(96);
对于(int i=0;i<96;i++)
好的列表。向后推(bankeround(8820.0*i/96.0)/8820.0);
然后,每次要验证输入时:

auto iter = find(good_list.begin(), good_list.end(), input);
if(iter != good_list.end()) //It's a match!
    cout << "Happy days! It's a match!" << endl;
else
    cout << "Oh bother. It's not a match." << endl;
auto iter=find(good_list.begin(),good_list.end(),input);
如果(iter!=good_list.end())//这是一个匹配!

为什么不将所有脉冲值存储在列表中,当系统向您发送一个值时,在列表中搜索它?您能否简化此示例以处理六个值而不是96个值?还要注意,SO使用英语,小数点分隔符是“.”,而不是“,”。脉冲列表不是一个固定的列表,我可以检查和比较。8820可以随时间而变化,因此滴答声和脉冲。唯一真正固定的值是滴答声。也许可以将问题简化为一个易于编译的完整程序,使用数组中的一些示例数据、一个示例输入和一个断言来断言您想要的结果?那么也许我们可以提供帮助理查德霍奇斯:我给你一些例子数据。你还需要什么?我什么都不想。好好读一读这个问题:我没有脉搏表。我从滴答声中得到它。它是动态的(即8820在这段时间内的变化)。因此,我没有任何固定的脉冲列表。当然,我正在舍入一个双精度,这只是一个例子。这在你的问题中是不清楚的,在我看来,好像你也在为服务器编程,并且由于计算错误,它传递了错误的值。问题是当你有“接近”时值。假设我从系统中获得刻度
0.0418367
(脉冲369)。误差较小,如368和0.0417234。但该值需要忽略。只需插入
0.0418367
,它会给出FALSE(其中as
0.0417234
给出TRUE)。如果你手边有一个电子表格,可能值得像我一样插入数字并玩一玩。即使
0.05
0.01
不是完美的,这项技术也应该是可靠的。它失败了,勾号
0.406349
(3584):.3584不是脉冲,3583 isI可以在每次迭代中获得每拍的值,所以我同意。我害怕的是那个“圆”。使用你的8820作为每拍的值,那么,下面是一个为什么这会起作用的示例。1/8820是小数位数可以不同的量,它被认为是不同的值(如93/8820-92/8820=1/8820).不确定我对你的代码有什么错:但这里没有一个值是有效的:(也许你在允许的错误中遗漏了一些东西?实际上,在你的代码中,没有关于我正在“缩放”到1/96系统的信息。在你的OP中,96 In“pulse=bankeround(8820*I/96),I[0,96[”已知/修复了吗?
double pulse = tick * 8820.0 ;
double i = pulse * 96.0 / 8820.0 ;
double error = abs( i - floor( i + 0.05 ) ) ;
if( error < 0.05 ) {
    // is pulse
}
vector<double> good_list;
good_list.reserve(96);
for(int i = 0; i < 96; i++)
    good_list.push_back(BankerRound(8820.0 * i / 96.0) / 8820.0);
auto iter = find(good_list.begin(), good_list.end(), input);
if(iter != good_list.end()) //It's a match!
    cout << "Happy days! It's a match!" << endl;
else
    cout << "Oh bother. It's not a match." << endl;
double input; //let input be elements in your list of doubles, such as 0.010430839
double allowed_error = 1.0 / values_per_beat;
double proposed = input * values_per_beat;
double rounded = std::round(proposed);
if(abs(rounded - proposed) < allowed_error){cout << "It's good!" << endl;}