【看到哪里寫到哪里】算閏年的(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
英文地址,請注明出處:http://en.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在…