C#の最下位桁の位置を見つけてdecimal
、その位置に1を設定し、他のすべての位置に0を設定したいと思います。
したがって、たとえば2mの場合、結果は1mになります。34mの場合、結果は1mになります。0.4mの場合、0.1mを返します。1200mの場合は100mが必要です。
どうすればよいですか?
https://stackoverflow.com/a/757266/246622に似たものを使用できますか?
(編集:紛らわしい2.0mを削除し、1200の結果を追加しました)
C#の最下位桁の位置を見つけてdecimal
、その位置に1を設定し、他のすべての位置に0を設定したいと思います。
したがって、たとえば2mの場合、結果は1mになります。34mの場合、結果は1mになります。0.4mの場合、0.1mを返します。1200mの場合は100mが必要です。
どうすればよいですか?
https://stackoverflow.com/a/757266/246622に似たものを使用できますか?
(編集:紛らわしい2.0mを削除し、1200の結果を追加しました)
Decimalの実装の詳細を利用できます。その指数は、小数部の有効桁数に等しくなります。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.0mのようなコーナーケースでも機能し、0.1mを生成することに注意してください。負の値がどうなるかを指定しなかったので、コンストラクターでfalseをパントしました。d < 0
結果をマイナスにしたい場合は、に置き換えてください。
これらの線に沿った何かはどうですか?
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));