如何将 2 个受限十进制变量转换为第三个变量,反之亦然?
我有 2 个转换器方法如下:
private const decimal MaxValidValue = 99.99m;
public decimal ConvertABToC(decimal a, decimal b)
{
return a * b;
}
public void ConvertCtoAB(decimal c, ref decimal a, ref decimal b)
{
if (c > MaxValidValue*MaxValidValue)
{
throw new ApplicationException();
}
if (c <= MaxValidValue)
{
a = 1.00m;
b = c;
}
else
{
// need to introduce some logic or assumptions here
}
}
有 3 件重要的事情需要知道:
1) a 和 b 变量的范围是 0.00 到 99.99 因此 c 的值不能大于 99.99*99.99
2) a,b c 不得超过 2 位小数进动,例如 a = 99.123 无效。
3)如果您需要,只要decimal.Round(a * b, 2) == c,您就可以使用舍入。
4) 像 (1, 3)、(3, 1)、(2, 2)、(1, 4)、(0.5, 8) 甚至 (0.25, 16) 这样的组合都是有效的;只要 c 是 a 和 b 的乘积就没有关系。
您将如何完成 ConvertCtoAB 的实施?
非常感谢,
I have 2 convertor methods as below:
private const decimal MaxValidValue = 99.99m;
public decimal ConvertABToC(decimal a, decimal b)
{
return a * b;
}
public void ConvertCtoAB(decimal c, ref decimal a, ref decimal b)
{
if (c > MaxValidValue*MaxValidValue)
{
throw new ApplicationException();
}
if (c <= MaxValidValue)
{
a = 1.00m;
b = c;
}
else
{
// need to introduce some logic or assumptions here
}
}
There are 3 important things to know:
1) The a and b variables are in the range of 0.00 to 99.99 therefore c can't have a value greater than 99.99*99.99
2) the a, b and c must not have more than 2 decimal precession e.g. a = 99.123 would be invalid.
3) you can use rounding if you'd need to as long as decimal.Round(a * b, 2) == c.
4) combinations like (1, 3), (3, 1), (2, 2), (1, 4), (0.5, 8) or even (0.25, 16) are all valid; it doesn't matter as long as c would be the product of a and b.
How would you complete the implementation of ConvertCtoAB?
Many thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
将
C
乘以 10,000。然后将这个数分解为它的质因数。然后将质因数划分为两个集合,使得每个集合中的数字的乘积小于 10,000。如果可以找到这样的分区,则将这两个乘积除以 100 返回为A
和B
。否则,将数字加一,然后重试。例如,如果
C=100.07
,则因子为2, 2, 5, 5, 10007
。由于其中一个乘积必须包含因子10007
,这是一个素数,因此第一个条件永远无法满足。因此,我们再次尝试使用1000701 = 3*3*3*13*2851
。这次,我们可以对数字进行分区,我们有A=3.51
和B=28.51
作为可能的解决方案。您最多可以执行 99 次。如果您需要 100 个或更多,则无法从
ConvertABToC
生成输入值。这仅保证
ConvertCtoAB
的结果在反馈到ConvertABtoC
时将产生相同的C
,而不是相反。它似乎违反了规则#3,但其他地方的问题是关于舍入的。如果根本不允许舍入,那么在尝试原始的 10000*C 后应该停止并报告不可行。
Multiply
C
by 10,000. Then factor this number into its prime factors. Then find a partition of the prime factors into two sets such that the product of the numbers in each set is less than 10,000. If such a partition can be found, then return these two products divided by 100 asA
andB
. Otherwise, add one to the number and try again.For example, if
C=100.07
, then the factors are2, 2, 5, 5, 10007
. Because one of the products must include the factor10007
, which is a prime number, the first condition can never be satisfied. So we try again with1000701 = 3*3*3*13*2851
. This time, we can partition the number, and we haveA=3.51
andB=28.51
as a possible solution.You can do this at most 99 times. If you need 100 or more, than the input value cannot have been generated from
ConvertABToC
.This only guarantees that the result of
ConvertCtoAB
, when fed back intoConvertABtoC
will produce the sameC
, not the other way around. It appears to violate rule #3, but then elsewhere the question is about rounding.If no rounding at all is allowed, then one should stop and report infeasibility after trying the original 10000*C.
我删除了之前的答案,因为我认为它不再有帮助,因为问题随着时间的推移发生了很大的变化。
这就是我理解的问题:
给你一个
decimal
类型的输入(c
),这样:0
0
0 = c <= 99.99m * 99.99m
c ==decimal.Round(c, 2)
)c 需要找到
十进制
值a
和b
使得:a
和b
中的每一个都在[0, 99.99m]
范围a
和b
最多有两位小数decimal.Round(a * b , 2) == c
我的答案是仍然不可能适用于
c
的所有值。反例:c = 9997.50
a
和b
的最高可能值(各 99.99m)给出decimal.Round(a * b , 2) == 9998.00
,因此产品过高会导致失败。现在,如果您将
a
保持尽可能高,并尽可能减少b
,我们会得到a=99.99m, b=99.98m - 现在是
decimal.Round(a * b, 2) == 9997.00
,因此结果会因产品太低而失败。无法获得这两个值之间的任何乘积 - 我们已经对第一次尝试进行了尽可能小的干扰。因此,
a
和b
没有值可以满足问题。(我预计会引入一项新规则来解决这个问题,因为这似乎就是这个问题的发展方向......)
I've deleted my previous answer, as I don't believe it was helpful any more, as the question's changed so much over time.
Here's what I understand the question to be:
You are given an input (
c
) of typedecimal
such that:0 <= c <= 99.99m * 99.99m
c
has at most two decimal places (i.e.c == decimal.Round(c, 2)
)You are required to find to
decimal
valuesa
andb
such that:a
andb
are in the range[0, 99.99m]
a
andb
have at most two decimal placesdecimal.Round(a * b, 2) == c
My answer is that it's still not possible for all values of
c
. Counterexample:c = 9997.50
The highest possible values of
a
andb
(99.99m each) givesdecimal.Round(a * b, 2) == 9998.00
, so that fails with a product which is too high.Now if you keep
a
as high as it can be, and reduceb
as little as possible, we geta=99.99m, b=99.98m
- and nowdecimal.Round(a * b, 2) == 9997.00
, so that fails with a product which is too low.There is no way of getting any product between those two values - we've perturbed our first attempt by as small an amount as possible. Therefore there are no values for
a
andb
satisfying the problem.(I'm anticipating a new rule being introduced to cope with this, as that seems to be the way this question is going...)
Skeet 将间隔视为本身 * 100 的想法使一切变得更加清晰......
问题确实没有完整的解决方案。它要求您创建一个双射函数 f : A x B -> C、
其中 A = B = {0 ... 9999} 且 C = {0 ... 9999*9999 }
9999*9999 = 9998001;再加上 0,基数为 99,980,002。
AXB 的基数为 100,000,000。
当域和余域具有不同的基数时,无法定义有限集上的双射函数。始终最多有 19,998 个 c 值,其 (a, b) 分解将有多个解。
回到最初的区间定义:您可以得到的最接近正确函数的形式类似于:
在这种情况下,0.02 到 99.97 之间的 a 值将给出唯一的结果; a = 0.00 或 99.99 是相同的,a = 0.01 或 99.98 也是如此。这两个值之间不可能存在区别。
}
Skeet's idea to treat the interval as itself * 100 makes everything so much clearer...
The problem is indeed without a complete solution. It asks you to create a bijective function f : A x B -> C,
where A = B = {0 ... 9999} and C = {0 ... 9999*9999 }
9999*9999 = 9998001; plus the 0, that gives a cardinality of 99,980,002.
A X B has a cardinality of 100,000,000.
A bijective function over finite sets can't be defined when the domain and codomain have different cardinalities. There will always be at most 19,998 values of c whose (a, b) breakdown will have more than one solution.
Going back on the original interval definition: the closest you can get to a proper function is something like:
In this case, values for a between 0.02 to 99.97 will give unique results; a = 0.00 or 99.99 will be identical, likewise for a = 0.01 or 99.98. there is NO possible discrimination between these two values.
}