|
|
View previous topic :: View next topic |
Author |
Message |
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
PIC24EP512 - Arithmetic question with unsigned int64 |
Posted: Fri May 19, 2023 8:35 am |
|
|
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: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Fri May 19, 2023 9:06 am |
|
|
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: 19498
|
|
Posted: Sat May 20, 2023 10:19 am |
|
|
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: 19498
|
|
Posted: Sun May 21, 2023 10:58 am |
|
|
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.... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Tue May 23, 2023 5:23 am |
|
|
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: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Wed May 24, 2023 9:26 am |
|
|
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: 19498
|
|
Posted: Wed May 24, 2023 9:51 am |
|
|
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: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Fri May 26, 2023 7:57 am |
|
|
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: 19498
|
|
Posted: Fri May 26, 2023 10:52 am |
|
|
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: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Fri May 26, 2023 2:56 pm |
|
|
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 |
|
|
|
|
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
|