https://youtu.be/sHA2L4ecY3U
今回はThe Basics
の 浮動小数点数リテラル
について見ていきます。そんなリテラルの特徴や書き方についてみていった後、整数リテラルも含めた少し特殊な書き方についておさらいします。それ以外にもリテラル周りの言語仕様について広くみていけたらいいなと思っています。よろしくお願いしますね。
———————————————————————— 熊谷さんのやさしい Swift 勉強会 #117
00:00 開始 00:28 C 言語の8進数 04:12 浮動小数点数リテラル 04:26 指数表記 05:28 16進数浮動小数点数リテラル 07:27 指数表記の省略 08:09 0 から始まる接頭辞 12:08 指数表記の記号の由来は? 16:15 数値リテラルの区切り記号 19:37 文字列の連結 20:32 文字列リテラルの特殊表現 21:36 複数行の文字列リテラル 25:08 複数行リテラルの行頭 28:03 ドキュメンテーションマークアップ 30:34 クロージング ————————————————————————
Transcription & Summarize : 熊谷さんのやさしい Swift 勉強会 #117
はい、では今日はリテラルの続きです。今画面に映っているのは、前回お話しした内容ですね。定数リテラルの表記方法には4つのリアルドがあるというお話でした。そして、そこで「八進数って面白いよね」という話になったのですが、なぜC言語ではゼロを頭につけるだけでうまくいくのかという点についても話しました。インターネットで色々な方がこのことについて話しているのを見て、納得しました。
昔のプログラミング言語は、コンパイラーがチープだったことやコンピュータそのものが限られた性能だったこともあり、できることが制限されていました。また、昔は名前をつけることに慎重になる文化もありませんでした。今は用途に合わせて慎重に名前をつけるガイドラインがありますが、昔は名前なんてどうでもいいという感じだったわけです。当時の変数名は2文字でしかつけられなかったり、せいぜい8文字程度という制約があったため、名前にこだわる必要がなかったのです。
そのため、コードの表現は便利に書きたいという要求があったのだと思います。発信数が便利に扱えた時代があり、C言語などでも同様にゼロを頭につけると発信数として解釈される仕様になっていたのです。Swiftなどの現在の言語では、二進数は0b
、八進数は0o
、十六進数は0x
と統一感のある表現が採用されています。しかし、当時は受信数の頭に何もつけないで、八進数ならゼロをつけるという感覚でした。
次に、不動小数点数リテラルについて見ていきます。前回少しだけ触れたのですが、詳しい話はまだしていないので、改めて見ていきましょう。不動小数点数のリテラルは、一般的に次のような書き方があります。普通の小数点数の書き方と、この指数表記です。
指数表記は昔から多くの言語でサポートされており、物理学などの分野で使われます。この表現は、「何かける10の何乗」という形式で、高校の物理でもお馴染みの書き方です。また、16進数の指数表記も可能で、0x
から始まり、その後にアルファベットのPで挟んで「何乗」という表現が用いられています。このPは2の何乗という意味を持ち、非常に興味深い特徴です。
2の何乗という表現は、プログラミングにおける不動小数点数がバイナリ表現であるためです。この表記方法により、リテラルを人間が書くことが可能になり、精密な数値の表現ができるようになっています。一方で、10進数の不動小数点数リテラルは指数表現を書かない場合と書く場合の2つが許されていますが、16進数の小数点数リテラルは必ず指数表現を書かないといけません。
このように、リテラルの表記方法には多くの違いがあり、それぞれの用途に合わせて使い分けることが重要です。 とりあえず、こういう仕様になっているようです。では、さっきの8進数の話ですが、面白いと思ったお話を続けます。例えば、8進数表現で 0888075
といったような数字が頭につく場合があります。このときに、頭にプレフィックスを付けるときに、例えば8進数は「オクタル(octal)」だから「O」を付けると仮に決めたとします。すると、誤解なく理解できます。しかし、具体的にどう書くかを考えたとき、昔のコンピュータの環境では頭に何か目印を付けようという発想がありました。
例えば、変数があってこれを8進数として解釈したいと思ったとき、昔のリソースが限られている状況では何か1文字くらいを付けようという発想がありました。そのとき、「O」がわかりやすいとされました。しかし、間違えて打ったりすると困ります。例えば 0
プレフィックスの場合、こうしたときにリテラルが全然違うものになってしまいます。1行目と2行目で解釈が変わるからです。
頭がアルファベットだと、これを変数と区別するのが難しいです。変数がアルファベットで名前が付いていると、頭が「O」だと、それが変数なのか8進数リテラルなのかを解釈するのに時間がかかります。以前の勉強会で、変数名には頭に数字以外のものを付けるというルールがありました。このルールが働いて、リテラルはとにかく数字で始め、それで変数はとにかくアルファベットで始めるという形になっています。リテラルと変数の区別がなくならないよう、プレフィックスをアルファベットで付けるのは難しいという感じで、結局 0
を選んだのでしょうね。
いろいろ面白いなという話ですが、話を戻すと、頭に数字を付けることが大事ということです。バックスラッシュとかでも良かったかもしれませんが、数字を選んだという話です。
次へ進みましょうか。次のお話も雑談ですが、e
という表現についてです。すごく不思議に思うのが、なぜ e
を選んだのかということです。数学では自然対数を表すeですが、ここでは 10
の何乗という意味で使っています。なぜここで e
を使っているのかが気になりました。しかし、調べてみて分かったのですが、これは指数部を意味する「エクスポネント(exponent)」の e
と解釈してよさそうです。断言している情報は見つけられませんでしたが、それが由来だと考えてよいでしょう。 まず、仮数部をかける指数の指数部乗というのは、仮数部がフラクション(fraction)、指数部がエクスポネント(exponent)だからです。このエクスポネントが何なのかというと、エクスポネントは指数のことです。では、なぜここで p
なのかを調べてみましたが、結局わかりませんでした。10の累乗と2の累乗を同じキーワードで表現すると混乱しやすくなるため、違う表現にしたのかもしれません。
それでも、なぜ p
を選んだのかというのは不明ですが、「パワー(power)」の可能性があるといえばありますね。パワーは累乗という意味もあり、特に二進数において適しています。また、二進数の計算や数列で p
というアルファベットが使われることがあったような記憶もありますが、確証は得られませんでした。
とりあえず、p
には何か意味があるのではないかという気がします。直感的にパワーのことではないかと考えると納得がいく部分もありますので、後でゆっくりと再確認してみようと思います。このように、なぜ p
を選んだのかという背景を調べるのも面白いですし、こういった経験が他の仕様を決める際に役立つこともあるかもしれません。
続いて、十六進数表記について触れましたが、もう一つ特別な表記がリテラルにはあります。それは、知る人ぞ知る、リテラル内で数字を自由に区切れるアンダースコア(_
)の記号です。これを使うと、数字を読みやすくすることができます。
例えば、100万のような大きな数字を設定したいときに、そのまま書くと非常にわかりにくくなりますが、アンダースコアを使うことで次のように区切ることができます:
let million = 1_000_000
このようにすると非常にわかりやすくなります。ただし、先頭と末尾以外の位置であれば、どこにでもアンダースコアを入れることができます。
実際に試してみると、リテラルの末尾にもアンダースコアを置けるようですね。これがどこで便利になるかはわかりませんが、場合によっては良い感じに使えることがあるかもしれません。このように、数字の可読性を高める方法としてアンダースコアを活用できる点は覚えておくと良いでしょう。 これを区切り記号として使う場合、桁数は全然関係ありません。例えば、2つずつ区切ったり、下は2つで上は3つなど、自由に使用することができます。この記号は無視されるだけなので、本当に問題ありません。
日本では昔、4桁区切りが一般的だったことがあります。私も幼い頃の話なので記憶が曖昧ですが、確かに日本では4桁区切りの形式がありました。例えば1万、10万、100万というように4桁区切りが使用されていました。この形式も現在のプログラミング言語では柔軟に対応できます。数値リテラルであればアンダースコアを使って区切ることができますので、その例として、1_0000
という具合に書くことができます。
次に、文字列リテラルについて考えてみましょう。例えば、文字列リテラルが ab
で、その後に cd
を連結する場合、通常は分離されません。言語によってはこういった書き方が違ったりすることがありますが、Swiftではこの形式はサポートされていません。言語によっては文字列を連結するために異なる手法が使われる場合もあります。例えば、ダブルクォートを挿入するといった書き方が必要になる場合があります。
Swiftでは、文字列に特殊な記号を含めたい場合に対応する方法があります。例えば、文字列内にダブルクォートを含めたい場合は、ダブルクォートの前後にシャープを置くことで対応できます。これによって、ダブルクォートを含む文字列を作成することができます。
また、改行を含む文字列リテラルを作成したい場合は、ダブルクォートを3つ書いて、その中に改行を含む文字列を書くことができます。この場合も適切に閉じられている必要があります。例えば、以下のように書きます。
let multilineString = """
これは
複数行の
文字列です。
"""
エラーが発生した場合は、エラーメッセージをよく読んで、何が原因かを確認することが大切です。最近ツイッターなどで「エラーを読まない開発者」という話題が出てきているようですが、エラーメッセージをしっかりと読むことが重要です。エラーを無視せず、理解することで、問題を解決する手助けとなります。自分もエラーメッセージを読むことの重要性を再認識しています。
このように、Swiftでは数値リテラルや文字列リテラルに関するさまざまな表現方法が用意されています。これらの機能を活用して、柔軟にプログラミングを行うことができます。 なので、時折変な発想のままエラーも読まずに「あれ、おかしいな」と感じつつ作業していることがあるようです。
コメントについては、ダブルコーテーションを使ってテキストを判定します。例えば、ダブルコーテーションが連なっているところが先頭にあり、その後にタブがちゃんと入る場合などです。このような場合、場所を把握しやすくなります。しかし、ルール上どこに位置するのか、直感的に理解して決めれば問題ない部分もありますが、「Cの頭なのか、それともここなのか」と判断が難しくなることもあります。
また、コメントをダブルコーテーションの列より前に置くとエラーになります。エラーが出ることは一見厳密に見えるかもしれませんが、手間が増えてしまうこともあります。それでも、ちゃんとコンパイルエラーになるのは素晴らしい仕組みですね。
昔のことですが、私もマークダウンパーサーを作っていました。マークダウンではリストの頭にアスタリスクやハイフンをつけることでリストを書けますが、インデントに関する仕様は公式には規定されていません。普通はインデントを考慮しないことが多いのですが、たとえばリストの最初の段を揃えるためにインデントをつける場合があります。このとき、パーサーがどこに何を置くのか判断するのが難しい場面がありました。
Xcodeがどのように解釈するのか試してみましたが、マークダウンのレンダリングでインデントがどうなるのか確認が必要です。ドキュメントコメントやマークダウン記法についても詳しく調べてみました。APIのためのドキュメントコメントではビックリマークを使うなどの仕様もありますね。
実際に実践してみると、インデントを増やすことでどうレンダリングされるのかもわかってきました。複数行の頭合わせに関しては、仕様がはっきりしていれば、外れたときにコンパイルエラーが出るので便利です。
では、これで勉強会を終わります。お疲れ様でした。ありがとうございました。