Shop OBEX P1 Docs P2 Docs Learn Events
Best type for a long — Parallax Forums

Best type for a long

Dr_AculaDr_Acula Posts: 5,484
edited 2012-05-13 17:50 in Propeller 1
What would be the best way to work with a standard propeller long?

I've tried using a "long" and it works fine and I can input 0b11111111_11111111_11111111_11111110 and it will print FFFFFFFE in hex.

But looking through some of the example code I found "unsigned int" and also "uint32_t"

long is probably the easiest as it is the same as spin but please let me know if it would be better to use a different type of variable.

Comments

  • Heater.Heater. Posts: 21,230
    edited 2012-05-11 02:41
    Dr_A,

    What is a "standard propeller long"?
    Be careful, a LONG in Spin is a signed number. A LONG in PASM need not be. You will get different results some times when changing from uint32_t to int32_t in C. Clearly comparisons work differently, less clearly things like the shift right operator work differently for singed an unsigned ints.

    I like to use the standard types defined in the C header file stdint.h. Like int32_t, uint8_t etc.

    If you ever want to run your C functions anywhere other than the Prop it is a well to stay away from the "int" and "long" etc as they have a habit of changing size from compiler to compiler, machine to machine.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-05-11 03:53
    Yikes! That small pop was the sound of a can of worms opening...
    What is a "standard propeller long"?

    Hmm. I'm a binary sort of chap. A standard propeller long is something between %00000000_00000000_00000000_00000000 and %11111111_11111111_11111111_11111111

    Of course, that might be a moot point when the 64 bit propeller comes out, but it should do for a little while yet.

    WRT comparisons and rotates, I guess the best solution would be to replicate what happens in Spin as closely as possible. That should simplify translating code over to C.

    Just to muddy the waters, maybe add "unsigned long" to the list as that is what I was using in Catalina.

    int32_t would be best then?
  • jazzedjazzed Posts: 11,803
    edited 2012-05-11 07:08
    The limits.h file in the library tells you exactly what is the range of variable types.
    Dr_Acula wrote: »
    int32_t would be best then?

    Definition for int and long are the same for P8x32a propeller-gcc.
    Generally you want to follow heater's advice :)

    Typedefs like uint32_t (unsigned 32 bit integer) found in stdint.h should be used. We don't always do that in our demos though.

    It's much easier to change a few typedef entries for porting than to change hundreds of lines of code. If your other compiler offers stdint.h the type is automatically ported for you.
  • ctwardellctwardell Posts: 1,716
    edited 2012-05-11 07:36
    Dr_Acula wrote: »
    I've tried using a "long" and it works fine and I can input 0b11111111_11111111_11111111_11111110 and it will print FFFFFFFE in hex.

    Did you actually use the underscores as seperators? I thought I had tried than and got an error.

    I know it gives an error in .s files maybe it's OK in .c files.

    C.W.
  • pedwardpedward Posts: 1,642
    edited 2012-05-11 10:52
    In C the INT type is architecture defined. To my knowledge, long, short, and char are all hard types which correspond to 32, 16, and 8 bits. In C, the datatypes will hold the full size of the value, but how it's interpreted can change. For instance, it is very common to see a char used to handle 8bit data, especially when the data is part of a buffer. It's just lazy programmer speak that sometimes bites back. If you are doing arithmetic in C, you will get bit by signed values occasionally. It's been my experience that SPIN tends to bite you back much more often than C in this regard.

    The uint32_t types are a new construct for programmers that want types that are rigidly defined and very obvious, like for embedded programming. That said, a lot of existing C code doesn't use these types and the programmers assume int is 32 bits.

    I don't see any problem with using long to describe a 32 bit signed variable ala SPIN.
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-05-11 11:46
    Dr_Acula wrote: »
    I've tried using a "long" and it works fine and I can input 0b11111111_11111111_11111111_11111110 and it will print FFFFFFFE in hex.
    Dr_A, how did you input the binary number? I had never heard of using 0b before, but it works! And it's not just a PropGCC thing. It works with gcc on my Linux box at work. I wonder if it's a Gnu extension.

    BTW, the embedded underscore don't work in a C program. I get a compiler error if I try that.
  • jazzedjazzed Posts: 11,803
    edited 2012-05-11 13:23
    Dave Hein wrote: »
    Dr_A, how did you input the binary number? I had never heard of using 0b before, but it works! And it's not just a PropGCC thing. It works with gcc on my Linux box at work. I wonder if it's a Gnu extension.

    I'm pretty sure it's a GNU extension. It's one of those promiscuous things your parents and strict C89 advocates warned you about. Once you've been there you're spoiled. Best to put #ifdef GNUC around it.
  • pedwardpedward Posts: 1,642
    edited 2012-05-11 13:48
    Speaking of, what compiler are you using for the Mac and Windows variants? Could you write up a short bit of info on how you setup your Windows dev environment (since you said you were using QtDesigner).
  • jazzedjazzed Posts: 11,803
    edited 2012-05-11 14:53
    pedward wrote: »
    Speaking of, what compiler are you using for the Mac and Windows variants? Could you write up a short bit of info on how you setup your Windows dev environment (since you said you were using QtDesigner).


    This is for SimpleIDE. I'll put some tools/build instructions on the wiki.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-05-11 15:57
    It's one of those promiscuous things your parents and strict C89 advocates warned you about.

    That makes me smile :)

    It is all very well for the purists where hex is just fine and hex got me through until Basic Stamp/Picaxe/Propeller chips came along, but these are languages that appear to have been designed before the age of single chip microcontrollers where many times you want to map variables directly to pins. In other words, turn a led on and off. And of course you can do it in hex or decimal or octal or whatever base you want, but binary is the most visual way to describe some things like turning pins on and off, logical OR and AND, and bitshifts.

    So 0b10101010 does work in GCC. I'm not sure about the underscores though. I'm actually using BCX basic (which does not have 0b1010101) but I added it because it is so useful, and then added the underscores as well because it is a feature from Spin that I really like.

    I wrote an IDE for BCX Basic last night which can do a one click compile/download to SD XMM (by reverse engineering the commands the SIDE sends, building a batch file then running the batch file). Apart from one minor bug in vb.net which insists on sending a 100ms pulse to the DTR line when a com port is opened and resetting the propeller (this is apparently a 'feature') it all works fine and I have one button for 'compile to ram' and another for 'compile to eeprom'. It opens a terminal but you have to compile to eeprom to use the terminal in vb.net. However, with a touchscreen the debug can be on the screen. I wanted to do this to see how hard it was to do. In the process the BCX file goes through a couple of text preprocessor programs (like the one to fix the binary variables) and there are also some tweaks so it plays nicely with GCC. But what my IDE does not have is fast color syntax highlighting, plus it ends up a rather bloated vb.net program. I have an idea it would not be too hard to add BCX Basic to SIDE. It could exist in a separate tab, and you hit compile and it would update the C tab in the process. It could shell out to a couple of simple command line programs that input a text file and output a text file for things like the binary tweaks and any other things that might show up along the way (itoa is another). I'll keep testing a few things, but I think this opens up huge Basic programs for the propeller. And also it is a good way for Basic programmers to learn C as you can see the C program evolve as you write the Basic, and sometimes it is then easier to write inline C in the BCX basic program. You can even write the whole program as inline C if you want. The C89 purists will probably be getting out the flaming brands and pitchforks by now!
  • denominatordenominator Posts: 242
    edited 2012-05-11 20:13
    pedward wrote: »
    In C the INT type is architecture defined. To my knowledge, long, short, and char are all hard types which correspond to 32, 16, and 8 bits.

    Actually: long is at least 32 bits, but could be more. short is at least 16 bits, but could be more. The size of char is not defined, but is typically 8 bits. long and short are signed, char is signed or unsigned depending on the compiler.

    Why should you care? If you're writing code only for the Propeller and promise yourself you'll never port it, then don't worry about it - get your program to work then kick back and have a beer to celebrate.

    However, if you ever want to port your code to a different chip and/or compiler, then the esoteric issues regarding actual length (vs minimum length) and the signed/unsigned nature of each of the "standard" types (int, long, short, char) will matter greatly - there are all kinds of porting bugs out there just waiting to happen to you.

    On the other hand, if you use int32_t, uint32_t, int16_t, uint16_t, int8_t, uint8_t, and are very careful about how you use casts, then you can largely avoid bunches of potential porting bugs with very little work on your part.
  • jazzedjazzed Posts: 11,803
    edited 2012-05-12 12:10
    pedward wrote: »
    Speaking of, what compiler are you using for the Mac and Windows variants? Could you write up a short bit of info on how you setup your Windows dev environment (since you said you were using QtDesigner).

    I've added information on building SimpleIDE from source here: http://code.google.com/p/propside/wiki/BuildingSimpleIDE

    Thanks,
    --Steve
  • Heater.Heater. Posts: 21,230
    edited 2012-05-12 13:39
    Dr_A,
    I'm somwhat against the idea of a BASIC IDE bolted into SimpleIDE. After all it is supposed to be simple. Once we have thrown in BASIC and Spin and Forth and whatever we might as well use Eclipse.

    The bigger issue is that a subsystem or module or plugin like that written in VB is a non-starter as it is not cross platform and it is not open source.

    Perhaps if you would implement your IDE in C++ using the Qt libs as SimpleIDE is it might become a contender.

    Qt has some nice edit widgets with syntax highlighting support.
  • pedwardpedward Posts: 1,642
    edited 2012-05-12 14:19
    Actually: long is at least 32 bits, but could be more. short is at least 16 bits, but could be more. The size of char is not defined, but is typically 8 bits. long and short are signed, char is signed or unsigned depending on the compiler.

    Why should you care? If you're writing code only for the Propeller and promise yourself you'll never port it, then don't worry about it - get your program to work then kick back and have a beer to celebrate.

    However, if you ever want to port your code to a different chip and/or compiler, then the esoteric issues regarding actual length (vs minimum length) and the signed/unsigned nature of each of the "standard" types (int, long, short, char) will matter greatly - there are all kinds of porting bugs out there just waiting to happen to you.

    On the other hand, if you use int32_t, uint32_t, int16_t, uint16_t, int8_t, uint8_t, and are very careful about how you use casts, then you can largely avoid bunches of potential porting bugs with very little work on your part.

    You are correct, however the convention has been, char, short, long, and long long.
  • mindrobotsmindrobots Posts: 6,506
    edited 2012-05-12 15:28
    Steve, I wasn't serious about Forth built into SimpleIDE! :smile: I like it the way it is (with SPIN), please don't turn it into Eclipse jr.

    I think ANY TYPE of IDE for an embedded Forth would be IMPOSSIBLE!! :lol:
  • jazzedjazzed Posts: 11,803
    edited 2012-05-12 17:56
    mindrobots wrote: »
    I think ANY TYPE of IDE for an embedded Forth would be IMPOSSIBLE!! :lol:

    Dang, and there I was half done ... ;)
  • Heater.Heater. Posts: 21,230
    edited 2012-05-13 07:28
    Dr_A,
    Hmm. I'm a binary sort of chap. A standard propeller long is something between %00000000_00000000_00000000_00000000 and %11111111_11111111_11111111_11111111

    Not really. And I suspect that is not quite what you meant. We have to be more rigorous:

    In twos complement representation as used by Spin
    The binary %00000000_00000000_00000000_00000000 is the representation of zero (0)
    That %11111111_11111111_11111111_11111111 is the representation of minus one (-1)

    So your statement becomes "A standard propeller long is something between zero and minus one" which would not be very useful if true. (By the way, I could go on and say there are no values between zero and minus one in this representation so the statement gets even more meaningless).

    In twos comp the top bit is regarded as the sign bit and the rest as the value (sort of) the lowest value is

    -2^31 or %10000000_00000000_00000000_00000000 or -2147483648

    The highest value is:

    +2^31 - 1 or %01111111_11111111_11111111_11111111 or 2147483647

    Note that this is not symmetrical around zero. There are more negative numbers. That's because there is no -0.
    You cannot just set the top bit of the value zero and turn it into minus zero.
    Or indeed you cannot set the top bit of any positive number and turn it into it's negative counterpart. Hence my "sort of" above.

    I'll leave it for you to google how to negate in twos comp.

    Now, a gotcha here is that if you shift a signed two's comp number right, the sign will be preserved in the result so shifting a negative number may not give what you expect. For negative numbers one's will be filling up the top end. Had you declared it unsigned there is no sign to preserve and zeros are shifted into the top end.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-05-13 17:50
    In twos complement representation as used by Spin
    The binary %00000000_00000000_00000000_00000000 is the representation of zero (0)
    That %11111111_11111111_11111111_11111111 is the representation of minus one (-1)

    That is why I like to think in binary - to avoid that sort of confusion. My first processor was 8 bit so -1 to me is binary %11111111, not %11111111_11111111_11111111_11111111.

    As I moved to bigger processors, and every processor (8, 16, 32 bit) defined -1 as the biggest number that processor could represent, I decided none of them were right and started trying to avoid -1 altogether in code. I tend to use binary if working with bitbanging, and or hex. So where someone might write "if a == -1" I would write "if a == 0xFFFFFFFF". Just my personal preference though.

    I tend to only use negative numbers when working with floating point variables.

    For the C variable type, uint32_t seems the least ambiguous. It is unsigned and 32 bits.

    heater said
    If you ever want to run your C functions anywhere other than the Prop it is a well to stay away from the "int" and "long" etc as they have a habit of changing size from compiler to compiler, machine to machine.

    Excellent advice there. And programs may well be run on other compilers - eg in the IDE I'm using I've got TinyC added which is very handy for a quick test that a function does what it is meant to.
Sign In or Register to comment.