メモの日々


2020年12月02日(水) [長年日記]

[c#] C#で浮動小数点の書式設定

C#での浮動小数点(double)の文字列化についてちょっとメモ。

ToString()

浮動小数点はToString()メソッドを使用すると文字列化することができる。このメソッドは、リファレンスによれば

ToString("G", CultureInfo.CurrentCulture)

と同じ挙動をする。Gは標準の数値書式指定文字列である。ただ、Gは値によっては指数表記になってしまうので困ることがある。

> 0.00001.ToString()
"1E-05"

書式指定文字列F

固定小数点表記を使いたい場合はFが使えそうに思うが、これを使うと小数部の桁数が固定になってしまう。末尾に不要なゼロが付くのが嫌なことがある。

> 0.00001.ToString("F6")
"0.000010"

カスタム数値形式文字列

固定小数点表記で末尾にゼロを含めないようにするにはカスタム数値形式文字列を使用する必要がありそう。"0.######"のような形式を指定すると所望の表記になる。

> 0.00001.ToString("0.######")
"0.00001"
> 12345.0.ToString("0.######")
"12345"

IFormatProvider

ToStringメソッドにはIFormatProviderインタフェースを実装したオブジェクトを指定することができる。これは小数点やマイナス記号にどのような文字を使用するかなどを制御するのに使う。

デフォルトのCultureInfo.CurrentCultureで問題ないことが多いと思うが、国/地域に関連づかないCultureInfo.InvariantCultureを使うべきなケースもあるだろう。

> 1.5.ToString(CultureInfo.InvariantCulture)
"1.5"
> 1.5.ToString(CultureInfo.CreateSpecificCulture("de-DE"))
"1,5"

文字列補間でのフォーマット指定

ToStringメソッドを使わず文字列補間を使って文字列化することもある。この場合も標準の数値書式指定文字列やカスタム数値形式文字列の指定はできる。IFormatProviderの指定は簡単にはできない。

> $"value={1.41421356:0.######}"
"value=1.414214"

2020年12月03日(木) [長年日記]

[c#] C#で日時の書式設定

C#での日時(DateTimeOffset)の文字列化についてちょっとメモ。DateTimeについても同じだと思うがここではDateTimeOffsetだけを対象としている。

ToString()

日時はToString()メソッドを使用すると文字列化することができる。このメソッドは、リファレンスによれば

ToString("G", CultureInfo.CurrentCulture)

と同じ挙動をする。Gは標準の日時書式指定文字列である。ただ、Gはカルチャによりフォーマットが大きく変わるので困ることがある。

> var d = DateTimeOffset.Now;
> d.ToString()
"2020/12/02 18:06:31 +09:00"
> d.ToString(CultureInfo.CreateSpecificCulture("en-us"))
"12/2/2020 6:06:31 PM +09:00"
> d.ToString(CultureInfo.InvariantCulture)
"12/02/2020 18:06:31 +09:00"
> d.ToString(DateTimeFormatInfo.InvariantInfo)
"12/02/2020 18:06:31 +09:00"

書式指定文字列sとu

標準の日付書式指定文字列はカルチャの影響を受けるものが多く使いにくい。使えそうなのはsuくらいだと思った。ただし、タイムゾーンがどう扱われるのかには注意する必要がある。

> d.ToString("s")
"2020-12-02T18:06:31"
> d.ToString("u")
"2020-12-02 09:06:31Z"

カスタム日時形式文字列

カルチャの影響を受けないように柔軟に日時の文字列化をするにはカスタム日時形式文字列を使う。次のような感じ。

> d.ToString("yyyy-MM-dd HH:mm:ss.fffK")
"2020-12-02 18:33:10.948+09:00"

2020年12月04日(金) [長年日記]

[c#] System.UriクラスのIsBaseOf()の振る舞い

System.Uri.IsBaseOf()の仕様が、リファレンスを読んでもいつもよくわからなくなるのでメモ。

  • URIの最後のスラッシュより後ろを削除したもの同士を比較している

と考えればいいみたい。比較の際にbaseにする方のURIからも後半が削除されるから混乱するんだと思う。

> var b = new Uri("http://host/path/file?query");
> b.IsBaseOf(new Uri("http://host/path/abc/def/"))
true
> b.IsBaseOf(new Uri("http://host/path/abc"))
true
> b.IsBaseOf(new Uri("http://host/path/"))
true
> b.IsBaseOf(new Uri("http://host/path"))
false

2020年12月08日(火) [長年日記]

[windows] WSL2とHyper-V仮想マシンの間で通信ができるようにする

WSL2上のシェルからHyper-Vで動かしている仮想マシンへSSHでアクセスしようとしたら接続できなかった。接続しているネットワークが、

  • WSL2は「vEthernet (WSL)」
  • Hyper-V仮想マシンは「vEthernet (Default Switch)」

であり、これらの間の通信ができないようだ。

検索するとWSLのリポジトリに次のissueが見つかった。

ivan-section-ioさんがネットワークインタフェース間のForwardingがDisabledになっているのを変更すれば通信できるようになることを発見し、jonaskuskeさんが設定を変更するワンライナーを書いてくれている。

手元の環境の設定をPowerShell上で確認してみる。

PS> Get-NetIPInterface |
>> select ifIndex,InterfaceAlias,AddressFamily,ConnectionState,Forwarding |
>> Sort-Object -Property IfIndex |
>> Format-Table

ifIndex InterfaceAlias              AddressFamily ConnectionState Forwarding
------- --------------              ------------- --------------- ----------
      1 Loopback Pseudo-Interface 1          IPv4       Connected   Disabled
      1 Loopback Pseudo-Interface 1          IPv6       Connected   Disabled
     11 イーサネット                         IPv4       Connected   Disabled
     11 イーサネット                         IPv6       Connected   Disabled
     12 vEthernet (Default Switch)           IPv4       Connected   Disabled
     12 vEthernet (Default Switch)           IPv6       Connected   Disabled
     25 vEthernet (WSL)                      IPv6       Connected   Disabled
     25 vEthernet (WSL)                      IPv4       Connected   Disabled

次のワンライナー

Get-NetIPInterface |
where {$_.InterfaceAlias -eq 'vEthernet (WSL)' -or $_.InterfaceAlias -eq 'vEthernet (Default Switch)'} |
Set-NetIPInterface -Forwarding Enabled

をPowerShell上で実行してみる(管理者権限が必要)と設定が次のように変わり、WSL2とHyper-V仮想マシンの間で通信ができるようになった。

PS> Get-NetIPInterface |
>> select ifIndex,InterfaceAlias,AddressFamily,ConnectionState,Forwarding |
>> Sort-Object -Property IfIndex |
>> Format-Table

ifIndex InterfaceAlias              AddressFamily ConnectionState Forwarding
------- --------------              ------------- --------------- ----------
      1 Loopback Pseudo-Interface 1          IPv4       Connected   Disabled
      1 Loopback Pseudo-Interface 1          IPv6       Connected   Disabled
     11 イーサネット                         IPv4       Connected   Disabled
     11 イーサネット                         IPv6       Connected   Disabled
     12 vEthernet (Default Switch)           IPv4       Connected    Enabled
     12 vEthernet (Default Switch)           IPv6       Connected    Enabled
     25 vEthernet (WSL)                      IPv6       Connected    Enabled
     25 vEthernet (WSL)                      IPv4       Connected    Enabled

2020年12月13日(日) [長年日記]

[hard] PCのメモリを増設した

2年前に買ったPCはメモリ16GBで使っていたが、現代ではこれでは不十分である。メモリスロットはまだ2つ空いていたので16GBの2枚セットであるCrucial製のCT2K16G4DFD8266を買った。ビックカメラで約13500円。

接続するのには一苦労した。ケースを開けてみるとメモリスロットの上にDVDドライブが被さっていてそのままではメモリを刺せない。DVDドライブをどかそうとするとCPUファンにぶつかるのでまずCPUファンを苦労して外してみたが、DVDドライブはまだ何かにつっかえてしまい外せない。DVDドライブというのは前面が大きいのでケース内側に引っ張る形では外せないのだった。ケース外側へ押し出さないといけないのだけれど、そのためにはPCのフロントパネルを外さねばならない。が、フロントパネルの外し方が分からなかった。長時間格闘してやっとフロントパネルから足が伸びてケースに噛んでいるのを発見し、外すことができた。

フロントパネルの足

DVDドライブをずらしてメモリを刺しケースを元に戻して起動した結果、無事48GBになったようで一安心。

メモリの状態


2020年12月14日(月) [長年日記]

[windows] Windows 10からUEFI画面を開く

PC起動時に特殊なキー操作をするのではなく、Windows 10の機能を使ってUEFIの画面を開く方法をメモ。

  1. 「設定」を開く。
  2. 「更新とセキュリティ」を選ぶ。
  3. 「回復」を選ぶ。
  4. 「今すぐ再起動」ボタンをクリックする。これにより再起動が行われる。
  5. 再起動後にメニューが表示されるので、そこで「トラブルシューティング」を選ぶ。
  6. 「詳細オプション」を選ぶ。
  7. 「UEFIファームウェアの設定」を選ぶ。これにより再起動が行われ、UEFI画面が開く。

2020年12月20日(日) [長年日記]

[hard] Pixel 4aを買った

Pixel 3aを買ってから1年半、特に問題はないが事情があってPixel 4aに変えることにした。税込42900円でPixel 3aより安いのはいいね。

画像の説明

大きさが同じくらいで使い勝手も変わった気はしない。インカメラがパンチホール型になりこれが邪魔に感じることはある。

前回と同じくSpigenのケース(1100円)とガラスフィルム(1600円)を買った。透明ケースはケースの汚れが目立つのが気になったので、Moto G5のときと同じラギッドアーマーに戻した。


2020年12月21日(月) [長年日記]

[hard] NVIDIA GT710搭載ビデオカードを買った

3台目のディスプレイを手に入れたので、トリプルモニタを実現するためにビデオカードを買うことにした。なるべく安く出力端子が3つあるものを選び、NVIDIA GT710を搭載したASUS製のGT710-SL-2GD5-BRKを購入した。ヨドバシカメラで約5500円。ロープロファイル用のブラケットが付属しているのかがはっきりせず心配だったが、ちゃんと付属していた。

ビデオカードを刺したときにオンボードのビデオ出力が使えるのかもよくわからず気になっていたが、手元のPCではUEFIで設定を変更すればオンボードのビデオ出力とビデオカードの出力は共存できた。

GT710というのはだいぶ古い型だが、今のところ使用感に問題はない。モニタが3面あると首が疲れるというのはあって、配置などに試行錯誤が必要かもしれない。