2013-11-07 5 views
1

Мне нужно реализовать 32-битную неподвижную точку в 16-разрядной системе. Мой компилятор, похоже, дает мне «предупреждение: целочисленное переполнение в выражении». Я не уверен, что мне не хватает ничего: S. Я приведу нижеприведенную версию моего кода ниже. Любые советы будут ценить :)32-разрядная целочисленная арифметика в 16-разрядной системе для PIC

#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; 
} 

ответ

2

Ваш Q22base является 16-бит на 16-битной int системе, вы должны привести его к Q22 поэтому ваше выражение * делается, по крайней мере, типа 32-битным.

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

Спасибо большое, что установил его. Обратите внимание, чтобы само по себе обратить внимание на типы данных. – Ramzicle

+2

И безопасный способ написать макрос - всегда помещать скобки параметров в определение макроса, например, здесь заменить '_a' на' (_a) '. – ouah

+0

Я не закодирован в C, на некоторое время, поэтому я действительно ржавый: S скриптовые языки испортили мне: P спасибо за совет Я исправил все свои макросы. – Ramzicle

2

Имеющийся код свободно доступен для реализации 32-разрядных операций в программном обеспечении. Это может быть достаточно для ваших целей.

PIC C code for the 32bit math functions. 

//////////////////////////////////////////////////////////////////////////// 
//                  // 
// This code is based on code by Vadim Gerasimov ([email protected]), // 
// and extended skillfully by Mark Newman ([email protected]) 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 Accessed 2013-11-07
+0

Быстрый вопрос. Как это отличается от использования определенного int32_t, который является подписанным long int? – Ramzicle

+0

Int32_t может даже не быть определен в системе, или если это так, система, вероятно, имеет библиотеку, которая уже обрабатывает 32-разрядную целочисленную арифметику в программном обеспечении и скрывает, если от вас. Мой пример выше находится на месте в случае, если вы хотите большего контроля и хотите вручную реализовать логику. – DevNull

+1

Хмм, я проверю это. Обучение - это забава ^. ^ – Ramzicle

0

Вам не нужно, чтобы бросить постоянную Вы можете просто написать #define Q22base 512L или #define Q22base 512UL