From: Raphael N. <rn...@we...> - 2008-02-03 22:25:59
|
Hi Ivan, > For a few days I'm trying to debug one C source and a sort of a > question is are there arithmetics limitations for PIC16? I mean they > have no instructions for multiplication, division and floating points, > but there are such operators in C. Complex arithmetics (everything beyond 8bit addition/subtraction) is emulated in software. Multibyte addtions/subtractions are fairly efficient in-line, most others, notably multi-byte multiplications and all divisions, are implemented as C routines in the libraries. To my knowledge, even floating point arithmetics (single precision, 32 bits?) is implemented, though I wonder if using it on an 8 bit micro is the best of solutions... Reportedly it works. > Also data types - int is 2 bytes, right? Yep. > What happens if I try to assign 8bit number to an int? Depends... > Lets discuss the following snipplet of code: > <code> > int x = ADRESH; //after an ADC conversion is done - ADRESH is 8bit, if > there is a value like 0xf1, is x == 0xf1? Depends... either ADRESH is considered to be unsigned, in which case x would be 0x00f1, or ADRESH is considered to be signed, in which case x would be 0xfff1. In this case, ADRESH is declared as an sfr, and these are considered to be entities close to 'volatile unsigned char'. For clarity, you could explicitly cast your 8-bit value: int x = (unsigned char)ADRESH; This forces the compiler to consider ADRESH as unsigned and to zero-fill the upper byte of x. For sign-extension, use int x = (signed char)ADRESH; // or simply (char)ADRESH > x = x * 4; //this is simple multiplication and I assume the compiler > optimizes it with shifting and rotating, but what happens if there > were multiplication by 3, or by some fractional number like 0.48 or > 0.6666... ? Yep, multiplications by powers of two are optimized, others (including x=3*x or x = x*x with statically unknown x) are turned into function calls to emulate the maths in software. > What happens if the result is too big for the int type > (more than 2 bytes), As usual, the result will be correct modulo the size of the data type, i.e., it wraps around. > and what happens with the result if there is a > fractional result? int x int --> int yields truncated results int x int --> float yields truncated results, converted to float (or error) int x float --> int and float x int --> int yield a complex float operation followed by truncating the result to an int (and a warning or even error about loosing precision or invalid implicit cast from float to int) int x float --> float and float x float --> float and float x float --> float yield complex floating point maths with floating point results All of this is plain ANSI C and not specific to SDCC. > If I have 3 * 0.5 = 1.5 what will x contain? Depends on the type of x, see above. > x = x /4; //the same questions Same answer. If x is integral, the result will be truncated. > x = 11; //after that step will x be equal to 0x000b ? Yep, though 11 is implicitly promoted to a 16-bit value equalling 11 internally (i.e., 00011 decimal or your 0x000b hex). > float y; //how the float will be interpreted? Well, as a IEEE floating point number. Beware of rather large and slow arithmetics, though... Regards, Raphael |