2017-02-03 97 views
2

我試圖在Arduino UNO上執行一個算法,它需要一些大數字的const表,有時我會得到溢出值。這個數字是這樣的:628331966747.0Arduino UNO上的const太大const

好的,這是一個很大的,但是它的類型是float(32位),其中最大值是3.4028235e38。所以理論上它應該起作用?

我能對此做些什麼?你知道一個解決方案嗎?

編輯:在Arduino的UNO,雙是exaclty漂浮同一類型(32個比特)

這裏是導致該錯誤的代碼:

float A; 

void setup() { 
    A = 628331966747.0; 
    Serial.begin(9600); 
} 

void loop() { 
    Serial.println(A); 
    delay(1000); 
} 

其打印「OVF,OVF, ...,ovf「

+0

什麼是錯誤? – GManNickG

+1

由於浮點數的存儲方式,FWIW'628331966747'不能精確地存儲爲浮點數。在32位浮點數中最接近的表示形式是'628331970560'。然而,雙倍將適合罰款。 – Thebluefish

+0

@GManNickG下面的代碼我發佈我收到「ovf,ovf,ovf ...」對我來說它應該返回類似於:6.283319e011,不是? –

回答

3

常數本身沒有什麼問題(除了相當樂觀的有效數字外),但問題在於Arduino庫支持打印浮點值。 Print::printFloat()包含以下條件的預測試:

if (isnan(number)) return print("nan"); 
    if (isinf(number)) return print("inf"); 
    if (number > 4294967040.0) return print ("ovf"); // constant determined empirically 
    if (number <-4294967040.0) return print ("ovf"); // constant determined empirically 

似乎可打印的值的範圍是爲了故意限制大概是爲了降低複雜性和代碼大小。隨後的代碼揭示了原因:

// Extract the integer part of the number and print it 
    unsigned long int_part = (unsigned long)number; 
    double remainder = number - (double)int_part; 
    n += print(int_part); 

的有些簡單化實現要求的整數部分的絕對值本身是一個32位整數。

令人擔憂的事情可能是評論「經常確定的經驗」這反而暗示價值觀是通過反覆試驗得出的,而不是對數學的理解!人們不得不想知道爲什麼這些值沒有按照INT_UMAX來定義。

還有就是提出了「修復」描述here,但它不會工作的,至少因爲它適用於整數abs()功能的double參數number,這要是整數部分小於更加嚴格MAX_INT只會工作。作者發佈了一個鏈接到一個包含修復的zip文件,該修復看起來更有可能工作(至少有測試證據證明!)。

+0

Upvoted。我想補充說的是,剛纔提出的'fix'已經在* github *上更新了。 –