2

试图找出这个伪代码。假设如下......我只能使用无符号和有符号整数(或长整数)。除法返回一个没有余数的实数。MOD 返回一个实数。不处理分数和小数。

INT I = 41828;
INT C = 15;
INT D = 0;

D = (I / 65535) * C;

在这种情况下,您将如何处理分数(或十进制值)?有没有办法用负值来表示余数?

在这个例子中,I/65535 应该是 0.638,但是,由于限制,我得到 0 和 638 的 MOD。然后我怎样才能乘以 C 来得到正确的答案?

希望这是有道理的。

这里的 MOD 实际上会返回 23707,而不是 638。(我希望我是对的 :))

4

3 回答 3

3

如果你要在最后一行切换你的操作顺序,你会得到你正在寻找的整数答案(9,如果我的计算是正确的)

D = (I * C) / 65535
/* D == 9 */

这就是你要找的答案吗?

于 2010-04-02T22:02:28.020 回答
0

假设这些是您一直用于此计算的值,那么我会执行以下操作:

D = I / (65535 / C);

或者

D = I / 4369;

因为 C 是 65535 的因数。这将有助于减少超出可用整数范围的可能性(即,如果您只有 16 位无符号整数)。

在更一般的情况下,如果您认为 I 和 C 的乘法可能会导致您使用的整数类型的允许范围之外的值(即使最终结果将在该范围内),您可以将分子和分母的GCD 分解为:

INT I = 41828;
INT C = 15;
INT DEN = 65535;

INT GCDI = GCD(I, DEN);
DEN = DEN / GCDI;
I = I / GCDI;

INT GCDC = GCD(C, DEN);
DEN = DEN / GCDC;
C = C / GCDC;

INT D = (I * C) / DEN;

其中 DEN 是您的分母(在本例中为 65535)。这不会在所有情况下为您提供正确的答案,特别是如果 I 和 C 都与 DEN 互质且 I*C > MAX_INT 时。

至于你提出的更大的问题,整数值的除法总是会丢失小数部分(相当于 floor 函数)。保留我们认为的“小数”部分中包含的信息的唯一方法是通过可以从模数导出的余数。我强烈建议您不要混淆这些不同数字系统的含义。整数就是整数。如果你需要它们是浮点数,你真的应该使用浮点数,而不是整数。如果您感兴趣的只是向用户显示小数部分(即您并没有真正使用它进​​行进一步计算),那么您可以编写一个例程将余数转换为表示余数的字符串。

于 2010-04-06T15:35:47.070 回答
0

好吧,处理小数的一种方法是这个替换除法函数。这种技术有许多明显的缺点。

ALT DIV (dividend, divisor) returns (decimal, point)
for point = 0 to 99
  if dividend mod divisor = 0 return dividend / divisor, point
  dividend = divident * 10
return dividend / divisor, 100
于 2010-04-06T15:46:06.243 回答