这是Haskell的printf“%g”中的错误吗?

时间:2013-12-31 00:12:47

标签: haskell printf

这个c ++程序

#include <cstdio>
int main(void)
{
  double x = 1.0;
  printf("%g\n", x);

  double y = 1.25;
  printf("%g\n", y);
}

似乎根据我的understanding fprint“%g”正确执行,因为它产生以下输出:

1
1.25

然而,这个Haskell程序的输出

import Numeric     (showGFloat)
import Text.Printf (printf)

main :: IO ()
main = do
  let x = 1.0 :: Double
  putStrLn $ printf "%g" x
  putStrLn $ showGFloat Nothing x ""

  let y = 1.25 :: Double
  putStrLn $ printf "%g" y
  putStrLn $ showGFloat Nothing y ""

1.0
1.0
1.25
1.25

我的问题是:为什么Haskell打印“1.0”而不是“1”,正如我所预期的那样? printf的Haskell docs表明Haskell行为应该与C ++行为相同。或者我错过了什么?

1 个答案:

答案 0 :(得分:6)

它真的看起来像个错误......

在C规范中,很明显%g是为了切断尾随'.000 ......。见http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf,p。 313:

  

最后,除非使用#fl ag,否则将从中移除任何尾随零   如果,则删除结果的小数部分和小数点字符   没有剩余的小数部分。

这个bug也存在于Hugs中,我试过了。

另外,awk使用printf,并且有一个Linux命令行版本的printf,两者都兼容c版本,所以ghci和拥抱肯定是奇怪的人。

这不是唯一的不兼容性,因为当没有给出精度时,printf应该(根据规范)截断5位数,而不是。

在Haskell

> printf "%g\n" 1.111111111111111111111

产量

1.1111111111111112

而在C

int main() {
  printf("%g\n", 1.111111111111111);
}

产量

1.11111

Haskell报告没有提到Text.Printf库,所以尽管它是基础的,我认为你不能认为这是一个Haskell,ghc或拥抱bug,而只是一个库bug。 / p>