Searching \ for '[PIC]: signed math' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/math/index.htm?key=math
Search entire site for: 'signed math'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: signed math'
2001\12\03@022704 by Vasile Surducan

flavicon
face
ooops, with corrected topic again:
{Quote hidden}

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\12\03@060532 by Gerhard Fiedler

flavicon
face
If you're talking about signed int in the form (1 sign bit + 8 bits
absolute value), this is rather easy.

For positive values (MSB = 0), both are equal (assuming that a sign bit = 0
means "positive"). For negative values, you just have to use the rules for
2th complement to complement the remaining 8 bit (bitwise inverting, then
incrementing).

Note that the two representations do not cover the same range: 2th
complement goes from -256 to +255, signed int goes from -255 to +255 (with
two representations for 0). Trying to convert -256 will result in -0, which
is wrong.


But if you're talking about the C language definition of "signed int", it
IS 2th complement...  ;)  just that it is probably 16 bits. You just have
to fill the whole MSByte with the content of the MSbit.

ge

At 09:22 12/03/2001 +0200, Vasile Surducan wrote:
{Quote hidden}

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\12\03@060753 by o-8859-1?Q?K=FCbek_Tony?=

flavicon
face
Hi,
Perhaps if you would elaborate a bit on the actual
formula you intend to use I can give some hints.

Signed/unsigned is fairly trivial
unless you mix data of variable size and signed/unsigned
then it starts to get a bit tricky :)

We have had some disscussions about signed/unsigned on the list
check the archives.

But a short re-cap ( signed math ):

Top bit set (msbit) = Value is negative
Top bit clear (msbit) = Value is positive

For addition/subtraction you need no special routines,
unless there are possibilities for overflow.

To 'convert' from negative to positive ( or the other way around ):

;++++++++++++
;
; NORM_16 - Normalises a 16 bit variable ( i.e make two's complement )
; argument must point to most significant byte, arg16+1 is lsb

NORM_16 MACRO   ARG_16
       ; first make one's complement
       COMF    LOW(ARG_16+1),F
       COMF    LOW(ARG_16),F
       ; then add one to form two's complement
       MOVLW   1
       ADDWF   LOW(ARG_16+1),F
       SKPNC
       ADDWF   LOW(ARG_16),F
       ENDM

/Tony

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\12\03@072749 by Vasile Surducan

flavicon
face
Thanks Gerhart and Tony

On Mon, 3 Dec 2001, [Iso-8859-1] Kübek Tony wrote:

> Hi,
> Perhaps if you would elaborate a bit on the actual
> formula you intend to use I can give some hints.
>   OK here is:
   temperature = temp_read - 1/2LSB + [ (count_per_degree - count_remain /
                                       count_per_degree) ]

All values are 9 bit numbers, Truncated half-degree bit ( temp_read - 1/2LSB ) its a simple task:
 rrf temp_read_lo, f
 bcf status_c
 rlf temp_read_lo, f
The new value ( 9 bit too ) will have resolution of only 1 C degree
instead of 0.5 C and will be contained in temp_read_lo, temp_read_hi ( the sign )
Application note 105 from Dallas said :
"convert truncated value from 2's complement to signed integer"
This is the problem I have. Application note does say nothing more about.
But also it seems that measuring only positive temperatures I will not
have errors even I will not perform that conversion. About division, I've plan to use a standard 16bit division routine,
maybe Nikolay will point to a 9 bit division one ?

> We have had some disscussions about signed/unsigned on the list
> check the archives.
  There are some problems by checking archives even for registered people
because of overloading ( 1search/minute ) At my low transfer rate in one
minute I've got nothing . What money are necesarry to improve the piclist server ?

Thanks, Vasile
--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\12\03@102414 by o-8859-1?Q?K=FCbek_Tony?=

flavicon
face
Hi Vasile,
I suspected there was abit more to this then the subject led on :),
in this case to understand why/what
caused the problem with signed/unsigned i consulted the maxim
site and the app. notes for the DS1620.

http://dbserv.maxim-ic.com/quick_view2.cfm?qv_pk=2735

Now I can understand your concerns, however there might be an solution :)
After an quick glance through the app-notes, I think the following
assumptions are correct:

-Data output in 8 bit+sign bit in 0.5 degrees resolution ( rounded )
-Possibility to read the slope/count registers manually to achive
higher accuracy.
-the examples uses float variables which is 'a tad bit' overkill
for temperature calculation on an pic.

Instead i propose the following:

Read data, store sign bit separately, if negative make 2's complement
and then perform remaing calculation for positive numbers only.
To avoid the float issue I think an alternative data format might be useful,
i.e the data is originally presented as 7Q1 in whole degrees ( 0.5 deg. 8
bits )
and formula is intended to extend the resolution to atleast 0.1 deg. Why
not multiply original data with 128 ( i.e leftshift by 7 ),
data would then be represented in two bytes as 8Q8. With the lowest byte as
fractional part ( i.e. fixed point ).
Use this data representation for all data from the device, then scaling
should not be an issue ( i.e. counter_remain, count_per_deg etc ).

pseuso hack/slash something like:


data_input      RES 2   ; storage for temp. data ( 9 bits from device )
count_rem       RES 2   ; storage for temp. internal counter
count_deg       RES 2 ; storage for temp. internal slope
bit_vars        RES 1 ; misc. bit varibales

#define _sign_bit               bit_vars,0      ; storage for sign

//pseudo..
data_input = read_data9bit()    // read data from device store in local ram

; store the sign bit for future use
BCF     _sign_bit               ; clear ev. previous sign
BTFSC   data_input,0    ; test sign bit
BSF     _sign_bit               ; temp. is negative

; if the 9'th bit is set then make 2's complemnt
BTFSS   data_input,0    ; set if negative
GOTO    DATA_SWAP
; negative, normalize data
COMF    data_input+1,F  ; 1's complement
MOVLW   D'1'
ADDWF   datainput+1,F   ; and add 1

:DATA_SWAP
; at entry we have data in as 15q1 ( in full degrees )
; now we want to store data in 8q8 ( really 7q8 ) format instead
; as input is limited to <255 we can just swap the bytes
; and right shift by one
CLRC                            ; clear carry for byte rotation
RRF     data_input+1,W  ; get data, get lowest bit into carry
MOVWF   data_input              ; overwrite top byte
CLRF    data_input+1    ; and clear bottom byte
RRF     data_input+1,F  ; and rotate the carry into top bit
; data now represented in fixed point as 8q8 ( where the top bit is always
zero )
; note data is *not* truncated yet
; now read the count_rem and count_deg variables
; and store them in 8q1 format  ( similar to data, i.e. left shifted by 7 )
; then you can use 'normal' 16 bit division routines

the result is then 'read out' from the 16 bit variable
as whole degrees in top byte, and fractional degrees in
low byte ( 256'th of deg. ) If you want 'normal' 10's base
representation, Nikolai's code generator works wonders :)

/Tony

PS don't forget about truncation, 0.25 degrees ! DS

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\12\03@104626 by o-8859-1?Q?K=FCbek_Tony?=

flavicon
face
Hi,

BTW:

Vasile Surduncan wrote:
<snip>
>Truncated half-degree bit ( temp_read - 1/2LSB ) its a simple task:
>  rrf temp_read_lo, f
>  bcf status_c
>  rlf temp_read_lo, f
<snip>

This is *not* correct, I hope you understand that.
Truncation should only be 0.25 degrees, i.e. 1/2 LSB !!!
*not* 1/2 degree !!!
Therefore digest my proposal and understand the reason I choosed
not to truncate data before conversion to fixed format. Removing
0.25 degree ( 1/2 LSB in this case ) is trivial if following my suggestion
as that only means an subtraction of the 16 bit value 0x0040 ( which is
0.25 degrees in 8q8 fixed format ). I.e.:

0x0040 is in 8q8 equal to:

0x00 ( top byte ) = 0 degrees
0x40 ( bottom byte ) -> 0x40/0xFF (implied decimal point) = 0.25 degrees



/tony

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\12\03@112200 by Rudy Rudy

flavicon
face
Vasile,

I remember doing similar thing with one of those Texas Instrument temperature sensors.  What I did was simply change the higher 8 bits
(the high byte).  In other words, if the number is positive, leave it as it is, but if it is negative, change it to 0xFF.

That should take care of it...

Rudy


{Quote hidden}

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\12\04@063218 by Vasile Surducan

flavicon
face
On Mon, 3 Dec 2001, [Iso-8859-1] Kübek Tony wrote:

> Hi,
>
> BTW:
>
> Vasile Surduncan wrote:
> <snip>
> >Truncated half-degree bit ( temp_read - 1/2LSB ) its a simple task:
> >  rrf temp_read_lo, f
> >  bcf status_c
> >  rlf temp_read_lo, f
> <snip>
>
> This is *not* correct, I hope you understand that.
> Truncation should only be 0.25 degrees, i.e. 1/2 LSB !!!
> *not* 1/2 degree !!!

 YES... I've realised that last night...
 I'll digest your mail, it's very close to my conclusions.
 Thanks a lot, it seems you're a great specialist in maths tricks.

Best regards, Vasile

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


2001\12\04@123658 by Scott Dattalo

face
flavicon
face
On Mon, 3 Dec 2001, Vasile Surducan wrote:

> Thanks Gerhart and Tony
>
> On Mon, 3 Dec 2001, [Iso-8859-1] K|bek Tony wrote:
>
> > Hi,
> > Perhaps if you would elaborate a bit on the actual
> > formula you intend to use I can give some hints.
> >
>   OK here is:
>
>   temperature = temp_read - 1/2LSB + [ (count_per_degree - count_remain /
>                                         count_per_degree) ]

I think your right most ')' is in the wrong place.
As I recall, count_per_degree is ~50.

Notice that the above formula can be reduced:

temperature = temp_read + [(count_per_degree - count_remain) /
             count_per_degree] - count_per_degree/(2*count_per_degree)

           = temp_read + [(2*count_per_degree - 2*count_remain) /
             2*count_per_degree] - count_per_degree/(2*count_per_degree)

           = temp_read + [(count_per_degree - 2*count_remain) /
             2*count_per_degree]


or another form that may even be more useful:

temperature = temp_read + 1/2LSB  - count_remain / count_per_degree



I doubt you really need more than a few bits from the division. If not
then you can try the routine below. Note that this does a 4-bit division
for the low byte of the temperature. Also, for clarity I included some
debug code to illustrate its use. It should be clear from the variable
names on how to change this to a real interface to a ds1820.


       include   /usr/local/share/gpasm/header/p16f84.inc

 cblock       0x0c
       temp_read
       temp_hi
       temp_lo
       count_remain
       count_per_degree
       x
 endc




       movlw   0x20
       movwf   temp_read

  ; debug loop
l1

       movlw   0x40
       movwf   count_per_degree
       movf    x,w
       movwf   count_remain

       call    div

 ; increment the temperature
       incf    x,f
       movf    x,w
       addlw   -0x40
       skpc
        goto   l1

       incf    temp_read,f
       clrf    x

       goto    l1

 ; convert the temperature into a 12 bit result: 8-bit integer
 ; plus a 4-bit fraction. Note, negative temperatures are not handled

div:
   movf   temp_read,w         ; Get the high 8 bits
   movwf  temp_hi


; 4-bit division

   movlw  0x08                ;Quotient of division is stored
   movwf  temp_lo             ;here. Also used as a loop counter

   movf   count_per_degree,w  ;Keep divisor in W

div_loop:
   clrc
   rlf    count_remain,f      ;Shift dividend

   subwf  count_remain,f      ;If divisor is <= dividend
   rlf    temp_lo,f           ;then C is set
   btfss  temp_lo,0           ;If C was not set then
    addwf  count_remain,f     ;we need to restore the subtraction

   btfss  temp_lo,7           ;If msb is clear (the loop count bit)
    goto  div_loop            ; we're done, else loop more


   ; through division. Low 4 bits of temp_lo contain result.
   ; we need to << 4, and subtract from "1/2" or 0x80/0x100.
   ; If the subtraction causes a borrow, then we need to
   ; decrement the high byte as well.

   swapf  temp_lo,w           ;<<4
   andlw  0xf0                ;get rid of loop count bit
   addlw  0x80                ;"subtract" 1/2 note -1/2=0x80
   movwf  temp_lo             ;save the low temperature

   skpc                       ;If the division is less than 1/2
    decf  temp_hi,f           ;get the borrow bit from the high byte


       return

 end


This routine works in this contrived example. There's a little room for
optimization too...

>
>  All values are 9 bit numbers,
> Truncated half-degree bit ( temp_read - 1/2LSB ) its a simple task:
>   rrf temp_read_lo, f
>   bcf status_c
>   rlf temp_read_lo, f

  The same can be accomplished with:

   bcf  temp_read_lo,0

But neither of these are the same for subtracting a 1/2 LSB.

You're going to need a whole other byte to store that extra bit.

If you want to subtract a half LSB do this:

   decf  HI_BYTE,F
   movlw 0x80
   movwf LO_BYTE


You can now think of the LO_BYTE as a fraction of 0x80/0x100 = 1/2.

{Quote hidden}

The last time I checked, Nikolai was too busy working on his foos serve.

Scott

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


2001\12\05@021944 by Vasile Surducan

flavicon
face
Oh my God,  Scott !
You have a really rested mind...
I'm wondering why the guys from Dalas haven't ...
However, the whole theory is shadowed by the instability of the
count_per_degree and count_remain values.
As many readings, as many values at the same temperature.

Thank you,
Vasile



On Tue, 4 Dec 2001, Scott Dattalo wrote:

{Quote hidden}

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\12\05@081511 by o-8859-1?Q?K=FCbek_Tony?=

flavicon
face
Hi,

Vasile wrote:
<snip>
>Thanks a lot, it seems you're a great specialist in maths tricks.
<snip>

Nope but I've encountered a few on the list :)
hmm...let's see...

Scott Dattalo wrote:
<removed excellent implementation>
> This routine works in this contrived example. There's a little room for
> optimization too...

ah that's right, there's one :)

Great stuff,


/Tony

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\12\05@084759 by o-8859-1?Q?K=FCbek_Tony?=

flavicon
face
Hi,

Vasile Surduncan wrote:
<snip>
>However, the whole theory is shadowed by the instability of the
>count_per_degree and count_remain values.
>As many readings, as many values at the same temperature.

I'm curious, how much flucatuation are we talking about ?
Assuming you had the 0.5 degrees stable prior to trying to
extend it to 0.1 degrees, the unstability ( i.e. noice etc. )
should be less than 0.5 degrees.
If you have higher fluctuations then you have to look for other causes,
you are using one-shot mode ?

In this case I assume the an fairly small FIR should be of use,
let's say an average of 8 readings ? Would that produce 'better' results ?


/Tony

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\12\06@134759 by Scott Dattalo

face
flavicon
face
On Wed, 5 Dec 2001, Vasile Surducan wrote:

> However, the whole theory is shadowed by the instability of the
> count_per_degree and count_remain values.
> As many readings, as many values at the same temperature.

I'm not sure what you're saying here. Are you saying that the DS1820 is
inherently flawed because there several temperatures that have
different "count_per_degree" and "count_remain" values, or the algorithm
which I posted was flawed because different "count_per_degree" and
"count_remain" can produce the same temperature?

All I can say is that the algorithm is accurate to within 1/8 of a degree.
If count_remain and count_per_degree change, the algorithm will still work
properly (the only assumption is that count_remain is less than
count_per_degree). Study it, try it, and tell us how it works.

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email spam_OUTlistservTakeThisOuTspammitvma.mit.edu with SET PICList DIGEST in the body


2001\12\07@054910 by Vasile Surducan

flavicon
face
On Thu, 6 Dec 2001, Scott Dattalo wrote:

> On Wed, 5 Dec 2001, Vasile Surducan wrote:
>
> > However, the whole theory is shadowed by the instability of the
> > count_per_degree and count_remain values.
> > As many readings, as many values at the same temperature.
>
> I'm not sure what you're saying here. Are you saying that the DS1820 is
> inherently flawed because there several temperatures that have
> different "count_per_degree" and "count_remain" values, or the algorithm
> which I posted was flawed because different "count_per_degree" and
> "count_remain" can produce the same temperature?
>

 No, I don't say nothing ugly about your algorithm. Even by absurd it is
wrong I don't dare to do this... ( until I not understad it 100% )
I'm working with DS1620 but it seems the hi res algorithm is the same. If
count_per_degree is almost constant ( fluctuating between 0x_40 to 0x_65 )
count_remain have a fluctuation from less than count_per_degree to 0x_01df
at the constant test temperature of about 20 C.
I think is too much, because the division between these two should be
almost constant and is not ...
Thanks, Vasile

--
http://www.piclist.com hint: To leave the PICList
.....piclist-unsubscribe-requestKILLspamspam@spam@mitvma.mit.edu


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