Casting (getting inside of...)

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

•I am in a function - passing a pointer to a structure.
•my_param is and unsigned 8-bit int (uint8_t).

The following gives an incorrect result:

#define SECONDS_IN_A_DAY 86400

my_param is and unsigned 8-bit int (uint8_t).
uint32_t var = my_strcut->my_param * SECONDS_IN_A_DAY;

If however I cast my_parm the result is correct.

uint32_t var = (uint32_t)my_strcut->my_param * SECONDS_IN_A_DAY;

My understanding of castign was that the first example is a case of implicit casting should still produce the correct result. As the final result of the equation is a 32-bit variable.
Also does the castign have any processor tick/cycle cost?

N.B. I'v made this post not becasue I have a problem with what is going on - more I am interested why.

Ben
-Using IAR (& ocasionally CodeVision)
0.7734
1101111011000000110111101101

Last Edited: Tue. May 6, 2008 - 10:44 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Integer promotion will make the computation with 16 bits (well, if int is 16 bits which is most often the case with C on the AVR). This is not enough hence you need the cast.
/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Alternatively add a UL to 36000UL

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Using IAR & CodeVision

Which are you using ?

There is never any harm in helping the compiler. So since you know that you will have to do a 32 bit math, why not add the UL to the constant or cast it.

You should only need one umul32 and one udiv32 I think. All the other calculations fit in umul16.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm running this project with IAR

Ben
-Using IAR (& ocasionally CodeVision)
0.7734
1101111011000000110111101101

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
My understanding of casting was that the first example is a case of implicit casting should still produce the correct result. As the final result of the equation is a 32-bit variable.

An implicit cast is done for each operator. There are two implicit casts here since there are two operators. The * is done first, and the constant will be defined as an int. So the first cast is from the uint8_t to int. Then the = is evaluated, causing the second cast from int to uint32_t.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Without any hint that 36000 is an UL, the 36000 will be evaluated as a signed int and the calculation will be with the "my_param" promoted to an unsigned int.

This result will be a signed 16 bit result.

The assignment will then cast to the type of the receiving variable.

It is fairly unlikely that this eventual result was the author's original intention.

Looking at my original code, I could have used 16 bit variables in several places. And some could even be 8 bit. (but it was originally on a cpu with 32bit registers anyway)

David.

Edit. I may be wrong about 36000 being int16_t. A C expert may know whether a positive constant > 32767 is treated as a int32_t. I would always play safe.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As the others have mentioned, casting merely overides the default rules of the compiler (which is described in the c spec). As to whether this involves extra cpu cycles depends on what effect the cast has. In short you're telling the compiler to do it *my way*, if your way involves a 32bit operation as opposed to a 16 bit operation, then on an AVR extra cycles are required.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

On another note entirely...

Isn't there 86400 seconds in 1 day?
Wouldnt 36000 secs be 10 hours?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

schtevo wrote:
On another note entirely...

Isn't there 86400 seconds in 1 day?
Wouldnt 36000 secs be 10 hours?

On earth! ;)

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Err... yes. I guess it may be presumptuous to think the end result is for an earth bound applicaiton but the op didnt exactly specify. And I supose it could be measuring some other astronomical quantity and still be earth bound. But what are the odds?

Care to explain, Ben?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

While I am sure I could think of a crazy (and perfectly logical) explanation - basically that is just a typo. I was writing the example off the top of my head.

Although just to be sure I have double checked by code and I do have:

#define SECONDS_IN_DAY      86400 // 24 * 60 * 60

I also have:

#define SECONDS_IN_AN_HOUR  3600  // 60 * 60

So I suspect that is where I have made the mistake :lol: :roll:

Ben
-Using IAR (& ocasionally CodeVision)
0.7734
1101111011000000110111101101