c语言里面TMin不能写成-2147483648的原因

C语言中,将TMin(32位有符号整数的最小值)写成 -2147483647-1,而不是简单地写成 -2147483648 或 0x80000000 。这是为什么呢?

首先,对于整数常量的定义:

    An integer constant begins with a digit, but has no period or exponent part. It may have a prefix that specifies its base and a suffix that specifies its type.

可见如果不发生溢出,整型常量的值总是非负数。如果前面出现符号,则是对整型常量使用的一元运算符,而不是整型常量的一部分。整型常量的实际类型取决于长度、基数、后缀字母和C语言实现确定的类型表示精度。具体的根据表一来确定。
  
其次,看看C语言中limits.h中对于INT_MIN和INT_MAX的定义如下所示:

    #define INT_MAX 2147483647
    #define INT_MIN (-INT_MAX - 1)

那么考虑到以上两点,如果将TMin32写成-2147483648并且将代码在一个32位的机器上面编译,当编译器遇到-X形式的数值,它首先会确定X的数据类型和值,然后取X的。

 ISO C90ISO C99
十进制(Decimal)十六进制(Hexadecimal)十进制(Decimal)十六进制(Hexadecimal)
int
long
unsigned
unsigned long
int
unsigned
long
unsigned long
int
long
long long
 
int
unsigned
long
unsigned long
long long
unsigned long long

表一 根据C语言版本和常量的格式(十进制和十六进制),常量的数据类型是从上面表格里选择第一个合适(能表示常量)的类型。

 Word SizeISO C90ISO C99
Expression-21474836480x80000000-21474836480x80000000
32
64
unsigned
long
unsigned
unsigned
long long
long
unsigned
unsigned

表二 根据C语言版本和常量的格式(十进制和十六进制),可以为这两个表达式得到三种不同的数据类型,包括数据为正值的情况。

由于2147483648超过了int所能够表示的范围,编译器就会再次选择一种可以正确的表示此值的类型。然后它就会按照第一个表格(十进制)的顺序往下继续尝试类型,再假设编译器采用的标准是ISO C90,int->long->unsigned,然后就发现unsigned是第一个合适的数据类型。正如我们知道的,2147483648和-2147483648在32位数值上拥有同样的位表示,使得此常量的最终数据类型是unsigned且值为2147483648。这对于16进制的0x80000000也是相同的结果。

对于64位来说十进制和十六进制会分别选择long(-2147483648)和unsigned(2147483648)。而ISO C99的情况则是按照上述规则数据类型为long long才能容纳2147483648。

最后结论是:-214748364832位机器里使用ISO C90进行编译,会先将2147483648看成是一个unsigned,再对2147483648进行无符号的加法逆元计算(见csapp第二版56页),得到结果是:
(-uw2147483648) = 2w - x = 232 - 231 = 231 = 2147483648。

所以对于下面的表达式:

    int result = -2147483648 < 2147483647;

在32位机器里面使用ISO C90进行编译, result = 0。

参考资料:
cs: app web aside

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
return false; t = -(normal * ray.origin - d) / denom; if (t > EPS) return true; return false; } }; class Light { public: Vector3 position; Vector3 color; Light() : position(0, 一致性检验不能通过的原因可能有很多种,以下是一些可能的原因: 1. 数据错误0, 0), color(1, 1, 1) {} Light(const Vector3& p, const Vector3& c:数据可能被篡改、遗漏、重复或格式错误,这可能导致一致性检验失败。 2.) : position(p), color(c) {} }; Vector3 trace(const Ray& ray, const Sphere* spheres, int nspheres, const Plane 并发问题:如果多个用户同时访问数据,可能导致并发问题,例如读取到过期数据或覆& plane, const Light& light) { double tmin = 1e10; Vector3 hit_color(0, 0盖其他用户的数据,这可能导致一致性检验失败。 3. 网络延迟:在分布式系统, 0); for (int i = 0; i < nspheres; ++i) { double t = 1e中,如果网络延迟较高,可能导致数据同步不及时,这可能导致一致性检验失败10; if (spheres[i].intersect(ray, t) && t < tmin) { tmin = t; Vector3 hit_point = ray.origin + ray.direction * t; Vector3 normal = (hit_point - spheres[i].center).normalize(); 。 4. 系统故障:如果系统发生故障,可能导致数据不一致,例如服务器宕机或数据库崩溃,这可能导致一致性检验失败。 5. 算法错误:一致性算法可能存在错误或 Vector3 view = (ray.origin - hit_point).normalize(); Vector3 h = (view + light.position.normalize()).normalize(); double diffuse = max(0.0, normal * light.position.normalize()); double specular = pow(max(0.0, normal漏洞,导致检验失败。 以上是一些可能的原因,具体原因需要根据具体情况进行分析。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值