Searching \ for '16 bit PIC math question on subtracting' in subject line. ()
Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/math/index.htm?key=math
Search entire site for: '16 bit PIC math question on subtracting'.

Truncated match.
'16 bit PIC math question on subtracting'
2000\02\07@215545 by

I have been looking at the 16 bit math routines at
http://www.myke.com/PICMicro/16bit.htm and I was wondering if
someone can tell me by looking at the subtraction routine(s) there, if they
handle negative numbers.  I am going to need to do things where I am ending
up with a final result that is a positive number, maybe dividing a negative
by a negative, but I want to know if these routines will do negative numbers
for my intermediate steps.  If now, how can I?

I cannot figure out how to make a 16-bit addition or subtraction
function that _cannot_ handle signed values.  Please test it.

--
James Cameron   quozlus.netrek.org   http://quozl.us.netrek.org/

Hiya,

The addition/subtraction routines handle and produce two's complement
numbers as a matter of course.  The multiplication routines should not have
any problems with negatives.

Dividing a negative by a negative - no the 16 bit division routine presented
on my page will not do that.  It's a pretty scary proposition.  What I
usually do is convert dividend and divisor to positive values and then when
I have the positive results, I convert them to negative.

myke
{Original Message removed}

But, when you divide a negative by a negative, don't you get a positive result anyways? My
calculator seems to think so.

BTW, at the risk of taking this thread OT, where have you been, Myke? Did your vision
problem take a while to get corrected? I, for one, have missed your input here, and your
Rentron articles (plus, I'm getting tired of the soft drink survey on your website)

-Randy Glenn
E-Mail: PICxpertyahoo.com
Web: http://i.am/PICxpert

Currently wondering why I can't get in to Safe Mode - where's a Mac when you need it?

{Original Message removed}

2000\02\08@031018 by
> Dividing a negative by a negative - no the 16 bit division routine
presented
> on my page will not do that.  It's a pretty scary proposition.  What I
> usually do is convert dividend and divisor to positive values and then
when
> I have the positive results, I convert them to negative.

I know it seems odd to ask such questions when I should be able to simply
"test" the code myself as was insisted in another response, but to me as a
Pic beginner....I'm looking at some black stuff with shiny pins on a
breadboard....I wouldn't really know how to test things off hand...it's hard
to get used to thinking in binary

...so on that note, my final result will always be positive so the signs
won't matter, and it's ok for me to convert negatives to positives for
division, but I wouldn't even know how to do that simple seeming task.

I want to implement an equation    x = (b^2 - a^2 - c^2) / (-2c)
In this equation, the value "c" is always going to be a constant, so c^2 is
going to be constant as well and no calculations are really needed, I'll
just define those values. I don't know yet what this numerical constant will
be but let's call it decimal 10 for "c" and decimal "100" for c^2 constants.

I just noticed that my denominator will always be a negative in this formula
with c > 0 and since my result is always positive, the numerator is also
always going to be negative for my purposes.  I can manipulate this equation
a little if necessary to handle negatives better so keeping all this in
mind,
the variables "a" and "b" will be program variables and it is possible that
a situation arises where say all a, b, and c are equal to decimal 10.  So
the formula says x = (100 - 100 - 100) / (-2(10))     so I get x = -100/-20
or x = 5

All I care about is getting this final +5, no matter how I go about it with
negatives in between.  So if I always end up with a negative over a
negative, and I decide to just modify the equation denominator to +2c
instead of -2c, how do I go about taking my final result for (b^2 - a^2 -
c^2), which I think is always going to end up negative in my case, and just
change the sign to positive for division purposes?   As I write this, I know
the answer must be as simple as "toggle <that bit> which indicates the sign
of the number, you idiot"  but again...it's not so intuitive for me to go

Let's say I have a variable defined as      "result"   in my program
definitions and this is where I store the numerator all calculated out.  How
do I toggle the sign of this memory location?   Even better, how do I verify
it's a negative number before toggling it?  I guess that's my final
question, as I'm seeming to figure most of my own problem out now...

On Tue, Feb 08, 2000 at 03:10:12AM -0500, Lorick wrote:
> I know it seems odd to ask such questions when I should be able to simply
> "test" the code myself as was insisted in another response, [...]

Sorry, I did sort of assume you'd have yourself a simulator.  MPSIM is
freely available from Microchip, and gpsim is free and comes with source.
gpsim works on Linux, MPSIM on something else.

I'll give you a quick negative numbers explanation ...

Think of a tape recorder counter.  Zero it and then rewind.  It goes;

000 999 998 997 996

And so on.  Think of 999 as -1.  Eventually you reach 500.  How you
treat that is up to you.  So a quick check for negative in this way of
numbering is "is the unsigned value > 500".

Same with binary.  Think of a four bit number.  Zero it and then rewind;

0000 1111 1110 1101 1100

And so on.  Think of 1111 as -1.  Eventually you will reach 1000.
The quick check for negative numbers is to examine the left most bit.

Expand it to sixteen bits ...

0000 0000 0000 0000  = 0
1111 1111 1111 1111  = -1
1111 1111 1111 1110  = -2
1111 1111 1111 1101  = -3

And so on.

This is how most computers store signed integers.

> Let's say I have a variable defined as      "result"   in my program
> definitions and this is where I store the numerator all calculated out.  How
> do I toggle the sign of this memory location?   Even better, how do I verify
> it's a negative number before toggling it?  I guess that's my final
> question, as I'm seeming to figure most of my own problem out now...

Subtract it from zero to reverse the sign.

See http://quozl.us.netrek.org/stack-math.asm and look for the function
"negate".  It does this.  Compare also the function "abs", which takes
the absolute value.  Here's the code ...

[note that fsr points to the top element on the data stack]

;;;
;;; sb_abs, sixteen bit absolute value
;;;
;;; data stack: ( a -- |a| ) [total 2]
;;; stack:      none
;;;
sb_abs_
btfss   indf,7                  ; is it negative?
retlw   0                       ; no, so return
; fall through to negate
;;;
;;; sb_negate, sixteen bit negate
;;;
;;; data stack: ( a -- 0-a ) [total 2]
;;; stack:      none
;;;
sb_negate_                              ; ( lsb msb -- lsb msb )
incf    fsr,f                   ; ( lsb ^ msb )
comf    indf,f                  ; lsb
incf    indf,f                  ; lsb
decfsz  fsr,f                   ; ( lsb msb ^ )
nop                             ; [decrement without losing z]
btfsc   status,z
decf    indf,f                  ; msb
comf    indf,f                  ; msb
retlw   0                       ; ( lsb msb )

--
James Cameron   quozlus.netrek.org   http://quozl.us.netrek.org/

----- Original Message -----
From: James Cameron <quozlUS.NETREK.ORG>
To: <PICLISTMITVMA.MIT.EDU>
Sent: Tuesday, February 08, 2000 3:47 AM
Subject: Re: 16 bit PIC math question on subtracting

>         0000 0000 0000 0000  = 0
>         1111 1111 1111 1111  = -1
>         1111 1111 1111 1110  = -2
>         1111 1111 1111 1101  = -3
>

So using signed numbers then, I reduce the number to 15 bits + 1 sign?   So
my highest decimal representation is 2^15 = 32768?  In that case, if I want
signed (if I'm right it all makes sense now and is coming back to me,
thanks) binary representation from an A/D channel, instead of having an
input signal between 0 and 5v and converting it to decimal 0 to 255, I would
be interested in scaling my maximum decimal reading so that I could square
the maximum and have it fit within decimal 32768, which decimal 180 does
nicely I think, so I would possibly reconsider having my analog input
between 0 and 3.5v instead of 0 and 5v to have a maximum reading of decimal
180?

I can anticipate all kinds of things like losing resolution maybe, and
0-5v input but software scaling the 0-255 result.....but right now time is
the issue for me and I'm better with the hardware restriction.  Losing
resolution would probably be ok for my application (experiments to come).

But was I on the right track with the signed 15 bit integer thing?

Myke Predko wrote:

> The addition/subtraction routines handle and produce two's complement
> numbers as a matter of course.  The multiplication routines should not
> have any problems with negatives.

Sorry, I don't follow.  *Why* do the multiplication routines not have
any problem with negatives?

As far as I have ever been able to determine, all multiply and divide
procedures require the rule:  determine the sign of the result (XOR the
signs of the two operands), make each operand positive, perform the
operation, apply the sign to the result.
--
Cheers,
Paul B.

Lorick, given a 16 Bit integer, an unsigned integer has a range of
16 Bits. A signed integer has a range of +/- 15 Bits with the MSB being
the sign Bit as James described. Note, James' example uses 2's complement
to represent negative numbers which is the common method.

- Tom

At 05:08 AM 2/8/00 -0500, Lorick wrote:
>{Original Message removed}

More... (looser matching)
- Last day of these posts
- In 2000 , 2001 only
- Today
- New search...