热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为什么在减去无符号和签名后符号会有所不同?

如何解决《为什么在减去无符号和签名后符号会有所不同?》经验,为你挑选了2个好方法。

让我们从分析结果开始t - d.

t是一个unsigned int同时d是一个int,这样做对他们的算术值d转换为unsigned int(C++规则说无符号送过来偏好).所以我们得到10u - 16u,(假设32位int)包裹到4294967290u.

然后将该值转换为float第一个声明,并转换为第二个声明int.

假设float(32位单精度IEEE)的典型实现,其最高可表示值大致是1e38,因此4294967290u在该范围内.会出现舍入错误,但转换为float不会溢出.

因为int,情况不同.4294967290u太大了,不适合int,所以发生回旋,我们回到了价值-6.请注意,标准不保证这样的回绕:在这种情况下,结果值是实现定义的(1),这意味着由编译器决定结果值是什么,但必须记录.


(1) C++ 17(N4659),[conv.integral] 7.8/3:

如果目标类型已签名,则该值如果可以在目标类型中表示,则不会更改; 否则,该值是实现定义的.

@ user1810087这意味着编译器必须记录将要发生的事情,这意味着编译器作者必须考虑将要发生的事情,并一致地实现它(或至少将其与实现一致地记录).他们的决定很可能会受到目标硬件的影响,因此这个文档将特定于平台. (4认同)

它不是_behavior_,它是实现定义的 - 只有值(参见你自己的脚注).特别是,由于这种转换,实现不能抛出异常,引发信号等. (3认同)


Sebastian Re.. 15

首先,你必须理解"通常的算术转换"(该链接用于C,但规则在C++中是相同的).在C++中,如果你使用混合类型进行算术运算(顺便说一下,你应该尽可能避免使用),那么就有一套规则可以决定计算的类型.

在您的情况下,您从unsigned int中减去signed int.促销规则说实际计算是使用unsigned int.

所以你的计算是10 - 16无符号int算术.无符号算术是模运算,意味着它包装.因此,假设您的典型32位int,此计算的结果是2 ^ 32 - 6.

这两条线都是一样的.请注意,减法完全独立于赋值; 左侧的类型对计算的发生方式完全没有影响.认为左侧的类型以某种方式影响计算是一个常见的初学者错误; 但是float f = 5 / 6为零,因为除法仍然使用整数运算.

那么,差异就是在任务期间发生的事情.减法的结果float在一种情况下隐式转换为另一种情况int.

转换为float会尝试查找与该类型可以表示的实际值最接近的值.这将是一些非常大的价值; 虽然不是最初减法产生的那个.

转换为int表示如果值适合int的范围,则值将保持不变.但是2 ^ 32 - 6远远大于32位int可以容纳的2 ^ 31 - 1,所以你得到转换规则的另一部分,它表示结果值是实现定义的.这是标准中的术语,意思是"不同的编译器可以做不同的事情,但他们必须记录他们做的事情".

出于所有实际目的,您可能遇到的所有编译器都会说位模式保持不变并且只是被解释为已签名.由于2的补码算法的工作方式(几乎所有计算机都代表负数的方式),结果是你对计算的期望值为-6.

但所有这一切都是重复第一点的很长的方式,即"不做混合型算术".首先明确地将类型转换为您知道会做正确事情的类型.



1> Reinstate Mo..:

让我们从分析结果开始t - d.

t是一个unsigned int同时d是一个int,这样做对他们的算术值d转换为unsigned int(C++规则说无符号送过来偏好).所以我们得到10u - 16u,(假设32位int)包裹到4294967290u.

然后将该值转换为float第一个声明,并转换为第二个声明int.

假设float(32位单精度IEEE)的典型实现,其最高可表示值大致是1e38,因此4294967290u在该范围内.会出现舍入错误,但转换为float不会溢出.

因为int,情况不同.4294967290u太大了,不适合int,所以发生回旋,我们回到了价值-6.请注意,标准不保证这样的回绕:在这种情况下,结果值是实现定义的(1),这意味着由编译器决定结果值是什么,但必须记录.


(1) C++ 17(N4659),[conv.integral] 7.8/3:

如果目标类型已签名,则该值如果可以在目标类型中表示,则不会更改; 否则,该值是实现定义的.


@ user1810087这意味着编译器必须记录将要发生的事情,这意味着编译器作者必须考虑将要发生的事情,并一致地实现它(或至少将其与实现一致地记录).他们的决定很可能会受到目标硬件的影响,因此这个文档将特定于平台.
它不是_behavior_,它是实现定义的 - 只有值(参见你自己的脚注).特别是,由于这种转换,实现不能抛出异常,引发信号等.

2> Sebastian Re..:

首先,你必须理解"通常的算术转换"(该链接用于C,但规则在C++中是相同的).在C++中,如果你使用混合类型进行算术运算(顺便说一下,你应该尽可能避免使用),那么就有一套规则可以决定计算的类型.

在您的情况下,您从unsigned int中减去signed int.促销规则说实际计算是使用unsigned int.

所以你的计算是10 - 16无符号int算术.无符号算术是模运算,意味着它包装.因此,假设您的典型32位int,此计算的结果是2 ^ 32 - 6.

这两条线都是一样的.请注意,减法完全独立于赋值; 左侧的类型对计算的发生方式完全没有影响.认为左侧的类型以某种方式影响计算是一个常见的初学者错误; 但是float f = 5 / 6为零,因为除法仍然使用整数运算.

那么,差异就是在任务期间发生的事情.减法的结果float在一种情况下隐式转换为另一种情况int.

转换为float会尝试查找与该类型可以表示的实际值最接近的值.这将是一些非常大的价值; 虽然不是最初减法产生的那个.

转换为int表示如果值适合int的范围,则值将保持不变.但是2 ^ 32 - 6远远大于32位int可以容纳的2 ^ 31 - 1,所以你得到转换规则的另一部分,它表示结果值是实现定义的.这是标准中的术语,意思是"不同的编译器可以做不同的事情,但他们必须记录他们做的事情".

出于所有实际目的,您可能遇到的所有编译器都会说位模式保持不变并且只是被解释为已签名.由于2的补码算法的工作方式(几乎所有计算机都代表负数的方式),结果是你对计算的期望值为-6.

但所有这一切都是重复第一点的很长的方式,即"不做混合型算术".首先明确地将类型转换为您知道会做正确事情的类型.


推荐阅读
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 加密世界下一个主流叙事领域:L2、跨链桥、GameFi等
    本文介绍了加密世界下一个主流叙事的七个潜力领域,包括L2、跨链桥、GameFi等。L2作为以太坊的二层解决方案,在过去一年取得了巨大成功,跨链桥和互操作性是多链Web3中最重要的因素。去中心化的数据存储领域也具有巨大潜力,未来云存储市场有望达到1500亿美元。DAO和社交代币将成为购买和控制现实世界资产的重要方式,而GameFi作为数字资产在高收入游戏中的应用有望推动数字资产走向主流。衍生品市场也在不断发展壮大。 ... [详细]
author-avatar
z1996y
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有