SORU
20 Kasım 2012, Salı


Bunun 80-bit genişletilmiş hassas kayan nokta

Bunun bir kütüphane IA-32 ve x86-64 mimarileri 80-bit genişletilmiş hassas kayan nokta türü yararlanmak var mı?

MPFR bindings biliyorum ama benim ideal kütüphane daha hafif olacaktır. Kayan nokta tarihi talimatları yararlanarak ideal olacaktır.

CEVAP
18 Mart 2013, PAZARTESİ


Böyle bir kütüphane uygulaması derleyici dışında mümkün, teşekkürlerffıdil desteği.

Kütüphane iki parçaya bölünmüş olması gerekir: bunun doğal kaynak bölümü, ve C çalışma zamanı parçası. Bunun kaynağı türü bildirisi olarak alınan tüm fonksiyonlarını beyan içermelidir. Örneğin, ameliyat olacak ekleyin:

(** basic binary operations on long doubles *)
external add : t -> t -> t = "ml_float80_add"
external sub : t -> t -> t = "ml_float80_sub"
external mul : t -> t -> t = "ml_float80_mul"
external div : t -> t -> t = "ml_float80_div"

C kodu, ml_float80_add işlevi Bunun kılavuzda anlatıldığı gibi tanımlanmış olmalıdır:

CAMLprim value ml_float80_add(value l, value r){
   float80 rlf = Float80_val(l);
   float80 rrf = Float80_val(r);
   float80 llf = rlf   rrf;
   value res = ml_float80_copy(llf);
   return res;
}

Burada value zamanı Bunun beyan C değerleri yerli, onlara ikili operator, ve Bunun yeni bir değer döndürmek için aktardık. ml_float80_copy işlevi olan zamanı temsil tahsisi yapar.

Aynı şekilde, sub, mul div fonksiyonları C uygulamaları da tanımlanmalıdır. İmzasındaki benzerlik ve fonksiyonları bu, uzak ve C kullanarak soyut makro uygulama fark edebilirsiniz:

#define FLOAT80_BIN_OP(OPNAME,OP)                   \
  CAMLprim value ml_float80_##OPNAME(value l, value r){     \
    float80 rlf = Float80_val(l);                           \
    float80 rrf = Float80_val(r);                           \
    float80 llf = rlf OP rrf;                               \
    value res = ml_float80_copy(llf);           \
    return res;                     \
  }


FLOAT80_BIN_OP(add, );
FLOAT80_BIN_OP(sub,-);
FLOAT80_BIN_OP(mul,*);
FLOAT80_BIN_OP(div,/);

Bunun ve C modülü geri kalanı takip etmelidir.

Nasıl kodlamak Bunun bir değeri içine float80 C tipi gibi birçok imkan var. En basit seçenek bir dize, ve ham long double mağaza kullanmaktır.

type t = string

C tarafında, işlevlerini Bunun bir değeri ileri geri C değeri dönüştürmek için tanımlayın:

#include <caml/mlvalues.h>
#include <caml/alloc.h>
#include <caml/misc.h>
#include <caml/memory.h>


#define FLOAT80_SIZE 10  /* 10 bytes */

typedef long double float80;

#define Float80_val(x) *((float80 *)String_val(x))

void float80_copy_str(char *r, const char *l){
   int i;
   for (i=0;i<FLOAT80_SIZE;i  )
      r[i] = l[i];
}

void store_float80_val(value v,float80 f){
   float80_copy_str(String_val(v), (const char *)&f);
}

CAMLprim value ml_float80_copy(value r, value l){
   float80_copy_str(String_val(r),String_val(l));
   return Val_unit;
}

Ancak, bu uygulama polimorfik karşılaştırma fonksiyonları Bunun içine inşa edilmiş* *19, ve birkaç diğer özellikleri için destek getirmez. Yukarıda float80 türü bir işlev kullanarak değerleri dizileri olan beleiving karşılaştırma işlevi yanıltmak ve içeriklerine kurb bir karşılaştırma yapacağız.

Bu özel özellikleri destekleyen yeteri kadar basit olsa. Biz Bunun türü soyut olarak tanımlamak ve oluşturmak ve bizim float80 için özel yapılar işlemek için C kodu değiştirin:

#include <caml/mlvalues.h>
#include <caml/alloc.h>
#include <caml/misc.h>
#include <caml/memory.h>
#include <caml/custom.h>
#include <caml/intext.h>

typedef struct {
   struct custom_operations *ops;
   float80 v;  
} float80_s;

#define Float80_val(x) *((float80 *)Data_custom_val(x))

inline int comp(const float80 l, const float80 r){
   return l == r ? 0: (l < r ? -1: 1); 
}

static int float80_compare(value l, value r){
   const float80 rlf = Float80_val(l);
   const float80 rrf = Float80_val(r);
   const int llf = comp(rlf,rrf);
   return llf;
}

/* other features implementation here */

CAMLexport struct custom_operations float80_ops = {
  "float80", custom_finalize_default, float80_compare, float80_hash,
  float80_serialize, float80_deserialize, custom_compare_ext_default
};

CAMLprim value ml_float80_copy(long double ld){
  value res = caml_alloc_custom(&float80_ops, FLOAT80_SIZE, 0, 1);  
  Float80_val(res) = ld;
  return res;
}

Biz o zaman her şeyi ocamlbuild ve küçük bir bash betiği kullanılarak inşa etmeyi öneriyoruz.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • gadgetgal38

    gadgetgal38

    9 HAZİRAN 2009
  • The Bad Tutorials

    The Bad Tuto

    6 EKİM 2009
  • xSammyJoe1

    xSammyJoe1

    19 Temmuz 2011