1 /++ 2 Functions and templates that do numeric calculations or other manipulation, 3 in some way or another. 4 5 Example: 6 --- 7 immutable width = 15.getMultipleOf(4); 8 assert(width == 16); 9 immutable width2 = 16.getMultipleOf(4, alwaysOneUp: true); 10 assert(width2 == 20); 11 --- 12 13 Copyright: [JR](https://github.com/zorael) 14 License: [Boost Software License 1.0](https://www.boost.org/users/license.html) 15 16 Authors: 17 [JR](https://github.com/zorael) 18 +/ 19 module lu.numeric; 20 21 private: 22 23 public: 24 25 @safe: 26 27 28 // getMultipleOf 29 /++ 30 Given a number, calculate the largest multiple of `n` needed to reach that number. 31 32 It rounds up, and if supplied `alwaysOneUp: true` it will always overshoot. 33 This is good for when calculating format pattern widths. 34 35 Example: 36 --- 37 immutable width = 15.getMultipleOf(4); 38 assert(width == 16); 39 immutable width2 = 16.getMultipleOf(4, alwaysOneUp: true); 40 assert(width2 == 20); 41 --- 42 43 Params: 44 num = Number to reach. 45 n = Base value to find a multiplier for. 46 alwaysOneUp = Whether or not to always overshoot. 47 48 Returns: 49 The multiple of `n` that reaches and possibly overshoots `num`. 50 +/ 51 auto getMultipleOf(Number) 52 (const Number num, 53 const int n, 54 const bool alwaysOneUp = false) pure nothrow @nogc 55 in ((n > 0), "Cannot get multiple of 0 or negatives") 56 in ((num >= 0), "Cannot get multiples for a negative number") 57 { 58 if (num == 0) return 0; 59 60 if (num == n) 61 { 62 return alwaysOneUp ? (n + 1) : n; 63 } 64 65 immutable frac = (num / double(n)); 66 immutable floor_ = cast(uint)frac; 67 immutable mod = alwaysOneUp ? (floor_ + 1) : ((floor_ == frac) ? floor_ : (floor_ + 1)); 68 69 return (mod * n); 70 } 71 72 /// 73 unittest 74 { 75 import std.conv : text; 76 77 immutable n1 = 15.getMultipleOf(4); 78 assert((n1 == 16), n1.text); 79 80 immutable n2 = 16.getMultipleOf(4, alwaysOneUp: true); 81 assert((n2 == 20), n2.text); 82 83 immutable n3 = 16.getMultipleOf(4); 84 assert((n3 == 16), n3.text); 85 immutable n4 = 0.getMultipleOf(5); 86 assert((n4 == 0), n4.text); 87 88 immutable n5 = 1.getMultipleOf(1); 89 assert((n5 == 1), n5.text); 90 91 immutable n6 = 1.getMultipleOf(1, alwaysOneUp: true); 92 assert((n6 == 2), n6.text); 93 94 immutable n7 = 5.getMultipleOf(5, alwaysOneUp: true); 95 assert((n7 == 6), n7.text); 96 97 immutable n8 = 5L.getMultipleOf(5L, alwaysOneUp: true); 98 assert((n8 == 6L), n8.text); 99 100 immutable n9 = 5UL.getMultipleOf(5UL, alwaysOneUp: false); 101 assert((n9 == 5UL), n9.text); 102 103 immutable n10 = (5.0).getMultipleOf(5UL, alwaysOneUp: true); 104 assert((n10 == (6.0)), n10.text); 105 }