PDA

View Full Version : Long Variables can be negative?

Ramius
- 5th July 2012, 03:02
On page 15 of the PBP3 Reference Manual (1.3) it says that "Long variables are 32-bits wide and can hold values -2147483648 to 2147483648. Is it really true you can have a negative number? Thanks, Ed

Ioannis
- 5th July 2012, 12:40
Only if you use PBPL instead of PBPW then yes. You can make e.g. comparisons for negative numbers.

Bval VAR BYTE
Bval = 0
IF ((Bval – 1) < 0) THEN negative

In the abobe example although Bval is byte, internally the PBPL holds the temporary result in a long variable which in turn can hold negative numbers too.

So the result of the IF-THEN will goto negative.

Ioannis

mackrackit
- 7th July 2012, 03:43
http://melabs.com/resources/articles/longs.pdf
Might be of interest too.

HenrikOlsson
- 7th July 2012, 10:46
Ioannis,

In the abobe example although Bval is byte, internally the PBPL holds the temporary result in a long variable which in turn can hold negative numbers too.
So the result of the IF-THEN will goto negative.

I thought that although you could "manually" look at the highest bit (IF BVal.7 THEN Negative) to see if it's negative doing a comparison for less than zero only really works with variables declared as LONGs. Or are you saying that it'll actually work because you're doing an intermediate calculation in your actual comparison ie

BVal VAR BYTE
BVal = 0
If (BVal - 1) < 0 THEN Negative
Works, while...

BVal VAR BYTE
BVal = 0
BVal = BVal - 1
If BVal < 0 THEN Negative
..doesn't?

Guess I could try it myself....

/Henrik.

pedja089
- 7th July 2012, 13:56
First code will work, if you use PBPL, because result is stored into temporally long variable.
That is same as this

Temp VAR LONG
BVal VAR BYTE
BVal = 0
Temp = BVal - 1
If Temp < 0 THEN Negative

HenrikOlsson
- 7th July 2012, 14:42
That's what I thought, makes sense, thanks!
I haven't yet used PBPL in any project. I tried on my servo project but the "cost" of compiling with PBPL was too high so I managed without it.

/Henrik.

Ioannis
- 8th July 2012, 17:01
Although answered by pedja089, yes Henrik. It will work in either your example if you compile with PBPL. But as you said, the cost is high. So if you only need a comparisson, you can find other ways to do it just fine.

Ioannis

pedja089
- 8th July 2012, 17:17
I think this won't work...

BVal VAR BYTE
BVal = 0
BVal = BVal - 1
If BVal < 0 THEN Negative
Because BVal is byte, and byte is always unsigned. So it can't be lower than 0. Correct me if I'm wrong...

Ioannis
- 8th July 2012, 19:12
It WILL work only if you use PBPL because the result is stored temporarily in a long variable. This variable is checked, so yes it will work fine.

For more info check the new PBP manual that clarifies the case.

Ioannis

pedja089
- 8th July 2012, 22:38
Isn't result stored in BVal in this example?
BVal = BVal - 1
Result in BVal is 255(Checked with debugger). And because BYTE is unsigned it can't be negative. Program won't jump to negative.
Then tried: If BVal - 1< 0 THEN Negative
Then is negative.
I really can't see how value in this statement is stored at end in temp var BVal = BVal - 1.
That code is same as:
Temp=BVal - 1
BVal =Temp
So we loose sing when value is passed to BVal.
I'm done my homework, now you do yours :D

Ioannis
- 8th July 2012, 23:36
Page 84-85 of the manual.

Ioannis

mackrackit
- 9th July 2012, 00:04
Page 81 and 82 of my manual... But who reads stinken manuals....

pedja089
- 9th July 2012, 00:50
From manual...
Bval=-1 (Same as Bval =0:Bval=Bval-1)
If ( Bval < 0 ) THEN negative 'Will never test true
So second example from post #4 vil never test true...

Ioannis
- 9th July 2012, 07:46
What PBP compiler are refering to?

I said, it will work on PBPL

NOT on PBPW

David, the manual I as refering to is the revision of Revised November 28, 2011.

Ioannis

F1CHF
- 26th December 2012, 19:19
hello
As am not super fluent in English, I understand that if I want to use PBPL.exe I need to use a 18Fxxx PIC
I need to use a variable that will contents the number 39000000 (39 millions)
it is use in a frequency generator that goes to this frequency
my board (display and push buttons is equiped with a 16F877 so I have no chance to use such LONG variable !
Am I right ?
francois F1CHF
thanks

HenrikOlsson
- 26th December 2012, 22:57
Hi,
Yes, LONGs can only be used on 18-series parts. Do you need to do any math etc on that 32bit variable or are you just trying to store it? If you only need to store it then simply use an array of 4 bytes. If you need math you could always take a look at Darrels N-Bit math routines (http://www.picbasic.co.uk/forum/showthread.php?t=12433&highlight=N_Bit) which will allow you to declare variables of "any" size and do math with them.

/Henrik.

F1CHF
- 27th December 2012, 10:22
Thanks Henrik for this quick answer
But it is "too much" for my old brain !
Darrel has done a great job , as usual !
yes I have just one calculation (I got the Arduino code)
something like that
unsigned long tuning_word = (frequency * pow(2, 32)) / DDS_REF
frequency will go from 1 to 39 millions
DDS_REF is 125 millions
and I must decode what is the POW(2,32) !
For this need I think that I will order an Arduino board !

Happy new year for everybody
and all my congratulations for this very nice help forum, it is great
Francois F1CHF (radio amateur) 65 years old now ....

HenrikOlsson
- 27th December 2012, 13:03
Hi,
Ah, it's that AD9850 DDS chip again, I've got a couple of those on their way to play with as well.
pow(2,32) simply means 2 raised to the power of 32, sometimes written as 2^32 (not in PBP though) or, spelled out, 4 294 967 296. So in reallity your formula looks like unsigned long tuning_word = (frequency * 4294697296) / 125000000

Knowing that you could shorten it to Tuning_Word = frequency * 34.3597 (where 34.3597 simply is 2^32/125M). Obviosuly non integer numbers like that 34.3597 won't fly with PBP but we could do Tuning_word = frequency */ 8796 which would be like saying tuning_word = frequency * 8796 / 256.

Now, lets see if this works out, first with the original formula for a frequency of 500Hz
Tuning_Word = (500 * 4294697296) / 125M = 17179
And then for our PBP way of doing it
Tuning_Word = 500 * 8796 / 256 = 17179

Now, this would still only allow frequencies up to around 1900Hz after which a WORD variable will overflow. There might be a way around this but before I spend more time on it would be nice if
A) You could verifu that the above actually works in frequencies <1900Hz and
B) Let me know it you don't concider switching to an 18F device would be easier.

/Henrik.

F1CHF
- 27th December 2012, 15:23
Hi Henrick
Mister "maestro's number" ... hi !
Yes I have ordered a AD9850 kit from ebay item 140776695890
I got the software from here http://f5mna.free.fr/dds.htm
I got PCB + LCD from here http://f6kbf.free.fr/pdf/Synfoxny.zip
my objective is to generate frequency between 25 and 28 Mhz
to play with a LNBPLL ebay item 320886789074
I satrt to remove the 27 mhz quartz and with a generator (ADRET) I am abble
to synchronize the pll to have different Local oscillator frequency, and the most
important is that the oscillator accep to go on 10.368 Ghz .... it is super to have a beacon for peanut !
so you know the complete story
You are right, if I can find a 18Fxxxx instead of the 16Fxxxx this is the solution with PBPL compiler
I can start the process with your example to check at least the basic (< 1900 hz) function
hold the line ...
my email is F1CHF at free.fr (in the case of direct messages )
best regards
Francois F1CHF

HenrikOlsson
- 27th December 2012, 16:54
Hi Francois,
Actually I'm not that great at math so don't take everything I write for granted....that's why I asked you verify it.

What type of accuracy do you need - realistically? I've been playing with it this afternoon and just now tried 25, 26.5 and 28MHz and the calculated tuning values are all at 99.99894% of the optimal one. This means that when you ask for 28MHz you'll get 27.9997MHz, or ~300Hz off your nominal center frequency. Is that too far off? (I'm not sure I could do better with using LONGs though).

It uses Darrels N-Bit routines so it should work fine on a 16F device. However you still won't be able to simply enter a frequency value directly in Hz since there are no variable size big enough to hold that value directly. Instead the frequency value is "built" by two word size variables. However, if the desired frequency could be entered in units of kHz instead, like 26500 for 26.5MHz then I could probably add that pretty easily.

I'm no radio guru so I don't understand all of what you're saying, especially the part with the peanut and 10.368Ghz...are you building a microwave for zapping peanuts? :-)

/Henrik.