<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>時光筆記</title><link>https://timememo.lizhou31.com/</link><description>This is a memo to record my life, my learning, and my thoughts.</description><generator>Hugo 0.143.0 &amp; FixIt v0.3.15</generator><language>zh-TW</language><lastBuildDate>Mon, 03 Feb 2025 12:23:52 +0800</lastBuildDate><atom:link href="https://timememo.lizhou31.com/index.xml" rel="self" type="application/rss+xml"/><item><title>近期關於生成式AI的一些想法</title><link>https://timememo.lizhou31.com/some_ai_murmur/</link><pubDate>Mon, 03 Feb 2025 12:23:52 +0800</pubDate><guid>https://timememo.lizhou31.com/some_ai_murmur/</guid><category domain="https://timememo.lizhou31.com/categories/tech_experience/">技術經驗</category><description>&lt;img src="https://timememo.lizhou31.com/some_ai_murmur/featured-image.webp" alt="featured image" referrerpolicy="no-referrer">&lt;p>&lt;em>An image captured on Yugung Island at sunset.&lt;/em>&lt;/p>
&lt;h2 id="前言" class="heading-element">&lt;span>前言&lt;/span>
 &lt;a href="#%e5%89%8d%e8%a8%80" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>回歸之作就獻給生成式 AI 吧。剛好也是最近使用的最多也嘗試得最多的領域。&lt;/p>
&lt;p>實際上甫從 chatGPT 問世，我幾乎是馬上就去使用了，當然一開始只是圖個新鮮，畢竟可以流利對話的聊天機器人到之前幾乎都是不出現的。當然，那個時候真的就只是一個新鮮感的玩具，儘管對於他的對話能力感到新奇，但當時幾乎並沒有任何生產力的想法。&lt;/p>
&lt;p>直到 OpenAI 開始發布更新，從 3.5, 3.5-turbo, 4, 4o，GPT 也從只可以文字輸入的娛樂，到現在多模態，支援圖片，語音，甚至是即時影片做為輸入的多樣化工具。&lt;/p>
&lt;p>而這些進步僅僅發生在 ChatGPT 推出的兩年以內，他就從娛樂進化成了可以提供各類協助的工具，於是，也讓我開始思考，&lt;strong>究竟接下來人類與 AI 工具會有什麼樣的發展&lt;/strong>（又或是 Ilya Sutskever 認為的，可能是一種全新的智能體物種），而我又該如何去面對這些幾乎是突破性的發展。&lt;/p>
&lt;p>當然 AI 影響的可不僅僅是日常生活而已。&lt;/p>
&lt;p>2024 諾貝爾獎應該是非常特別的一年，這年的諾獎開創性的頒給了不少 AI 相關的研究，例如諾貝爾物理學獎的得主 John J. Hopfield 和 Geoffrey E. Hinton，表彰他們在人工神經網路的基礎研究。諾貝爾化學獎也頒給了利用 AI 研究蛋白質結構與設計的學著。&lt;/p>
&lt;p>這些獎項頒給了與 AI 相關的科研內容，可以說是一大震撼彈，代表在學術界的頂級榮譽，也認可了目前的 AI 科技。儘管諾獎看似離我這種普通人應該都是太遠了，但當一個人類文化智慧結晶的殿堂都開始接受這項科技的成果時，這個衝擊應該不會過很久就會席捲整個社會。&lt;/p>
&lt;p>甚至其實 AI 們早就在內捲人類的生活了。根據 &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4602944"target="_blank" rel="external nofollow noopener noreferrer">Who Is AI Replacing? The Impact of Generative AI on Online Freelancing Platforms&lt;/a> 調查了 Freelancer 市場在 ChatGPT 出現前後以及 AI 繪圖相關工具出現前後的工作需求佔比，而這是他們的其中一段結果摘錄：
&lt;div class="details admonition abstract open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-clipboard-list" aria-hidden="true">&lt;/i>摘要&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;p>•	Within eight months of ChatGPT’s release, job postings for &lt;strong>automation-prone roles (e.g., writing, coding, and automation) decreased by 20.86% more than manual-intensive jobs.&lt;/strong>&lt;/p>
&lt;p>•	&lt;strong>Writing jobs&lt;/strong> saw the largest decline &lt;strong>(30.37%)&lt;/strong>, followed by &lt;strong>software development (20.62%)&lt;/strong> and &lt;strong>engineering (10.42%)&lt;/strong>.&lt;/p>
&lt;p>•	The introduction of AI-powered image-generation tools (Midjourney, Stable Diffusion, DALL-E 2) led to a &lt;strong>17.01% decline in job postings for graphic design (18.49%) and 3D modeling (15.57%).&lt;/strong>&lt;/p>
&lt;/div>
 &lt;/div>
&lt;/div>&lt;/p>
&lt;p>也就是說，就算只是截止到目前(2024)的 AI 工具，對於人類的影響已經可以說是非常大的了。那我就在想，在這個可能是時代變革的時間點上，究竟我該拿什麼態度去對待這些工具，才能夠再好好利用工具的情況下又不會失去我原先該有的能力。&lt;/p>
&lt;h2 id="那些-ai-工具對我的影響" class="heading-element">&lt;span>那些 AI 工具對我的影響&lt;/span>
 &lt;a href="#%e9%82%a3%e4%ba%9b-ai-%e5%b7%a5%e5%85%b7%e5%b0%8d%e6%88%91%e7%9a%84%e5%bd%b1%e9%9f%bf" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>欸？失去什麼原先該有的能力？難道人會被 AI 取代？我會沒有工作？其實我並不是在擔心這個。不過如果這件事情真的發生了其實我也沒有太多的驚訝，畢竟現在任何的科技（或是說 AI）發展真的都是不斷超乎想像的。誰能想像 2022 才出現的 ChatGPT，發展了僅僅兩年就已經可以勝任原本只有真人才能做得到的工作，甚至有些還做得更好。&lt;/p>
&lt;p>實際上我一邊使用這些工具並享受著這些東西帶給我的便利性時，我一邊也開始有點惶恐，當我對這些好用的工具產生依賴性時，是否會失去什麼原先我該具備的能力。&lt;/p>
&lt;p>舉個例子，之前有段時間我在與朋友討論相機的成像原理時，對於 &lt;strong>CoC (Circle of confusion)&lt;/strong> 這個名詞感到陌生，於是我很順手的就直接丟給了 ChatGPT 請他解釋，但當時為了方便直接是使用中文問的（一般在使用時我還是覺得英文的問答品質會比中文高很多），於是 ChatGPT 給我了一個似是而非的解答，而當時我也沒有太在意，就把他的回答當作我的理解給記了下來。&lt;/p>
&lt;p>結果大概是中文語意的問題，實際上 ChatGPT 上的解釋是具有誤導性的，而這個誤導讓我後續對於整個模糊圈（CoC）的判斷又出現了問題，後面跟朋友的討論就出現了雞同鴨講的情況。&lt;/p>
&lt;p>後來我回想一下整件事情的發生，我才突然驚覺自己好像因為太過於依賴 ChatGPT 的回答導致我喪失了當初多方求證的能力。儘管每個在教你使用任何大語言模型工具的課程，大多都會提到所有的 AI 工具都會有一定程度的錯誤，使用者都必需自己花時間去審慎評估。&lt;/p>
&lt;p>但是當看似高品質的資訊越來越易於取得時，求證的過程就會漸漸的被省略，至少我是如此。&lt;/p>
&lt;p>當然影響也不僅僅只有這樣，還有包括自己在寫程式的習慣漸漸的在改變，也越來越倚靠 AI 快速先幫我打底，我再去慢慢精修的結果。又或是碰到問題，直接習慣性地先丟給 ChatGPT 的語言模型幫我做一次 Survey，這樣得到答案的效率更高。&lt;/p>
&lt;p>這樣不好嗎？很好，老實說。無論是我工作上或是生活中，效率都有提高。只是似乎，倚靠著自己“思考“的過程在慢慢地減少。&lt;/p>
&lt;figure>&lt;img src="https://timememo.lizhou31.com/some_ai_murmur/Kazz_stopThinking.webp"
 alt="Description" width="100%">&lt;figcaption>
 &lt;p>卡茲停止了思考&lt;/p>
 &lt;/figcaption>
&lt;/figure>

&lt;h2 id="關於-ai-工具應用的一些小結" class="heading-element">&lt;span>關於 AI 工具應用的一些小結&lt;/span>
 &lt;a href="#%e9%97%9c%e6%96%bc-ai-%e5%b7%a5%e5%85%b7%e6%87%89%e7%94%a8%e7%9a%84%e4%b8%80%e4%ba%9b%e5%b0%8f%e7%b5%90" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>其實這篇真的就比較偏向一些 MurMur，怕越寫焦點會越模糊掉。（其實是太久沒寫文章開始詞窮了Ｘ）之後或許會根據某些主題再多 MurMur 一點？&lt;/p>
&lt;p>儘管 AI 工具帶來了非常多的方便，但當我們有許多能力漸漸的因為這些方便而疏於使用後，究竟會帶來哪些副作用目前仍是沒有肯定的。至少對我自己來說我已經受到些許的負面的副作用影響了。&lt;/p>
&lt;p>曾經在聽了某個跟 AI 工具相關的演講，當時的講師表示:&lt;/p>
&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>引用&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">在接下來的的 AI 時代，你必須找到自己真正熱忱的事情，才能夠讓自己更能夠面對這些衝擊。&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>更進一步地說，AI 工具已經能夠滿足不少工作及格分左右的需求，剩下的就是需要靠自己的熱忱去完成更多的分數。但也可以說，當你對某些事情有熱忱時，能夠擋住實現這些熱忱的門檻已經越來越少了。例如一個毫無程式能力基礎的，甚至連 Python 要去哪裡執行都不知道的財務統計專業人員，可以通過不斷地詢問 ChatGPT 在僅僅一天之內來完成一個功能非常完整，能夠自己搜尋到各類財務資料並且自己出報告的程式。沒有繪畫能力的我，也能非常簡單地透過幾句指令，就能在我的投影片裡面加入有意義且精美的插圖。&lt;/p>
&lt;p>達成目標的門檻越來越低，但“及格”的標準也會越來越高了。我認為在接下來的時代，把握自己熱忱相關的技能，透過 AI 帶來的方便性工具來弭平可能的困難，並且用來持續精境支持自己熱忱的那些能力，不要讓輕易的讓自己的這些能力退化成能夠被輕易取代。&lt;/p>
&lt;p>這大概是，我認為接下來艱難的時代我需要學習的內容。&lt;/p></description></item><item><title>週末的一點前端小旅程</title><link>https://timememo.lizhou31.com/vue_threejs_journey/</link><pubDate>Mon, 14 Aug 2023 21:20:55 +0800</pubDate><guid>https://timememo.lizhou31.com/vue_threejs_journey/</guid><category domain="https://timememo.lizhou31.com/categories/tech_note/">技術筆記</category><description>&lt;img src="https://timememo.lizhou31.com/vue_threejs_journey/featured-image.webp" alt="featured image" referrerpolicy="no-referrer">&lt;p>&lt;em>從零開始的一點前端小旅程&lt;/em>&lt;/p>
&lt;h2 id="前言" class="heading-element">&lt;span>前言&lt;/span>
 &lt;a href="#%e5%89%8d%e8%a8%80" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>週五下班前和同事聊到公司的某個系統功能開發的想法，聊著聊著就突然來了興趣，想著坐而言不如起而行，直接上手試試看最不熟練的前端。&lt;/p>
&lt;p>由於公司是用 &lt;a href="https://vuejs.org/"target="_blank" rel="external nofollow noopener noreferrer">Vue&lt;/a> 當作開發框架，然後我想試試看 TypeScript 進行開發，因此整個開發便是在 Vue.js + &lt;a href="https://threejs.org/"target="_blank" rel="external nofollow noopener noreferrer">Three.js&lt;/a> + TypeScript 底下完成。&lt;/p>
&lt;h2 id="開發功能描述" class="heading-element">&lt;span>開發功能描述&lt;/span>
 &lt;a href="#%e9%96%8b%e7%99%bc%e5%8a%9f%e8%83%bd%e6%8f%8f%e8%bf%b0" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>先簡略描述一下系統狀態，有個 3D 模型，上面會有數個測量點顯示在模型上，如下圖所示：
&lt;figure>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/vue_threejs_journey/demo1.webp?size=large" data-thumbnail="/vue_threejs_journey/demo1.webp?size=small" data-sub-html="&lt;h2>Demo1&lt;/h2>&lt;p>模型示意圖&lt;/p>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/vue_threejs_journey/demo1.webp" alt="Demo1" srcset="https://timememo.lizhou31.com/vue_threejs_journey/demo1.webp?size=small, https://timememo.lizhou31.com/vue_threejs_journey/demo1.webp?size=medium 1.5x, https://timememo.lizhou31.com/vue_threejs_journey/demo1.webp?size=large 2x" data-title="模型示意圖" style="--width: 931px;--aspect-ratio: 931 / 508;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;figcaption class="image-caption">Demo1&lt;/figcaption>
 &lt;/figure>
然後每個點上都會有個針對這個模型的一些數值，主要就是想開發一個功能，如果點擊/搜尋到畫面上的任意測量點，會把視角移動到最適合使用者看到點的位置，如下圖所示：
&lt;figure>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/vue_threejs_journey/demo2.webp?size=large" data-thumbnail="/vue_threejs_journey/demo2.webp?size=small" data-sub-html="&lt;h2>Demo2&lt;/h2>&lt;p>功能示意圖&lt;/p>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/vue_threejs_journey/demo2.webp" alt="Demo2" srcset="https://timememo.lizhou31.com/vue_threejs_journey/demo2.webp?size=small, https://timememo.lizhou31.com/vue_threejs_journey/demo2.webp?size=medium 1.5x, https://timememo.lizhou31.com/vue_threejs_journey/demo2.webp?size=large 2x" data-title="功能示意圖" style="--width: 1004px;--aspect-ratio: 1004 / 963;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;figcaption class="image-caption">Demo2&lt;/figcaption>
 &lt;/figure>
那對我來說會有幾個難點：&lt;/p>
&lt;ol>
&lt;li>因為前端網頁以及框架的不熟悉，所以幾乎需要從零開始學習這次所需要的 Vue 框架，前端 3D 套件 Three.js，以及 TypeScript 。&lt;/li>
&lt;li>由於模型多少還是有一定的複雜度，因此在移動相機視角的時候必須根據測量點在模型上的哪個位置進行視角改變，如果測量點在模型傾斜 45 度角的位置，就必須讓視角也跟著傾斜 45 度角，才能達到最好的視角角度。&lt;/li>
&lt;li>因為希望能夠讓這份程式有重用性，以及希望嘗試一點設計方法，因此會需要在一開始就規劃一下程式架構。&lt;/li>
&lt;/ol>
&lt;h2 id="程式架構講解" class="heading-element">&lt;span>程式架構講解&lt;/span>
 &lt;a href="#%e7%a8%8b%e5%bc%8f%e6%9e%b6%e6%a7%8b%e8%ac%9b%e8%a7%a3" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;h3 id="架構簡述" class="heading-element">&lt;span>架構簡述&lt;/span>
 &lt;a href="#%e6%9e%b6%e6%a7%8b%e7%b0%a1%e8%bf%b0" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;p>主要架構大致如下：
&lt;pre class="mermaid">
classDiagram
 class BaseModel{
 model_type : model_base
 allBaseObject : Array
 search_points(x : number, y : number, z : number, d : number) Vector3
 }
 class model_base{
 &lt;&lt; interface >>
 construct_Mesh() Array
 calculate_and_compare_point(point_height : number) number
 getCameraPosition(x : number, y : number, z : number, distance : number) Vector3
 }
 class cylinder_model{
 CylinderArray : Array
 params : Array
 layer_Height : Array
 layer_TRadius : Array
 layer_BRadius : Array
 calculate_y_offset() number
 record_layer_info(height : number, tradius : number, bradius : number)
 construct_Mesh() Array
 calculate_and_compare_point(point_height : number) number
 getCameraPosition(x : number, y : number, z : number, distance : number) Vector3
 }
 class other_model{
 construct_Mesh() Array
 calculate_and_compare_point(point_height : number) number
 getCameraPosition(x : number, y : number, z : number, distance : number) Vector3
 }
 BaseModel --> model_base : Contains
 model_base &lt;|.. cylinder_model : implements
 model_base &lt;|.. other_model : implements
&lt;/pre>
&lt;template>
classDiagram
 class BaseModel{
 model_type : model_base
 allBaseObject : Array
 search_points(x : number, y : number, z : number, d : number) Vector3
 }
 class model_base{
 &lt;&lt; interface >>
 construct_Mesh() Array
 calculate_and_compare_point(point_height : number) number
 getCameraPosition(x : number, y : number, z : number, distance : number) Vector3
 }
 class cylinder_model{
 CylinderArray : Array
 params : Array
 layer_Height : Array
 layer_TRadius : Array
 layer_BRadius : Array
 calculate_y_offset() number
 record_layer_info(height : number, tradius : number, bradius : number)
 construct_Mesh() Array
 calculate_and_compare_point(point_height : number) number
 getCameraPosition(x : number, y : number, z : number, distance : number) Vector3
 }
 class other_model{
 construct_Mesh() Array
 calculate_and_compare_point(point_height : number) number
 getCameraPosition(x : number, y : number, z : number, distance : number) Vector3
 }
 BaseModel --> model_base : Contains
 model_base &lt;|.. cylinder_model : implements
 model_base &lt;|.. other_model : implements
&lt;/template>&lt;/p>
&lt;p>我希望利用 interface 來隔開實際上不同模型的實現方式，如可以利用圓柱層層疊加產生的模型、球體模型、透過外部引入的模型等&amp;hellip;
最後再透過最外層的 BaseModel 操作整個模型，讓上層應用的開發者在操作時不必知道實際上操作的是哪個模型，這樣之後再增加模型時也會比較好增加，只需要增加新的 Class 並實現 Interface 中的方法。（如 other_model）&lt;/p>
&lt;div class="details admonition tip open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-regular fa-lightbulb" aria-hidden="true">&lt;/i>提示&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;ol>
&lt;li>實際上這應該是 Abstract factory pattern&lt;/li>
&lt;li>也是因為 TypeScript 有 interface 所以我才決定用 TypeScript 而不是 Javascript&lt;/li>
&lt;/ol>
&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>大概的程式碼檔案結構如下&lt;/p>
&lt;ul>
&lt;li>src/components/
&lt;ul>
&lt;li>HelloWorld.vue &amp;mdash;&amp;gt; 主要視圖和 Vue 掛載&lt;/li>
&lt;li>ts/
&lt;ul>
&lt;li>TBaseModel.ts &amp;mdash;&amp;gt; 這次主要程式碼，司職模型的建構以及計算&lt;/li>
&lt;li>TData.ts &amp;mdash;&amp;gt; 毫無反應，就是一個紀錄 Data 的檔案&lt;/li>
&lt;li>TEngine.ts &amp;mdash;&amp;gt; &lt;a href="https://www.cnblogs.com/wjw1014/p/16825565.html"target="_blank" rel="external nofollow noopener noreferrer">網路上文章&lt;/a>參考的 Three.js 渲染程式&lt;/li>
&lt;li>THelper.ts &amp;mdash;&amp;gt; &lt;a href="https://www.cnblogs.com/wjw1014/p/16825565.html"target="_blank" rel="external nofollow noopener noreferrer">網路上文章&lt;/a>參考的 Three.js 輔助程式&lt;/li>
&lt;li>TLights.ts &amp;mdash;&amp;gt; &lt;a href="https://www.cnblogs.com/wjw1014/p/16825565.html"target="_blank" rel="external nofollow noopener noreferrer">網路上文章&lt;/a>參考的 Three.js 光線程式&lt;/li>
&lt;li>TPoints.ts &amp;mdash;&amp;gt; 用來生成測量點模型&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="模型分類" class="heading-element">&lt;span>模型分類&lt;/span>
 &lt;a href="#%e6%a8%a1%e5%9e%8b%e5%88%86%e9%a1%9e" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;p>考量到會有不同的模型，因此我先設想了幾個可能性：&lt;/p>
&lt;ul>
&lt;li>圓柱模型：此分類主要特色為透過軸心一樣的圓柱體（包含上下圓半徑不同的圓柱體）來組成模型，用圓柱座標系能夠輕易描述&lt;/li>
&lt;li>球體模型：利用球座標建立的模型系列&lt;/li>
&lt;li>複雜模型：透過直接外部引入模型檔的方式進行建立的模型系列&lt;/li>
&lt;/ul>
&lt;p>目前手上的模型資料大部分都是由第一個模型組成，因此這次會主要建立圓柱模型。&lt;/p>
&lt;p>利用 Three.js 圓柱體模型( CylinderGeometry 類 )的彈性（上下半徑可以不同），在建立圓柱體模型時可以利用不同層疊加的方式建立出多樣化的模型，如上圖的錐形實際上就是利用兩個圓柱體實現而成。&lt;/p>
&lt;p>但在建立模型類時希望能夠操作同樣一個實體，透過參數自動進行調整就能讓整體的模型順利建立。&lt;/p>
&lt;p>例如順序傳入第一層上半徑、下半徑、高，第二層上半徑、下半徑、高，然後就能自動建立出模型。&lt;/p>
&lt;p>因此 cylinder_model class 的建構子如下：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-TypeScript" data-lang="TypeScript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">constructor&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">params&lt;/span>: &lt;span class="kt">Array&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">number&lt;/span>&lt;span class="p">&amp;gt;)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">params&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">params&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">index&lt;/span>: &lt;span class="kt">number&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">params&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">index&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="nx">params&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">CylinderHeight&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">params&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">index&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">CylinderTopRadius&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">params&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">index&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">CylinderButtomRadius&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">params&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">index&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">y_offset&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">calculate_y_offset&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">CylinderHeight&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1">// 求出每一層的起始高度
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cm">/* 建立 各層 CylinderGeometry 實體 */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">CylinderArray&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">push&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">new&lt;/span> &lt;span class="nx">CylinderGeometry&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">CylinderTopRadius&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">CylinderButtomRadius&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">CylinderHeight&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">32&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">translate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">y_offset&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cm">/* 每層高度計算方式 */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cm">/*
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * 若共 N 層，每層高度為 H_k，k = [1,N]
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * 則第 K 層的高度偏移為 SUM(H_k) 當 k=[1,K-1]，再加上 0.5 * H_K 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> */&lt;/span> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">record_layer_info&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">CylinderHeight&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">CylinderTopRadius&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">CylinderButtomRadius&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1">// 紀錄每一層的數據
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span> 
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>可以看到建構子傳入為一個 number array，裡面依序存放著從最底層至最高層的高，上半徑，下半徑。&lt;/p>
&lt;p>而由於會需要計算出每一層的起始高度，&lt;code>calculate_y_offset()&lt;/code>則是用來實現計算每層累積高度的方法。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-TypeScript" data-lang="TypeScript">&lt;span class="line">&lt;span class="cl">&lt;span class="cm">/* 簡單計算每層起始高度 */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">calculate_y_offset&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">current_height&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kt">number&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">height&lt;/span>: &lt;span class="kt">number&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kd">let&lt;/span> &lt;span class="nx">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="nx">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">CylinderArray&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="nx">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">height&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">params&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">i&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">height&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mf">0.5&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="nx">current_height&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>計算每層起始高度的公式如下：&lt;/p>
&lt;p>若 $H_i$ 代表每層的高度，$i\in(1,N)$，而目前要計算第 $K$ 層的高度，$1 \leqq K \leqq N$，則第$K$層起始高度為：
$$\sum_{1}^{K-1} H_i+\frac{1}{2}H_K$$&lt;/p>
&lt;p>最後為了之後計算相機移動座標方便，先記錄下每層的三個參數資訊。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-TypeScript" data-lang="TypeScript">&lt;span class="line">&lt;span class="cl">&lt;span class="cm">/* 記錄每層資料 */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">record_layer_info&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">height&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">tradius&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">bradius&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">layer_Height&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">push&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">height&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">layer_TRadius&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">push&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">tradius&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">layer_BRadius&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">push&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">bradius&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="計算相機座標" class="heading-element">&lt;span>計算相機座標&lt;/span>
 &lt;a href="#%e8%a8%88%e7%ae%97%e7%9b%b8%e6%a9%9f%e5%ba%a7%e6%a8%99" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;p>上面終於建立好模型了（實際上省略不少部分，但簡單來說就是建立了:rofl:）&lt;/p>
&lt;p>那接下來終於能開發主要的功能了，讓相機（視角）移動到所選點位的正前方。&lt;/p>
&lt;p>首先要確定一下“正前方“的定義，如果選的點位是在與 XZ 平面垂直的地方，那相機直接移動到距離點位同高度並且平視即可。
&lt;figure>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/vue_threejs_journey/camera_p1.webp?size=large" data-thumbnail="/vue_threejs_journey/camera_p1.webp?size=small" data-sub-html="&lt;h2>Camera_p1&lt;/h2>&lt;p>垂直於平面示意圖&lt;/p>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/vue_threejs_journey/camera_p1.webp" alt="Camera_p1" srcset="https://timememo.lizhou31.com/vue_threejs_journey/camera_p1.webp?size=small, https://timememo.lizhou31.com/vue_threejs_journey/camera_p1.webp?size=medium 1.5x, https://timememo.lizhou31.com/vue_threejs_journey/camera_p1.webp?size=large 2x" data-title="垂直於平面示意圖" style="--width: 1621px;--aspect-ratio: 1621 / 1000;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;figcaption class="image-caption">Camera_p1&lt;/figcaption>
 &lt;/figure>
但是如果所選點位是和平面有夾角的，那是觀測最佳視角就應該有相應的傾斜角度，使相機位置就會需要進行偏移計算。
&lt;figure>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/vue_threejs_journey/camera_p2.webp?size=large" data-thumbnail="/vue_threejs_journey/camera_p2.webp?size=small" data-sub-html="&lt;h2>Camera_p2&lt;/h2>&lt;p>與平面有夾角示意圖&lt;/p>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/vue_threejs_journey/camera_p2.webp" alt="Camera_p2" srcset="https://timememo.lizhou31.com/vue_threejs_journey/camera_p2.webp?size=small, https://timememo.lizhou31.com/vue_threejs_journey/camera_p2.webp?size=medium 1.5x, https://timememo.lizhou31.com/vue_threejs_journey/camera_p2.webp?size=large 2x" data-title="與平面有夾角示意圖" style="--width: 1851px;--aspect-ratio: 1851 / 1000;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;figcaption class="image-caption">Camera_p2&lt;/figcaption>
 &lt;/figure>&lt;/p>
&lt;p>那觀測的角度我認為是以視線垂直於平面為最佳觀測角度，因此底下會以這個角度設計。&lt;/p>
&lt;p>首先要解決的是，必須先計算出選擇的點在哪層圓柱體上，才能夠根據圓柱體的參數進行視角的計算，好在圓柱體模型要確認層數只需要利用 Y 軸進行判斷即可。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-TypeScript" data-lang="TypeScript">&lt;span class="line">&lt;span class="cl">&lt;span class="cm">/* 計算傳入的點在哪一層 */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">calculate_and_compare_point&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">pointX&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">PointY&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">PointZ&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">result&lt;/span>: &lt;span class="kt">number&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cm">/* 線性比較高度 */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">PointY&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">PointY&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">PointY&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">layer_Height&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">result&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">result&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">result&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>計算出點位在哪層之後就能開始計算相機位置，那先給個計算示意圖：
&lt;figure>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/vue_threejs_journey/camera_p_calculate.webp?size=large" data-thumbnail="/vue_threejs_journey/camera_p_calculate.webp?size=small" data-sub-html="&lt;h2>camera_p_calculate&lt;/h2>&lt;p>計算示意圖&lt;/p>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/vue_threejs_journey/camera_p_calculate.webp" alt="camera_p_calculate" srcset="https://timememo.lizhou31.com/vue_threejs_journey/camera_p_calculate.webp?size=small, https://timememo.lizhou31.com/vue_threejs_journey/camera_p_calculate.webp?size=medium 1.5x, https://timememo.lizhou31.com/vue_threejs_journey/camera_p_calculate.webp?size=large 2x" data-title="計算示意圖" style="--width: 1000px;--aspect-ratio: 1000 / 1005;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;figcaption class="image-caption">camera_p_calculate&lt;/figcaption>
 &lt;/figure>&lt;/p>
&lt;p>$TR$ 是上半徑，$BR$ 是下半徑，$H$ 是層的高度，$D$ 是相機距離量測點的距離。&lt;/p>
&lt;p>其中 $\theta$ 是相機與水平的夾角，而我們其實主要要求的是 $h&amp;rsquo;$ 和 $r&amp;rsquo;$，也就是相機對於觀測點的 Ｙ 軸偏移量以及 R 軸偏移量（於圓柱座標系)。&lt;/p>
&lt;p>求出 $h&amp;rsquo;$ 的公式如下：
$$h&amp;rsquo;=D*\sin{\theta}$$
而求出 $r&amp;rsquo;$ 的公式如下：
$$r&amp;rsquo;=D*\cos{\theta}$$
而 $\theta$ 則可以透過下式算出：
$$\theta=\arctan{(\frac{TR-BR}{H})}$$
則最後合併式子：
$$h&amp;rsquo;=D*\sin{[\arctan{(\frac{TR-BR}{H})}]}$$
$$r&amp;rsquo;=D*\cos{[\arctan{(\frac{TR-BR}{H})}]}$$
得到 Y 軸偏移量後，還需要進行座標轉換，先將觀測點的圓柱座標 $Point = (r,\theta,y)$ 求出，再根據 y 軸的偏移量進行修正 $Camera = (r+r&amp;rsquo;,\theta,y-h&amp;rsquo;)$，就能得到最後的相機位置。&lt;/p>
&lt;p>程式實現如下&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-TypeScript" data-lang="TypeScript">&lt;span class="line">&lt;span class="cl">&lt;span class="cm">/* 計算出傳入的點會需要將照相機移動到何處 */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">getCameraPosition&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">pointX&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">pointY&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">pointZ&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">distance&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cm">/* 先確定點在哪層 */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">layer_index&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">calculate_and_compare_point&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">pointX&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">pointY&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">pointZ&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cm">/* 計算偏移角度 theta */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">theta&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">Math&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">atan&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">layer_TRadius&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">layer_index&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">layer_BRadius&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">layer_index&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">/&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">layer_Height&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">layer_index&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cm">/* 計算照相機的 y 軸偏移(於圓柱座標系) */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">camera_y_offset&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">distance&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="nb">Math&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">sin&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">theta&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cm">/* 計算照相機的 r 軸偏移(於圓柱座標系) */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">camera_r_offset&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">distance&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="nb">Math&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">cos&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">theta&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cm">/* 將座標轉換回笛卡兒座標 */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">c&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">Cylindrical&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="nx">setFromCartesianCoords&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">pointX&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">pointY&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">pointZ&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">c_new&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">Cylindrical&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">c&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">radius&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">camera_r_offset&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">c&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">theta&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">c&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">y&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="nx">camera_y_offset&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">let&lt;/span> &lt;span class="nx">v&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">Vector3&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="nx">setFromCylindrical&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">c_new&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">v&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;div class="details admonition tip open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-regular fa-lightbulb" aria-hidden="true">&lt;/i>提示&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;p>當 $TR = BR$ 的時候，由於 $\arctan{0} = 0$，而 $sin{0}=0$ 且 $cos{0}=1$，則回歸到 Y 軸偏移量為零，R 為 1 的簡單狀態。&lt;/p>
&lt;p>而 $TR &amp;lt; BR$ 時，由於 $\arctan{-\theta}=-\arctan{\theta}$，而 $\sin{-\theta}=-\sin{\theta}$ 且 $\cos{-\theta}=\cos{\theta}$，因此完全符合實際狀況。&lt;/p>
&lt;/div>
 &lt;/div>
&lt;/div>
&lt;h3 id="interface" class="heading-element">&lt;span>Interface&lt;/span>
 &lt;a href="#interface" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;p>最後講到利用 interface 實現的好處，我建立一個 BaseModel 用來控制所有實現介面的類別。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-TypeScript" data-lang="TypeScript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">export&lt;/span> &lt;span class="kr">class&lt;/span> &lt;span class="nx">BaseModel&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">model_type&lt;/span>: &lt;span class="kt">model_base&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">allBaseObject&lt;/span>: &lt;span class="kt">Array&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">Mesh&lt;/span>&lt;span class="p">&amp;gt;;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">constructor&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">model_type&lt;/span>: &lt;span class="kt">model_base&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">model_type&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">model_type&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">allBaseObject&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">model_type&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">construct_Mesh&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cm">/* Demo用方法，傳入需要聚焦的點位和希望相機離目標的距離，回傳相機該移動到的地方 */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">search_points&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">x&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">y&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">z&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">d&lt;/span>: &lt;span class="kt">number&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">Vector3&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">model_type&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">getCameraPosition&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">y&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">z&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">d&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>當我想建立一個圓柱形模型類別時，我只需要如下建立資料並傳入相應的參數：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-TypeScript" data-lang="TypeScript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">let&lt;/span> &lt;span class="nx">test_base_model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">BaseModel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span> &lt;span class="nx">cylinder_model&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">[&lt;/span>&lt;span class="nx">data&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ConeHeight&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">data&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ConeTopRadius&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">data&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ConeButtomRadius&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">data&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Height&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">data&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">TopRadius&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">data&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ButtomRadius&lt;/span>&lt;span class="p">]))&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>這樣我之後在操作模型時，只需要操作最外層的模型類別，並不用在意到底現在是哪個種類的模型實現，如下：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-TypeScript" data-lang="TypeScript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">let&lt;/span> &lt;span class="nx">v&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">basemodel&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">search_points&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">point&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">point&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">y&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">point&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">z&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">10&lt;/span>&lt;span class="p">)&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="結語" class="heading-element">&lt;span>結語&lt;/span>
 &lt;a href="#%e7%b5%90%e8%aa%9e" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>最後是功能展示影片：&lt;/p>
&lt;p>&lt;div class="fi-row"> 
&lt;video width=100% controls autoplay>
 &lt;source src="./DemoV.webm" type="video/webm">
 Your browser does not support the video tag. 
&lt;/video>
&lt;/div>
老實說這次的 Vue 輕旅程還滿有趣的，難得的在一定的時間沈浸在完全的程式裡面進行開發（可憐的嵌入式工程師總需要編寫程式邊確定硬體有沒有出錯:cry:）&lt;/p>
&lt;p>再加上能夠多少測試一下一些開發的方式，其實收穫還滿大的:laughing:&lt;/p>
&lt;p>原始程式碼會放在 &lt;a href="https://github.com/Lizhou31/vue-threejs"target="_blank" rel="external nofollow noopener noreferrer">github&lt;/a> 上。&lt;/p></description></item><item><title>讀後感 - The Clean Coder（ㄧ）</title><link>https://timememo.lizhou31.com/the_clean_coder_reflection_1/</link><pubDate>Fri, 28 Jul 2023 13:35:24 +0800</pubDate><guid>https://timememo.lizhou31.com/the_clean_coder_reflection_1/</guid><category domain="https://timememo.lizhou31.com/categories/book_reflection/">讀後感</category><description>&lt;img src="https://timememo.lizhou31.com/the_clean_coder_reflection_1/featured-image.webp" alt="featured image" referrerpolicy="no-referrer">&lt;p>&lt;em>The Clean Coder 第一章讀後感&lt;/em>&lt;/p>
&lt;h2 id="前言" class="heading-element">&lt;span>前言&lt;/span>
 &lt;a href="#%e5%89%8d%e8%a8%80" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>最近又重新把 The Clean Coder 重新拿出來讀了一遍，根據這一年工作的一些經歷，又有更多的思考和體悟（？打算來記錄一下。&lt;/p>
&lt;p>因為 The Clean Coder 太多章節，我認為許多章節都很值得單獨拿出來寫，所以可能這也會是一整個系列的讀書心得。&lt;/p>
&lt;p>先簡短簡介一下 The Clean Coder 這本書，中譯 &lt;em>&lt;strong>&amp;ldquo;無瑕的程式碼番外篇-專業程式設計師的生存之道&amp;rdquo;&lt;/strong>&lt;/em>，作者為 Robert C. Martin，是很著名的軟體工程師，以提倡許多軟體設計原則和開發方式聞名。這本書其實也是 &lt;em>&lt;strong>&amp;ldquo;The Clean Code&amp;rdquo;&lt;/strong>&lt;/em> 的番外篇，主要是在敘述如何成為一名“專業的”程式設計師。&lt;/p>
&lt;p>這本書我認為其實也不僅僅只適合工程師閱讀，其中有不少對於工作上專業態度的解釋與例子，也很適用於其他情況。&lt;/p>
&lt;h2 id="be-careful-what-you-ask-for" class="heading-element">&lt;span>Be careful what you ask for&lt;/span>
 &lt;a href="#be-careful-what-you-ask-for" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>第一個章節，主要就是要探討到底何謂 &lt;em>Professionalism&lt;/em> 以及一個追逐專業態度的人該有的表現。&lt;/p>
&lt;p>但是最重要的是 &lt;strong>&amp;ldquo;What you ask for&amp;rdquo;&lt;/strong>，追求專業一定不是一件簡單且輕鬆的事情，會需要承擔的責任一定會比不用追求專業來的沈重，但我認為不追求專業並不能讓自己逃避掉什麼，因為該負的責任本身就會隨著自己的年齡增長開始受到外界的期待，如果持續抱持著&amp;quot;不專業&amp;quot;的態度，僅僅只會讓自己與社會期待脫節，而到那個時候所需要付出的心理壓力並不會更小。&lt;/p>
&lt;p>就如同社會期待一名父親需要做好養育孩子，教育孩子，以及與伴侶扶持家庭的責任，或許可能因為很多原因在身為父親的角色不夠“專業”，但是社會的期待如此，外界看到的結論也只會是你有沒有做好這件事情。你可以選擇在其他的部分上“專業”下心力，但所有的都是取決於 &lt;strong>&amp;ldquo;What you ask for&amp;rdquo;&lt;/strong>，而你選擇的道路，就會承擔相應的責任。&lt;/p>
&lt;p>稍微離題了，但總之，選擇了一項專業，隨之而來的就是相應的責任。&lt;/p>
&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>引用&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;p>&lt;em>&lt;strong>&amp;ldquo;You can&amp;rsquo;t take pride and honor in something that you can&amp;rsquo;t be held accountable.&amp;rdquo;&lt;/strong>&lt;/em>&lt;/p>
&lt;p>&lt;em>&lt;strong>&amp;ldquo;Professionalism is all about taking reponsibility.&amp;rdquo;&lt;/strong>&lt;/em>&lt;/p>
&lt;p>&lt;em>&amp;ndash; &amp;laquo;The Clean Coder&amp;raquo;&lt;/em>&lt;/p>
&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>拿我自身為例，我在公司裡因為本身有一點相關背景和知識，所以時常擔任著公司在做相關決策時的諮詢討論者。從一項 Project 的功能增加，時程預估；又或是一個產品的品質控管，或是一項技術的引入與否，很常都會徵求我的意見。&lt;/p>
&lt;p>對，這是我的專業，我願意這樣想，但隨之而來的是責任的沈重感。當我認為這是我的專業並給出我的建議時，我就該付出相應的責任，因為每句話都可能影響到整個公司接下來的發展，以及大家以後吃不吃得飽飯。&lt;/p>
&lt;p>我很聰明嗎？並沒有；我很有經驗嗎？更不可能有。那當我決定給出我的建議，我的“專業”看法前，我就需要花很大量的時間去思考，去搜集各種資訊，去詢問各種比我更有經驗的專家，去佐證我給出的建議是有跡可循的，是可以付諸實行的。&lt;/p>
&lt;p>然後更重要的是，我要有心理準備是，我如果犯錯了，我就該承擔責任。&lt;/p>
&lt;h2 id="所謂專業人士就是能對自己錯誤負責的人" class="heading-element">&lt;span>所謂專業人士，就是能對自己錯誤負責的人&lt;/span>
 &lt;a href="#%e6%89%80%e8%ac%82%e5%b0%88%e6%a5%ad%e4%ba%ba%e5%a3%ab%e5%b0%b1%e6%98%af%e8%83%bd%e5%b0%8d%e8%87%aa%e5%b7%b1%e9%8c%af%e8%aa%a4%e8%b2%a0%e8%b2%ac%e7%9a%84%e4%ba%ba" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;div class="details admonition abstract open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-clipboard-list" aria-hidden="true">&lt;/i>摘要&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;em>It is the lot of a professional to be accountable for errors even though errors are virtually certain. So, my aspiring professional, the first thing you must practice is apologizing. &lt;strong>Apologies are necessary, but insufficient. You cannot simply keep making the same errors over and over.&lt;/strong> As you mature in your profession, your error rate should rapidly decrease towards the asymptote of zero. It won&amp;rsquo;t ever get to zero, but it is your reponsibility to get as close as possible to it.&lt;/em>&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>如同上述書中所言，人不可能完全不犯錯，沒有人永遠保證自己犯錯的機率為零，但是專業就體現在由於經驗的累積和持續不斷的修正，犯錯機率會持續下降直到趨近於零。&lt;/p>
&lt;p>&lt;figure>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/the_clean_coder_reflection_1/Zero_would_be_nice.webp?size=large" data-thumbnail="/the_clean_coder_reflection_1/Zero_would_be_nice.webp?size=small" data-sub-html="&lt;h2>Zero would be nice&lt;/h2>&lt;p>Oppenheimer 預告中討論引爆核彈毀滅世界的機率&lt;/p>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/the_clean_coder_reflection_1/Zero_would_be_nice.webp" alt="Zero would be nice" srcset="https://timememo.lizhou31.com/the_clean_coder_reflection_1/Zero_would_be_nice.webp?size=small, https://timememo.lizhou31.com/the_clean_coder_reflection_1/Zero_would_be_nice.webp?size=medium 1.5x, https://timememo.lizhou31.com/the_clean_coder_reflection_1/Zero_would_be_nice.webp?size=large 2x" data-title="Oppenheimer 預告中討論引爆核彈毀滅世界的機率" style="--width: 1920px;--aspect-ratio: 1920 / 1080;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;figcaption class="image-caption">Zero would be nice&lt;/figcaption>
 &lt;/figure>&lt;/p>
&lt;p>然後當犯錯的時候，大方承認自己的錯誤並且找到該修正的點。如果是自己疏失的錯誤，要狠狠地記上一筆（心裡面），然後提醒自己下次需要注意。但如果不是自己疏失，可能是因為外界因素的錯誤，其實也是需要修正的。&lt;/p>
&lt;p>我認為永遠不該把任何的錯誤結果 &lt;strong>僅僅&lt;/strong> 歸咎於外界因素，例如電腦當機，天氣太熱。這些可以是 &lt;strong>&amp;ldquo;原因&amp;rdquo;&lt;/strong>，但不能是 &lt;strong>&amp;ldquo;結果&amp;rdquo;&lt;/strong>。永遠無法完全控制外界的干擾因素，只能去適應外界的干擾。&lt;/p>
&lt;p>舉個例子，曾經有次公司產品出外 Demo 時意外發生了電腦無故無法開機，最後查證是電池沒電的問題，但是我們在前一天都確認過電量和所有狀態都是 OK 的了，怎麼會有這種問題？&lt;/p>
&lt;p>後來才發現可能是有其他同事改過電腦設定導致關機程序改變，因而並沒有完全進入關機，只是休眠狀態，我們也沒有注意到，就造成了錯誤的結果。&lt;/p>
&lt;p>這是我們犯下的錯誤嗎？不完全是。但是這是我們應該負起的責任，因此我們馬上重新審視了外出工作的前置作業檢查，把有可能的出錯情況降到最低。&lt;/p>
&lt;p>那要應對不同的錯誤進行改正，需要的就是不斷的學習。&lt;/p>
&lt;h2 id="了解自己的領域並堅持學習" class="heading-element">&lt;span>了解自己的領域並堅持學習&lt;/span>
 &lt;a href="#%e4%ba%86%e8%a7%a3%e8%87%aa%e5%b7%b1%e7%9a%84%e9%a0%98%e5%9f%9f%e4%b8%a6%e5%a0%85%e6%8c%81%e5%ad%b8%e7%bf%92" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>學習很重要，尤其對追求專業來說，更為重要。除了理解新知識，也需要去回顧歷史。&lt;/p>
&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>引用&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;em>Remember Santayana&amp;rsquo;s curse: &lt;strong>&amp;ldquo;Those who cannot remember the past are condemned to repeat it.&amp;rdquo;&lt;/strong> &amp;ndash; &amp;laquo;The Clean Code&amp;raquo;&lt;/em>&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>過去的知識並不是一文不值，更多的是能夠讓我們理解到知識發展的脈絡，讓以後的路更加清晰。&lt;/p>
&lt;p>當然更重要的是需要在自己的領域深耕並堅持學習，其中包含兩個方面：&lt;/p>
&lt;h3 id="理解自己的領域" class="heading-element">&lt;span>理解自己的領域&lt;/span>
 &lt;a href="#%e7%90%86%e8%a7%a3%e8%87%aa%e5%b7%b1%e7%9a%84%e9%a0%98%e5%9f%9f" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;p>專業就是在自己的領域有著一定程度深耕，就如書中建議軟體工程師需要理解的內容：&lt;/p>
&lt;div class="details admonition abstract open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-clipboard-list" aria-hidden="true">&lt;/i>摘要&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;p>&lt;em>Here is a &lt;strong>minimal&lt;/strong> list of the things that every software professional should be conversant with:&lt;/em>&lt;/p>
&lt;ul>
&lt;li>&lt;em>Design patterns. You ought to be able to decribe all 24 patterns in the GOF book and have a working knoledge of many of the patterns in the POSA books.&lt;/em>&lt;/li>
&lt;li>&lt;em>Design principles. You should know the SOLID principles and have a good undersatanding of the component principle.&lt;/em>&lt;/li>
&lt;li>&lt;em>Methods. You should understand XP, Scrum, Lean, Kanban, Waterfall, Structured Analysis, and Structured Designed.&lt;/em>&lt;/li>
&lt;li>&lt;em>Disclilines. You should pratice TDD, Object-Oriented design, Structured Programming, Continous Integration, and Pair Programming.&lt;/em>&lt;/li>
&lt;li>&lt;em>Artifacts. You should know how to use: UML, DFDs, Structure Charts, PetriNets, State Transition Diagrams and Tables, flow charts, and decision tables.&lt;/em>&lt;/li>
&lt;/ul>&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>真的慚愧，我上述有很多都很不了解，看來需要認真惡補惡補。&lt;/p>
&lt;p>另外，除了 &lt;strong>“自己的領域”&lt;/strong>，書中也有提到需要了解 &lt;strong>“業務領域”&lt;/strong>，開發什麼，就必須了解相對應的業務領域。&lt;/p>
&lt;p>我今天想開發一個工業應用上的自動化設備，除了理解本身軟體開發的領域，也需要去理解到底工業自動化都是怎麼設計的，需要怎麼樣的連接接口，應用設備。我不需要成為那個領域的專業人士，但我一定需要具備能與相關領域專業人士溝通的能力。&lt;/p>
&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>引用&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;em>&amp;ldquo;It is worst kind of unprofessional behavior to simply code from a spec without understanding why that spec makes sense to the business. Rather, you should know enough about the domain to be able to recognize and challenge specification errors.&amp;rdquo; &amp;ndash; &amp;laquo;The Clean Coder&amp;raquo;&lt;/em>&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>好像可以參考領域驅動開發 (Domain-Driven Design,DDD) 的相關知識。因為很多時候問題並不是寫寫程式就能夠簡單解決的，會需要更多的專業知識支持，僅僅只是固守自己的專業是沒有用的，還需要具備與其他專業溝通的能力。&lt;/p>
&lt;h3 id="堅持學習" class="heading-element">&lt;span>堅持學習&lt;/span>
 &lt;a href="#%e5%a0%85%e6%8c%81%e5%ad%b8%e7%bf%92" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>引用&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;em>&amp;ldquo;Would you visit a doctor who did not keep current with medical journals? Would you hire a tax lawyer who did not keep current wth the tax laws and precedents? Why should employers hire developers who don&amp;rsquo;t keep current?&amp;rdquo; &amp;ndash; &amp;laquo;The Clean Coder&amp;raquo;&lt;/em>&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>堅持學習除了學習新知識以外，還需要堅持反覆練習。本書作者有提到他會使用一種 &amp;ldquo;kata&amp;rdquo; 來持續反覆練習已有的技巧，保持技巧成熟。並非使用難以解決的問題，而是使用已知解決但疏於練習的問題，來增加熟練度。&lt;/p>
&lt;div class="details admonition abstract open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-clipboard-list" aria-hidden="true">&lt;/i>摘要&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;em>The point of doing the kata is not of figure out how to solve the problem you know how to do that already. The point of the kata is to train your finger and your brain&lt;/em>&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>這也是我目前需要增進的地方，很多東西我儘管都知道要怎麼做，但是真正上手的時候也都會需要卡一陣子才能夠真的寫出來。&lt;/p>
&lt;h2 id="修改與測試" class="heading-element">&lt;span>修改與測試&lt;/span>
 &lt;a href="#%e4%bf%ae%e6%94%b9%e8%88%87%e6%b8%ac%e8%a9%a6" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>好的程式碼應該保持靈活可維護的軟體結構，而如果想要讓程式碼靈活，則必須時常去修改它。&lt;/p>
&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>引用&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;em>&amp;ldquo;If you want your software to be flexible, you have to flex it!&amp;rdquo; &amp;ndash; &amp;laquo;The Clean Code&amp;raquo;&lt;/em>&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>而能保證修改後不會破壞整個程式的運行結構，就需要建立良好的測試環境以及流程。書中建議，不，是要求要做到覆蓋 100% 的單元測試，去測試每行程式碼，這樣才能保證每次修改後不會產生預期外的錯誤。&lt;/p>
&lt;p>而要有辦法做到覆蓋率如此高的測試，就需要在設計階段就要有良好的模組化思考和測試驅動開發思維（Test-Driven Developement, TDD）&lt;/p>
&lt;h2 id="謙遜" class="heading-element">&lt;span>謙遜&lt;/span>
 &lt;a href="#%e8%ac%99%e9%81%9c" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>書中提到，程式設計是一門及其自負的行為，畢竟程式設計師們是本質上是一名創作者，透過自己的程式去構成相應的結果。&lt;/p>
&lt;p>我認為的確如此，我們需要對自己寫出的每行程式極度自信，因為花了時間去理解了到底寫了什麼東西，並且經過的大量測試，那是應該要對自己的程式抱持著十分的自信。而這種自信的確也是一種自負的狀態。&lt;/p>
&lt;p>但這種自負是建立在，因為需要謙遜地去對待過去的所有錯誤，以及小心的去看待每一行自己寫出來的程式，所以才會有這種心態。而每當發生錯誤時，更要毫不保留的去承認自己的錯誤，然後去找出問題。&lt;/p>
&lt;p>專業人士是謙遜且自信的，對待所有未知謙遜且小心，而在已知的地方則自信並大膽。&lt;/p>
&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;我保證這部分可行&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>這是我很常對我的組員說的:rofl:，儘管我離真正的專業人士還差得遠呢！&lt;/p></description></item><item><title>RT_Thread 學習紀錄（一）</title><link>https://timememo.lizhou31.com/learning_rt_thread_1/</link><pubDate>Fri, 21 Jul 2023 20:44:24 +0800</pubDate><guid>https://timememo.lizhou31.com/learning_rt_thread_1/</guid><category domain="https://timememo.lizhou31.com/categories/tech_note/">技術筆記</category><description>&lt;img src="https://timememo.lizhou31.com/learning_rt_thread_1/featured-image.webp" alt="featured image" referrerpolicy="no-referrer">&lt;p>&lt;em>初探 RT-Thread&lt;/em>&lt;/p>
&lt;h2 id="緣起" class="heading-element">&lt;span>緣起&lt;/span>
 &lt;a href="#%e7%b7%a3%e8%b5%b7" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>從大學上過作業系統（OS）課程以後，對於整個系統運作就一直抱有一種很不明的情愫（？&lt;/p>
&lt;p>透過一段程式調度整個硬體設備，包括邏輯運算中樞，各種通訊界面，還有控制外部週邊單元，還要應付&lt;del>毛病一堆&lt;/del>的使用者，如果把作業系統放在現實生活根本就是神一般的人物吧？&lt;/p>
&lt;p>總之，在學到作業系統以後對於運用和編寫作業系統這件事一直都抱有憧憬。&lt;/p>
&lt;p>&lt;figure>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/learning_rt_thread_1/Kira.webp?size=large" data-thumbnail="/learning_rt_thread_1/Kira.webp?size=small" data-sub-html="&lt;h2>Kira&lt;/h2>&lt;p>我絕對不會說其實最早啟發我作業系統幻想的是他&lt;/p>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/learning_rt_thread_1/Kira.webp" alt="Kira" srcset="https://timememo.lizhou31.com/learning_rt_thread_1/Kira.webp?size=small, https://timememo.lizhou31.com/learning_rt_thread_1/Kira.webp?size=medium 1.5x, https://timememo.lizhou31.com/learning_rt_thread_1/Kira.webp?size=large 2x" data-title="我絕對不會說其實最早啟發我作業系統幻想的是他" style="--width: 1920px;--aspect-ratio: 1920 / 1028;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;figcaption class="image-caption">Kira&lt;/figcaption>
 &lt;/figure>&lt;/p>
&lt;p>後來大學開始使用 Linux 系統，並因緣際會的學到了一些 Kernel 知識和 Kernel module 開發，對作業系統更加著迷了，但受限於 Linux 這種大型且複雜的作業系統，我也只能在旁邊摸摸皮毛過過乾癮，但總覺得參與感不夠。&lt;/p>
&lt;p>後來大學專題因為主題是 BLE Mesh，為了能夠良好的移植 Bluetooth 的協議層，接觸到了 Linux Foundation 底下的 &lt;a href="https://zephyrproject.org/"target="_blank" rel="external nofollow noopener noreferrer">Zephyr Project&lt;/a>，開始接觸並使用 RTOS，不過這時還是以應用為主。但是心底一直有個想法，應該真正的去摸清楚整個 RTOS 的實做，並且透過自己重新實現來加深理解整個作業系統的概念。但是可以說自己懶，或是一直找不到很合適的專題或機會去真正實現這個想法。&lt;/p>
&lt;p>到現在剛好在工作上碰到系統需要規劃使用 RTOS，決定正式開啟這個學習計劃。&lt;/p>
&lt;p>至於選擇 RT-Thread 也沒有什麼特別的理由，第一是程式組成順眼，至少我可以比較輕鬆的了解整個檔案架構（相比於最早接觸的 Zephyr OS，儘管功能很強，可是整個架構太多可以學習的地方讓人不知道要怎麼下手），第二是程式碼風格也很簡潔，組成也易懂，第三是 RT-Thread 有一個很簡單的內核實現 RT-Thread Nano，能夠讓我很簡單的剝離出我最想先學習的內核架構使用，並且在整合進 STM 系列生態系也簡單許多。&lt;/p>
&lt;h2 id="rt-thread-簡介" class="heading-element">&lt;span>RT-Thread 簡介&lt;/span>
 &lt;a href="#rt-thread-%e7%b0%a1%e4%bb%8b" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;div class="details admonition info open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-circle-info" aria-hidden="true">&lt;/i>資訊&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">以下內容主要出自於 &lt;a href="https://www.rt-thread.io/index.html"target="_blank" rel="external nofollow noopener noreferrer">RT-Thread&lt;/a> 官網&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>RT-Thread 是源自中國的一個開源 RTOS，主要由 C 語言撰寫，而且是使用 OOP (Object-oriented programing) 方法撰寫的。其主要 Architechture 如下：
&lt;figure>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/learning_rt_thread_1/architecture.webp?size=large" data-thumbnail="/learning_rt_thread_1/architecture.webp?size=small" data-sub-html="&lt;h2>RT-Thread Architechture&lt;/h2>&lt;p>RT-Thread Architecture 出自 : https://www.rt-thread.io/document/site/&lt;/p>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/learning_rt_thread_1/architecture.webp" alt="RT-Thread Architechture" srcset="https://timememo.lizhou31.com/learning_rt_thread_1/architecture.webp?size=small, https://timememo.lizhou31.com/learning_rt_thread_1/architecture.webp?size=medium 1.5x, https://timememo.lizhou31.com/learning_rt_thread_1/architecture.webp?size=large 2x" data-title="RT-Thread Architecture 出自 : https://www.rt-thread.io/document/site/" style="--width: 934px;--aspect-ratio: 934 / 725;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;figcaption class="image-caption">RT-Thread Architechture&lt;/figcaption>
 &lt;/figure>&lt;/p>
&lt;p>RT-Thread 的實現功能非常豐富，而我對下面幾個已實現部份感興趣：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Hard Real-time Kernel&lt;/strong> : RTOS 主要的核心功能，用這個部份來熟悉整個作業系統的運作模式&lt;/li>
&lt;li>&lt;strong>IoT Connection Components&lt;/strong> : 包括底層通訊規範（ETH、Lora&amp;hellip;）到上層的協議規範（LwIP）或是更上層的應用，透過已經實現的規範更了解通訊機制，而且也想嘗試移植其他工業用規範或應用。&lt;/li>
&lt;li>&lt;strong>Exception Handling / Log&lt;/strong> : 通常在建構整個系統，尤其是複雜的整合系統時，最麻煩的就是如何紀錄系統的錯誤，如果有良好的錯誤日誌機制，在系統執行任務出現問題時才能夠快速的定位出問題。&lt;/li>
&lt;li>&lt;strong>Network Framwork&lt;/strong> : 如上面的 IoT Connect Components 一樣。&lt;/li>
&lt;li>&lt;strong>FinSH Console&lt;/strong> : 過去在開發 bare metal 的應用時，沒有標準化輸入輸出介面真的有點麻煩，能夠蹭別人開發好的當然讚。&lt;/li>
&lt;li>&lt;strong>Key Value DB&lt;/strong> : Key-Value 結構在之前開發應用的時候很常用到，尤其是 JSON 輸出，在應用層協議真的用起來很有彈性。&lt;/li>
&lt;li>&lt;strong>Device Framework&lt;/strong> : 抽象化介面對於應用開發真的是一個福音，但是建立一個良好的設備系統真的是大學問。&lt;/li>
&lt;li>&lt;strong>POSIX API&lt;/strong> : POSIX 畢竟行之有年，而且許多應用也都是會根據 POSIX 進行開發，如果能夠移植 POSIX 對於各類應用的適配性一定有幫助。&lt;/li>
&lt;li>&lt;strong>RTI SystemView&lt;/strong> : 過去在使用 FreeRTOS 時有使用過一次 SystemView，對於圖形化整個 RTOS 運作的強大功能印象深刻。&lt;/li>
&lt;li>&lt;strong>Utest&lt;/strong> : RT-Thread 下的單元測試框架，能夠針對運行在 RT-Thread 上的程式模組進行 Unit test 並記錄結果。&lt;/li>
&lt;/ol>
&lt;p>除了上述功能以外，也對 RT-Thread 實現的一些手法感興趣，例如：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Object Oriented&lt;/strong> : RT-Thread 是使用 Object Oritened method 進行程式編寫的，並且對於內核的一些物件有特殊的機制去管理。&lt;/li>
&lt;li>&lt;strong>Kconfig&lt;/strong> : 過去對於 Linux 的內核配置選單就很感興趣，之前在 Zephyr 也體驗過，這次想深入了解到底要怎麼用。&lt;/li>
&lt;/ol>
&lt;h2 id="目前規劃" class="heading-element">&lt;span>目前規劃&lt;/span>
 &lt;a href="#%e7%9b%ae%e5%89%8d%e8%a6%8f%e5%8a%83" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>首要目的當然是希望透過理解 RT-Thread 的 Source Code 更理解整個 RTOS 乃至 OS 的概念，以及實現辦法。所以應該會先就 RT-Thread 的內核實現進行一系列學習和研究：&lt;/p>
&lt;ol>
&lt;li>內核 Object 的實現&lt;/li>
&lt;li>IPC 的實現 (Mutex, Semaphore, Event, Mailbox &amp;hellip;)&lt;/li>
&lt;li>Scheduler 和 Thread 的實現&lt;/li>
&lt;li>內存管理&lt;/li>
&lt;/ol>
&lt;p>由於目前使用的是 Nano 版本，希望能夠自己移植其他感興趣的功能上去，除上述原先 RT-Thread 標準版就有的功能以外，還想嘗試增加：&lt;/p>
&lt;ol>
&lt;li>針對整個程式（包含 Kernel 部分）的 Unit Test（目前候選是 Unity）&lt;/li>
&lt;li>DDS 的移入&lt;/li>
&lt;li>針對有限狀態機的實現&lt;/li>
&lt;/ol>
&lt;p>就，慢慢來開始建構自己想要的東西 :rofl:&lt;/p>
&lt;h2 id="後語" class="heading-element">&lt;span>後語&lt;/span>
 &lt;a href="#%e5%be%8c%e8%aa%9e" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>這篇只是簡單寫寫目前自己的規劃，也沒包含什麼太有意義（？的東西，主要是寫來督促自己，希望自己能夠持續的更新這系列文章。&lt;/p></description></item><item><title>Integer Promotions</title><link>https://timememo.lizhou31.com/talk_about_integer_promotion/</link><pubDate>Sun, 09 Jul 2023 22:32:01 +0800</pubDate><guid>https://timememo.lizhou31.com/talk_about_integer_promotion/</guid><category domain="https://timememo.lizhou31.com/categories/tech_note/">技術筆記</category><description>&lt;img src="https://timememo.lizhou31.com/talk_about_integer_promotion/featured-image.webp" alt="featured image" referrerpolicy="no-referrer">&lt;p>&lt;em>來討論一點整型提升&lt;/em>&lt;/p>
&lt;h2 id="overview" class="heading-element">&lt;span>Overview&lt;/span>
 &lt;a href="#overview" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>C語言的發明人 &lt;strong>Dennis MacAlistair Ritchie&lt;/strong> 與 &lt;strong>Kenneth Lane Thompsont&lt;/strong> 創設以下規則：
&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>引用&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;em>“A character, a short integer, or an integer bit-field, all either signed or not, or an object of enumeration type, may be used in an expression wherever an integer maybe used. &lt;strong>If an int can represent all the values of the original type, then the value is converted to int; otherwise the value is converted to unsigned int.&lt;/strong> This process is called integral promotion.”&lt;/em>&lt;/div>
 &lt;/div>
&lt;/div>&lt;/p>
&lt;p>也就是所謂的 Integer Promotion （整型提升）。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Wiki - 整型提升：
&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>Wiki&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;em>整型提升的意義在於：表達式的整型運算要在 CPU 的相應運算器件內執行，&lt;strong>CPU內整型運算器 (ALU) 的操作數的字節長度一般就是 int 的字節長度&lt;/strong>，同時也是CPU的通用暫存器的長度。因此，即使兩個 char 類型的相加，在 CPU執行時實際上也要先轉換為 CPU 內整型操作數的標準長度。通用 CPU（general-purpose CPU）是難以直接實現兩個 8比特字節直接相加運算（雖然機器指令中可能有這種字節相加指令）。所以，表達式中各種長度可能小於int長度的整型值，都必須先轉換為int或unsigned int，然後才能送入 CPU去執行運算。&lt;/em>&lt;/div>
 &lt;/div>
&lt;/div>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="c-standard-c99--n1570" class="heading-element">&lt;span>C Standard (C99 / N1570)&lt;/span>
 &lt;a href="#c-standard-c99--n1570" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>C99 中有關 integer promotions 的地方分別在：&lt;strong>§5.1.2.3&lt;/strong>, &lt;strong>§5.2.4.2.1&lt;/strong>, &lt;strong>§6.3.1.1&lt;/strong>, &lt;strong>§6.5.2.2&lt;/strong>, &lt;strong>§6.5.3.3&lt;/strong>, &lt;strong>§6.5.7&lt;/strong>, &lt;strong>§6.8.4.2&lt;/strong>
以下將不按照順序，按筆者的閱讀邏輯講解：&lt;/p>
&lt;h3 id="_6311_" class="heading-element">&lt;span>&lt;em>§6.3.1.1&lt;/em>&lt;/span>
 &lt;a href="#_6311_" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>§6.3.1.1 / 2, 3&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;p>&lt;em>The following may be used in an expression wherever an &lt;code>int&lt;/code> or &lt;code>unsigned int&lt;/code> may be used:&lt;/em>&lt;/p>
&lt;ul>
&lt;li>&lt;em>An object or expression with an integer type (other than &lt;code>int&lt;/code> or &lt;code>unsigned int&lt;/code>) whose integer conversion rank is less than or equal to the rank of &lt;code>int&lt;/code> and &lt;code>unsigned int&lt;/code>.&lt;/em>&lt;/li>
&lt;li>&lt;em>A bit-field of type &lt;code>_Bool&lt;/code>, &lt;code>int&lt;/code>, &lt;code>signed int&lt;/code>, or &lt;code>unsigned int&lt;/code>.&lt;/em>&lt;/li>
&lt;/ul>
&lt;p>&lt;em>If an &lt;code>int&lt;/code> can represent all value of the original type (as restricted by the width, for a bit-field), the value is converted to an &lt;code>int&lt;/code>; otherwise, it is converted to an &lt;code>unsigned int&lt;/code>. These are called the &lt;strong>integer promotions&lt;/strong>. All other types are unchanged by the integer promotions.&lt;/em>&lt;/p>
&lt;p>&lt;em>The integer promotions preserve value including sign. As discussed earlier, whether a “plain” &lt;code>char&lt;/code> is treated as signed is implementation-defined.&lt;/em>&lt;/p>
&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>此處講明了假設一個原始的型態能夠被 &lt;code>int&lt;/code> 表達，則會被轉換至 &lt;code>int&lt;/code>；要不然則會被轉換至 &lt;code>unsigned int&lt;/code>，此行為稱作 &lt;strong>integer promotions&lt;/strong>。&lt;/p>
&lt;p>前段也敘述了 integer promotions 會發生的情境：&lt;/p>
&lt;ol>
&lt;li>Integer type 且 Integer conversion rank 小於或等於 &lt;code>int&lt;/code> 或 &lt;code>unsigned int&lt;/code>&lt;/li>
&lt;li>bit-field type&lt;/li>
&lt;/ol>
&lt;p>並且 promotion 以後的數值是會保持著原本的正負。&lt;/p>
&lt;div class="details admonition tip open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-regular fa-lightbulb" aria-hidden="true">&lt;/i>提示&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">Integer conversion rank 同樣於 §6.3.1.1 / 1 有描述。&lt;/div>
 &lt;/div>
&lt;/div>
&lt;h3 id="_5123--11_" class="heading-element">&lt;span>&lt;em>§5.1.2.3 / 11&lt;/em>&lt;/span>
 &lt;a href="#_5123--11_" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>§5.1.2.3 / 11&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;p>&lt;em>EXAMPLE 2 In executing the fragment&lt;/em>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-c" data-lang="c">&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">char&lt;/span> &lt;span class="n">c1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">c2&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="cm">/* ... */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">c1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">c1&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">c2&lt;/span>&lt;span class="p">;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;em>the &amp;lsquo;&amp;lsquo;integer promotions&amp;rsquo;&amp;rsquo; require that the abstract machine promote the value of each variable to int size and then add the two ints and truncate the sum. Provided the addition of two chars &lt;strong>can be done without overflow&lt;/strong>, or &lt;strong>with overflow wrapping silently&lt;/strong> to produce the correct result, the actual execution need only produce the same result, possibly omitting the promotions.&lt;/em>&lt;/p>
&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>這邊用了一個例子來簡單說明了 Integer promotions，在 C Standard abstract machine model中，這段運算的 &lt;code>char c1&lt;/code>, &lt;code>char c2&lt;/code> 都會被整型提升至 int，使其不會產生 overflow 的結果，或悄悄地 wrap overflow。&lt;/p>
&lt;h3 id="_6522--6_" class="heading-element">&lt;span>&lt;em>§6.5.2.2 / 6&lt;/em>&lt;/span>
 &lt;a href="#_6522--6_" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>§6.5.2.2 / 6&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;p>&lt;em>If the expression that denote the called &lt;strong>function has a type that does not include a prototype, the integer promotions are performed on each argument, and argument that have type float are promoted to double.&lt;/strong> These are called the &lt;strong>default argument promotions.&lt;/strong> If the number of arguments does not equal the number of parameters, the behaviors is undefined. If the function is defined with a type that includes a prototype, and either the prototype ends with an ellipsis (,&amp;hellip;) or &lt;strong>the type of the arguments after promotion are are not compatible with the types of the parameters, the behavior is undefined.&lt;/strong> If the function is defined with a type that does not include a prototype, and the types of the arguments after promotion are not compatible with those of the parameters after promotion, the behavior is undefined, except for the following cases:&lt;/em>&lt;/p>
&lt;ul>
&lt;li>&lt;em>one promoted type is a signed integer type, the other promoted type is the corresponding unsigned integer type, and the value is representable in both types;&lt;/em>&lt;/li>
&lt;li>&lt;em>both types are pointers to qualified or unqualified versions of a character type or void.&lt;/em>&lt;/li>
&lt;/ul>&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>這邊解釋了 function argument 的 promotion 情境，當：&lt;/p>
&lt;ol>
&lt;li>Function without prototype&lt;/li>
&lt;li>Function has variable arguments&lt;/li>
&lt;/ol>
&lt;p>會使用 default argument promotions 。&lt;/p>
&lt;p>參考以下解釋：&lt;/p>
&lt;p>&lt;a href="https://stackoverflow.com/a/60225225"target="_blank" rel="external nofollow noopener noreferrer">stack overflow - I want default argument promotion’s example&lt;/a>&lt;/p>
&lt;p>可以得知 default function prototype 的使用情境。&lt;/p>
&lt;div class="details admonition tip open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-regular fa-lightbulb" aria-hidden="true">&lt;/i>提示&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">另，在 &lt;a href="https://stackoverflow.com/a/55419261"target="_blank" rel="external nofollow noopener noreferrer">stack overflow - Function without prototype called with non-compatible type&lt;/a> 之中有說到了 function declare without prototype 的講解，底下的 comment 也有提到 function without prototype is old syntax you should not use in new code.&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>針對 function 的 parameters 和 arguments 的 integer promotion，有幾個會造成 UB (Undefined Behavior)：&lt;/p>
&lt;ul>
&lt;li>如果 function 的 prototype 是 defined，但經過 promotion 之後的 arguments 和 parameters 是無法匹配起來的，會造成 UB。&lt;/li>
&lt;li>如果 function 的 prototype 是 not defined，parameters 和 arguments 雙邊進行 promotion 之後是無法匹配的，也會造成 UB。&lt;/li>
&lt;/ul>
&lt;div class="details admonition tip open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-regular fa-lightbulb" aria-hidden="true">&lt;/i>提示&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">也可以參考以下資訊 &lt;a href="https://stackoverflow.com/a/61836943"target="_blank" rel="external nofollow noopener noreferrer">stack overflow - Default argument and parameter promotions in C&lt;/a>&lt;/div>
 &lt;/div>
&lt;/div>
&lt;h3 id="_6533_" class="heading-element">&lt;span>&lt;em>§6.5.3.3&lt;/em>&lt;/span>
 &lt;a href="#_6533_" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>§6.5.3.3&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;p>&lt;em>The result of the unary + operator is the value of its (promoted) operand. The integer promotions are performed on the operand, and &lt;strong>the result has the promoted type&lt;/strong>.&lt;/em>&lt;/p>
&lt;p>&lt;em>The result of the unary - operator is the negative of its (promoted) operand. The integer promotions are performed on the operand, and &lt;strong>the result has the promoted type&lt;/strong>.&lt;/em>&lt;/p>
&lt;p>&lt;em>The result of the ~ operator is the bitwise complement of its (promoted) operand (that is, each bit in the result is set if and only if the corresponding bit in the converted operand is not set). The integer promotions are performed on the operand, and &lt;strong>the result has the promoted type&lt;/strong>. If the promoted type is an unsigned type, the expression ~E is equivalent to the maximum value representable in that type minus E.&lt;/em>&lt;/p>
&lt;p>&lt;em>The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0 == E).&lt;/em>&lt;/p>
&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>此段講解了 unary arithmetic operator 使用上的 integer promotions 場景：&lt;/p>
&lt;ul>
&lt;li>Unary &lt;code>+&lt;/code> operator&lt;/li>
&lt;li>Unary &lt;code>-&lt;/code> operator&lt;/li>
&lt;li>Unary &lt;code>~&lt;/code> operator&lt;/li>
&lt;/ul>
&lt;p>此三個 unary operator 都會表現出 promoted result，&lt;code>+E&lt;/code> 甚至可以當作主動觸發 Integer Promotion 的方法。&lt;/p>
&lt;h3 id="_657--3_" class="heading-element">&lt;span>&lt;em>§6.5.7 / 3&lt;/em>&lt;/span>
 &lt;a href="#_657--3_" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>§6.5.7 / 3&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;em>The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. &lt;em>&lt;strong>If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.&lt;/strong>&lt;/em>&lt;/em>&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>此段是對於 Bitwise shift operators 的更多說明，當使用 Bitwise shift operators 時，兩邊的 operands 都會 integer promotions，並且若右側的 operand 是負數或其 shift 的位數 (bits) 大於等於左側 promoted 以後的位數 (bits)，則是 undefined behavior。&lt;/p>
&lt;div class="details admonition tip open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-regular fa-lightbulb" aria-hidden="true">&lt;/i>提示&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;p>在 jserv 老師的 &amp;lt;2021年「Linux核心」暑期課程&amp;gt; 中的 &amp;lt;&lt;a href="https://hackmd.io/@sysprog/bitwise-rotation"target="_blank" rel="external nofollow noopener noreferrer">位元旋轉實做和Linux核心案例&lt;/a>&amp;gt; 中有講解到關於 Linux 核心在實做位元旋轉時因應 integer promotions 所做出的不同實做。&lt;/p>
 &lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>節錄位元旋轉實作和 Linux 核心案例&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;p>Linux Kernel 曾經的 32 位元旋轉實作如下：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-c" data-lang="c">&lt;span class="line">&lt;span class="cl"> &lt;span class="k">static&lt;/span> &lt;span class="kr">inline&lt;/span> &lt;span class="n">__u32&lt;/span> &lt;span class="nf">rol32&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">__u32&lt;/span> &lt;span class="n">word&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">shift&lt;/span>&lt;span class="p">)&lt;/span> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">word&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">shift&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">|&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">word&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mi">32&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">shift&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>但上述實作當 shift 為 0 時，其中 &amp;raquo; 32 對於 32 位元整數來說，會遇到 C 語言中規範的 undefined behavior（如上述規格書所述）&lt;/p>
&lt;p>因此後續進行改善為如下實作：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-c" data-lang="c">&lt;span class="line">&lt;span class="cl"> &lt;span class="k">static&lt;/span> &lt;span class="kr">inline&lt;/span> &lt;span class="n">__u32&lt;/span> &lt;span class="nf">rol32&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">__u32&lt;/span> &lt;span class="n">word&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">shift&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">word&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">shift&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="mi">31&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="o">|&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">word&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="p">((&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">shift&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="mi">31&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>但上述主要是因為 32 位元的 integer promotion 的結果造成 UB，如果是 8 位元的實作則並不會有問題：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-c" data-lang="c">&lt;span class="line">&lt;span class="cl"> &lt;span class="k">static&lt;/span> &lt;span class="kr">inline&lt;/span> &lt;span class="n">__u8&lt;/span> &lt;span class="nf">rol8&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">__u8&lt;/span> &lt;span class="n">word&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">shift&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">word&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">shift&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">|&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">word&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mi">8&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">shift&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/div>
 &lt;/div>
&lt;/div>
&lt;/div>
 &lt;/div>
&lt;/div>
&lt;h3 id="_6842--5_" class="heading-element">&lt;span>&lt;em>§6.8.4.2 / 5&lt;/em>&lt;/span>
 &lt;a href="#_6842--5_" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>§6.8.4.2 / 5&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;em>&lt;strong>The integer promotions are performed on the controlling expression&lt;/strong>. The constant expression in each case label is converted to the promoted type of the controlling expression. If a converted value matches that of the promoted controlling expression, control jumps to the statement following the matched case label. Otherwise, if there is a default label, control jumps to the labeled statement. If no converted case constant expression matches and there is no default label, no part of the switch body is executed.&lt;/em>&lt;/div>
 &lt;/div>
&lt;/div>
&lt;p>此段是對於 switch statement 的附加敘述，switch statement 的 controlling expression 會先經過 promote，然後各個 Label 在進行 convert 進行比對。&lt;/p>
&lt;h2 id="關於-integer-promotions-的一些想法與延伸" class="heading-element">&lt;span>關於 Integer Promotions 的一些想法與延伸&lt;/span>
 &lt;a href="#%e9%97%9c%e6%96%bc-integer-promotions-%e7%9a%84%e4%b8%80%e4%ba%9b%e6%83%b3%e6%b3%95%e8%88%87%e5%bb%b6%e4%bc%b8" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;ul>
&lt;li>實際上關於 Integer Promotions 的發生可以說是必然的，就如同 Wiki 上所說的，任何值要送入 ALU 運算時都會需要把數值存進某個 register 中，而這個 register 大小通常等於 &lt;code>int&lt;/code> 的大小。當送入 register 的情況發生以後，實際上就等同於發生了 Integer Promotions 。&lt;/li>
&lt;li>機器（硬體）上的“必然”在軟體是由規格書特別規範出來，這樣似乎可以針對語言的 Abstract machine 進行討論了&amp;hellip;（下集待續？）&lt;/li>
&lt;/ul>
&lt;p>其他參考資料來源&lt;/p>
&lt;ul>
&lt;li>&lt;em>&lt;strong>&lt;a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf"target="_blank" rel="external nofollow noopener noreferrer">ISO/IEC 9899:201X (N1570)&lt;/a>&lt;/strong>&lt;/em>&lt;/li>
&lt;/ul></description></item><item><title>那些生活上的趣事（一）</title><link>https://timememo.lizhou31.com/funny_stories_1/</link><pubDate>Sat, 08 Jul 2023 22:26:02 +0800</pubDate><guid>https://timememo.lizhou31.com/funny_stories_1/</guid><category domain="https://timememo.lizhou31.com/categories/life_memo/">生活雜記</category><description>&lt;img src="https://timememo.lizhou31.com/funny_stories_1/featured-image.webp" alt="featured image" referrerpolicy="no-referrer">&lt;p>&lt;em>辦公處近晚照&lt;/em>&lt;/p>
&lt;h2 id="前言" class="heading-element">&lt;span>前言&lt;/span>
 &lt;a href="#%e5%89%8d%e8%a8%80" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>人生苦短，快樂長存（X&lt;/p>
&lt;p>反正這個系列（希望是系列？）打算拿來紀錄一下生活中多少碰到的趣事，大多是短篇分享。&lt;/p>
&lt;h2 id="嚴重意外受傷除了痛還可以幹麻還可以拿來當作地獄題材" class="heading-element">&lt;span>嚴重意外受傷除了痛還可以幹麻？還可以拿來當作地獄題材&lt;/span>
 &lt;a href="#%e5%9a%b4%e9%87%8d%e6%84%8f%e5%a4%96%e5%8f%97%e5%82%b7%e9%99%a4%e4%ba%86%e7%97%9b%e9%82%84%e5%8f%af%e4%bb%a5%e5%b9%b9%e9%ba%bb%e9%82%84%e5%8f%af%e4%bb%a5%e6%8b%bf%e4%be%86%e7%95%b6%e4%bd%9c%e5%9c%b0%e7%8d%84%e9%a1%8c%e6%9d%90" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>大概在五月出的時候，我們的同事 Tim 因為意外工作期間受了很嚴重的傷，左手食指和中指被粉碎性骨折。發生的當下大家都很驚慌，因為 Tim 的慘叫幾乎可以是突破天際。好在是後來送醫手術後目前恢復狀況良好。&lt;/p>
&lt;p>但你以為結束了嘛？這個愛好地獄梗的辦公室怎麼可能放過這個題材。&lt;/p>
&lt;p>首先是造成意外的機器因為捲進 Tim 的手指，有了新的外號&amp;quot;捲捲號&amp;quot;，以後 Tim 在介紹這台機器的時候甚至可以說&lt;/p>
&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;看，這是我的手指&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>還有 Tim 本身也很愛拿自己當題材，他後來回來以後描述那天被送上救護車的時候的心境變化：&lt;/p>
&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;我那天原本在救護車上一直在擔心自己的手指如果沒了要怎麼辦，可是我又突然想到，如果手指沒了，是不是就可以申請殘障手冊了？這樣我找停車位和停車費就可以狠狠的省一筆，手指突然就沒這麼痛了&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>萬幸後來手指依然好好的待在 Tim 的手上，可惜 Tim 在救護車上的幻想了。&lt;/p>
&lt;p>有次幾個同事一起出去吃飯，Tim 因為手還在康復期間，左手很常會比出一個軟軟的 YA 手勢，我看到了趕快拍下來。&lt;/p>
&lt;a class="lightgallery" href="https://timememo.lizhou31.com/funny_stories_1/raptor.webp?size=large" data-thumbnail="/funny_stories_1/raptor.webp?size=small" data-sub-html="&lt;h2>/funny_stories_1/raptor.webp&lt;/h2>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/funny_stories_1/raptor.webp" alt="/funny_stories_1/raptor.webp" srcset="https://timememo.lizhou31.com/funny_stories_1/raptor.webp?size=small, https://timememo.lizhou31.com/funny_stories_1/raptor.webp?size=medium 1.5x, https://timememo.lizhou31.com/funny_stories_1/raptor.webp?size=large 2x" data-title="/funny_stories_1/raptor.webp" width="50%" height="50%" style="--width: 346px;--aspect-ratio: 346 / 749;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>
&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;欸，迅猛龍&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;h2 id="拳上" class="heading-element">&lt;span>拳上&lt;/span>
 &lt;a href="#%e6%8b%b3%e4%b8%8a" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>最近剛結束完&lt;a href="https://zh.wikipedia.org/zh-tw/%E6%8B%B3%E4%B8%8A2023_%E7%B5%82%E6%96%BC%E4%B9%8B%E6%88%B0"target="_blank" rel="external nofollow noopener noreferrer">拳上&lt;/a>的拳賽，那天有幾個同事都有一起看直播，結果隔天有幾個直接瘋了。尤其是 Tien 先生，整天在咻咻的出拳，弄的好像真的想去打拳賽一樣。重點是我和 Tien 先生會一起去健身，那天他臨時有事沒辦法去，發了一則訊息給我。&lt;/p>
&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;欸欸我今天有事就不去練拳了喔？&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>我看是想打拳想瘋了。&lt;/p>
&lt;p>剛好最近有發生了”嗆人事件“，我們的 Tim 總工程師，因為最近早上有時候會外出去買工程用品，會比較晚進公司。那天有個同事看到 Tim 早上沒進公司以後，說了一句：&lt;/p>
&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;股東是不是都不用準時上班啊？&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>掀起一陣波瀾。:rofl:&lt;/p>
&lt;p>看來本辦公室可以籌備一場拳上了。&lt;/p>
&lt;h2 id="減重計畫" class="heading-element">&lt;span>減重計畫&lt;/span>
 &lt;a href="#%e6%b8%9b%e9%87%8d%e8%a8%88%e7%95%ab" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>最近辦公室有女同事為了之後想穿上伴娘禮服開始實施減重計話，但是我們幾個 R&amp;amp;D 看到他的飯量真的不敢苟同他的計畫，中午僅僅吃了一小盒花椰菜米和蔬菜，一看熱量就超級低，然後下午開始喊餓。&lt;/p>
&lt;p>當然喜歡&lt;strong>&lt;ruby>解決問題&lt;rt>&lt;del>出餿主意&lt;/del>&lt;/rt>&lt;/ruby>&lt;/strong>的 R&amp;amp;D 們怎麼會坐視不管，當然是開始想辦法解決同事的民生問題，吃不飽怎麼能做好事呢？&lt;/p>
&lt;p>我們開始針對辦公室的零食上的熱量精打細算，幫她找出能夠解饞又不至於發胖的吃法。&lt;/p>
&lt;blockquote>
&lt;p>&lt;em>“不要這鈉含量很高:expressionless:”&lt;/em> &lt;br>
&lt;em>&amp;ldquo;蛤這個我不喜歡:confounded:&amp;rdquo;&lt;/em> &lt;br>
&lt;em>&amp;ldquo;少騙了這熱量一看就很高欸:unamused:&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>真是難纏。&lt;/p>
&lt;p>於是我們只好討論熱量吃多一點沒關係，多運動就好，於是討論到了游泳。&lt;/p>
&lt;blockquote>
&lt;p>&lt;em>Tim：“欸欸以前游泳都喜歡找旁邊都有熱食部的，游完泳起來吃一碗熱食超級舒服”&lt;/em> &lt;br>
&lt;em>Tien：&amp;ldquo;對啊對啊以前小時候我游泳完我爸都端一碗鍋燒意麵給我，哇賽那真的超級讚&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>噢不，減重主角看起來又更餓了。&lt;/p>
&lt;p>不過後來好像一兩天後他就偷吃零食了，看來總算想開了，可喜可賀。&lt;em>&lt;del>減重失敗&lt;/del>&lt;/em>&lt;/p>
&lt;h2 id="超涼感症候群" class="heading-element">&lt;span>超涼感症候群&lt;/span>
 &lt;a href="#%e8%b6%85%e6%b6%bc%e6%84%9f%e7%97%87%e5%80%99%e7%be%a4" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>最近一個朋友圈裡掀起了一陣組電腦風潮，幾個以前從沒換過電腦的電腦小白第一次開始自己挑零件，第一次自己組出理想中的電腦。&lt;/p>
&lt;p>當然，一同流行起來的還有可怕的 RGB 和一定要讓電腦很涼症候群。&lt;/p>
&lt;p>RGB 我可以理解，畢竟幾年前我第一次組電腦得時候也是如此，一定要讓電腦跟電子花車一樣，RGB 插好插滿，多錢也沒問題。&lt;/p>
&lt;p>畢竟內行的都知道，RGB 能顯著提高電腦 50% 的效能。&lt;/p>
&lt;p>不過後來我開始無法忍受每次晚上睡覺還要有個閃瞎人的夜光燈在那邊閃，還有久了以後根本就不會去注意的燈效，於是 RGB 症候群就自然痊癒了。&lt;/p>
&lt;p>但是超涼感症候群我就不太能理解了，我知道電腦溫度太高會降低元組建壽命，但是你到底想要電腦多涼&amp;hellip;？&lt;/p>
&lt;a class="lightgallery" href="https://timememo.lizhou31.com/funny_stories_1/supercool.webp?size=large" data-thumbnail="/funny_stories_1/supercool.webp?size=small" data-sub-html="&lt;h2>/funny_stories_1/supercool.webp&lt;/h2>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/funny_stories_1/supercool.webp" alt="/funny_stories_1/supercool.webp" srcset="https://timememo.lizhou31.com/funny_stories_1/supercool.webp?size=small, https://timememo.lizhou31.com/funny_stories_1/supercool.webp?size=medium 1.5x, https://timememo.lizhou31.com/funny_stories_1/supercool.webp?size=large 2x" data-title="/funny_stories_1/supercool.webp" width="50%" height="50%" style="--width: 864px;--aspect-ratio: 864 / 1872;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>
&lt;p>&lt;em>“已保護當事人”&lt;/em>&lt;/p>
&lt;p>SSD 插那麼大一個風扇的用意是&amp;hellip;？想讓電腦感冒嗎？&lt;/p>
&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;會不會下次我去你家你的電腦已經能夠起飛了&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote></description></item><item><title>一場從零引發的慘案</title><link>https://timememo.lizhou31.com/talk_about_ieee754/</link><pubDate>Sat, 01 Jul 2023 23:12:03 +0800</pubDate><guid>https://timememo.lizhou31.com/talk_about_ieee754/</guid><category domain="https://timememo.lizhou31.com/categories/tech_note/">技術筆記</category><description>&lt;img src="https://timememo.lizhou31.com/talk_about_ieee754/IEEE754_float_double_fraction.webp" alt="featured image" referrerpolicy="no-referrer">&lt;p>&lt;em>討論一點浮點數&lt;/em>&lt;/p>
&lt;h2 id="前言" class="heading-element">&lt;span>前言&lt;/span>
 &lt;a href="#%e5%89%8d%e8%a8%80" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>不久前，朋友在群組貼了一篇文章，引起了我的興趣，文章內容大致是在討論IEEE 754關於浮點數中+0與-0的差異以及運算性質，看了看突然發現自己對於浮點數的概念幾乎忘的一乾二淨了，再加上對於文中的性質也有不小的興趣，因此乾脆開始了浮點數的學習之旅。
&lt;div class="details admonition info open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-circle-info" aria-hidden="true">&lt;/i>資訊&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">實際上這篇文章應該是兩年多前寫給自己看的，搬運過來水一篇文章XD&lt;/div>
 &lt;/div>
&lt;/div>&lt;/p>
&lt;h2 id="關於浮點數" class="heading-element">&lt;span>關於浮點數…&lt;/span>
 &lt;a href="#%e9%97%9c%e6%96%bc%e6%b5%ae%e9%bb%9e%e6%95%b8" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>浮點數(Floating Number)，是常見紀錄小數手段，相對於定點數(Fixed Number)，浮點數利用 $N = X × 2^y$ 使得小數點的位置並不固定，讓能夠紀錄的數字達到更廣的範圍。&lt;/p>
&lt;p>其中，在1985年提出的IEEE 754規範了目前的浮點數格式，並沿用至今。&lt;/p>
&lt;h2 id="ieee-754" class="heading-element">&lt;span>IEEE 754&lt;/span>
 &lt;a href="#ieee-754" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>先由浮點數的格式入手，可以分為三個部份：&lt;/p>
&lt;ul>
&lt;li>Sign&lt;/li>
&lt;li>Exponent&lt;/li>
&lt;li>Significand&lt;/li>
&lt;/ul>
&lt;p>Sign用來表示此數字的正負號，只有1 bit，Exponent 則用來表示2的乘冪，Significand 則用來表示尾數。大致如下：&lt;/p>
&lt;p>$$ (− 1)^s × M × 2^E\quad——— \quad(1)$$&lt;/p>
&lt;p>而在C語言中的 Float(32-bits) 和 Double(64-bits) 分別對應如下：&lt;/p>
&lt;p>&lt;figure>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/IEEE754_float_double_fraction.webp?size=large" data-thumbnail="/talk_about_ieee754/IEEE754_float_double_fraction.webp?size=small" data-sub-html="&lt;h2>IEEE 754 Float and Double&lt;/h2>&lt;p>IEEE 754 float and double&lt;/p>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/IEEE754_float_double_fraction.webp" alt="IEEE 754 Float and Double" srcset="https://timememo.lizhou31.com/talk_about_ieee754/IEEE754_float_double_fraction.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/IEEE754_float_double_fraction.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/IEEE754_float_double_fraction.webp?size=large 2x" data-title="IEEE 754 float and double" style="--width: 994px;--aspect-ratio: 994 / 227;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;figcaption class="image-caption">IEEE 754 Float and Double&lt;/figcaption>
 &lt;/figure>&lt;/p>
&lt;p>而其中，一個IEEE 754規範的浮點數又可以分為三個種類：&lt;/p>
&lt;ol>
&lt;li>規格化數 (normalized)&lt;/li>
&lt;li>非規格化數 (denormalized)&lt;/li>
&lt;li>特殊值 (special: NaN, Ifinity)&lt;/li>
&lt;/ol>
&lt;h3 id="規格化數normalized-value" class="heading-element">&lt;span>規格化數(Normalized Value)&lt;/span>
 &lt;a href="#%e8%a6%8f%e6%a0%bc%e5%8c%96%e6%95%b8normalized-value" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;p>&lt;figure>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/Normalized_value.webp?size=large" data-thumbnail="/talk_about_ieee754/Normalized_value.webp?size=small" data-sub-html="&lt;h2>Normalized Value&lt;/h2>&lt;p>Normalized value&lt;/p>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/Normalized_value.webp" alt="Normalized Value" srcset="https://timememo.lizhou31.com/talk_about_ieee754/Normalized_value.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/Normalized_value.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/Normalized_value.webp?size=large 2x" data-title="Normalized value" style="--width: 1120px;--aspect-ratio: 1120 / 141;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;figcaption class="image-caption">Normalized Value&lt;/figcaption>
 &lt;/figure>&lt;/p>
&lt;p>規格化數是浮點數格式中佔最多的種類，其Exponent的部份介於255和0之間。在這個種類中:&lt;/p>
&lt;p>&lt;strong>Exponent&lt;/strong> 的部份會表示為 $E = e − Bias$，$E$ 為上方(1)式的2的乘冪部份，$e$ 為 Exponent 部份所表示的&lt;strong>無號整數&lt;/strong>，$Bias$ 為 $2^{(k − 1)} − 1$，其中 $k$ 表示為 Exponent 部份的 bit 數，因此 Float 的 $Bias$ 為 $2^{(8 − 1)} − 1 = 127$，Double 的 $Bias$ 為 $2^{(11 − 1)} − 1 = 1027$。&lt;/p>
&lt;p>&lt;strong>Significand&lt;/strong> 的部份會表示為 $M = 1 + f$，也就是 $1.f_{n − 1}f_{n − 2}f_{n − 3}&amp;hellip;$ ，這種方法可以使 Significand 的部份可以增加 1 bit 的精度(因為前方多了一個隱含的開頭1)，因此可以肯定&lt;/p>
&lt;p>$$0&amp;lt;=fraction&amp;lt;1$$&lt;/p>
&lt;h3 id="非規格化數denormalized-value" class="heading-element">&lt;span>非規格化數(denormalized Value)&lt;/span>
 &lt;a href="#%e9%9d%9e%e8%a6%8f%e6%a0%bc%e5%8c%96%e6%95%b8denormalized-value" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;p>&lt;figure>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/Denormalized_value.webp?size=large" data-thumbnail="/talk_about_ieee754/Denormalized_value.webp?size=small" data-sub-html="&lt;h2>Denormalized Value&lt;/h2>&lt;p>Denormalized value&lt;/p>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/Denormalized_value.webp" alt="Denormalized Value" srcset="https://timememo.lizhou31.com/talk_about_ieee754/Denormalized_value.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/Denormalized_value.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/Denormalized_value.webp?size=large 2x" data-title="Denormalized value" style="--width: 1112px;--aspect-ratio: 1112 / 118;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;figcaption class="image-caption">Denormalized Value&lt;/figcaption>
 &lt;/figure>&lt;/p>
&lt;p>為了表達規格化數無法表達的更小的浮點數，IEEE 754提供了一個特性稱為 Gradual underflow ，讓浮點數表示能夠平滑的向下接近 0 的數字，也就是非規格化數的種類。&lt;/p>
&lt;p>非規格化數的 Exponent 全為 0，而 $E = 1 − Bias$，$M = f$，相較於規格化數，非規格化數少了M的隱含開頭1。&lt;/p>
&lt;p>其中，當 fraction 全為零，sign 為 0 時，可以得到 +0.0，而 sign 為 1 時，可以得到 -0.0，這樣設計的好處是，假設一個數字經過運算後已經過小到浮點數無法表示的程度，但是 +0.0 和 -0.0 仍然可以讓我們輕鬆知道這個數字原始是大於 0 或是小於 0 的。&lt;/p>
&lt;div class="details admonition tip open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-regular fa-lightbulb" aria-hidden="true">&lt;/i>提示&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">+0.0 和 -0.0 在 IEEE 754 規格中是兩個不同的值( sign 不同)，但是其進行對比得出的結果會是 equal 的，但若進行其他運算則又有可能得出不同的結果，而這些特殊運算結果都是有定義的。&lt;/div>
 &lt;/div>
&lt;/div>
&lt;div class="details admonition tip open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-regular fa-lightbulb" aria-hidden="true">&lt;/i>提示&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">關於 $E=1−Bias$ 而非 $E=−Bias$ 是因為這樣提供了規格化數到非規格化數平滑的過度。&lt;/div>
 &lt;/div>
&lt;/div>
&lt;h3 id="特殊值special-value" class="heading-element">&lt;span>特殊值(Special Value)&lt;/span>
 &lt;a href="#%e7%89%b9%e6%ae%8a%e5%80%bcspecial-value" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;p>&lt;figure>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/Special_value.webp?size=large" data-thumbnail="/talk_about_ieee754/Special_value.webp?size=small" data-sub-html="&lt;h2>Special Value&lt;/h2>&lt;p>Special value&lt;/p>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/Special_value.webp" alt="Special Value" srcset="https://timememo.lizhou31.com/talk_about_ieee754/Special_value.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/Special_value.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/Special_value.webp?size=large 2x" data-title="Special value" style="--width: 1127px;--aspect-ratio: 1127 / 272;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;figcaption class="image-caption">Special Value&lt;/figcaption>
 &lt;/figure>&lt;/p>
&lt;p>當 Exponent 部份全為 1 時，會得到特殊值，如圖所示。&lt;/p>
&lt;h3 id="特殊運算" class="heading-element">&lt;span>特殊運算&lt;/span>
 &lt;a href="#%e7%89%b9%e6%ae%8a%e9%81%8b%e7%ae%97" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;p>IEEE 754 有很好的定義了個別特殊運算的結果：&lt;/p>
&lt;a class="lightgallery" href="Special_calculate.webp?size=large" data-thumbnail="Special_calculate.webp?size=small" data-sub-html="&lt;h2>Special_calculate.webp&lt;/h2>">&lt;img loading="lazy" src="Special_calculate.webp" alt="Special_calculate.webp" srcset="Special_calculate.webp?size=small, Special_calculate.webp?size=medium 1.5x, Special_calculate.webp?size=large 2x" data-title="Special_calculate.webp" style="background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>
&lt;p>其中 NaN 與任何數字做任何運算都會得出 NaN 的結果。&lt;/p>
&lt;h3 id="程式驗證" class="heading-element">&lt;span>程式驗證&lt;/span>
 &lt;a href="#%e7%a8%8b%e5%bc%8f%e9%a9%97%e8%ad%89" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h3>&lt;div class="details admonition info open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-circle-info" aria-hidden="true">&lt;/i>資訊&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">以下程式參考於一系列的 &lt;a href="https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/"target="_blank" rel="external nofollow noopener noreferrer">blog&lt;/a> 並使用 g++(C++14) 編譯與 gdb 進行 debug&lt;/div>
 &lt;/div>
&lt;/div>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#define _DEBUG
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">union&lt;/span> &lt;span class="nc">Float_t&lt;/span>&lt;span class="p">{&lt;/span> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="n">Float_t&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">float&lt;/span> &lt;span class="n">num&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="n">f&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">num&lt;/span>&lt;span class="p">){}&lt;/span> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="kt">bool&lt;/span> &lt;span class="nf">Negative&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="k">const&lt;/span>&lt;span class="p">{&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span>&lt;span class="mi">31&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">!=&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">;}&lt;/span> &lt;span class="c1">//Sign 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>	&lt;span class="kt">int32_t&lt;/span> &lt;span class="nf">RawMantissa&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="k">const&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="k">return&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="p">((&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="mi">23&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">);}&lt;/span> &lt;span class="c1">//Significand 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>	&lt;span class="kt">int32_t&lt;/span> &lt;span class="nf">RawExponent&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="k">const&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span>&lt;span class="mi">23&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="mh">0xFF&lt;/span>&lt;span class="p">;}&lt;/span> &lt;span class="c1">//Exponent 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>	&lt;span class="kt">int32_t&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">//IEEE 754 float的直接轉成正整數表達結果 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">float&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">//IEEE 754 float
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#ifdef _DEBUG 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>	&lt;span class="k">struct&lt;/span>&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">		&lt;span class="kt">uint32_t&lt;/span> &lt;span class="nl">mantissa&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="mi">23&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">//Sign 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>		&lt;span class="kt">uint32_t&lt;/span> &lt;span class="nl">exponent&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="mi">8&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">//Exponent 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>		&lt;span class="kt">uint32_t&lt;/span> &lt;span class="nl">sign&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">//Significand 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>	&lt;span class="p">}&lt;/span>&lt;span class="n">parts&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#endif
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">(){&lt;/span> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="k">union&lt;/span> &lt;span class="nc">Float_t&lt;/span> &lt;span class="n">num&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mf">1.0f&lt;/span>&lt;span class="p">);&lt;/span> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="k">for&lt;/span>&lt;span class="p">(;;){&lt;/span> &lt;span class="c1">//Breakpoint here. 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>	&lt;span class="n">printf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;%1.8e,0x%08X,%d,%d,0x%06X&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">				&lt;span class="n">num&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">f&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">num&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">num&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">parts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">sign&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">num&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">parts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">exponent&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">num&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">parts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">mantissa&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>利用gdb進行debug修改各個部位的數值並觀察，其中下面給出幾個比較特殊的結果： （皆以sign = 0作為範例）&lt;/p>
&lt;ul>
&lt;li>
&lt;p>0 (float)&lt;/p>
&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/test1.webp?size=large" data-thumbnail="/talk_about_ieee754/test1.webp?size=small" data-sub-html="&lt;h2>/talk_about_ieee754/test1.webp&lt;/h2>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/test1.webp" alt="/talk_about_ieee754/test1.webp" srcset="https://timememo.lizhou31.com/talk_about_ieee754/test1.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/test1.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/test1.webp?size=large 2x" data-title="/talk_about_ieee754/test1.webp" style="--width: 274px;--aspect-ratio: 274 / 89;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>
&lt;/li>
&lt;li>
&lt;p>1 (float)&lt;/p>
&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/test2.webp?size=large" data-thumbnail="/talk_about_ieee754/test2.webp?size=small" data-sub-html="&lt;h2>/talk_about_ieee754/test2.webp&lt;/h2>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/test2.webp" alt="/talk_about_ieee754/test2.webp" srcset="https://timememo.lizhou31.com/talk_about_ieee754/test2.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/test2.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/test2.webp?size=large 2x" data-title="/talk_about_ieee754/test2.webp" style="--width: 285px;--aspect-ratio: 285 / 88;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>
&lt;/li>
&lt;li>
&lt;p>最大標準化數&lt;/p>
&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/test3.webp?size=large" data-thumbnail="/talk_about_ieee754/test3.webp?size=small" data-sub-html="&lt;h2>/talk_about_ieee754/test3.webp&lt;/h2>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/test3.webp" alt="/talk_about_ieee754/test3.webp" srcset="https://timememo.lizhou31.com/talk_about_ieee754/test3.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/test3.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/test3.webp?size=large 2x" data-title="/talk_about_ieee754/test3.webp" style="--width: 320px;--aspect-ratio: 320 / 88;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>
&lt;/li>
&lt;li>
&lt;p>最小標準化數&lt;/p>
&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/test4.webp?size=large" data-thumbnail="/talk_about_ieee754/test4.webp?size=small" data-sub-html="&lt;h2>/talk_about_ieee754/test4.webp&lt;/h2>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/test4.webp" alt="/talk_about_ieee754/test4.webp" srcset="https://timememo.lizhou31.com/talk_about_ieee754/test4.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/test4.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/test4.webp?size=large 2x" data-title="/talk_about_ieee754/test4.webp" style="--width: 276px;--aspect-ratio: 276 / 90;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>
&lt;/li>
&lt;li>
&lt;p>最大非標準化數
&lt;div class="details admonition tip open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-regular fa-lightbulb" aria-hidden="true">&lt;/i>提示&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">可以看到由於使用 $E = 1 − Bias$ 的關係，最小標準化數與最大非標準化數之間有平滑的過度&lt;/div>
 &lt;/div>
&lt;/div>
&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/test5.webp?size=large" data-thumbnail="/talk_about_ieee754/test5.webp?size=small" data-sub-html="&lt;h2>/talk_about_ieee754/test5.webp&lt;/h2>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/test5.webp" alt="/talk_about_ieee754/test5.webp" srcset="https://timememo.lizhou31.com/talk_about_ieee754/test5.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/test5.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/test5.webp?size=large 2x" data-title="/talk_about_ieee754/test5.webp" style="--width: 323px;--aspect-ratio: 323 / 91;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>最小非標準化數&lt;/p>
&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/test6.webp?size=large" data-thumbnail="/talk_about_ieee754/test6.webp?size=small" data-sub-html="&lt;h2>/talk_about_ieee754/test6.webp&lt;/h2>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/test6.webp" alt="/talk_about_ieee754/test6.webp" srcset="https://timememo.lizhou31.com/talk_about_ieee754/test6.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/test6.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/test6.webp?size=large 2x" data-title="/talk_about_ieee754/test6.webp" style="--width: 275px;--aspect-ratio: 275 / 91;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>
&lt;/li>
&lt;li>
&lt;p>NaN&lt;/p>
&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/test7.webp?size=large" data-thumbnail="/talk_about_ieee754/test7.webp?size=small" data-sub-html="&lt;h2>/talk_about_ieee754/test7.webp&lt;/h2>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/test7.webp" alt="/talk_about_ieee754/test7.webp" srcset="https://timememo.lizhou31.com/talk_about_ieee754/test7.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/test7.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/test7.webp?size=large 2x" data-title="/talk_about_ieee754/test7.webp" style="--width: 319px;--aspect-ratio: 319 / 92;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>
&lt;/li>
&lt;li>
&lt;p>Infinity&lt;/p>
&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/test8.webp?size=large" data-thumbnail="/talk_about_ieee754/test8.webp?size=small" data-sub-html="&lt;h2>/talk_about_ieee754/test8.webp&lt;/h2>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/test8.webp" alt="/talk_about_ieee754/test8.webp" srcset="https://timememo.lizhou31.com/talk_about_ieee754/test8.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/test8.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/test8.webp?size=large 2x" data-title="/talk_about_ieee754/test8.webp" style="--width: 285px;--aspect-ratio: 285 / 92;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>
&lt;/li>
&lt;li>
&lt;p>最大整數奇數 此數字為float所能表示的最大奇整數，由於其Significand為最大，且Exponent經過Bias運算後正好為23，對應Significand 的23 bits，在此數過後由於Exponent將會&amp;gt;23，所以無法在表示出任何奇數，換句話說，在16777216之後的整數，float在表示時精度都會小於同數字的 int表示方法。如下圖所示: 可以看到當&amp;gt;16777216之後的所有奇數都會無法表示。&lt;/p>
&lt;p>&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/test9.webp?size=large" data-thumbnail="/talk_about_ieee754/test9.webp?size=small" data-sub-html="&lt;h2>/talk_about_ieee754/test9.webp&lt;/h2>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/test9.webp" alt="/talk_about_ieee754/test9.webp" srcset="https://timememo.lizhou31.com/talk_about_ieee754/test9.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/test9.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/test9.webp?size=large 2x" data-title="/talk_about_ieee754/test9.webp" style="--width: 323px;--aspect-ratio: 323 / 90;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a> &lt;br>
&lt;br>
&lt;a class="lightgallery" href="https://timememo.lizhou31.com/talk_about_ieee754/test10.webp?size=large" data-thumbnail="/talk_about_ieee754/test10.webp?size=small" data-sub-html="&lt;h2>/talk_about_ieee754/test10.webp&lt;/h2>">&lt;img loading="lazy" src="https://timememo.lizhou31.com/talk_about_ieee754/test10.webp" alt="/talk_about_ieee754/test10.webp" srcset="https://timememo.lizhou31.com/talk_about_ieee754/test10.webp?size=small, https://timememo.lizhou31.com/talk_about_ieee754/test10.webp?size=medium 1.5x, https://timememo.lizhou31.com/talk_about_ieee754/test10.webp?size=large 2x" data-title="/talk_about_ieee754/test10.webp" style="--width: 296px;--aspect-ratio: 296 / 521;background: url(/images/loading.min.svg) no-repeat center;" onload="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}this.dataset.lazyloaded='';" onerror="this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}"/>&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="ieee-754浮點數以及其整數格式" class="heading-element">&lt;span>IEEE 754浮點數以及其整數格式…&lt;/span>
 &lt;a href="#ieee-754%e6%b5%ae%e9%bb%9e%e6%95%b8%e4%bb%a5%e5%8f%8a%e5%85%b6%e6%95%b4%e6%95%b8%e6%a0%bc%e5%bc%8f" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;ul>
&lt;li>當遞增浮點數無號整數表示時的值，其對應的浮點數數值也會朝著遠離零的方向移動。因此浮點數能夠使用整數序函數來進行排序。&lt;/li>
&lt;li>以下程式為一道 &lt;em>&lt;strong>Computer Systems: A Programmer’s Perspective&lt;/strong>&lt;/em> 書內的題目： 撰寫一個函數，只能使用給定的幾個參數測試輸入函數的第一個參數是否小於等於第二個參數，又假設兩個參數不會有NaN，並且+0和-0被認為是相同的。&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-c" data-lang="c">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// 使用gcc進行編譯
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">union&lt;/span> &lt;span class="n">Float_t&lt;/span>&lt;span class="p">{&lt;/span> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="kt">float&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">;&lt;/span> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">ui&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">float_le&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">float&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">float&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">){&lt;/span> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="k">union&lt;/span> &lt;span class="n">Float_t&lt;/span> &lt;span class="n">X&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">Y&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="n">X&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">f&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="n">Y&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">f&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Get the sign bits 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>	&lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">sx&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">X&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">ui&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span>&lt;span class="mi">31&lt;/span>&lt;span class="p">;&lt;/span> 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="kt">unsigned&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">sy&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Y&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">ui&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span>&lt;span class="mi">31&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">	&lt;span class="c1">// Given an expression using only X.ui, Y.ui, sx, and sy
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>	&lt;span class="k">return&lt;/span> &lt;span class="n">sx&lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="n">sy&lt;/span>&lt;span class="o">?&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="n">X&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">ui&lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">&amp;lt;=&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Y&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">ui&lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">))&lt;/span>&lt;span class="o">^&lt;/span>&lt;span class="nl">sx&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="n">sx&lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="n">X&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">ui&lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="o">&amp;amp;&amp;amp;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Y&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">ui&lt;/span>&lt;span class="o">&amp;lt;&amp;lt;&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="reference" class="heading-element">&lt;span>Reference&lt;/span>
 &lt;a href="#reference" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>&lt;a href="https://steve.hollasch.net/cgindex/coding/ieeefloat.html?fbclid=IwAR0V7qUZKU9ymFCdFnMz-Z3yF9XBISKBVNIxBvKGVS_4MDxvbXvuSKC07g0"target="_blank" rel="external nofollow noopener noreferrer">IEEE Standard 754 Floating Point Numbers&lt;/a>&lt;/p>
&lt;p>&lt;a href="https://chi_gitbook.gitbooks.io/personal-note/content/floating_point.html"target="_blank" rel="external nofollow noopener noreferrer">Floating Point&lt;/a>&lt;/p>
&lt;p>&lt;a href="https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/"target="_blank" rel="external nofollow noopener noreferrer">Comparing Floating Point Numbers, 2012 Edition&lt;/a>&lt;/p>
&lt;p>&lt;em>&lt;strong>Computer Systems: A Programmer’s Perspective&lt;/strong>&lt;/em>&lt;/p></description></item><item><title>這就是開始嗎？</title><link>https://timememo.lizhou31.com/first_post/</link><pubDate>Mon, 26 Jun 2023 12:26:32 +0800</pubDate><guid>https://timememo.lizhou31.com/first_post/</guid><category domain="https://timememo.lizhou31.com/categories/life_memo/">生活雜記</category><description>&lt;img src="https://timememo.lizhou31.com/first_post/featured-image.webp" alt="featured image" referrerpolicy="no-referrer">&lt;p>&lt;em>A charming café located near the sea in Kaohsiung Mituo. Please enjoy a cup of cofee and take a break.&lt;/em>&lt;/p>
&lt;h2 id="前言" class="heading-element">&lt;span>前言&lt;/span>
 &lt;a href="#%e5%89%8d%e8%a8%80" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>不免俗的，第一篇先來對於這個 Blog 的誕生，以及對過去自己經歷的反思和對未來的期許充點字數。&lt;/p>
&lt;p>可能內容會包含不少冗言閒談，又或是一些很主觀的看法觀點。總之就像封面圖一樣，如果有閒的話，可以泡杯咖啡，當作看個簡單的廢文休息一下。&lt;/p>
&lt;h2 id="緣由" class="heading-element">&lt;span>緣由&lt;/span>
 &lt;a href="#%e7%b7%a3%e7%94%b1" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>到底什麼時候開始萌生架一個網站的想法其實也忘了，或許是過去看了很多前輩在自己的網站上無私的分享著各項技術，以及自己碰過的坑，幫助了最早期懵懂在科技汪洋的我能夠至少抓住點方向。&lt;/p>
&lt;p>後來自己稍微有點經驗以後，大概想著也希望自己能留下點什麼資訊，除了紀錄自己曾經走過的路給其他人參考，也是讓自己未來回首時能夠多一份參考資料。&lt;/p>
&lt;p>更重要的，其實也是用來逼自己往前走的。&lt;/p>
&lt;p>實際上過去的自己，在大學畢業以前，總是懵懵懂懂的，雖然隱約的知道自己的方向。畢竟從小就耳濡目染了工程師的工作，甚至國中開始就參加各類比賽，也早早的就接觸到並參與了一些簡單的業界開發，但實際上，我依然不知道自己為什麼要做，更不知道自己的終點在哪裡。&lt;/p>
&lt;p>說終點好像有點過於沈重了，應該說最早的我，完全是沒有目標的在走，看到什麼做什麼，淺淺的觸碰了一點以後就又被其他東西吸引走了注意力。所以你可以說我都做過，但就都做不好。就像當年我申請研究所推甄時，洋洋灑灑的寫了一堆會的東西，後來自己回頭看到以後不經啞然失笑，這麼一大堆不就某種程度上的代表自己什麼都不精嗎？&lt;/p>
&lt;p>但至少我當初完全不這麼覺得，甚至很長一段時間一直引以為傲。&lt;/p>
&lt;p>於是就這樣如浮萍一般的隨波逐流很長一段時間以後，大學延畢狠狠賞了我一巴掌。&lt;/p>
&lt;p>延畢的原因也說來可笑，單純就是我自己某個必修課完全因為提不起興趣的關係，長期的蹺課和不念書，妄想用考前臨時抱佛腳的方式唬弄過去。但很不幸的，完全不行，於是在大四下又一次必修被當掉以後，我才驚覺的開始反省自己的過往種種。&lt;/p>
&lt;p>我到底想做什麼，我現在在做什麼，我為什麼要做什麼。從那時候開始我很常詢問自己這些問題。&lt;/p>
&lt;p>但是單純的詢問自己，實際上也得不出任何答案，就如同任何的理論就算推論的在過完美，沒有經過實驗證實的理論終究無法得到科學面上的信服。而這個 Blog 就如同我的實驗記錄本，透過寫實驗記錄這件事情，去逼自己在現實中真正的去實踐某先想法，並且透過這些紀錄去反思到底哪個目標是我打算邁向的。&lt;/p>
&lt;p>當然另一部分也是怕自己不斷地會忘記某些事情，留點紀錄給以後去提醒以後的自己，或是讓以後的自己感到羞恥也不錯。&lt;/p>
&lt;p>至少，這樣代表我有成長了？&lt;/p>
&lt;h2 id="期許" class="heading-element">&lt;span>期許?&lt;/span>
 &lt;a href="#%e6%9c%9f%e8%a8%b1" class="heading-mark">
 &lt;svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">&lt;path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z">&lt;/path>&lt;/svg>
 &lt;/a>
&lt;/h2>&lt;p>引用黃仁勳的一段話：
&lt;div class="details admonition quote open">
 &lt;div class="details-summary admonition-title">&lt;i class="icon fa-fw fa-solid fa-quote-right" aria-hidden="true">&lt;/i>引用&lt;i class="details-icon fa-solid fa-angle-right fa-fw" aria-hidden="true">&lt;/i>&lt;/div>
 &lt;div class="details-content">
 &lt;div class="admonition-content">&lt;em>&amp;ldquo;Vision&amp;rdquo; is an awfully big word to me. First of all, vision matters. But I like to use the word &amp;ldquo;perspective&amp;rdquo; because it makes it possible for anyone to have one. When you say vision, it feels like only a few selected visionaries of the world can have one. But everyone has a perspective and that&amp;rsquo;s, in fact, all visions means. That you see the world in a way that is either different or otherwise than somebody else. And you see opportunities that I think you believe are particularly important to go on and address. That you can address in a particualr way.&lt;/em>&lt;/div>
 &lt;/div>
&lt;/div>
所以，我的觀點是什麼？既然每個人都有觀點，那我對於自己，對於生活，對於任何事情，我是否能夠提出一個觀點。&lt;/p>
&lt;p>更重要的是，我是否能夠根據我的觀點去實現什麼，去改變什麼，去影響什麼。&lt;/p>
&lt;p>期望自己也能夠透過不停地記錄和成長的過程，真正的找出自己的 &amp;ldquo;Perpective&amp;rdquo;，去找出我在這條人生經歷上打算實現的，想去感受的，以及願意付出的。&lt;/p></description></item></channel></rss>