如何计算分量非常大的 2 向量的大小?

发布于 2024-12-02 07:28:17 字数 409 浏览 2 评论 0原文

我正在使用一种算法,该算法生成的数字大于扩展类型允许的数字,这会导致运行时错误。

var 
  a, b, magn: Extended;
...
a := -3,6854775808e-3109;
b := 2,3020377564e+3549;
magn:= a * a + b * b; //EInvalidOp, "invalid floating point operation"

我该如何解决这个问题?


我正在将算法 SmbPitchShift Site http://www.dspdimension.com c++ 编写为 pascal。如果有人有 Pascal 语言,我会感谢

I'm working with an algorithm that generates numbers larger than the Extended type allows, which leads to runtime errors.

var 
  a, b, magn: Extended;
...
a := -3,6854775808e-3109;
b := 2,3020377564e+3549;
magn:= a * a + b * b; //EInvalidOp, "invalid floating point operation"

How can I solve this problem?


I'm writing the algorithm SmbPitchShift Site http://www.dspdimension.com c + + to pascal. If someone has it in Pascal, I will thank

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笑脸一如从前 2024-12-09 07:28:17

如果您确实想要向量大小的平方,那么这是不可能的。这确实是溢出了。

如果您确实想要大小,那么您可以像这样避免溢出:

function Magnitude(const a, b: Extended): Extended;
//calculate Sqrt(a*a + b*b) avoiding overflow
var
  x, y: Extended;
begin
  x := abs(a);
  y := abs(b);
  if x=0.0 then begin
    Result := y;
  end else if y=0.0 then begin
    Result := x;
  end else if x>y then begin
    Result := x*System.Sqrt(1.0+Sqr(y/x));
  end else begin
    Result := y*System.Sqrt(1.0+Sqr(x/y));
  end;
end;

根据我的经验,使用低效、非标准的 Extended 类型而不是 Double 通常表示你的算法有问题。总是有一种方法可以使用 Double 算术来表达算法。

If you really do want the square of the magnitude of the vector then that's not possible. That really is an overflow.

If you actually want the magnitude, then you can avoid the overflow like this:

function Magnitude(const a, b: Extended): Extended;
//calculate Sqrt(a*a + b*b) avoiding overflow
var
  x, y: Extended;
begin
  x := abs(a);
  y := abs(b);
  if x=0.0 then begin
    Result := y;
  end else if y=0.0 then begin
    Result := x;
  end else if x>y then begin
    Result := x*System.Sqrt(1.0+Sqr(y/x));
  end else begin
    Result := y*System.Sqrt(1.0+Sqr(x/y));
  end;
end;

In my experience, using the inefficient, non-standard Extended type rather than Double is usually indicative of a problem with your algorithm. Invariably there is a way to express the algorithm using Double arithmetic.

老街孤人 2024-12-09 07:28:17

如果我理解正确的话,问题是异常,而不是溢出。合理的解决方案是使用基于 SSE2 的数学,它允许饱和而不是溢出。 (IOW,如果有溢出,它会更改为类型中的最高有效数字)

据我所知,Delphi 目前不支持 SSE2 代码生成或内在函数,而这些在高级语言中是可行的。

但由于 64 位 Delphi 即将推出,并且 x86_64 通常更喜欢 SSE2 而不是 FPU,因此这种情况可能会在短期内发生变化。

If I understood you correctly, the problem is the exception, rather than the overflow. The logical solution would be to use SSE2 based math which allows for saturation rather than overflow. (IOW if something overflows, it changes to the highest valid number in the type)

To my best knowledge, Delphi does not currently support SSE2 code generation or intrinsics that would make this doable in higher level language.

But since a 64-bit Delphi is imminent, and x86_64 generally favours SSE2 over FPU, that might change short term.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文