- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我使用大数时,我遇到了 C# 中 Math.Sin 函数的这种奇怪行为;例如:
C#:.Net 4.7.2:Math.Sin(6.2831853071795856E+45) = 6.2831853071795856E+45
C++:sin(6.2831853071795856E+45) = -0.089650623841643268
任何想法如何获得与 C++ 相同的结果?
C# 示例:
double value = 6.2831853071795856E+45;
Console.WriteLine(Math.Sin(value));
C++ 示例:
double x = 6.2831853071795856E+45;
double result;
result = sin(x);
cout << "sin(x) = " << result << endl;
最佳答案
这两个答案都非常错误——但你提出的问题很可能会让你陷入困境。
sin(6.2831853071795856 × 10⁴⁵)的真值约为0.09683996046341126;此近似值与真实值的差异小于真实值的 10⁻¹⁶ 部分。 (我使用具有 165 位中间精度的 Sollya 计算了这个近似值。)
但是,通过询问带有签名 public static double Sin (double a)
的 C# 函数,您不会得到这个答案。 ,或带有签名 double sin(double)
的 C++ 函数.为什么? 6.2831853071795856 × 10⁴⁵ 不是 IEEE 754 binary64 或“double”浮点数,因此您最多只能了解附近浮点数的 sin 是什么。最接近的浮点数,通常输入 6.2831853071795856E+45
会得到什么进入一个程序,是6283185307179585571582855233194226059181031424,它与6.2831853071795856 × 10⁴⁵1457612⁵1457612⁵1457612⁵1457612⁵1457612⁵1487612⁵1457612⁵1487612⁵1457612⁵1457612⁵1457612⁵1487612⁵1487612⁵9
该IEEE 754 binary64浮点数6283185307179585571582855233194226059181031424是一个很好的近似6.2831853071795856×10⁴⁵在相对误差(它相差小于10⁻¹⁷份真值的),但绝对误差〜2.84×10²⁸远远超出了周期2π罪(远不及𝜋的整数倍)。 因此,您通过询问双重函数得到的答案与您的源代码似乎提出的问题没有相似之处:您在哪里编写 sin(6.2831853071795856E+45)
,而不是罪(6283185307179585600000000000000000000000000000)充其量你会得到罪(6283185307179585571582855233194226059181031424),大约是0.8248163906169679(再次,加上或减去10个-16厘米部分的真正值(value))。
这不是浮点的错,这出错了。 浮点算术可以很好地保持相对误差很小——一个好的数学库可以很容易地使用 binary64 浮点数来计算你提出的问题的好答案。如果您的标尺没有超过 10⁴⁵ 的等级,那么您对 sin 的输入误差也可能来自一个小的测量误差。错误可能来自某种近似错误,例如通过使用截断级数来评估给您 sin 输入的任何函数,无论您使用哪种算术来计算该输入。 问题是您要求在一个小的相对误差对应于远远超出函数周期的绝对误差的点处评估周期函数 (sin)。
因此,如果您发现自己试图回答 6.2831853071795856 × 10⁴⁵ 的罪过是什么的问题,那么您可能做错了什么——天真地使用双浮点数学库例程并不能帮助您回答问题。但是使这个问题更加复杂的是,您的 C# 和 C++ 实现都无法返回接近 sin(6283185307179585571582855233194226059181031424) 真实值的任何值:
fsin
指令,根据 Intel manual仅限于域 [−2⁶³, 2⁶³] 中的输入,而您的输入超出了 2¹⁵²。正如您所观察到的,该域之外的输入是逐字返回的,即使它们对于正弦函数来说是完全无意义的值。Math.Sin(Math.IEEERemainder(6.2831853071795856E+45, 2*Math.PI))
这样,您就不会误用 Math.Sin 库例程,因此答案至少应该在 [−1,1] 中,因为正弦应该如此。您可以使用 sin(fmod(6.2831853071795856E+45, 2*M_PI))
安排在 C/C++ 中获得相同或接近的结果。 .但是您可能会得到接近 0.35680453559729486 的结果,这也是错误的——参见下文关于参数减少的内容。sin
的C++实现但是,您正在使用的只是损坏了;在 C++ 标准中对域没有这样的限制,并且使用广泛可用的高质量软件来计算参数减少模好问题!)。fldpi
指令以 64 位精度加载二进制 80 格式的近似值 𝜋,然后使用 fprem1
减少模那个近似于𝜋。这种近似不是很好:在内部,Intel 架构近似 𝜋 0x0.c90fdaa22168c234cp+2 = 3.14159265358979323845859109827323700303965 14,16 16 16 16 5 16 5 16 16 16 5 16 16 5 9 7 位精度为 4,595然后将其四舍五入为 binary80 浮点数 0x0.c90fdaa22168c235p+2 = 3.14159265358979323851280895940618620443274267017841338912513 位,精度为 16 位。fldpi
/fldpi
/fprem1
给出大约 -0.8053589558881794,与 x87 单元设置为 binary64 算术(53 位精度)而不是 binary80 算术(64 位精度)相同,或者首先使用 binary64 逼近 𝜋,给出大约 0.356804953556972因此,显然您的 C++ 数学库正在做其他事情来为一个糟糕的问题提供错误的答案!fsin
得到 sin(2𝜋𝑡) 的近似值。在这种情况下,由于 𝑡 是一个整数(实际上对于任何二进制 64 位浮点数,其大小至少为 2⁵²,它们都是整数),你会得到恰好 0。
关于c# - c++ 和 c# sin 函数大值的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66030225/
*> sin sin 0.5 :10:1: Non type-variable argument in the constraint: Floating (a -> a) (Use Flexible
我一直在尝试实现一个快速但更重要的是准确的自定义 sin 函数(我不能在我的项目中使用 math.h sin)。我不是这类数学方面的专家,所以请和我一起工作 XD。在网上稍作搜索后,我发现了以下代码,
我编写了一个 Prolog 程序来求解简单的三角方程。我写它是为了获取三角函数的值。例如,我可以获得 sin(45) 的值,但我无法将 sin(45) 的值赋给术语 sin(45 )。我尝试了 =,=
这是我的代码: # point of intersection between opposite and hypotenuse x,y = pygame.mouse.get_pos() # u
我有一个简单的 C++ 代码,它在一个值 vector 上运行一个默认的 sin 函数。 static void BM_sin() { int data_size = 10000000
有什么区别,如何让 WebGL 的 sin 产生与 Math.sin 相同的结果? 编辑:我的顶点着色器中有一些代码(这不是全部代码),它计算球体周围的斐波那契点,并且应该将顶点放置在这个新点上: a
我有一个客户试图在一个过时的编译器上编译,该编译器似乎没有来自 c++11 的 std::sin 和 std::cos。 (而且他们不能升级)我正在寻找某种快速修复方法来插入标题的顶部以使 std::
#include #include const int TERMS = 7; const float PI = 3.14159265358979; int fact(int n) { r
不幸的是,标准 C++ 库没有对 sincos 的单一调用,这为这个问题提供了空间。 第一个问题: 如果我想计算 sin 和 cos,计算 sin 和 cos 更便宜,还是先计算 sin 再计算 sq
我正在实时渲染 500x500 点。我必须使用 atan() 和 sin() 函数计算点的位置。通过使用 atan() 和 sin(),我得到了 24 fps(每秒帧数)。 float thetaC
我知道 Math.sin() 可以工作,但我需要自己使用 factorial(int) 实现它 我已经在下面有一个阶乘方法是我的 sin 方法,但我无法获得与 Math.sin() 相同的结果: pu
我想知道,当我在 Reddit thread 中发现问题时,为什么 Math.sin(double) 委托(delegate)给 StrictMath.sin(double) .提到的代码片段如下所示
为什么 Pytorch 和 Numpy 的三角函数在以 Pi 的整数倍计算时会导致数量级上如此巨大的差异? >>> torch.sin(torch.ones(1)*2*np.pi) tensor([1
这是一个很简单的问题,让我很困惑。 我收到一个源文件的以下错误,但另一个没有: 4 src/Source2.cpp:1466: error: no matching function for cal
我在 JavaScript 中发现了一个有趣的异常现象。其中重点是我尝试通过预先计算 sin(x) 和 cos(x) 并简单地引用预先计算的值来加速三 Angular 变换计算。 直觉上,预计算比每次
我正在尝试用 Python 对方程 x=a*sin(x) 进行数值求解,其中 a 是某个常数。我已经尝试先用符号求解方程,但似乎这种特殊的表达形式并没有在 sympy 中实现。我也尝试过使用 symp
我在使用 matlab 计算时遇到问题。我知道“pi”是一个 float ,并不精确。因此,在 matlab 中 sin(pi) 不完全为零。我的问题是,如果“pi”不准确,那么为什么 sin(pi/
如何只使用 sin 或 cos 而不是 Math.sin 或 Math.cos?我尝试导入 Math.* 但我想我可能需要对命名空间做一些事情? 最佳答案 import static java.lan
测试代码: #include #include const int N = 4096; const float PI = 3.1415926535897932384626; float cosin
我在其他问题中读到,例如由于浮点表示,sin(2π) 不为零,但非常接近。这个非常小的错误在我的代码中不是问题,因为例如我可以四舍五入 5 位小数。 但是当2π乘以一个非常大的数时,误差就会放大很多。
我是一名优秀的程序员,十分优秀!