【问题标题】:Same calculation on Linux and Windows --> different resultsLinux 和 Windows 上的相同计算 --> 不同的结果
【发布时间】:2013-05-20 14:27:37
【问题描述】:

我编写了以下算法,将十进制值转换为二进制/十六进制等。

string toFormatFromDecimal(long long t, Format format) {
    int digitCount = ceil(log(t) / log((int) format));
    string hex = "";
    for (int i = 0; i < digitCount; i++) {
        long double cur = (long double)t / (long double)(format);
        long long ganzzahl = (long long) cur;
        long double kommazahl = cur - ganzzahl;
        hex += digits[(long long) (kommazahl * format)];
        t = ganzzahl;
    }
    return string(hex.rbegin(), hex.rend());
}

我在 linux 中使用 GCC,在 Windows 上使用 Visual Studio c++ 编译器 看来我在这里的“整数”部门得到了不同的值:

long long ganzzahl = (long long) cur;

知道这怎么会发生吗? Linux 和 Windows 有不同的精度吗?

谢谢 弗洛里安

--解决方案--

string toFormatFromDecimal(long long t, Format format) {
    int digitCount = ceil(log(t) / log((int) format));
    string hex = "";
    for (int i = 0; i < digitCount; i++) {
        hex += digits[(int) (t%format)];
        t = t/format;
    }
    return string(hex.rbegin(), hex.rend());
}

【问题讨论】:

    标签: c++ linux windows gcc floating-point


    【解决方案1】:

    是的,GCC 和 Visual Studio C++ 有不同的long double 类型。在 GCC 为 x86 生成代码时,long double 是 80 位双扩展 IEEE 754 格式 (*),而 Visual Studio C++ 将 long double 视为 64 位双精度 IEEE 754 格式(*)。

    所以(long double)t 在两个平台上不必是相同的数字,划分也不相同。尽管您已将问题标记为“整数除法”,但它是不同浮点类型之间的浮点除法。

    (*) 几乎:它的行为非常类似于具有 15 个指数位和 63 个有效位的 79 位 IEEE 754 类型,但它具有稍宽的指数范围,因为它使用显式位作为前导 1在有效数字中。

    (**) 几乎:因为编译器在将 x87 配置为 53 位有效位后生成使用历史 x87 指令的指令,所以非正规结果可能会被双舍入 (reference)。

    【讨论】:

    • 非常感谢!是否有机会在两个平台上获得相同的结果?实际上,我将 double 转换为 64 位 IEEE 754,在这两个平台上我得到相同的结果,但是当我尝试使用给定的算法将这些 long long 转换为十六进制时,我得到不同的结果
    • @user2071938 要使程序在两个平台上运行相同,请完全避免使用浮点。您的计算kommazahl = cur - ganzzahl … kommazahl * format 看起来像是避免整数之间的余数运算符% 的复杂方法:stackoverflow.com/q/7070346/139746
    • 非常感谢,这解决了我的问题!我在我的问题中发布了我改编的算法
    • @user2071938 我认为你可以写(long long) (((t%format)/double(format)) * format) 简单地t % format
    猜你喜欢
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    • 2021-07-16
    • 2015-05-04
    相关资源
    最近更新 更多