Metaprog can be abstruse

kdevel kdevel at vogtner.de
Sun Jan 1 23:05:46 UTC 2023


On Wednesday, 28 December 2022 at 13:57:13 UTC, Dom Disc wrote:
> [...]
> I now have a function
>
> ```d
> ubyte maxpow(const ulong base) { }
> ```

Code?

> That returns the maximum power of the given base that fits in a 
> ucent

ucent? Cannot use cent/ucent or core.int128's types here.

> (for smaller target types, shift down the result by one for 
> each halfing of the size).

What do you mean by "shift down"? "Shift right" aka "divide by 
two"?

> With this you can create the function
>
>     ```d
>     ulong[] powersOf(byte n)
>     {
>        import std.range : iota;
>        import std.algorithm : map;
>        return iota(maxpow(n)>>1).map!(p => ulong(n)^^p).array;
>     }
>     ```

This generates too few elements.

```
import std.stdio;
import mod_maxpow;

auto powersOf (T) (ulong n)
{
    import std.range : iota;
    import std.algorithm : map;
    import std.array : array;
    return iota(maxpow!T (n) + 1).map!(p => n^^p).array;
}

int main (string [] args)
{
    static immutable ranksOf17 = powersOf!ulong (17);
    writeln (ranksOf17);
    return 0;
}
```

prints

```
[1, 17, 289, 4913, 83521, 1419857, 24137569, 410338673, 
6975757441, 118587876497, 2015993900449, 34271896307633, 
582622237229761, 9904578032905937, 168377826559400929, 
2862423051509815793]
```

`maxpow!ulong(17)` is 15. Counting starts with 0 so we must add 
one.

> If this function is used to create lookup-tables, it will be 
> called only during compile-time, so the imports are not in the 
> resulting executable (therefore it doesn't matter that I 
> replaced pow by the buildin ^^).
>
> ```d
> static immutable ulong[maxpow(17)>>1] ranksOf17 = powersOf(17);
> ```

Unnecessary code duplication.

> I think this is much more readable as a list of obscure number 
> literals, it is safe to use,

Unit tests?




More information about the Digitalmars-d mailing list