1
0

More than 3 years have passed since last update.

その分数は整数と等価か?

Last updated at Posted at 2020-05-05

はじめに

1.23や34.5などの数値は小数ですよね。整数ではありません。
1.0や34.0も小数ですが、まあ整数ともいえるのかもしれません。

1/3などの分数も、整数ではありません。
3/3の分数は、整数ともいえそうです。

ここでは整数をこのように定義します。
"1や34などの他、1.0や3.0のように小数点以下が0である数と、分子・分母が共に同じ数である分数"

この記事では、分数や小数でありながら整数でもあるリテラルを判別する方法について考察していきます。

そもそも、分数の表現方法とは

純粋な整数や小数は以下のように、変数に数値を入力するだけで済みます。


a = 123
b = 123.4
print(a)
print(b)

# 123
# 123.4

一方で分数はというと、上記と同様に"1/4"などと記述すると計算処理が自動的に行われてしまうため、表現できません。
そこでPythonの標準ライブラリ fractionsを利用します。

from fractions import Fraction

f = Fraction(1, 3)
print(f)

# 1/3

小数の判別ならかんたん

is_integer() メソッドを使って小数を判別してみる

小数に対しては、is_integer()メソッドを使うことで判定できます。

n = 1.23
print(n.is_integer())
# False

m = 1.00
print(m.is_integer())
# True

is_integer()メソッドを使って分数を判別してみる

しかし、fractionsを用いた分数表現には利用できません。


from fractions import Fraction

f = Fraction(1, 3)
print(f.is_integer())

# AttributeError: 'Fraction' object has no attribute 'is_integer'

分数を小数に変換してis_integer()を適用する

分数にis_integer()メソッドが使えないのならどうすればよいのか。
分数として定義されたリテラルを小数(float型)に直してやれば、is_integer()メソッドは問題なく利用できるはずです。

分数として定義されたリテラルを、1.0で割ってやることで小数に変換します。
コメント欄にてご指摘いただきまして、
float(hoge)というアプローチにより、直感的に分かりやすいよう変更しました。

この操作を挟むことで、is_integer()メソッドによる判定が可能になりました。

from fractions import Fraction

f = Fraction(1, 3)
g = float(f)

x = Fraction(3, 3)
y = float(x)

print(g)
print(y)
# 0.3333333333333333
# 1.0

print(g.is_integer())
print(y.is_integer())
# False
# True

おまけ:is_integer()メソッドがなかったらどうする?

is_integerの存在を知らなかった当時の私が考えた、遠回りな判定方法も紹介しておきます。

小数点以下を切り上げした数と、小数点以下を切り下げした数が一致していれば整数と判断する
という考えに基づいてアプローチします。

例えば1.1という数について、小数点以下を切り上げればこれは2になります。
逆に小数点以下切り下げであれば1です。
数が一致しないので、これは整数ではないと。

1.0であれば、小数点以下切り上げでも切り下げでも同じ1となるので、これは整数であると、そういう理屈です。

小数点切り上げにはmathライブラリのceil()メソッド、
切り下げには同じくmathライブラリのfloor()メソッドを使うことで、このように判別が可能になりました。
下記の関数は、1.23のような小数に対しても有効です。

from fractions import Fraction
import math


def isInteger(n):

    nx = math.ceil(n)
    ny = math.floor(n)

    return (nx == ny)


n = Fraction(1, 3)
m = Fraction(3, 3)

print(isInteger(n))
print(isInteger(m))
# False
# True

1
0
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0