2013-08-20 16 views
1

編輯:我編寫了與在家工作時重新創建該錯誤相同的代碼。這是確切的代碼!將它們從CLI傳遞到C時,會發生變化#

我想從C++傳遞浮動數字到C#和我使用C++ CLI作爲中間。 我有以下功能在C++ CLI

void myclass::getFloats(float% f1, float %f2) 
{ 
    float f11=734212.384f; 
    float f22=467474.26675f; 
    f1=f11; 
    f2=f22; 
} 

當我把一個破發點中的函數的結束,停在那裏,我看到:

  • F1認爲:734212.38
  • F2舉行:467474.28

我假設由於浮點限制,它是可以的。

但是當範圍結束,我返回到調用這個函數看起來像這樣的C#代碼:

myclass m = new myclass(); 
float f1=0, f2=0; 
m.getFloats(ref f1, ref f2); 

而且getFloat功能我看到後,我停下來。

  • F1持有734212.4
  • F2持有467474.281

我不知道爲什麼發生這種情況,爲什麼在第一個號碼,他四捨五入0.38到0.4,並在第二他沒有並剛剛添加0.001?

任何幫助將不勝感激, 在此先感謝

+3

因爲C++ CLI調試器顯示只有三個顯著數字(所以回合的顯示值),而C#有四個顯著位在其值的顯示器? –

+0

你確定它不只是C++和C#調試器具有不同的舍入? – Medinoc

+0

這不是這種情況,當我在cli中看到4.79999的手錶時,會出現這種情況,並且它會在c#中轉換爲4.8。該手錶會在CLI中顯示更多3位數字。 – OopsUser

回答

0

你遇上了精度爲32位浮點的限制。我會換成double,看看你的「問題」是否會消失。

你擁有的數量是

float f22=467474.26675f; 

最近的浮點表示是

48E44249 467474.28125 

你看到的調試顯示器,"467474.28""467474.281",都顯示該值的兩個合理的方式。

下表示數爲

48E4424A 467474.3125 

您的評論認爲,舍入誤差是0.0000001順序上表達的想法是隻爲0.5和1.0之間的值如此。一般來說,舍入誤差將在0.0000001 * value的數量級上。

+0

你有何變化發生在節目結束的CLI命令的任何想法代碼並返回到C#? 我知道舍入應該發生在這一行: float f11 = 734212.384f;但在浮動得到數字後,它不應該改變。 C++和c#有不同的float的表示形式嗎? – OopsUser

+0

@OopsUser:號碼沒有變化。它仍然是0x48E44249。你只是處理兩個不同的調試器,它們顯示的方式稍有不同。沒有人向您顯示真正的準確值,即467474.28125 –

+0

有沒有辦法在調試時看到確切的值? – OopsUser

0

我認爲這是由浮點模式引起的。在本地C++中,我們可以使用編譯器選項/ fp指定3種浮動模式:fast, precise,strict。默認情況下,本地C++項目使用fp:precise;而根據此post,託管代碼使用與fp:fast等效的內容。雖然fp:fast比fp:精確度要低,但我認爲這是問題的原因。

您可以嘗試在本地C++中指定fp:fast,以查看是否可以修復此問題。

僅供參考,Microsoft Visual C++ Floating-Point Optimization

+0

我在C++ CLI改變從精確到快,它並沒有改變任何東西:( – OopsUser

+0

你在本地C++項目更改設置? – Matt

+0

我刪除了C++項目,看看我的代碼,我有簡單的CLI返回不變數字。 – OopsUser

相關問題