2012-07-28 36 views
35

當輸入1e9999999999999999999999999999999到R中時,R掛起並且不會響應 - 要求終止它。爲什麼數字1e9999 ...(31 9s)在R中導致問題?

它似乎發生在3個不同的計算機,操作系統(Windows 7和Ubuntu)。它發生在RStudio,RGui和RScript中。

下面是一些代碼更容易地生成數量:

boom <- paste(c("1e", rep(9, 31)), collapse="") 
eval(parse(text=boom)) 

現在顯然這不是一個實際的問題。我不需要使用這個數量的數字。這只是一個好奇心的問題。好奇地,如果你嘗試1e99999999999999999999999999999981e10000000000000000000000000000000(加上或減去一個電源),你分別得到Inf0。這個數字顯然是某種邊界,但是在這裏的什麼和爲什麼?

我認爲,它可能是:

  • 浮點問題,但我認爲他們最大程度的發揮在1.7977e308,有問題的數量不久。
  • 32位整數的問題,但2^32是4294967296,遠遠小於所討論的數量。
  • 真的很奇怪。這是我的主導理論。

編輯:截至2015-09-15最晚,這更長的時間導致R掛起。他們必須修補它。

+0

愛主流理論!順便說一句 - 這也發生在我身上。也許是記憶的東西? – 2012-07-28 11:53:40

+0

更好:'boom < - paste(c(「10 ^」,rep(9,31)),collapse =「」)'作品:P – nico 2012-07-28 11:58:27

+0

這很有趣。看起來'1e9 ...'效果不好,但'1^9 ...'效果不錯。 – 2012-07-28 12:12:41

回答

24

這看起來像是解析器中的極端情況。格式在R Language DefinitionSection 10.3.1: Literal Constants中描述,並指向?NumericConstants以獲得「關於當前接受的格式的最新信息」。

問題似乎是解析器如何處理指數。數字常數由NumericValue(線的main/gram.c 4361),它調用mkFloat(線的main/gram.c 4124),它調用R_atof(線的main/util.c 1584),它調用R_strtod4(線的main/util.c 1461)來處理。 (均爲修訂版60052.)

main/utils.c的行1464顯示expn聲明爲int並且如果指數太大,它將在行1551溢出。有符號的整數溢出會導致未定義的行爲。

例如,下面的代碼產生值指數< 308左右和Inf爲指數> 308

const <- paste0("1e",2^(1:31)-2) 
for(n in const) print(eval(parse(text=n))) 

可以看到爲指數的未定義的行爲> 2^31(R掛起的指數= 2^31):

const <- paste0("1e",2^(31:61)+1) 
for(n in const) print(eval(parse(text=n))) 

我懷疑這將得到R-核心任何關注,因爲R可以只存儲介於約2E-308到2e + 308(參見?double),並且該號碼是數值除此之外的方式

+0

我擔心這些事情對此,「懷疑這將得到R核心的任何關注」 - 正在不斷增長。我在過去幾周發了兩封郵件,沒有回覆。 : -/ – 2012-07-30 16:05:45

+1

在這個集合和「我會問R核心這個問題(或者提交這個補丁),但我確信我會得到徹底打擊」的設置,我很難加強參與。 – 2012-07-30 20:13:32

+4

我希望*任何*溢出,不管上下文如何,都會被認爲是可修補的。 – 2012-07-30 20:14:25

4

R有時可能會使用bignums。也許1e9999999999999999999999999999999是一些門檻,或者解析例程有一個有限的緩衝區來讀取指數。您的觀察結果與指數的32位字符(以空字符結尾)緩衝​​區一致。

我寧願在R的論壇或郵件列表上提出這個問題,這些傳聞是友好的。

另外,由於R是免費軟件,您可以調查其源代碼。

7

這很有趣,但我認爲R有與解析數字,有非常大的指數的系統性問題:

> 1e10000000000000000000000000000000 
[1] 0 
> 1e1000000000000000000000000000000 
[1] Inf 
> 1e100000000000000000000 
[1] Inf 
> 1e10000000000000000000 
[1] 0 
> 1e1000 
[1] Inf 
> 1e100 
[1] 1e+100 

我們去那裏,最後的東西合理。根據這一結果和下面的Joshua Ulrich的評論,R似乎支持代表數字高達約2e308,並分析指數高達+ 2 * 10^9的數字,但它不能代表它們。之後,顯然由於溢出而存在未定義的行爲。

+2

它可以用指數+/- 2 * 10^9來_parse_數字常量,但不能表示它們,因爲雙精度值被限制在大約2e-308到2e + 308(參見'?double')。 – 2012-07-30 17:56:05

+2

我不會說它正確解析它們。該表示在+ Inf和0之間保持不變,這僅取決於指數中的位數。如果正確解析,它會拒絕輸入或將所有這些輸入映射到+ Inf。 – 2012-07-30 18:48:16

+0

我只說它可以解析指數直到帶符號的整數範圍,並且一旦指數大於那個值,結果只在'0'和'Inf'之間變化,並且你在解析器中溢出指數變量:'const < - paste0( 「1e」,2 ^(10:32-1); for(n in const)print(eval(parse(text = n)))'。 – 2012-07-30 18:58:50

相關問題