Skip to content

Commit 75ecfdf

Browse files
committedDec 15, 2017
replace quicksort with blocksort
closes #657
·
0.15.10.2.0
1 parent c9e0141 commit 75ecfdf

File tree

4 files changed

+1099
-60
lines changed

4 files changed

+1099
-60
lines changed
 

‎std/math/index.zig‎

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,6 @@ test "math" {
174174
}
175175

176176

177-
pub const Cmp = enum {
178-
Less,
179-
Equal,
180-
Greater,
181-
};
182-
183177
pub fn min(x: var, y: var) -> @typeOf(x + y) {
184178
if (x < y) x else y
185179
}
@@ -522,3 +516,28 @@ pub fn cast(comptime T: type, x: var) -> %T {
522516
return T(x);
523517
}
524518
}
519+
520+
pub fn floorPowerOfTwo(comptime T: type, value: T) -> T {
521+
var x = value;
522+
523+
comptime var i = 1;
524+
inline while(T.bit_count > i) : (i *= 2) {
525+
x |= (x >> i);
526+
}
527+
528+
return x - (x >> 1);
529+
}
530+
531+
test "math.floorPowerOfTwo" {
532+
testFloorPowerOfTwo();
533+
comptime testFloorPowerOfTwo();
534+
}
535+
536+
fn testFloorPowerOfTwo() {
537+
assert(floorPowerOfTwo(u32, 63) == 32);
538+
assert(floorPowerOfTwo(u32, 64) == 64);
539+
assert(floorPowerOfTwo(u32, 65) == 64);
540+
assert(floorPowerOfTwo(u4, 7) == 4);
541+
assert(floorPowerOfTwo(u4, 8) == 8);
542+
assert(floorPowerOfTwo(u4, 9) == 8);
543+
}

‎std/math/sqrt.zig‎

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,34 @@
77

88
const math = @import("index.zig");
99
const assert = @import("../debug.zig").assert;
10+
const builtin = @import("builtin");
11+
const TypeId = builtin.TypeId;
1012

11-
pub fn sqrt(x: var) -> @typeOf(x) {
13+
pub fn sqrt(x: var) -> (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typeOf(x).bit_count / 2) else @typeOf(x)) {
1214
const T = @typeOf(x);
13-
switch (T) {
14-
f32 => @inlineCall(sqrt32, x),
15-
f64 => @inlineCall(sqrt64, x),
15+
switch (@typeId(T)) {
16+
TypeId.FloatLiteral => {
17+
return T(sqrt64(x))
18+
},
19+
TypeId.Float => {
20+
return switch (T) {
21+
f32 => sqrt32(x),
22+
f64 => sqrt64(x),
23+
else => @compileError("sqrt not implemented for " ++ @typeName(T)),
24+
};
25+
},
26+
TypeId.IntLiteral => comptime {
27+
if (x > @maxValue(u128)) {
28+
@compileError("sqrt not implemented for comptime_int greater than 128 bits");
29+
}
30+
if (x < 0) {
31+
@compileError("sqrt on negative number");
32+
}
33+
return T(sqrt_int(u128, x));
34+
},
35+
TypeId.Int => {
36+
return sqrt_int(T, x);
37+
},
1638
else => @compileError("sqrt not implemented for " ++ @typeName(T)),
1739
}
1840
}
@@ -274,3 +296,35 @@ test "math.sqrt64.special" {
274296
assert(math.isNan(sqrt64(-1.0)));
275297
assert(math.isNan(sqrt64(math.nan(f64))));
276298
}
299+
300+
fn sqrt_int(comptime T: type, value: T) -> @IntType(false, T.bit_count / 2) {
301+
var op = value;
302+
var res: T = 0;
303+
var one: T = 1 << (T.bit_count - 2);
304+
305+
// "one" starts at the highest power of four <= than the argument.
306+
while (one > op) {
307+
one >>= 2;
308+
}
309+
310+
while (one != 0) {
311+
if (op >= res + one) {
312+
op -= res + one;
313+
res += 2 * one;
314+
}
315+
res >>= 1;
316+
one >>= 2;
317+
}
318+
319+
const ResultType = @IntType(false, T.bit_count / 2);
320+
return ResultType(res);
321+
}
322+
323+
test "math.sqrt_int" {
324+
assert(sqrt_int(u32, 3) == 1);
325+
assert(sqrt_int(u32, 4) == 2);
326+
assert(sqrt_int(u32, 5) == 2);
327+
assert(sqrt_int(u32, 8) == 2);
328+
assert(sqrt_int(u32, 9) == 3);
329+
assert(sqrt_int(u32, 10) == 3);
330+
}

‎std/mem.zig‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,3 +527,40 @@ pub fn max(comptime T: type, slice: []const T) -> T {
527527
test "mem.max" {
528528
assert(max(u8, "abcdefg") == 'g');
529529
}
530+
531+
pub fn swap(comptime T: type, a: &T, b: &T) {
532+
const tmp = *a;
533+
*a = *b;
534+
*b = tmp;
535+
}
536+
537+
/// In-place order reversal of a slice
538+
pub fn reverse(comptime T: type, items: []T) {
539+
var i: usize = 0;
540+
const end = items.len / 2;
541+
while (i < end) : (i += 1) {
542+
swap(T, &items[i], &items[items.len - i - 1]);
543+
}
544+
}
545+
546+
test "std.mem.reverse" {
547+
var arr = []i32{ 5, 3, 1, 2, 4 };
548+
reverse(i32, arr[0..]);
549+
550+
assert(eql(i32, arr, []i32{ 4, 2, 1, 3, 5 }))
551+
}
552+
553+
/// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1)
554+
/// Assumes 0 <= amount <= items.len
555+
pub fn rotate(comptime T: type, items: []T, amount: usize) {
556+
reverse(T, items[0..amount]);
557+
reverse(T, items[amount..]);
558+
reverse(T, items);
559+
}
560+
561+
test "std.mem.rotate" {
562+
var arr = []i32{ 5, 3, 1, 2, 4 };
563+
rotate(i32, arr[0..], 2);
564+
565+
assert(eql(i32, arr, []i32{ 1, 2, 4, 5, 3 }))
566+
}

‎std/sort.zig‎

Lines changed: 979 additions & 50 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.