CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Is my INT a FLOAT? Or Vice Versa

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
s_mack



Joined: 04 Jun 2009
Posts: 107

View user's profile Send private message

Is my INT a FLOAT? Or Vice Versa
PostPosted: Fri Jun 05, 2009 4:40 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 05, 2009 4:43 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 05, 2009 4:58 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 05, 2009 5:04 pm     Reply with quote

No, I get you there. I do in fact want an INT result. But I want the right one Smile

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

View user's profile Send private message

PostPosted: Fri Jun 05, 2009 5:20 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 05, 2009 6:27 pm     Reply with quote

thanks.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sat Jun 06, 2009 12:28 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 06, 2009 12:36 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 06, 2009 1:39 am     Reply with quote

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







PostPosted: Sat Jun 06, 2009 7:45 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 06, 2009 10:31 am     Reply with quote

Thank you both. Most helpful.
Ttelmah
Guest







PostPosted: Sat Jun 06, 2009 2:48 pm     Reply with quote

Except (of course) it should return temp, not _var.....

Best Wshs
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group