2012-07-02 65 views
5

我提出以下問題,我不知道該怎麼回答。我想知道是否有人可以幫助:舍入雙,而無需使用圓形或截斷

使用C#,並且不使用任何數學函數(Round()和Truncate()不被允許))採用以下雙精度3.009784654並將其舍入到四位小數位。

這是接受記者採訪時,不是一類項目或家庭作業。面試官似乎試圖讓我使用mod,但我仍然想不出如何去做。

謝謝!通過1E4乘以1E4,鑄爲int,除法:

+0

沒有mod,但是可以將它格式化爲一個顯示4位小數的字符串,並將其解析爲一個double(效率不高!)。 – assylias

+0

什麼類型的舍入? –

+0

是的 - 我提到他們,但這也是不允許的! – MattW

回答

7

要截斷(因爲沒有指定舍入規則)。乘

+0

+1擊敗我。 – mellamokb

+0

是的,我也是... ^^ – poke

+0

哦,你是最快的^^ –

1

10^numberOfDigitsAfterComma,轉換成int,然後返回到10 ^浮動,分...

double x = 3.009784654; 
x = ((double)((int)(x * 10000)))/10000; 
1

如果你真的需要MOD,你可以這樣做:

double number = 3.009784654; 
double truncatedNumber = number - number % 0.0001; 
0

使用mod的答案:

double d = 1.23456789; 
int digitsToKeep = 2; 
double divisor = Math.Pow(10, digitsToKeep * -1); 
double rounded = d - (d % divisor); 
0

如果需要的話,這也將數字向上舍入。

public static double Round(double number, int digits) 
{ 
    for (int i = 0; i < digits; i++) 
     number *= 10; 

    int whole = (int)number; 
    double fraction = number - whole; 

    if (fraction >= 0.5) 
     whole++; 

    number = whole; 

    for (int i = 0; i < digits; i++) 
     number /= 10.0; 

    return number; 
} 
2

這是一個糟糕的面試問題,因爲任務是一般不可能,因爲預期的工具,因爲最正確的結果不能代表。也就是說,公共浮點型不能準確地表示正確的數學結果,3.0098。所以計算並返回正確的答案是不可能的。您將不得不使用一些替代機制,例如以不同類型返回值(縮放爲整數,字符串,十進制浮點格式等)。

我懷疑答案可能已經期待面試官是評估(INT)(X * 10000 + .5)* 0001。這個縮放值,使得所期望的結果爲整數(舍入量子,0.0001,被縮放到1),添加0.5,截斷成整數,並反轉縮放。添加.5和截斷的組合幾乎等價於四舍五入,除非它要求x是正數,從零開始將關係舍入,並且具有範圍/域問題。這些調整可以根據情況和期望的行爲進行。而且,當然,由於無法表示確切的結果,答案通常稍微不正確。

一個更有趣的回答是評估(X * 10000 + 0x1p52-0x1p52)* 0001。這將使用當前的浮點舍入模式對值進行縮放,將其舍入爲整數,並取消縮放。由於公共雙精度型在其有效位數中有53位,所以舍入有效,所以當高位爲0x1p52時,低位值爲0x1p0(也稱爲1)。爲了產生添加0x1p52的結果,有效位必須被舍入,這在浮點硬件中自動完成。然後減去0x1p52刪除添加的數字,留下四捨五入的值。和以前一樣,有範圍/域的警告,並確保編譯器執行雙精度算術,而不是更多,並且可以進行調整。但是,在某些硬件上轉換速度比轉換爲整數更快。

使用fmod或字符串轉換的性能較差,因爲它們需要分區,這在大多數常見處理器上都很慢。