【问题标题】:C program giving different results on OSX and windows在 OSX 和 windows 上给出不同结果的 C 程序
【发布时间】:2014-01-30 04:33:54
【问题描述】:

我用 C 语言编写了一个递归函数来反转一个整数 (123 -> 321),当我在我的 Mac 上运行它时它运行良好,但当我的导师在她运行 Windows 的计算机上运行它时表现奇怪。

int rev(int num)
{
    int base;

    if (num < 10) return (num); 

    base = pow(10,(int)log10(num));
    return(rev(num/10)+num%10*base);
}

例如,在 OSX 上调用 rev(8765) 返回 5678,在 Windows 上,rev(8765) 返回 5672。我无法访问 Windows 机器来尝试在调试模式下运行程序,所以我已经一直很难猜测问题出在哪里。如果有任何见解,我将不胜感激!

环境:

我正在使用 OSX 10.8 和 GCC 4.2。我很确定我的导师正在使用 MinGW 作为她的编译器。

【问题讨论】:

  • Windows 端使用了哪个编译器?
  • 她使用 Dev C++,我认为 MinGW 默认自带。
  • 除非您是数值分析专家,否则不要在此类事情上使用浮点数。
  • 如果这是 slashdot,那么回复将是 - “你对 M$windoze 有什么期望?”

标签: c macos compiler-construction


【解决方案1】:

powlog10 不需要正确舍入;他们产生的结果可以并且将在平台之间有所不同,即使对于“应该”与您的示例完全相同的情况也是如此。在这种情况下,OS X 产生的结果比 Windows 更准确,这会导致错误仅显示在 Windows 输出中。

更好的解决方案是使用整数的重复除法和乘以 10,并且根本不使用浮点(有一个非常干净的递归解决方案,类似于你的,不需要你计算base)。


顺便说一句,小吐槽:可耻这么多数学库不能正确处理 log10log2exp2 和 @ 中的 10 和 2 的小幂987654327@。设计这些功能并不难,以便它们为这些情况做“正确的事情”,并且可以在不对其他情况的性能产生不利影响的情况下完成。虽然标准不要求这样做,但它是一件简单的事情,它有助于使没有经验的程序员免于出现此类(异常常见的)错误。

【讨论】:

  • 我不确定在多大程度上可以说pow() 的 10 次幂的特殊情况不会对函数的其余部分产生不利影响(在性能以外的方面)。也许 Windows 的pow() 函数的设计者非常自豪地设计了一个函数,使得pow(0xA.0000000000008p0, 2) 大于pow(10, 2),就像数学函数一样,如果他们特殊情况下的幂,这个属性就会被破坏整数。在我看来,制作一个不出所料的pow() 的正确方法是将其精确到一个 ulp,而不是制作特殊情况。
  • @PascalCuoq:这正是我的意思。我不是在谈论添加特殊情况。我说的是使这些函数足够准确,以使有问题的情况正确地出现,这并不难。
猜你喜欢
  • 2015-11-10
  • 2012-12-25
  • 2020-08-01
  • 2016-05-13
  • 1970-01-01
  • 2016-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多