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

PIC24EP512 - Arithmetic question with unsigned int64

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



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PIC24EP512 - Arithmetic question with unsigned int64
PostPosted: Fri May 19, 2023 8:35 am     Reply with quote

Device: PIC24EP512GP806
Compiler: 5.026

Hi all,

I'm trying to understand what is going-on here using the following code:

Code:
unsigned int64  states[5] = {};
unsigned int16  a,b,c,d,e;
unsigned int64 Temp;
 
states[0] = 26437;
states[1] = 61389;
states[2] = 33682;
states[3] = 4660;
states[4] = 22136;

a = 19851;
b = 60486;
c = 34486;
d = 63961;
e = 34964;

Temp = states[0] + a;
states[0] = Temp;

Temp = states[1] + b;
states[1] = Temp;

Temp = states[2] + c;
states[2] = Temp;

Temp = states[3] + d;
states[3] = Temp;

Temp = states[4] + e;
states[4] = Temp;


A print-out of these operations returns the following which makes sense:

states[0]: 46288
states[1]: 121875
states[2]: 68168
states[3]: 68621
states[4]: 57100

Then, the following operations are performed:

Code:

states[0] &= 0xFFFF;
states[1] &= 0xFFFF;
states[2] &= 0xFFFF;
states[3] &= 0xFFFF;
states[4] &= 0xFFFF;


If I do a print-out of all 5 states, this is the result:

states[0]: 46288
states[1]: 0
states[2]: 0
states[3]: 0
states[4]: 0

The same code on my PC returns the following:

states[0]: 46288
states[1]: 56339
states[2]: 2632
states[3]: 3085
states[4]: 57100


What's wrong?
benoitstjean



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Fri May 19, 2023 9:06 am     Reply with quote

I went through the entire code and there was no reason for the states array to be unsigned int64 so I changed it to unsigned int16 and it works.

It's just odd that the first iteration worked but not the other ones.

I won't mark it as solved for now in case someone has an explanation.

Thanks,

Ben
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat May 20, 2023 10:19 am     Reply with quote

I hope/think you mean int32, Several of the operations are too large to
fit in an int16.
I have reported here in the past issues with int64. I suspect you wold
find it was with the propogation of your mask from int16.
So if you had used an explicitly int64 mask it would have worked.

I realise too, how old your compiler is. There have been a lot of fixes on
the int64 maths after this time. When I was having issues, it was around
5.06x, and CCS at the time introduced about three fixes, which corrected
my problems.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun May 21, 2023 10:58 am     Reply with quote

I'm wondering how you are testing this?.

I just took your exact code, and compiled it with your compiler, and I get
after the &= pass:

states[0] = B4D0
states[1] = DC13
states[2] = A48
states[3] = C0D
states[4] = DF0C

(printing in hex). This on your chip.

Not what you describe at all.

However, it does have problems if you print the values using a for loop
and a counter. There was an issue described here a while ago, where
array indexes into int64 arrays did not work correctly. Accessing the
wrong element from the array.

I suspect this is what you are actually seeing.

There is one other thing.
I remember that on the earlier compilers, int64 could only be signed.
Just checked on your compiler, and the manual page for type specifiers,
says:

Quote:

(Except int64 may only be signed)


This may well also be causing problems.... Sad
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue May 23, 2023 5:23 am     Reply with quote

Are you possibly running this in the MPLAB 8.92 simulator?.
If so, it has a weird maths problem. The MUL instruction used to perform
the array access, is giving twice the result it should!... Result the wrong
bytes are accessed in memory by the array accesses.
Doesn't do this on the MPLABX simulator, or in the real chip.

MUL.UU 0x0008, #8, 0x0

Which takes the value stored at 0x8, and multiplies it by the constant '8',
and writes this to location 0, for 2 in address 8, writes 0x20 into location
0 on this simulator, not 0x10 as it should....
Eeek.

Seems to only do it on this chip family.

Caveat.

Yes. Just confirmed. Using your compiler, MPLAB-X produces:

STATES 0 = 46288
STATES 1 = 56339
STATES 2 = 2632
STATES 3 = 3085
STATES 4 = 57100

My initial test was with the real chip which is why I was getting correct
results.

What you actually get on the later values depends on what is stored in the
RAM after the states array.

So you have a simulator fault, not a compiler problem.....
benoitstjean



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Wed May 24, 2023 9:26 am     Reply with quote

Sorry for the late response, I wrote back something yesterday but I guess my message didn't go through?

I looked at my code and it does produce the same result as yours:

states[0] = B4D0
states[1] = DC13
states[2] = A48
states[3] = C0D
states[4] = DF0C

My code was simplified for understanding purposes in my message. So what I'm trying to accomplish here may be feaible in part but bear with me. Last week, I was asked to look into file hashing as a means of confirming if a file was manipulated or not. The files are on an SD card and the PIC will read the data and produce the output hash.

I realize that SHA256 is not possible due to the large numbers required in the hashing.

So I asked my good friend chatGPT to create the simplest C code with some constraints such that the result of an arithmetic operation cannot and must not exceed a 64-bit number. The code had a few errors in it which I've fixed and I can run it on both my PC in a small Windows app just like I can run it on the PIC and they both appear to be returning the same output hash for the same input data.

However, somewhere in the CCS documentation, I saw some place where it showed unsigned int64 intgers but I figured I'd give it a quick try and this is what I get:

Code:

   int64 Val = 0x3FFFFFFFFFFFFFFF;

   fprintf( MONITOR_SERIAL, "\n\r64-bit test: %08X * 2 = %08X", Val, ( Val * 2 ) + 1 );
   fprintf( MONITOR_SERIAL, "\n\r64-bit test: %08X * 2 = %08X", Val, ( Val * 2 ) + 2 );



Result:

64-bit test: 3FFFFFFFFFFFFFFF * 2 = 7FFFFFFFFFFFFFFF
64-bit test: 3FFFFFFFFFFFFFFF * 2 = 800000000

As you can see, the second where I add +2 returns only a 16-bit value. So I guess the reason my code works on both the PC and the PIC is that I just didn't run into a situation where the same input will result in different outputs. Also, the result hash in the simplified code doesn't return a full string of hex but rather some hex values with 00 in repetitive places.

If I was to upgrade my compiler, does it now support unsigned int64?

Otherwise, any other suggestion for file hashing?

Thanks!

Ben
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Wed May 24, 2023 9:51 am     Reply with quote

It is fairly borderline, on when your compiler dates to. They seemed to
realise that people might want unsigned, and bought it in in parts over a few
versions. The manual slowly changed to reflect this.
On the current version, it merrily accepts a silly -ve number like
-123456789, and prints this as unsigned 18446744073586094827
which is correct for the unsigned representation of FFFFFFFFF8A432EB.
So it is storing it, and printing it correctly as unsigned.

However it is interesting that the current version of Pconvert, still does not
offer unsigned int64.
benoitstjean



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Fri May 26, 2023 7:57 am     Reply with quote

Alrighty, I guess I got lost in my code somehow because I think it works:

Code:

   unsigned int64 Val =  0xFFFFFFFFFFFFFFFF;
   unsigned int32 Val1 = 0x12345678;
   unsigned int32 Val2 = 0x90ABCDEF;
   unsigned int64 Val3 = (unsigned int64 ) Val1 << 32 | (unsigned int64 ) Val2;
   
   fprintf( MONITOR_SERIAL, "\n\rVal: %16X", Val );
   fprintf( MONITOR_SERIAL, "\n\rVal1: %8X", Val1 );
   fprintf( MONITOR_SERIAL, "\n\rVal2: %8X", Val2 );
   fprintf( MONITOR_SERIAL, "\n\rVal3: %16X", Val3 );


Result:
Val: FFFFFFFFFFFFFFFF
Val1: 12345678
Val2: 90ABCDEF
Val3: 1234567890ABCDEF


Ben
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri May 26, 2023 10:52 am     Reply with quote

Yes, looks right.
As I said, is it possible you were using the MPLAB simulator?. This has a
serious issue on this chip of performing the array access maths wrong.
So gives silly answers.

I don't think anyone has actually worked out the exact version where CCS
made unsigned int64 work.
benoitstjean



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Fri May 26, 2023 2:56 pm     Reply with quote

Nope, not using MPLAB.

And I wrote to CCS support and they did confirm that my version works with unsigned int64 as I have proven in my last test.

Ben
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