View previous topic :: View next topic |
Author |
Message |
s_mack
Joined: 04 Jun 2009 Posts: 107
|
Is my INT a FLOAT? Or Vice Versa |
Posted: Fri Jun 05, 2009 4:40 pm |
|
|
newbie Q...
Code: |
int8 test = 200;
float modifier = 2.3;
unsigned int8 Function ( unsigned int8 _var ) {
_var = _var * modifier;
return _var;
}
result = Function ( test );
|
Similar code to this isn't doing what I expect.
Because the function is preceded with int8 I think "result" should be 255. I can't actually see what it is because my device has no display but it isn't behaving appropriately. It is behaving as though the number is much lower. Is it because of the float? I think I'm not clear on how datatypes convert from one to the other. _var is an int8 so I thought _var * modifier (a float) would still be an int8? But even if its a float, it should still end up being larger than 255 so it should be returned (forced) as the max allowable int8, no?
Confused.
- Steven |
|
|
s_mack
Joined: 04 Jun 2009 Posts: 107
|
|
Posted: Fri Jun 05, 2009 4:43 pm |
|
|
related...
int = int / 10. Result is what? Int? Float? (presuming int not divisible by 10)
Last edited by s_mack on Fri Jun 05, 2009 5:05 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 05, 2009 4:58 pm |
|
|
If you want a floating point result, at least one of the variables in the
expression must be a floating point, or if it's a constant, the constant
must be written with a decimal point in the number. In a division
expression, at least one of the operations must be declared as a
floating point variable (or be written with a decimal point, if it's a constant).
Also, the variable that receives the result must be floating point.
If a function is to return a floating point value, it must specify that
in the function declaration.
An integer expression will result in an integer result. Any decimal
fraction will be truncated.
In other words, don't expect any 'magical' type promotions. |
|
|
s_mack
Joined: 04 Jun 2009 Posts: 107
|
|
Posted: Fri Jun 05, 2009 5:04 pm |
|
|
No, I get you there. I do in fact want an INT result. But I want the right one
Riddle me this... does ccs for some reason roll over int8 values once they've reached their limit?
This should be a clear example (assume all items are int8):
250 + 50 = ?
I'd expect 255 (the highest int8 value). And from c++ specs I read that should be correct. Does CCS instead interpret that as 45? (rolled over at 255)
That would be consistent with the results I'm seeing. If that is the case, how do I correct? Declare _var as an int16 instead and then manually cap it? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 05, 2009 5:20 pm |
|
|
Quote: |
I'd expect 255 (the highest int8 value). And from c++ specs I read that
should be correct. |
That's not true. I just compiled the following .cpp program in
MSVC++ 6.0 and I got 44.
8-bit integer math gives an 8-bit integer result. There is no rounding
to limits. If you want it, you have to do it. This is elemental C. It's a
couple steps above assembly. Don't assume anything.
Code: | #include "stdafx.h"
#include <stdlib.h>
//========================================
void main()
{
unsigned char a, b, c;
a = 250;
b = 50;
c = a + b;
printf("%d\n", c);
exit(0);
} |
|
|
|
s_mack
Joined: 04 Jun 2009 Posts: 107
|
|
Posted: Fri Jun 05, 2009 6:27 pm |
|
|
thanks. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat Jun 06, 2009 12:28 am |
|
|
Generally, you should spend some time to learn more about the C-standard implicit type conversion and arithmetic processing rules. They are rather straightforward and allow to predict the result of the above questioned cases easily.
In the first example, a float conversion is performed during the calculation but followed by a conversion to int8. So the float factor should be considered correctly.
As already clarified by PCM programmer, modular overflow rather than saturation is the result of exceeding the number range in C arithmetic operations. The C standard committees are discussing fixed point extensions to the C language with saturation as required overflow handling, similar to respective libraries in the VHDL world. |
|
|
s_mack
Joined: 04 Jun 2009 Posts: 107
|
|
Posted: Sat Jun 06, 2009 12:36 am |
|
|
Thanks.
The point of confusion was a document I read (on wikipedia - by no means guaranteed reliable) which stated in no uncertain terms that when a data type's maximum (or minimum) value is exceeded that the variable takes on that maximum (or minimum) value.
I recognize that I lack a fundamental understanding.
I also lack a basic means of testing. Or, rather, I likely have such a means and am not aware of how to utilize it.
In PHP, I'd write some code open a browser and see what happens. With C++ I was handed a Microchip MPLAB ICD 2 device with pre-setup software on the computer and instructions on how to program our PIC devices. In other words, thrown into the pool (as shallow as it may be) without a lesson in the fundamentals of swimming. I don't know how to take these tools and even make a simple "hello world" work.
You are correct. I need to learn the basics. Whether that will happen or not I'm unsure. I'll continue to struggle along and seek help and see how far that gets me. If I find I run into something I can't do... well that's when the company has to get out its pocket book and either teach me to swim or hire a better lifeguard.
Cheers. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat Jun 06, 2009 1:39 am |
|
|
My point was to mention, that the C language has well-defined rules. It's not necessarily required to start C programming by learning them systematically. It's probably more instructive to learn them by the way, solving a problem. It's advisable however to have a language reference or a text book at hand.
Testing code on real hardware is pretty easy with a small PIC development board and an ICD or PICkit adapter. But also MPLAB SIM can give many insights, without any hardware. |
|
|
Ttelmah Guest
|
|
Posted: Sat Jun 06, 2009 7:45 am |
|
|
The problem is that without knowing the exact context of the Wiki quote, it may perfectly well be correct, but be being interpreted 'out of context', applying to a specific language or library.
The best 'reference' for C, is the original K&R 'C programming language', and possibly it's second edition, where ANSI starts to come along. This says for mathematical overflows:
"The handling of overflow, divide check, and other exceptions in expression evaluation, is not defined by the language. Most existing implementations of C ignore overflow in evaluation of signed integral expressions and assignments, but this behaviour is not guaranteed. Treatment of division by 0 and all floating point exceptions, varies among implementations; sometimes it is adjustable by a non-standard library function".
ANSI C, specifically defines unsigned integer overflows, to wrap (as CCS does).
At the end of the day, if you want a error-proof version, you just generate it. For instance:
Code: |
int8 test = 200;
float modifier = 2.3;
unsigned int8 Function ( unsigned int8 _var ) {
float temp;
temp = _var * modifier;
if (temp<256) return _var;
else return 255;
}
result = Function ( test );
|
Best Wishes |
|
|
s_mack
Joined: 04 Jun 2009 Posts: 107
|
|
Posted: Sat Jun 06, 2009 10:31 am |
|
|
Thank you both. Most helpful. |
|
|
Ttelmah Guest
|
|
Posted: Sat Jun 06, 2009 2:48 pm |
|
|
Except (of course) it should return temp, not _var.....
Best Wshs |
|
|
|