From: roelof 't H. <ro...@it...> - 2013-02-08 15:26:14
|
Hi guys, I am using a #define to do a calculation during compile time and load the result in an (8 bit) uart register so that I can set the baudrate. I am using the following in a header file : #define crystal 11059200 #define bd4800 (256 - crystal / 192 * 4800) Here the result is 0xef854100 #define crystal 11059200 #define bd4800 (256 - (crystal / 921600)) And here the (correct) result is 0xf4 Why is it that the multiplication in the first #define fails ? I have used brackets "()" in numerous places, did typecasts, split up the #define in multiple parts but all failed on the multiplication. It seems that when I use a multiplication the result stored in the #define is limited to a signed 16 bit number. Is this assumption correct ? Update : I have done some further tests and the assumption seems correct for a multiplication. If I do the following division #define (crystal / 100) the answer is 0x0001b000 which is correct. I am using SDCC : mcs51 3.2.1 #8413 (8 Feb 2013) (Linux) The command line is : sdcc -D_89v664 -c --model-small --code-size 65536 --xram-size 2048 serial.c Thanks. roelof |
From: Harley L. <los...@gm...> - 2013-02-08 15:56:19
|
TL;DR On Fri, Feb 8, 2013 at 9:08 AM, roelof 't Hooft <ro...@it...>wrote: > I am using the following in a header file : > > #define crystal 11059200 > #define bd4800 (256 - crystal / 192 * 4800) > > Here the result is 0xef854100 > Based on the order of precidence, this looks like the right answer to me: 11059200/192 = 57600 57600*4800 = 276480000 256-276480000=0xFFFFFFFFEF854100 > > #define crystal 11059200 > #define bd4800 (256 - (crystal / 921600)) > > And here the (correct) result is 0xf4 > If this is the answer you're expecting, you'd want to use: #define bd4800 (256 - crystal / (192 * 4800)) |
From: Harley L. <los...@gm...> - 2013-02-08 16:26:07
|
On Fri, Feb 8, 2013 at 9:56 AM, Harley Laue <los...@gm...>wrote: > TL;DR > > > On Fri, Feb 8, 2013 at 9:08 AM, roelof 't Hooft <ro...@it...>wrote: > >> I am using the following in a header file : >> >> #define crystal 11059200 >> #define bd4800 (256 - crystal / 192 * 4800) >> >> Here the result is 0xef854100 >> > > Based on the order of precidence, this looks like the right answer to me: > 11059200/192 = 57600 > 57600*4800 = 276480000 > 256-276480000=0xFFFFFFFFEF854100 > > >> >> #define crystal 11059200 >> #define bd4800 (256 - (crystal / 921600)) >> >> And here the (correct) result is 0xf4 >> > > If this is the answer you're expecting, you'd want to use: > #define bd4800 (256 - crystal / (192 * 4800)) > I guess I /should/ have read the rest/verified the results. Without actually looking at SDCC's source code, I'd wager your assumption on it doing the math in 16 bit ints is correct (as it gives the warning: integer overflow in expression.) |
From: roelof 't H. <ro...@it...> - 2013-02-08 16:42:21
|
On Fri, 2013-02-08 at 09:56 -0600, Harley Laue wrote: > On Fri, Feb 8, 2013 at 9:08 AM, roelof 't Hooft <ro...@it...> > wrote: > > I am using the following in a header file : > > > > #define crystal 11059200 > > #define bd4800 (256 - crystal / 192 * 4800) > > > > Here the result is 0xef854100 > > > Based on the order of precidence, this looks like the right answer to > me: > 11059200/192 = 57600 > 57600*4800 = 276480000 > 256-276480000=0xFFFFFFFFEF854100 You are right. Stupid me, I forgot to type the extra brackets while copying :-( > If this is the answer you're expecting, you'd want to use: > #define bd4800 (256 - crystal / (192 * 4800)) I did use that and it still does not give me the correct answer. This is what I have in my header file now : // #define bd4800 (256 - ((crystal / 100) / (2^0 * 16 * 12 * 48))) #define bd4800 (256 - ((crystal / 100) / 9216)) // 244 And that works for now :-) roelof |
From: Erik P. <epe...@iv...> - 2013-02-08 16:04:25
|
On Fri, 8 Feb 2013, roelof 't Hooft wrote: > Hi guys, > > I am using a #define to do a calculation during compile > time and load the result in an (8 bit) uart register so > that I can set the baudrate. > > I am using the following in a header file : > > #define crystal 11059200 > #define bd4800 (256 - crystal / 192 * 4800) > > Here the result is 0xef854100 > > #define crystal 11059200 > #define bd4800 (256 - (crystal / 921600)) > > And here the (correct) result is 0xf4 > > Why is it that the multiplication in the first #define fails ? > I have used brackets "()" in numerous places, did typecasts, > split up the #define in multiple parts but all failed on the > multiplication. Multiplication and division have equal precedence and are evaluated left-to-right, so #define bd4800 (256 - crystal / 192 * 4800) is evaluated as #define bd4800 (256 - ((crystal / 192) * 4800)) which gives you the result you see. However, adding parenthesis like this #define bd4800 (256 - crystal / (192 * 4800)) will also give an unexpected result since the integer promotion rules require that 192 * 4800 be computed with an int result, but the arithmetic result is too large to fit in SDCC's 16-bit int. I'd suggest using: #define bd4800 (256 - crystal / (192L * 4800)) > It seems that when I use a multiplication the result stored in > the #define is limited to a signed 16 bit number. > Is this assumption correct ? The #define performs no math; it just defines text for substitution. When the substituted text is evaluated by the next stage of the compiler you need to be aware of the scale of the intermediate results and make sure they will fit within the C specified promoted type (which may not be sufficiently promoted automatically). Erik |
From: roelof 't H. <ro...@it...> - 2013-02-08 17:22:58
|
On Fri, 2013-02-08 at 10:04 -0600, Erik Petrich wrote: > I'd suggest using : > > #define bd4800 (256 - crystal / (192L * 4800)) This is what I have in the header file now. And I looked at the .lst file for the results which are as I expect them to be. (I only needed to add the "L") > The #define performs no math; it just defines text for substitution. I know that, just did not know how to correctly express myself when trying to explain the problem I was facing. > When > the substituted text is evaluated by the next stage of the compiler you > need to be aware of the scale of the intermediate results and make sure > they will fit within the C specified promoted type (which may not be > sufficiently promoted automatically). And because I did not know the scale (16 bit signed) of the result I was having problems making things work. Any way, thank you all for the help. Much appreciated. roelof |