Manpages

NAME

perlnumber − Perl 中 數 字 的 語 義 以 及 算 術 操 作

SYNOPSIS 總 覽

    $n = 1234;              # 十 進 制 數
    $n = 0b1110011;         # 二 進 制 數
    $n = 01234;             # 八 進 制 數
    $n = 0x1234;            # 十 六 進 制 數
    $n = 12.34e-56;         # 指 數 形 式
    $n = "-12.34e56";       # 用 字 符 串 描 述 的 數
    $n = "1234";            # 用 字 符 串 描 述 的 數

DESCRIPTION 描 述

這 篇 文 章 描 述 了 Perl內 部 是 怎 樣 處 理 數 的 數 值 的 。

在 這 裏 不 會 提 到 Perl的 運 算 符 重 載 機 制 , 運 算 符 重 載 允 許 \[u4F7F]用 者 自 定 義 對 數 的 操 作 , 例 如 對 任 意 大 的 整 型 數 或 者 任 意 精 度 的 浮 點 數 進 行 的 操 作 , 或 者 一 些 其 它 的 算 術 類 型 如 求 模 操 作 和 p−adic操 作 等 等 。 要 想 知 道 運 算 符 重 載 的 細 節 , 請 看 重 載 。

Storing numbers 數 值 存 儲

Per在 內 部 能 用 三 種 方 法 表 示 數 值 : 用 「 Native整 型 」 , 「 Native浮 點 型 」 或 是 用 十 進 制 形 式 的 字 符 串 。 其 中 十 進 制 字 符 串 可 以 帶 一 個 指 數 描 述 的 部 分 , 就 像 "12.34e−56"。 在 這 裏 術 語 Native的 含 義 是 用 於 編 譯 perl 的 C 編 譯 器 所 支 持 的 類 型 。

在 我 們 談 及 整 型 時 , "native"這 個 術 語 所 包 含 的 含 義 比 我 們 談 論 浮 點 數 時 要 少 一 些 。 對 "native"整 型 來 說 , 這 個 術 語 所 的 含 義 僅 僅 是 指 整 型 數 的 可 以 有 最 大 值 和 最 小 值 會 是 2的 某 次 方 , 而 對 "native"浮 點 數 來 說 , 有 一 條 基 本 的 限 制 就 是 它 只 能 表 示 那 些 能 用 有 限 幾 位 二 進 制 小 數 所 表 示 的 實 數 。 舉 例 來 說 , 0.9就 不 是 "native"浮 點 數 , 因 為 0.9用 二 進 制 小 數 表 示 是 有 無 窮 多 位 的 :

  二 進 制 0.1110011001100...

序 列 1100 將 無 休 止 的 循 環 下 去 。 除 了 這 條 限 制 以 外 , 二 進 制 浮 點 數 在 用 指 數 型 式 表 達 時 也 存 有 限 制 。 在 特 定 的 硬 體 條 件 下 , 浮 點 型 的 數 可 以 存 儲 最 多 53位 二 進 制 數 再 加 上 范 圍 從 −1024到 1024的 指 數 值 (譯 者 : -1024到 1024用 11位 二 進 制 數 , 加 上 53等 於 64, 就 是 說 這 裏 用 用 64位 存 一 個 浮 點 數 ) 轉 換 成 十 進 制 也 就 是 說 差 不 多 能 用 16位 有 效 數 字 和 從 −304到 304的 指 數 值 和 起 來 表 示 一 個 浮 點 數 。 這 種 表 示 方 法 的 一 種 結 果 就 是 我 們 不 可 能 在 不 損 失 精 度 的 情 況 下 用 浮 點 型 存 儲 像 12345678901234567這 樣 的 數 。

類 似 的 , 十 進 制 字 符 串 也 只 能 表 示 有 限 位 數 的 十 進 制 數 .光 就 字 符 串 來 言 ,它 可 以 是 任 意 長 度 的 ,沒 有 什 麼 關 於 指 數 或 有 效 數 字 位 數 上 的 限 制 .(但 是 請 意 識 到 我 們 正 在 討 論 的 存 放 數 值 的 那 些 規 則 .事 實 是 你 能 用 字 符 串 存 放 很 大 的 數 值 並 不 代 表 相 應 的 數 值 操 作 能 夠 把 字 符 串 中 的 所 有 的 數 位 都 用 上 .欲 知 詳 情 ,請 看 "數 值 運 算 符 和 數 值 轉 換 "

事 實 上 「 Native整 型 數 」 存 儲 的 數 值 可 以 是 帶 符 號 的 , 或 者 是 不 帶 符 號 的 。 所 以 很 典 型 的 , Perl中 「 Native整 型 數 」 可 以 表 示 的 整 數 的 范 圍 是 −2**31..2**32−1, 這 個 范 圍 對 64位 的 整 數 來 說 是 比 較 合 適 的 。 但 這 並 不 意 味 著 Perl只 能 處 理 這 個 范 圍 內 的 整 數 : 浮 點 類 型 可 以 存 下 更 大 的 整 數 。

總 而 言 之 , Perl中 的 數 是 有 限 位 數 的 十 進 制 數 或 者 說 是 足 夠 短 的 二 進 制 數 。

Numeric operators and numeric conversions 數 值 運 算 符 和 數 值 轉 換

就 像 前 面 說 的 那 樣 , Perl可 以 用 三 種 格 式 中 的 任 意 一 種 存 放 一 個 數 , 但 是 大 多 數 運 算 符 只 能 理 解 這 三 種 格 式 中 的 一 種 。 當 一 個 數 值 作 為 參 數 傳 給 一 個 運 算 符 時 , 它 將 會 被 轉 換 成 運 算 符 可 以 理 解 的 那 種 格 式 。

可 能 出 現 的 轉 換 有 下 面 六 種 :

  native 整 型         --> native 浮 點 型       (*)
  native 整 型         --> 十 進 制 形 式 的 字 符 串
  native 浮 點 型  --> native 整 型               (*)
  native 浮 點 型  --> decimal string              (*)
  十 進 制 的 字 符 串         --> native 整 型
  十 進 制 的 字 符 串         --> native 浮 點 型        (*)

這 些 轉 換 按 照 下 列 的 規 則 進 行 :

如 果 原 來 的 數 可 以 用 要 轉 換 成 的 格 式 表 述 , 則 其 值 繼 續 使 用 , 不 會 改 變 。

如 果 原 來 的 數 超 出 了 要 轉 換 成 的 格 式 所 能 表 述 的 極 限 , 則 最 接 近 極 限 的 那 個 值 會 被 用 來 做 最 後 的 值 。 ( 這 會 有 信 息 上 的 損 失 )

如 果 原 來 的 數 在 要 轉 換 成 的 格 式 所 能 表 述 的 兩 個 相 鄰 的 數 之 間 , 則 這 兩 個 數 中 的 一 個 會 被 用 來 做 最 後 的 值 。 ( 這 會 有 信 息 上 的 損 失 )

"native 浮 點 型 −−> native 整 型 " 的 轉 換 中 , 結 果 的 值 小 於 等 於 原 來 的 值 。 ( 因 為 是 直 接 截 取 小 數 位 取 整 的 ) ("Rounding to zero".)

如 果 "十 進 制 的 字 符 串 −−> native 整 型 " 的 轉 換 不 能 在 不 損 失 信 息 的 情 況 下 完 成 , 結 果 將 會 和 下 列 的 轉 換 序 列 的 結 果 一 致 : "十 進 制 的 字 符 串 −−> native_浮 點 型 −−> native_整 型 ". 特 別 要 指 出 的 是 , 儘 管 像 "0.99999999999999999999" 這 樣 的 數 可 能 會 取 整 成 1, 取 整 一 般 是 傾 向 於 0的 。

限 制 : 上 面 標 有 "(*)" 的 轉 換 包 含 有 C編 譯 器 的 動 作 步 驟 。 在 特 殊 情 況 下 , C編 譯 器 的 一 些 特 性 或 者 Bugs可 能 會 導 致 上 述 一 些 規 則 的 不 成 立 。

Flavors of Perl numeric operations 數 值 操 作 的 特 色

Perl 中 帶 有 數 值 參 數 的 操 作 將 按 照 四 種 方 法 處 理 參 數 : 它 們 可 能 會 將 參 數 強 制 轉 換 為 整 型 , 浮 點 型 或 是 字 符 串 型 中 的 一 種 , 或 者 按 照 操 作 數 的 格 式 來 處 理 參 數 。 在 把 一 個 數 的 類 型 強 制 轉 換 成 另 一 種 特 定 的 類 型 的 過 程 中 , 原 來 存 儲 的 值 不 會 改 變 。

所 有 需 要 整 型 數 作 參 數 的 運 算 符 會 對 參 數 進 行 取 模 的 操 作 。 比 如 說 用 32位 存 放 整 型 數 時 會 把 數 對 2的 32次 方 取 模 ("mod 2**32"), 所 以 "sprintf "%u", −1" 的 結 果 和 "sprintf "%u", ~0" 的 結 果 是 一 樣 的 。
Arithmetic operators 算 術 運 算 符

二 進 制 運 算 符 "+" "−" "*" "/" "%" "==" "!=" ">" "<" ">=" "<=" 以 及 一 元 運 算 符 "−" "abs" and "−−" 總 試 圖 將 參 數 轉 換 為 整 形 。 如 果 轉 換 都 可 以 無 損 精 度 地 進 行 , 並 且 運 算 也 無 損 於 精 度 , 那 麼 返 回 整 數 的 結 果 。 否 則 , 參 數 被 轉 換 為 浮 點 數 , 返 回 浮 點 數 結 果 。 轉 換 的 緩 沖 過 程 保 証 了 整 數 轉 換 不 會 將 浮 點 數 的 零 頭 丟 掉

++

"++" 的 行 為 與 其 他 操 作 符 類 似 , 但 是 如 果 操 作 數 是 滿 足 "/^[a−zA−Z]*[0−9]*\z/" 格 式 的 字 符 串 , 將 進 行 perlop 中 描 述 的 字 符 串 遞 增 運 算 。

定 義 了 "use integer" 時 的 算 術 運 算

"use integer;" 的 作 用 范 圍 內 , 幾 乎 上 面 列 出 的 所 有 操 作 符 都 將 它 們 的 操 作 數 轉 換 為 整 數 , 返 回 整 數 的 結 果 , 例 外 情 況 是 "abs", "++""−−", 在 這 種 情 況 下 不 改 變 行 為 。

Other mathematical operators 其 他 數 學 操 作 符

類 似 "**", "sin""exp" 的 操 作 符 強 制 參 數 為 浮 點 格 式 。

Bitwise operators 位 操 作 符

如 果 不 是 字 符 串 , 操 作 數 被 強 制 轉 換 為 整 型

定 義 了 "use integer" 時 的 位 運 算

強 制 參 數 為 整 型 。 並 且 , 移 位 操 作 在 內 部 使 用 有 符 號 整 型 而 不 是 預 設 的 無 符 號 數

需 要 整 型 操 作 數 的 操 作 符

強 制 操 作 數 轉 換 為 整 型 。 例 如 , 在 函 數 "sysread" 的 第 三 和 第 四 個 參 數 中 , 這 樣 做 是 合 適 的 。

需 要 字 符 串 的 操 作 符

強 制 操 作 數 為 字 符 串 格 式 。 例 如 , 在 "printf "%s", $value" 中 , 這 樣 做 是 合 適 的 。

儘 管 強 制 轉 換 參 數 為 特 定 格 式 不 會 改 變 已 存 儲 的 數 字 , Perl 會 記 錄 轉 換 的 結 果 。 特 別 的 , 儘 管 第 一 次 轉 換 會 耗 費 一 定 時 間 , 重 復 進 行 的 操 作 不 會 需 要 重 新 轉 換 。

AUTHOR 作 者

Ilya Zakharevich "ilya [AT] math.ohio−state.edu"

由 Gurusamy Sarathy <gsar [AT] ActiveState.com> 編 輯

由 Nicholas Clark <nick [AT] ccl4.org> 更 新 為 5.8.0 版

SEE ALSO 參 見

overload, perlop