这个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 ++行为相同。或者我错过了什么?
答案 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>