当前位置: 首页 > 知识库问答 >
问题:

正弦结果依赖于使用的C++编译器

谭玉泽
2023-03-14

我使用以下两个C++编译器:

  • cl.exe:Microsoft(R)C/C++优化编译器版本19.00.24210 for x86
  • g++:g++(Ubuntu 5.2.1-22Ubuntu2)5.2.1 201 51010

当使用内置正弦函数时,我得到不同的结果。这并不重要,但有时结果对我来说太有意义了。下面是一个具有“硬编码”值的示例:

printf("%f\n", sin(5451939907183506432.0));

使用cl.exe生成的结果:

0.528463

G++的结果:

0.522491

我知道G++的结果更准确,我可以使用一个额外的库来得到同样的结果,但这不是我的重点。我会真正理解这里发生的事情:为什么cl.exe是错误的?

有趣的是,如果我在param上应用(2*pi)的模,那么我得到的结果与g++相同...

共有1个答案

雷国兴
2023-03-14

您有一个19位的文字,但double通常有15-17位的精度。因此,可以得到很小的相对误差(当转换为double时),但足够大的绝对误差(在正弦计算的上下文中)。

实际上,标准库的不同实现在处理如此大的数字时存在差异。例如,在我的环境中,如果我们执行

std::cout << std::fixed << 5451939907183506432.0;

G++结果为5451939907183506432.000000
cl结果为5451939907183506400.000000

不同之处在于,早于19的cl版本有一个格式算法,该算法只使用有限数量的数字,并用零填充剩余的小数位数。

此外,让我们看看这段代码:

double a[1000];
for (int i = 0; i < 1000; ++i) {
    a[i] = sin(5451939907183506432.0);
}
double d = sin(5451939907183506432.0);
cout << a[500] << endl;
cout << d << endl; 

使用我的x86 VC++编译器执行时,输出为:

0.522491
0.528463

似乎在填充数组时,sin被编译为__vdecl_sin2的调用,当有单个操作时,被编译为__libm_sse2_sin_precise的调用(使用/fp:precise)。

在我看来,对于sin计算来说,您的数字太大了,无法期望不同编译器的相同行为,也无法期望通常的正确行为。

 类似资料:
  • 我正在使用mongodb和Spring Boot。最近,我的mongodb升级到了3.0版本。 我对Spring使用以下Gradle依赖项: 如果我查看maven存储库中的gradle:,我会看到以下内容(http://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-mongodb/1.2.6

  • Java和Maven新手。 我试图配置我的应用程序,以便我可以通过cmd线生成一个jar,其中包含我所有的依赖项。 据我所知,我正在正确设置Pom以使用此插件:https://github.com/javafx-maven-plugin/javafx-maven-plugin 以下是我在Pom中的依赖项: 在我的

  • 问题内容: 我意识到这更多是语义上的追求,而不是功能上的追求。 我有三种类型的编译范围依赖项: 仅编译范围,在运行时不使用。GWT客户端开发人员,MVP4G,RestyGWT,源保留注释处理器。我使用REST,因此不需要GWT服务器端。 提供-编译所需的Hibernate jar,但由JBoss提供。 编译+运行时jars。 对于情况2,我们可以使用提供的范围。情况3,我们将使用编译范围。 但是,

  • 这完全是一个新手的问题——所以我道歉。我正在拓展视野,潜入Java。 我试图编译一些从Tika依赖项导入的java类。 我想如果我把我的java文件放在和tika-app-1.6.jar目录相同的目录下,编译器会找到它需要的东西。它返回了19个它找不到的符号错误。 所以,我尝试过:javactest.java, javac-classpath"test.java, javac-classpath"

  • 我正在构建一个JavaProject,这是一个项目的插件[加载在我的工作区中,并且是类型jar和范围编译的MaterialsDep的直接依赖项]。在eclipse中查看MaterialsDep的pom依赖层次结构,CB所需的所有jars都显示为已解析并正确列出。然而,在项目AP上运行只复制直接依赖项,而不复制其他内容。 运行依赖关系:树显示: 这是直接的依赖关系。 我应该如何确保的依赖关系被识别和