【コーディングを支える技術】Python、Fortran、C++。整数型+浮動小数点型でどうなる?
本日も「コーディングを支える技術」を読んでいます。
プログラミングがどのように進化していったかを知ることで、現代風の記述などを知り、そしていかにコードが直感的で書きやすく変わっていったかをしることができます。
前回は「どのプログラミング言語をはじめに学んだ方が良いのか」と「プログラミング言語をどのように学んだ方が良いのか?」というテーマでお話をしました。
今回異なるデータ型どうしの演算について、
Python
Fortran
C++
で見ていこうと思います。
【Python】整数型+浮動小数点型
Pythonで以下のように整数型a,cと浮動小数点型bを用意します。
a = 3
b = 2.0
c = 2
print('a/b = ',a/b, type(a/b))
print('float(a)/b = ',float(a)/b, type(float(a)/b))
print('a/c = ',a/c, type(a/c))
print('3/2 = ', 3/2, type(3/2))
Pythonにはデータの型宣言が不要で変数を設定した時点の記述の仕方でデータの型が決まります。
Python2系で実行結果は以下となります。
('a/b = ', 1.5, <type 'float'>)
('float(a)/b = ', 1.5, <type 'float'>)
('a/c = ', 1, <type 'int'>)
('3/2 = ', 1, <type 'int'>)
Python2系は今や古いバージョンでPython3系が最新になります。 そしてPython3系になってずいぶんと記述方法や出力結果が変わってきました。 出力結果の違いの一つが「print('a/c = ',a/c, type(a/c))」の部分です。 整数型a,cの割り算は3/2=1.5となりそうですが結果は小数点以下が切り捨てられて1となります。 データの型をどちらも整数型としたことで出力結果も整数型で返すようになっているからですね。コンピュータにとって1と1.5は別物だからですね。 もし、3/2=1.5のように期待した結果を示したかったら型変換を行って、、
float(a)/b
のように書かないといけません。
でも、プログラムが膨大になるとある変数がどんなデータ型になっているのかわからないです・・・・3/2とした際の自然な結果は1.5となることなのでプログラム側で意図を汲み取って勝手に変換してほしいですよね。
というわけで最新のPython3系で実行してみましょう。
出力結果は以下となります。
a/b = 1.5 <class 'float'>
float(a)/b = 1.5 <class 'float'>
a/c = 1.5 <class 'float'>
3/2 = 1.5 <class 'float'>
整数型a,cどうしの割り算を行った結果はデータ型floatに変換され、値も1.5となっています。
どうやら人間が自然に期待している結果にプログラムがアップデートされているようです。
【C++】整数型+浮動小数点型
Pythonは人間が意図した結果に進化していることがわかりました
大規模開発かつ高速実行が可能なC++はどうでしょう。
Pythonより学習コストが膨大な上歴史もあるC++はどうでしょうか。
#include <iostream>
#include <typeinfo>
int main()
{
int a, c;
float b;
a = 3;
b = 2.0;
c = 2;
std::cout << "a/b = "<<a/b << typeid(a/b).name() << std::endl;
std::cout << "(float)a/b = " << (float) a/b << typeid((float)a/c).name() << std::endl;
std::cout << "a/c = " << a/c << typeid(a/c).name() << std::endl;
std::cout << "3/2 = " << 3/2 << typeid(3/2).name() << std::endl;
std::cout << "a + b = "<< a + b << typeid(a+b).name() << std::endl;
return 0;
}
【出力結果】
a/b = 1.5f
(float)a/b = 1.5f
a/c = 1i
3/2 = 1i
a + b = 5f
データ型を確認するために標準ライブラリ#include <typeinfo>をインクルードしています。
注目すべきは以下の部分です。
std::cout << "a/c = " << a/c << typeid(a/c).name() << std::endl;
std::cout << "3/2 = " << 3/2 << typeid(3/2).name() << std::endl;
std::cout << "a + b = "<< a + b << typeid(a+b).name() << std::endl;
はじめに宣言したデータ型のまま出力されa/c=1と小数点以下が切り捨てられています。
しかし、足し算の方は整数型+浮動小数点型で結果は浮動小数点型になっています。
GNU GCC (GNUコンパイラコレクション)のg++-9 (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0で実行してみました。
最新版がどうなっているのか終えていませんがPythonとは違う出力結果になったのが興味深いですね。
C++は割り算の演算にはデータ型を意識した記述が必要ですね。
【Fortran】整数型+浮動小数点型
Fortranならどうでしょう。
program main
implicit none
!型の宣言
integer::a, c
real(kind=8)::b
a = 3
b = 2.0
c = 2
print*, "a/b = ", a/b
print*, "real(a)/b = ", real(a)/b
print*, "a/c = ",a/c
print*, "a + b = ", a + b
end program main
FortranもC++同じ出力結果になるのではないかというのがおおかたの予想でしたが、やはりそうでした。
【出力結果】
a/b = 1.5000000000000000
real(a)/b = 1.5000000000000000
a/c = 1
a + b = 5.0000000000000000
Fortranでの型確認の方法がわからなかったので保留にしています。
今回の学んだこととして、
●プログラミングは日々改良され進化している
●プログラミング言語ごとで出力結果が異なる
というものです。
Twitter➡@t_kun_kamakiri
Instagram➡kamakiri1225
youtube➡https://www.youtube.com/channel/UCbG6_Q9ZRqqVT6YZOpcjDlQ
ブログ➡宇宙に入ったカマキリ(物理ブログ)
ココナラ➡物理の質問サポートサービス
コミュニティ➡製造業ブロガー