0

2 つの入力を受け取る関数があり、指定されたタプルの 2 つの数値が関数に指定された 2 つの数値とまったく同じ比率を持つタプルの配列を返します。

したがって、すべてが正常に機能していましたが、何らかの理由で、すべてのタプルを取得していない場合があります。以下にその例を示しますが、その理由はわかりません。

In [52]: def find_r(num1,num2):
   ....:         ratio = num1/float(num2)
   ....:         ratio = 1/ratio
   ....:         my_list = [(a,int(a * ratio)) for a in range(1,num1) if float(a * ratio).is_integer()] #and a * 1/float(ratio) + a <= num1]
   ....:         return my_list
   ....: 

In [53]: find_r(100,364)
Out[53]: [(75, 273)]

したがって、タプルは 1 つしか返されませんでしたが、75 と 273 の両方を 3 で割ると、同じ比率の 25 と 91 のタプルが得られます。関数がこのインスタンスを取得しなかったのはなぜですか?

それが役立つ場合、私はそれがメソッドと関係があると疑っていますが、is_integer()よくわかりません.

ありがとう!

4

2 に答える 2

5

これは、浮動小数点演算の不正確さが原因です。

>>> ((100/364)*364).is_integer()
False
>>> ((25/91)*91).is_integer()
False

あなたがしていることをする代わりに、クロス乗算によって分数の等価性をチェックする必要があります。つまり、分数 が与えられたa/b場合、それが別の と等しいかどうかをc/d確認するには、 かどうかを確認しad == bcます。これにより、除算が回避され、すべてが整数として保持されます。

あなたはこれを行うことができます:

def find_r(num1,num2):
    return [(a, a*num2//num1) for a in range(1, num1) if (a*num2) % num1 == 0]

>>> find_r(100, 364)
[(25, 91), (50, 182), (75, 273)]

(タスクを達成する方法は他にもありますが、これは元のアプローチに最も似ています。)

于 2013-05-04T18:47:09.923 に答える
0

期待通りの答えが得られると思います

>>> r=100/float(364)
>>> r
0.27472527472527475
>>> r=1/r
>>> r
3.6399999999999997
>>> r*25
90.99999999999999
>>> r*75
273.0

整数チェックを行うには、次を使用できます

if(int(a*ratio) == a*ratio)のように

def find_r(num1,num2):
       ratio = num1/float(num2)
       ratio = 1/ratio
       my_list = [(a,int(a * ratio)) for a in range(1,num1) if int(a * ratio) == a * ratio] 
       for a in range(1,num1):
           if int(a * ratio) == a * ratio:
               print a * ratio
       return my_list


print find_r(100,364)
于 2013-05-04T19:34:33.277 に答える