我想查找C#decimal
的最低有效位數,並在該位置設置1,在所有其他位置設置爲零。查找C#十進制的最低有效位數
因此,例如2米的結果將是1米。 對於34米的結果將是1米。 對於0.4米,它將返回0.1米。 對於1200米我想要100米。
我該怎麼做?
我可以使用類似於https://stackoverflow.com/a/757266/246622的東西嗎?
(編輯:我刪除了混亂2.0M,增加了1200結果)
我想查找C#decimal
的最低有效位數,並在該位置設置1,在所有其他位置設置爲零。查找C#十進制的最低有效位數
因此,例如2米的結果將是1米。 對於34米的結果將是1米。 對於0.4米,它將返回0.1米。 對於1200米我想要100米。
我該怎麼做?
我可以使用類似於https://stackoverflow.com/a/757266/246622的東西嗎?
(編輯:我刪除了混亂2.0M,增加了1200結果)
你可以採取十進制的實現細節的優點的伎倆,其指數等於分數中的有效位數。您可以使用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
。
雖然這個聰明的技巧肯定會適用於標準化的小數,但一些棘手的角落案例會打破它。例如,如果你將'd'設置爲'new decimal(100000,0,0,false,5)',這是一個有效但非常規的'1.0M'表示,你的程序會產生'0.00001'([link到演示](http://ideone.com/XMw5c8))。 – dasblinkenlight 2013-02-25 17:13:34
當然,沒有辦法解決垃圾進出的問題。您無法合理斷言這樣的數字包含*任何*有效數字。 – 2013-02-25 17:16:24
撇開一個頗具爭議的「100000 * 10^-5」代表性的「垃圾」級別,更多的防禦性算法肯定會爲這裏的垃圾問題提供足夠的解決方法。但效率會受損。 – dasblinkenlight 2013-02-25 17:24:42
怎麼樣東西沿着這些路線?
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例如加入我的解決方案是不是整齊了......但我認爲它應該做的
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));
爲什麼2.0m會導致1m而不是0.1m? – Guffa 2013-02-25 16:34:45
因爲2是最不重要的數字,所以它被替換爲1 .. 2.0m - >將2替換爲1 - > 1.0m - >用0 - > 1.0m替換所有其他數字。 – christopher 2013-02-25 16:36:36