حساب عدد صحيح 32 بت على نظام 16 بت للموافقة المسبقة عن علم

StackOverflow https://stackoverflow.com/questions/19842311

سؤال

أحتاج إلى تنفيذ نقطة ثابتة 32 بت على نظام 16 بت. يبدو أن المترجم الخاص بي يعطيني "تحذيرًا: integer verflow في التعبير". لست متأكدًا مما أفتقده أي شيء: ق. سأقدم نسخة مغمورة من الكود الخاص بي أدناه. أي نصيحة ستكون تقدير :)

#include <stdint.h>
typedef int32_t Q22;

#define Q22base     512
#define Q22_Convert(_a) ((Q22)(_a*Q22base))

int main (){
    // a bunch of code that does stuff goes here
    Q22 variable1=0;

    variable1 = Q22_Convert(some_value1) - Q22_Convert(some_value1);      
    return 0;
}
هل كانت مفيدة؟

المحلول

لك Q22base هو 16 بت على 16 بت int النظام ، تحتاج إلى إلقاءه على Q22 بحيث * يتم التعبير في نوع 32 بت على الأقل.

#define Q22_Convert(_a) ((Q22)(_a * (Q22) Q22base))

نصائح أخرى

هناك رمز موجود متاح بحرية لتنفيذ عمليات 32 بت في البرامج. قد يكون هذا كافيًا لأغراضك.

PIC C code for the 32bit math functions.

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// This code is based on code by Vadim Gerasimov (vadim@media.mit.edu),   //
// and extended skillfully by Mark Newman (newman@media.mit.edu) for the  //
// Robotic F.A.C.E. project                                               //
//                                                                        //
// Copyright (C) 2001-2004 MIT Media Laboratory                           //
//                                                                        //
////////////////////////////////////////////////////////////////////////////


// 32-bit arithmetic
#define move32(to,from) {to[0]=from[0];to[1]=from[1];to[2]=from[2];to[3]=from[3];}
#define zero32(n) {n[0]=0;n[1]=0;n[2]=0;n[3]=0;}
#define is_zero32(n) ((n[0]|n[1]|n[2]|n[3])==0)
#define inc32(n) {if(++n[0]==0)if(++n[1]==0)if(++n[2]==0)++n[3];}

void dec32 (char* n) {
  if (n[0]--==0) if(n[1]--==0) if (n[2]--==0) --n[3];
}

void add32 (char* a, char* b)
{
   byte r[4];

   r[0] = *(b);
   r[1] = *(b + 1);
   r[2] = *(b + 2);
   r[3] = *(b + 3);

#asm
   movf    a,w
   movwf   4
   movf    r[0],w
   addwf   0,f
   movf    r[1],w
   incf    4,f
   btfsc   3,0
   incfsz  r[1],w
   addwf   0,f
   movf    r[2],w
   incf    4,f
   btfsc   3,0
   incfsz  r[2],w
   addwf   0,f
   movf    r[3],w
   incf    4,f
   btfsc   3,0
   incfsz  r[3],w
   addwf   0,f
#endasm
}

void sub32(char* a, char* b) { // a = a - b
   byte r[4];
   r[0] = *(b);
   r[1] = *(b + 1);
   r[2] = *(b + 2);
   r[3] = *(b + 3);
#asm
   movf    a,w
   movwf   4
   movf    r[0],w
   subwf   0,f
   movf    r[1],w
   incf    4,f
   btfss   3,0
   incfsz  r[1],w
   subwf   0,f
   movf    r[2],w
   incf    4,f
   btfss   3,0
   incfsz  r[2],w
   subwf   0,f
   movf    r[3],w
   incf    4,f
   btfss   3,0
   incfsz  r[3],w
   subwf   0,f
#endasm
}

int lt32(char *a, char *b) {
    int i;
    for (i = 3; i >= 0; i--) {
        if (a[i] > b[i])
            return 0;
        if (a[i] < b[i])
            return 1;
    }
    return 0;
}
int le32(char *a, char *b) {
    int i;
    for (i = 3; i >= 0; i--) {
        if (a[i] < b[i])
            return 1;
        if (a[i] > b[i])
            return 0;
    }
    return 1;
}
int gt32(char *a, char *b) {
    int i;
    for (i = 3; i >= 0; i--) {
        if (a[i] < b[i])
            return 0;
        if (a[i] > b[i])
            return 1;
    }
    return 0;
}
int ge32(char *a, char *b) {
    int i;
    for (i = 3; i >= 0; i--) {
        if (a[i] > b[i])
            return 1;
        if (a[i] < b[i])
            return 0;
    }
    return 1;
}

void shift32(char *n) {
    char i, in, out;
    in = 0;
    for (i = 0; i < 4; i++) {
        out = n[i] >> 7;
        n[i] = in + (n[i] << 1);
        in = out;
    }
}

void mult32byte(char *a, char b) {
    char i;
    char r[4];
    move32(r, a);
    zero32(a);

    for (i = 0; i < 8; i++) {
        if (b & 1)
            add32(a, r);
        b = b >> 1;
        shift32(r);
    }
    a[0] = a[1];
    a[1] = a[2];
    a[2] = a[3];
    a[3] = 0;
}

مراجع


  1. "PIC C رمز لوظائف الرياضيات 32 بت." http://web.media.mit.edu/~stefanm/yano/picc_math32.html تم الوصول إليها 2013-11-07

لا تحتاج إلى إلقاء الثابتة ، يمكنك ببساطة كتابة #Define Q22Base 512L أو #DEFINE Q22BASE 512UL

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top