🌊

浮動小数点数計算のPython、Java、C#での実装について

2022/10/25に公開

はじめに

浮動小数点数に関わる計算の実装について、一度は悩まされた人も多いと思いますので、自分が良く使うPython、Java、C#での実装方法を備忘録代わりに執筆します。

浮動小数点数についての教科書的な知識は、以下のリンクを参照して下さい。
https://workteria.forward-soft.co.jp/blog/detail/10401

AtCoderという競技プログラミングのサイトで浮動小数点数を扱っている問題があるので、今回はここで通るコードを紹介したいと思います。
https://atcoder.jp/contests/abc169/tasks/abc169_c

この問題は、10^15くらいの大きな整数aと10以下の正の少数bが与えられ、a * bの結果を小数点以下を切り捨てて標準出力する問題です。
競技プログラミングを知らない方向けに説明すると、各サンプルコードの冒頭の部分は入力から変数a,bに代入を行っていると考えればよいです。

Pythonの場合

from decimal import *
a, b = input().split()
print(int((Decimal(a) * Decimal(b))))

浮動小数点数を正確に扱えるdecimalライブラリがあるので、それを使用します。
最後にint型に変換することで、小数点以下を切り捨てることが出来ます。

Javaの場合

import java.util.*;
import java.math.BigDecimal;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        BigDecimal a = sc.nextBigDecimal();
        BigDecimal b = sc.nextBigDecimal();
        System.out.println(a.multiply(b).toBigInteger());
    }
}

java.math.BigDecimalを使います。
BigDecimal型同士の演算で通常の乗算子を用いることは出来ないので注意("a * b"とするとコンパイルエラーが起きる)。掛け算の場合はmultiplyメソッドを用います。
最後にIntに変換することで小数点以下を切り捨てています。

C#の場合

using System;
class Decimal_Multiplicator
{
    static void Main()
    {
        string[] Input = Console.ReadLine().Split(' ');
        decimal a = decimal.Parse(Input[0]);
        decimal b = decimal.Parse(Input[1]);
        Console.WriteLine(Decimal.Floor(a * b));
    }
}

組み込み型にdecimal型があるので、それを使用します。intを扱うのとほとんど同じような感覚で扱えると思います。
C#の場合、小数点切り捨ては型キャストするよりもfloor関数を用いたほうがわかりやすいと思います。

おわりに

単純な掛け算という簡単な実装例ですが、思ったよりも各言語で浮動小数点数の扱いが異なる感じで驚きました。
この記事が浮動小数点数がかかわる計算の実装に悩んでいる方のお役に立てば幸いです。

Discussion