mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Add @intlog2 for Floored CT log-base2 (#2355)
* Add `@intlog2` for Floored CT log-base2 --------- Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
@@ -344,6 +344,23 @@ macro log(x, base)
|
||||
*>
|
||||
macro log2(x) => $$log2(values::promote_int(x));
|
||||
|
||||
<*
|
||||
@require values::@is_int($x) : `The input value must be an integer.`
|
||||
@require $x >= 0 : `The input value must be a positive integer.`
|
||||
@return `A floored base-2 log of an input integer value.`
|
||||
*>
|
||||
macro @intlog2($x)
|
||||
{
|
||||
$if $x <= 1:
|
||||
return 0;
|
||||
$endif
|
||||
|
||||
$typeof($x) $z = 0;
|
||||
$for var $y = $x; $y > 0; $y >>= 1, ++$z: $endfor
|
||||
|
||||
return $z - 1;
|
||||
}
|
||||
|
||||
<*
|
||||
@require values::@is_promotable_to_floatlike(x) : `The input must be a number or a float vector`
|
||||
*>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
### Changes / improvements
|
||||
- Support `alias foo = module std::io` module aliasing.
|
||||
- Add compile-time `@intlog2` macro to math.
|
||||
|
||||
### Fixes
|
||||
- List.remove_at would incorrectly trigger ASAN.
|
||||
|
||||
@@ -457,6 +457,24 @@ fn void test_log() @test
|
||||
}
|
||||
}
|
||||
|
||||
fn void test_ct_intlog2() @test @if($feature(SLOW_TESTS))
|
||||
{
|
||||
uint128 actual, expected;
|
||||
$for var $x = 0; $x <= 128; ++$x :
|
||||
expected = (uint128)math::floor(math::log2($x));
|
||||
actual = (uint128)math::@intlog2($x);
|
||||
assert(expected == actual, "input %d: floor(log2($x)) -> %d is not equal to @intlog2($x) -> %d", $x, expected, actual);
|
||||
$endfor
|
||||
|
||||
var $logme = (uint128)1;
|
||||
$for var $x = 0; $x < 8192; ++$x :
|
||||
$logme *= 13;
|
||||
expected = (uint128)math::floor(math::log2((uint128)$logme));
|
||||
actual = (uint128)math::@intlog2((uint128)$logme);
|
||||
assert(expected == actual, "input %d (idx %d): floor(log2(|$logme|)) -> %d is not equal to @intlog2(|$logme|) -> %d", $logme, $x, expected, actual);
|
||||
$endfor
|
||||
}
|
||||
|
||||
fn void test_pow() @test
|
||||
{
|
||||
int[<10>] e = { 2, 1, 0, -1, -2, 2, 1, 0, -1, -2 };
|
||||
|
||||
Reference in New Issue
Block a user