13

Çiftler kullanan bir C kodum var. Kodu bir DSP'de (TMS320) çalıştırabilmek istiyorum. Fakat DSP ikilileri desteklemiyor, sadece sabit nokta sayıları. Kodu sabit noktaya dönüştürmenin en iyi yolu nedir? Sabit nokta sayıları için iyi bir C kütüphanesi var mı (tamsayı olarak uygulandı)?Kayan nokta C kodunu sabit noktaya nasıl dönüştürebilirim?

+3

Bu oldukça büyük bir konudur. Bu SO sorusunda büyük bir tartışma var: http://stackoverflow.com/questions/79677/whats-the-best-way-to-do-fixed-point-math. Hemen hemen tüm cevaplar bazı yararlı nuggets vardı. – mtrw

+1

Merak ediyorum, DSP'nin derleyicisi sabit noktaları nasıl gösteriyor? İki tam sayı olarak mı? Örneğin, iki sabit nokta sayısını nasıl eklersiniz? – chrisaycock

+0

Türünde bir örtüşmeyle birlikte, 32 bit değerler ('long') olarak temsil edilir. Örneğin, noktadan sonra 16 bit varsa ('_iq16'), temel noktadaki 65536 tamsayı ile sabit nokta sayısını 1.0 temsil edersiniz. Aynı türdeki sabit nokta sayılarını eklemek ve çıkarmak için standart tam sayı işlemlerini kullanabilirsiniz. Çarpma, ölçeklemeyi düzeltmek için ekstra bir kaymaya ihtiyaç duyar. – starblue

cevap

8

TI "IQmath" adında bir sabit nokta kitaplığı sağlar:

http://focus.ti.com/lit/sw/sprc990/sprc990.pdf

geçerli kod analiz edilmesini içeren dönüştürme - Eğer tutabilir aralığı bilmemiz gerekiyor her bir değişken için ve ne hassas ihtiyacı . Daha sonra, hangi türün depolanacağına karar verebilirsiniz. IQMath, +/- +/- 1 aralığında ve 0,0000000001 - q1 aralığında ve +/- +/- 1 milyon aralığında ve 0,5 hassasiyetle q30'dan türler sağlar.

muhtemelen değişkenlerin aralığını taşabilir, sen taşma için çek eklemem gerekiyor ve bunu nasıl işleneceğine karar olabilir operasyonlar için

- vs. max, farklı bir ölçekle mağazasında sabitleyin bir hata yükseltmek,

Gerçekten işleminizin veri akışını derinlemesine anlamadan sabit noktaya dönüştürmenin hiçbir yolu yoktur.

5

Çoğu DSP araç yazılımı, yazılımda kayan noktalı öykünme kitaplıkları içerir. Bu yavaş olacaktır, ancak başlangıçta kayan nokta desteği ile kodunuzu oluşturmalı, sonra da yeterli performans elde etmek için sabit noktaya dönüştürmeniz gereken birkaç yer olup olmadığını görmek için profil. Ayrıca, süreç içinde hiçbir şey kaybetmediğinizden emin olmak için, sabit noktaya bağlantı noktası olarak bir karşılaştırma sağlamak için kayan nokta işleyişine sahip olmanız gerekir.

0

Sizin için bunu yapabilecek birkaç kütüphane var. Yine de, cihazınız için PSP bir çeşit matematik kütüphanesi içermelidir. Belgelenmelidir. Bazı kodlarınızı yeniden yazmanız gerekecektir, çünkü ilkel tabanlı kayan nokta aritmetiğini kullanırken kullandığınız kontrol yapıları, PSP'niz tarafından sağlanan API'yi kullanırken anlam ifade etmeyebilir.

Örneğin - C kodu seyrek, o zaman bir kayan nokta öykünmesi kitaplığını kullanmak mümkün olabilir nadiren/çiftler kullanıyorsa, bu

double arraysum = 0.0; 
for (int i = 0; i < arraylen; i++) 
{ 
    arraysum += array[i]; 
} 

bu

psp_decimal_t arraysum; 
if (0 != psp_sum_elements(&array, arraylen, &arraysum)) 
{ 
    printf("error!"); 
} 
+0

Bağlantı öldü, lütfen düzeltin. – Danijel

+0

Ne yazık ki, bu içeriği başka herhangi bir yerde bulamadık. –

2

dönüştürmek olabilir C kodunuzu 10X'den 100X'e daha yavaş çalıştırmaya neden olmadan. Eğer bu performansı vurmak istemiyorsanız ve çok sayıda kayan nokta işlemi varsa ve her gerçekçi giriş için her aritmetik ve mağaza çalışmasında gereken ölçek ve kesinlikleri biliyorsunuz, o zaman her aritmetik işlemi el ile Ölçeklendirilmiş tamsayı veri türleri ve işlemleri kullanılır. Ancak, hassasiyet gerekliliklerinin analizi genel olarak DSP tipi kod için önemsizdir. Konuyla ilgili birçok DSP ve Sayısal Yöntemler ders kitabı bölümleri vardır.

+0

... son cümlede ayrıntılı olarak çalışın, bunun için yararlı olarak nitelendirebilirsiniz. – jpinto3912

12

Aşağıdaki kod, tamsayıların dahili temsili olarak kullanıldığı bir Sabit türü tanımlar. Eklemeler ve çıkarma işlemleri, yalnızca + ve - işleçleri ile gerçekleştirilir. Çarpma, tanımlı MULT makrosu kullanılarak gerçekleştirilir.

#include <stdio.h> 
typedef int Fixed; 

#define FRACT_BITS 16 
#define FRACT_BITS_D2 8 
#define FIXED_ONE (1 << FRACT_BITS) 
#define INT2FIXED(x) ((x) << FRACT_BITS) 
#define FLOAT2FIXED(x) ((int)((x) * (1 << FRACT_BITS))) 
#define FIXED2INT(x) ((x) >> FRACT_BITS) 
#define FIXED2DOUBLE(x) (((double)(x))/(1 << FRACT_BITS)) 
#define MULT(x, y) (((x) >> FRACT_BITS_D2) * ((y)>> FRACT_BITS_D2)) 

Görüntü işleme algoritmamdaki kesirleri göstermek için yukarıdaki kodu kullanıyordum. Çiftler kullanan versiyondan daha hızlıydı ve sonuçlar neredeyse aynıydı.

+0

bu kütüphaneyi de kontrol edin: [http://www.sf.net/projects/fixedptc](http://www.sf.net/projects/fixedptc) –