负数的奇怪 Objective-C Mod 行为

发布于 2024-07-25 01:52:49 字数 247 浏览 5 评论 0原文

所以我认为负数在修改时应该放入正空间...我无法在 Objective-c 中发生这种情况

我期望这样:

-1 % 3 = 2
 0 % 3 = 0
 1 % 3 = 1
 2 % 3 = 2

但是得到这个

-1 % 3 = -1
 0 % 3 = 0
 1 % 3 = 1
 2 % 3 = 2

为什么是这样并且有解决方法吗?

So I thought that negative numbers, when mod'ed should be put into positive space... I cant get this to happen in objective-c

I expect this:

-1 % 3 = 2
 0 % 3 = 0
 1 % 3 = 1
 2 % 3 = 2

But get this

-1 % 3 = -1
 0 % 3 = 0
 1 % 3 = 1
 2 % 3 = 2

Why is this and is there a workaround?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

难以启齿的温柔 2024-08-01 01:52:49
result = n % 3;
if( result < 0 ) result += 3;

不要按照其他答案中的建议执行额外的 mod 操作。 它们非常昂贵且不必要。

result = n % 3;
if( result < 0 ) result += 3;

Don't perform extra mod operations as suggested in the other answers. They are very expensive and unnecessary.

埋情葬爱 2024-08-01 01:52:49

在 C 和 Objective-C 中,除法和模运算符执行向零的截断。 如果 a / b > 则 a / bfloor(a / b) 0,否则如果a / b 则为ceiling(a / b) 0 。 情况始终是 a == (a / b) * b + (a % b),除非 b 为 0。因此,正 % 正 == 正正 % 负 == 正负 % 正 == 负负 % 负 == 负 (您可以计算出所有 4 种情况的逻辑,尽管有点棘手)。

In C and Objective-C, the division and modulus operators perform truncation towards zero. a / b is floor(a / b) if a / b > 0, otherwise it is ceiling(a / b) if a / b < 0. It is always the case that a == (a / b) * b + (a % b), unless of course b is 0. As a consequence, positive % positive == positive, positive % negative == positive, negative % positive == negative, and negative % negative == negative (you can work out the logic for all 4 cases, although it's a little tricky).

や三分注定 2024-08-01 01:52:49

如果 n 的范围有限,那么您只需添加一个大于最小值绝对值的已知常数倍 3 即可得到您想要的结果。

例如,如果 n 限制为 -1000..2000,则可以使用表达式:

result = (n+1002) % 3;

确保最大值加上常量在求和时不会溢出。

If n has a limited range, then you can get the result you want simply by adding a known constant multiple of 3 that is greater that the absolute value of the minimum.

For example, if n is limited to -1000..2000, then you can use the expression:

result = (n+1002) % 3;

Make sure the maximum plus your constant will not overflow when summed.

国际总奸 2024-08-01 01:52:49

我们有一个语言问题:

math-er-says: i take this number plus that number mod other-number
code-er-hears: I add two numbers and then devide the result by other-number
code-er-says: what about negative numbers?
math-er-says: WHAT? fields mod other-number don't have a concept of negative numbers?
code-er-says: field what? ...
  • 对话中的数学人正在谈论在圆形数轴上做数学。 如果减去底部,就会绕到顶部。
  • 代码人员正在谈论计算余数的运算符。

在这种情况下,您需要数学家的 mod 运算符并拥有可供您使用的余数函数。 你可以通过检查每次做减法时是否跌入谷底,将余数运算符转换为数学家的取模运算符。

We have a problem of language:

math-er-says: i take this number plus that number mod other-number
code-er-hears: I add two numbers and then devide the result by other-number
code-er-says: what about negative numbers?
math-er-says: WHAT? fields mod other-number don't have a concept of negative numbers?
code-er-says: field what? ...
  • the math person in this conversations is talking about doing math in a circular number line. If you subtract off the bottom you wrap around to the top.
  • the code person is talking about an operator that calculates remainder.

In this case you want the mathematician's mod operator and have the remainder function at your disposal. you can convert the remainder operator into the mathematician's mod operator by checking to see if you fell of the bottom each time you do subtraction.

美羊羊 2024-08-01 01:52:49

如果这将是行为,并且您知道它会是,那么对于 m % n = r,只需使用 r = n + r。 如果您不确定这里会发生什么,请使用 r = r % n

编辑:总而言之,使用 r = ( n + ( m % n ) ) % n

If this will be the behavior, and you know that it will be, then for m % n = r, just use r = n + r. If you're unsure of what will happen here, use then r = r % n.

Edit: To sum up, use r = ( n + ( m % n ) ) % n

始终不够 2024-08-01 01:52:49

我本来也期望一个正数,但我从 ISO/IEC 14882:2003 中找到了这个:编程语言 -- C++,5.6.4(可在 关于模数运算的维基百科文章):

二元 % 运算符产生第一个表达式除以第二个表达式的余数。 .... 如果两个操作数都是非负的,那么余数也是非负的; 如果不是,则余数的符号是​​实现定义的

I would have expected a positive number, as well, but I found this, from ISO/IEC 14882:2003 : Programming languages -- C++, 5.6.4 (found in the Wikipedia article on the modulus operation):

The binary % operator yields the remainder from the division of the first expression by the second. .... If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined

入怼 2024-08-01 01:52:49

JavaScript 也能做到这一点。 我已经被它抓住过几次了。 将其视为围绕零的反射而不是延续。

JavaScript does this, too. I've been caught by it a couple times. Think of it as a reflection around zero rather than a continuation.

那片花海 2024-08-01 01:52:49

原因:因为这是 C 标准中指定 mod 运算符的方式(请记住 Objective-C 是 C 的扩展)。 它让我认识的大多数人(比如我)感到困惑,因为它令人惊讶,而且你必须记住它。

至于解决方法:我会使用 uneo's。

Why: because that is the way the mod operator is specified in the C-standard (Remember that Objective-C is an extension of C). It confuses most people I know (like me) because it is surprising and you have to remember it.

As to a workaround: I would use uncleo's.

冷弦 2024-08-01 01:52:49

UncleO 的答案可能更稳健,但如果您想在一行上执行此操作,并且您确定负值不会比 mod 的单次迭代更负(例如,如果任何时候你最多只减去 mod 值)你可以将其简化为单个表达式:

int result = (n + 3) % 3;

因为无论如何你都在做 mod,所以在初始值上添加 3 没有效果除非 n 为负数(但不小于 -3),在这种情况下,它会导致结果为预期的正模数。

UncleO's answer is probably more robust, but if you want to do it on a single line, and you're certain the negative value will not be more negative than a single iteration of the mod (for example if you're only ever subtracting at most the mod value at any time) you can simplify it to a single expression:

int result = (n + 3) % 3;

Since you're doing the mod anyway, adding 3 to the initial value has no effect unless n is negative (but not less than -3) in which case it causes result to be the expected positive modulus.

走走停停 2024-08-01 01:52:49

其余的有两种选择,符号取决于语言。 ANSI C 选择被除数的符号。 我怀疑这就是为什么你看到 Objective-C 也这样做的原因。 另请参阅维基百科条目

There are two choices for the remainder, and the sign depends on the language. ANSI C chooses the sign of the dividend. I would suspect this is why you see Objective-C doing so also. See the wikipedia entry as well.

倾`听者〃 2024-08-01 01:52:49

不仅是java脚本,几乎所有语言都显示错误答案'
coneybeare 说的是正确的,当我们有模式时,我们必须得到余数
余数只不过是除法后剩下的,它应该是一个正整数....

如果你检查数字行,你就会明白

我在 VB 中也面临着同样的问题,这让我强制添加额外的检查,例如
如果结果是负数,我们必须将除数添加到结果中

Not only java script, almost all the languages shows the wrong answer'
what coneybeare said is correct, when we have mode'd we have to get remainder
Remainder is nothing but which remains after division and it should be a positive integer....

If you check the number line you can understand that

I also face the same issue in VB and and it made me to forcefully add extra check like
if the result is a negative we have to add the divisor to the result

总攻大人 2024-08-01 01:52:49

而不是 a%b

使用:ab*floor((float)a/(float)b)

您期望余数并且正在使用取模。 在数学中它们是相同的,在 C 中它们是不同的。 GNU-C 有 Rem() 和 Mod(),objective-c 只有 mod(),所以你必须使用上面的代码来模拟 rem 函数(这与数学世界中的 mod 相同,但在编程中则不然) world [至少对于大多数语言])


另请注意,您可以为此定义一个易于使用的宏。

#define rem(a,b) ((int)(ab*floor((float)a/(float)b)))

然后你可以使用 rem(-1,3 ) 在你的代码中,它应该可以正常工作。

Instead of a%b

Use: a-b*floor((float)a/(float)b)

You're expecting remainder and are using modulo. In math they are the same thing, in C they are different. GNU-C has Rem() and Mod(), objective-c only has mod() so you will have to use the code above to simulate rem function (which is the same as mod in the math world, but not in the programming world [for most languages at least])


Also note you could define an easy to use macro for this.

#define rem(a,b) ((int)(a-b*floor((float)a/(float)b)))

Then you could just use rem(-1,3) in your code and it should work fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文