authorgravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2019-05-01 18:15:57+12:00
committergravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2019-05-01 18:37:46+12:00
log89d71a960b0f90335fded84a449a84806bb6f661
treeefbb720dbdd17ad782233c958f11d2f584d662c4
parentf94964cd057ace39caa05c10d9626ac6a4beb23b

std.math: Add documentation for all functions and algorithm sources


64 files changed, 592 insertions(+), 197 deletions(-)

std/math/acos.zig+8-2
......@@ -1,11 +1,17 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - acos(x) = nan if x < -1 or x > 1
4// https://git.musl-libc.org/cgit/musl/tree/src/math/acosf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/acos.c
46
57const std = @import("../std.zig");
68const math = std.math;
79const expect = std.testing.expect;
810
11/// Returns the arc-cosine of x.
12///
13/// Special cases:
14/// - acos(x) = nan if x < -1 or x > 1
915pub fn acos(x: var) @typeOf(x) {
1016 const T = @typeOf(x);
1117 return switch (T) {
std/math/acosh.zig+9-3
......@@ -1,13 +1,19 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - acosh(x) = snan if x < 1
4// - acosh(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/acoshf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/acosh.c
56
67const builtin = @import("builtin");
78const std = @import("../std.zig");
89const math = std.math;
910const expect = std.testing.expect;
1011
12/// Returns the hyperbolic arc-cosine of x.
13///
14/// Special cases:
15/// - acosh(x) = snan if x < 1
16/// - acosh(nan) = nan
1117pub fn acosh(x: var) @typeOf(x) {
1218 const T = @typeOf(x);
1319 return switch (T) {
std/math/asin.zig+9-3
......@@ -1,12 +1,18 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - asin(+-0) = +-0
4// - asin(x) = nan if x < -1 or x > 1
4// https://git.musl-libc.org/cgit/musl/tree/src/math/asinf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/asin.c
56
67const std = @import("../std.zig");
78const math = std.math;
89const expect = std.testing.expect;
910
11/// Returns the arc-sin of x.
12///
13/// Special Cases:
14/// - asin(+-0) = +-0
15/// - asin(x) = nan if x < -1 or x > 1
1016pub fn asin(x: var) @typeOf(x) {
1117 const T = @typeOf(x);
1218 return switch (T) {
std/math/asinh.zig+10-4
......@@ -1,14 +1,20 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - asinh(+-0) = +-0
4// - asinh(+-inf) = +-inf
5// - asinh(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/asinhf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/asinh.c
66
77const std = @import("../std.zig");
88const math = std.math;
99const expect = std.testing.expect;
1010const maxInt = std.math.maxInt;
1111
12/// Returns the hyperbolic arc-sin of x.
13///
14/// Special Cases:
15/// - asinh(+-0) = +-0
16/// - asinh(+-inf) = +-inf
17/// - asinh(nan) = nan
1218pub fn asinh(x: var) @typeOf(x) {
1319 const T = @typeOf(x);
1420 return switch (T) {
std/math/atan.zig+9-3
......@@ -1,12 +1,18 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - atan(+-0) = +-0
4// - atan(+-inf) = +-pi/2
4// https://git.musl-libc.org/cgit/musl/tree/src/math/atanf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/atan.c
56
67const std = @import("../std.zig");
78const math = std.math;
89const expect = std.testing.expect;
910
11/// Returns the arc-tangent of x.
12///
13/// Special Cases:
14/// - atan(+-0) = +-0
15/// - atan(+-inf) = +-pi/2
1016pub fn atan(x: var) @typeOf(x) {
1117 const T = @typeOf(x);
1218 return switch (T) {
std/math/atan2.zig+24-18
......@@ -1,27 +1,33 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// atan2(y, nan) = nan
4// atan2(nan, x) = nan
5// atan2(+0, x>=0) = +0
6// atan2(-0, x>=0) = -0
7// atan2(+0, x<=-0) = +pi
8// atan2(-0, x<=-0) = -pi
9// atan2(y>0, 0) = +pi/2
10// atan2(y<0, 0) = -pi/2
11// atan2(+inf, +inf) = +pi/4
12// atan2(-inf, +inf) = -pi/4
13// atan2(+inf, -inf) = 3pi/4
14// atan2(-inf, -inf) = -3pi/4
15// atan2(y, +inf) = 0
16// atan2(y>0, -inf) = +pi
17// atan2(y<0, -inf) = -pi
18// atan2(+inf, x) = +pi/2
19// atan2(-inf, x) = -pi/2
4// https://git.musl-libc.org/cgit/musl/tree/src/math/atan2f.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/atan2.c
206
217const std = @import("../std.zig");
228const math = std.math;
239const expect = std.testing.expect;
2410
11/// Returns the arc-tangent of y/x.
12///
13/// Special Cases:
14/// - atan2(y, nan) = nan
15/// - atan2(nan, x) = nan
16/// - atan2(+0, x>=0) = +0
17/// - atan2(-0, x>=0) = -0
18/// - atan2(+0, x<=-0) = +pi
19/// - atan2(-0, x<=-0) = -pi
20/// - atan2(y>0, 0) = +pi/2
21/// - atan2(y<0, 0) = -pi/2
22/// - atan2(+inf, +inf) = +pi/4
23/// - atan2(-inf, +inf) = -pi/4
24/// - atan2(+inf, -inf) = 3pi/4
25/// - atan2(-inf, -inf) = -3pi/4
26/// - atan2(y, +inf) = 0
27/// - atan2(y>0, -inf) = +pi
28/// - atan2(y<0, -inf) = -pi
29/// - atan2(+inf, x) = +pi/2
30/// - atan2(-inf, x) = -pi/2
2531pub fn atan2(comptime T: type, y: T, x: T) T {
2632 return switch (T) {
2733 f32 => atan2_32(y, x),
std/math/atanh.zig+10-4
......@@ -1,14 +1,20 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - atanh(+-1) = +-inf with signal
4// - atanh(x) = nan if |x| > 1 with signal
5// - atanh(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/atanhf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/atanh.c
66
77const std = @import("../std.zig");
88const math = std.math;
99const expect = std.testing.expect;
1010const maxInt = std.math.maxInt;
1111
12/// Returns the hyperbolic arc-tangent of x.
13///
14/// Special Cases:
15/// - atanh(+-1) = +-inf with signal
16/// - atanh(x) = nan if |x| > 1 with signal
17/// - atanh(nan) = nan
1218pub fn atanh(x: var) @typeOf(x) {
1319 const T = @typeOf(x);
1420 return switch (T) {
std/math/big/int.zig+112-45
......@@ -21,32 +21,49 @@ comptime {
2121 debug.assert(Limb.is_signed == false);
2222}
2323
24/// An arbitrary-precision big integer.
25///
26/// Memory is allocated by an Int as needed to ensure operations never overflow. The range of an
27/// Int is bounded only by available memory.
2428pub const Int = struct {
2529 const sign_bit: usize = 1 << (usize.bit_count - 1);
2630
31 /// Default number of limbs to allocate on creation of an Int.
32 pub const default_capacity = 4;
33
34 /// Allocator used by the Int when requesting memory.
2735 allocator: ?*Allocator,
28 // - little-endian ordered
29 // - len >= 1 always
30 // - zero value -> len == 1 with limbs[0] == 0
36
37 /// Raw digits. These are:
38 ///
39 /// * Little-endian ordered
40 /// * limbs.len >= 1
41 /// * Zero is represent as Int.len() == 1 with limbs[0] == 0.
42 ///
43 /// Accessing limbs directly should be avoided.
3144 limbs: []Limb,
32 // High bit is the sign bit. 1 is negative, 0 positive.
33 // Remaining bits indicate the number of used limbs.
34 //
35 // If Zig gets smarter about packing data, this can be rewritten as a u1 and usize - 1 field.
36 metadata: usize,
3745
38 const default_capacity = 4;
46 /// High bit is the sign bit. If set, Int is negative, else Int is positive.
47 /// The remaining bits represent the number of limbs used by Int.
48 metadata: usize,
3949
50 /// Creates a new Int. default_capacity limbs will be allocated immediately.
51 /// Int will be zeroed.
4052 pub fn init(allocator: *Allocator) !Int {
4153 return try Int.initCapacity(allocator, default_capacity);
4254 }
4355
56 /// Creates a new Int. Int will be set to `value`.
57 ///
58 /// This is identical to an `init`, followed by a `set`.
4459 pub fn initSet(allocator: *Allocator, value: var) !Int {
4560 var s = try Int.init(allocator);
4661 try s.set(value);
4762 return s;
4863 }
4964
65 /// Creates a new Int with a specific capacity. If capacity < default_capacity then the
66 /// default capacity will be used instead.
5067 pub fn initCapacity(allocator: *Allocator, capacity: usize) !Int {
5168 return Int{
5269 .allocator = allocator,
......@@ -59,14 +76,17 @@ pub const Int = struct {
5976 };
6077 }
6178
79 /// Returns the number of limbs currently in use.
6280 pub fn len(self: Int) usize {
6381 return self.metadata & ~sign_bit;
6482 }
6583
84 /// Returns whether an Int is positive.
6685 pub fn isPositive(self: Int) bool {
6786 return self.metadata & sign_bit == 0;
6887 }
6988
89 /// Sets the sign of an Int.
7090 pub fn setSign(self: *Int, positive: bool) void {
7191 if (positive) {
7292 self.metadata &= ~sign_bit;
......@@ -75,14 +95,17 @@ pub const Int = struct {
7595 }
7696 }
7797
98 /// Sets the length of an Int.
99 ///
100 /// If setLen is used, then the Int must be normalized to suit.
78101 pub fn setLen(self: *Int, new_len: usize) void {
79102 self.metadata &= sign_bit;
80103 self.metadata |= new_len;
81104 }
82105
83 // Initialize an Int directly from a fixed set of limb values. This is considered read-only
84 // and cannot be used as a receiver argument to any functions. If this tries to allocate
85 // at any point a panic will occur due to the null allocator.
106 /// Returns an Int backed by a fixed set of limb values.
107 /// This is read-only and cannot be used as a result argument. If the Int tries to allocate
108 /// memory a runtime panic will occur.
86109 pub fn initFixed(limbs: []const Limb) Int {
87110 var self = Int{
88111 .allocator = null,
......@@ -95,6 +118,9 @@ pub const Int = struct {
95118 return self;
96119 }
97120
121 /// Ensures an Int has enough space allocated for capacity limbs. If the Int does not have
122 /// sufficient capacity, the exact amount will be allocated. This occurs even if the requested
123 /// capacity is only greater than the current capacity by one limb.
98124 pub fn ensureCapacity(self: *Int, capacity: usize) !void {
99125 self.assertWritable();
100126 if (capacity <= self.limbs.len) {
......@@ -110,12 +136,15 @@ pub const Int = struct {
110136 }
111137 }
112138
139 /// Frees all memory associated with an Int.
113140 pub fn deinit(self: *Int) void {
114141 self.assertWritable();
115142 self.allocator.?.free(self.limbs);
116143 self.* = undefined;
117144 }
118145
146 /// Clones an Int and returns a new Int with the same value. The new Int is a deep copy and
147 /// can be modified separately from the original.
119148 pub fn clone(other: Int) !Int {
120149 other.assertWritable();
121150 return Int{
......@@ -129,6 +158,8 @@ pub const Int = struct {
129158 };
130159 }
131160
161 /// Copies the value of an Int to an existing Int so that they both have the same value.
162 /// Extra memory will be allocated if the receiver does not have enough capacity.
132163 pub fn copy(self: *Int, other: Int) !void {
133164 self.assertWritable();
134165 if (self.limbs.ptr == other.limbs.ptr) {
......@@ -140,6 +171,8 @@ pub const Int = struct {
140171 self.metadata = other.metadata;
141172 }
142173
174 /// Efficiently swap an Int with another. This swaps the limb pointers and a full copy is not
175 /// performed. The address of the limbs field will not be the same after this function.
143176 pub fn swap(self: *Int, other: *Int) void {
144177 self.assertWritable();
145178 mem.swap(Int, self, other);
......@@ -152,35 +185,39 @@ pub const Int = struct {
152185 debug.warn("\n");
153186 }
154187
188 /// Negate the sign of an Int.
155189 pub fn negate(self: *Int) void {
156190 self.metadata ^= sign_bit;
157191 }
158192
193 /// Make an Int positive.
159194 pub fn abs(self: *Int) void {
160195 self.metadata &= ~sign_bit;
161196 }
162197
198 /// Returns true if an Int is odd.
163199 pub fn isOdd(self: Int) bool {
164200 return self.limbs[0] & 1 != 0;
165201 }
166202
203 /// Returns true if an Int is even.
167204 pub fn isEven(self: Int) bool {
168205 return !self.isOdd();
169206 }
170207
171 // Returns the number of bits required to represent the absolute value of self.
208 /// Returns the number of bits required to represent the absolute value an Int.
172209 fn bitCountAbs(self: Int) usize {
173210 return (self.len() - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len() - 1]));
174211 }
175212
176 // Returns the number of bits required to represent the integer in twos-complement form.
177 //
178 // If the integer is negative the value returned is the number of bits needed by a signed
179 // integer to represent the value. If positive the value is the number of bits for an
180 // unsigned integer. Any unsigned integer will fit in the signed integer with bitcount
181 // one greater than the returned value.
182 //
183 // e.g. -127 returns 8 as it will fit in an i8. 127 returns 7 since it fits in a u7.
213 /// Returns the number of bits required to represent the integer in twos-complement form.
214 ///
215 /// If the integer is negative the value returned is the number of bits needed by a signed
216 /// integer to represent the value. If positive the value is the number of bits for an
217 /// unsigned integer. Any unsigned integer will fit in the signed integer with bitcount
218 /// one greater than the returned value.
219 ///
220 /// e.g. -127 returns 8 as it will fit in an i8. 127 returns 7 since it fits in a u7.
184221 fn bitCountTwosComp(self: Int) usize {
185222 var bits = self.bitCountAbs();
186223
......@@ -203,7 +240,7 @@ pub const Int = struct {
203240 return bits;
204241 }
205242
206 pub fn fitsInTwosComp(self: Int, is_signed: bool, bit_count: usize) bool {
243 fn fitsInTwosComp(self: Int, is_signed: bool, bit_count: usize) bool {
207244 if (self.eqZero()) {
208245 return true;
209246 }
......@@ -215,18 +252,20 @@ pub const Int = struct {
215252 return bit_count >= req_bits;
216253 }
217254
255 /// Returns whether self can fit into an integer of the requested type.
218256 pub fn fits(self: Int, comptime T: type) bool {
219257 return self.fitsInTwosComp(T.is_signed, T.bit_count);
220258 }
221259
222 // Returns the approximate size of the integer in the given base. Negative values accommodate for
223 // the minus sign. This is used for determining the number of characters needed to print the
224 // value. It is inexact and will exceed the given value by 1-2 digits.
260 /// Returns the approximate size of the integer in the given base. Negative values accommodate for
261 /// the minus sign. This is used for determining the number of characters needed to print the
262 /// value. It is inexact and may exceed the given value by ~1-2 bytes.
225263 pub fn sizeInBase(self: Int, base: usize) usize {
226264 const bit_count = usize(@boolToInt(!self.isPositive())) + self.bitCountAbs();
227265 return (bit_count / math.log2(base)) + 1;
228266 }
229267
268 /// Sets an Int to value. Value must be an primitive integer type.
230269 pub fn set(self: *Int, value: var) Allocator.Error!void {
231270 self.assertWritable();
232271 const T = @typeOf(value);
......@@ -290,6 +329,9 @@ pub const Int = struct {
290329 TargetTooSmall,
291330 };
292331
332 /// Convert self to type T.
333 ///
334 /// Returns an error if self cannot be narrowed into the requested type without truncation.
293335 pub fn to(self: Int, comptime T: type) ConvertError!T {
294336 switch (@typeId(T)) {
295337 TypeId.Int => {
......@@ -353,6 +395,13 @@ pub const Int = struct {
353395 };
354396 }
355397
398 /// Set self from the string representation `value`.
399 ///
400 /// value must contain only digits <= `base`. Base prefixes are not allowed (e.g. 0x43 should
401 /// simply be 43).
402 ///
403 /// Returns an error if memory could not be allocated or `value` has invalid digits for the
404 /// requested base.
356405 pub fn setString(self: *Int, base: u8, value: []const u8) !void {
357406 self.assertWritable();
358407 if (base < 2 or base > 16) {
......@@ -380,6 +429,8 @@ pub const Int = struct {
380429 self.setSign(positive);
381430 }
382431
432 /// Converts self to a string in the requested base. Memory is allocated from the provided
433 /// allocator and not the one present in self.
383434 /// TODO make this call format instead of the other way around
384435 pub fn toString(self: Int, allocator: *Allocator, base: u8) ![]const u8 {
385436 if (base < 2 or base > 16) {
......@@ -463,7 +514,7 @@ pub const Int = struct {
463514 return s;
464515 }
465516
466 /// for the std lib format function
517 /// To allow `std.fmt.printf` to work with Int.
467518 /// TODO make this non-allocating
468519 pub fn format(
469520 self: Int,
......@@ -480,7 +531,7 @@ pub const Int = struct {
480531 return output(context, str);
481532 }
482533
483 // returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively.
534 /// Returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively.
484535 pub fn cmpAbs(a: Int, b: Int) i8 {
485536 if (a.len() < b.len()) {
486537 return -1;
......@@ -505,7 +556,7 @@ pub const Int = struct {
505556 }
506557 }
507558
508 // returns -1, 0, 1 if a < b, a == b or a > b respectively.
559 /// Returns -1, 0, 1 if a < b, a == b or a > b respectively.
509560 pub fn cmp(a: Int, b: Int) i8 {
510561 if (a.isPositive() != b.isPositive()) {
511562 return if (a.isPositive()) i8(1) else -1;
......@@ -515,17 +566,17 @@ pub const Int = struct {
515566 }
516567 }
517568
518 // if a == 0
569 /// Returns true if a == 0.
519570 pub fn eqZero(a: Int) bool {
520571 return a.len() == 1 and a.limbs[0] == 0;
521572 }
522573
523 // if |a| == |b|
574 /// Returns true if |a| == |b|.
524575 pub fn eqAbs(a: Int, b: Int) bool {
525576 return cmpAbs(a, b) == 0;
526577 }
527578
528 // if a == b
579 /// Returns true if a == b.
529580 pub fn eq(a: Int, b: Int) bool {
530581 return cmp(a, b) == 0;
531582 }
......@@ -559,7 +610,11 @@ pub const Int = struct {
559610 };
560611 }
561612
562 // r = a + b
613 /// r = a + b
614 ///
615 /// r, a and b may be aliases.
616 ///
617 /// Returns an error if memory could not be allocated.
563618 pub fn add(r: *Int, a: Int, b: Int) Allocator.Error!void {
564619 r.assertWritable();
565620 if (a.eqZero()) {
......@@ -617,7 +672,11 @@ pub const Int = struct {
617672 r[i] = carry;
618673 }
619674
620 // r = a - b
675 /// r = a - b
676 ///
677 /// r, a and b may be aliases.
678 ///
679 /// Returns an error if memory could not be allocated.
621680 pub fn sub(r: *Int, a: Int, b: Int) !void {
622681 r.assertWritable();
623682 if (a.isPositive() != b.isPositive()) {
......@@ -684,9 +743,11 @@ pub const Int = struct {
684743 debug.assert(borrow == 0);
685744 }
686745
687 // rma = a * b
688 //
689 // For greatest efficiency, ensure rma does not alias a or b.
746 /// rma = a * b
747 ///
748 /// rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.
749 ///
750 /// Returns an error if memory could not be allocated.
690751 pub fn mul(rma: *Int, a: Int, b: Int) !void {
691752 rma.assertWritable();
692753
......@@ -759,6 +820,9 @@ pub const Int = struct {
759820 }
760821 }
761822
823 /// q = a / b (rem r)
824 ///
825 /// a / b are floored (rounded towards 0).
762826 pub fn divFloor(q: *Int, r: *Int, a: Int, b: Int) !void {
763827 try div(q, r, a, b);
764828
......@@ -771,6 +835,9 @@ pub const Int = struct {
771835 r.setSign(b.isPositive());
772836 }
773837
838 /// q = a / b (rem r)
839 ///
840 /// a / b are truncated (rounded towards -inf).
774841 pub fn divTrunc(q: *Int, r: *Int, a: Int, b: Int) !void {
775842 try div(q, r, a, b);
776843 r.setSign(a.isPositive());
......@@ -969,7 +1036,7 @@ pub const Int = struct {
9691036 r.normalize(r.len());
9701037 }
9711038
972 // r = a << shift, in other words, r = a * 2^shift
1039 /// r = a << shift, in other words, r = a * 2^shift
9731040 pub fn shiftLeft(r: *Int, a: Int, shift: usize) !void {
9741041 r.assertWritable();
9751042
......@@ -1002,7 +1069,7 @@ pub const Int = struct {
10021069 mem.set(Limb, r[0 .. limb_shift - 1], 0);
10031070 }
10041071
1005 // r = a >> shift
1072 /// r = a >> shift
10061073 pub fn shiftRight(r: *Int, a: Int, shift: usize) !void {
10071074 r.assertWritable();
10081075
......@@ -1038,7 +1105,9 @@ pub const Int = struct {
10381105 }
10391106 }
10401107
1041 // r = a | b
1108 /// r = a | b
1109 ///
1110 /// a and b are zero-extended to the longer of a or b.
10421111 pub fn bitOr(r: *Int, a: Int, b: Int) !void {
10431112 r.assertWritable();
10441113
......@@ -1067,7 +1136,7 @@ pub const Int = struct {
10671136 }
10681137 }
10691138
1070 // r = a & b
1139 /// r = a & b
10711140 pub fn bitAnd(r: *Int, a: Int, b: Int) !void {
10721141 r.assertWritable();
10731142
......@@ -1093,7 +1162,7 @@ pub const Int = struct {
10931162 }
10941163 }
10951164
1096 // r = a ^ b
1165 /// r = a ^ b
10971166 pub fn bitXor(r: *Int, a: Int, b: Int) !void {
10981167 r.assertWritable();
10991168
......@@ -1279,10 +1348,8 @@ test "big.int bitcount/to" {
12791348 try a.set(0);
12801349 testing.expect(a.bitCountTwosComp() == 0);
12811350
1282 // TODO: stack smashing
1283 // testing.expect((try a.to(u0)) == 0);
1284 // TODO: sigsegv
1285 // testing.expect((try a.to(i0)) == 0);
1351 testing.expect((try a.to(u0)) == 0);
1352 testing.expect((try a.to(i0)) == 0);
12861353
12871354 try a.set(-1);
12881355 testing.expect(a.bitCountTwosComp() == 1);
std/math/big/rational.zig+55-13
......@@ -14,11 +14,22 @@ const Limb = bn.Limb;
1414const DoubleLimb = bn.DoubleLimb;
1515const Int = bn.Int;
1616
17/// An arbitrary-precision rational number.
18///
19/// Memory is allocated as needed for operations to ensure full precision is kept. The precision
20/// of a Rational is only bounded by memory.
21///
22/// Rational's are always normalized. That is, for a Rational r = p/q where p and q are integers,
23/// gcd(p, q) = 1 always.
1724pub const Rational = struct {
18 // Sign of Rational is sign of p. Sign of q is ignored
25 /// Numerator. Determines the sign of the Rational.
1926 p: Int,
27
28 /// Denominator. Sign is ignored.
2029 q: Int,
2130
31 /// Create a new Rational. A small amount of memory will be allocated on initialization.
32 /// This will be 2 * Int.default_capacity.
2233 pub fn init(a: *Allocator) !Rational {
2334 return Rational{
2435 .p = try Int.init(a),
......@@ -26,18 +37,21 @@ pub const Rational = struct {
2637 };
2738 }
2839
40 /// Frees all memory associated with a Rational.
2941 pub fn deinit(self: *Rational) void {
3042 self.p.deinit();
3143 self.q.deinit();
3244 }
3345
46 /// Set a Rational from a primitive integer type.
3447 pub fn setInt(self: *Rational, a: var) !void {
3548 try self.p.set(a);
3649 try self.q.set(1);
3750 }
3851
39 // TODO: Accept a/b fractions and exponent form
52 /// Set a Rational from a string of the form `A/B` where A and B are base-10 integers.
4053 pub fn setFloatString(self: *Rational, str: []const u8) !void {
54 // TODO: Accept a/b fractions and exponent form
4155 if (str.len == 0) {
4256 return error.InvalidFloatString;
4357 }
......@@ -111,8 +125,10 @@ pub const Rational = struct {
111125 }
112126 }
113127
114 // Translated from golang.go/src/math/big/rat.go.
128 /// Set a Rational from a floating-point value. The rational will have enough precision to
129 /// completely represent the provided float.
115130 pub fn setFloat(self: *Rational, comptime T: type, f: T) !void {
131 // Translated from golang.go/src/math/big/rat.go.
116132 debug.assert(@typeId(T) == builtin.TypeId.Float);
117133
118134 const UnsignedIntType = @IntType(false, T.bit_count);
......@@ -164,8 +180,13 @@ pub const Rational = struct {
164180 try self.reduce();
165181 }
166182
167 // Translated from golang.go/src/math/big/rat.go.
183 /// Return a floating-point value that is the closest value to a Rational.
184 ///
185 /// The result may not be exact if the Rational is too precise or too large for the
186 /// target type.
168187 pub fn toFloat(self: Rational, comptime T: type) !T {
188 // Translated from golang.go/src/math/big/rat.go.
189 // TODO: Indicate whether the result is not exact.
169190 debug.assert(@typeId(T) == builtin.TypeId.Float);
170191
171192 const fsize = T.bit_count;
......@@ -259,6 +280,7 @@ pub const Rational = struct {
259280 return if (self.p.isPositive()) f else -f;
260281 }
261282
283 /// Set a rational from an integer ratio.
262284 pub fn setRatio(self: *Rational, p: var, q: var) !void {
263285 try self.p.set(p);
264286 try self.q.set(q);
......@@ -273,11 +295,13 @@ pub const Rational = struct {
273295 }
274296 }
275297
298 /// Set a Rational directly from an Int.
276299 pub fn copyInt(self: *Rational, a: Int) !void {
277300 try self.p.copy(a);
278301 try self.q.set(1);
279302 }
280303
304 /// Set a Rational directly from a ratio of two Int's.
281305 pub fn copyRatio(self: *Rational, a: Int, b: Int) !void {
282306 try self.p.copy(a);
283307 try self.q.copy(b);
......@@ -288,23 +312,29 @@ pub const Rational = struct {
288312 try self.reduce();
289313 }
290314
315 /// Make a Rational positive.
291316 pub fn abs(r: *Rational) void {
292317 r.p.abs();
293318 }
294319
320 /// Negate the sign of a Rational.
295321 pub fn negate(r: *Rational) void {
296322 r.p.negate();
297323 }
298324
325 /// Efficiently swap a Rational with another. This swaps the limb pointers and a full copy is not
326 /// performed. The address of the limbs field will not be the same after this function.
299327 pub fn swap(r: *Rational, other: *Rational) void {
300328 r.p.swap(&other.p);
301329 r.q.swap(&other.q);
302330 }
303331
332 /// Returns -1, 0, 1 if a < b, a == b or a > b respectively.
304333 pub fn cmp(a: Rational, b: Rational) !i8 {
305334 return cmpInternal(a, b, true);
306335 }
307336
337 /// Returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively.
308338 pub fn cmpAbs(a: Rational, b: Rational) !i8 {
309339 return cmpInternal(a, b, false);
310340 }
......@@ -325,9 +355,11 @@ pub const Rational = struct {
325355 return if (is_abs) q.cmpAbs(p) else q.cmp(p);
326356 }
327357
328 // r/q = ap/aq + bp/bq = (ap*bq + bp*aq) / (aq*bq)
329 //
330 // For best performance, rma should not alias a or b.
358 /// rma = a + b.
359 ///
360 /// rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.
361 ///
362 /// Returns an error if memory could not be allocated.
331363 pub fn add(rma: *Rational, a: Rational, b: Rational) !void {
332364 var r = rma;
333365 var aliased = rma.p.limbs.ptr == a.p.limbs.ptr or rma.p.limbs.ptr == b.p.limbs.ptr;
......@@ -351,9 +383,11 @@ pub const Rational = struct {
351383 try r.reduce();
352384 }
353385
354 // r/q = ap/aq - bp/bq = (ap*bq - bp*aq) / (aq*bq)
355 //
356 // For best performance, rma should not alias a or b.
386 /// rma = a - b.
387 ///
388 /// rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.
389 ///
390 /// Returns an error if memory could not be allocated.
357391 pub fn sub(rma: *Rational, a: Rational, b: Rational) !void {
358392 var r = rma;
359393 var aliased = rma.p.limbs.ptr == a.p.limbs.ptr or rma.p.limbs.ptr == b.p.limbs.ptr;
......@@ -377,14 +411,22 @@ pub const Rational = struct {
377411 try r.reduce();
378412 }
379413
380 // r/q = ap/aq * bp/bq = ap*bp / aq*bq
414 /// rma = a * b.
415 ///
416 /// rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.
417 ///
418 /// Returns an error if memory could not be allocated.
381419 pub fn mul(r: *Rational, a: Rational, b: Rational) !void {
382420 try r.p.mul(a.p, b.p);
383421 try r.q.mul(a.q, b.q);
384422 try r.reduce();
385423 }
386424
387 // r/q = (ap/aq) / (bp/bq) = ap*bq / bp*aq
425 /// rma = a / b.
426 ///
427 /// rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.
428 ///
429 /// Returns an error if memory could not be allocated.
388430 pub fn div(r: *Rational, a: Rational, b: Rational) !void {
389431 if (b.p.eqZero()) {
390432 @panic("division by zero");
......@@ -395,7 +437,7 @@ pub const Rational = struct {
395437 try r.reduce();
396438 }
397439
398 // r/q = q/r
440 /// Invert the numerator and denominator fields of a Rational. p/q => q/p.
399441 pub fn invert(r: *Rational) void {
400442 Int.swap(&r.p, &r.q);
401443 }
std/math/cbrt.zig+10-4
......@@ -1,13 +1,19 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - cbrt(+-0) = +-0
4// - cbrt(+-inf) = +-inf
5// - cbrt(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/cbrtf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/cbrt.c
66
77const std = @import("../std.zig");
88const math = std.math;
99const expect = std.testing.expect;
1010
11/// Returns the cube root of x.
12///
13/// Special Cases:
14/// - cbrt(+-0) = +-0
15/// - cbrt(+-inf) = +-inf
16/// - cbrt(nan) = nan
1117pub fn cbrt(x: var) @typeOf(x) {
1218 const T = @typeOf(x);
1319 return switch (T) {
std/math/ceil.zig+10-4
......@@ -1,14 +1,20 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - ceil(+-0) = +-0
4// - ceil(+-inf) = +-inf
5// - ceil(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/ceil.c
66
77const builtin = @import("builtin");
88const std = @import("../std.zig");
99const math = std.math;
1010const expect = std.testing.expect;
1111
12/// Returns the least integer value greater than of equal to x.
13///
14/// Special Cases:
15/// - ceil(+-0) = +-0
16/// - ceil(+-inf) = +-inf
17/// - ceil(nan) = nan
1218pub fn ceil(x: var) @typeOf(x) {
1319 const T = @typeOf(x);
1420 return switch (T) {
std/math/complex.zig+12
......@@ -23,13 +23,18 @@ pub const sqrt = @import("complex/sqrt.zig").sqrt;
2323pub const tanh = @import("complex/tanh.zig").tanh;
2424pub const tan = @import("complex/tan.zig").tan;
2525
26/// A complex number consisting of a real an imaginary part. T must be a floating-point value.
2627pub fn Complex(comptime T: type) type {
2728 return struct {
2829 const Self = @This();
2930
31 /// Real part.
3032 re: T,
33
34 /// Imaginary part.
3135 im: T,
3236
37 /// Create a new Complex number from the given real and imaginary parts.
3338 pub fn new(re: T, im: T) Self {
3439 return Self{
3540 .re = re,
......@@ -37,6 +42,7 @@ pub fn Complex(comptime T: type) type {
3742 };
3843 }
3944
45 /// Returns the sum of two complex numbers.
4046 pub fn add(self: Self, other: Self) Self {
4147 return Self{
4248 .re = self.re + other.re,
......@@ -44,6 +50,7 @@ pub fn Complex(comptime T: type) type {
4450 };
4551 }
4652
53 /// Returns the subtraction of two complex numbers.
4754 pub fn sub(self: Self, other: Self) Self {
4855 return Self{
4956 .re = self.re - other.re,
......@@ -51,6 +58,7 @@ pub fn Complex(comptime T: type) type {
5158 };
5259 }
5360
61 /// Returns the product of two complex numbers.
5462 pub fn mul(self: Self, other: Self) Self {
5563 return Self{
5664 .re = self.re * other.re - self.im * other.im,
......@@ -58,6 +66,7 @@ pub fn Complex(comptime T: type) type {
5866 };
5967 }
6068
69 /// Returns the quotient of two complex numbers.
6170 pub fn div(self: Self, other: Self) Self {
6271 const re_num = self.re * other.re + self.im * other.im;
6372 const im_num = self.im * other.re - self.re * other.im;
......@@ -69,6 +78,7 @@ pub fn Complex(comptime T: type) type {
6978 };
7079 }
7180
81 /// Returns the complex conjugate of a number.
7282 pub fn conjugate(self: Self) Self {
7383 return Self{
7484 .re = self.re,
......@@ -76,6 +86,7 @@ pub fn Complex(comptime T: type) type {
7686 };
7787 }
7888
89 /// Returns the reciprocal of a complex number.
7990 pub fn reciprocal(self: Self) Self {
8091 const m = self.re * self.re + self.im * self.im;
8192 return Self{
......@@ -84,6 +95,7 @@ pub fn Complex(comptime T: type) type {
8495 };
8596 }
8697
98 /// Returns the magnitude of a complex number.
8799 pub fn magnitude(self: Self) T {
88100 return math.sqrt(self.re * self.re + self.im * self.im);
89101 }
std/math/complex/abs.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the absolute value (modulus) of z.
78pub fn abs(z: var) @typeOf(z.re) {
89 const T = @typeOf(z.re);
910 return math.hypot(T, z.re, z.im);
std/math/complex/acos.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the arc-cosine of z.
78pub fn acos(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const q = cmath.asin(z);
std/math/complex/acosh.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the hyperbolic arc-cosine of z.
78pub fn acosh(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const q = cmath.acos(z);
std/math/complex/arg.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the angular component (in radians) of z.
78pub fn arg(z: var) @typeOf(z.re) {
89 const T = @typeOf(z.re);
910 return math.atan2(T, z.im, z.re);
std/math/complex/asin.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7// Returns the arc-sine of z.
78pub fn asin(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const x = z.re;
std/math/complex/asinh.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the hyperbolic arc-sine of z.
78pub fn asinh(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const q = Complex(T).new(-z.im, z.re);
std/math/complex/atan.zig+7
......@@ -1,9 +1,16 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/catanf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/catan.c
6
17const std = @import("../../std.zig");
28const testing = std.testing;
39const math = std.math;
410const cmath = math.complex;
511const Complex = cmath.Complex;
612
13/// Returns the arc-tangent of z.
714pub fn atan(z: var) @typeOf(z) {
815 const T = @typeOf(z.re);
916 return switch (T) {
std/math/complex/atanh.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the hyperbolic arc-tangent of z.
78pub fn atanh(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const q = Complex(T).new(-z.im, z.re);
std/math/complex/conj.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the complex conjugate of z.
78pub fn conj(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 return Complex(T).new(z.re, -z.im);
std/math/complex/cos.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the cosine of z.
78pub fn cos(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const p = Complex(T).new(-z.im, z.re);
std/math/complex/cosh.zig+7
......@@ -1,3 +1,9 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/ccoshf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/ccosh.c
6
17const std = @import("../../std.zig");
28const testing = std.testing;
39const math = std.math;
......@@ -6,6 +12,7 @@ const Complex = cmath.Complex;
612
713const ldexp_cexp = @import("ldexp.zig").ldexp_cexp;
814
15/// Returns the hyperbolic arc-cosine of z.
916pub fn cosh(z: var) Complex(@typeOf(z.re)) {
1017 const T = @typeOf(z.re);
1118 return switch (T) {
std/math/complex/exp.zig+7
......@@ -1,3 +1,9 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/cexpf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/cexp.c
6
17const std = @import("../../std.zig");
28const testing = std.testing;
39const math = std.math;
......@@ -6,6 +12,7 @@ const Complex = cmath.Complex;
612
713const ldexp_cexp = @import("ldexp.zig").ldexp_cexp;
814
15/// Returns e raised to the power of z (e^z).
916pub fn exp(z: var) @typeOf(z) {
1017 const T = @typeOf(z.re);
1118
std/math/complex/ldexp.zig+7
......@@ -1,9 +1,16 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/__cexpf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/__cexp.c
6
17const std = @import("../../std.zig");
28const debug = std.debug;
39const math = std.math;
410const cmath = math.complex;
511const Complex = cmath.Complex;
612
13/// Returns exp(z) scaled to avoid overflow.
714pub fn ldexp_cexp(z: var, expt: i32) @typeOf(z) {
815 const T = @typeOf(z.re);
916
std/math/complex/log.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the natural logarithm of z.
78pub fn log(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const r = cmath.abs(z);
std/math/complex/pow.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns z raised to the complex power of c.
78pub fn pow(comptime T: type, z: T, c: T) T {
89 const p = cmath.log(z);
910 const q = c.mul(p);
std/math/complex/proj.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the projection of z onto the riemann sphere.
78pub fn proj(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910
std/math/complex/sin.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the sine of z.
78pub fn sin(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const p = Complex(T).new(-z.im, z.re);
std/math/complex/sinh.zig+7
......@@ -1,3 +1,9 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/csinhf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/csinh.c
6
17const std = @import("../../std.zig");
28const testing = std.testing;
39const math = std.math;
......@@ -6,6 +12,7 @@ const Complex = cmath.Complex;
612
713const ldexp_cexp = @import("ldexp.zig").ldexp_cexp;
814
15/// Returns the hyperbolic sine of z.
916pub fn sinh(z: var) @typeOf(z) {
1017 const T = @typeOf(z.re);
1118 return switch (T) {
std/math/complex/sqrt.zig+8
......@@ -1,9 +1,17 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/csqrtf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/csqrt.c
6
17const std = @import("../../std.zig");
28const testing = std.testing;
39const math = std.math;
410const cmath = math.complex;
511const Complex = cmath.Complex;
612
13/// Returns the square root of z. The real and imaginary parts of the result have the same sign
14/// as the imaginary part of z.
715pub fn sqrt(z: var) @typeOf(z) {
816 const T = @typeOf(z.re);
917
std/math/complex/tan.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the tanget of z.
78pub fn tan(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const q = Complex(T).new(-z.im, z.re);
std/math/complex/tanh.zig+7
......@@ -1,9 +1,16 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/ctanhf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/ctanh.c
6
17const std = @import("../../std.zig");
28const testing = std.testing;
39const math = std.math;
410const cmath = math.complex;
511const Complex = cmath.Complex;
612
13/// Returns the hyperbolic tangent of z.
714pub fn tanh(z: var) @typeOf(z) {
815 const T = @typeOf(z.re);
916 return switch (T) {
std/math/copysign.zig+7
......@@ -1,8 +1,15 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/math/copysignf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/copysign.c
6
17const std = @import("../std.zig");
28const math = std.math;
39const expect = std.testing.expect;
410const maxInt = std.math.maxInt;
511
12/// Returns a value with the magnitude of x and the sign of y.
613pub fn copysign(comptime T: type, x: T, y: T) T {
714 return switch (T) {
815 f16 => copysign16(x, y),
std/math/cosh.zig+10-4
......@@ -1,8 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - cosh(+-0) = 1
4// - cosh(+-inf) = +inf
5// - cosh(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/coshf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/cosh.c
66
77const builtin = @import("builtin");
88const std = @import("../std.zig");
......@@ -11,6 +11,12 @@ const expo2 = @import("expo2.zig").expo2;
1111const expect = std.testing.expect;
1212const maxInt = std.math.maxInt;
1313
14/// Returns the hyperbolic cosine of x.
15///
16/// Special Cases:
17/// - cosh(+-0) = 1
18/// - cosh(+-inf) = +inf
19/// - cosh(nan) = nan
1420pub fn cosh(x: var) @typeOf(x) {
1521 const T = @typeOf(x);
1622 return switch (T) {
std/math/exp.zig+9-3
......@@ -1,13 +1,19 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - exp(+inf) = +inf
4// - exp(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/expf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/exp.c
56
67const std = @import("../std.zig");
78const math = std.math;
89const assert = std.debug.assert;
910const builtin = @import("builtin");
1011
12/// Returns e raised to the power of x (e^x).
13///
14/// Special Cases:
15/// - exp(+inf) = +inf
16/// - exp(nan) = nan
1117pub fn exp(x: var) @typeOf(x) {
1218 const T = @typeOf(x);
1319 return switch (T) {
std/math/exp2.zig+9-3
......@@ -1,12 +1,18 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - exp2(+inf) = +inf
4// - exp2(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/exp2f.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/exp2.c
56
67const std = @import("../std.zig");
78const math = std.math;
89const expect = std.testing.expect;
910
11/// Returns 2 raised to the power of x (2^x).
12///
13/// Special Cases:
14/// - exp2(+inf) = +inf
15/// - exp2(nan) = nan
1016pub fn exp2(x: var) @typeOf(x) {
1117 const T = @typeOf(x);
1218 return switch (T) {
std/math/expm1.zig+13-4
......@@ -1,14 +1,23 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - expm1(+inf) = +inf
4// - expm1(-inf) = -1
5// - expm1(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/expmf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/expm.c
6
7// TODO: Updated recently.
68
79const builtin = @import("builtin");
810const std = @import("../std.zig");
911const math = std.math;
1012const expect = std.testing.expect;
1113
14/// Returns e raised to the power of x, minus 1 (e^x - 1). This is more accurate than exp(e, x) - 1
15/// when x is near 0.
16///
17/// Special Cases:
18/// - expm1(+inf) = +inf
19/// - expm1(-inf) = -1
20/// - expm1(nan) = nan
1221pub fn expm1(x: var) @typeOf(x) {
1322 const T = @typeOf(x);
1423 return switch (T) {
std/math/expo2.zig+7
......@@ -1,5 +1,12 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/math/__expo2f.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/__expo2.c
6
17const math = @import("../math.zig");
28
9/// Returns exp(x) / 2 for x >= log(maxFloat(T)).
310pub fn expo2(x: var) @typeOf(x) {
411 const T = @typeOf(x);
512 return switch (T) {
std/math/fabs.zig+9-3
......@@ -1,13 +1,19 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - fabs(+-inf) = +inf
4// - fabs(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/fabsf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/fabs.c
56
67const std = @import("../std.zig");
78const math = std.math;
89const expect = std.testing.expect;
910const maxInt = std.math.maxInt;
1011
12/// Returns the absolute value of x.
13///
14/// Special Cases:
15/// - fabs(+-inf) = +inf
16/// - fabs(nan) = nan
1117pub fn fabs(x: var) @typeOf(x) {
1218 const T = @typeOf(x);
1319 return switch (T) {
std/math/floor.zig+10-4
......@@ -1,14 +1,20 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - floor(+-0) = +-0
4// - floor(+-inf) = +-inf
5// - floor(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/floorf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/floor.c
66
77const builtin = @import("builtin");
88const expect = std.testing.expect;
99const std = @import("../std.zig");
1010const math = std.math;
1111
12/// Returns the greatest integer value less than or equal to x.
13///
14/// Special Cases:
15/// - floor(+-0) = +-0
16/// - floor(+-inf) = +-inf
17/// - floor(nan) = nan
1218pub fn floor(x: var) @typeOf(x) {
1319 const T = @typeOf(x);
1420 return switch (T) {
std/math/frexp.zig+11-4
......@@ -1,8 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - frexp(+-0) = +-0, 0
4// - frexp(+-inf) = +-inf, 0
5// - frexp(nan) = nan, undefined
4// https://git.musl-libc.org/cgit/musl/tree/src/math/frexpf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/frexp.c
66
77const std = @import("../std.zig");
88const math = std.math;
......@@ -17,6 +17,13 @@ fn frexp_result(comptime T: type) type {
1717pub const frexp32_result = frexp_result(f32);
1818pub const frexp64_result = frexp_result(f64);
1919
20/// Breaks x into a normalized fraction and an integral power of two.
21/// f == frac * 2^exp, with |frac| in the interval [0.5, 1).
22///
23/// Special Cases:
24/// - frexp(+-0) = +-0, 0
25/// - frexp(+-inf) = +-inf, 0
26/// - frexp(nan) = nan, undefined
2027pub fn frexp(x: var) frexp_result(@typeOf(x)) {
2128 const T = @typeOf(x);
2229 return switch (T) {
std/math/hypot.zig+11-5
......@@ -1,15 +1,21 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - hypot(+-inf, y) = +inf
4// - hypot(x, +-inf) = +inf
5// - hypot(nan, y) = nan
6// - hypot(x, nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/hypotf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/hypot.c
76
87const std = @import("../std.zig");
98const math = std.math;
109const expect = std.testing.expect;
1110const maxInt = std.math.maxInt;
1211
12/// Returns sqrt(x * x + y * y), avoiding unncessary overflow and underflow.
13///
14/// Special Cases:
15/// - hypot(+-inf, y) = +inf
16/// - hypot(x, +-inf) = +inf
17/// - hypot(nan, y) = nan
18/// - hypot(x, nan) = nan
1319pub fn hypot(comptime T: type, x: T, y: T) T {
1420 return switch (T) {
1521 f32 => hypot32(x, y),
std/math/ilogb.zig+10-4
......@@ -1,8 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - ilogb(+-inf) = maxInt(i32)
4// - ilogb(0) = maxInt(i32)
5// - ilogb(nan) = maxInt(i32)
4// https://git.musl-libc.org/cgit/musl/tree/src/math/ilogbf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/ilogb.c
66
77const std = @import("../std.zig");
88const math = std.math;
......@@ -10,6 +10,12 @@ const expect = std.testing.expect;
1010const maxInt = std.math.maxInt;
1111const minInt = std.math.minInt;
1212
13/// Returns the binary exponent of x as an integer.
14///
15/// Special Cases:
16/// - ilogb(+-inf) = maxInt(i32)
17/// - ilogb(0) = maxInt(i32)
18/// - ilogb(nan) = maxInt(i32)
1319pub fn ilogb(x: var) i32 {
1420 const T = @typeOf(x);
1521 return switch (T) {
std/math/inf.zig+1
......@@ -1,6 +1,7 @@
11const std = @import("../std.zig");
22const math = std.math;
33
4/// Returns value inf for the type T.
45pub fn inf(comptime T: type) T {
56 return switch (T) {
67 f16 => math.inf_f16,
std/math/isfinite.zig+1
......@@ -3,6 +3,7 @@ const math = std.math;
33const expect = std.testing.expect;
44const maxInt = std.math.maxInt;
55
6/// Returns whether x is a finite value.
67pub fn isFinite(x: var) bool {
78 const T = @typeOf(x);
89 switch (T) {
std/math/isinf.zig+3
......@@ -3,6 +3,7 @@ const math = std.math;
33const expect = std.testing.expect;
44const maxInt = std.math.maxInt;
55
6/// Returns whether x is an infinity, ignoring sign.
67pub fn isInf(x: var) bool {
78 const T = @typeOf(x);
89 switch (T) {
......@@ -28,6 +29,7 @@ pub fn isInf(x: var) bool {
2829 }
2930}
3031
32/// Returns whether x is an infinity with a positive sign.
3133pub fn isPositiveInf(x: var) bool {
3234 const T = @typeOf(x);
3335 switch (T) {
......@@ -49,6 +51,7 @@ pub fn isPositiveInf(x: var) bool {
4951 }
5052}
5153
54/// Returns whether x is an infinity with a negative sign.
5255pub fn isNegativeInf(x: var) bool {
5356 const T = @typeOf(x);
5457 switch (T) {
std/math/isnan.zig+4-2
......@@ -3,13 +3,15 @@ const math = std.math;
33const expect = std.testing.expect;
44const maxInt = std.math.maxInt;
55
6/// Returns whether x is a nan.
67pub fn isNan(x: var) bool {
78 return x != x;
89}
910
10/// Note: A signalling nan is identical to a standard nan right now but may have a different bit
11/// representation in the future when required.
11/// Returns whether x is a signalling nan.
1212pub fn isSignalNan(x: var) bool {
13 // Note: A signalling nan is identical to a standard nan right now but may have a different bit
14 // representation in the future when required.
1315 return isNan(x);
1416}
1517
std/math/isnormal.zig+1
......@@ -3,6 +3,7 @@ const math = std.math;
33const expect = std.testing.expect;
44const maxInt = std.math.maxInt;
55
6// Returns whether x has a normalized representation (i.e. integer part of mantissa is 1).
67pub fn isNormal(x: var) bool {
78 const T = @typeOf(x);
89 switch (T) {
std/math/ln.zig+11-5
......@@ -1,9 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - ln(+inf) = +inf
4// - ln(0) = -inf
5// - ln(x) = nan if x < 0
6// - ln(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/lnf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/ln.c
76
87const std = @import("../std.zig");
98const math = std.math;
......@@ -11,6 +10,13 @@ const expect = std.testing.expect;
1110const builtin = @import("builtin");
1211const TypeId = builtin.TypeId;
1312
13/// Returns the natural logarithm of x.
14///
15/// Special Cases:
16/// - ln(+inf) = +inf
17/// - ln(0) = -inf
18/// - ln(x) = nan if x < 0
19/// - ln(nan) = nan
1420pub fn ln(x: var) @typeOf(x) {
1521 const T = @typeOf(x);
1622 switch (@typeId(T)) {
std/math/log.zig+7
......@@ -1,9 +1,16 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/math/logf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/log.c
6
17const std = @import("../std.zig");
28const math = std.math;
39const builtin = @import("builtin");
410const TypeId = builtin.TypeId;
511const expect = std.testing.expect;
612
13/// Returns the logarithm of x for the provided base.
714pub fn log(comptime T: type, base: T, x: T) T {
815 if (base == 2) {
916 return math.log2(x);
std/math/log10.zig+11-5
......@@ -1,9 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - log10(+inf) = +inf
4// - log10(0) = -inf
5// - log10(x) = nan if x < 0
6// - log10(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/log10f.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/log10.c
76
87const std = @import("../std.zig");
98const math = std.math;
......@@ -12,6 +11,13 @@ const builtin = @import("builtin");
1211const TypeId = builtin.TypeId;
1312const maxInt = std.math.maxInt;
1413
14/// Returns the base-10 logarithm of x.
15///
16/// Special Cases:
17/// - log10(+inf) = +inf
18/// - log10(0) = -inf
19/// - log10(x) = nan if x < 0
20/// - log10(nan) = nan
1521pub fn log10(x: var) @typeOf(x) {
1622 const T = @typeOf(x);
1723 switch (@typeId(T)) {
std/math/log1p.zig+12-6
......@@ -1,16 +1,22 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - log1p(+inf) = +inf
4// - log1p(+-0) = +-0
5// - log1p(-1) = -inf
6// - log1p(x) = nan if x < -1
7// - log1p(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/log1pf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/log1p.c
86
97const builtin = @import("builtin");
108const std = @import("../std.zig");
119const math = std.math;
1210const expect = std.testing.expect;
1311
12/// Returns the natural logarithm of 1 + x with greater accuracy when x is near zero.
13///
14/// Special Cases:
15/// - log1p(+inf) = +inf
16/// - log1p(+-0) = +-0
17/// - log1p(-1) = -inf
18/// - log1p(x) = nan if x < -1
19/// - log1p(nan) = nan
1420pub fn log1p(x: var) @typeOf(x) {
1521 const T = @typeOf(x);
1622 return switch (T) {
std/math/log2.zig+11-5
......@@ -1,9 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - log2(+inf) = +inf
4// - log2(0) = -inf
5// - log2(x) = nan if x < 0
6// - log2(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/log2f.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/log2.c
76
87const std = @import("../std.zig");
98const math = std.math;
......@@ -12,6 +11,13 @@ const builtin = @import("builtin");
1211const TypeId = builtin.TypeId;
1312const maxInt = std.math.maxInt;
1413
14/// Returns the base-2 logarithm of x.
15///
16/// Special Cases:
17/// - log2(+inf) = +inf
18/// - log2(0) = -inf
19/// - log2(x) = nan if x < 0
20/// - log2(nan) = nan
1521pub fn log2(x: var) @typeOf(x) {
1622 const T = @typeOf(x);
1723 switch (@typeId(T)) {
std/math/modf.zig+10-3
......@@ -1,7 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - modf(+-inf) = +-inf, nan
4// - modf(nan) = nan, nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/modff.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/modf.c
56
67const std = @import("../std.zig");
78const math = std.math;
......@@ -17,6 +18,12 @@ fn modf_result(comptime T: type) type {
1718pub const modf32_result = modf_result(f32);
1819pub const modf64_result = modf_result(f64);
1920
21/// Returns the integer and fractional floating-point numbers that sum to x. The sign of each
22/// result is the same as the sign of x.
23///
24/// Special Cases:
25/// - modf(+-inf) = +-inf, nan
26/// - modf(nan) = nan, nan
2027pub fn modf(x: var) modf_result(@typeOf(x)) {
2128 const T = @typeOf(x);
2229 return switch (T) {
std/math/nan.zig+4-2
......@@ -1,5 +1,6 @@
11const math = @import("../math.zig");
22
3/// Returns the nan representation for type T.
34pub fn nan(comptime T: type) T {
45 return switch (T) {
56 f16 => math.nan_f16,
......@@ -10,9 +11,10 @@ pub fn nan(comptime T: type) T {
1011 };
1112}
1213
13// Note: A signalling nan is identical to a standard right now by may have a different bit
14// representation in the future when required.
14/// Returns the signalling nan representation for type T.
1515pub fn snan(comptime T: type) T {
16 // Note: A signalling nan is identical to a standard right now by may have a different bit
17 // representation in the future when required.
1618 return switch (T) {
1719 f16 => @bitCast(f16, math.nan_u16),
1820 f32 => @bitCast(f32, math.nan_u32),
std/math/powi.zig+13-9
......@@ -1,12 +1,7 @@
1// Special Cases:
1// Based on Rust, which is licensed under the MIT license.
2// https://github.com/rust-lang/rust/blob/360432f1e8794de58cd94f34c9c17ad65871e5b5/LICENSE-MIT
23//
3// powi(x, +-0) = 1 for any x
4// powi(0, y) = 0 for any y
5// powi(1, y) = 1 for any y
6// powi(-1, y) = -1 for for y an odd integer
7// powi(-1, y) = 1 for for y an even integer
8// powi(x, y) = Overflow for for y >= @sizeOf(x) - 1 y > 0
9// powi(x, y) = Underflow for for y > @sizeOf(x) - 1 y < 0
4// https://github.com/rust-lang/rust/blob/360432f1e8794de58cd94f34c9c17ad65871e5b5/src/libcore/num/mod.rs#L3423
105
116const builtin = @import("builtin");
127const std = @import("../std.zig");
......@@ -14,7 +9,16 @@ const math = std.math;
149const assert = std.debug.assert;
1510const testing = std.testing;
1611
17// This implementation is based on that from the rust stlib
12/// Returns the power of x raised by the integer y (x^y).
13///
14/// Special Cases:
15/// - powi(x, +-0) = 1 for any x
16/// - powi(0, y) = 0 for any y
17/// - powi(1, y) = 1 for any y
18/// - powi(-1, y) = -1 for y an odd integer
19/// - powi(-1, y) = 1 for y an even integer
20/// - powi(x, y) = Overflow for y >= @sizeOf(x) - 1 or y > 0
21/// - powi(x, y) = Underflow for y > @sizeOf(x) - 1 or y < 0
1822pub fn powi(comptime T: type, x: T, y: T) (error{
1923 Overflow,
2024 Underflow,
std/math/round.zig+10-4
......@@ -1,14 +1,20 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - round(+-0) = +-0
4// - round(+-inf) = +-inf
5// - round(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/roundf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/round.c
66
77const builtin = @import("builtin");
88const expect = std.testing.expect;
99const std = @import("../std.zig");
1010const math = std.math;
1111
12/// Returns x rounded to the nearest integer, rounding half away from zero.
13///
14/// Special Cases:
15/// - round(+-0) = +-0
16/// - round(+-inf) = +-inf
17/// - round(nan) = nan
1218pub fn round(x: var) @typeOf(x) {
1319 const T = @typeOf(x);
1420 return switch (T) {
std/math/scalbn.zig+7
......@@ -1,7 +1,14 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/math/scalbnf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/scalbn.c
6
17const std = @import("../std.zig");
28const math = std.math;
39const expect = std.testing.expect;
410
11/// Returns x * 2^n.
512pub fn scalbn(x: var, n: i32) @typeOf(x) {
613 const T = @typeOf(x);
714 return switch (T) {
std/math/signbit.zig+1
......@@ -2,6 +2,7 @@ const std = @import("../std.zig");
22const math = std.math;
33const expect = std.testing.expect;
44
5/// Returns whether x is negative or negative 0.
56pub fn signbit(x: var) bool {
67 const T = @typeOf(x);
78 return switch (T) {
std/math/sinh.zig+10-4
......@@ -1,8 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - sinh(+-0) = +-0
4// - sinh(+-inf) = +-inf
5// - sinh(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/sinhf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/sinh.c
66
77const builtin = @import("builtin");
88const std = @import("../std.zig");
......@@ -11,6 +11,12 @@ const expect = std.testing.expect;
1111const expo2 = @import("expo2.zig").expo2;
1212const maxInt = std.math.maxInt;
1313
14/// Returns the hyperbolic sine of x.
15///
16/// Special Cases:
17/// - sinh(+-0) = +-0
18/// - sinh(+-inf) = +-inf
19/// - sinh(nan) = nan
1420pub fn sinh(x: var) @typeOf(x) {
1521 const T = @typeOf(x);
1622 return switch (T) {
std/math/sqrt.zig+7-7
......@@ -1,10 +1,3 @@
1// Special Cases:
2//
3// - sqrt(+inf) = +inf
4// - sqrt(+-0) = +-0
5// - sqrt(x) = nan if x < 0
6// - sqrt(nan) = nan
7
81const std = @import("../std.zig");
92const math = std.math;
103const expect = std.testing.expect;
......@@ -12,6 +5,13 @@ const builtin = @import("builtin");
125const TypeId = builtin.TypeId;
136const maxInt = std.math.maxInt;
147
8/// Returns the square root of x.
9///
10/// Special Cases:
11/// - sqrt(+inf) = +inf
12/// - sqrt(+-0) = +-0
13/// - sqrt(x) = nan if x < 0
14/// - sqrt(nan) = nan
1515pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typeOf(x).bit_count / 2) else @typeOf(x)) {
1616 const T = @typeOf(x);
1717 switch (@typeId(T)) {
std/math/tanh.zig+10-4
......@@ -1,8 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - sinh(+-0) = +-0
4// - sinh(+-inf) = +-1
5// - sinh(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/tanhf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/tanh.c
66
77const builtin = @import("builtin");
88const std = @import("../std.zig");
......@@ -11,6 +11,12 @@ const expect = std.testing.expect;
1111const expo2 = @import("expo2.zig").expo2;
1212const maxInt = std.math.maxInt;
1313
14/// Returns the hyperbolic tangent of x.
15///
16/// Special Cases:
17/// - sinh(+-0) = +-0
18/// - sinh(+-inf) = +-1
19/// - sinh(nan) = nan
1420pub fn tanh(x: var) @typeOf(x) {
1521 const T = @typeOf(x);
1622 return switch (T) {
std/math/trunc.zig+10-4
......@@ -1,14 +1,20 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - trunc(+-0) = +-0
4// - trunc(+-inf) = +-inf
5// - trunc(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/truncf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/trunc.c
66
77const std = @import("../std.zig");
88const math = std.math;
99const expect = std.testing.expect;
1010const maxInt = std.math.maxInt;
1111
12/// Returns the integer value of x.
13///
14/// Special Cases:
15/// - trunc(+-0) = +-0
16/// - trunc(+-inf) = +-inf
17/// - trunc(nan) = nan
1218pub fn trunc(x: var) @typeOf(x) {
1319 const T = @typeOf(x);
1420 return switch (T) {