是的我知道,對double值進行按位操作似乎是一個壞主意,但我確實需要它。C++通過長長指針中斷輸出雙位輸入
你並不需要閱讀我的問題下一段落,只爲好奇你們的:
其實我嘗試一種特殊的MOD給Mozilla的Tamarin(ActionScript虛擬機)。其中,任何對象都有爲其類型保留的前3位(例如,double是7)。這些位降低了原始數據類型的精度(int只有29位等)。對於我的國防部,我需要擴大這個區域2位。這意味着,例如,當您添加2個雙打時,您需要將最後5位設置爲零,進行數學運算,然後將結果重置。那麼爲什麼^^
現在回到代碼。 這裏最小例子示出了非常類似的問題:
double *d = new double;
*d = 15.25;
printf("float: %f\n", *d);
//forced hex output of double
printf("forced bitwise of double: ");
unsigned char * c = (unsigned char *) d;
int i;
for (i = sizeof (double)-1; i >=0 ; i--) {
printf ("%02X ", c[i]);
}
printf ("\n");
//cast to long long-pointer, so that bitops become possible
long long * l = (long long*)d;
//now the bitops:
printf("IntHex: %016X, float: %f\n", *l, *(double*)l); //this output is wrong!
*l = *l | 0x07;
printf("last 3 bits set to 1: %016X, float: %f\n", *l, *d);//this output is wrong!
*l = *l | 0x18;
printf("2 bits more set to 1: %016X, float: %f\n", *l, *d);//this output is wrong!
在VisualStudio2008運行此時,第一輸出是正確的。第二。 3rd對於十六進制和浮點數表示都會產生0,這顯然是錯誤的。 4th和5th對於十六進制和浮點數也都爲零,但修改後的比特以十六進制值顯示。所以我想,也許這個類型混淆了這裏的事情。所以2個輸出:
printf("float2: %f\n", *(double*)(long long*)d); //almost right
printf("float3: %f\n", *d); //almost right
很好,他們表現出15.25,但它應該是15.2500000000000550670620214078。所以我想,嘿,這只是輸出中的精確問題。允許修改位進一步向上:
*l = *l |= 0x10000000000;
printf("float4: %f\n", *d);
再次,輸出是15.25(0000),和不15.2519531250000550670620214078。奇怪的是,另一個強制十六進制輸出(見上面的代碼)根本沒有顯示d的修改。所以我修了一下,意識到第31位(0x80000000)是我手動設置的最後一個。和神聖莫里,它實際上對輸出有影響(15.250004)!
所以,雖然我略有偏差,仍然有很多混亂。 printf被破壞了嗎?我在這裏有一個大/小端的困惑嗎?我無意中創建了某種緩衝區溢出?
如果有人有興趣,在原來的問題(ta thing的事情,見上文),這幾乎是相反的。在那裏,最後三位已經被設置(表示雙倍)。將它們設置爲零可以正常工作(這是最初的實現)。將2更多地設置爲零具有與上述相同的效果(總體值被置爲零)。順便說一下,它不是特定於輸出的,而且數學運算似乎可以與這些地形數值一起工作(得到的2個數值的mul結果爲0)。
任何幫助,將不勝感激。 問候。
謝謝邁克。那個流氓=實際上是一個複製粘貼錯誤,我發現在寫這個問題的時候並沒有在這裏糾正它。 LL是我以前不知道的東西,所以非常感謝。 有什麼奇怪的是:當我把這些%.30f放在printf的時候,他們沒有再顯示0.0,但實際上是15.25。 – 2012-07-27 11:04:15