|
|
View previous topic :: View next topic |
Author |
Message |
kgng97ccs
Joined: 02 Apr 2022 Posts: 97
|
Mixing floats and integers |
Posted: Mon Oct 10, 2022 2:09 am |
|
|
I am using the PIC18LF46K22, CCS C compiler v5.110, and MPLAB IDE v8.92.
Recently I ran the following program: Code: | #include "18LF46K22.h"
#include "math.h"
#use delay(clock=1600000)
#use rs232(UART, baud=9600, errors)
void main()
{
unsigned int16 x, y, z1, z2, z3, z4, z5, z6;
x = 1000;
y = 125;
z1 = floor ( (2.0/3)*x/y + 0.5 );
z2 = floor ( (2/3.0)*x/y + 0.5 );
z3 = floor ( (2.0/3.0)*x/y + 0.5 );
z4 = floor ( (2f/3)*x/y + 0.5 );
z5 = floor ( (2/3f)*x/y + 0.5 );
z6 = floor ( (2f/3f)*x/y + 0.5 );
printf("z1 = %Lu\n", z1);
printf("z2 = %Lu\n", z2);
printf("z3 = %Lu\n", z3);
printf("z4 = %Lu\n", z4);
printf("z5 = %Lu\n", z5);
printf("z6 = %Lu\n", z6);
} |
Results: Code: | z1 = 336
z2 = 5
z3 = 5
z4 = 336
z5 = 5
z6 = 5 |
When converting the ratio 2/3 to a float or double, I thought I would just need to convert either the numerator or the denominator to a float [e.g., 2f/3 or (float) 2/3)] or a double (e.g. 2.0/3); I am assuming that 2.0 is a double. However, the correct results were obtained only when the denominator is converted.
Questions:
1. For those conversions that did not give the correct result (z1 and z4), did I do anything wrong?
2. What is causing z1 and z4 to give 336 instead of 5?
3. Does it matter whether we append an âfâ (e.g., 2f) or a decimal point (e.g., 2.0) when converting an integer to a float or double? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19548
|
|
Posted: Mon Oct 10, 2022 2:45 am |
|
|
There is not a double float in CCS (except once you go up to the PIC24/33),
so all the floats are single.
The parser 'knows' it can represent 2.0 exactly as an integer, so does so.
This then means the maths doesn't get forced to be fp maths.
2f, doesn't result in a cast up, it is just that same as 2.0.
However an explicit cast will work.
So:
z1 = floor ( (float)2/3)*x/y + 0.5 );
Will merrily work.
Or
z1 = floor ( (2.1/3)*x/y + 0.5 );
z1 = floor ( (1.99999/3)*x/y + 0.5 );
Because the number is explicitly switched to being a 'float'. Because it
can't be represented as an integer.
With the denominator made into a float the compiler 'knows' FP maths
is required.
It is an oddity in the parsing, that has been reported before. Basically
if the compiler sees a number that can be an integer, it will assume it is
as it parses along the line, until something forces it to not be treated as
an integer. |
|
|
kgng97ccs
Joined: 02 Apr 2022 Posts: 97
|
|
Posted: Tue Oct 11, 2022 10:09 pm |
|
|
Thank you, Ttelmah, for your explanation.
I find it really odd that the compiler behaves this way, so I wrote to CCS and asked them whether this behavior was intended or due to a bug.
CCS replied: "It is a compiler bug and will be fixed in the next release." |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19548
|
|
Posted: Wed Oct 12, 2022 1:01 am |
|
|
Yes, it is definitely a bug, but so minor as to be not worth worrying about
really. It has been mentioned here before. I think honestly the explicit
cast is clearer, and this has always worked OK....
If they fix it 'great'. |
|
|
kgng97ccs
Joined: 02 Apr 2022 Posts: 97
|
|
Posted: Wed Oct 12, 2022 1:47 am |
|
|
This behavior was really unexpected and I think most people would not have suspected the type casting to be the cause of the error. It actually took me quite a while to find out the cause.
Anyway, in line with your suggestion, I have modified all my code to use only the explicit method for type casting, so that the code will work correctly with both earlier and later versions of the compiler. |
|
|
kgng97ccs
Joined: 02 Apr 2022 Posts: 97
|
|
Posted: Fri Oct 21, 2022 5:19 am |
|
|
This bug has now been fixed in the new compiler version, v5.111, released today (2022-10-21). See third item below.
From CCS: Code: | 5.111 IDE file history right click now allows you to clear all entries
5.111 A problem with the IDE Wizard starting up on some machines is fixed
5.111 A type problem with a constant float being divided by a constant integer is fixed.
5.111 Duplicate #defines in some devices header files has been fixed.
5.111 Fixed bad SFR names in PIC16F180xx family.
5.111 Fixed an issue where DSM and CRC peripheral functions in the PIC16F180xx family.
5.111 Fixed setup_oscillator() and port_x_pullups() writing to unused registers for PIC16F180xx family.
5.111 Fixed header files for some dsPIC33 devices that caused a compiler error.
5.111 Fixed an issue with missing BROWNOUT_NOSL for some PIC16 devices. |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19548
|
|
Posted: Fri Oct 21, 2022 5:27 am |
|
|
Have you tested it?.....
As always, only believe it, when you have tested. |
|
|
kgng97ccs
Joined: 02 Apr 2022 Posts: 97
|
|
Posted: Fri Oct 21, 2022 10:56 am |
|
|
Yes, Ttelmah. I have tested the same program (with additional variations), and got the correct results. Code: | #include "18LF46K22.h"
#include "math.h"
#use delay(clock=1600000)
#use rs232(UART, baud=9600, errors)
void main()
{
unsigned int16 x, y, z1, z2, z3, z4, z5, z6, z7, z8;
x = 1000;
y = 125;
z1 = floor ( (2.0/3)*x/y + 0.5 );
z2 = floor ( (2/3.0)*x/y + 0.5 );
z3 = floor ( (2.0/3.0)*x/y + 0.5 );
z4 = floor ( ((float) 2/3)*x/y + 0.5 );
z5 = floor ( (2f/3)*x/y + 0.5 );
z6 = floor ( (2/3f)*x/y + 0.5 );
z7 = floor ( (2f/3f)*x/y + 0.5 );
z8 = floor ( (2/3)*x/y + 0.5 );
printf("z1 = %Lu\n", z1);
printf("z2 = %Lu\n", z2);
printf("z3 = %Lu\n", z3);
printf("z4 = %Lu\n", z4);
printf("z5 = %Lu\n", z5);
printf("z6 = %Lu\n", z6);
printf("z7 = %Lu\n", z7);
printf("z8 = %Lu\n", z8);
} |
Results: Code: | z1 = 5
z2 = 5
z3 = 5
z4 = 5
z5 = 5
z6 = 5
z7 = 5
z8 = 0
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19548
|
|
Posted: Fri Oct 21, 2022 10:04 pm |
|
|
Good.
Historically, some years ago, CCS was rather poor at launching changes
without much testing. They improved a while ago, but then seemed to
go downhill again, so I treat all new versions as 'beta' till I have done
significant testing.
Caveat.
Nice to have a problem fixed. |
|
|
|
|
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
|