再探再报 除 0 这件事有不同

2024-03-10 18:28
文章标签 不同 这件 事有

本文主要是介绍再探再报 除 0 这件事有不同,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先,在数学中,一个数除以0是没有意义的。

其次,在计算机中,对于除零,传统概念里是会上报一个异常。首先是CPU内部实现会报异常。最早学组成原理和汇编的时候,都是说CPU寄存器中有个表示除零异常的位。在Linux系统中,除零也会出现异常。为了简单期间,我们从应用层来看。

如果代码里直接出现除零,编译器是会报警告的:

当然,我们可以规避这一点,将常量0换成一个表达式。这时候欺骗过了编译器,执行时会上报浮点异常:

不过这样做的前提是整型数。浮点数由于内部表示的差异,可能不会出现真正的除零(即使写直接写0.0,结果也是无穷 inf)。这里就不再展开说明了。

不过最近,博主遇到了一件奇怪的事,在review代码的时候,发现了除零的情况,但是实际运行时,并没有上报异常,当然执行结果也是不对的。

不过博主是在ARM平台上调试的,难道这跟x86有不同?后来实验了一下,本质上二种平台是一致的。ARM中也会提供处理异常的向量,操作系统注册后,遇到处理,就会进入异常处理,类似中断处理的过程。这其实是操作系统底层的处理方法。而博主实测的环境又有所不同,主要是没有使用操作系统,跑的是裸机程序。可是转念一想,也不对啊,即使是裸机方式,也是使用了CPU厂家提供的BSP,其中对异常是有定义的。为了摸清这个问题,不得已再上汇编,看看到底执行指令的情况是啥样的,省得想的头疼。

不看不知道,一看吓一跳。汇编代码里,对除零做了特殊处理,如下图:

汇编后的代码逻辑变成了这样:首先判断除数是否为零,如果是零,就跳到新的位置进行处理。在新的位置,判断被除数与零的大小,如果大于,则将0x80000000取反返回,否则,将其返回。大概意思是,如果被除数大于零,返回最大正数,当前32位系统,就是2,147,483,647,否则,返回最小负数,当前32位系统,就是-2,147,483,648。

有了上面的汇编作支撑,程序没有报异常,也就可以很好的理解了。

从这个例子,还有之前博主测试发现关于堆栈的增长反向的例子(实践出真知--你的字节对齐和堆栈认知可能是错误的_gdb查看字节对齐-CSDN博客),可以看出,计算机领域,很多工程结论是有前提条件的,尤其是在语言、编译器、操作系统、CPU平台存在多种选择的情况下。如果实际工程中遇到了奇怪的问题,并且怀疑是一些基础概念的话,可以做个简单验证,加以快速排除疑惑。这其中的关键就是要意识到很多东西是依赖语言本身特性、编译器实现、操作系统处理方法、CPU支持情况来综合决定的。这也是为啥标准统一显得重要的原因了。

这篇关于再探再报 除 0 这件事有不同的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/795118

相关文章

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

uva 10061 How many zero's and how many digits ?(不同进制阶乘末尾几个0)+poj 1401

题意是求在base进制下的 n!的结果有几位数,末尾有几个0。 想起刚开始的时候做的一道10进制下的n阶乘末尾有几个零,以及之前有做过的一道n阶乘的位数。 当时都是在10进制下的。 10进制下的做法是: 1. n阶位数:直接 lg(n!)就是得数的位数。 2. n阶末尾0的个数:由于2 * 5 将会在得数中以0的形式存在,所以计算2或者计算5,由于因子中出现5必然出现2,所以直接一

速了解MySQL 数据库不同存储引擎

快速了解MySQL 数据库不同存储引擎 MySQL 提供了多种存储引擎,每种存储引擎都有其特定的特性和适用场景。了解这些存储引擎的特性,有助于在设计数据库时做出合理的选择。以下是 MySQL 中几种常用存储引擎的详细介绍。 1. InnoDB 特点: 事务支持:InnoDB 是一个支持 ACID(原子性、一致性、隔离性、持久性)事务的存储引擎。行级锁:使用行级锁来提高并发性,减少锁竞争

MyBatis 切换不同的类型数据库方案

下属案例例当前结合SpringBoot 配置进行讲解。 背景: 实现一个工程里面在部署阶段支持切换不同类型数据库支持。 方案一 数据源配置 关键代码(是什么数据库,该怎么配就怎么配) spring:datasource:name: test# 使用druid数据源type: com.alibaba.druid.pool.DruidDataSource# @需要修改 数据库连接及驱动u

linux中使用rust语言在不同进程之间通信

第一种:使用mmap映射相同文件 fn main() {let pid = std::process::id();println!(

Ubuntu ftp搭建--配置不同用户不同权限

一、安装VSFTP sudo apt-get install vsftpd 二、添加FTP用户 sudo mkdir /etc/vsftpdsudo useradd -m -d /home/vsftpd vsftpd --用户名为vsftpd,目录和用户名可以自己更改sudo vi /etc/vsftpd/ftpuser.txt --这个到时与vsftp的配置文件对应建立一

为libpng不同架构创建构建目录、编译、安装以及合并库文件的所有步骤。

好的。既然你已经有了 libpng 的源代码,并且当前处在它的目录下,我们可以简化脚本,不再需要下载和解压源代码这一步。以下是修改后的脚本:```sh#!/bin/bash# 当前目录即 libpng 源代码目录LIBPNG_SRC_DIR=$(pwd)# 设置工作目录WORK_DIR=$(pwd)/libpng_buildBUILD_DIR_X86_64="$WORK_DIR/build

BeanUtils.copyProperties()在不同包下,用法不同!!! 切记!!!

用法一: 在import org.springframework.beans.BeanUtils;包下: <span style="white-space:pre"> </span>//赋值vo对象的值到po中 <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span>* <spa

操作系统是怎么为不同的程序分配所需的内存空间的

操作系统为不同的程序分配内存空间的过程涉及多个关键步骤,确保每个程序都有其所需的内存资源,同时避免程序之间的冲突。以下是操作系统如何为程序分配内存空间的详细过程: 1. 内存管理的基础概念 虚拟内存:现代操作系统使用虚拟内存机制来为程序提供隔离的内存空间。每个程序运行在其独立的虚拟地址空间中,这使得程序间的内存互不干扰。物理内存:实际的 RAM(随机存取存储器),由操作系统和硬件共同管理。虚拟