Python の組み込み関数 divmod の使い方です。
divmod(a, b)
で、a
を b
で割ったときの『商』と『余り(剰余)』を、同時に求めることができました。
そのコード例と、実行結果を載せました。
divmod 関数の結果は、(商, 剰余)
のタプルになっていました。
あと、『エラーになったコード例』も書きました。
エラーになったコード例
divmod 関数で、エラーになったコード例です。
divmod() # 引数無し
TypeError: divmod expected 2 arguments, got 0
divmod(10)
TypeError: divmod expected 2 arguments, got 1
divmod(10, 0)
ZeroDivisionError: integer division or modulo by zero
divmod('10', '3')
TypeError: unsupported operand type(s) for divmod(): 'str' and 'str'
divmod(b'10', b'3')
TypeError: unsupported operand type(s) for divmod(): 'bytes' and 'bytes'
divmod(25, None)
TypeError: unsupported operand type(s) for divmod(): 'int' and 'NoneType'
divmod(None, 25)
TypeError: unsupported operand type(s) for divmod(): 'NoneType' and 'int'
divmod(complex(5, 12), complex(3, 4))
TypeError: can't take floor or mod of complex number.
組み込み定数を渡した結果
divmod 関数に、組み込み定数を渡した結果です。
divmod(False, False)
ZeroDivisionError: integer division or modulo by zero
divmod(False, True)
(0, 0)
divmod(True, False)
ZeroDivisionError: integer division or modulo by zero
divmod(True, True)
(1, 0)
int を渡した結果
divmod 関数に、int(整数)を渡した結果です。
int 型の数値の書き方は(整数リテラルは)、普通の 10 進数で書くこともできましたし、接頭辞を付けて、2 進数、8 進数、16 進数の表現で書くこともできました。
(Python) 整数リテラル (Integer literals)
10 進数
10 進数の場合です。
divmod(15, 7)
(2, 1)
divmod(15, -7)
(-3, -6)
divmod(-15, 7)
(-3, 6)
divmod(-15, -7)
(2, -1)
2 進数
2 進数の場合です。
divmod(0b1111, 0b0111) # (15, 7)
(2, 1)
divmod(0b1111, -0b0111) # (15, -7)
(-3, -6)
divmod(-0b1111, 0b0111) # (-15, 7)
(-3, 6)
divmod(-0b1111, -0b0111) # (-15, -7)
(2, -1)
8 進数
8 進数の場合です。
divmod(0o17, 0o7) # (15, 7)
(2, 1)
divmod(0o17, -0o7) # (15, -7)
(-3, -6)
divmod(-0o17, 0o7) # (-15, 7)
(-3, 6)
divmod(-0o17, -0o7) # (-15, -7)
(2, -1)
16 進数
16 進数の場合です。
divmod(0xf, 0x7) # (15, 7)
(2, 1)
divmod(0xf, -0x7) # (15, -7)
(-3, -6)
divmod(-0xf, 0x7) # (-15, 7)
(-3, 6)
divmod(-0xf, -0x7) # (-15, -7)
(2, -1)
float を渡した結果
divmod 関数に、float(浮動小数点数)を渡した結果です。
(Python) 浮動小数点数リテラル (Floating point literals)
ところで、浮動小数点数の中には、計算機の中だと、近似値でしか表現できないものがありました。
試しに、いくつかの数値を、『小数点以下 30 桁 (.30f
)』まで、表示してみました。
f'{0.1:.30f}' -> '0.100000000000000005551115123126'
f'{0.4:.30f}' -> '0.400000000000000022204460492503'
f'{0.5:.30f}' -> '0.500000000000000000000000000000'
f'{0.9:.30f}' -> '0.900000000000000022204460492503'
f'{1.0:.30f}' -> '1.000000000000000000000000000000'
f'{1.1:.30f}' -> '1.100000000000000088817841970013'
f'{1.5:.30f}' -> '1.500000000000000000000000000000'
f'{7.0:.30f}' -> '7.000000000000000000000000000000'
f'{15.0:.30f}' -> '15.000000000000000000000000000000'
やはり、わずかにズレた数値になっている場合がありました。
なので、そういった数値を divmod 関数に渡したときは、直感的ではない結果になりました。
正確
float 型の数値を渡して、結果が正確な数値で返ってきた場合です。
divmod(15.0, 7.0)
(2.0, 1.0)
divmod(15.0, -7.0)
(-3.0, -6.0)
divmod(-15.0, 7.0)
(-3.0, 6.0)
divmod(-15.0, -7.0)
(2.0, -1.0)
近似値
近似値でしか表現できない 0.1
を渡した場合です。
divmod(1.0, 0.1)
(9.0, 0.09999999999999995)
divmod(1.0, -0.1)
(-10.0, -5.551115123125783e-17)
divmod(-1.0, 0.1)
(-10.0, 5.551115123125783e-17)
divmod(-1.0, -0.1)
(9.0, -0.09999999999999995)
指数
浮動小数点数は、指数を使用して書くこともできました。
divmod(1.5e1, 7.0e0) # (15.0, 7.0)
(2.0, 1.0)
無限大 (inf) と非数 (nan)
『無限大 (inf)』と『非数 (nan)』も、使用可能でした。
divmod(float('inf'), float('inf')) # (inf, inf)
(nan, nan)
divmod(float('-inf'), float('-inf')) # (-inf, -inf)
(nan, nan)
divmod(1.0, float('inf')) # (1.0, inf)
(0.0, 1.0)
divmod(1.0, float('-inf')) # (1.0, -inf)
(-1.0, -inf)
divmod(-1.0, float('inf')) # (-1.0, inf)
(-1.0, inf)
divmod(-1.0, float('-inf')) # (-1.0, -inf)
(0.0, -1.0)
divmod(float('inf'), 1.0) # (inf, 1.0)
(nan, nan)
divmod(float('-inf'), 1.0) # (-inf, 1.0)
(nan, nan)
divmod(float('nan'), float('nan')) # (nan, nan)
(nan, nan)
divmod(1.0, float('nan')) # (1.0, nan)
(nan, nan)
divmod(float('nan'), 1.0) # (nan, 1.0)
(nan, nan)
Decimal を渡した結果
divmod 関数に、Decimal 型(十進数型)を渡した結果です。
(Python) class decimal.Decimal(value="0", context=None)
Decimal 型
引数に『Decimal 型』だけを渡した場合です。
ところで、divmod 関数に『マイナスの数値』を渡したときについてです。
計算結果が、『int 型』や『float 型』のときとは、異なっている場合がありました。
from decimal import Decimal
divmod(Decimal(15.0), Decimal(7.0))
(Decimal('2'), Decimal('1'))
from decimal import Decimal
divmod(Decimal(15.0), Decimal(-7.0))
(Decimal('-2'), Decimal('1'))
divmod(15.0, -7.0) # (参考) float 型
(-3.0, -6.0)
divmod(15, -7) # (参考) int 型
(-3, -6)
from decimal import Decimal
divmod(Decimal(-15.0), Decimal(7.0))
(Decimal('-2'), Decimal('-1'))
divmod(-15.0, 7.0) # (参考) float 型
(-3.0, 6.0)
divmod(-15, 7) # (参考) int 型
(-3, 6)
from decimal import Decimal
divmod(Decimal(-15.0), Decimal(-7.0))
(Decimal('2'), Decimal('-1'))
divmod(-15.0, -7.0) # (参考) float 型
(2.0, -1.0)
divmod(-15, -7) # (参考) int 型
(2, -1)
from decimal import Decimal
divmod(Decimal(1.0), Decimal(0.1))
(Decimal('9'), Decimal('0.09999999999999995003996389187'))
from decimal import Decimal
divmod(Decimal(1.0), Decimal(-0.1))
(Decimal('-9'), Decimal('0.09999999999999995003996389187'))
divmod(1.0, -0.1) # (参考) float 型
(-10.0, -5.551115123125783e-17)
from decimal import Decimal
divmod(Decimal(1.5e1), Decimal(7.0e0)) # (Decimal('15'), Decimal('7'))
(Decimal('2'), Decimal('1'))
from decimal import Decimal
divmod(Decimal(1), Decimal('inf')) # (Decimal('1'), Decimal('Infinity'))
(Decimal('0'), Decimal('1'))
from decimal import Decimal
divmod(Decimal(1), Decimal('-inf')) # (Decimal('1'), Decimal('-Infinity'))
(Decimal('-0'), Decimal('1'))
from decimal import Decimal
divmod(Decimal(-1), Decimal('inf')) # (Decimal('-1'), Decimal('Infinity'))
(Decimal('-0'), Decimal('-1'))
from decimal import Decimal
divmod(Decimal(-1), Decimal('-inf')) # (Decimal('-1'), Decimal('-Infinity'))
(Decimal('0'), Decimal('-1'))
from decimal import Decimal
divmod(Decimal('inf'), Decimal(1)) # (Decimal('Infinity'), Decimal('1'))
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
from decimal import Decimal
divmod(Decimal(1), Decimal('nan')) # (Decimal('1'), Decimal('NaN'))
(Decimal('NaN'), Decimal('NaN'))
from decimal import Decimal
divmod(Decimal(1), Decimal('snan')) # (Decimal('1'), Decimal('sNaN'))
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
Decimal 型と int 型
引数に『Decimal 型と int 型の組み合わせ』を渡した場合です。
from decimal import Decimal
divmod(15, Decimal(7.0)) # (15, Decimal('7'))
(Decimal('2'), Decimal('1'))
from decimal import Decimal
divmod(15, Decimal(-7.0)) # (15, Decimal('-7'))
(Decimal('-2'), Decimal('1'))
from decimal import Decimal
divmod(-15, Decimal(7.0)) # (-15, Decimal('7'))
(Decimal('-2'), Decimal('-1'))
from decimal import Decimal
divmod(-15, Decimal(-7.0)) # (-15, Decimal('-7'))
(Decimal('2'), Decimal('-1'))
from decimal import Decimal
divmod(Decimal(15.0), 7) # (Decimal('15'), 7)
(Decimal('2'), Decimal('1'))
from decimal import Decimal
divmod(Decimal(15.0), -7) # (Decimal('15'), -7)
(Decimal('-2'), Decimal('1'))
from decimal import Decimal
divmod(Decimal(-15.0), 7) # (Decimal('-15'), 7)
(Decimal('-2'), Decimal('-1'))
from decimal import Decimal
divmod(Decimal(-15.0), -7) # (Decimal('-15'), -7)
(Decimal('2'), Decimal('-1'))
Decimal 型と float 型
引数に『Decimal 型と float 型の組み合わせ』を渡した場合は、エラーになりました。
これは、(Python) class decimal.Decimal(value="0", context=None)
のところに、説明がありました。
『Decimal オブジェクトは一般に、算術演算で浮動小数点数や fractions.Fraction オブジェクトと組み合わせることができません。』と書かれていました。
from decimal import Decimal
divmod(Decimal(15.0), 7.0) # (Decimal('15'), 7.0)
TypeError: unsupported operand type(s) for divmod(): 'decimal.Decimal' and 'float'
from decimal import Decimal
divmod(15.0, Decimal(7.0)) # (15.0, Decimal('7'))
TypeError: unsupported operand type(s) for divmod(): 'float' and 'decimal.Decimal'
『商』を求める演算子 // と『剰余』を求める演算子 %
divmod 関数では、商と剰余を、同時に取得することができました。
ですが、それらを別々に計算して取得することもできました。
Python には、切り捨て除算の『商だけ』を求める演算子 //
と、『余りだけ(剰余だけ)』を求める演算子 %
がありました。
(Python) 二項算術演算 (binary arithmetic operation) 除算 /
と切り捨て除算 //
(Python) 二項算術演算 (binary arithmetic operation) 剰余 %
以上です。