Castign from double to uint32

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

Hi folks,

 

I had to realize that my casting operation returns complete ********.

Here's the failing code snippet:

dGainCorrFactor = ((double)(740000000000) / (double)(2300)) /
					(double)(u32CrntVal);
dNewGain = (double)(u16Gain) * dGainCorrFactor;
u32NewGain = (uint32_t)(dNewGain);

dGainCorrFactor and dNewGain result in the expected results.

In one example I calculated manually during debug. u32NewGain should have resulted in 0xe179 instead it became 0xe179e179. 

Changing the line of u32NewGain to 

u32NewGain = (uint32_t)((uint16_t)(dNewGain));

fixed the casting issue but this is not what I want since I'm not sure what would happen if dNewGain would be larger than 0xFFFF. 

Does anybody know why this problem occured? Why would that cast ja write the lower two bytes the same way than the upper two bytes? The compiler I use i avr-gcc.

 

Thanks for your help!

Last Edited: Tue. Oct 20, 2020 - 12:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why are you using a cast?

 

A cast says, "take the bit pattern stored in memory and interpret it this way"

 

Don't you actually want a conversion from double to uint32_t ?

 

A straight assignment will do that ...

 

EDIT

 

I think I'm wrong about the cast - but still, just the assignment is needed.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Tue. Oct 20, 2020 - 01:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EHEMMMM ... really? Gosh I feal stupid now. You'll find me in the corner of shame ....

 

but thanks for the help ;)

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

No worries.

 

If that's it, please mark the solution - see Tip #5 in my signature, below, for instructions:

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hmmm it seams like it's actually not the solution. I changed my code to:

dGainCorrFactor = (740000000000.0f / 2300.0f) / u32CrntVal;
dNewGain = u16Gain * dGainCorrFactor;
u32NewGain = dNewGain;

and u32NewGain again holds a copy of the lower two bytes in  the upper two bytes (u32NewGain = 0x0f2b0f2b)

 

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

Have you tried this on a PC ?

 

How about giving some actual data - some inputs, your expected results, and what you actually get ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah I was going to ask that - what are the actual u32CrntVal and u16Gain when this appears to go wrong?

 

(I have a sneaking suspicion this might all be about debugger misinterpretation in fact).

 

Also, like Andy, I would try this in a PC development environment first - if it's a trangression of C's promotion rules or something you will see that much more easily on the PC than in AVR code.

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

Allright I did some more debugging. 

I had the suspission of misinterpretation as well but than I tried the above with no other code in the program and it worked as expected. Both examples btw. so if I cast a double to a uint32_t it doesn't just copy the binary representation and changes the interpretation of it but rather converts the integer part of the double to be decimally correct in the uint ... assumind that the integer part isn't to large or negative ... 

However, when I define the variable globally the program works again. So I think the issue is a stack problem?!

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

You haven't said what tools you're using.

 

Are you sure you've configured correctly for 'double' support?

 

avr-gcc Wiki wrote:
In avr-gcc up to v9, double and long double are only 32 bits wide and implemented in the same way as float.

In avr-gcc v10 and higher, the layout of double and long double are determined by configure options

 

https://gcc.gnu.org/wiki/avr-gcc...

 

clawson wrote:
this might all be about debugger misinterpretation

That's a thought.

 

@ Dudovitz - how, exactly, are you observing the values ?

 

Does printf() give the same results ?

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dudovitz wrote:
if I cast a double to a uint32_t it doesn't just copy the binary representation

Yes, I was talking rubbish there.

 

Added a note in #2

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hui gcc version hmmmm good question. I'm using AtmelStudio 7.0 and I assume I use the default gcc that comes with it?! All I see in the project properties is  that I'm using the avr-gcc but I don't know where to find the version number.

I'm programming an Atmega328pb and debugging on it using breakpoints. 

The problem occurs deep in my program. If I erase my entire program just try the little code snippet above (all declared volatile). The calculation works. Deep in my prog it doesn't. Except if I declare u32NewGain globally. That's why I came to the conclusion of having a problem with the stack?!

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

Dudovitz wrote:
However, when I define the variable globally the program works again.
Similar when done in a linter.

Dudovitz wrote:
So I think the issue is a stack problem?!
Scope issue?

Re-arranging the source code reduced the quantity of linter errors (almost always more than one way to code an algorithm)

 

PC-lint Plus Online Demo - Gimpel Software - The Leader in Static Analysis for C and C++ with PC-lint Plus (based on Clang)

 

"Dare to be naïve." - Buckminster Fuller

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

... or a C interpreter on a server.

Concur on a test case.

 

cling@GOREPL (Cling is based on Clang)

 

"Dare to be naïve." - Buckminster Fuller

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

awneil wrote:

How about giving some actual data - some inputs, your expected results, and what you actually get ?

+1000

 

We can't try it for ourselves unless you give us a failing test case.

 

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

Thanks for all your help folks. Really appreciate it!

Turned out the actual error was a little earlier where I caused a variable overflow which finally resulted in all the trouble. Now where I fixed that the code is running as expected when I set the compiler optimization to 1. In the above example it was set to “opt. for debug”. I assume the lower grade of optimization Caused the stack overflow.

Anyway. For the sake of understanding I’ll check on the above again tomorrow when I’m back in the office.