In order to create an arbitrary precision floating point / drop in replacement for Double, I'm trying to wrap MPFR using the FFI but despite all my efforts the simplest bit of code doesn't work. It compiles, it runs, but it crashes mockingly after pretending to work for a while. A simple C version of the code happily prints the number "1" to (640 decimal places) a total of 10,000 times. The Haskell version, when asked to do the same, silently corrupts (?) the data after only 289 print outs of "1.0000...0000" and after 385 print outs, it causes an assertion failure and bombs. I'm at a loss for how to proceed in debugging this since it "should work".

为了创建一个替代Double的任意精度浮点/丢弃,我试图使用FFI包装MPFR,但尽管我付出了所有努力,但最简单的代码不起作用。它编译,它运行,但它假装工作一段时间后嘲讽崩溃。代码的简单C版本愉快地将数字“1”打印到(640个小数位)总共10,000次。当被要求做同样的事情时,Haskell版本在仅仅289次打印输出“1.0000 ... 0000”之后默默地破坏(?)数据,并且在385次打印输出之后,它导致断言失败和炸弹。我不知道如何继续调试它,因为它“应该工作”。

The code can be perused at http://hpaste.org/10923 and downloaded at http://www.updike.org/mpfr-broken.tar.gz

该代码可以在http://hpaste.org/10923上阅读,并在http://www.updike.org/mpfr-broken.tar.gz下载。

I'm using GHC 6.83 on FreeBSD 6 and GHC 6.8.2 on Mac OS X. Note you will need MPFR (tested with 2.3.2) installed with the correct paths (change the Makefile) for libs and header files (along with those from GMP) to successfully compile this.

我在Mac OS X上使用FreeBSD 6上的GHC 6.83和Mac OS X上的GHC 6.8.2。注意你需要安装带有正确路径的MPFR(用2.3.2测试)(更改Makefile)以及libs和头文件(以及那些从GMP)到成功编译。

Questions

  • Why does the C version work, but the Haskell version flake out? What else am I missing when approaching the FFI? I tried StablePtrs and had the exact same results.

    为什么C版本可以工作,但Haskell版本会崩溃?在接近FFI时我还缺少什么?我尝试了StablePtrs并得到了完全相同的结果。

  • Can someone else verify if this is a Mac/BSD only problem by compiling and running my code? (Does the C code "works" work? Does the Haskell code "noworks" work?) Can anyone on Linux and Windows attempt to compile/run and see if you get the same results?

    有人可以通过编译和运行我的代码来验证这是否只是Mac / BSD问题? (C代码“工作”是否有效?Haskell代码“noworks”是否有效?)Linux和Windows上的任何人都可以尝试编译/运行并查看是否得到相同的结果?

C code: (works.c)

C代码:(works.c)

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  

#include <gmp.h>  
#include <mpfr.h>
#include "mpfr_ffi.c"  

int main()  
{  
  int i;  
  mpfr_ptr one;  

  mpf_set_default_prec_decimal(640);  

  one = mpf_set_signed_int(1);  
  for (i = 0; i < 10000; i++)
    {  
      printf("%d\n", i);
      mpf_show(one);
    }  
}  

Haskell code: (Main.hs --- doesn't work)

Haskell代码:(Main.hs ---不起作用)

module Main where  

import Foreign.Ptr            ( Ptr, FunPtr )  
import Foreign.C.Types        ( CInt, CLong, CULong, CDouble )  
import Foreign.StablePtr      ( StablePtr )  

data MPFR = MPFR  

foreign import ccall "mpf_set_default_prec_decimal"  
    c_set_default_prec_decimal          :: CInt -> IO ()  
setPrecisionDecimal                     :: Integer -> IO ()  
setPrecisionDecimal decimal_digits = do  
    c_set_default_prec_decimal (fromInteger decimal_digits)  

foreign import ccall "mpf_show"  
   c_show                               :: Ptr MPFR -> IO ()  

foreign import ccall "mpf_set_signed_int"  
   c_set_signed_int                     :: CLong -> IO (Ptr MPFR)  

showNums k n = do  
   print n  
   c_show k  

main = do  
   setPrecisionDecimal 640  
   one <- c_set_signed_int (fromInteger 1)  
   mapM_ (showNums one) [1..10000]  

3 个解决方案

#1


3

I see the problem too, on a

我也看到了这个问题

$ uname -a
Linux burnup 2.6.26-gentoo-r1 #1 SMP PREEMPT Tue Sep 9 00:05:54 EDT 2008 i686 Intel(R) Pentium(R) 4 CPU 2.80GHz GenuineIntel GNU/Linux
$ gcc --version
gcc (GCC) 4.2.4 (Gentoo 4.2.4 p1.0)
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.8.3

I also see the output changing from 1.0000...000 to 1.0000...[garbage].

我也看到输出从1.0000 ... 000变为1.0000 ... [垃圾]。

Let's see, the following does work:

让我们看看,以下确实有效:

main = do
    setPrecisionDecimal 640
    mapM_ (const $ c_set_signed_int (fromInteger 1) >>= c_show) [1..10000]

which narrows down the problem to parts of one being somehow clobbered during runtime. Looking at the output of ghc -C and ghc -S, though, isn't giving me any hints.

这会将问题缩小到在运行时期间以某种方式被破坏的部分。但是,看看ghc -C和ghc -S的输出,并没有给我任何提示。

Hmm, ./noworks +RTS -H1G also works, and ./noworks +RTS -k[n]k, for varying values of [n], demonstrate failures in different ways.

嗯,。/ noworks + RTS -H1G也可以工作,而./noworks + RTS -k [n] k,对于[n]的不同值,以不同的方式演示失败。

I've got no solid leads, but there are two possibilities that jump to my mind:

我没有坚实的线索,但有两种可能性让我想到:

  • GMP, which the GHC runtime uses, and MPFR having some weird interaction
  • GHC运行时使用的GMP和MPFR有一些奇怪的交互

  • stack space for C functions called within the GHC runtime is limited, and MPFR not dealing well
  • 在GHC运行时内调用的C函数的堆栈空间是有限的,并且MPFR处理不好

That being said... is there a reason you're rolling your own bindings rather than use HMPFR?

那就是说...你有没有理由推出自己的绑定而不是使用HMPFR?

更多相关文章

  1. 不能让noUISlider工作
  2. 如何更模块化地编写jQuery代码?
  3. [生活娱乐] 从后端室友那学来的代码
  4. 循环不能正常工作 - 守夜人
  5. js金额数字格式化实现代码(三位加逗号处理保留两位置小数)
  6. 无法让.click()在禁用的textarea上工作
  7. Aptana Studio 3 IDE中有运行JavaScript代码的方法吗?
  8. 如何在JavaScript中编写适当的OOP代码?
  9. 高性能JavaScript代码高亮插件

随机推荐

  1. Python(名称空间、函数嵌套、函数对象)
  2. flask-admin 新增功能关联两张表,关联的表
  3. IronPython编辑器 —— FantasyPython雏
  4. 数据挖掘(三)分类模型的描述与性能评估,以决
  5. Windows7下搭建Django运行环境
  6. Python3 串口两进程同时读写
  7. Python 基础之在ubuntu系统下安装双版本p
  8. python-多线程3-生产者消费者
  9. django-modeltranslation:如何知道该值是
  10. 6.3 Python class 运算符重载