Rでは、次のような"L"
接尾辞を使用して整数を指定することを保証したい場合に便利であることがわかっています。
1L
# [1] 1
明示的にRに整数を指定しない場合は、numeric
データ型を使用することを想定しています...
str( 1 * 1 )
# num 1
str( 1L * 1L )
# int 1
なぜ「L」が好ましい接尾辞なのか、なぜ「I」はなぜですか?歴史的な理由はありますか?
さらに、なぜRは私にできるのですか(警告付き):
str(1.0L)
# int 1
# Warning message:
# integer literal 1.0L contains unnecessary decimal point
だがしかし..
str(1.1L)
# num 1.1
#Warning message:
#integer literal 1.1L contains decimal; using numeric value
どちらもエラーを返すと思います。
私はそれを書き留めたのを見たことがないが、私は2つの理由で簡単に理論化する:
Rは接尾辞"i"
を使用して指定できる複素数を処理し、これは"I"
とあまりにも似ているためです。
Rの整数は32ビットの長整数であるため、「L」はこのデータ型を参照するための合理的な略記のように見えます。
長整数が取り得る値は、Wordのサイズによって異なります。 Rは、語長が64ビットの整数をネイティブにサポートしていません。 Rの整数のワード長は32ビットであり、符号付きであるため、−2,147,483,648
から2,147,483,647
の範囲になります。大きな値はdouble
として保存されます。
このWikiページ には、一般的なデータ型、それらの従来の名前と範囲に関する詳細情報があります。
また、?integer
からも
Rの現在の実装では、整数ベクトルに32ビット整数が使用されているため、表現可能な整数の範囲は約+/- 2 * 10 ^ 9に制限されています。
1.0L
と1.1L
が異なるデータ型を返すのは、1.1
の整数を返すと情報が失われるためです。また、1.0
の場合はそうではありません(ただし、浮動小数点数値がなくなったことを知りたい場合があります)。字句解析ツール(/src/main/gram.c:4463-4485
)には、このコード(関数NumericValue()
の一部)が深く埋め込まれています。このコードは、ASCII "L"
がサフィックスとなっているint
入力からdouble
データ型を実際に作成します。
/* Make certain that things are okay. */
if(c == 'L') {
double a = R_atof(yytext);
int b = (int) a;
/* We are asked to create an integer via the L, so we check that the
double and int values are the same. If not, this is a problem and we
will not lose information and so use the numeric value.
*/
if(a != (double) b) {
if(GenerateCode) {
if(seendot == 1 && seenexp == 0)
warning(_("integer literal %s contains decimal; using numeric value"), yytext);
else {
/* hide the L for the warning message */
*(yyp-2) = '\0';
warning(_("non-integer value %s qualified with L; using numeric value"), yytext);
*(yyp-2) = (char)c;
}
}
asNumeric = 1;
seenexp = 1;
}
}