2013-02-25 60 views
1

我想查找C#decimal的最低有效位數,並在該位置設置1,在所有其他位置設置爲零。查找C#十進制的最低有效位數

因此,例如2米的結果將是1米。 對於34米的結果將是1米。 對於0.4米,它將返回0.1米。 對於1200米我想要100米。

我該怎麼做?

我可以使用類似於https://stackoverflow.com/a/757266/246622的東西嗎?

(編輯:我刪除了混亂2.0M,增加了1200結果)

+2

爲什麼2.0m會導致1m而不是0.1m? – Guffa 2013-02-25 16:34:45

+1

因爲2是最不重要的數字,所以它被替換爲1 .. 2.0m - >將2替換爲1 - > 1.0m - >用0 - > 1.0m替換所有其他數字。 – christopher 2013-02-25 16:36:36

回答

2

你可以採取十進制的實現細節的優點的伎倆,其指數等於分數中的有效位數。您可以使用GetBits()方法獲取指數的值。這使得這個(相當晦澀)代碼的工作:

public static Decimal SignificantFraction(Decimal d) { 
     var b = decimal.GetBits(d); 
     return new decimal(1, 0, 0, false, (byte)((b[3] >> 16) & 0x7fff)); 
    } 

請注意,這甚至工作在角落情況下,像0.0米,它產生0.1米。你沒有指定負值應該發生什麼,所以我在構造函數中輸入了false。如果您希望結果爲負數,請將其替換爲d < 0

+1

雖然這個聰明的技巧肯定會適用於標準化的小數,但一些棘手的角落案例會打破它。例如,如果你將'd'設置爲'new decimal(100000,0,0,false,5)',這是一個有效但非常規的'1.0M'表示,你的程序會產生'0.00001'([link到演示](http://ideone.com/XMw5c8))。 – dasblinkenlight 2013-02-25 17:13:34

+0

當然,沒有辦法解決垃圾進出的問題。您無法合理斷言這樣的數字包含*任何*有效數字。 – 2013-02-25 17:16:24

+0

撇開一個頗具爭議的「100000 * 10^-5」代表性的「垃圾」級別,更多的防禦性算法肯定會爲這裏的垃圾問題提供足夠的解決方法。但效率會受損。 – dasblinkenlight 2013-02-25 17:24:42

1

怎麼樣東西沿着這些路線?

 decimal number = 1200m; 

     decimal result = 1; 
     decimal tmp = number; 
     while (tmp % 1 != 0) 
     { 
      result /= 10; 
      tmp *= 10; 
     } 
     if (result > 0 && number != 0) 
     { 
      tmp = number; 
      while (tmp % 10 == 0) 
      { 
       result *= 10; 
       tmp /= 10; 
      } 
     } 

編輯:那麼與1200例如加入我的解決方案是不是整齊了......但我認爲它應該做的

+0

這對'1200'有效嗎? – HABO 2013-02-25 16:54:24

+0

返回1.我認爲這是OP自34m以來的結果應該是1 aswel – Evelie 2013-02-25 16:55:21

+0

我猜想OP認爲'100'是輸入「1200」的答案。也許我們會聽到他們的消息。 – HABO 2013-02-25 16:56:39

0
 var t = 1.11111000m; 
     //var t = 134000m; 

     var tr = t.ToString().Reverse().ToArray(); 
     char[] ca; 
     if (t % 1 > 0) 
      ca = tr.SkipWhile(c => c == '0').Select((c, i) => i == 0 ? '1' : c == ',' ? ',' : '0').Reverse().ToArray(); 
     else 
     { 
      ca = tr.TakeWhile((c, i) => c == '0' || tr[i - 1] == '0').Reverse().ToArray(); 
      ca[0] = '1'; 
     } 

     var result = decimal.Parse(new string(ca));