相关疑难解决方法(0)

当y是整数时,fmod()是否准确?

在使用double fmod(double x, double y)y是一个整数时,结果似乎总是精确的.

(这是y一个完全确切的数字,int在这里不是意思.)

也许C不要求 fmod()提供这些选择的情况下一个确切的答案,但我试过编译器,结果是准确的,即使当商x/y是不能准确地表示.

  1. y是整数时,是否预期确切的答案?
  2. 如果没有,请提供一个反例.

例子:

double x = 1e10;
// x = 10000000000
printf("%.50g\n", fmod(x, 100));
// prints 0

x = 1e60;
// x = 999999999999999949387135297074018866963645011013410073083904
printf("%.50g\n", fmod(x, 100));
// prints 4

x = DBL_MAX;
// x = 179769313486231570...6184124858368
printf("%.50g\n", fmod(x, 100));
// prints 68

x = 123400000000.0 / 9999;
// x = 12341234.1234123408794403076171875
printf("%.50g %a\n", fmod(x, 100), …
Run Code Online (Sandbox Code Playgroud)

c floating-point

9
推荐指数
2
解决办法
1258
查看次数

Visual C++ 2012中的正弦计算不一致?

请考虑以下代码:

// Filename fputest.cpp

#include <cmath>
#include <cstdio>

int main()
{
    double x;
    *(__int64 *) &x = 0xc01448ec3aaa278di64; // -5.0712136427263319
    double sine1 = sin(x);
    printf("%016llX\n", sine1);
    double sine2;
    __asm {
    fld x
    fsin
    fstp sine2
    }
    printf("%016llX\n", sine2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用Visual C++ 2012(cl fputest.cpp)编译并执行程序时,输出如下:

3FEDF640D8D36174
3FEDF640D8D36175
Run Code Online (Sandbox Code Playgroud)

问题:

  • 为什么这两个值不同?
  • 是否可以发出一些编译器选项,以便计算出的正弦值完全相同?

c c++ assembly visual-c++ x87

8
推荐指数
1
解决办法
1394
查看次数

FPU用什么算法来计算超越函数?

现代FPU用什么方法来计算超越函数

例如,英特尔CPU提供指令,例如FSIN,FCOS,FYL2X等我很好奇,什么样的算法将用于实际的硬件实现这些.

我天真的猜测是泰勒系列可能与一些查找表相结合,但这只不过是一个疯狂的猜测.请赐教.

PS这个问题比英特尔硬件更普遍.

hardware math floating-point fpu numerical-methods

7
推荐指数
1
解决办法
712
查看次数

sin 和 cos 是如何在硬件上实现的?

我一直在研究如何计算正弦和余弦。我找到了一些“标准”方法,包括查找表、CORDIC 算法和泰勒级数。我还发现大多数现代处理器都有一个汇编指令来计算三角函数。我想知道的是这些命令是如何工作的。

所以,我的问题是:当前的处理器使用什么特定算法来计算正弦和余弦?

assembly trigonometry

7
推荐指数
1
解决办法
3259
查看次数

如何加速棘手的随机数生成

我有一些代码执行许多日志tancos双打操作.我需要这个尽可能快.目前我使用的代码如

#include <stdio.h>
#include <stdlib.h>
#include "mtwist.h"
#include <math.h>


int main(void) {
   int i;
   double x;
   mt_seed();
   double u1;
   double u2;
   double w1;
   double w2;
   x = 0;
   for(i = 0; i < 100000000; ++i) {
     u1 = mt_drand();
     u2 = mt_drand();
     w1 = M_PI*(u1-1/2.0);
     w2 = -log(u2);
     x += tan(w1)*(M_PI_2-w1)+log(w2*cos(w1)/(M_PI_2-w1));
   }
   printf("%f\n",x); 

   return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用gcc.

有两种明显的方法可以加快速度.首先是选择更快的RNG.第二是加快先验功能.
要做到这一点,我想知道

  1. 如何在x86上的程序集中实现tan和cos?我的CPU是AMD FX-8350,如果它有所作为.(答案fcoscosfptantan.)
  2. 如何使用查找表来加速计算?我只需要32位的精度.例如,你可以使用一个大小为2 ^ 16的表来加速tan和cos操作吗?

英特尔优化手册

如果不需要使用80位的扩展精度来评估超越函数,则应用程序应考虑使用基于软件的替代方法,例如使用插值技术的基于查找表的算法.通过选择所需的数值精度和查找表的大小,并利用SSE和SSE2指令的并行性,可以通过这些技术提高超越性能. …

c math performance assembly micro-optimization

6
推荐指数
4
解决办法
795
查看次数

如何查看System.Math.Sin的源代码?

在这个链接中,我们可以看到System.Math类的源代码.但我找不到正弦定义的源代码.

这里有什么我想念的吗?

.net c# clr

6
推荐指数
2
解决办法
2546
查看次数

math.h 中的 sin(x) 或 cos(x) 是如何实现的?

可能的重复:
C 如何计算 sin() 和其他数学函数?

我很好奇如何sin以及cos如何在低水平上实施。

我刚刚查看了 math.h 内部,找不到sin和 的声明cos。但由于这对我来说是一条死胡同,所以我转向你,所以。

我想知道计算正弦需要多少次操作以及使用什么技巧来加速。它们在不同硬件上的实现方式是否不同,是否有处理器支持本机指令?例如,与添加相比,它们的速度有多快?

谢谢!

c c++ algorithm math.h

5
推荐指数
0
解决办法
435
查看次数

没有 math.h 的 sin 和 cos 函数

我不能使用C ++函数sin(),并cos()因引起的PS3 3.40 SDK编译器的某些问题。sin()&的计算是什么,cos()所以我可以在不需要的情况下使用函数math.h

到目前为止,我已经想出了这些,但它们似乎无法正常运行?

float sin(float deg) {
    bool neg = false;
    while (deg >= 360) deg = deg - 360;
    while (deg < 0) deg = deg + 360;
    if (deg > 180) {
        deg = deg - 180;
        neg = true;
    }
    float ret = (float)(4*deg*(180-deg))/(40500-(deg*(180-deg)));
    if (neg)return ret*-1;
    return ret;
}

float cos(float AnglesDeg)
{
 float AnglesRad = DegreesToRadians(AnglesDeg);
 float Rad = (float)(PI/2.0f)-AnglesRad;
 float ang = …
Run Code Online (Sandbox Code Playgroud)

c++ math trigonometry

3
推荐指数
1
解决办法
1万
查看次数

如何用 C 语言正确构建 sin 查找表?

为了节省调用性能sin,并处理整数角度(更便于操作和保存),而不是使用浮点作为角度,我正在构建一个sin查找函数,其中 4096 个单位等于 2pi 弧度。为了节省内存,我只存储前 1024 个 sin 值,它们相当于sin( [0, pi/2) ).

static const float SinTable[1024] = {0, 0.00153398, ..., 0.999995, 0.999999};
Run Code Online (Sandbox Code Playgroud)

为了处理第三象限​​和第四象限的角度,我简单地有条件地否定:

return Angle&2048 ? -UnsignedSin : UnsignedSin;
Run Code Online (Sandbox Code Playgroud)

UnsignedSin查找到的 sin 值位于 之间的位置[0, 2048)。但我该如何处理第二象限和第四象限呢?如何通过检查角度是否位于第二或第四象限(例如 )[0, 1)来有条件地正确映射 存储的 sin 值?我尝试了这个,但这不太正确,因为角度的结果是 0.999999 而不是它应该是的 1。[1, 0)Angle&10241024

const float UnsignedSin = SinTable[(Angle&1024 ? ~A : A)&1023];
Run Code Online (Sandbox Code Playgroud)

1 的值永远不会存储在 sin 表中,所以我假设 a1-SinTable[...]是必需的?但我不能完全正确地理解它。

c trigonometry lookup-tables

3
推荐指数
1
解决办法
2656
查看次数

Intel x86_64 汇编,如何在 x87 和 SSE2 之间移动?(计算双精度数的反正切)

我尝试计算双精度浮点值的反正切,该值保存在 xmm 寄存器中。对于正常的浮点,可以使用旧的 x87 指令 FPATAN,但是如何使用 double 来做到这一点?

precision assembly x86-64 intel

2
推荐指数
1
解决办法
1222
查看次数