【问题标题】:Nested MAX causes smallest value to sometimes be returned when using various object types - MAX(a,MAX(b,c))使用各种对象类型时,嵌套的 MAX 有时会返回最小值 - MAX(a,MAX(b,c))
【发布时间】:2016-10-31 11:12:41
【问题描述】:

在我发现定义为 MAX(2,x) 的整数之一返回 -4 之前,我正在调试一段时间,即使 2 明显大于 -4。

这是我的代码运行的简化版本,因此您可以亲身体验不规则性。

    NSLog(@"a) %i", (int)MAX(2,-4));
    NSString *aString = @"90586381095716439405631195482586763570805293418319186736659080000000000000";
    int aNumber = (int)MAX(2,10-MAX(1,(aString.length/5)));
    NSLog(@"b) %i", aNumber);
    NSLog(@"c) %i", (int)MAX(2,10-MAX(1,16)));

a) 将按预期记录 2。

b) 将记录 -4 这对我来说毫无意义。

c) 将按预期记录 2(现在 b 对我来说更没有意义了)


我没有得到什么? MAX 在 xCode 中是棕色的,这让我觉得它在 UIKit 或数学库的某个地方设置为 CLANG,如果是这种情况,可能只有在处理了第一个 MAX 之后才处理内部 MAX,因此嵌套 MAX 会导致奇怪的错误。但如果是这样的话,c) 不会也记录 -4 吗?

【问题讨论】:

    标签: objective-c integer max integer-overflow


    【解决方案1】:

    我不使用Objective-C,但字符串的length 可能是一个无符号值。如果它的工作方式与普通 C 相同,那将导致内部 MAX 的结果也无符号,因此从 10 中的减法将作为无符号执行。这将导致值下溢并导致一个非常大的值,例如 4294967292 假设为 32 位整数,因此它将由外部 MAX 选择。

    最后的int 是然后将其转换回有符号的,最终得到一个负值。如果您的编译器没有问题,而您将 (int) 排除在外,您应该会收到有关它的警告。

    故事的道德,不要使用无关的强制转换,这会导致编译器不给你有价值的警告。

    【讨论】:

    • 哇,你是对的,将(int) 转换为 string.length 解决了问题。 (int)aString.length - 以及 c) 将 (NSUInteger)(即 .length 的含义)投射到 16 重现问题。所以 MAX 在处理NSUInteger 时遇到了问题,很有趣..
    • @AlbertRenshaw:这确实与MAX 无关。问题是减法。如果您要减去无符号值并且不希望下溢,则需要在减去之前检查您的值。
    • 不一定,如果我在应用 MAX 之前检查该值,问题就会自行解决。如果我将 MAX(b,c) 定义为整数“d”,然后执行 MAX(a,d),它确实返回 a。因此,当涉及 NSUinteger 时,处理 MAX 背后的逻辑似乎是一个问题。事先处理 NSUinteger 并将其置于最大值(或事先检查值,然后将其置于最大值)可以防止出现问题。嗯
    • @AlbertRenshaw:什么是“处理整数”?
    • 对不起,我的意思是处理嵌套的 MAX 的内部值并将存储转换为整数。
    猜你喜欢
    • 1970-01-01
    • 2017-02-23
    • 2018-03-06
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    相关资源
    最近更新 更多