惭愧!直到今天才真正明白为什么int型的取值范围是-2^31~2^31-1

个人博客:The Blog Of WaiterXiaoYY 欢迎来互相交流学习。

前言

虽然之前学过《计算机组成原理》,也理解了原码、补码、反码等东西,但终究还是理解不够深刻,

最近在做位运算类型的题目的时候,脑子突然闪过到一个问题,

为什么 int 型数据类型的取值范围不对称呢?

为什么最大值是 2^31 - 1呢?

为什么最小值是 -2^31,而不是-2^31 + 1呢?

正如标题中所说,很惭愧,直到今天才真正弄明白,

但亡羊补牢,终究未晚。


正 负 数在计算机中的表示

我们知道,计算机能够认识的只有二进制(也就是 0 和 1),而我们所认识的字符和数字都要转换成二进制才能让计算机识别并执行。

这里以java的int型为例说明,

我们首先要明白的是,

java的 int 型是32位的,

因为一个 int 值占 4 个字节 byte ,一个字节是 8 位 bit(即8个二进制位),所以 int型 占 32 位,

其中第32位,也就是最高位是符号位,正数为 0,负数为 1

剩下的31位是用来表示数字部分。

正数

正数在计算机中表示为 原码

比如:

1 的原码是 :0000 0000 0000 0000 0000 0000 0000 0001

1 的补码是:0000 0000 0000 0000 0000 0000 0000 0001

1 的反码是:0000 0000 0000 0000 0000 0000 0000 0001

没错,正数的 原码 、补码 、 反码 都相同

那么最大是多少呢?

当然是除了符号位,其他位置上都为 1 的时候,

0111 1111 1111 1111 1111 1111 1111 1111

这个数就是 2147483647,它是 32 位中所能表示的最大正数。

负数

负数在计算机中表示为 补码

比如:

-1 的原码是:1000 0000 0000 0000 0000 0000 0000 0001

-1 的反码是:1111 1111 1111 1111 1111 1111 1111 1110

-1 的补码是:1111 1111 1111 1111 1111 1111 1111 1111

很明显,负数的 原码 、补码 、 反码 并不相同

而且,

负数的原码 是在 正数的原码 上 将符号位取反 取反

负数的反码 是在 负数的原码 上 除符号位后 取反

负数的补码 是在 负数的反码加一

负数的补码 也可以说是在 负数的原码取反加一

所以我们再来看看 -2147483647 的表示,

-2147483647 的原码是:1111 1111 1111 1111 1111 1111 1111 1111

-2147483647 的反码是:1000 0000 0000 0000 0000 0000 0000 0000

-2147483647 的补码是:1000 0000 0000 0000 0000 0000 0000 0001

那它是最小值吗?

不是,还有一个很奇怪的东西。


0 在计算机中的表示

在二进制中,0 有两种表示方法,

+0 的原码:0000 0000 0000 0000 0000 0000 0000 0000

-0 的原码:1000 0000 0000 0000 0000 0000 0000 0000

因为 0 只需要一个,所以就把 -0 当成了最小的数 -2147483648

可以这么理解,正因为 0 有两种表示方式,所以会多了一个负数出来,

-2147483648 的补码就是:1000 0000 0000 0000 0000 0000 0000 0000它在 32位里面是没有原码的

但需要注意的是,这个补码并不是真正的补码,

真正的补码应该是 1100 0000 0000 0000 0000 0000 0000 0000,但在 java 中溢出了,

所以,就是1000 0000 0000 0000 0000 0000 0000 0000


经过上面,还可搞懂为什么8位的范围是[-128, 127],是不是有点绕?

嗯,我也觉得,但总算有点恍然大悟的样子。



整理于 2020.4.13

### Spring Boot 应用启动后立即关闭的原因分析 Spring Boot 应用程序在某些情况下可能会在启动完成后立刻退出,这通常是因为应用程序没有保持运行状态的任务或线程。以下是可能的原因以及解决方案: #### 1. **未启用 Web 支持** 如果项目是一个纯命令行应用而非基于 Web 的服务,则默认情况下,在完成 `main` 方法中的逻辑之后,JVM 将终止进程[^1]。 对于这种情况,可以通过引入 `spring-boot-starter-web` 或其他依赖来创建一个嵌入式的服务器实例(如 Tomcat),从而让应用程序持续监听请求并维持运行状态。如果没有显式配置任何阻塞操作或者事件循环机制的话,那么 JVM 可能会在初始化完毕后自动结束执行流程[^2]。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` #### 2. **缺少长时间运行的服务或组件** 即使存在一些后台任务处理需求的应用场景下,也需要确保这些异步作业能够被正确管理起来以免过早释放资源而导致整个系统崩溃停止工作。可以考虑利用线程池技术实现多线程并发控制,并通过调用特定 API 来加入到全局共享资源集合当中去防止主线程提前返回造成子线程也被强制销毁的情况发生。 例如下面展示了一个简单的例子展示了如何定义自己的自定义线程工厂类以便更好地管理和跟踪各个独立工作的单元模块之间的关系链路图谱结构化表达形式如下所示: ```java @Bean public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.initialize(); return executor; } ``` 另外还可以借助于 @Scheduled 注解定时触发器功能安排周期性的重复动作序列号列表项编号分别为零开始计数直到达到最大长度为止期间每隔固定时间间隔重新评估一次当前条件满足与否进而决定是否继续往下走下一步骤直至最终目标达成位置处才允许完全退出整个生命周期过程结束标志位设置成功即可认为完成了全部预定计划内的所有事项清单核查无误确认完毕方可安心离去告辞离开现场不再停留驻足观望等待进一步指示行动指南针方向指引明确清晰可见度高容易辨认理解接受采纳实施落地转化成果显著效果明显提升效率质量双丰收双赢局面形成良好态势发展势头强劲有力推动前进动力源泉源源不断涌现出来供我们随时取用享用不尽也! #### 3. **Main 函数中缺乏足够的延迟或其他阻止行为** 有时开发者忘记添加必要的暂停指令使得程序快速跑完既定脚本内容随后便迅速消亡不见踪影了事一般简单粗暴直接干脆利落毫不拖泥带水犹豫不决拖延症患者看了都得汗颜惭愧不已啊!因此建议适当增加一点小小的延时措施也好给用户留有喘息之机观察一下实际运行状况到底怎么样再做打算也不迟嘛~比如这样写就很好看又实用哦~ ```java @PostConstruct public void init() throws InterruptedException { Thread.sleep(Long.MAX_VALUE); // Keep app alive forever. } ``` 当然啦这只是权宜之计并非长久之策毕竟无限期挂起也不是什么好办法所以还是推荐按照前面提到的方式方法论体系框架搭建合理的架构设计模式才是王道真理永恒不变定律法则规律准则标准规范等等诸如此类的概念术语表述方式均可适用于此情境之中哟亲们知道了吧嘿嘿😊 --- ###
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值