我有一个困难的数学问题,正在打破我的大脑,我的白板和我所有的笔。我正在使用表达2个值的文件,被乘数和百分比。这两个值都必须是整数。将这两个值相乘以产生范围。范围是浮点值。
我的用户编辑范围,我必须计算新的百分比和被乘数值。困惑了吗?这是一个例子:
Multiplicand: 25000 Apples Percentage: 400 (This works out to .4% or .004) Range: 100.0 Apples (Calculated by Multiplicand * Percentage)
要使事情复杂化,Percentage的允许值为0-100000。 (含义0-100%)Multiplicand是1到32bit int max之间的值(可能是unsigned)。
我需要允许用户输入范围,如下所示:
Range: .04 Apples
并计算适当的百分比和乘数。使用第一个例子:
OriginalMultiplicand: 25000 Apples OriginalPercentage: 400 (This works out to .4% or .004) OriginalRange: 100.0 Apples (Calculated by Multiplicand * Percentage) NewRange: .01 Apples NewPercentage: 40 NewMultiplicand: 25 Apples
示例计算很简单,所需要的只是通过新旧范围的比例因子调整被乘数和百分比。当用户将值更改为1400.00555时会出现问题。突然间,我没有一个干净的方法来调整这两个值。
我需要一种算法来获取M&的值。 P产生与所需范围最接近的可能值。有什么建议吗?
答案 0 :(得分:1)
要最大化存储的小数点数,您应使用P为1或0.1%。如果溢出M,则递增P
因此,对于1400.00555的示例,P为1,M为1400006
您的算法将搜索最低的P,以便M不会溢出。你可以在这里进行二元搜索。
public int binarySearch(int P0, int P1) {
P = (P1 - P0)/2;
if(P == P0) {
if(R/(P0/100f) does not overflows 32-bit int) {
return P0;
} else {
return P1;
}
}
if(R/(P/100f) does not overflows 32-bit int) {
return binarySearch(P0, P);
} else {
return binarSearch(P, P1);
}
}
P = binarySearch(1, 100000);
M = round(R/(P/100f));
答案 1 :(得分:0)
据我通过您的示例了解,您可以代表range
100000
multiplicand * percentage
中的multiplicand
。任何Multiplicand * Percentage = 100.0
的选择都会给你一个令人满意的百分比值,反之亦然。所以你有两个变量的等式:
Multiplicand
您应该找出另一个等式(约束),以获得特定值Percentage
或0-100000
来解决此等式。否则,您可以选择百分比为Multiplicand
之间的任意数字,只需将其替换为第一个等式即可获得range
的值。我希望我能正确理解这个问题:)
编辑:好的,那么您应该轻松地对范围进行分解。获取percentage(2-100000)
,然后尝试通过将范围除以get range;
percentage = 2;
while(range % percentage != 0)
{
percentage++;
}
multiplicand = range / percentage;
来对其进行分解。一旦分裂提醒为零,你就得到了这些因素。这是一个快速的伪代码:
max of percentage = 100000;
max of multiplicand = 4294967295;
Max of range = 4294967295 * 100000 = 429496729500000 (15-digit);
现在你要做的就是计算你的限制:
double
您的最大范围最多包含15位数。大多数编程语言中的doubles
数据类型可以代表它。使用Multiplicand & Percentage
进行计算,最后将int
转换为{{1}}。
答案 2 :(得分:0)
说你有
1) M * P = A
然后你有A的第二个值,所以M和P的新值也可以调用M2,P2和A2:
2) M2 * P2 = A2
这个我不确定,但这就是你似乎在说imho:比例必须保持不变,然后
3) M/P = M2/P2
现在我们有3个方程和2个未知数M2和P2
解决问题的一种方法:
3)变成
M/P = M2/P2
=>M2 = (M/P)*P2
而不是替代2)
(M/P)*P2*P2 = A2
=> P2*P2 = A2 * (P/M)
=> P2 = sqrt(A2 * (P/M))
首先解决P2,然后M2,如果我没有犯任何错误
如果M2和P2必须是整数,则必须进行一些舍入。
编辑:我忘记了整数百分比,所以说
P = percentage/100000 or P*100000 = percentage
P2 = percentage2/100000 or P2*100000 = percentage2
所以只需求解P2和M2,然后将P2乘以100000
答案 3 :(得分:0)
(我在这里遇到了一个糟糕的方法,但我删除了它,因为它很糟糕。)
修改强>
必须有一种比这更好的方法。让我们重新解释一下这个问题:
你拥有的是一个任意的浮点数。您希望用两个整数表示此浮点数。当乘以一起然后除以100000.0时,整数等于浮点数。唯一的另一个约束是其中一个整数必须等于或小于100000。
很明显,您无法准确地表示浮点数。实际上,即使在“被乘数”中具有无限数量的精度数字,也只能准确表示在1/100000s中可表达的数字。您可以准确地表示333.33333,其中33333333为一个数字,另一个为1;你不能再获得3s。
鉴于此限制,我认为您最好的选择如下:
答案 4 :(得分:0)
似乎你想选择M和P使得R =(M * P)/ 100000。 所以M * P = 100000 * R,你必须将右边四舍五入为整数。
我将范围乘以100000,然后选择M和P作为结果的因子,这样它们就不会溢出它们允许的范围。