gpt4 book ai didi

delphi - 这个产生超大数字的 C 乘法的等效 Delphi 代码是什么?

转载 作者:行者123 更新时间:2023-12-03 15:01:52 32 4
gpt4 key购买 nike

这个问题的背景是......我正在尝试从 Wikipedia: Hamming weight 移植 C 函数 int popcount_3(uint64_t x) ,但它的算法不是本题的重点。

假设x是无符号64位值的最大数量(即x = 18446744073709551615),在计算结束时,C代码将计算:

uint64_t iResult = 578721382704613384ull * 72340172838076673ull;

首先我怀疑C代码引发了溢出错误,因为使用浮点乘法时的实际/真实结果等于41864804849942400000000000000000000,但事实上,没有编译该 C 代码错误。输出为4627501566018457608

众所周知,上述 C 代码的 Delphi 代码为:

iResult := UInt64(578721382704613384) * UInt64(72340172838076673);

Delphi 编译器引发错误E2099 转换或算术运算溢出。好的,我发现这个错误是合理的。

所以,我的问题是...用于超大数字乘法的等效 Delphi 代码是什么,以便 Delphi 给出与 C 中相同的结果?

稍后添加

为了预测即将出现的潜在问题“为什么我使用真常量表达式提供示例?”,原因是我想创建一个计算 computer word 中的位数的 true 常量通过计算 High(NativeUInt) 中设置的位数。

重现步骤

GCC 4.8.1(MinGW)

#include <stdio.h>
#include <stdint.h>

int main () {
uint64_t iResult = 578721382704613384ull * 72340172838076673ull;
printf("iResult = %llu\n", iResult); // output --> 4627501566018457608
return 0;
}

64位Windows编译器模式下的Delphi XE3

procedure Test;
var
iResult : UInt64;
RealResult: Double;

begin
iResult := UInt64(578721382704613384) * UInt64(72340172838076673);
RealResult := 578721382704613384.0 * 72340172838076673.0;
WriteLn('iResult = ', iResult); // error --> E2099 Overflow in ...
WriteLn('RealResult = ', RealResult); // output --> 4.18648048499424E+0034
end;

最佳答案

Delphi 编译器尝试在编译时计算常量表达式 UInt64(578721382704613384) * UInt64(72340172838076673) 并向您报告溢出错误。

解决方案是使用变量:

var
iResult, i1, i2 : UInt64;
RealResult: Double;

begin
i1 := 578721382704613384;
i2 := 72340172838076673;
iResult := i1 * i2;
RealResult := 578721382704613384.0 * 72340172838076673.0;

此代码产生所需的结果。

请注意,项目选项中的溢出检查标志必须关闭。或者在代码中使用编译器指令,例如

  {$OVERFLOWCHECKS OFF}
iResult := i1 * i2;
{$OVERFLOWCHECKS ON}

编辑基于@hvd的警告

这些指令仅在项目选项中的溢出检查处于打开的情况下才有意义。如果不是,则可以省略这些指令。

第三种方法,最常见和通用的,是使用 {$ifopt ...} 指令(@hvd,再次感谢):

{$ifopt Q+} // If option is On ...
{$Q-} // then turn it Off ...
{$define TURNQON} // and keep in mind that it must be restored
{$endif}
iResult := i1 * i2;
{$ifdef TURNQON}{$Q+}{$undef TURNQON}{$endif}

但是,更好的方法是使用已经计算出的所需结果,然后再使用此类技巧。

关于delphi - 这个产生超大数字的 C 乘法的等效 Delphi 代码是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32410902/

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