This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

unexpected results in integer arithmetics

Hello experts,

to avoid a division, I use integer arithmetics. The unsigned int x which is in the range of 2000 is first multiplied by a number s which is 2048 plus/minus 1000 and then shifted by 11 digits which should replace a division by 2048.

unsigned int  near x;
unsigned int  s

 x = ( (unsigned long) x * (unsigned long) s ) >> 11 ;

For testing I used s=2048. The result should be (x*2048)>>11 = x, but what I get as a result is about 30 times too big, and all results for different values of x are multiples of 0x20.

Type casting problem?

Please help, I run out of ideas.

Parents
  • I only change the case to lower and add an 'r_' prefix to indicate the SFRs are not regular variables (e.g. r_pcon vs PCON). ALL CAPS was a bad idea for the SFRs since most programmers use all caps for manifest constants.

    Indeed, I normally only use all caps for manifest constants, but when there is something of a standard in place I stick with it so that my code has a similar look to the majority of the available codebase. I gradually get used to it until it seems perfectly natural and presto! I can glance at third party code and read it easily, others can do the same with my code.

    Also, SFRs in a header file is somewhat like defining a bunch of global variables in a header file. True, hardware is actually globabl but the namespace to access it does not need to be. In my UART driver I only needed to type a few SRF and SBIT. There is also some semblance of attempting to limit scope by placing the SFR definitions in the .c file instead of in the .h file, admittedly a semblance.

    As you say the hardware is global. What then is the point of trying to restrict scope or namespace? Bear in mind that we're talking about code for an 8 bit microcontroller here rather than something like MS Office.

    Do you find my code that hard to read? Easier than most? More difficult than most? I've yet to have anyone complain about my code either from a functional standpoint or a readability standpoint.

    I would find your code easy to read if you stuck to standard C data types and 'standard' 8051 nomenclature. typedefs and enumerated types do have their uses but always have me flipping backwards and forwards to and from header files to find out what the actual data type and value is. This disturbs the flow when trying to follow a piece of code. Everybody seems to have different ideas about these things - uINT8, Uint8, uChar, U8, u8 etc - I know they're all obvious but I'd rather have to deal with remembering that the Crayfish Vector 22B has a 13 bit unsigned char that all that.

    This small change does add clarity since you get extra visual information that this r_pcon is somehow not the same as a regular variable and it won't be confused with a manifest constant.

    It doesn't add clarity to the bulk of the 8051 community: those who are used to PCON, SCON etc.

    Besides, I work with many CPUs (MIPS, PowerPC, ARM, PIC, MSP430, 8051, and Z80) and I do not remember all the registers for all of these, the r_ prefix helps me and is consistent with my coding standards, which I'm sure you'd hate, located on my website.

    That's fine: if it helps you and you are going to be the maintainer of your code then do it. If you're writing 8051 code for the consumption of others I think you would be better sticking to the 'standard'.

    Your coding standards don't mesh perfectly with my preferences but you definitely are right about curly brace placement.

Reply
  • I only change the case to lower and add an 'r_' prefix to indicate the SFRs are not regular variables (e.g. r_pcon vs PCON). ALL CAPS was a bad idea for the SFRs since most programmers use all caps for manifest constants.

    Indeed, I normally only use all caps for manifest constants, but when there is something of a standard in place I stick with it so that my code has a similar look to the majority of the available codebase. I gradually get used to it until it seems perfectly natural and presto! I can glance at third party code and read it easily, others can do the same with my code.

    Also, SFRs in a header file is somewhat like defining a bunch of global variables in a header file. True, hardware is actually globabl but the namespace to access it does not need to be. In my UART driver I only needed to type a few SRF and SBIT. There is also some semblance of attempting to limit scope by placing the SFR definitions in the .c file instead of in the .h file, admittedly a semblance.

    As you say the hardware is global. What then is the point of trying to restrict scope or namespace? Bear in mind that we're talking about code for an 8 bit microcontroller here rather than something like MS Office.

    Do you find my code that hard to read? Easier than most? More difficult than most? I've yet to have anyone complain about my code either from a functional standpoint or a readability standpoint.

    I would find your code easy to read if you stuck to standard C data types and 'standard' 8051 nomenclature. typedefs and enumerated types do have their uses but always have me flipping backwards and forwards to and from header files to find out what the actual data type and value is. This disturbs the flow when trying to follow a piece of code. Everybody seems to have different ideas about these things - uINT8, Uint8, uChar, U8, u8 etc - I know they're all obvious but I'd rather have to deal with remembering that the Crayfish Vector 22B has a 13 bit unsigned char that all that.

    This small change does add clarity since you get extra visual information that this r_pcon is somehow not the same as a regular variable and it won't be confused with a manifest constant.

    It doesn't add clarity to the bulk of the 8051 community: those who are used to PCON, SCON etc.

    Besides, I work with many CPUs (MIPS, PowerPC, ARM, PIC, MSP430, 8051, and Z80) and I do not remember all the registers for all of these, the r_ prefix helps me and is consistent with my coding standards, which I'm sure you'd hate, located on my website.

    That's fine: if it helps you and you are going to be the maintainer of your code then do it. If you're writing 8051 code for the consumption of others I think you would be better sticking to the 'standard'.

    Your coding standards don't mesh perfectly with my preferences but you definitely are right about curly brace placement.

Children
No data