xlsxファイル内部では数値「1.225」が、「1.2250000000000001」として格納されていることに気づきました。
こうなると、拙著『Excel VBAユーザーのためのOpenPyXL入門: Pythonの定番ライブラリの特徴をちゃんと知ろう』でも基本を解説している、OpenPyXLを使って、実際は「1.2250000000000001」の「1.225」を読み込んだときにどうなるのかが気になります。
「1.333」「1.225」などのセルを確認するスクリプト
A1:A4セルに以下のデータを入力したワークシートがアクティブな状態で、
1.333 1.225 -1.333 -1.225
Cドライブtempフォルダーに、samp_1333_1225.xlsxとして保存しておいてから、以下のスクリプトを実行しました。
bk = xl.load_workbook(r'c:\temp\samp_1333_1225.xlsx')
ws = bk.active
sum = 0
for i in range(1, 5):
val = ws.cell(i, 1).value
print(f'{val:>6} {val:>20.15f} {val:>20.16f} {val:>20.17f}')
sum += val
c:\temp\samp_1333_1225.xlsxを読み込み、アクティブシートを変数wsに代入しておいてから、
bk = xl.load_workbook(r'c:\temp\samp_1333_1225.xlsx')
ws = bk.active
A1:A4セルの値を順番に取得・出力しています。
for i in range(1, 5):
val = ws.cell(i, 1).value
print(f'{val:>6} {val:>20.15f} {val:>20.16f} {val:>20.17f}')
出力時には、拙著『Python入門を読み終えた人へ…1: 文字列フォーマットの基本』でも基本を解説しているf-stringで、取得したデータそのもの、小数第15位、小数第16位、小数第17位まで右揃えになるようにしています。
また、A1:A4セルの値を合計して、最後にprintする処理も入れています。
sum = 0
for i in range(1, 5):
val = ws.cell(i, 1).value
sum += val
print('合計:', sum)
スクリプトの実行結果
実行結果は以下のとおりです。
1.333 1.333000000000000 1.3330000000000000 1.33299999999999996 1.225 1.225000000000000 1.2250000000000001 1.22500000000000009 -1.333 -1.333000000000000 -1.3330000000000000 -1.33299999999999996 -1.225 -1.225000000000000 -1.2250000000000001 -1.22500000000000009 合計: -2.220446049250313e-16
肝心の「1.225」は「1.225」として取得できているようです。
ただし、f-stringで小数第16位まで表示させると「1.2250000000000001」になっています。
取得した値の合計は、「0」ではなく誤算を含む「-2.220446049250313e-16」となっています。
「1.2250000000000001」が「1.225」となる理由
xlsxファイル内の「1.2250000000000001」が、「1.225」として取得されるのは、opynpyxlパッケージのworksheetフォルダー内の_reader.pyモジュールで、以下のように_cast_number関数が定義されているためだと思われます。
def _cast_number(value): if "." in value or "E" in value or "e" in value: return float(value) return int(value)
最終更新日時:2024-01-16 13:23
Home » Python » OpenPyXLの使い方 » OpenPyXLで「1.2250000000000001」を読み込んでも「1.225」