Controls Guy
Internal Dev
   
Posts: 1134
Darth Ladder
|
 |
« on: February 22, 2011, 11:04:54 am » |
|
Does MULB potentially leave garbage in the accumulator high word if its result will fit in 16 bits? The instructions say: Multiply Binary is a 16 bit instruction that multiplies the binary value (Aaaa), which is either a V memory location or a 4-digit (max.) binary constant, by the binary value in the accumulator The result can be up to 32 bits and resides in the accumulator.
which sounds to me like there should always be a correct 32-bit result left in accumulator after the operation regardless of the size of the result. I had FOR V26651 LD P26650 SUBB V26654 OUTD V26656 MULB V26656 ADDBD V26660 OUTD V26660 MATHBIN V26650 = V26650 + K1 NEXT and I was getting strange results after the MULB. In one case the result following the SUBB was -13, and the V26656 contained l69 (correct), but V26657 wasn't cleared, which led to incorrect results in V26660/61. I added ANDD KFFFF between the MULB and the ADDBD and the calculation is now correct. So what happens with the accumulator when a MULB returns a value less than 16 bits?
|
|
|
|
|
Logged
|
I retract my earlier statement that half of all politicians are crooks. Half of all politicians are NOT crooks. There.
|
|
|
|
franji1
|
 |
« Reply #1 on: February 22, 2011, 11:54:50 am » |
|
The 32 bit accumulator represents the correct result. If you know the result fits in 16 bits, then the hiword will be 0x0000. Remember, though, that multiply just 256 x 256 will yield 65536, which doesn't fit in 16 bits. LD K100 // sad, but this is 256 decimal MULB K100 // ditto OUT V2000 // V2000 will equal 0 OUTD V2001 // V2001 as a double binary will equal 65536
|
|
|
|
|
Logged
|
|
|
|
Controls Guy
Internal Dev
   
Posts: 1134
Darth Ladder
|
 |
« Reply #2 on: February 22, 2011, 12:27:49 pm » |
|
The 32 bit accumulator represents the correct result. Then I don't understand how in my situation V26657 was non-zero.
|
|
|
|
|
Logged
|
I retract my earlier statement that half of all politicians are crooks. Half of all politicians are NOT crooks. There.
|
|
|
|
franji1
|
 |
« Reply #3 on: February 22, 2011, 12:34:41 pm » |
|
The 32 bit accumulator represents the correct result. Then I don't understand how in my situation V26657 was non-zero. I don't think the "decimal" format of the DL PLCs understands negative numbers, so if your SUBB results in a -1, the result will be 4294967295 (or 0xFFFFFFFF), which you are squaring. Could the result of the SUBB be a negative number?
|
|
|
|
|
Logged
|
|
|
|
Controls Guy
Internal Dev
   
Posts: 1134
Darth Ladder
|
 |
« Reply #4 on: February 22, 2011, 12:45:40 pm » |
|
The result of the SUBB WAS a negative number (-13 as noted) but in earlier test, squaring a number which when displayed in signed decimal is negative results in a correct positive 32 bit result. But...those tests were using multiplicands large enough that the result was over 16 bits.
Even in this case (-13^^2), the low word contained the correct result, 169, just that the high word was non-zero.
|
|
|
|
|
Logged
|
I retract my earlier statement that half of all politicians are crooks. Half of all politicians are NOT crooks. There.
|
|
|
|
franji1
|
 |
« Reply #5 on: February 22, 2011, 12:51:36 pm » |
|
It appears the lower word would be correct, even though it is doing 65523 * 65523 (not -13 * -13). The result is 4293263529, in hex that's FFE600A9, looking at the lower word is 0x00A9 which is 169!
|
|
|
|
|
Logged
|
|
|
|
Controls Guy
Internal Dev
   
Posts: 1134
Darth Ladder
|
 |
« Reply #6 on: February 22, 2011, 01:08:25 pm » |
|
But if that's the case, then why did my test squaring larger negative numbers (like in the -2000 to -4000 range) work correctly, giving answers in the 10 million range?
|
|
|
|
|
Logged
|
I retract my earlier statement that half of all politicians are crooks. Half of all politicians are NOT crooks. There.
|
|
|
|
franji1
|
 |
« Reply #7 on: February 22, 2011, 02:24:05 pm » |
|
It's all in the modulo math, but to see answers in the 10M range, you would have to look at it as a DWORD, not a WORD. If you want warm-fuzzies algebraically, you could take the absolute value of the result of the SUBB before you square it (if negative, take the 2's completement doing INV + K1) STR SP70 // I'm assuming this is looking at bit 31 of the accumulator and that's it - if it's "smart", then this might not work INV ADDB K1
|
|
|
|
|
Logged
|
|
|
|
Controls Guy
Internal Dev
   
Posts: 1134
Darth Ladder
|
 |
« Reply #8 on: February 22, 2011, 02:45:00 pm » |
|
That's exactly what I'm trying to tell you. You say the 32 bit result is correct. I say No, if I square -13 I get 169 in the lower word but garbage in the upper word so the WORD answer is right but the DWORD wrong. You say the problem is squaring negative numbers. That if you square negative numbers you won't get a correct result because it squares (65536-n) but that's not true because when I square -3500 (62036 if interpreted as unsigned) I get the correct answer in a DWORD (12250000 rather than 3848465296). The platform is a 450. Try it for yourself. So my conclusion is that if the answer from a MULB will fit in the lower word, the upper word is unpredictable, and probably incorrect.
|
|
|
|
|
Logged
|
I retract my earlier statement that half of all politicians are crooks. Half of all politicians are NOT crooks. There.
|
|
|
Controls Guy
Internal Dev
   
Posts: 1134
Darth Ladder
|
 |
« Reply #9 on: March 09, 2011, 12:26:03 pm » |
|
Sorry if my tone was a bit abrupt.  Didn't mean to scare you off. Still trying to figure out what MULB's doing and how to get it to work as expected.
|
|
|
|
|
Logged
|
I retract my earlier statement that half of all politicians are crooks. Half of all politicians are NOT crooks. There.
|
|
|
|
franji1
|
 |
« Reply #10 on: March 09, 2011, 03:58:17 pm » |
|
Basically, if it's negative, negate it, then square it. Then you won't get your random values in the HIWORD That's what my logic was from before (this is the answer you are looking for) STR SP70 // accumulator negative? INV // invert the accumulator ADDB K1 // add 1
Now the accumulator has the absolute value of your negative number. Square that and your upper word should be fine.
|
|
|
|
|
Logged
|
|
|
|
Controls Guy
Internal Dev
   
Posts: 1134
Darth Ladder
|
 |
« Reply #11 on: March 09, 2011, 04:53:54 pm » |
|
Yes, that's a workaround but I still don't **understand** what it's doing. Why can it correctly square large negative numbers (result > 65536) such as -3500 but not small ones?
|
|
|
|
|
Logged
|
I retract my earlier statement that half of all politicians are crooks. Half of all politicians are NOT crooks. There.
|
|
|
|
franji1
|
 |
« Reply #12 on: March 09, 2011, 05:24:12 pm » |
|
A computer's architecture has to interpret it as a 2's complement number (i.e. high bit is NEGATIVE 2^(bitnum)), or as a binary number (i.e. high bit is POSITIVE 2^(bitnum).
Sometimes there are register flags to let a computer know that the value in the register is signed or unsigned (2's complement or straight binary). This is how PC's do it.
DL PLCs look at it as binary, not 2's complement.
|
|
|
|
|
Logged
|
|
|
|
Controls Guy
Internal Dev
   
Posts: 1134
Darth Ladder
|
 |
« Reply #13 on: March 18, 2011, 12:42:03 pm » |
|
Interesting....I tried squaring negative numbers on a 260 and it works exactly as you describe. It assumes the format is unsigned. Unfortunately I no longer have access to the 450 where I had the issue, but I swear I squared -3500 and got 12,250,000. Weird.
|
|
|
|
|
Logged
|
I retract my earlier statement that half of all politicians are crooks. Half of all politicians are NOT crooks. There.
|
|
|
|