当前位置:  开发笔记 > 编程语言 > 正文

无符号值之间的减法 - 意外结果

如何解决《无符号值之间的减法-意外结果》经验,为你挑选了2个好方法。

我有两个变量(test1test2),都是无符号的.我需要检查哪一个更大.

我试图了解如果发生溢出会发生什么.

我的第一个测试是使用uint8_t(char)数据类型完成的:

#include 
#include 
#include 

int main()
{
    uint8_t test1 = 0;
    printf("test1 = %d\n", test1);

    uint8_t test2 = pow(2, 8 * sizeof(test1)) - 1; //max holdable value of uint8_t
    printf("test2 = %d\n", test2);

    uint8_t test3 = test1 - test2;
    printf("test1 - test2 = %d\n", test3);

    if ((test1 - test2) == 0)
        printf("test1 == test2\n");
    if ((test1 - test2) > 0)
        printf("test1 > test2\n");
    if ((test1 - test2) < 0)
        printf("test1 < test2\n");

    if (test3 == 0)
        printf("test1 == test2\n");
    if (test3 > 0)
        printf("test1 > test2\n");
    if (test3 < 0)
        printf("test1 < test2\n");

    return 0;
}

输出:

test1 = 0                                                                                                                                                       
test2 = 255                                                                                                                                                     
test1 - test2 = 1                                                                                                                                               
test1 < test2                                                                                                                                                   
test1 > test2

什么?进行减法并将其保存在变量中,然后进行检查,这与在运行中检查减法不同

我的第二次测试是使用uint32_t(long)数据类型完成的:

#include 
#include 
#include 

int main()
{
    uint32_t test1 = 0;
    printf("test1 = %d\n", test1);

    uint32_t test2 = pow(2, 8 * sizeof(test1)) - 1; //max holdable value of uint32_t
    printf("test2 = %lu\n", test2);

    uint32_t test3 = test1 - test2;
    printf("test1 - test2 = %d\n", test3);

    if ((test1 - test2) == 0)
        printf("test1 == test2\n");
    if ((test1 - test2) > 0)
        printf("test1 > test2\n");
    if ((test1 - test2) < 0)
        printf("test1 < test2\n");

    if (test3 == 0)
        printf("test1 == test2\n");
    if (test3 > 0)
        printf("test1 > test2\n");
    if (test3 < 0)
        printf("test1 < test2\n");

    return 0;
}

输出:

test1 = 0                                                                                                                                                       
test2 = 4294967295                                                                                                                                              
test1 - test2 = 1                                                                                                                                               
test1 > test2                                                                                                                                                   
test1 > test2

什么???现在进行减法并将其保存在变量中,然后检查它,就像在运行中检查减法一样

SO 我期待无符号值之间的减法(没有明确的CAST)始终返回值> = 0.但这样做的IF内的减法导致意想不到的结果.

现在我很困惑.有人可以向我解释这种行为吗?



1> Clifford..:

有些神秘的类型促销规则适用.在操作数为的第一个示例中uint8_t,对于表达式:

test1 - test2

两个操作数int 减法之前被隐式提升,并且表达式本身具有类型int.



2> Ian..:

由于类型提升,您uint8将被升级为基于平台的int,在当今大多数计算机中,可能会大于8位(通常为32位).

这一行:

if ((test1 - test2) < 0)

如果相当于

if ((int)((int)test1 - (int)test2) < 0) = -255 < 0

这是真的.

但是,对于这条线,

uint8_t test3 = test1 - test2;

它相当于

uint8_t test3 = (uint8_t)((int)test1 - (int)test2); //(uint8_t)(-255) = 1!!;

因此,无论test1 - test2 < 0test3 > 0是(欢迎到计算机的世界!)正确的!

这解释了你的结果.

但是uint32因为它比本地人的"更高"等级int,所以它不是"升级"并且一直保持uint32,或换句话说

这一行:

if ((test1 - test2) > 0)

如果相当于

if ((uint32_t)((uint32_t)test1 - (uint32_t)test2) > 0) = large positive number > 0

这条线

uint32_t test3 = test1 - test2;

相当于

uint32_t test3 = (uint32_t)test1 - (uint32_t)test2; //also large positive number

因此你有两个test1 - test2 > 0test3 > 0.

因此,在您的两种情况下,只有在8位机器上运行时才能正确.或者,假设将来本机int是64位,那么这两种情况也都是正确的......

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有