コグノスケ


2020年 4月 11日

三角関数の float 版

目次: C 言語と libc - まとめリンク

標準 C ライブラリには double を返す三角関数(sin(), cos(), tan())と float を返す三角関数(sinf(), cosf(), tanf())が定義されています。

標準 C ライブラリの一つの実装である musl のコードを見ると、sinf, cosf, tanf の計算に double 演算を内部で使っています。これは基になった FreeBSD の libm と同じ実装です。PC は float でも double でも関係なく速いんですが、double をハードで扱えない貧相なプロセッサには優しくない作りです。

もう一つの実装である newlib のコードを見ると、double 版の sin, cos こそ FreeBSD の実装と同じですが、float 版の sinf, cosf は float を使ったコードが独自に追加されていて、貧相なプロセッサにも優しい作りになっています。組み込みにやたら使われる実績は伊達じゃないですね。

じゃあ musl に newlib の float 版の sinf, cosf を移植すれば、double が苦手なプロセッサでも速くなるのでは?と思いました。

テストを先に書こう

コードを触る前に、それぞれの実装の素性を調べておこうと思います。テスト方法は、

  • 期待値: glibc の sin, cos, tan(double 版)を float に変換した結果
  • 判定方法: sinf, cosf は 1 の誤差を許す、tanf は 3 の誤差を許す
  • 比較範囲: float を 32bit として、全値域(=約 43億パターン)

どうして tanf だけ判定が甘いかというと、正しい値がわからなかったからです。なぜか glibc の実装も誤差 1 に収まっていません。どういうことなの……。

テストのコードは GitHub に置き(リンク)ました。特に難しい点はありませんが、musl と newlib から三角関数を拝借するところは、やや面倒かもしれません。

現在のプロセッサは超速いし、問題の性質上マルチスレッド化も簡単ですから、32並列くらいで頑張れば 32bit 全域を調査しても 3分もかかりません。楽勝ですね〜。

最初にテストして良かった

テスト結果は、当然、全て一致かと思いきや、そんなことはなかった。最初にテストしておいて良かったですね。

良い方から言うと musl は内部で double で演算しているからか、結果もパーフェクトでした。

一方の newlib は cosf だけ変な値を返します。32bit 全域を試してわずか 6パターンです。

誤差が許容範囲を超えるパターン
cos,cosf_newlib: NG : x:3fc90fe0 f:1.570797 d:1, exp:b52bbbd3 -0.000001, res:b52bbbd0 -0.000001
cos,cosf_newlib: NG : x:3fc90fe1 f:1.570797 d:1, exp:b54bbbd3 -0.000001, res:b54bbbd0 -0.000001
cos,cosf_newlib: NG : x:3fc90fe2 f:1.570797 d:1, exp:b56bbbd3 -0.000001, res:b56bbbd0 -0.000001

cos,cosf_newlib: NG : x:bfc90fe0 f:-1.570797 d:1, exp:b52bbbd3 -0.000001, res:b52bbbd0 -0.000001
cos,cosf_newlib: NG : x:bfc90fe1 f:-1.570797 d:1, exp:b54bbbd3 -0.000001, res:b54bbbd0 -0.000001
cos,cosf_newlib: NG : x:bfc90fe2 f:-1.570797 d:1, exp:b56bbbd3 -0.000001, res:b56bbbd0 -0.000001

正負を考慮(浮動小数点は最上位ビットが符号を示すビット)すると、実質 3パターンで変な値が返ることがわかります。

  • 正: 0x3fc90fe0, 0x3fc90fe1, 0x3fc90fe2
  • 負: 0xbfc90fe0, 0xbfc90fe1, 0xbfc90fe2

誤差は 3 でした。ほぼ合ってます、おしい。誤差が出ることも不思議ですが、sinf は合っていて cosf だけ値がズレるのも不思議です。

編集者: すずき(更新: 2022年 4月 22日 03:00)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2020年 4月 17日

Facebook のリッチエディタ

Facebook のエディタはめちゃくちゃ重くて、添付の画像のように表示がおかしくなったり、突然カーソル位置が先頭に吹っ飛んだり、変な動きばかりします。


顔文字が真っ二つ

文章が長い場合は、他のテキストエディタで書いて張り付けた方が良いですね。

これは Facebook に長い文章を書くんじゃねえよ、という Facebook の意思なのかな……。

メモ: 技術系の話は Facebook から転記しておくことにした。

編集者: すずき(更新: 2020年 4月 19日 01:20)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2020年 4月 18日

Transport Fever 2 楽しい

最近 Steam で購入した Transport Fever 2(Good Shepherd Entertainment/Urban Games)というゲームにハマっています。在宅勤務を良いことに、仕事終わった瞬間から深夜までやりまくっていたら、プレイ時間が 3週間で 130時間に。やりすぎですね……。

Steam では一定の条件を満たすと「実績」が解除されるシステムがあります。他のゲームでは、実績はほとんど気にしませんが、このゲームでは気になり 59/61 まで取りました。


Steam のタイトルバナー、実績表示

もう 1つ取れますが、最後の 1個「大都市」は難しそうです。

ゲームの紹介

Transport Fever 2 を軽く紹介すると「輸送」シミュレーションゲームです。


ゲーム画面

シムシティから街を作る機能を除いて、交通網を作る機能のみを超強化したゲームとでもいいますか。A 列車で行こう(アートディンク)をご存知でしたら、あのイメージが一番近いです。違いとしては、

  • 自力で建物を建てられない
  • 道路、鉄道以外に、船舶、航空機も運用できる
  • 荷物の種類が多く加工が必要、基本は、原料→中間加工→製品加工→都市の流れ

プレイヤーが出来るのは、人と荷物の「輸送」のみです。輸送すると運賃が貰えるので、輸送網の維持費を上回る運賃を得て、輸送網を拡大するのが基本です。

簡単なので気になったらどうぞ

ゲームの難易度は簡単です。人でも荷物でも同じですが、運びたいものを、運びたいところに真っ直ぐ運ぶ(運賃は道のりではなく、直線距離に応じる)だけで基本黒字です。めちゃくちゃしない限り、財政破綻はないはず。

むしろ序盤を過ぎると、資金が有り余って使い切れなくなるほどです。箱庭系ゲームでは、難易度が低いのは良いことで、資金を気にせず、レイアウトに凝ってみたり、道路縛りとか、鉄道縛りとか、比較的自由に遊べます。

その他の機能としては、動いている列車や車などのコックピットビューができます。自分が引いた鉄道や道路を走る様子をぼーっと見るのも楽しいです。


コックピットビュー(列車が駅に入るところ)

Steam では素敵な Mod がたくさん公開されているので、お気に入りのマップや列車を探してみるのも楽しいかもしれません。

編集者: すずき(更新: 2020年 4月 19日 01:30)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2020年 4月 22日

Transport Fever 2 ひと段落

Transport Fever 2 の実績コンプリートしました。やはり最後になったのは「大都会」で、何度かやり直す羽目になって、とても時間が掛かりました。


Transport Fever 2 の実績コンプリート

都市のターゲット人口が 271 +470% で 1500人達成できました。+460% = 1518 だとダメでした。基本的には都市の人口はこのターゲット人口に近づこうとするんですが、時に越えたり時に越えなかったりします。良くわからない数字です。


1500人超え達成

フリーマップはランダム生成なので、必勝法は無いです。ただまあ、何回かやり直す中で最初にこだわっておいた方が良いなと思った条件は、

1800年スタート
1800年〜1900年後半くらいまでは、都市のベース人口が勝手に増える(1年に 1増えるかどうかくらい)からです。2000年スタートだと全く増えませんし、クリアできるほどのベース人口になりません。
1960年〜1970年までが勝負
2000年に近づくほどマイカー渋滞が増え、都市内の物資配達が滞って人口が安定しなくなります。渋滞をうまく捌ける人は気にしなくて良いです。
マップは中サイズ以上
人口に一番影響するのは公共交通機関の利用者数で、小サイズだと街の数が少なくて、公共交通機関の利用者数が増えないからです。私の場合は、中サイズを使いました。
たぶん広い方が良いと思いますけど、PC スペック次第ですね。私のノート PC はスペックが低くて、大サイズだと時間の経過が遅すぎてダルかったです。
マップの街と産業は高密度以上
低密度だと街が少なく、公共交通機関の利用者数が増えず、人口が伸びないからです。
ターゲット人口の初期値が最大の街を育てる
ターゲット人口は時間経過で増えるとはいえ、限度があるからです。どこまでもは増えません。初期値は高い方が良いです(1800年だと最大 200 かな?)。
人口の初期値が高い街が真ん中付近に 3つ出るまでガチャる
公共交通機関の利用者を増やすためです。大都市 3つはあくまで目安ですが、公共交通機関は街と街の行き来に使うため、大きい街が 1つだけだと利用者が伸びませんでした(これで 1回やり直した)。
私は初期人口 190 くらいの街がほどほどの距離に 3つ出るまでリスタートしまくりました。
編集者: すずき(更新: 2020年 4月 24日 00:11)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2020年 4月 23日

Transport Fever 2 大都市達成のヒント

「大都市」達成を目指すとき、ゲーム進行で気を付けていたところの紹介です。前回も言った通り必勝法はないですが、ヒントになれば幸いです。

全都市を鉄道で繋ぐ
輸送量の関係で、道路+バス、空路は、キャパオーバーでうまくいかず、海路のみでは全都市にアプローチできないからです。私は使いませんでしたが、海路+鉄道ならば有効かもしれません。
鉄道でさえ大都市間の輸送はキャパオーバー気味で、駅に300〜400人溜まります。あと、私は都市間の道路は整備せず、初期状態で放置でしたが、マイカーの利用者数は時代が進むにつれ勝手に伸びました。
都市内はバスを走らせる
人口に影響が大きい、公共交通機関(=駅)の利用者を増やすためです。
バス停は住宅地、商業地、産業地をもれなくカバーするよう配置します。バス停に大量の人が溜まると人々は家に帰ってしまう(駅利用者が減る)ので、混んでいたら適宜バスを増発し、駅と各地域の人を行き来を増やします。
街の拡大に対応する
街は勝手に広くなるので、トラックの荷物輸送や、バス停のカバー範囲を広げてください。
物資は 800個分確保する
物資を産業、商業それぞれ 800個分(最終工場 2つ分)確保します。少なくとも 500 以上は必要です。
簡単な「燃料」「資材」「道具」辺りを要求する街だと運用が楽ですが、多少引きが悪くても 1935年に出てくる OPEL Blitz トラックを 20台くらい使えば、どんなものでも力業で運べます。マップの端から端に運ぶとかでもない限り、気にしなくて良いです。
物資供給用の道路を新設する
物資が滞ると人口が減るためです。 トラック専用の道路を引き、街と街を繋ぐ道路を高架かトンネルで越えるようにすると、渋滞も起きないし、物資供給も安定します。
編集者: すずき(更新: 2020年 4月 24日 00:11)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2020年 4月 28日

Transport Fever 2 初めの一歩 - その 1

Transport Fever 2 の基本となる片道の輸送について紹介します。画像をできるだけ使うようにしました。ゲームの雰囲気を感じてもらえたら嬉しいです。

参考までにフリープレイの条件は、ヨーロッパ、温暖、1950年、難易度イージー、街の密度は中、産業の密度も中です。

輸送するターゲットを見つける

最初に時間を止めます。なぜかというとこのゲームの初期資金は借金だからで、ぼうっとしているだけで、利子をどんどん取られて資金がなくなります。世知辛いね……。

輸送する対象を探します。今回は「森(右下)」から「製材所(左上)」に木材を運びたいと思います。画面に両施設の位置関係を示します。


森(右下)と製材所(左上)

どの施設が何のアイテムを消費 or 生産するのか?については、矢印のアイコンを見るとわかります。薄いグレーの背景が消費、濃いグレーの背景が生産です。消費側はない場合もあります。例えば森であれば「木材」を生産し、製材所であれば「木材」から「板」を生産することが分かります。


森のアイコン、何も消費せず、木材を生産


製材所のアイコン、木材を消費(左側)して、板を生産(右側)

他の消費と生産の組み合わせについては、今回の本題ではないので割愛します。

道路を作ろう

木材はトラックで運びたいので、両施設を道路で結んで、トラックが行き来できるようにしなければなりません。既存の道路も使えますが、今回は道路を新設してみます。道路アイコンを選び、両施設の間にズドンと真っ直ぐ引きましょう。


道路建設の手順


道路を真っ直ぐ引いた

トラックが貨物をピックアップする場所「トラック駅」を建設します。駅へ引き込む道路がそっぽを向いていたら Shift + ドラッグで、回転させることができます。画像のように先ほど引いた道路とくっつくように近づけて建設してください。


トラック駅建設の手順

実はこれではダメで、施設から木材をトラック駅に持ってきてもらうためには、道路を施設に「接続」する必要があります。もう一度、道路建設アイコンを選び、道路を施設の近くまで引っぱると、施設にヒゲのような細い道路が表示されます。


道路を施設に接続

接続できたかどうか確認する簡単な方法は、付近のトラック駅をクリックすることです。もし道路の接続に成功していたら、トラック駅付近の施設が白く光り、失敗していたら光りません。道路が接続できていなければ、道路を引き直しましょう。


道路を施設に接続(成功)


道路を施設に接続(失敗)

道路が接続出来ていても、トラック駅が遠すぎても施設が光りません(=木材を持ってきてくれません)。その場合はトラック駅を配置しなおしましょう。

製材所の方も同様にトラック駅を建設して、道路を接続しましょう。うまくいっていれば、両施設のトラック駅をクリックすると、両施設とも白く光るはずです。


トラック駅建設&道路接続

トラックを購入するには「道路発着所」を建設し、トラックを走らせたい道路と繋げてある必要があります。つなげ方はトラック駅と同じです。


道路発着所建設の手順

続きは次回。

編集者: すずき(更新: 2020年 4月 30日 01:07)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2020年 4月 29日

Transport Fever 2 初めの一歩 - その 2

昨日(2020年 4月 28日の日記参照)に引き続き Transport Fever 2 の基本となる片道の輸送について紹介します。画像をできるだけ使うようにしました。ゲームの雰囲気を感じてもらえたら嬉しいです。

輸送する路線を作る

道路で繋いだだけでは貨物は輸送されません。路線を作成して、どこからどこへ輸送するか決めます。


路線の作成

「森(右下)」から「製材所(左上)」に木材を運びたいので、2つのトラック駅を路線に追加します。トラックでも何でもそうですが、輸送車両は「終点」までたどり着いたら、次は「始点」に戻ります。例えば A, B, C, D という経路を作ったら、A B C D A B C D ... という順に巡回します。


路線にトラック駅 2つを追加

今回は 2駅しかないピストン輸送ですので、始点と終点はどちらが先でも気にしなくて良いです。

トラックを配備する

最後にトラックを購入、路線に配備します。発着所をクリックするか、車両マネージャから発着所を選択します。大抵の場合は前者の方が楽です。


道路発着所

トラックを購入します。車両マネージャーから購入画面を出して、Opel Blitz 防水布トラックを購入します。目的の貨物(木材)が搭載できれば何でも良いです(Benz 製防水布トラック、Saurer C Type 防水布トラックなどでも大丈夫)。


トラックを購入

運送車両の種類によって、積めるものに制限がありますので、車両購入の際は「貨物の種類」をチェックしましょう。例えば Opel Blitz タンクトラックは石油や燃料のような液体しか積めず、木材を運ぶことはできません。

輸送手段即時性輸送力貨物の種類制限備考
トラック×〜〇×〜〇自由 時代が進むと性能が桁違いに上がる、街のマイカーに邪魔される
船舶 × △〜〇割と自由時代が進むと性能が上がる、石油系とその他に分かれていることが多い
鉄道 △〜〇△〜〇厳しい 時代が進むと性能が上がる
航空機 × 自由 使用可能になる年代が遅い

各輸送手段の違いは上記の通りです。トラックは 1850年代は遅いし輸送力も低いですが、時代が進むと割と万能になります(スピードが速く「すべての貨物」が積める)。ただし道路の他の車(マイカー、バス)により、邪魔される点には注意しないといけません。

個人的なオススメは、鉄道とか船舶とか癖の強いものに挑む前に、1950年(良いトラックが使える)開始で、トラックを使った輸送の仕方を色々試すことです。ストレスも少ないし、慣れるのも早いと思います。キャンペーンの最初の方をやってみるのも一興ですね。

輸送開始

購入したトラックを、先ほど作成した路線に配備すると、木材の輸送が開始されます。森の近くのトラック駅を眺めると、木材がどんどん積まれていく様子が見えるはずです。


トラック配備の手順

無事、車両の配備まで成功したら、こんな風になるはずです。


トラック配備の手順

上記はトラック 1台だと寂しいので、トラックを 10台ほど同じ路線に配備した状態です。せっせと働くトラックを眺めるのは楽しいですよね。

うまくいかない?

森のトラック駅に何もなく、トラックの積み荷がずっと空っぽの場合は、下記をチェックしてみてください。製材所側のトラック駅には何もないのが正しいです。

  • 施設と道路の接続ができていない
  • トラック駅が施設から遠すぎる

このゲームの特徴として「生産施設は、消費施設へ貨物の運送経路が確立するまで稼働しない」という点があります。さすが輸送ゲームらしい仕様ですね。

  • 施設間の道路を引く、もしこれがダメだと「路線が作成できない」「車がやたら遠回りする」
  • 施設と道路を繋げる、もしこれがダメだと「貨物がトラック駅に来ない」
  • トラック駅を道路に繋げる、もしこれがダメだと「路線が作成できない」
  • 適切な路線を作成する、もしこれがダメだと「トラックが配備できない(配備先が出てこない)」
  • 適切な路線にトラックを配備する、もしこれがダメだと「道路にトラックが出てこない」「何も運送されない」

今回やったことは、上記の 5つです。どれが欠けても生産施設は稼働しません。

編集者: すずき(更新: 2020年 4月 30日 01:07)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2020年 4月 30日

Transport Fever 2 初めの一歩 - その 3

昨日(2020年 4月 29日の日記参照)に引き続き Transport Fever 2 の基本である、生産量について紹介します。画像をできるだけ使うようにしました。ゲームの雰囲気を感じてもらえたら嬉しいです。

生産量の概念は、私が最初に躓いたというか、一番訳の分からなかったところです。うまく説明できると良いんですけど。

生産施設と消費施設

Transport Fever 2 のフリープレイで出現する生産者、消費者は 5段階に分類できます。カテゴリの正式名がないため、私が適当に名付けています。間違っていたらごめんなさい。


生産施設と消費施設の相関図

図の見方を一応説明しておくと、食料加工プラントの場合、農場から「穀物」を 2つ運ぶと、1つの「食料」が生産される、という風に見ます。生産がダントツで面倒くさいのは「商品」ですね。

経路がシンプルな「穀物」→「食料」にも罠があります。施設の生産キャパシティは基本的に最大 400 ですが、なぜか農場だけ 200 しかありません。レベル最大の食料加工プラントで食料を 400 生産するには、穀物が 800 必要になりますから、農場 4つから穀物を運ばなければなりません。

ちなみに…、「製油所」が 2つ出てくるのは誤植ではありません。「製品」工場が「商品」を作るのも、「工場」と「プラント」が混ざっているのも誤植ではありません。Transport Fever 2 の日本語はポンコツなので、突っ込み出すとキリがないです。

中間、最終生産のレベル

中間と最終生産を担う工場にはレベルがあり、生産上限がレベルで決まります。レベルは各施設をクリックすると出てくる概要に表示されています。


製材所はレベル 1、森(一次生産)はレベルがない

ただまあ、工場のレベルを上げるぞ!!と思って上げることはあまりなくて「たくさん原料を運び込んで」「生産したものを全部消費」しているうちに、勝手に上がっていることが多いです。

生産と消費の条件

生産と消費が Transport Fever 2 で一番わかりにくい概念だと思います。生産施設は常に「必要とされた分」しか作りません。私は最初、この概念が全く分かりませんでした。

先日作った経路で説明しましょう。森から製材所への運送経路を 1つだけ作りました。生産(森)と消費(製材所)の関係はこうなります。


製材所と森の消費・生産の関係

基本的に消費側(製材所)の要求数 = 生産側(森)の生産数(2番目の「輸送」の数字)になります。正確に言えば、下記のロジックで決まります。

  • 板を作るのに、木材は 2つ必要 -- (A)
  • 消費側(製材所レベル 1)の生産上限は、板 200 個/年 -- (B)
  • 製材所は経路が繋がっている生産側(森)「全て」に「合計」(A) x (B) = 2 x 200 = 400 個/年の木材を要求
  • 森は要求された数(400 個/年)を満たす木材を生産

消費側は繋がっている生産側「全て」に要求するというのが、わかりにくいんですけど、結構大事です。

もし製材所レベル 1 に、森 A、森 Bを 2つ繋いだとすると、森 2つに対し「合計 400 の木材が要求」され、森の生産力が余ります。すると、森 A は 100、森 B は 300 のように分散して生産し始めます。

このダイアログの情報は難しい部類ですが、日本語が完全に本当にポンコツです、全く説明になっていません。特に「輸送」を違う意味で 2つ並べた人は何を考えているんでしょう?どう見てもおかしいでしょう??

路線の輸送力

これはわかりにくいというより、紛らわしい数字が表示されることが多いので、説明しておきます。トラック駅をクリックして、路線をクリックすると、路線の情報が表示されます。

ほとんど見ればわかる系の情報なのですが「割合」は注意が必要です。数字は路線の年間輸送力を意味しています。これもポンコツ翻訳のひとつですね……。

この路線は 400 の木材を森から製材所に運ぶために作ったことを思い出せば、400 前後の輸送力にしておくと無駄がないことが分かると思います。


路線の情報

路線のコースを変えたり、トラックの種類や数を変更すると、すぐに年間輸送力の数字が変化します。例えばこの路線だと、トラックを 1台から 12台にすると、400 くらいの値が表示されました。

しかしながら、この数字は実際の輸送力とかけ離れている場合があります。ある程度待つと、実情に近い値に補正されます。この補正がかなり劇的で、路線の変更直後は 400 だったのに、しばらく経つと 480 など大幅に増えたり、逆に激減したりすることが多々あり、気づかないうちに輸送力が不足したり、無駄になったりします。

ですから路線の輸送力を変更したときは、ちょっと時間をおいてから再チェックすることをお勧めします。

私の個人的な感覚では、トラックは最初の数字が低めに出る傾向(=後で増える)、鉄道と船舶は最初の数字が高めに出る(=後で減る)傾向があるように感じます。

編集者: すずき(更新: 2020年 4月 30日 02:51)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報