整数を英語で表現する4(序数と負数)
最後に、序数と負数について説明します。
序数
数が0~19までの序数はすでに表に出しています。
例えば13は下記の通り。
* (format t "~:R" 13) thirteenth
20以上の場合、例えば43は次のようになる。
* (format t "~:R" 43) forty-third
40であるforty
は通常の表記ですが、最後の単語である3が序数となります。
単語がいくつあっても、最後だけが序数表記となります。
数が50であった場合は、十の位が最後の単語になるため、
fifty
の序数が表記されます。
* (format t "~:R" 50) fiftieth
複数の単語の例を挙げます。
* (format t "~:R" 1234) one thousand two hundred thirty-fourth
hundredの場合は単純にthをつけます。
* (format t "~:R" 100) one hundredth
それ以外のもの、も例えばthousand
やmillion
、
あるいは巨大な単位milliquattuortrigintaducentillion
なども、
単純に最後のth
をつけるだけです。
例を挙げます。
thousand → thousandth million → millionth milliquattuortrigintaducentillion → milliquattuortrigintaducentillionth
実行例をあげます。
* (format t "~:R" 1000) one thousandth * (format t "~:R" 10000000000) ten billionth
負数
負数については、単純に最初にminus
かnegative
をつけます。
例を示します。
[sbcl]
* (format t "~R" -100) negative one hundred * (format t "~:R" -100) negative one hundredth
[ccl]
? (format t "~R" -100) negative one hundred ? (format t "~:R" -100) negative one hundredth
[clisp]
> (format t "~R" -100) minus one hundred > (format t "~:R" -100) minus one hundredth
なお、cltl2では序数で負数の場合は、
最後にprevious
を印字するものもあるとのこと。
例えば次の通り。
* (format t "~:R" -4) fourth previous
以上で整数を英語で表現する説明は終わりです。
整数を英語で表現する3(巨大な数)
前回はthousand, million, billionの次は何かという話題で終わらせました。 この3桁区切りの単位さえわかれば、無限に数を表現できることになります。 どうも、この単位を求める方法は決まっておらず、色々あるようです。 本投稿では、 The Conway-Wechsler System という方法について説明していきます。
【注意】今回の内容はThe Conway-Wechsler Systemそのものなので、 英語がわかる人は下記ページを見た方が正確です。
The Conway-Wechsler System
http://www.mrob.com/pub/math/largenum.html#conway-wechsler
Wikipediaではまた違った方法で説明しているようです。 本投稿では説明するつもりはないですが興味がある方はどうぞ。
Names of large numbers
https://en.wikipedia.org/wiki/Names_of_large_numbers
それでは単位を求めて行きます。 まずは対象となる数が、何番目の単位に該当するのかを求めます。 数が10の何乗かを求めます。 10なら1、10,000なら4になります。
求めた数から3を引きます。 1,000なら3-3=0、1,000,000,000なら9-3=6です。
引いた数を3で割り、商と余りを求めます。 もし余りが0ならoneから、1ならtenから、2ならone hundredから始まることになります。 求めた商が重要であり、解説ではNと表現されていました。
もし商Nが10未満の場合は、下記の表によって決定されます。
商N | 英語 |
---|---|
0 | thousand |
1 | million |
2 | billion |
3 | trillion |
4 | quadrillion |
5 | quintillion |
6 | sextillion |
7 | septillion |
8 | octillion |
9 | nonillion |
商Nが10以上の場合は、 商Nの一の位、十の位、百の位の数の組み合わせによって文字列を求めます。 ひとまずは商Nが10~999までの場合を考慮しましょう。 ちなみに商Nが999というのは、元の数が3000桁の場合となります。
組み合わせの表を示します。
商N | 1の位 | 10の位 | 100の位 |
---|---|---|---|
0 | - | - | - |
1 | un | (n) deci | (nx) centi |
2 | duo | (ms) viginti | (n) ducenti |
3 | tre (*) | (ns) triginta | (ns) trecenti |
4 | quattuor | (ns) quadraginta | (ns) quadringenti |
5 | quin | (ns) quinquaginta | (ns) quingenti |
6 | se (sx) | (n) sexaginta | (n) sescenti |
7 | septe (mn) | (n) septuaginta | (n) septingenti |
8 | octo | (mx) octoginta | (mx) octingenti |
9 | nove (mn) | nonaginta | nongenti |
表より商Nの一の位、十の位、百の位の文字をつなげて文字列を作ります。
ただし()
が隣り合っている場合は、カッコ内の文字が等しいときにその文字を入れます。
例えば
septe(mn) + (ms)viginti = septemviginti
この例では、(mn)
と(ms)
でどちらにもm
が含まれているため、
文字m
を二つの単語の間に入れました。
他には
se(sx) + (mx)octoginta = sexoctoginta
カッコが連結しているのは一の位と十の位、あとは一の位と百の位であり、 十の位と百の位ではカッコが隣り合っていないので注意。
特別な場合として、一の位のtre(*)
があります。
これは、隣り合っているカッコにs
かx
が含まれている場合には、
文字s
を入れます。
例えば
tre(*) + (mx)octingenti = tresoctingenti
この例では、(*)
と(mx)
が隣り合っており、文字にx
があるため、
文字x
ではなく文字s
を挿入しています。
求めた英単語の最後の母音を削除します。
母音はa,i,u,e,o
であり、例えば次のようになります。
tresoctingenti → tresoctingent
英単語の最後に文字illion
をつけます。
例えば下記の通り。
tresoctingent → tresoctingentillion
完成です。
例を挙げます。
値 | 英語 |
---|---|
10の261乗 | sexoctogintillion |
10の2421乗 | sexoctingentillion |
10の309乗 | duocentillion |
10の603乗 | ducentillion |
10の312乗 | trescentillion |
10の903乗 | trecentillion |
以上で、商Nが0~999まで説明はしました。 では商Nが999が超えた場合を説明します。
まずは商Nを3桁区切りにします。 例えば求めた商Nが987654321であった場合は、
987,654,321
となります。考え方としては、
987 illi 654 illi 321 illion
のように、文字を少し変えて横に直列でつなぐことで求めます。 それぞれ3桁の単位を求めると次のようになります。
987 septemoctogintanongentillion 654 quattuorquinquagintasescentillion 321 unvigintitrecentillion
321以外の単語の最後についている「on」削除します。
987 septemoctogintanongentilli ★on削除 654 quattuorquinquagintasescentilli ★on削除 321 unvigintitrecentillion
単語をつなげます。
septemoctogintanongentilliquattuorquinquagintasescentilliunvigintitrecentllion
非常に長いが完成です。 あまりに長すぎるようにも思えますが、そもそも商Nが987654321という場合は 元々の数の桁数が2962962966であり、30億個近くも数値が連なる場合なので 単位もここまで長くなってしまうのです。
このアルゴリズムでは、単位が必ずillion
で終わることが前提となっているのですが、
たった一つだけ、商Nが0の時はthousand
なのでillion
で終わりません。
そこでthousand
ではなく、nillion
という表記で代用します。
例を挙げます。
1000 millinillion (million + thousand) 1001 millimillion 1002 millibillion 1003 millitrillion 1013 millitredecillion 1234 milliquattuortrigintaducentillion 6560 sextillisexagintaquingentillion 19683 novendecillitresoctogintasescentillion 1000000 millinillinillion
以上で説明は終わりですが、注意点をいくつか。 このアルゴリズムは絶対ではなく、方言が色々あるようです。 基本的な考え方はラテン語をベースとしているようで、 ラテン語にとって自然な場合はこっちだろうということで、 人によって色んな考え方があるようです。
解説しているリンク先では詳しく説明されていますが、 例えば
The Conway-Wechsler Systemでは quinquadecillion, sedecillion, and novendecillion だが、 quindecillion, sexdecillion and novemdecillion としてよく知られているとか、 millinillion ではなく millillion と表現する場合があるとか、 quinqua より quin の方が自然だろう
とかが話題として出ているので、 もし他のシステムと相違があって困った場合は確認してみてください。 例えば2の200乗の例では、sbclとclispでは
one novemdecillion
で始まりますが、The Conway-Wechsler Systemでは
one novendecillion
となります。
その他にもWikipediaに載っている方法も何となく違って見えます。
Names of large numbers
https://en.wikipedia.org/wiki/Names_of_large_numbers
ここまででThe Conway-Wechsler Systemの解説は終わりですので、 最後にいくつか話題を残します。 まずは、本解説を用いて出力した2の200乗の結果を下記に示します。
one novendecillion, six hundred and six octodecillion, nine hundred and thirty-eight septendecillion, forty-four sedecillion, two hundred and fifty-eight quindecillion, nine hundred and ninety quattuordecillion, two hundred and seventy-five tredecillion, five hundred and forty-one duodecillion, nine hundred and sixty-two undecillion, ninety-two decillion, three hundred and forty-one nonillion, one hundred and sixty-two octillion, six hundred and two septillion, five hundred and twenty-two sextillion, two hundred and two quintillion, nine hundred and ninety-three quadrillion, seven hundred and eighty-two trillion, seven hundred and ninety-two billion, eight hundred and thirty-five million, three hundred and one thousand, three hundred and seventy-six
せっかくなのでgoogolについての話題もしておきます。 googolとは「10の100乗」を意味しており、 wikipediaによると検索サイトgoogleはgoogolの誤字がもとになっているとのこと。
The Conway-Wechsler Systemによると、10の100乗は下記のようになります。
ten duotrigintillion
あと、商Nが0から1000くらいまでならnpt
のテストケースに例がありますので示します。
https://github.com/nptcl/npt/blob/v0.1.1/test/case_large.txt
次の投稿では序数と負数について説明します。
整数を英語で表現する2(中学レベル)
あまり大きくない整数を英語で表す方法について説明します。 どれくらいかというと、0から億くらいでしょうか。 それ以上の整数の表現は次章になります。
自分は中学レベルの英語の知識も危うかったため調べました。 せっかくなのでその内容をここに記載しておきます。 俺もわからんぜって方は、ここじゃなく別のサイトに飛んで、 ちゃんとした所で勉強したほうがいいかもしれません。 間違っている可能性がありますので。
では、あまり大きくない整数をshort scaleの英語で 表現する方法について説明します。
まずは0から19までの表現を示します。 せっかくなのでCommon Lispを使って出力します。 これらは暗記するしかありません。
* (dotimes (i 20) (format t "~D: ~:*~R, ~:*~:R~%" i)) 0: zero, zeroth 1: one, first 2: two, second 3: three, third 4: four, fourth 5: five, fifth 6: six, sixth 7: seven, seventh 8: eight, eighth 9: nine, ninth 10: ten, tenth 11: eleven, eleventh 12: twelve, twelfth 13: thirteen, thirteenth 14: fourteen, fourteenth 15: fifteen, fifteenth 16: sixteen, sixteenth 17: seventeen, seventeenth 18: eighteen, eighteenth 19: nineteen, nineteenth
出力は「数: 英語表記, 序数表記」となります。
20から99までの表現は、十桁と一桁を組み合わせて表現します。 20, 30, ...といった十桁の表現の仕方も、暗記するしかありません。
* (dotimes (i 10) (format t "~D: ~:*~R, ~:*~:R~%" (* i 10))) 0: zero, zeroth 10: ten, tenth 20: twenty, twentieth 30: thirty, thirtieth 40: forty, fortieth 50: fifty, fiftieth 60: sixty, sixtieth 70: seventy, seventieth 80: eighty, eightieth 90: ninety, ninetieth
それでは2桁の数を考えます。
例えば48の場合、40-8のようにあらわします。
【例】48 → forty-eight
十桁と一桁の間にハイフン - をつけます。
【例】67 → sixty-seven
十桁が0の場合は十桁を記載しません。
【例】7 → seven
一桁が0の場合も一桁は記載しません。
【例】60 → sixty
つまり、40はfortyでありforty-zeroとは書かないし、 7はsevenでありをzeroty-sevenと書きません。
百の位が出てきた場合は、「百桁 hundred 下二桁」となります。 例えば123の場合は、1と23を分けて表記するため、
one hundred twenty-three
のようになります。
345の場合は
three hundred forty-five
205の場合は、十桁が省略されるので
two hundred five
560の場合は、一桁が省略されるので
five hundred sixty
800の場合は、十桁と一桁が省略されるので
eight hundred
これで0から999まで表現できました。
それ以上の数は、三桁に分けて特別な単位を付与します。 例えば1234567890の場合は、三桁区切りにすると次のようになります。
1,234,567,890
左のカンマから順に十億、百万、千に対応します。 英語ではそれぞれ次のように表現されます。
数値 | 英語 | 日本語 |
---|---|---|
1,000,000,000 | billion | 十億 |
1,000,000 | million | 百万 |
1,000 | thousand | 千 |
考え方としては、次のようになります。
1 billion, 234 million, 567 thousand, 890
つまり、
* (format t "~R" 1234567890) one billion two hundred thirty-four million five hundred sixty-seven thousand eight hundred ninety
注意点としては、三桁の場合と同じようにzeroは省略し、 記載が必要ない場合は単位も省略します。
例えば
1,000,000,000
は
one billion
であり、
one billion zero million zero thousand zero
ではありません。
それではCommon Lisp処理系の出力例を見てみます。
[sbclの実行例]
* (format t "~R" 1234567890) one billion two hundred thirty-four million five hundred sixty-seven thousand eight hundred ninety
[clispの実行例]
* (format t "~R" 1234567890) one billion, two hundred and thirty-four million, five hundred and sixty-seven thousand, eight hundred and ninety
上記2例では少しだけ表現が違っています。 sbclに対して、clispでは三桁区切りでカンマが挿入されています。 また、hundredの次にandが挿入されています。 この辺りはいろいろな流儀があるのでしょう。 好みでいいと思います。
今回は三桁区切りの表現方法を説明しました。 それではthousand, million, billionの次は何でしょうか。 これが次章の本題となります。
整数を英語で表現する1
これから整数を英語で表す方法をひたすら説明します。
Common Lispのformat関数~R
では、整数を英語で表現できます。
例えば下記の通り。
* (format t "~R" 13) thirteen * (format t "~R" 1234) one thousand two hundred thirty-four * (format t "~R" -200) minus two hundred
オプションのコロンをつけて、~:R
とすることで序数を表すことができます。
序数とは、one, two, threeじゃなくて、first, second, thirdみたいなやつです。
* (format t "~:R" 13) thirteenth * (format t "~:R" 2) second * (format t "~:R" -987) minus nine hundred eighty-seventh
この整数を英語で表現するという機能を開発したときの話です。
引数の整数とは一体どれくらい大きな値を考慮するべきでしょうか。
一億、一兆まで? 一無量大数まで? それ以上?
ANSI Common Lispの規格書には記載が見つけられませんでしたが、
cltl2には詳しく書かれていました。
話題にしたい部分を抜き出すと、
- 2の200乗の表示例がある。
- 999,999,999を超える場合は10進数表記でもいいんじゃない?
2の200乗というのは10進数で61桁という巨大な数値であり、下記のようになります。
* (ash 1 200) 1606938044258990275541962092341162602522202993782792835301376
日本語で記載すると
1那由他6069阿僧祇3804恒河沙・・・億3530万1376
みたいな感じなります。
那由他ってなんだ。
cltl2の表示例を下記に示します。
https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node200.html#SECTION002633000000000000000
one times ten to the sixtieth power six hundred six times ten to the fifty-seventh power nine hundred thirty-eight septdecillion forty-four sexdecillion two hundred fifty-eight quindecillion nine hundred ninety quattuordecillion two hundred seventy-five tredecillion five hundred forty-one duodecillion nine hundred sixty-two undecillion ninety-two decillion three hundred forty-one nonillion one hundred sixty-two octillion six hundred two septillion five hundred twenty-two sextillion two hundred two quintillion nine hundred ninety-three quadrillion seven hundred eighty-two trillion seven hundred ninety-two billion eight hundred thirty-five million three hundred one thousand three hundred seventy-six Another implementation prints it this way (note the use of plus): one times ten to the sixtieth power plus six hundred six times ten to the fifty-seventh power plus ... plus two hundred seventy-five times ten to the forty-second power plus five hundred forty-one duodecillion nine hundred sixty-two undecillion ... three hundred seventy-six (I have elided some of the text here to save space.)
では999,999,999を超える場合は10進数表記でもよいというのは何故でしょうか。 ここで話題に出しておかなければいけないのは、 数値を英語で表記する際の「scale」の問題です。 scaleというのは、方言みたいなもので、long scaleとshort scaleが存在します。 昔からアメリカはshort scaleであり、 long scaleを使っていたイギリスも、つい最近?はshort scaleに 移行したとかしなかったとか。 たぶんみなさまが知ってるのはshort scaleだと思います。
詳細はここ
https://ja.wikipedia.org/wiki/西洋の命数法
999,999,999を超えるとshort scaleとlong scaleで 英語の表現が変わってきてしまいます。 例えばbillionという単位は、short scaleでは十億ですが、 long scaleでは一兆のことになります。 だから10進数表記を勧めるとの記載があるのです。
でも多くのCommon Lisp処理系ではとんでもない数字でも 何とか頑張って出してしまいます。 2の200乗を各処理系で出力してみます。
clispの場合
> (format t "~R" (ash 1 200)) one novemdecillion, six hundred and six octodecillion, nine hundred and thirty-eight septendecillion, forty-four sexdecillion, two hundred and fifty-eight quindecillion, nine hundred and ninety quattuordecillion, two hundred and seventy-five tredecillion, five hundred and forty-one duodecillion, nine hundred and sixty-two undecillion, ninety-two decillion, three hundred and forty-one nonillion, one hundred and sixty-two octillion, six hundred and two septillion, five hundred and twenty-two sextillion, two hundred and two quintillion, nine hundred and ninety-three quadrillion, seven hundred and eighty-two trillion, seven hundred and ninety-two billion, eight hundred and thirty-five million, three hundred and one thousand, three hundred and seventy-six
sbclの場合
* (format t "~R" (ash 1 200)) one novemdecillion six hundred six octodecillion nine hundred thirty-eight septendecillion forty-four sexdecillion two hundred fifty-eight quindecillion nine hundred ninety quattuordecillion two hundred seventy-five tredecillion five hundred forty-one duodecillion nine hundred sixty-two undecillion ninety-two decillion three hundred forty-one nonillion one hundred sixty-two octillion six hundred two septillion five hundred twenty-two sextillion two hundred two quintillion nine hundred ninety-three quadrillion seven hundred eighty-two trillion seven hundred ninety-two billion eight hundred thirty-five million three hundred one thousand three hundred seventy-six
cclの場合
? (format t "~R" (ash 1 200)) エラー
そんなに頑張らなかったcclが一番賢いような気がします。
上記2例は全てshort scaleで出力されています。 調査した範囲のCommon Lisp処理系では全部short scaleでした。 たぶん日本でなじみが深いのもshort scaleだと思うので、 本投稿の説明はすべてshort scaleで説明することにしました。
最初の疑問の回答ですが、どれくらいの数を対象にするべきかというと、 999,999,999制限で絶対に問題ないでしょう。 でも他のLispさんたちが結構頑張っているようなので、 制限なしでいくらでも大きな数を対象すると決めました。
では次の投稿から数値を英語で表現する方法について説明します。 自分は中学レベルの英語の知識も危ういので、 最初は小さな数から説明し、次に巨大な数を説明します。
遅すぎるPCでsbclのソースをコンパイルする
遅すぎるPC上でsbclのソースをコンパイルすると、途中でエラーが発生して止まります。 あまり問題になっていないように見えるのですが、 みんないいコンピュータを使用しているからなのでしょう。
うちにあるのはクソみてえなPCばかりで、 FreeBSDのportsでコンパイルしてもあっさりエラーになってしまいます。 エラーの内容は下記の通り。
# make ・・・ ・・・ WARNING! Some of the contrib modules did not build successfully or pass their self-tests. Failed contribs:" sb-concurrency 410.14 real 1025.96 user 112.83 sys *** Error code 1 Stop. make[1]: stopped in /usr/ports/lang/sbcl *** Error code 1 Stop. make: stopped in /usr/ports/lang/sbcl #
もっとさかのぼってみると、次のようなエラーが生じていました。
Doing 25 pending tests of 25 tests total. SB-CONCURRENCY-TEST::FRLOCK.1 SB-CONCURRENCY-TEST::QUEUE.1 SB-CONCURRENCY-TEST::QUEUE.2 SB-CONCURRENCY-TEST::QUEUE.3 SB-CONCURRENCY-TEST::QUEUE.4 SB-CONCURRENCY-TEST::QUEUE.5 SB-CONCURRENCY-TEST::QUEUE.T.1 SB-CONCURRENCY-TEST::QUEUE.T.2 SB-CONCURRENCY-TEST::QUEUE.T.3 SB-CONCURRENCY-TEST::MAILBOX-TRIVIA.1 SB-CONCURRENCY-TEST::MAILBOX-TRIVIA.2 SB-CONCURRENCY-TEST::MAILBOX-TRIVIA.3 SB-CONCURRENCY-TEST::MAILBOX-TIMEOUTS SB-CONCURRENCY-TEST::MAILBOX.SINGLE-PRODUCER-SINGLE-CONSUMER SB-CONCURRENCY-TEST::MAILBOX.SINGLE-PRODUCER-MULTIPLE-CONSUMERS SB-CONCURRENCY-TEST::MAILBOX.MULTIPLE-PRODUCERS-SINGLE-CONSUMER Test SB-CONCURRENCY-TEST::MAILBOX.MULTIPLE-PRODUCERS-MULTIPLE-CONSUMERS failed Form: (SB-CONCURRENCY-TEST::TEST-MAILBOX-PRODUCERS-CONSUMERS :N-SENDERS 50 :N-RECEIVERS 50 :N-MESSAGES 1000) Expected values: (:RECEIVED . 50000) (:GARBAGE . 0) (:ERRORS . 0) (:TIMEOUTS . 0) Actual values: (:RECEIVED . 48389) (:GARBAGE . 0) (:ERRORS . 0) (:TIMEOUTS . 6). SB-CONCURRENCY-TEST::MAILBOX.INTERRUPTS-SAFETY.1 SB-CONCURRENCY-TEST::GATE.0 SB-CONCURRENCY-TEST::GATE.1 SB-CONCURRENCY-TEST::GATE.2 SB-CONCURRENCY-TEST::GATE-DEADLINE.1 SB-CONCURRENCY-TEST::GATE-DEADLINE.2 SB-CONCURRENCY-TEST::GATE-TIMEOUT.1 SB-CONCURRENCY-TEST::GATE-TIMEOUT.2 1 out of 25 total tests failed: SB-CONCURRENCY-TEST::MAILBOX.MULTIPLE-PRODUCERS-MULTIPLE-CONSUMERS. WARNING: ignoring expected failures in test-op Unhandled SIMPLE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {10005305B3}>: test-op failed with unexpected failures
大体はこいつ、mailboxのせいです。 PCが遅すぎるからsb-concurrencyのテストでタイムアウトするのです。 仕方がないので次のようにファイルを変更してからコンパイルを行います。
--- contrib/sb-concurrency/tests/test-mailbox.lisp.error 2017-03-01 04:51:29.000000000 +0900 +++ contrib/sb-concurrency/tests/test-mailbox.lisp 2017-03-26 11:14:54.834397000 +0900 @@ -204,10 +204,10 @@ #-win32 (deftest mailbox.multiple-producers-multiple-consumers - (test-mailbox-producers-consumers :n-senders 50 - :n-receivers 50 - :n-messages 1000) - (:received . 50000) + (test-mailbox-producers-consumers :n-senders 5 + :n-receivers 5 + :n-messages 1) + (:received . 5) (:garbage . 0) (:errors . 0) (:timeouts . 0))
sbclのバージョンによって行が違うでしょうから、 上のdiffは参考にする程度で手で書き換えてください。
場合によっては他にもエラーが生じるので、 そのたびにテストケースを変更しなければなりません。 頻度は少ないですが、それなりに生じるものはfrlockです。
--- contrib/sb-concurrency/tests/test-frlock.lisp.error 2017-05-17 10:57:20.356675776 +0900 +++ contrib/sb-concurrency/tests/test-frlock.lisp 2017-05-17 10:57:30.386806999 +0900 @@ -87,7 +87,7 @@ #+sb-thread (deftest* (frlock.1) (handler-case - (sb-ext:with-timeout 10 + (sb-ext:with-timeout 100 (test-frlocks #+win32 :outer-write-pause #+win32 t )) (sb-ext:timeout (c) (error "~A" c)))
エラーはconcurrencyで出力されているため、 遅すぎるPCにスレッドはいらんだろうという考えで コンパイル時にthreadを無効にしてもいいかもしれません。
話はかなりずれますが、sbclを手動でコンパイルするとき、 threadを使いたい場合は、例えばこんな感じでmakeを行います。
$ sh make.sh --fancy
ファンシー?
なにやら可愛らしいですねって思ってたんですが、 fancyというのはそういう意味はないって 英語部さんのサイトで説明されていました。
- 日米英で意味が全然違う「fancy」の正しい使い方
勉強になります。
【参考】ファンシー
https://www.nijntje.nl/
https://www.miffy.com/
https://www.dickbruna.jp/
clispをFreeBSDにインストールする
【追記】13.0-RELEASEの手順はこちら FreeBSD 13.0-RELEASEでclispをソースから構築 - nptclのブログ
【追記】portsにclispが追加されました clispをFreeBSDにインストールする2 - nptclのブログ
【追記】最新バージョンのclispを入れる手順を追記しました
大昔のFreeBSDでは、clispが普通にportsで利用できていたように思えます。 しかし、ある日忽然と消えてしまいました。 clisp本家からたどれる、 Get CLISP->FreeBSD にはDEPRECATEDとか書かれています。 だからもう利用できません。
本当にそうなのか? 少なくとも自分はclispがないと生きていけないんですが、 みんな諦めて別のを使っているのでしょうか? たぶん諦めた方が賢明かもしれませんが、 ここではFreeBSDにclispをインストールする方法を説明します。
FreeBSDから削除された理由は、たぶんFreeBSDの標準コンパイラが gccからclangに変わったからだと思います。 clangではclispはコンパイルできませんでした。 結構がんばったのですが、gccじゃないとコンパイルは無理っぽい。
gccはportsから導入できるはずですが、 clispのためだけに入れるのも嫌だったので、 ここでは、ローカル環境でclispをコンパイルする方法を示します。 ちなみに確認用に実施した環境は FreeBSD 11.1-RELEASE (amd64)。
事前準備
shellは/bin/sh
で説明します。
csh系を使っている場合は切り替えてください。
% /bin/sh $
方法はgccをローカルに入れて、そのあとにclispをコンパイルするという流れとなります。
手順では、$HOME/work
配下に下記のディレクトリを作成します。
ディレクトリ | 説明 |
---|---|
install | 作業用 |
gcc | gccコンパイラ一式 |
clisp | clisp一式 |
ディレクトリ名をいちいち入力するのが面倒なので、 作業用ディレクトリ用の環境変数を設定します。
$ work="${HOME}/work" $ gcc="${HOME}/work/gcc" $ clisp="${HOME}/work/clisp"
作業用ディレクトリを作成します。
$ mkdir ${work} $ mkdir ${work}/install
gccのインストール
最新の安定版gccは8.3.0でした。 最低限の依存関係を考慮した場合、下記のファイルが必要になります。
- gmp-6.1.2.tar.xz
- mpc-1.1.0.tar.gz
- mpfr-4.0.2.tar.xz
- isl-0.20.tar.xz
- make-4.2.1.tar.bz2
- gcc-8.3.0.tar.xz
ダウンロード
$ cd ${work}/install $ fetch http://ftp.jaist.ac.jp/pub/GNU/gmp/gmp-6.1.2.tar.xz $ fetch http://ftp.jaist.ac.jp/pub/GNU/mpc/mpc-1.1.0.tar.gz $ fetch http://ftp.jaist.ac.jp/pub/GNU/mpfr/mpfr-4.0.2.tar.xz $ fetch http://isl.gforge.inria.fr/isl-0.20.tar.xz $ fetch http://ftp.jaist.ac.jp/pub/GNU/make/make-4.2.1.tar.bz2 $ fetch http://ftp.jaist.ac.jp/pub/GNU/gcc/gcc-8.3.0/gcc-8.3.0.tar.xz
ミラーサイトjaistさんを利用させていただきました。 ありがとうございます。
gmpの導入
$ cd ${work}/install $ tar Jxf gmp-6.1.2.tar.xz $ cd gmp-6.1.2 $ ./configure --prefix=${gcc} $ make $ make install $ make clean
mpfrの導入
$ cd ${work}/install $ tar Jxf mpfr-4.0.2.tar.xz $ cd mpfr-4.0.2 $ ./configure --prefix=${gcc} --with-gmp=${gcc} $ make $ make install $ make clean
mpcの導入
$ cd ${work}/install $ tar zxf mpc-1.1.0.tar.gz $ cd mpc-1.1.0 $ ./configure --prefix=${gcc} --with-gmp=${gcc} --with-mpfr=${gcc} $ make $ make install $ make clean
islの導入
$ cd ${work}/install $ tar Jxf isl-0.20.tar.xz $ cd isl-0.20 $ ./configure --prefix=${gcc} --with-gmp-prefix=${gcc} $ make $ make install $ make clean
GNU makeの導入
$ cd ${work}/install $ tar jxf make-4.2.1.tar.bz2 $ cd make-4.2.1 $ ./configure --prefix=${gcc} $ make $ make install $ make clean
gccの導入
$ cd ${work}/install $ tar Jxf gcc-8.3.0.tar.xz $ mkdir gcc-object $ cd gcc-object $ export LD_LIBRARY_PATH=${gcc}/lib:$LD_LIBRARY_PATH $ export LIBRARY_PATH=${gcc}/lib $ export C_INCLUDE_PATH=${gcc}/include $ export CPLUS_INCLUDE_PATH=${gcc}/include $ export LC_COLLATE=C $ ../gcc-8.3.0/configure \ --enable-languages=c \ --prefix=${gcc} \ --with-gmp=${gcc} \ --with-mpfr=${gcc} \ --with-mpc=${gcc} \ --with-isl=${gcc} \ --disable-bootstrap $ ${gcc}/bin/make $ ${gcc}/bin/make install $ ${gcc}/bin/make clean
確認
これで下記のファイルからgccを使用できます。
${HOME}/work/gcc/bin/gcc
確認してみます。
$ ${HOME}/work/gcc/bin/gcc --version gcc (GCC) 8.3.0 Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
注意点があり、環境変数をちゃんと設定しないと コンパイルが上手く動作しません。 この辺りはclispコンパイル時にちゃんと見ていきます。
clispのインストール
前の手順にてすでに設定されていますが、 念のため次の環境変数が設定されているか確認してください。
$ work="${HOME}/work" $ gcc="${HOME}/work/gcc" $ clisp="${HOME}/work/clisp"
前手順ではローカル環境にgccを導入したので、環境変数の設定をします。
$ export CC=${gcc}/bin/gcc $ export LD_LIBRARY_PATH=${gcc}/lib:$LD_LIBRARY_PATH $ export LIBRARY_PATH=${gcc}/lib $ export C_INCLUDE_PATH=${gcc}/include $ export CPLUS_INCLUDE_PATH=${gcc}/include
最新版clispは2.49でした。 最低限の依存関係を考慮した場合、下記のファイルが必要になります。
- libsigsegv-2.12.tar.gz
- ffcall-1.10.tar.gz
- readline-8.0.tar.gz
- clisp-2.49.tar.bz2
ダウンロード
$ cd ${work}/install $ fetch http://ftp.jaist.ac.jp/pub/GNU/libsigsegv/libsigsegv-2.12.tar.gz $ fetch http://www.haible.de/bruno/gnu/ffcall-1.10.tar.gz ★もしsslエラーになったら下記を実行 $ fetch --no-verify-peer http://www.haible.de/bruno/gnu/ffcall-1.10.tar.gz $ fetch http://ftp.jaist.ac.jp/pub/GNU/readline/readline-8.0.tar.gz
【追記】リリース版のclispを入れる場合
$ fetch http://ftp.jaist.ac.jp/pub/GNU/clisp/release/2.49/clisp-2.49.tar.bz2
【追記】最新版のclispを入れる場合
$ fetch --no-verify-peer https://gitlab.com/gnu-clisp/clisp/-/archive/master/clisp-master.tar.bz2
libsigsegvの導入
$ cd ${work}/install $ tar zxf libsigsegv-2.12.tar.gz $ cd libsigsegv-2.12 $ ./configure --prefix=${clisp} $ make $ make install $ make clean
ffcallの導入
$ cd ${work}/install $ tar zxf ffcall-1.10.tar.gz $ cd ffcall-1.10 $ ./configure --prefix=${clisp} $ make $ make install $ make clean
readlineの導入
$ cd ${work}/install $ tar zxf readline-8.0.tar.gz $ cd readline-8.0 $ ./configure --prefix=${clisp} $ make $ make install $ make clean
clispの導入
$ cd ${work}/install
★リリース版の場合 $ tar jxf clisp-2.49.tar.bz2 $ cd clisp-2.49 ★最新版の場合 $ tar jxf clisp-master.tar.bz2 $ cd clisp-master
$ ./configure --prefix=${clisp} \ --with-libsigsegv-prefix=${clisp} \ --with-libffcall-prefix=${clisp} \ --with-readline-prefix=${clisp} \ --disable-mmap $ cd src $ make $ make install $ make clean
確認
これで下記のファイルが作成されます。
${HOME}/work/clisp/bin/clisp
実行できるか確認します。
$ ${HOME}/work/clisp/bin/clisp i i i i i i i ooooo o ooooooo ooooo ooooo I I I I I I I 8 8 8 8 8 o 8 8 I \ `+' / I 8 8 8 8 8 8 \ `-+-' / 8 8 8 ooooo 8oooo `-__|__-' 8 8 8 8 8 | 8 o 8 8 o 8 8 ------+------ ooooo 8oooooo ooo8ooo ooooo 8 Welcome to GNU CLISP 2.49 (2010-07-07) <http://clisp.cons.org/> Copyright (c) Bruno Haible, Michael Stoll 1992, 1993 Copyright (c) Bruno Haible, Marcus Daniels 1994-1997 Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998 Copyright (c) Bruno Haible, Sam Steingold 1999-2000 Copyright (c) Sam Steingold, Bruno Haible 2001-2010 Type :h and hit Enter for context help. [1]> (quit) Bye. $
環境変数が設定されていなくても実行できるはずなので、 確認をするなら一度ログアウトしてから実施してみてください。
Common Lispを作りたい
Common LispをC言語で作りたいと思い、コツコツとやって来て、 だいたい半分くらいまで作り上げました。 しかし最近になって作成する時間があまりとれなくなったため、 せっかくなので現状で公開することにしました。
とっても不完全でかなり遅いですが、なんとなく形にはなっています。 開発は中断したわけではないので、細く続けていこうと思っています。 FreeBSD, Linuxで実行できます。