gpt4 book ai didi

d - 无法在 D 中的编译时递归地将 BigInt 乘以一定数量的迭代

转载 作者:行者123 更新时间:2023-12-05 05:38:12 25 4
gpt4 key购买 nike

我需要获得任意数量变量的乘积。变量的实际数量及其值将在编译时已知,但我不能对这些进行硬编码,因为它们来自编译时使用模板对类型进行的反射。

我可以在运行时将它们的乘积放入 BigInt 中,但是如果我尝试在编译时使用模板和不可变变量这样做,我只能获得一个乘积在出现编译器错误之前使用少量变量。

这是一个不使用类型特征的浓缩示例,但存在同样的问题:

import std.bigint;   // BigInt
import std.stdio; // writeln

template Product(ulong value) {
immutable BigInt Product = value;
}

template Product(ulong value, values...) {
immutable BigInt Product = Product!value * Product!values;
}

immutable BigInt NO_PROBLEM = cast(BigInt)ulong.max * ulong.max * ulong.max;
immutable BigInt ERROR = Product!(ulong.max, ulong.max, ulong.max);

void main() {
writeln(NO_PROBLEM, " ", ERROR);
}

尝试用 dmd 编译器编译它会给出错误信息:

/opt/compiler-explorer/dmd2-nightly/dmd2/linux/bin64/../../src/druntime/import/core/cpuid.d(121): Error: static variable `_dataCaches` cannot be read at compile time
/opt/compiler-explorer/dmd2-nightly/dmd2/linux/bin64/../../src/phobos/std/internal/math/biguintcore.d(200): called from here: `dataCaches()`
/opt/compiler-explorer/dmd2-nightly/dmd2/linux/bin64/../../src/phobos/std/internal/math/biguintcore.d(1547): called from here: `getCacheLimit()`
/opt/compiler-explorer/dmd2-nightly/dmd2/linux/bin64/../../src/phobos/std/internal/math/biguintcore.d(758): called from here: `mulInternal(result, cast(const(uint)[])y.data, cast(const(uint)[])x.data)`
/opt/compiler-explorer/dmd2-nightly/dmd2/linux/bin64/../../src/phobos/std/bigint.d(380): called from here: `mul(this.data, y.data)`
/opt/compiler-explorer/dmd2-nightly/dmd2/linux/bin64/../../src/phobos/std/bigint.d(380): called from here: `this.data.opAssign(mul(this.data, y.data))`
/opt/compiler-explorer/dmd2-nightly/dmd2/linux/bin64/../../src/phobos/std/bigint.d(430): called from here: `r.opOpAssign(y)`
<source>(9): called from here: `Product.opBinary(Product)`
<source>(13): Error: template instance `example.Product!(18446744073709551615LU, 18446744073709551615LU, 18446744073709551615LU)` error instantiating
ASM generation compiler returned: 1

我对此感到很困惑。乍一看,似乎在编译时请求了太多内存(我会理解编译时执行期间可用的堆是否少于运行时),但我不确定这是否真的是问题所在,因为我可以在编译时生成结果,而不是通过递归模板。

这可能是 Phobos 运行时中的错误,还是未记录的限制?
std.bigint 似乎被设计成能够在编译时产生巨大的值(value),像这样的行编译和执行得很好(并且膨胀了可执行文件的大小!):

immutable BigInt VERY_BIG = BigInt(2) ^^ 10000000;

最佳答案

错误发生在这个函数的最后一行:

https://github.com/dlang/phobos/blob/e0af01c8adf75b164b43832dd7544e297347cf6f/std/internal/math/biguintcore.d#L1824-L1844

在这种情况下,std.bigint 似乎目前并未编写为在 CTFE 中工作。也许简单地使 GC.free 调用以 __ctfe 为条件即可解决问题。

至于为什么它发生在 10 次迭代而不是 11 次迭代时,该函数有一个分支允许在没有动态内存分配的情况下对小数字执行计算。

关于d - 无法在 D 中的编译时递归地将 BigInt 乘以一定数量的迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72986499/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com