はじめに
正値の範囲において、整数の除算を行った結果をFloor・Ceilしたい時は、下記の記事の簡単な式で算出可能になります。
本稿では、正値・負値全ての範囲に拡大させた場合を考えてみます。
整数の除算時にFloor・Ceil (正値・負値全ての範囲版)
整数の除算「整数 / 整数」は、正負の間で特性が変わるので(下記の記事: 正の範囲ではFloorの値、負の範囲ではCeilの値と同じ)、正側と負側で算出式を切り替える必要があることが分かります。
下記の算出式を、正側と負側で正負を考慮しながら切り替えて、整数の除算を行った結果をFloor・Ceilする関数を作成すると、
正値の範囲において、整数の除算を行った結果をFloor・Ceilしたい時、
- Floorは、c = a / b
- Ceilは、c = (a - 1) / b + 1
整数の除算を行った結果をFloorする時は、
// 整数の除算時にFloorした値を返す floor(a / b)
// 整数除算でFloorの値を作る 正値・負値の双方の範囲で利用可
public static int IntFloor(int a, int b) {
return a >= 0 ?
a / b : // 正値の整数除算はfloor値となる
(a + 1) / b - 1; // 負値の整数除算をfloor値となるように+1,/,-1でシフト
}
整数の除算を行った結果をCeilする時は、
// 整数の除算時にCeilした値を返す ceil(a / b)
// 整数除算でCeilの値を作る 正値・負値の双方の範囲で利用可
public static int IntCeil(int a, int b) {
return a >= 1 ?
(a - 1) / b + 1 : // 整数除算をceil値となるように-1,/,+1でシフト
a / b; // 負値の整数除算はゼロ側へfloor値となる
}
テストコード
Program 2302-4 整数除算 負値を含む.cs
using System;
namespace ConsoleApp1 {
class Program {
static void Main(string[] args) {
/* 結果:
▼整数除算でFloorの値を作る 正値・負値の双方の範囲で利用可
int: 7 / 3 = 2
int: 6 / 3 = 2
int: 5 / 3 = 1
int: 4 / 3 = 1
int: 3 / 3 = 1
int: 2 / 3 = 0
int: 1 / 3 = 0
int: 0 / 3 = 0
int: -1 / 3 = -1
int: -2 / 3 = -1
int: -3 / 3 = -1
int: -4 / 3 = -2
int: -5 / 3 = -2
int: -6 / 3 = -2
int: -7 / 3 = -3
▼整数除算でCeilの値を作る 正値・負値の双方の範囲で利用可
int: 7 / 3 = 3
int: 6 / 3 = 2
int: 5 / 3 = 2
int: 4 / 3 = 2
int: 3 / 3 = 1
int: 2 / 3 = 1
int: 1 / 3 = 1
int: 0 / 3 = 0
int: -1 / 3 = 0
int: -2 / 3 = 0
int: -3 / 3 = -1
int: -4 / 3 = -1
int: -5 / 3 = -1
int: -6 / 3 = -2
int: -7 / 3 = -2
*/
Action<string> WL = Console.WriteLine; // 短縮
WL("▼整数除算でFloorの値を作る 正値・負値の双方の範囲で利用可");
var a = 7;
var b = 3;
for (; a >= -7; a--) {
var c = IntDiv.IntFloor(a, b);
WL($"int: {a,2} / {b} = {c,2}");
}
WL("");
WL("▼整数除算でCeilの値を作る 正値・負値の双方の範囲で利用可");
a = 7;
b = 3;
for (; a >= -7; a--) {
var c = IntDiv.IntCeil(a, b);
WL($"int: {a,2} / {b} = {c,2}");
}
}
}
// 整数除算でFloor/Ceilの値を作ったもの
public static class IntDiv {
// 整数の除算時にFloorした値を返す floor(a / b)
// 整数除算でFloorの値を作る 正値・負値の双方の範囲で利用可
public static int IntFloor(this int a, int b) {
return a >= 0 ?
a / b : // 正値の整数除算はfloor値となる
(a + 1) / b - 1; // 負値の整数除算をfloor値となるように+1,/,-1でシフト
}
// 整数の除算時にCeilした値を返す ceil(a / b)
// 整数除算でCeilの値を作る 正値・負値の双方の範囲で利用可
public static int IntCeil(this int a, int b) {
return a >= 1 ?
(a - 1) / b + 1 : // 整数除算をceil値となるように-1,/,+1でシフト
a / b; // 負値の整数除算はゼロ側へfloor値となる
}
}
}
環境
Microsoft Visual Studio Community 2019 Version 16.11.22
VisualStudio.16.Release
Microsoft .NET Framework
Version 4.8.04084