2020年08月03日(月) [長年日記]
■ [math] 巨大自然数Aが自然数Bの倍数かどうかを調べる
long型では表現できない大きな数AがBの倍数かどうかを調べるにはどうするか。
倍数かどうかを知るにはAをBで割った余りが0かどうかを調べればよい。Aが大きな数でもその余りはBより大きくならないので、余りさえ計算できればうまくいく。
例えば、Aを「11111111111111111111111111111111111111111111111111」のように1が連続した整数とする。このような数は1から始めて「10倍して1を加える」という操作を繰り返すことで生成できるので、剰余演算の等価性から得られる
(10a + 1) % b = (10a % b + 1 % b) % b = (((10 % b)(a % b)) % b + 1 % b) % b
という変換を繰り返すことで余りを求めることができる(「a % b」はaをbで割った余りを表すものとする)。
1が連続する整数のことをレピュニット数と言うようだが、120桁のレピュニット数は5964848081の倍数らしい。それを次のコードで確認できる。
#include <iostream> int main() { const long b = 5964848081L; long rem = 1; for (int n = 2; n <= 120; ++n) { rem = ((10 * rem) % b + 1) % b; } std::cout << rem << std::endl; }
0
2020年08月26日(水) [長年日記]
■ [vim] Vimで改行コードをCRLFで保存できなかった
Vimで改行コードをCRLFで保存しようとしても自動的にLFに変換されてしまい困った。fileformatをdosに設定しても効かない。なんでや。
原因はEditorConfig Vim Pluginだった。.editorconfigファイルの影響範囲下では改行コードを強制されてしまう。そういうプラグインなのだから当たり前なのだが、なかなか気づかなかったのでメモ。
なお、Vimをプラグイン無効で起動するには--nopluginオプションを指定して起動すればよい。
2020年08月28日(金) [長年日記]
■ [dev][windows] Gitの改行コード自動変換の動作
Visual Studio 2017のGit機能を使ってリポジトリからファイルを取り出すと、ファイルの改行コードがCRLFに変換されてしまうことに気づいた。
Gitの core.autocrlf の設定はしていないはずなのにおかしいなと思ったが、Visual Studio 2017のGit機能は ~/.gitconfig は見ておらず Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Git\etc\gitconfig の設定に従っているようだった。このファイルには「autocrlf = true」 が設定されている。Visual Studio上にはこの設定を変更する機能は見つけられなかった。
ではどうすればいいのか。
Gitの改行コード自動変換の動作をよく理解していなかったので、調べた結果をメモしておく。結構複雑だったので誤解している所があるかもしれない。もし間違いがあったら教えてください。
改行コード自動変換に影響する設定情報
改行コード自動変換に影響するのは次の設定情報だと考えればよさそう。
- ファイルのtext属性およびeol属性
- text属性の値ははtrue, false, auto, 未指定の4通り。
- eol属性の値はlf, crlf, 未指定の3通り。
- Gitクライアント用オプションのcore.autocrlf, core.eol
- core.autocrlfの値はtrue, false, inputの3通り。未指定の場合はfalseになる。
- core.eolの値はlf, crlf, nativeの3通り。未指定の場合はnativeになる。
ファイルの属性はリポジトリにコミットする .gitattributes ファイルにより設定できる。この情報は共有されるので全ユーザ共通の設定になる。 Gitクライアント用オプションはgit configコマンドにより設定する。この結果はリポジトリにはコミットされないのでユーザ毎に別々の設定になる。
改行コード自動変換の動作
改行コードの自動変換は、リポジトリへのチェックイン時とリポジトリからのチェックアウト時の2種類の動作がある。
リポジトリへのチェックイン時に行われるのは
- ファイルのCRLFをLFへ変換した結果をリポジトリへ格納する(これを「動作A」と呼ぶことにする)
だけであり、リポジトリからのチェックアウト時に行われるのは
- LFをCRLFへ変換したファイルを作業ディレクトリへ出力する(これを「動作B」と呼ぶことにする)
だけであると理解した。特に、チェックアウト時にCRLFをLFへ変換する機能は無いという理解。
設定情報と自動変換動作の関係
まず各ファイルが改行コード自動変換の対象となる(〇)かならない(×)かが次のようにして決まる。
- text属性がtrueの場合、〇。
- text属性がfalseの場合、×。
- text属性がautoの場合、どちらになるかGitが自動的に決める。
- text属性が未指定の場合、
- eol属性がlfまたはcrlfの場合、〇。
- eol属性が未指定の場合、
- core.autocrlfがtrueまたはinputの場合、どちらになるかGitが自動的に決める。
- core.autocrlfがfalseの場合、×。
ファイルが自動変換の対象となると決まった場合、次の変換処理が行われる。
- 動作Aは必ず行われる。
- 動作Bは次のケースでだけ行われる。
- eol属性がcrlf
- eol属性が未指定でcore.autocrlfがtrue
- eol属性が未指定でcore.autocrlfがfalseでcore.eolがcrlf
- eol属性が未指定でcore.autocrlfがfalseでcore.eolがnativeでプラットフォームの改行コードがcrlf(Windowsなど)
設定例
以上を踏まえると次のようになると考えられる。
改行コードの自動変換が行われないようにしたい場合
すべてのファイルのtext属性がfalseなら改行コードの変換は行われない。なので、次のような .gitattributes をコミットしておけばよい。
* -text
.editorconfig などにより改行コードを統一できている場合はこのような設定でいい気がする。
リポジトリ内の改行コードをLFに統一したい場合
必要なファイルに対し動作Aが起こるようにすればよく、そのためには必要なファイルが改行コード自動変換の対象となるようにすればよい。例えば次のようにする。
* text=auto
バイナリファイルが自動変換の対象にならないように注意する必要がある。
チェックアウト時にWindowsではCRLF、LinuxではLFになるようにしたい場合
Windowsでだけ動作Bが起こるようにすればよい。リポジトリ側でこの動作を強制することはできなさそうだが、上述のようにしてリポジトリ内の改行コードをLFに統一するようにしておけば通常のケースではうまくいきそう。
次のように設定しているユーザに対しては想定通りにならないが、このようなユーザはあまりいないと考えられる。
- Windows上でcore.autocrlfをinputに設定している
- Linux上でcore.autocrlfをtrueに設定している
- Linux上でcore.autocrlfをfalse, core.eolをcrlfに設定している
● ひぃ [有益な情報ありがとうございます。 クライアントでcore.autocrlfがtrueとなっていても、「* -t..]
● 小川 [そのような意図で書いていましたが、間違えているのかもしれません。core.autocrlf の説明 https:/..]
● 小川 [試してみました。本文に書いていたことは間違えてはいないのかなと思いました。次のようになりました。 1. リポジ..]