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
  • We are not C experts to write dumbed down code folks. We are C experts because we learn the language and continually strive to improve and augment our C skills.

    We are C experts when we write efficient, functional code that is clear and comprehensible to not only ourselves but those who will have to work on our code afterwards. This is one of the most important skills as a professional programmer.

    I don't believe in writing unclear, obfuscated code but I also do not believe in writing C for the lowest common denominator of programmers. How will they ever learn?

    Oh come on. Every 8051 programmer is familiar with the names of the commonly used special function registers: PCON, SCON etc. That is what they are called in the data sheets. Keil have very sensibly declared these in the device specific header files. Every Keil 8051 programmer will be familiar with using these - so what do you do? You ignore the Keil header file and give your own declarations. Please don't tell me that aids clarity. The first thing I'd do asked to work on your code would be some global replacement!

    Do you really want a bunch of programmer's writing basic C code or do you want them to grow into the language? Where do you draw the line? No use of ?:, no use of +=, *=, -=, etc., no use of bit-fields? No use of switch blocks? Are these constructs simply to diffucult for a programmer to understand? Nay, I think not.

    I want a bunch of C programmers writing clear, working code that everybody understands. This discussion was about the use of parentheses to aid clarity and overcome the operator precedence rules. Nobody is suggesting not using basic C constructs, were suggesting adding code to clarify intention.

Reply
  • We are not C experts to write dumbed down code folks. We are C experts because we learn the language and continually strive to improve and augment our C skills.

    We are C experts when we write efficient, functional code that is clear and comprehensible to not only ourselves but those who will have to work on our code afterwards. This is one of the most important skills as a professional programmer.

    I don't believe in writing unclear, obfuscated code but I also do not believe in writing C for the lowest common denominator of programmers. How will they ever learn?

    Oh come on. Every 8051 programmer is familiar with the names of the commonly used special function registers: PCON, SCON etc. That is what they are called in the data sheets. Keil have very sensibly declared these in the device specific header files. Every Keil 8051 programmer will be familiar with using these - so what do you do? You ignore the Keil header file and give your own declarations. Please don't tell me that aids clarity. The first thing I'd do asked to work on your code would be some global replacement!

    Do you really want a bunch of programmer's writing basic C code or do you want them to grow into the language? Where do you draw the line? No use of ?:, no use of +=, *=, -=, etc., no use of bit-fields? No use of switch blocks? Are these constructs simply to diffucult for a programmer to understand? Nay, I think not.

    I want a bunch of C programmers writing clear, working code that everybody understands. This discussion was about the use of parentheses to aid clarity and overcome the operator precedence rules. Nobody is suggesting not using basic C constructs, were suggesting adding code to clarify intention.

Children
  • Oh come on. Every 8051 programmer is familiar with the names of the commonly used special function registers: PCON, SCON etc. That is what they are called in the data sheets. Keil have very sensibly declared these in the device specific header files. Every Keil 8051 programmer will be familiar with using these - so what do you do? You ignore the Keil header file and give your own declarations. Please don't tell me that aids clarity. The first thing I'd do asked to work on your code would be some global replacement!

    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.

    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.

    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.

    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.

    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 (ignore the confidential markers). http://www.embeddedfw.com

    Regards.

    - Mark

  • 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.