【看到哪里写到哪里】算闰年的(year 3) == 0

【??BUG??】在MYSQL源码里面有一段,算每年的天数。其中用到了两个很有意思的

1)(year & 3) == 0

2)(year % 400 == 0 && year),为什么要 &&year呢?

>>>>>mysql-server/mysys/my_time.cc 的128~137行/**Calc days in one year.@note Works with both two and four digit years.@return number of days in that year
*/
uint calc_days_in_year(uint year) {return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)) ? 366: 365);
}

一般的算闰年的写法很简单

一、闰年的基本定义与规则

闰年是为了弥补因公历纪年中 “平年”(365 天)与地球实际公转周期(约 365.2422 天)的时间差而设立的。具体判断规则如下:

1. 普通闰年判断规则

满足以下条件之一的年份为闰年:

  • 能被 4 整除且不能被 100 整除
    例:2004 年(2004÷4=501,2004÷100=20.04)是闰年;
    1900 年(1900÷4=475,但 1900÷100=19)不是闰年。
2. 世纪闰年判断规则
  • 能被 400 整除的整百年份为闰年。
    例:2000 年(2000÷400=5)是闰年;
    1800 年(1800÷400=4.5)不是闰年。

二、规则拆解与逻辑说明

可用逻辑表达式表示为:
(年份 % 4 == 0 且 年份 % 100 != 0) 或 年份 % 400 == 0

  • 为什么除以 4?
    地球公转约 365.2422 天,每 4 年积累约 0.9688 天,接近 1 天,故每 4 年设 1 个闰年(加 1 天)。

  • 为什么除以 100 的例外?
    每 4 年加 1 天会导致误差:400 年累计多算约 3 天。因此规定 “能被 100 整除但不能被 400 整除的年份” 不算闰年(如 1900 年、2100 年),以修正误差。

  • 为什么除以 400 的例外?
    进一步修正误差:每 400 年中,原本应排除 3 个整百年(如 1700、1800、1900),但保留能被 400 整除的年份(如 2000 年),使 400 年内闰年数量为 97 个,更接近实际公转周期。

C语言写个简单的函数,首先要判断不能<=0,再做判断。

int isLeapYear(int year) {if (year <= 0) return 0;return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

=====================================================================

但是前面那段mysql的程序是什么意思呢?

在闰年判断函数中,(year & 3) == 0 是一种高效的位运算技巧,用于替代 year % 4 == 0 判断一个年份是否能被 4 整除。

一、位运算原理:为什么 (year & 3) == 0 等价于 year % 4 == 0

1. 4 的倍数的二进制特征

一个整数能被 4 整除,当且仅当其二进制表示的最后两位是 0

例如:

  • 4 的二进制:100(最后两位是 00)
  • 8 的二进制:1000(最后两位是 00)
  • 12 的二进制:1100(最后两位是 00)
  • 15 的二进制:1111(最后两位是 11,不能被 4 整除)
2. 位与运算(&)的作用

3 的二进制是 0011(假设是 32 位整数,则为 000...0011)。当一个数 year 与 3 进行位与运算时:

year & 3 等价于:只保留 year 的二进制表示的最后两位,其余位清零

因此:

  • 若 year 能被 4 整除(最后两位是 00),则 year & 3 的结果为 00(十进制 0)。
  • 若 year 不能被 4 整除(最后两位不为 00),则 year & 3 的结果为 0110 或 11(十进制 1、2 或 3)。

二、为什么用位运算替代取模(%)?

1. 性能优势
  • 取模运算(%):在 CPU 中通常需要除法指令,涉及多次减法或移位操作,计算开销较大。
  • 位与运算(&):直接对二进制位进行操作,仅需一次逻辑运算,速度远快于取模。
2. 编译器优化的局限性

虽然现代编译器可能会将 year % 4 优化为 year & 3(当除数是 2 的幂时),但:

  • 不同编译器的优化能力不同,手动使用位运算能确保在所有环境下都高效。
  • 代码可读性不受影响,因为 (year & 3) == 0 的含义很直观(“判断是否为 4 的倍数”)。

三、原代码的闰年判断逻辑拆解

原代码为:

return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)) ? 366 : 365);
1. 逻辑表达式的结构

整体逻辑等价于:

if ((year & 3) == 0 && (year % 100 != 0 || year % 400 == 0)) {return 366;  // 闰年
} else {return 365;  // 平年
}
2. 核心判断步骤
  • 第一步:判断是否为 4 的倍数(year & 3) == 0 替代 year % 4 == 0,高效检查年份是否能被 4 整除。
  • 第二步:判断是否为 100 的倍数year % 100 != 0(原代码中 year % 100 为真等价于 year % 100 != 0)。
  • 第三步:判断是否为 400 的倍数year % 400 == 0
3. 特殊情况处理:&& year 的作用

原代码中 (year % 400 == 0 && year) 中的 && year 是冗余的,因为:

  • 年份 year 是 uint(无符号整数),其值 ≥ 0。
  • 当 year = 0 时,year % 400 == 0 为真,但 && year 为假,结果为平年(符合实际,因为公元 0 年不存在)。
  • 当 year > 0 时,&& year 恒为真,不影响判断。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/86178.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/86178.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis的渐进式hash和缓存时间戳深入学习

前言 关于redis&#xff0c;可由应用维度、系统维度来进行了解。 如下所示&#xff1a; redis在缓存应用发挥着重要作用&#xff0c;不知道你有没思考过Redis为什么这么快&#xff1f; 1、纯内存访问 为什么内存访问比磁盘访问更快&#xff0c;可参考&#xff1a; 操作系统的…

视频续播功能实现 - 断点续看从前端到 Spring Boot 后端

&#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Micro麦可乐的博客 &#x1f425;《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程&#xff0c;入门到实战 &#x1f33a;《RabbitMQ》…

【工具】Linux 中 find 命令使用教程

find 命令是 Linux 系统中最强大、最灵活的文件搜索工具&#xff0c;其能力远超简单的文件名匹配。掌握 find 能让你在复杂的文件系统中精准定位目标&#xff0c;实现高效的文件管理。 一、命令结构与核心概念 find [起始路径] [选项] [表达式]起始路径&#xff1a;搜索的根目…

0629-

0629 0629操作3. 权限 0629 操作 进入数据库 mysql -uroot -proot123 .use idatabase; select * from customer; 2.select distinct name&#xff0c;idnum from customer; 3.UPDATE customer SET idnum left(MD5(idnum),16); 4. UPDATE customer SET phone CONCAT( LEFT(p…

JVM调优实战 Day 6:JVM性能监控工具实战

【JVM调优实战 Day 6】JVM性能监控工具实战 文章简述 在Java应用的性能优化过程中&#xff0c;JVM性能监控工具是不可或缺的“眼睛”。它们能够帮助开发者实时掌握系统运行状态&#xff0c;识别性能瓶颈&#xff0c;并为后续调优提供数据支撑。本文作为“JVM调优实战”系列的第…

【嘉立创EDA】PCB 如何按板框轮廓进行铺铜

文章路标👉 :one: 文章解决问题:two: 主题内容:three: 参考方法be end..1️⃣ 文章解决问题 操作环境:嘉立创EDA专业版 V2.2.40 本文使用嘉立创EDA,描述如何在PCB设计时,直接使用板框轮廓进行铺铜。本文将此过程记录,以供有需要的读者参考。 2️⃣ 主题内容 在PCB设计…

dockerfile命令及构建

一&#xff0c;dockerfile常用命令 命令介绍FROM–指定基础镜像LABEL作者信息USER切换运行属主身份WORKDUR切换工作目录ENV用于docker容器设置环境变量RUN用来执行命令行的命令COPY把宿主机文件复制到镜像中去ADD将文件路径复制添加到容器内部路径EXPOSE为容器打开指定要监听的…

uniApp实战四:网络请求封装

文章目录 1.最终效果预览2.请求封装3.创建config配置文件4.创建api请求5.页面调用 说明&#xff1a;当前笔记基于Vue3开发&#xff0c;HbuilderX版本4.66 1.最终效果预览 2.请求封装 在util/request.js下创建js文件&#xff0c;代码如下 import config from /configconst tim…

MCP协议全解:大模型时代的能力开放与服务集成最佳实践

一、MCP协议是什么&#xff1f; MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;是大模型和多智能体&#xff08;Agent&#xff09;生态中&#xff0c;用于标准化描述和传递上下文信息、能力开放、服务集成的协议。它的目标是让不同模型、Agent…

oracle 返回最新记录

在Oracle数据库中&#xff0c;如果你想获取一个表中基于某些条件的最新记录&#xff0c;通常有两种常见的方法&#xff1a;使用ROWID或者使用带有ORDER BY和ROWNUM的子查询。下面我将介绍这两种方法的基本用法。 方法1&#xff1a;使用ROWID 如果你的表有一个时间戳字段或者递…

华为云服务器:Can’t connect to MySql server on ‘localhost’(10060)

本地远程连接服务器数据库&#xff0c;提示10060 在 Ubuntu/Debian 系统中&#xff0c;检查 3306 端口是否开启需要从两个方面验证&#xff1a;MySQL 服务是否监听该端口以及防火墙是否允许外部访问该端口。以下是具体步骤&#xff1a; sudo ufw status查看到为开启mysql端口 …

利用Percona XtraDB Cluster搭建MySql高可用集群

引言拉取镜像创建单节点实例(一般在测试环境中使用)自定义网络(集群间相互隔离)映射数据目录创建docker-compose PXC容器用docker-compose启动PXC集群集群验证数据库负载均衡的必要性Haproxy负载均衡器部署故障排查引言 告别单点故障,拥抱持续可用——构建基于 Percona X…

Leetcode 3592. Inverse Coin Change

Leetcode 3592. Inverse Coin Change 1. 解题思路2. 代码实现 题目链接&#xff1a;3592. Inverse Coin Change 1. 解题思路 这一题的话思路上我们走的是一个贪婪算法的思路&#xff0c;即从小到大依次考察&#xff0c;显然&#xff0c;每一次当前最小的非零面额有且必有当前…

打造属于你的AI智能体,从数据开始 —— 使用 Bright Data MCP+Trae快速构建垂直智能体

一、AI智能体的机遇与挑战 最近这两年全民AI热潮开始&#xff0c;各种智能体应用层出不穷。在AI智能体火热的当下&#xff0c;越来越多开发者想要构建自己的智能体&#xff0c;特别是垂直领域&#xff0c;需求更是旺盛。比如招聘助手、电商导购、财经分析师等等。从技术角度来…

嵌入式自学四十八天

时钟 cpu528MHz&#xff0c; PLL&#xff1a;锁相环电路 倍频功能&#xff1a;Fin*n Fout Prescale&#xff1a; 预分频器 降频 Fin/m Fout PFD&#xff1a;相位分子分频器 Fin *n/m Fout 时钟开了后&#xff0c;先到时钟根产生器&#xff0c;对时钟频率更改&…

光谱相机应对复杂环境条件的关键技术与方案

一、极端温度适应性‌ ‌主动温控系统‌ ‌半导体冷却&#xff08;TEC&#xff09;‌&#xff1a;维持探测器在5-40℃工作区间&#xff0c;防止高温噪声&#xff08;如SPECIM FX17&#xff09;。 ‌散热结构‌&#xff1a;铝合金外壳散热鳍片&#xff0c;工业级相机可在-10℃…

个人技术文档库构建实践:基于Cursor和GitHub的知识管理系统(含cursor rules)

技术选型 核心工具链 Cursor编辑器&#xff1a;AI辅助写作&#xff0c;智能补全和结构优化GitHub&#xff1a;版本控制、跨设备同步、团队协作Markdown&#xff1a;轻量级格式&#xff0c;跨平台兼容&#xff0c;与Git完美集成 与主流工具对比 选择CursorGitHub适合&#xf…

烟花爆竹生产企业库房存储安全风险预警系统

烟花爆竹生产企业库房存储安全风险预警系统是保障库房物资安全、规范作业流程、防范安全事故的重要技术手段&#xff0c;涵盖多个关键预警功能。​ 温湿度预警​ 在库房内安装温湿度传感器&#xff0c;这些传感器如同敏锐的“环境感知员”&#xff0c;能够实时监测库房内环境变…

LINUX 625 DNS域名管理系统

建安错题 根据《安全色》&#xff0c;红、黄、蓝、绿四种安全色各自传递着不同的安全含义和信息,其中表示要求人们必须遵守的规定的颜色是()。 根据《安全色》国家标准&#xff08;GB 2893-2008&#xff09;&#xff0c;四种安全色的含义如下&#xff1a; ​​红色​​&#…

FastMCP框架进行MCP开发:(三)从SSE升级到SteamableHTTP

一、前言 在MCP&#xff08;Model Context Protocol&#xff09;中&#xff0c;Streamable HTTP和SSE&#xff08;Server-Sent Events&#xff09;都是用于实现客户端与服务器之间通信的传输机制。然而&#xff0c;它们在设计、功能以及性能表现上有着显著的区别。 二、SSE在…