> sprintf('%d', c(1, 1.5))
[1] "1" "1"
,這並不:
> sprintf('%d', c(1.5, 1))
Error in sprintf("%d", c(1.5, 1)) :
invalid format '%d'; use format %f, %e, %g or %a for numeric objects
爲什麼?
> sprintf('%d', c(1, 1.5))
[1] "1" "1"
,這並不:
> sprintf('%d', c(1.5, 1))
Error in sprintf("%d", c(1.5, 1)) :
invalid format '%d'; use format %f, %e, %g or %a for numeric objects
爲什麼?
這實際上是一個非常有趣的問題。首先,%d
代表整數。如果可能的話,矢量參數將被回收,但如果它是c(1.5, 1)
,則sprintf()
試圖用1.5(不是整數)代替%d
時將失敗。
我認爲這可能與這樣的事實中的R整數和雙是數字模式,例如:
storage.mode(c(1.5, 1))
# [1] "double"
storage.mode(c(1, 1.5))
# [1] "double"
mode(c(1,1.5))
# [1] "numeric"
mode(c(1.5,1))
# [1] "numeric"
因此,兩個向量應該被存儲爲兩倍。關於向量R language definition和? numeric
文檔中的更多信息:
潛在的困惑是,R已經使用模式「數字」是指「雙或整數」」
我可能已經找到了在the underlying C code哪一行解釋正在發生的事情:
if(TYPEOF(_this) == REALSXP) {
double r = REAL(_this)[0];
if((double)((int) r) == r)
_this = coerceVector(_this, INTSXP);
此代碼執行以下操作:如果載體類型是REALSXP
(這意味着數值)再轉換矢量的第一個成員到double r
。然後將r
轉換爲整數,然後加倍,如果字節仍然相同,則將整個向量轉換爲INTSXP
。重要的是,這段代碼只檢查向量的第一個元素;如果該元素可以被強制爲整數,則整個向量被強制,否則代碼會給出錯誤。
爲了檢驗這一假設,人們可以用自定義sprintf()
,其中double r = REAL(_this)[0];
改爲double r = REAL(_this)[1];
編譯R和現在還是不測試是否c(1.5, 1)
作品。
對不起,我不明白這是如何解釋'c(1.5,1)'和'c(1,1.5)' – pomber 2014-11-24 21:59:59
之間的區別。可以從這裏找到Excact答案:[rsource/sprintf。 C](https://github.com/SurajGupta/r-source/blob/46102b91b35a7befa0cf6cc6abd0da09b86f1621/src/main/sprintf.c)。如果有更多C經驗的人可以找到它? – 2014-11-24 22:22:13
很好的回答,奇怪的實現。出於性能原因,必須這樣做。 – pomber 2014-11-26 01:41:32
我知道我可以使用類似'sprintf('%。f',c(1.5,1))''但我想了解'%d'' – pomber 2014-11-24 14:53:47
我在思考[sprintf。 c](https://svn.r-project.org/R/trunk/src/main/sprintf.c),到目前爲止很難說出爲什麼這種行爲是不對稱的。在'ns = 0'處有一個關於強制嘗試的評論,儘管它周圍的代碼是神祕的。 – tonytonov 2014-11-24 15:28:38
@RichardScriven幫助文件中的內容是什麼? – pomber 2014-11-24 22:00:41