簡體   English   中英

未初始化的浮點變量,再現不確定的行為

[英]Uninitialized floating point variables, repoducing indeterminate behavior

我不得不調試一些表現出瞬時和零星行為的代碼,這些代碼最終可以歸因於初始化行中未初始化的浮點數,即:

float a = number, b, c = other_number;

這部分代碼是通過串行連接快速采樣設備,並在一定間隔內對輸出求平均。 每隔一段時間,就會報告編號2.7916085e + 035 ,但否則該代碼將按預期工作,並且該錯誤無法再現。

由於該數字始終為2.7916085e + 035 ,我認為通信處理或設備本身可能存在一些問題,但已排除了這些問題。 我幾乎准備將其歸咎於外部干擾,直到最終在調試器中發現錯誤的樣本。

所以,這個問題。 有人可以假設2.7916085e + 035的重要性嗎? 我不確定它在我的上下文之外是否具有任何意義,但是令我困擾的是該數字本質上是不可復制的 就是說,我無法可靠地復制問題,但是當問題出現時,總是一樣。 據我了解,未初始化的變量應該是不確定的。 值得注意的是,問題發生在程序執行的所有不同位置,階段,一天中的時間等等,但是總是在同一系統上發生。

.NET框架,運行時或操作系統中是否有引起此現象的東西? 追蹤起來特別麻煩,因為未幸運地將未初始化的變量設置為0時,它始終具有相同的值。

編輯:一些上下文。 該代碼位於具有可變刻度率的計時器內,因此變量是類的局部非靜態成員:

if(//some box checked)
{
    switch(//some output index)
    {
        case problem_variable:
        {
            if(ready_to_sample)
            {
               float average;

               for each(float num in readings)
               {
                 average += num;
               }

               average /= readings.Count;
            }
         }
    }
}

這里討論的變量將是average readings是我要平均的輸出列表。 average會被重新聲明一次。平均,這可能會在幾秒鍾,幾分鍾,幾小時內發生,或者只要滿足條件就進行平均。 變量經常會得到0,但偶爾也會得到上面的數字。

在常見的浮點編碼中,2.7916085e + 035為0x7a570ec5(浮點數),0x474ae1d8a58be975為雙模尾數。 這些看起來不像典型的文本字符串,簡單的整數或公共地址。 (雙重編碼的低位不確定,因為您沒有捕獲到足夠的十進制數字來確定它們,但是高位看起來沒有意義。)

我希望從此值本身可以推斷出很少的信息。

64位二進制雙精度轉換為

0100011101001010111000011101100010100101100010111110100000000000

要么

01111010010101110000111011000101

作為32位浮點數。 幾乎所有現代處理器都將指令和數據分開,尤其是R / W數據。 當然,例外是舊的x86,它是CISC處理器,基於每個字節都非常寶貴的4004,甚至微型計算機都沒有緩存可以使用。 但是,在現代操作系統中,很有可能在移動4或8KB頁面時,在不將舊頁面清零的情況下更改了指令頁面。

雙重版本可能等同於

Increment by 1, where r7 (EDI - extended destination index) is selected

第二個被視為浮點數,看起來它將轉換為x86或x86-64:

如何插入此x86_64程序集操作碼?

您看到的未初始化變量的值就是該內存位置中的任何值。 這不是隨機的。 它是通過上一個函數調用存儲在內存中的值。 例如:

void f() {
    int i = 3;
}

void g() {
    int i;
    std::cout << i << std::endl;
}

int main() {
    f();
    g();
    return 0;
}

該程序(假設編譯器未優化f()的初始化)可能會將3寫入控制台。

浮點數是以2為基數的系統。 因此,存在無法准確保存的特定值,無法進行近似估算。

您的輸出結果可能會給您一個值,該值具體得到相同的估計。 嘗試遍歷從串行連接中獲得的一些常用值,看看是否可以找到引起悲傷的值。 我個人會使用double代替浮點數,尤其是如果您要針對這些數字進行任何類型的計算時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM