gcc: printf 和 long double 会导致错误的输出。 [C - 类型转换混乱]

2023-11-26

我对 C 相当陌生。我尝试为 Vector 编写函数,但一定有问题。
这是代码:

/* Defines maths for particles. */

#include <math.h>
#include <stdio.h>

/* The vector struct. */
typedef struct {
    long double x, y, z;
} Vector;

Vector Vector_InitDoubleXYZ(double x, double y, double z) {
    Vector v;
    v.x = (long double) x;
    v.y = (long double) y;
    v.z = (long double) z;
    return v;
}

Vector Vector_InitDoubleAll(double all) {
    Vector v;
    v.x = v.y = v.z = (long double) all;
    return v;
}


Vector Vector_InitLongDXYZ(long double x, long double y, long double z) {
    Vector v;
    v.x = x;
    v.y = y;
    v.z = z;
    return v;
}

Vector Vector_InitLongDAll(long double all) {
    Vector v;
    v.x = v.y = v.z = all;
    return v;
}

Vector Vector_AddVector(Vector *v1, Vector *v2) {
    Vector v3;
    v3.x = v1->x + v2->x;
    v3.y = v1->y + v2->y;
    v3.z = v1->z + v2->z;
    return v3;
}

Vector Vector_AddDouble(Vector *v1, double other) {
    Vector v2;
    v2.x = v1->x + other;
    v2.y = v1->y + other;
    v2.z = v1->z + other;
    return v2;
}

Vector Vector_AddLongD(Vector *v1, long double other) {
    Vector v2;
    v2.x = v1->x + other;
    v2.y = v1->y + other;
    v2.z = v1->z + other;
    return v2;
}

void Vector_Print(Vector *v) {
    printf("X: %Lf, Y: %Lf, Z: %Lf\n", v->x, v->y, v->z); //Before edit: used %ld
}

double Vector_Length(Vector *v) {
    return pow(pow(v->x, 2) + pow(v->y, 2) + pow(v->z, 2), 0.5);
}



int main() {
    Vector v = Vector_InitDoubleXYZ(2.0, 1.0, 7.0); //Before edit: (2.0d, 1.0d, 7.0d);

    Vector_Print(&v);
}

我使用gcc来编译。跑步vector.exe在命令行中给我以下输出:

X:0,Y:-2147483648,Z:9650176

我不明白为什么会发生这种情况。

我很欣赏任何提示(甚至是关于我的编码风格或任何可以在代码中做得更好的提示)。
谢谢你,

Update: 使用MSVC编译器工作得很好,这似乎是gcc的问题。你知道为什么会发生这种情况吗?


问题(在修复了使用整数说明符进行浮点格式化时的各种问题之后)是您将 GCC 类型与不理解它们的 MSVC 运行时混合在一起。

首先,MinGW 是一个 GCC 编译器,但它使用 MSVC 运行时来提供大部分运行时支持。这对于printf()函数族的特点是只有格式说明符msvcrt.dll仅支持且仅支持的类型msvcrt.dll支持会起作用。但 GCC 对此一无所知,因此它将传递自己的类型,当然,格式说明符是您在格式字符串中传递的任何内容(尽管 GCC 可能会发出并不真正适用于msvcrt.dll情况)。看奇怪的“unsigned long long int”行为对于一些基于 64 位整数的示例(我认为较新版本的msvcrt.dll不过可能已经修复了部分或全部 64 位 int 问题)。

您遇到的这个问题的另一部分是long doubleGCC 中的类型不同于long double在 MSVC 中。 GCC 使用 96 位或 128 位类型long double在 x86 或 x64 目标上(请参阅http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html)。然而,MSVC 使用 64 位类型 - 基本上long double完全一样double for msvcrt.dll (http://msdn.microsoft.com/en-us/library/9cx8xs15.aspx):

以前的 16 位版本的 Microsoft C/C++ 和 Microsoft Visual C++ 支持长双精度、80 位精度数据类型。然而,在 Win32 编程中,long double 数据类型映射到 double、64 位精度数据类型。 Microsoft 运行时库提供数学函数的长双精度版本只是为了向后兼容。 long double 函数原型与其对应的 double 函数原型相同,只是 long double 数据类型替换了 double 数据类型。这些函数的长双精度版本不应在新代码中使用。

归根结底,GCC/MinGWlong double类型将与格式化的 I/O 不兼容msvcrt.dll。要么切换到使用double与 MinGW,或者如果您需要使用long double你必须将这些值转换为(double)用于格式化 I/O 或提出您自己的格式化例程。

另一种选择可能是使用 Cygwin 下的 GCC 编译器,我认为这将避免依赖msvcrt.dll用于 I/O 格式化(以依赖 Cygwin 环境为代价)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gcc: printf 和 long double 会导致错误的输出。 [C - 类型转换混乱] 的相关文章

随机推荐

  • 通过内存地址获取对象

    我正在尝试寻找在 R 中制作链接列表的方法 I found tracemem 返回对象的内存地址 那么有什么方法可以通过内存地址找到对象呢 那不是这样做的方法 如果您想要引用 请使用引用类或环境 像这样 首先 我将把三个对象放入链接列表中
  • 未调用 WSFederationAuthenticationModule.RedirectingToIdentityProvider 事件

    我的 Global asax cs 文件中有 2 个事件 WSFederationAuthenticationModule SecurityTokenValidated and WSFederationAuthenticationModul
  • 使用指针修改字符串时发生分段错误?

    Context 我正在学习 C 并且正在尝试使用指针反转字符串 我知道你可以使用数组 这更多的是关于学习指针 Problem 当尝试运行下面的代码时 我不断遇到分段错误 GCC似乎不喜欢 end begin line 这是为什么 特别是因为
  • VM 初始化期间发生错误无法为对象堆保留足够的空间无法创建 Java 虚拟机

    我一个多月以来一直面临这个问题 这是我在命令行运行java时看到的 java Xmx1300m Error occurred during initialization of VM Could not reserve enough spac
  • 是否有一种直接的方法来停止服务以响应用户单击通知?

    我想要以下行为 用户单击通知 Android 停止我的服务 问题是停止服务需要调用 stopService 而我无法轻松创建执行此操作的 PendingIntent 因此 我发现做到这一点的唯一方法是让我的服务接收一个特殊的 Intent
  • C++ 和 QML 之间的通信

    This page展示如何从 QML 中调用 C 函数 我想做的是通过 C 函数更改按钮上的图像 触发状态更改或无论如何完成 我怎样才能实现这个目标 UPDATE 我尝试了 Radon 的方法 但是当我插入这一行时立即 QObject te
  • 如何将 System.Windows.Media.SolidcolorBrush 转换为 System.Drawing.Color?

    我需要在 C 中将 System Windows Media SolidcolorBrush 转换为 System Drawing Color 任何线索都会很好 您可以使用SolidColorBrush Color获取或设置颜色 这是一个S
  • Spring Boot 的 CORS 问题

    我有一个在端口 8443 上运行的 Spring Boot 应用程序 以及在端口 8080 上运行的基于 angular2 的前端 我需要我的前端向我的 Spring 服务器发出请求 但我左右都收到 CORS 错误 我已经添加了 Cross
  • linux file命令输出中的版本号字段是什么

    如果我对在 Fedora Core 11 上编译的名为 version 的可执行文件执行以下命令 我会得到以下输出 文件版本 版本 ELF 32 位 LSB 可执行文件 Intel 80386 版本 1 SYSV 动态链接 使用共享库 适用
  • 用于目录遍历的任务并行库

    我想遍历硬盘上的目录并在所有文件中搜索特定的搜索字符串 这听起来像是可以 或应该 并行完成的事情的完美候选者 因为 IO 相当慢 传统上 我会编写一个递归函数来查找并处理当前目录中的所有文件 然后递归到该目录中的所有目录 我想知道如何修改它
  • 使用 XSD 验证 XML

    我在验证 XML 时遇到了真正的困难XSD 我应该在所有这些前面加上前缀 并预先声明 我是 XSD 和验证的新手 所以我不确定这是代码问题还是 XML 问题 我经历过 XML API 的地狱 并带着无数不同的选项回来 我认为我已经找到了使用
  • 防止基类的序列化

    我觉得我应该知道这一点 但出于某种原因 序列化从 可能是抽象 基类派生的类而不必一直序列化到树上的首选方法是什么 例如 也许您无法控制派生的类 但希望使用序列化来克隆您的对象 仅克隆您的对象 而不是基础对象 例如 This is a bas
  • 如何在 bash 脚本的批处理文件的参数中包含管道字符?

    我有一个 shell 脚本 我想执行这一行 qtvars bat vsstart qt sln BUILD Debug Win32 This works fine though I had to modify qtvars bat but
  • 如何模拟低带宽、高延迟环境? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我需要模拟与服务器的低带宽 高延迟连接 以便模拟远程站点的 VPN 条件 带宽和延迟应该是可调整的 这样我就可以找到运行我们的软件包的最佳组合 For macOS there i
  • 自定义 git 命令自动完成

    我通过编写位于以下位置的 shell 脚本实现了自定义 git 命令 usr local bin 它工作正常 但我希望脚本在命令行中自动完成分支 就像git checkout TAB TAB 这怎么可能做到呢 编辑 只需添加一些上下文 gi
  • 在 Rust 中对字符串进行分区

    Rust 中是否有一种机制可以将字符串划分为等长度元素的列表 子字符串或元组 字符数组 我想要一个字符串 abcdefghijkl 并将其分成一个列表 例如 ab cd ef gh ij kl 我不需要手动查看执行此操作的方法 我只是想知道
  • python:如何从 HKLM 中删除注册表项(和子项)(出现错误 5)

    我正在尝试通过 python 脚本删除某些注册表项 我从 HKEY CURRENT USER 读取和删除键没有问题 但尝试从 HKEY LOCAL MACHINE 执行相同操作 给我带来了可怕的WindowsError 错误 5 访问被拒绝
  • 在自定义视图/uiview子类上实现iphone的复制/粘贴控件

    我承认 在 S O 上已经有一个完全符合这些思路的问题 但它缺乏实现细节 有效的答案 而且我想更具体 所以我认为应该提出一个新问题 显然 如果我错了 请告诉我 我们可以尝试重新启动那里的线程 基本上 当用户按住标签时 我想将 UILabel
  • 通过 HTTPS 使用 Web 服务时抛出 System.Net.WebException

    当使用 HTTPS 调用服务器上运行的 Web 服务时 我的应用程序抛出 System Net WebException 并显示消息 底层连接已关闭 无法与远程服务器建立信任关系 我不确定如何解决此问题并成功拨打电话 经过一番研究 我发现了
  • gcc: printf 和 long double 会导致错误的输出。 [C - 类型转换混乱]

    我对 C 相当陌生 我尝试为 Vector 编写函数 但一定有问题 这是代码 Defines maths for particles include