C言語で四捨五入,切り捨て,切り上げする標準ライブラリ関数と自作関数を教えて!
こういった悩みにお答えします.
本記事の信頼性
- リアルタイムシステムの研究歴12年.
- 東大教員の時に,英語でOS(Linuxカーネル)の授業.
- 2012年9月~2013年8月にアメリカのノースカロライナ大学チャペルヒル校(UNC)コンピュータサイエンス学部で客員研究員として勤務.C言語でリアルタイムLinuxの研究開発.
- プログラミング歴15年以上,習得している言語: C/C++,Python,Solidity/Vyper,Java,Ruby,Go,Rust,D,HTML/CSS/JS/PHP,MATLAB,Verse(UEFN), Assembler (x64,ARM).
- 東大教員の時に,C++言語で開発した「LLVMコンパイラの拡張」,C言語で開発した独自のリアルタイムOS「Mcube Kernel」をGitHubにオープンソースとして公開.
- 2020年1月~現在はアメリカのノースカロライナ州チャペルヒルにあるGuarantee Happiness LLCのCTOとしてECサイト開発やWeb/SNSマーケティングの業務.2022年6月~現在はアメリカのノースカロライナ州チャペルヒルにあるJapanese Tar Heel, Inc.のCEO兼CTO.
- 最近は自然言語処理AIとイーサリアムに関する有益な情報発信に従事.
- (AI全般を含む)自然言語処理AIの論文の日本語訳や,AIチャットボット(ChatGPT,Auto-GPT,Gemini(旧Bard)など)の記事を50本以上執筆.アメリカのサンフランシスコ(広義のシリコンバレー)の会社でプロンプトエンジニア・マネージャー・Quality Assurance(QA)の業務委託の経験あり.
- (スマートコントラクトのプログラミングを含む)イーサリアムや仮想通貨全般の記事を200本以上執筆.イギリスのロンドンの会社で仮想通貨の英語の記事を日本語に翻訳する業務委託の経験あり.
こういった私から学べます.
C言語を独学で習得することは難しいです.
私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.
私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!
独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!
目次
四捨五入,切り捨て,切り上げ
四捨五入とは,数値計算における端数処理の1つです.
ある桁までの値がほしい時は,その下の桁が4以下なら切り捨て,5以上なら切り上げます.
切り捨ては,その下の桁を0にします.
これに対して,切り上げは,その下の桁を0にするだけでなく,1つ上の桁を1加算します.
下表に数値を整数に変換する場合(小数点第1位)の四捨五入,切り捨て,切り上げの例をまとめました.
数値の例 | 四捨五入 | 切り捨て | 切り上げ |
---|---|---|---|
0.5 | 1 | 0 | 1 |
-2.6 | -3 | -3 | -2 |
C言語で四捨五入,切り捨て,切り上げする標準ライブラリ関数
C言語の四捨五入,切り捨て,切り上げする標準ライブラリ関数を紹介していきます.
round/roundf/roundl関数で四捨五入
1 2 3 |
double round(double x); float roundf(float x); long double roundl(long double x); |
round/roundf/roundl関数は,最も近い整数に丸める(2つの整数の中間の場合は0から遠い方に丸める)ように四捨五入した結果を返す関数です.
round/roundf/roundl関数の利用例は以下のコードです.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> #include <math.h> int main(void) { double d1 = 0.5; double d2 = -2.6; float f1 = 1.1; float f2 = -3.5; long double ld1 = 2.7; long double ld2 = -5.8; printf("round(%lf) = %lf\n", d1, round(d1)); printf("round(%lf) = %lf\n", d2, round(d2)); printf("roundf(%f) = %f\n", f1, roundf(f1)); printf("roundf(%f) = %f\n", f2, roundf(f2)); printf("roundl(%Lf) = %Lf\n", ld1, roundl(ld1)); printf("roundl(%Lf) = %Lf\n", ld2, roundl(ld2)); return 0; } |
実行結果は以下になります.
1 2 3 4 5 6 7 8 |
$ gcc round.c -lm $ a.out round(0.500000) = 1.000000 round(-2.600000) = -3.000000 roundf(1.100000) = 1.000000 roundf(-3.500000) = -4.000000 roundl(2.700000) = 3.000000 roundl(-5.800000) = -6.000000 |
floor/floorf/floorl関数で切り捨て
1 2 3 |
double floor(double x); float floorf(float x); long double floorl(long double x); |
floor/floorf/floorl関数は引数を越えない最大の整数を返す関数です.
floor/floorf/floorl関数の利用例は以下のコードです.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> #include <math.h> int main(void) { double d1 = 0.5; double d2 = -2.6; float f1 = 1.1; float f2 = -3.5; long double ld1 = 2.7; long double ld2 = -5.8; printf("floor(%lf) = %lf\n", d1, floor(d1)); printf("floor(%lf) = %lf\n", d2, floor(d2)); printf("floorf(%f) = %f\n", f1, floorf(f1)); printf("floorf(%f) = %f\n", f2, floorf(f2)); printf("floorl(%Lf) = %Lf\n", ld1, floorl(ld1)); printf("floorl(%Lf) = %Lf\n", ld2, floorl(ld2)); return 0; } |
実行結果は以下になります.
1 2 3 4 5 6 7 8 |
$ gcc floor.c -lm $ a.out floor(0.500000) = 0.000000 floor(-2.600000) = -3.000000 floorf(1.100000) = 1.000000 floorf(-3.500000) = -4.000000 floorl(2.700000) = 2.000000 floorl(-5.800000) = -6.000000 |
ceil/ceilf/ceill関数で切り上げ
1 2 3 |
double ceil(double x); float ceilf(float x); long double ceill(long double x); |
ceil/ceilf/ceill関数は,引き数を下回らない最小の整数を返す関数です.
ceil/ceilf/ceill関数の利用例は以下のコードです.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> #include <math.h> int main(void) { double d1 = 0.5; double d2 = -2.6; float f1 = 1.1; float f2 = -3.5; long double ld1 = 2.7; long double ld2 = -5.8; printf("ceil(%lf) = %lf\n", d1, ceil(d1)); printf("ceil(%lf) = %lf\n", d2, ceil(d2)); printf("ceilf(%f) = %f\n", f1, ceilf(f1)); printf("ceilf(%f) = %f\n", f2, ceilf(f2)); printf("ceill(%Lf) = %Lf\n", ld1, ceill(ld1)); printf("ceill(%Lf) = %Lf\n", ld2, ceill(ld2)); return 0; } |
実行結果は以下になります.
1 2 3 4 5 6 7 8 |
$ gcc ceil.c -lm $ a.out ceil(0.500000) = 1.000000 ceil(-2.600000) = -2.000000 ceilf(1.100000) = 2.000000 ceilf(-3.500000) = -3.000000 ceill(2.700000) = 3.000000 ceill(-5.800000) = -5.000000 |
C言語で四捨五入,切り捨て,切り上げする自作関数
C言語で四捨五入,切り捨て,切り上げする自作関数と,小数第n位を四捨五入,切り捨て,切り上げする自作関数を紹介します.
myround/myroundf/myroundl関数で四捨五入
myround/myroundf/myroundl関数で四捨五入するコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> double myround(double x) { return x > 0.0 ? (long)(x + 0.5) : (long)(x - 0.5); } float myroundf(float x) { return x > 0.0 ? (long)(x + 0.5) : (long)(x - 0.5); } long double myroundl(long double x) { return x > 0.0 ? (long)(x + 0.5) : (long)(x - 0.5); } int main(void) { double d1 = 0.5; double d2 = -2.6; float f1 = 1.1; float f2 = -3.5; long double ld1 = 2.7; long double ld2 = -5.8; printf("myround(%lf) = %lf\n", d1, myround(d1)); printf("myround(%lf) = %lf\n", d2, myround(d2)); printf("myroundf(%f) = %f\n", f1, myroundf(f1)); printf("myroundf(%f) = %f\n", f2, myroundf(f2)); printf("myroundl(%Lf) = %Lf\n", ld1, myroundl(ld1)); printf("myroundl(%Lf) = %Lf\n", ld2, myroundl(ld2)); return 0; } |
実行結果は以下になります.
1 2 3 4 5 6 7 8 |
$ gcc myround.c $ a.out myround(0.500000) = 1.000000 myround(-2.600000) = -3.000000 myroundf(1.100000) = 1.000000 myroundf(-3.500000) = -4.000000 myroundl(2.700000) = 3.000000 myroundl(-5.800000) = -6.000000 |
myround_n/myroundf_n/myroundl_n関数で小数第n位を四捨五入
myround_n/myroundf_n/myroundl_n関数で小数第n位を四捨五入します(第2引数に指定).
myround_n/myroundf_n/myroundl_n関数を利用するコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> long lpow(long x, long y) { long ret = 1; int i; for (i = 0; i < y; i++) { ret *= x; } return ret; } double myround(double x) { return x > 0.0 ? (long)(x + 0.5) : (long)(x - 0.5); } double myround_n(double x, int n) { double y; y = x * lpow(10, n - 1); y = myround(y); y /= lpow(10, n - 1); return y; } float myroundf(float x) { return x > 0.0 ? (long)(x + 0.5) : (long)(x - 0.5); } float myroundf_n(float x, int n) { float y; y = x * lpow(10, n - 1); y = myroundf(y); y /= lpow(10, n - 1); return y; } long double myroundl(long double x) { return x > 0.0 ? (long)(x + 0.5) : (long)(x - 0.5); } long double myroundl_n(long double x, int n) { long double y; y = x * lpow(10, n - 1); y = myroundf(y); y /= lpow(10, n - 1); return y; } int main(void) { double d1 = 0.55; double d2 = -2.66; float f1 = 1.11; float f2 = -3.55; long double ld1 = 2.77; long double ld2 = -5.88; int n = 2; printf("myround_n(%lf, %d) = %lf\n", d1, n, myround_n(d1, n)); printf("myround_n(%lf, %d) = %lf\n", d2, n, myround_n(d2, n)); printf("myroundf_n(%f, %d) = %f\n", f1, n, myroundf_n(f1, n)); printf("myroundf_n(%f, %d) = %f\n", f2, n, myroundf_n(f2, n)); printf("myroundl_n(%Lf, %d) = %Lf\n", ld1, n, myroundl_n(ld1, n)); printf("myroundl_n(%Lf, %d) = %Lf\n", ld2, n, myroundl_n(ld2, n)); return 0; } |
実行結果は以下になります.
1 2 3 4 5 6 7 8 |
$ gcc myround_n.c $ a.out myround_n(0.550000, 2) = 0.600000 myround_n(-2.660000, 2) = -2.700000 myroundf_n(1.110000, 2) = 1.100000 myroundf_n(-3.550000, 2) = -3.600000 myroundl_n(2.770000, 2) = 2.800000 myroundl_n(-5.880000, 2) = -5.900000 |
myfloor/myfloorf/myfloorl関数で切り捨て
myfloor/myfloorf/myfloorl関数で切り捨てるコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> double myfloor(double x) { if (x > 0.0) { return (long) x; } else { return x < (long) x ? (long)(x - 1.0) : (long) x; } } float myfloorf(float x) { if (x > 0.0) { return (long) x; } else { return x < (long) x ? (long)(x - 1.0) : (long) x; } } long double myfloorl(long double x) { if (x > 0.0) { return (long) x; } else { return x < (long) x ? (long)(x - 1.0) : (long) x; } } int main(void) { double d1 = 0.5; double d2 = -2.6; float f1 = 1.1; float f2 = -3.5; long double ld1 = 2.7; long double ld2 = -5.8; printf("myfloor(%lf) = %lf\n", d1, myfloor(d1)); printf("myfloor(%lf) = %lf\n", d2, myfloor(d2)); printf("myfloorf(%f) = %f\n", f1, myfloorf(f1)); printf("myfloorf(%f) = %f\n", f2, myfloorf(f2)); printf("myfloorl(%Lf) = %Lf\n", ld1, myfloorl(ld1)); printf("myfloorl(%Lf) = %Lf\n", ld2, myfloorl(ld2)); return 0; } |
実行結果は以下になります.
1 2 3 4 5 6 7 8 |
$ gcc myfloor.c $ a.out myfloor(0.500000) = 0.000000 myfloor(-2.600000) = -3.000000 myfloorf(1.100000) = 1.000000 myfloorf(-3.500000) = -4.000000 myfloorl(2.700000) = 2.000000 myfloorl(-5.800000) = -6.000000 |
myfloor_n/myfloorf_n/myfloorl_n関数で小数第n位を切り捨て
myfloor_n/myfloorf_n/myfloorl_n関数で小数第n位を四捨五入します(第2引数に指定).
myfloor_n/myfloorf_n/myfloorl_n関数を利用するコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> long lpow(long x, long y) { long ret = 1; int i; for (i = 0; i < y; i++) { ret *= x; } return ret; } double myfloor(double x) { if (x > 0.0) { return (long) x; } else { return x < (long) x ? (long)(x - 1.0) : (long) x; } } double myfloor_n(double x, int n) { double y; y = x * lpow(10, n - 1); y = myfloor(y); y /= lpow(10, n - 1); return y; } float myfloorf(float x) { if (x > 0.0) { return (long) x; } else { return x < (long) x ? (long)(x - 1.0) : (long) x; } } float myfloorf_n(float x, int n) { float y; y = x * lpow(10, n - 1); y = myfloorf(y); y /= lpow(10, n - 1); return y; } long double myfloorl(long double x) { if (x > 0.0) { return (long) x; } else { return x < (long) x ? (long)(x - 1.0) : (long) x; } } long double myfloorl_n(long double x, int n) { long double y; y = x * lpow(10, n - 1); y = myfloorl(y); y /= lpow(10, n - 1); return y; } int main(void) { double d1 = 0.55; double d2 = -2.66; float f1 = 1.11; float f2 = -3.55; long double ld1 = 2.77; long double ld2 = -5.88; int n = 2; printf("myfloor_n(%lf, %d) = %lf\n", d1, n, myfloor_n(d1, n)); printf("myfloor_n(%lf, %d) = %lf\n", d2, n, myfloor_n(d2, n)); printf("myfloorf_n(%f, %d) = %f\n", f1, n, myfloorf_n(f1, n)); printf("myfloorf_n(%f, %d) = %f\n", f2, n, myfloorf_n(f2, n)); printf("myfloorl_n(%Lf, %d) = %Lf\n", ld1, n, myfloorl_n(ld1, n)); printf("myfloorl_n(%Lf, %d) = %Lf\n", ld2, n, myfloorl_n(ld2, n)); return 0; } |
実行結果は以下になります.
1 2 3 4 5 6 7 8 |
$ gcc myfloor_n.c $ a.out myfloor_n(0.550000, 2) = 0.500000 myfloor_n(-2.660000, 2) = -2.700000 myfloorf_n(1.110000, 2) = 1.100000 myfloorf_n(-3.550000, 2) = -3.600000 myfloorl_n(2.770000, 2) = 2.700000 myfloorl_n(-5.880000, 2) = -5.900000 |
myceil/myceilf/myceill関数で切り上げ
myceil/myceilf/myceill関数で切り上げるコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> double myceil(double x) { return x > (long) x ? (long)(x + 1.0) : (long) x; } float myceilf(float x) { return x > (long) x ? (long)(x + 1.0) : (long) x; } long double myceill(long double x) { return x > (long) x ? (long)(x + 1.0) : (long) x; } int main(void) { double d1 = 0.5; double d2 = -2.6; float f1 = 1.1; float f2 = -3.5; long double ld1 = 2.7; long double ld2 = -5.8; printf("myceil(%lf) = %lf\n", d1, myceil(d1)); printf("myceil(%lf) = %lf\n", d2, myceil(d2)); printf("myceilf(%f) = %f\n", f1, myceilf(f1)); printf("myceilf(%f) = %f\n", f2, myceilf(f2)); printf("myceill(%Lf) = %Lf\n", ld1, myceill(ld1)); printf("myceill(%Lf) = %Lf\n", ld2, myceill(ld2)); return 0; } |
実行結果は以下になります.
1 2 3 4 5 6 7 8 |
$ gcc myceil.c $ a.out myceil(0.500000) = 1.000000 myceil(-2.600000) = -2.000000 myceilf(1.100000) = 2.000000 myceilf(-3.500000) = -3.000000 myceill(2.700000) = 3.000000 myceill(-5.800000) = -5.000000 |
myceil_n/myceilf_n/myceill_n関数で小数第n位を切り上げ
myceil_n/myceilf_n/myceill_n関数で小数第n位を切り上げます(第2引数に指定).
myceil_n/myceilf_n/myceill_n関数で小数第n位を切り上げるコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> long lpow(long x, long y) { long ret = 1; int i; for (i = 0; i < y; i++) { ret *= x; } return ret; } double myceil(double x) { return x > (long) x ? (long)(x + 1.0) : (long) x; } double myceil_n(double x, int n) { double y; y = x * lpow(10, n - 1); y = myceil(y); y /= lpow(10, n - 1); return y; } float myceilf(float x) { return x > (long) x ? (long)(x + 1.0) : (long) x; } float myceilf_n(float x, int n) { float y; y = x * lpow(10, n - 1); y = myceilf(y); y /= lpow(10, n - 1); return y; } long double myceill(long double x) { return x > (long) x ? (long)(x + 1.0) : (long) x; } long double myceill_n(long double x, int n) { long double y; y = x * lpow(10, n - 1); y = myceill(y); y /= lpow(10, n - 1); return y; } int main(void) { double d1 = 0.55; double d2 = -2.66; float f1 = 1.11; float f2 = -3.55; long double ld1 = 2.77; long double ld2 = -5.88; int n = 2; printf("myceil_n(%lf, %d) = %lf\n", d1, n, myceil_n(d1, n)); printf("myceil_n(%lf, %d) = %lf\n", d2, n, myceil_n(d2, n)); printf("myceilf_n(%f, %d) = %f\n", f1, n, myceilf_n(f1, n)); printf("myceilf_n(%f, %d) = %f\n", f2, n, myceilf_n(f2, n)); printf("myceill_n(%Lf, %d) = %Lf\n", ld1, n, myceill_n(ld1, n)); printf("myceill_n(%Lf, %d) = %Lf\n", ld2, n, myceill_n(ld2, n)); return 0; } |
実行結果は以下になります.
1 2 3 4 5 6 7 8 |
$ gcc myceil_n.c $ a.out myceil_n(0.550000, 2) = 0.600000 myceil_n(-2.660000, 2) = -2.600000 myceilf_n(1.110000, 2) = 1.200000 myceilf_n(-3.550000, 2) = -3.500000 myceill_n(2.770000, 2) = 2.800000 myceill_n(-5.880000, 2) = -5.800000 |
まとめ
C言語で四捨五入,切り捨て,切り上げする標準ライブラリ関数と自作関数,小数第n位を四捨五入,切り捨て,切り上げする自作関数を紹介しました.
四捨五入,切り捨て,切り上げするコードを書きたい時の参考にして下さい.
round関数以外で整数に丸める関数を知りたいあなたはこちらからどうぞ.
C言語を独学で習得することは難しいです.
私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.
私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!
独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!