0

99% を超えない限り、小数点以下 3 桁までパーセンテージを表示したいと考えています。次に、使用可能なすべての 9 と 9 以外の 3 文字を含む数字を表示したいと思います。

これをPythonで書くにはどうすればよいですか?文字列の"%.8f"書式設定は適切に機能しますが、最後の 9 の文字列の後の最後の 3 文字を保持する必要があります。

つまり:
54.8213% -> 54.821%
95.42332% -> 95.423%
99.9932983% -> 99.99330%
99.99999999992318 -> 99.9999999999232%

4

6 に答える 6

3

これを試して:

import math
def format_percentage(x, precision=3):
    return ("%%.%df%%%%" % (precision - min(0,math.log10(100-x)))) % x
于 2009-09-29T20:47:25.307 に答える
2

マーク・ランサムの答えは美しいものです。少しの作業で、あらゆる入力の問題を解決できます。私は先に進んで少し仕事をしました。

nines()にコードを追加するだけです。

def nines(x):
    x = abs(x)  # avoid exception caused if x is negative
    x -= int(x)  # keep fractional part of x only
    cx = ceilpowerof10(x) - x
    if 0 == cx:
        return 0  # if x is a power of 10, it doesn't have a string of 9's!
    return -int(math.log10(cx))

次に、threeplaces()は何に対しても機能します。ここにいくつかのテストケースがあります:

>>> threeplaces(0.9999357)
'0.9999357'
>>> threeplaces(1000.9999357)
'1000.9999357'
>>> threeplaces(-1000.9999357)
'-1000.9999357'
>>> threeplaces(0.9900357)
'0.99004'
>>> threeplaces(1000.9900357)
'1000.99004'
>>> threeplaces(-1000.9900357)
'-1000.99004'
于 2009-09-29T21:58:24.757 に答える
1
def ceilpowerof10(x):
    return math.pow(10, math.ceil(math.log10(x)))

def nines(x):
    return -int(math.log10(ceilpowerof10(x) - x))

def threeplaces(x):
    return ('%.' + str(nines(x) + 3) + 'f') % x

nines() は、最初は 10 の累乗である数値に対してエラーをスローすることに注意してください。すべての入力に対して安全にするには、もう少し作業が必要です。おそらく負の数にもいくつかの問題があります。

于 2009-09-29T20:32:52.247 に答える
0

これを試して:

def print_percent(p):    
    for i in range(30):
        if p <= 100. - 10.**(-i):
            print ("%." + str(max(3,3+i-1)) + "f") % p
            return

または、文字列を取得するだけの場合はこれ

def print_percent(p):    
    for i in range(20):
        if p <= 100. - 10.**(-i):
            return ("%." + str(max(3,3+i-1)) + "f") % p
于 2009-09-29T20:29:03.893 に答える
0

これは標準フォーマットでは不可能であると確信しています。次のようなものを使用することをお勧めします (C# のような疑似コード)。特に、文字列演算に依存し、精度と丸めの問題が多数発生する可能性があるため、数学コードを使用しないことをお勧めします。

string numberString = number.ToStringWithFullPrecision();

int index = numberString.IndexOf('.');

while ((index < numberString.Length - 1) && (numberString[index + 1] == '9'))
{
    index++;
}

WriteLine(number.PadRightWithThreeZeros().SubString(0, index + 4));

正規表現が好きなら、それらを使用できます。次の式を取り、それを 3 つのゼロで埋められた完全精度の数値文字列と突き合わせれば完了です。

^([0-9]|[1-9][0-9]|100)\.(9*)([0-8][0-9]{2})

どちらの提案も丸め誤差を引き起こす可能性があることに気付きました。99.91238123になる99.9123べきときになる99.9124- したがって、最後の桁には追加の修正が必要です。実行するのは簡単ですが、私の提案はさらに醜いものになります。これは、エレガントでスマートなアルゴリズムとはかけ離れています。

于 2009-09-29T20:31:52.843 に答える
0
 def ilike9s(f):
   return re.sub(r"(\d*\.9*\d\d\d)\d*",r"\1","%.17f" % f)

そう...

>>> ilike9s(1.0)
'1.000'
>>> ilike9s(12.9999991232132132)
'12.999999123'
>>> ilike9s(12.345678901234)
'12.345'

そして、忘れないでくださいimport re

于 2009-09-29T21:35:57.590 に答える