首頁>科技>

昨天看到一段程式碼[1]:

我一看,就懂了:這程式碼定義了一個叫做width的函式,這個函式接受三個引數,其中後兩個有預設值,如果三個引數中的第一個大於等於 2 ,並且第二個不等於 0 ,並且第三個小於 19 ,那麼遞迴呼叫width(n, d % n * 10, w+1)並返回呼叫結果加 1 ,否則返回 0 。

比如說計算width(8):

不管引數是多少,照這樣都能算出結果,很簡單,對吧。

但是今天看了其他兩個版本的實現,才發現我之前根本不懂這個函式在做什麼。

這並不是什麼高大上的演算法,只是小學除法而已。d是被除數,n是除數,w是結果的位數。

每次呼叫都會計算餘數,然後在餘數末尾加 0 ,把這當成新的被除數。如果被除數是 0 ,那麼表示之前已經除盡,直接返回。

例如,要計算 10 除以 8:

因為每呼叫一次都增加一個 0,所以遞迴呼叫的次數等於商的位數。如果發現商的位數超過 19 位,就不再繼續。除數是 0 或 1 時,結果是 0 。

最後結果就等於 1/n 對應的小數在十進位制中的小數位數。

對比一下:

定義一個叫做 width 的函式,這個函式接受三個引數,其中後兩個有預設值,如果三個引數中的第一個大於等於 2 ,並且第二個不等於 0 ,並且第三個小於 19 ,那麼遞迴呼叫width(n, d % n * 10, w+1)並返回呼叫結果加 1 ,否則返回 0 。

width(n) 返回 1/n 在十進位制中的小數位數,當位數大於等於 19 時返回 19 ,當 n 為 0 或 1 時返回 0。

似乎這兩段都正確描述了 width 的功能,都能算作“看得懂”,但這兩個“懂”大概是不一樣的。

那麼題主是哪種呢?

參考^這段程式碼來自:https://github.com/llvm/llvm-project/blob/a59283a74529c74a8ee8682f9acf9d993f7cda08/libcxx/include/chrono#L2772-L2777

10
最新評論
  • 整治雙十一購物亂象,國家再次出手!該跟這些套路說再見了
  • 隱私洩露、資料壟斷,網際網路之父看不下去了:必須改變