Google OR-Tools: ortools/base/mathutil.h Source File

30 public:

31

32

33

34

35

36

37

38 template <typename IntegralType>

39 static IntegralType CeilOfRatio(IntegralType numerator,

40 IntegralType denominator) {

41 DCHECK_NE(0, denominator);

42 const IntegralType rounded_toward_zero = numerator / denominator;

43 const IntegralType intermediate_product = rounded_toward_zero * denominator;

44 const bool needs_adjustment =

45 (rounded_toward_zero >= 0) &&

46 ((denominator > 0 && numerator > intermediate_product) ||

47 (denominator < 0 && numerator < intermediate_product));

48 const IntegralType adjustment = static_cast<IntegralType>(needs_adjustment);

49 const IntegralType ceil_of_ratio = rounded_toward_zero + adjustment;

50 return ceil_of_ratio;

51 }

52 template <typename IntegralType>

53 static IntegralType FloorOfRatio(IntegralType numerator,

54 IntegralType denominator) {

55 DCHECK_NE(0, denominator);

56 const IntegralType rounded_toward_zero = numerator / denominator;

57 const IntegralType intermediate_product = rounded_toward_zero * denominator;

58 const bool needs_adjustment =

59 (rounded_toward_zero <= 0) &&

60 ((denominator > 0 && numerator < intermediate_product) ||

61 (denominator < 0 && numerator > intermediate_product));

62 const IntegralType adjustment = static_cast<IntegralType>(needs_adjustment);

63 const IntegralType floor_of_ratio = rounded_toward_zero - adjustment;

64 return floor_of_ratio;

65 }

66

67

68 static unsigned int GCD(unsigned int x, unsigned int y) {

69 while (y != 0) {

70 unsigned int r = x % y;

71 x = y;

72 y = r;

73 }

74 return x;

75 }

76

77

78

80 if (a > b) {

82 } else if (a < b) {

84 } else {

85 return a;

86 }

87 }

88

89

90

91

92

93

94 template <typename T>

95 static T Abs(const T x) {

96 return x > 0 ? x : -x;

97 }

98

99

100 template <typename T>

104

105

106

107 static int64_t GCD64(int64_t x, int64_t y) {

108 DCHECK_GE(x, 0);

109 DCHECK_GE(y, 0);

110 while (y != 0) {

111 int64_t r = x % y;

112 x = y;

113 y = r;

114 }

115 return x;

116 }

117

118 template <typename T>

120 return pow(base, exp);

121 }

122

123 template <class IntOut, class FloatIn>

124 static IntOut Round(FloatIn x) {

125

126

127

128

129 if (x > -0.5 && x < 0.5) {

130

131

132

133 return static_cast<IntOut>(0);

134 }

135 return static_cast<IntOut>(x < 0 ? (x - 0.5) : (x + 0.5));

136 }

137

138

139

140

141

142 template <typename IntType>

143 static IntType RoundUpTo(IntType input_value, IntType rounding_value) {

144 static_assert(std::numeric_limits<IntType>::is_integer,

145 "RoundUpTo() operation type is not integer");

146 DCHECK_GE(input_value, 0);

147 DCHECK_GT(rounding_value, 0);

148 const IntType remainder = input_value % rounding_value;

149 return (remainder == 0) ? input_value

150 : (input_value - remainder + rounding_value);

151 }

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173 template <class IntOut, class FloatIn>

175

176 if (std::isnan(x)) {

177 return 0;

178 }

179

180

181 if (!std::numeric_limits<IntOut>::is_signed && x < 0) {

182 return 0;

183 }

184

185

186 if (std::isinf(x)) {

187 return x < 0 ? std::numeric_limits<IntOut>::lowest()

188 : std::numeric_limits<IntOut>::max();

189 }

190

191

192

193

194 int exp = 0;

195 std::frexp(x, &exp);

196

197

198

199

200

201

202 if (exp <= std::numeric_limits<IntOut>::digits) {

203 return x;

204 }

205

206

207 return x < 0 ? std::numeric_limits<IntOut>::lowest()

208 : std::numeric_limits<IntOut>::max();

209 }

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224 template <class IntOut, class FloatIn>

225 static IntOut SafeRound(FloatIn x) {

226 if (std::isnan(x)) {

227 return 0;

228 } else {

230 }

231 }

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

258

259

260

261 static double Stirling(double n);

262

263

264

265

266

267

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310 template <typename T>

311 static bool AlmostEquals(const T x, const T y) {

312 static_assert(std::is_arithmetic_v<T>);

313 if constexpr (std::numeric_limits<T>::is_integer) {

314 return x == y;

315 } else {

316 if (x == y)

317 return true;

318

319 if (std::abs(x) <= 1e-6 && std::abs(y) <= 1e-6) return true;

320 if (std::abs(x - y) <= 1e-6) return true;

321 return std::abs(x - y) / std::max(std::abs(x), std::abs(y)) <= 1e-6;

322 }

323 }

324};

325}

326

327#endif