2017-09-03 31 views
0

this question中,OP試圖隔離大程序中難以捉摸的錯誤。他觀察了一些double值,然後嘗試將它們作爲輸入硬編碼到較小的測試程序。 ideea非常適合隔離這樣的bug。將精確表示分配給浮點值

但是所選擇的方法違反了字符串別名規則,引入UB,從而所述測試是完全不可靠:

  1. 手錶的調試器的表達式:

    +------------------------+----------------------| 
    | Watch Expression  | Value    | 
    +------------------------+----------------------| 
    | *(long long int *)(&a) | 4594681439063077250 | 
    +------------------------+----------------------| 
    
  2. 和然後將其指定在測試程序:

    double a; 
    *(long long int *)(&a) = 4594681439063077250; 
    

(我強烈懷疑)他這樣做是爲了一點一點地保留確切的double值。

問題:如何在調試會話中觀察到如何將雙精度值分配給位 - ?

+0

爲什麼你的意思是「一點一滴」。數字是一個數字,如果你知道數字並知道表示格式,那麼你知道它的表示形式。 –

+0

您的調試工具是否允許您查看變量中的實際位,或僅顯示十進制表示? – Beta

+0

您已經回答說這引入_undefined behavior_。我懷疑沒有實際引入_UB_的方法。 – user0042

回答

0

這可以通過代表兼作的char陣列來完成:

double as_double = 0.0; 
uint64_t as_uint64 = 4594681439063077250 ; 

static_assert(sizeof(double) == sizeof(uint64_t), ""); 
memcpy(&as_double, &as_uint64_t, sizeof(double)); 
0

我的嚴格別名規則的解釋,說這將是UB

uint64_t x = 4594681439063077250; 
double * a = (double *) & x; 

你的代碼是好的。

4

Hexadecimal representation是分配浮點值的精確位表示的好方法。如果因爲您尚未使用C++ 17而無法使用文字,請注意,strtod可識別此格式。

+1

自C + 11以來,您可以使用['std :: hexfloat'](http://en.cppreference.com/w/cpp/io/manip/fixed)和'<<' and '>>流操作符。 – rici