1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 /** 6 * Number theory. 7 * 8 * Copyright: Eugene Wissner 2017-2020. 9 * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, 10 * Mozilla Public License, v. 2.0). 11 * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) 12 * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/math/nbtheory.d, 13 * tanya/math/nbtheory.d) 14 */ 15 module tanya.math.nbtheory; 16 17 import tanya.meta.trait; 18 import tanya.meta.transform; 19 20 import core.math : fabs; 21 import std.math : log; 22 23 /** 24 * Calculates the absolute value of a number. 25 * 26 * Params: 27 * T = Argument type. 28 * x = Argument. 29 * 30 * Returns: Absolute value of $(D_PARAM x). 31 */ 32 Unqual!T abs(T)(T x) 33 if (isIntegral!T) 34 { 35 static if (isSigned!T) 36 { 37 return x >= 0 ? x : -x; 38 } 39 else 40 { 41 return x; 42 } 43 } 44 45 /// 46 @nogc nothrow pure @safe unittest 47 { 48 int i = -1; 49 assert(i.abs == 1); 50 static assert(is(typeof(i.abs) == int)); 51 52 uint u = 1; 53 assert(u.abs == 1); 54 static assert(is(typeof(u.abs) == uint)); 55 } 56 57 /// ditto 58 Unqual!T abs(T)(T x) 59 if (isFloatingPoint!T) 60 { 61 return fabs(x); 62 } 63 64 /// 65 @nogc nothrow pure @safe unittest 66 { 67 float f = -1.64; 68 assert(f.abs == 1.64F); 69 static assert(is(typeof(f.abs) == float)); 70 71 double d = -1.64; 72 assert(d.abs == 1.64); 73 static assert(is(typeof(d.abs) == double)); 74 75 real r = -1.64; 76 assert(r.abs == 1.64L); 77 static assert(is(typeof(r.abs) == real)); 78 } 79 80 /** 81 * Calculates natural logarithm of $(D_PARAM x). 82 * 83 * Params: 84 * T = Argument type. 85 * x = Argument. 86 * 87 * Returns: Natural logarithm of $(D_PARAM x). 88 */ 89 Unqual!T ln(T)(T x) 90 if (isFloatingPoint!T) 91 { 92 return log(x); 93 } 94 95 /// 96 @nogc nothrow pure @safe unittest 97 { 98 import tanya.math; 99 100 assert(isNaN(ln(-7.389f))); 101 assert(isNaN(ln(-7.389))); 102 assert(isNaN(ln(-7.389L))); 103 104 assert(isInfinity(ln(0.0f))); 105 assert(isInfinity(ln(0.0))); 106 assert(isInfinity(ln(0.0L))); 107 108 assert(ln(1.0f) == 0.0f); 109 assert(ln(1.0) == 0.0); 110 assert(ln(1.0L) == 0.0L); 111 }